~ubuntu-branches/debian/experimental/xfce4-panel/experimental

« back to all changes in this revision

Viewing changes to migrate/migrate-default.c

  • Committer: Bazaar Package Importer
  • Author(s): Yves-Alexis Perez, Lionel Le Folgoc, Yves-Alexis Perez
  • Date: 2011-02-06 18:10:07 UTC
  • mfrom: (1.3.13 upstream) (5.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110206181007-vpw5z3xnm3hdvybx
Tags: 4.8.1-1
[ Lionel Le Folgoc ]
* New upstream bugfix release.
* debian/control:
  - refreshed (b-)deps for this new major release
  - add myself to Uploaders
  - bump Standards-Version to 3.9.1.
* debian/NEWS: dropped, unneeded.
* debian/xfce4-panel.shlibs: refreshed, bump to (>= 4.7.2).
* debian/xfce4-panel.lintian-overrides: refreshed, new lib name.
* debian/xfce4-panel.preinst: added, handles removal of old conffiles.
* debian/xfce4-panel.postinst: explicitly set -e.
* debian/*.install: refreshed.
* debian/rules:
  - call dpkg-buildflags
  - dropped rc files mangling as they don't exist anymore
  - updated removal of *.{l,}a files.
  - drop overrides for dh_auto_{configure,clean}, obsolete.
* debian/xfce4-panel.{preinst,postinst,prerm}: use dpkg-maintscript-helper
  to remove pre-xfconf config files.
* Bugs fixed by 4.7.x/4.8.x series:
  - rgba support                                                  lp: #586012
  - disappearing menus                                             lp: #53897
  - xrandr support                               lp: #176174, Closes: #432914
  - Fails to reap children, creating zombies                      lp: #420187
  - DND of desktop-files on the panel to create new launchers Closes: #480380
* Bumped shlibs to >= 4.7.7, abi break for external plugins.

[ Yves-Alexis Perez ]
* New upstream development release
* debian/xfce4-panel.install:
  - install wrapper and migrate tools in xfce4-panel package
  - update plugins paths
* debian/rules:
  - update path when removing .a/.la files for plugins.
  - add hardening flags to {C,LD}FLAGS
* debian/control:
  - add build-dep on hardening-includes
  - update build-dep on garcon to 0.1.4.
* debian/copyright updated for new release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2009-2010 Nick Schermer <nick@xfce.org>
 
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 Foundatoin; 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 along
 
15
 * with this program; if not, write to the Free Software Foundatoin, Inc.,
 
16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
17
 */
 
18
 
 
19
#ifdef HAVE_CONFIG_H
 
20
#include <config.h>
 
21
#endif
 
22
 
 
23
#ifdef HAVE_STDLIB_H
 
24
#include <stdlib.h>
 
25
#endif
 
26
#ifdef HAVE_STRING_H
 
27
#include <string.h>
 
28
#endif
 
29
 
 
30
#include <gtk/gtk.h>
 
31
#include <xfconf/xfconf.h>
 
32
#include <libxfce4util/libxfce4util.h>
 
33
#include <migrate/migrate-default.h>
 
34
#include <libxfce4panel/xfce-panel-macros.h>
 
35
 
 
36
 
 
37
 
 
38
typedef struct
 
39
{
 
40
  XfconfChannel *channel;
 
41
  GSList        *path;
 
42
  GPtrArray     *array;
 
43
}
 
44
ConfigParser;
 
45
 
 
46
 
 
47
 
 
48
static GType
 
49
migrate_default_gtype_from_string (const gchar *type)
 
50
{
 
51
  if (strcmp (type, "string") == 0)
 
52
    return G_TYPE_STRING;
 
53
  else if (strcmp (type, "uint") == 0)
 
54
    return G_TYPE_UINT;
 
55
  else if (strcmp (type, "int") == 0)
 
56
    return G_TYPE_INT;
 
57
  else if (strcmp (type, "double") == 0)
 
58
    return G_TYPE_DOUBLE;
 
59
  else if (strcmp (type, "bool") == 0)
 
60
    return G_TYPE_BOOLEAN;
 
61
  else if (strcmp (type, "array") == 0)
 
62
    return G_TYPE_BOXED;
 
63
  else if (strcmp (type, "empty") == 0)
 
64
    return G_TYPE_NONE;
 
65
 
 
66
  return G_TYPE_INVALID;
 
67
}
 
68
 
 
69
 
 
70
 
 
71
static void
 
72
migrate_default_set_value (GValue      *value,
 
73
                           const gchar *string)
 
74
{
 
75
  switch (G_VALUE_TYPE (value))
 
76
    {
 
77
    case G_TYPE_STRING:
 
78
      g_value_set_string (value, string);
 
79
      break;
 
80
 
 
81
    case G_TYPE_UINT:
 
82
      g_value_set_uint (value, strtol (string, NULL, 0));
 
83
      break;
 
84
 
 
85
    case G_TYPE_INT:
 
86
      g_value_set_int (value, strtoul (string, NULL, 0));
 
87
      break;
 
88
 
 
89
    case G_TYPE_DOUBLE:
 
90
      g_value_set_double (value, g_ascii_strtod (string, NULL));
 
91
      break;
 
92
 
 
93
    case G_TYPE_BOOLEAN:
 
94
      g_value_set_boolean (value, strcmp (string, "true") == 0);
 
95
      break;
 
96
 
 
97
    }
 
98
}
 
99
 
 
100
 
 
101
 
 
102
static gchar *
 
103
migrate_default_property_path (ConfigParser *parser)
 
104
{
 
105
  GSList  *li;
 
106
  GString *path;
 
107
 
 
108
  path = g_string_new (NULL);
 
109
 
 
110
  for (li = parser->path; li != NULL; li = li->next)
 
111
    {
 
112
      g_string_append_c (path, '/');
 
113
      g_string_append (path, (const gchar *) li->data);
 
114
    }
 
115
 
 
116
  return g_string_free (path, FALSE);
 
117
}
 
118
 
 
119
 
 
120
 
 
121
static void
 
122
migrate_default_start_element_handler (GMarkupParseContext  *context,
 
123
                                       const gchar          *element_name,
 
124
                                       const gchar         **attribute_names,
 
125
                                       const gchar         **attribute_values,
 
126
                                       gpointer              user_data,
 
127
                                       GError              **error)
 
128
{
 
129
  ConfigParser *parser = user_data;
 
130
  guint         i;
 
131
  const gchar  *channel_name;
 
132
  const gchar  *prop_name, *prop_value, *prop_type;
 
133
  GType         type;
 
134
  gchar        *prop_path;
 
135
  GValue        value = { 0, };
 
136
  const gchar  *value_value, *value_type;
 
137
  GValue       *value2;
 
138
 
 
139
  if (strcmp (element_name, "channel") == 0)
 
140
    {
 
141
      channel_name = NULL;
 
142
 
 
143
      if (G_LIKELY (attribute_names != NULL))
 
144
        {
 
145
          for (i = 0; attribute_names[i] != NULL; i++)
 
146
            {
 
147
              if (strcmp (attribute_names[i], "name") == 0)
 
148
                {
 
149
                  channel_name = attribute_values[i];
 
150
 
 
151
                  /* this is an xfce4-panel workaround to make it work
 
152
                   * with the custom channel names */
 
153
                  channel_name = XFCE_PANEL_CHANNEL_NAME;
 
154
                }
 
155
            }
 
156
        }
 
157
 
 
158
      if (channel_name != NULL)
 
159
        {
 
160
          /* open the xfconf channel */
 
161
          parser->channel = xfconf_channel_new (channel_name);
 
162
        }
 
163
      else
 
164
        {
 
165
          g_set_error_literal (error, G_MARKUP_ERROR_INVALID_CONTENT, G_MARKUP_ERROR,
 
166
                               "The channel element has no name attribute");
 
167
        }
 
168
    }
 
169
  else if (strcmp (element_name, "property") == 0)
 
170
    {
 
171
      prop_name = NULL;
 
172
      prop_value = NULL;
 
173
      prop_type = NULL;
 
174
 
 
175
      if (G_LIKELY (attribute_names != NULL))
 
176
        {
 
177
          for (i = 0; attribute_names[i] != NULL; i++)
 
178
            {
 
179
              if (strcmp (attribute_names[i], "name") == 0)
 
180
                prop_name = attribute_values[i];
 
181
              else if (strcmp (attribute_names[i], "value") == 0)
 
182
                prop_value = attribute_values[i];
 
183
              else if (strcmp (attribute_names[i], "type") == 0)
 
184
                prop_type = attribute_values[i];
 
185
            }
 
186
        }
 
187
 
 
188
      if (prop_name != NULL && prop_type != NULL)
 
189
        {
 
190
          type = migrate_default_gtype_from_string (prop_type);
 
191
 
 
192
          parser->path = g_slist_append (parser->path, g_strdup (prop_name));
 
193
 
 
194
          if (type == G_TYPE_INVALID)
 
195
            {
 
196
              g_set_error (error, G_MARKUP_ERROR_INVALID_CONTENT, G_MARKUP_ERROR,
 
197
                           "Property \"%s\" has invalid type \"%s\"",
 
198
                           prop_name, prop_type);
 
199
            }
 
200
          if (type == G_TYPE_BOXED)
 
201
            {
 
202
              parser->array = g_ptr_array_new ();
 
203
            }
 
204
          else if (type != G_TYPE_NONE && prop_value != NULL)
 
205
            {
 
206
              g_value_init (&value, type);
 
207
              migrate_default_set_value (&value, prop_value);
 
208
 
 
209
              prop_path = migrate_default_property_path (parser);
 
210
              xfconf_channel_set_property (parser->channel, prop_path, &value);
 
211
              g_free (prop_path);
 
212
 
 
213
              g_value_unset (&value);
 
214
            }
 
215
        }
 
216
      else
 
217
        {
 
218
          g_set_error (error, G_MARKUP_ERROR_INVALID_CONTENT, G_MARKUP_ERROR,
 
219
                       "Found property without name (%s), type (%s) or value (%s)",
 
220
                       prop_name, prop_type, prop_value);
 
221
        }
 
222
    }
 
223
  else if (strcmp (element_name, "value") == 0)
 
224
    {
 
225
      if (parser->array != NULL)
 
226
        {
 
227
          value_type = NULL;
 
228
          value_value = NULL;
 
229
 
 
230
          if (G_LIKELY (attribute_names != NULL))
 
231
            {
 
232
              for (i = 0; attribute_names[i] != NULL; i++)
 
233
                {
 
234
                  if (strcmp (attribute_names[i], "type") == 0)
 
235
                    value_type = attribute_values[i];
 
236
                  else if (strcmp (attribute_names[i], "value") == 0)
 
237
                    value_value = attribute_values[i];
 
238
                }
 
239
            }
 
240
 
 
241
          if (value_type != NULL && value_value != NULL)
 
242
            {
 
243
              type = migrate_default_gtype_from_string (value_type);
 
244
 
 
245
              if (type != G_TYPE_INVALID && type != G_TYPE_NONE && type != G_TYPE_BOXED)
 
246
                {
 
247
                  value2 = g_new0 (GValue, 1);
 
248
                  g_value_init (value2, type);
 
249
 
 
250
                  migrate_default_set_value (value2, value_value);
 
251
 
 
252
                  g_ptr_array_add (parser->array, value2);
 
253
                }
 
254
              else
 
255
                {
 
256
                  g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
 
257
                               "Found value has unknown type \"%s\"", value_type);
 
258
                }
 
259
            }
 
260
          else
 
261
            {
 
262
              g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
 
263
                           "Found value element with missing type (%s) or value (%s)",
 
264
                           value_type, value_value);
 
265
            }
 
266
        }
 
267
      else
 
268
        {
 
269
          g_set_error_literal (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
 
270
                               "Found value element without an array property");
 
271
        }
 
272
    }
 
