~ubuntu-branches/ubuntu/precise/xfce4-panel/precise

« back to all changes in this revision

Viewing changes to panel/panel-module.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc
  • Date: 2010-12-04 15:45:53 UTC
  • mto: (4.1.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 50.
  • Revision ID: james.westby@ubuntu.com-20101204154553-f452gq02eiksf09f
Tags: upstream-4.7.5
ImportĀ upstreamĀ versionĀ 4.7.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2008-2009 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 Foundation; 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 Foundation, 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
#include <gmodule.h>
 
24
#include <exo/exo.h>
 
25
#include <glib/gstdio.h>
 
26
#include <libxfce4util/libxfce4util.h>
 
27
 
 
28
#include <common/panel-private.h>
 
29
#include <libxfce4panel/libxfce4panel.h>
 
30
#include <libxfce4panel/xfce-panel-plugin-provider.h>
 
31
 
 
32
#include <panel/panel-module.h>
 
33
#include <panel/panel-module-factory.h>
 
34
#include <panel/panel-plugin-external-wrapper.h>
 
35
#include <panel/panel-plugin-external-46.h>
 
36
 
 
37
#define PANEL_PLUGINS_LIB_DIR (LIBDIR G_DIR_SEPARATOR_S "panel" G_DIR_SEPARATOR_S "plugins")
 
38
#define PANEL_PLUGINS_LIB_DIR_OLD (LIBDIR G_DIR_SEPARATOR_S "panel-plugins")
 
39
 
 
40
 
 
41
typedef enum _PanelModuleRunMode PanelModuleRunMode;
 
42
typedef enum _PanelModuleUnique  PanelModuleUnique;
 
43
 
 
44
 
 
45
 
 
46
static void      panel_module_dispose          (GObject          *object);
 
47
static void      panel_module_finalize         (GObject          *object);
 
48
static gboolean  panel_module_load             (GTypeModule      *type_module);
 
49
static void      panel_module_unload           (GTypeModule      *type_module);
 
50
static void      panel_module_plugin_destroyed (gpointer          user_data,
 
51
                                                GObject          *where_the_plugin_was);
 
52
 
 
53
 
 
54
 
 
55
struct _PanelModuleClass
 
56
{
 
57
  GTypeModuleClass __parent__;
 
58
};
 
59
 
 
60
enum _PanelModuleRunMode
 
61
{
 
62
  UNKNOWN,    /* Unset */
 
63
  INTERNAL,   /* plugin library will be loaded in the panel */
 
64
  WRAPPER,    /* external library with comunication through PanelPluginExternal */
 
65
  EXTERNAL_46 /* external executable with comunication through PanelPluginExternal46 */
 
66
};
 
67
 
 
68
enum _PanelModuleUnique
 
69
{
 
70
  UNIQUE_FALSE,
 
71
  UNIQUE_TRUE,
 
72
  UNIQUE_SCREEN
 
73
};
 
74
 
 
75
struct _PanelModule
 
76
{
 
77
  GTypeModule __parent__;
 
78
 
 
79
  /* module type */
 
80
  PanelModuleRunMode   mode;
 
81
 
 
82
  /* filename to the library or executable
 
83
   * for an old 4.6 plugin */
 
84
  gchar               *filename;
 
85
 
 
86
  /* plugin information from the desktop file */
 
87
  gchar               *display_name;
 
88
  gchar               *comment;
 
89
  gchar               *icon_name;
 
90
 
 
91
  /* unique handling */
 
92
  guint                use_count;
 
93
  PanelModuleUnique    unique_mode;
 
94
 
 
95
  /* module location (null for 4.6 plugins) */
 
96
  GModule             *library;
 
97
 
 
98
  /* for non-gobject plugin */
 
99
  PluginConstructFunc  construct_func;
 
100
 
 
101
  /* for gobject plugins */
 
102
  GType                plugin_type;
 
103
};
 
104
 
 
105
 
 
106
 
 
107
static GQuark module_quark = 0;
 
108
 
 
109
 
 
110
 
 
111
G_DEFINE_TYPE (PanelModule, panel_module, G_TYPE_TYPE_MODULE)
 
112
 
 
113
 
 
114
 
 
115
static void
 
116
panel_module_class_init (PanelModuleClass *klass)
 
117
{
 
118
  GObjectClass     *gobject_class;
 
119
  GTypeModuleClass *gtype_module_class;
 
120
 
 
121
  gobject_class = G_OBJECT_CLASS (klass);
 
122
  gobject_class->dispose = panel_module_dispose;
 
123
  gobject_class->finalize = panel_module_finalize;
 
124
 
 
125
  gtype_module_class = G_TYPE_MODULE_CLASS (klass);
 
126
  gtype_module_class->load = panel_module_load;
 
127
  gtype_module_class->unload = panel_module_unload;
 
128
 
 
129
  module_quark = g_quark_from_static_string ("panel-module");
 
130
}
 
131
 
 
132
 
 
133
 
 
134
static void
 
135
panel_module_init (PanelModule *module)
 
136
{
 
137
  module->mode = UNKNOWN;
 
138
  module->filename = NULL;
 
139
  module->display_name = NULL;
 
140
  module->comment = NULL;
 
141
  module->icon_name = NULL;
 
142
  module->use_count = 0;
 
143
  module->unique_mode = UNIQUE_FALSE;
 
144
  module->library = NULL;
 
145
  module->construct_func = NULL;
 
146
  module->plugin_type = G_TYPE_NONE;
 
147
}
 
148
 
 
149
 
 
150
 
 
151
static void
 
152
panel_module_dispose (GObject *object)
 
153
{
 
154
  /* Do nothing to avoid problems with dispose in GTypeModule when
 
155
   * types are registered.
 
156
   *
 
157
   * For us this is not a problem since the modules are released when
 
158
   * everything is destroyed. So we really want that last unref before
 
159
   * closing the application. */
 
160
}
 
161
 
 
162
 
 
163
 
 
164
static void
 
165
panel_module_finalize (GObject *object)
 
166
{
 
167
  PanelModule *module = PANEL_MODULE (object);
 
168
 
 
169
  g_free (module->filename);
 
170
  g_free (module->display_name);
 
171
  g_free (module->comment);
 
172
  g_free (module->icon_name);
 
173
 
 
174
  (*G_OBJECT_CLASS (panel_module_parent_class)->finalize) (object);
 
175
}
 
176
 
 
177
 
 
178
 
 
179
static gboolean
 
180
panel_module_load (GTypeModule *type_module)
 
181
{
 
182
  PanelModule    *module = PANEL_MODULE (type_module);
 
183
  PluginInitFunc  init_func;
 
184
  gboolean        make_resident = TRUE;
 
185
  gpointer        foo;
 
186
 
 
187
  panel_return_val_if_fail (PANEL_IS_MODULE (module), FALSE);
 
188
  panel_return_val_if_fail (G_IS_TYPE_MODULE (module), FALSE);
 
189
  panel_return_val_if_fail (module->mode == INTERNAL, FALSE);
 
190
  panel_return_val_if_fail (module->library == NULL, FALSE);
 
191
  panel_return_val_if_fail (module->plugin_type == G_TYPE_NONE, FALSE);
 
192
  panel_return_val_if_fail (module->construct_func == NULL, FALSE);
 
193
 
 
194
  /* open the module */
 
195
  module->library = g_module_open (module->filename, G_MODULE_BIND_LOCAL);
 
196
  if (G_UNLIKELY (module->library == NULL))
 
197
    {
 
198
      g_critical ("Failed to load module \"%s\": %s.",
 
199
                  module->filename,
 
200
                  g_module_error ());
 
201
      return FALSE;
 
202
    }
 
203
 
 
204
    /* check if there is a preinit function */
 
205
  if (g_module_symbol (module->library, "xfce_panel_module_preinit", &foo))
 
206
    {
 
207
      /* large message, but technically never shown to normal users */
 
208
      g_warning ("The plugin \"%s\" is marked as internal in the desktop file, "
 
209
                 "but the developer has defined an pre-init function, which is "
 
210
                 "not supported for internal plugins. " PACKAGE_NAME " will force "
 
211
                 "the plugin to run external.", module->filename);
 
212
 
 
213
      panel_module_unload (type_module);
 
214
 
 
215
      /* from now on, run this plugin in a wrapper */
 
216
      module->mode = WRAPPER;
 
217
 
 
218
      return FALSE;
 
219
    }
 
220
 
 
221
  /* try to link the contruct function */
 
222
  if (g_module_symbol (module->library, "xfce_panel_module_init", (gpointer) &init_func))
 
223
    {
 
224
      /* initialize the plugin */
 
225
      module->plugin_type = init_func (type_module, &make_resident);
 
226
 
 
227
      /* whether to make this plugin resident or not */
 
228
      if (make_resident)
 
229
        g_module_make_resident (module->library);
 
230
    }
 
231
  else if (!g_module_symbol (module->library, "xfce_panel_module_construct",
 
232
                             (gpointer) &module->construct_func))
 
233
    {
 
234
      g_critical ("Module \"%s\" lacks a plugin register function.",
 
235
                  module->filename);
 
236
 
 
237
      panel_module_unload (type_module);
 
238
 
 
239
      return FALSE;
 
240
    }
 
241
 
 
242
  return TRUE;
 
243
}
 
244
 
 
245
 
 
246
 
 
247
static void
 
248
panel_module_unload (GTypeModule *type_module)
 
249
{
 
250
  PanelModule *module = PANEL_MODULE (type_module);
 
251
 
 
252
  panel_return_if_fail (PANEL_IS_MODULE (module));
 
253
  panel_return_if_fail (G_IS_TYPE_MODULE (module));
 
254
  panel_return_if_fail (module->mode == INTERNAL);
 
255
  panel_return_if_fail (module->library != NULL);
 
256
  panel_return_if_fail (module->plugin_type != G_TYPE_NONE
 
257
                        || module->construct_func != NULL);
 
258
 
 
259
  g_module_close (module->library);
 
260
 
 
261
  /* reset plugin state */
 
262
  module->library = NULL;
 
263
  module->construct_func = NULL;
 
264
  module->plugin_type = G_TYPE_NONE;
 
265
}
 
266
 
 
267
 
 
268
 
 
269
static void
 
270
panel_module_plugin_destroyed (gpointer  user_data,
 
271
                               GObject  *where_the_plugin_was)
 
272
{
 
273
  PanelModule *module = PANEL_MODULE (user_data);
 
274
 
 
275
  panel_return_if_fail (PANEL_IS_MODULE (module));
 
276
  panel_return_if_fail (G_IS_TYPE_MODULE (module));
 
277
  panel_return_if_fail (module->use_count > 0);
 
278
 
 
279
  /* decrease counter */
 
280
  module->use_count--;
 
281
 
 
282
  /* unuse the library if the plugin runs internal */
 
283
  if (module->mode == INTERNAL)
 
284
    g_type_module_unuse (G_TYPE_MODULE (module));
 
285
 
 
286
  /* emit signal unique signal in the factory */
 
287
  if (module->unique_mode != UNIQUE_FALSE)
 
288
    panel_module_factory_emit_unique_changed (module);
 
289
}
 
290
 
 
291
 
 
292
 
 
293
PanelModule *
 
294
panel_module_new_from_desktop_file (const gchar *filename,
 
295
                                    const gchar *name,
 
296
                                    gboolean     force_external)
 
297
{
 
298
  PanelModule *module = NULL;
 
299
  XfceRc      *rc;
 
300
  const gchar *module_name;
 
301
  gchar       *path;
 
302
  const gchar *module_exec;
 
303
  const gchar *module_unique;
 
304
  gboolean     found;
 
305
 
 
306
  panel_return_val_if_fail (!exo_str_is_empty (filename), NULL);
 
307
  panel_return_val_if_fail (!exo_str_is_empty (name), NULL);
 
308
 
 
309
  rc = xfce_rc_simple_open (filename, TRUE);
 
310
  if (G_UNLIKELY (rc == NULL))
 
311
    {
 
312
      g_critical ("Plugin %s: Unable to read from desktop file \"%s\"",
 
313
                  name, filename);
 
314
      return NULL;
 
315
    }
 
316
 
 
317
  if (!xfce_rc_has_group (rc, "Xfce Panel"))
 
318
    {
 
319
      g_critical ("Plugin %s: Desktop file \"%s\" has no "
 
320
                  "\"Xfce Panel\" group", name, filename);
 
321
      xfce_rc_close (rc);
 
322
      return NULL;
 
323
    }
 
324
 
 
325
  xfce_rc_set_group (rc, "Xfce Panel");
 
326
 
 
327
  /* read module location from the desktop file */
 
328
  module_name = xfce_rc_read_entry_untranslated (rc, "X-XFCE-Module", NULL);
 
329
  if (G_LIKELY (module_name != NULL))
 
330
    {
 
331
#ifndef NDEBUG
 
332
      if (xfce_rc_has_entry (rc, "X-XFCE-Module-Path"))
 
333
        {
 
334
          /* show a messsage if the old module path key still exists */
 
335
          g_message ("Plugin %s: The \"X-XFCE-Module-Path\" key is "
 
336
                     "ignored in \"%s\", the panel will look for the "
 
337
                     "module in %s. See bug #5455 why this decision was made",
 
338
                     name, filename, PANEL_PLUGINS_LIB_DIR);
 
339
        }
 
340
#endif
 
341
 
 
342
      path = g_module_build_path (PANEL_PLUGINS_LIB_DIR, module_name);
 
343
      found = g_file_test (path, G_FILE_TEST_EXISTS);
 
344
 
 
345
      if (!found)
 
346
        {
 
347
          /* deprecated location for module plugin directories */
 
348
          g_free (path);
 
349
          path = g_module_build_path (PANEL_PLUGINS_LIB_DIR_OLD, module_name);
 
350
          found = g_file_test (path, G_FILE_TEST_EXISTS);
 
351
        }
 
352
 
 
353
      if (G_LIKELY (found))
 
354
        {
 
355
          /* create new module */
 
356
          module = g_object_new (PANEL_TYPE_MODULE, NULL);
 
357
          module->filename = path;
 
358
 
 
359
          /* run mode of the module, by default everything runs in
 
360
           * the wrapper, unless defined otherwise */
 
361
          if (force_external || !xfce_rc_read_bool_entry (rc, "X-XFCE-Internal", FALSE))
 
362
            module->mode = WRAPPER;
 
363
          else
 
364
            module->mode = INTERNAL;
 
365
        }
 
366
      else
 
367
        {
 
368
          g_critical ("Plugin %s: There was no module found at \"%s\"",
 
369
                      name, path);
 
370
          g_free (path);
 
371
        }
 
372
    }
 
373
  else
 
374
    {
 
375
      /* yeah, we support ancient shizzle too... */
 
376
      module_exec = xfce_rc_read_entry_untranslated (rc, "X-XFCE-Exec", NULL);
 
377
      if (module_exec != NULL
 
378
          && g_path_is_absolute (module_exec)
 
379
          && g_file_test (module_exec, G_FILE_TEST_EXISTS))
 
380
        {
 
381
          module = g_object_new (PANEL_TYPE_MODULE, NULL);
 
382
          module->filename = g_strdup (module_exec);
 
383
          module->mode = EXTERNAL_46;
 
384
        }
 
385
      else
 
386
        {
 
387
          g_critical ("Plugin %s: There was no executable found at \"%s\"",
 
388
                      name, module_exec);
 
389
        }
 
390
    }
 
391
 
 
392
  if (G_LIKELY (module != NULL))
 
393
    {
 
394
      g_type_module_set_name (G_TYPE_MODULE (module), name);
 
395
      panel_assert (module->mode != UNKNOWN);
 
396
 
 
397
      /* read the remaining information */
 
398
      module->display_name = g_strdup (xfce_rc_read_entry (rc, "Name", name));
 
399
      module->comment = g_strdup (xfce_rc_read_entry (rc, "Comment", NULL));
 
400
      module->icon_name = g_strdup (xfce_rc_read_entry_untranslated (rc, "Icon", NULL));
 
401
 
 
402
      module_unique = xfce_rc_read_entry (rc, "X-XFCE-Unique", NULL);
 
403
      if (G_LIKELY (module_unique == NULL))
 
404
        module->unique_mode = UNIQUE_FALSE;
 
405
      else if (strcasecmp (module_unique, "screen") == 0)
 
406
        module->unique_mode = UNIQUE_SCREEN;
 
407
      else if (strcasecmp (module_unique, "true") == 0)
 
408
        module->unique_mode = UNIQUE_TRUE;
 
409
      else
 
410
        module->unique_mode = UNIQUE_FALSE;
 
411
    }
 
412
 
 
413
  xfce_rc_close (rc);
 
414
 
 
415
  return module;
 
416
}
 
417
 
 
418
 
 
419
 
 
420
GtkWidget *
 
421
panel_module_new_plugin (PanelModule  *module,
 
422
                         GdkScreen    *screen,
 
423
                         gint          unique_id,
 
424
                         gchar       **arguments)
 
425
{
 
426
  GtkWidget *plugin = NULL;
 
427
 
 
428
  panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
 
429
  panel_return_val_if_fail (G_IS_TYPE_MODULE (module), NULL);
 
430
  panel_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
 
431
  panel_return_val_if_fail (unique_id != -1, NULL);
 
432
  panel_return_val_if_fail (module->mode != UNKNOWN, NULL);
 
433
 
 
434
  /* return null if the module is not usable (unique and already used) */
 
435
  if (G_UNLIKELY (!panel_module_is_usable (module, screen)))
 
436
    return NULL;
 
437
 
 
438
  switch (module->mode)
 
439
    {
 
440
    case INTERNAL:
 
441
      if (g_type_module_use (G_TYPE_MODULE (module)))
 
442
        {
 
443
          if (module->plugin_type != G_TYPE_NONE)
 
444
            {
 
445
              /* plugin is build as an object, to use its gtype */
 
446
              plugin = g_object_new (module->plugin_type,
 
447
                                     "name", panel_module_get_name (module),
 
448
                                     "unique-id", unique_id,
 
449
                                     "display-name", module->display_name,
 
450
                                     "comment", module->comment,
 
451
                                     "arguments", arguments,
 
452
                                     NULL);
 
453
            }
 
454
          else if (module->construct_func != NULL)
 
455
            {
 
456
              /* create plugin using the 'old style' construct function */
 
457
              plugin = (*module->construct_func) (panel_module_get_name (module),
 
458
                                                  unique_id,
 
459
                                                  module->display_name,
 
460
                                                  module->comment,
 
461
                                                  arguments,
 
462
                                                  screen);
 
463
            }
 
464
 
 
465
          if (G_LIKELY (plugin != NULL))
 
466
            break;
 
467
          else
 
468
            g_type_module_unuse (G_TYPE_MODULE (module));
 
469
        }
 
470
 
 
471
      /* fall-through (make wrapper plugin), probably a plugin with
 
472
       * preinit_func which is not supported for internal plugins */
 
473
 
 
474
    case WRAPPER:
 
475
      plugin = panel_plugin_external_wrapper_new (module, unique_id, arguments);
 
476
      break;
 
477
 
 
478
    case EXTERNAL_46:
 
479
      plugin = panel_plugin_external_46_new (module, unique_id, arguments);
 
480
      break;
 
481
 
 
482
    default:
 
483
      panel_assert_not_reached ();
 
484
      break;
 
485
    }
 
486
 
 
487
  if (G_LIKELY (plugin != NULL))
 
488
    {
 
489
      /* increase count */
 
490
      module->use_count++;
 
491
 
 
492
      /* handle module use count and unloading */
 
493
      g_object_weak_ref (G_OBJECT (plugin),
 
494
          panel_module_plugin_destroyed, module);
 
495
 
 
496
      /* add link to the module */
 
497
      g_object_set_qdata (G_OBJECT (plugin), module_quark, module);
 
498
    }
 
499
 
 
500
  return plugin;
 
501
}
 
502
 
 
503
 
 
504
 
 
505
const gchar *
 
506
panel_module_get_name (PanelModule *module)
 
507
{
 
508
  panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
 
509
  panel_return_val_if_fail (G_IS_TYPE_MODULE (module), NULL);
 
510
 
 
511
  return G_TYPE_MODULE (module)->name;
 
512
}
 
513
 
 
514
 
 
515
 
 
516
const gchar *
 
517
panel_module_get_filename (PanelModule *module)
 
518
{
 
519
  panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
 
520
  panel_return_val_if_fail (G_IS_TYPE_MODULE (module), NULL);
 
521
 
 
522
  return module->filename;
 
523
}
 
524
 
 
525
 
 
526
 
 
527
const gchar *
 
528
panel_module_get_display_name (PanelModule *module)
 
529
{
 
530
  panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
 
531
  panel_return_val_if_fail (G_IS_TYPE_MODULE (module), NULL);
 
532
  panel_return_val_if_fail (module->display_name == NULL
 
533
                            || g_utf8_validate (module->display_name, -1, NULL), NULL);
 
534
 
 
535
  return module->display_name;
 
536
}
 
537
 
 
538
 
 
539
 
 
540
const gchar *
 
541
panel_module_get_comment (PanelModule *module)
 
542
{
 
543
  panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
 
544
  panel_return_val_if_fail (module->comment == NULL
 
545
                            || g_utf8_validate (module->comment, -1, NULL), NULL);
 
546
 
 
547
  return module->comment;
 
548
}
 
549
 
 
550
 
 
551
 
 
552
const gchar *
 
553
panel_module_get_icon_name (PanelModule *module)
 
554
{
 
555
  panel_return_val_if_fail (PANEL_IS_MODULE (module), NULL);
 
556
  panel_return_val_if_fail (module->icon_name == NULL
 
557
                            || g_utf8_validate (module->icon_name, -1, NULL), NULL);
 
558
 
 
559
  return module->icon_name;
 
560
}
 
561
 
 
562
 
 
563
 
 
564
PanelModule *
 
565
panel_module_get_from_plugin_provider (XfcePanelPluginProvider *provider)
 
566
{
 
567
  panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), NULL);
 