273
  else
 
274
    {
 
275
      g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
 
276
                   "Unknown start element \"%s\"", element_name);
 
277
    }
 
278
}
 
279
 
 
280
 
 
281
 
 
282
static void
 
283
migrate_default_end_element_handler (GMarkupParseContext  *context,
 
284
                                     const gchar          *element_name,
 
285
                                     gpointer              user_data,
 
286
                                     GError              **error)
 
287
{
 
288
  ConfigParser *parser = user_data;
 
289
  GSList       *li;
 
290
  gchar        *prop_path;
 
291
 
 
292
  if (strcmp (element_name, "channel") == 0)
 
293
    {
 
294
      if (G_LIKELY (parser->channel != NULL))
 
295
        {
 
296
          g_object_unref (G_OBJECT (parser->channel));
 
297
          parser->channel = NULL;
 
298
        }
 
299
 
 
300
     if (parser->path != NULL)
 
301
       {
 
302
         g_set_error_literal (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
 
303
                              "Property path still contains items");
 
304
       }
 
305
    }
 
306
  else if (strcmp (element_name, "property") == 0)
 
307
    {
 
308
      if (parser->array != NULL)
 
309
        {
 
310
          prop_path = migrate_default_property_path (parser);
 
311
          xfconf_channel_set_arrayv (parser->channel, prop_path, parser->array);
 
312
          g_free (prop_path);
 
313
 
 
314
          xfconf_array_free (parser->array);
 
315
          parser->array = NULL;
 
316
        }
 
317
 
 
318
      li = g_slist_last (parser->path);
 
319
      if (li != NULL)
 
320
        {
 
321
          g_free (li->data);
 
322
          parser->path = g_slist_delete_link (parser->path, li);
 
323
        }
 
324
      else
 
325
        {
 
326
          g_set_error_literal (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
 
327
                              "Element could no be popped from the path");
 
328
        }
 
329
    }
 
330
  else if (strcmp (element_name, "value") == 0)
 
331
    {
 
332
      /* nothing to do */
 
333
    }
 
334
  else
 
335
    {
 
336
      g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
 
337
                   "Unknown end element \"%s\"", element_name);
 
338
    }
 
339
}
 
340
 
 
341
 
 
342
 
 
343
static GMarkupParser markup_parser =
 
344
{
 
345
  migrate_default_start_element_handler,
 
346
  migrate_default_end_element_handler,
 
347
  NULL,
 
348
  NULL,
 
349
  NULL
 
350
};
 
351
 
 
352
 
 
353
 
 
354
gboolean
 
355
migrate_default (const gchar    *filename,
 
356
                 GError        **error)
 
357
{
 
358
  gsize                length;
 
359
  gchar               *contents;
 
360
  GMarkupParseContext *context;
 
361
  ConfigParser        *parser;
 
362
  gboolean             succeed = FALSE;
 
363
 
 
364
  g_return_val_if_fail (filename != NULL, FALSE);
 
365
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
366
 
 
367
  if (!g_file_get_contents (filename, &contents, &length, error))
 
368
    return FALSE;
 
369
 
 
370
  parser = g_slice_new0 (ConfigParser);
 
371
  parser->path = NULL;
 
372
 
 
373
  context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);
 
374
 
 
375
  if (g_markup_parse_context_parse (context, contents, length, error))
 
376
    {
 
377
      /* check if the entire file is parsed */
 
378
      if (g_markup_parse_context_end_parse (context, error))
 
379
        succeed = TRUE;
 
380
    }
 
381
 
 
382
  g_free (contents);
 
383
  g_markup_parse_context_free (context);
 
384
  g_slice_free (ConfigParser, parser);
 
385
 
 
386
  return succeed;
 
387
}