568
 
 
569
  /* return the panel module */
 
570
  return g_object_get_qdata (G_OBJECT (provider), module_quark);
 
571
}
 
572
 
 
573
 
 
574
 
 
575
gboolean
 
576
panel_module_is_valid (PanelModule *module)
 
577
{
 
578
  panel_return_val_if_fail (PANEL_IS_MODULE (module), FALSE);
 
579
 
 
580
  return g_file_test (module->filename, G_FILE_TEST_EXISTS);
 
581
}
 
582
 
 
583
 
 
584
 
 
585
gboolean
 
586
panel_module_is_unique (PanelModule *module)
 
587
{
 
588
  panel_return_val_if_fail (PANEL_IS_MODULE (module), FALSE);
 
589
 
 
590
  return module->unique_mode != UNIQUE_FALSE;
 
591
}
 
592
 
 
593
 
 
594
 
 
595
gboolean
 
596
panel_module_is_usable (PanelModule *module,
 
597
                        GdkScreen   *screen)
 
598
{
 
599
  PanelModuleFactory *factory;
 
600
  GSList             *plugins, *li;
 
601
  gboolean            usable = TRUE;
 
602
 
 
603
  panel_return_val_if_fail (PANEL_IS_MODULE (module), FALSE);
 
604
  panel_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
 
605
 
 
606
  if (module->use_count > 0
 
607
      && module->unique_mode == UNIQUE_TRUE)
 
608
    return FALSE;
 
609
 
 
610
  if (module->use_count > 0
 
611
      && module->unique_mode == UNIQUE_SCREEN)
 
612
    {
 
613
      factory = panel_module_factory_get ();
 
614
      plugins = panel_module_factory_get_plugins (factory, panel_module_get_name (module));
 
615
 
 
616
      /* search existing plugins if one of them runs on this screen */
 
617
      for (li = plugins; usable && li != NULL; li = li->next)
 
618
        if (screen == gtk_widget_get_screen (GTK_WIDGET (li->data)))
 
619
          usable = FALSE;
 
620
 
 
621
      g_slist_free (plugins);
 
622
      g_object_unref (G_OBJECT (factory));
 
623
    }
 
624
 
 
625
  return usable;
 
626
}