~ubuntu-branches/ubuntu/maverick/cairo-dock/maverick

« back to all changes in this revision

Viewing changes to src/cairo-dock-modules.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100809232612-yp4c6ig3jt1bzpdv
Tags: 2.2.0~0beta4-0ubuntu1
* New Upstream Version (LP: #614624)
* Fixed a few bugs on LP:
 - LP: #518453: Dock appears under all windows
                 (Compiz - fullscreen window)
 - LP: #521369: Separator are not removed when closing
                 grouped windows
 - LP: #521762: Some sentences are not correct
 - LP: #526466: Icons of apps with same class shouldn't
                 be stacked by default
 - LP: #535083: Dialogues looks ugly when a lot of them
                 appears at the same time
 - More details on the 'ChangeLog' file
* debian/rules:
 - Autotools has been replaced by CMake
 - Man pages are now included in the source code
* debian/copyright:
 - Updated with the new pathes and new files
* debian/control:
 - Autotools has been replaced by CMake
 - Added libcurl4-gnutls-dev as Build-deps
 - Bump Standard-Version to 3.9.1
* debian/cairo-dock-core.install:
 - Man pages are now included in the source code
 - All sonames are now installed into lib32 or lib64
* debian/cairo-dock-dev.install:
 - pkgconfig is now installed into lib32 or lib64

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
* This file is a part of the Cairo-Dock project
3
 
*
4
 
* Copyright : (C) see the 'copyright' file.
5
 
* E-mail    : see the 'copyright' file.
6
 
*
7
 
* This program is free software; you can redistribute it and/or
8
 
* modify it under the terms of the GNU General Public License
9
 
* as published by the Free Software Foundation; either version 3
10
 
* of the License, or (at your option) any later version.
11
 
*
12
 
* This program 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
15
 
* GNU General Public License for more details.
16
 
* You should have received a copy of the GNU General Public License
17
 
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
*/
19
 
 
20
 
#include <math.h>
21
 
#include <string.h>
22
 
#include <stdlib.h>
23
 
#include <gtk/gtk.h>
24
 
#include <glib/gstdio.h>
25
 
#include <glib/gi18n.h>
26
 
 
27
 
#include <cairo.h>
28
 
 
29
 
#include "cairo-dock-draw.h"
30
 
#include "cairo-dock-icons.h"
31
 
#include "cairo-dock-load.h"
32
 
#include "cairo-dock-config.h"
33
 
#include "cairo-dock-dock-factory.h"
34
 
#include "cairo-dock-dock-facility.h"
35
 
#include "cairo-dock-dock-manager.h"
36
 
#include "cairo-dock-keyfile-utilities.h"
37
 
#include "cairo-dock-log.h"
38
 
#include "cairo-dock-applet-factory.h"
39
 
#include "cairo-dock-desklet.h"
40
 
#include "cairo-dock-animations.h"
41
 
#include "cairo-dock-internal-icons.h"
42
 
#include "cairo-dock-dialogs.h"
43
 
#include "cairo-dock-file-manager.h"
44
 
#include "cairo-dock-callbacks.h"
45
 
#include "cairo-dock-container.h"
46
 
#include "cairo-dock-gui-manager.h"
47
 
#include "cairo-dock-internal-accessibility.h"
48
 
#include "cairo-dock-internal-position.h"
49
 
#include "cairo-dock-internal-system.h"
50
 
#include "cairo-dock-internal-taskbar.h"
51
 
#include "cairo-dock-internal-background.h"
52
 
#include "cairo-dock-internal-indicators.h"
53
 
#include "cairo-dock-internal-labels.h"
54
 
#include "cairo-dock-internal-desklets.h"
55
 
#include "cairo-dock-internal-dialogs.h"
56
 
#include "cairo-dock-internal-icons.h"
57
 
#include "cairo-dock-internal-views.h"
58
 
#include "cairo-dock-modules.h"
59
 
 
60
 
extern CairoDock *g_pMainDock;
61
 
extern gchar *g_cConfFile;
62
 
extern gchar *g_cCurrentThemePath;
63
 
extern gchar *g_cCairoDockDataDir;
64
 
extern int g_iMajorVersion, g_iMinorVersion, g_iMicroVersion;
65
 
extern gboolean g_bEasterEggs;
66
 
 
67
 
static GHashTable *s_hModuleTable = NULL;
68
 
static GHashTable *s_hInternalModuleTable = NULL;
69
 
static int s_iMaxOrder = 0;
70
 
static GList *s_AutoLoadedModules = NULL;
71
 
 
72
 
static void _entered_help_once (CairoDockModuleInstance *pInstance, GKeyFile *pKeyFile)
73
 
{
74
 
        gchar *cHelpDir = g_strdup_printf ("%s/.help", g_cCairoDockDataDir);
75
 
        gchar *cHelpHistory = g_strdup_printf ("%s/entered-once", cHelpDir);
76
 
        if (! g_file_test (cHelpDir, G_FILE_TEST_EXISTS))
77
 
        {
78
 
                if (g_mkdir (cHelpDir, 7*8*8+7*8+5) != 0)
79
 
                {
80
 
                        cd_warning ("couldn't create directory %s", cHelpDir);
81
 
                        return;
82
 
                }
83
 
        }
84
 
        if (! g_file_test (cHelpHistory, G_FILE_TEST_EXISTS))
85
 
        {
86
 
                g_file_set_contents (cHelpHistory,
87
 
                        "1",
88
 
                        -1,
89
 
                        NULL);
90
 
        }
91
 
        g_free (cHelpHistory);
92
 
        g_free (cHelpDir);
93
 
}
94
 
 
95
 
void cairo_dock_initialize_module_manager (const gchar *cModuleDirPath)
96
 
{
97
 
        if (s_hModuleTable == NULL)
98
 
                s_hModuleTable = g_hash_table_new_full (g_str_hash,
99
 
                        g_str_equal,
100
 
                        NULL,  // la cle est le nom du module, et pointe directement sur le champ 'cModuleName' du module.
101
 
                        (GDestroyNotify) cairo_dock_free_module);
102
 
        
103
 
        if (s_hInternalModuleTable == NULL)
104
 
        {
105
 
                s_hInternalModuleTable = g_hash_table_new_full (g_str_hash,
106
 
                        g_str_equal,
107
 
                        NULL,  // la cle est le nom du module, et pointe directement sur le champ 'cModuleName' du module.
108
 
                        (GDestroyNotify) NULL);  // ne sont jamais liberes.
109
 
                cairo_dock_preload_internal_modules (s_hInternalModuleTable);
110
 
        }
111
 
        
112
 
        if (cModuleDirPath != NULL && g_file_test (cModuleDirPath, G_FILE_TEST_IS_DIR))
113
 
        {
114
 
                GError *erreur = NULL;
115
 
                cairo_dock_preload_module_from_directory (cModuleDirPath, &erreur);
116
 
                if (erreur != NULL)
117
 
                {
118
 
                        cd_warning ("%s\n  no module will be available", erreur->message);
119
 
                        g_error_free (erreur);
120
 
                }
121
 
        }
122
 
        
123
 
        //\________________ ceci est un vilain hack ... mais je trouvais ca lourd de compiler un truc qui n'a aucun code, et puis comme ca on a l'aide meme sans les plug-ins.
124
 
        CairoDockModule *pHelpModule = g_new0 (CairoDockModule, 1);
125
 
        CairoDockVisitCard *pVisitCard = g_new0 (CairoDockVisitCard, 1);
126
 
        pHelpModule->pVisitCard = pVisitCard;
127
 
        pVisitCard->cModuleName = "Help";
128
 
        pVisitCard->cTitle = _("Help");
129
 
        pVisitCard->iMajorVersionNeeded = 2;
130
 
        pVisitCard->iMinorVersionNeeded = 0;
131
 
        pVisitCard->iMicroVersionNeeded = 0;
132
 
        pVisitCard->cPreviewFilePath = NULL;
133
 
        pVisitCard->cGettextDomain = NULL;
134
 
        pVisitCard->cDockVersionOnCompilation = CAIRO_DOCK_VERSION;
135
 
        pVisitCard->cUserDataDir = "help";
136
 
        pVisitCard->cShareDataDir = CAIRO_DOCK_SHARE_DATA_DIR;
137
 
        pVisitCard->cConfFileName = "help.conf";
138
 
        pVisitCard->cModuleVersion = "0.0.8";
139
 
        pVisitCard->iCategory = CAIRO_DOCK_CATEGORY_SYSTEM;
140
 
        pVisitCard->cIconFilePath = CAIRO_DOCK_SHARE_DATA_DIR"/icon-help.png";
141
 
        pVisitCard->iSizeOfConfig = 0;
142
 
        pVisitCard->iSizeOfData = 0;
143
 
        pVisitCard->cDescription = N_("A useful FAQ that contains also a lot of hints.\nLet the mouse over a sentence to make the hint dialog popups.");
144
 
        pVisitCard->cAuthor = "Fabounet";
145
 
        pHelpModule->pInterface = g_new0 (CairoDockModuleInterface, 1);
146
 
        pHelpModule->pInterface->load_custom_widget = _entered_help_once;
147
 
        g_hash_table_insert (s_hModuleTable, (gpointer)pHelpModule->pVisitCard->cModuleName, pHelpModule);
148
 
        cairo_dock_activate_module (pHelpModule, NULL);
149
 
        pHelpModule->fLastLoadingTime = time (NULL) + 1e7;  // pour ne pas qu'il soit desactive lors d'un reload general, car il n'est pas dans la liste des modules actifs du fichier de conf.
150
 
}
151
 
 
152
 
 
153
 
static gchar *cairo_dock_extract_default_module_name_from_path (gchar *cSoFilePath)
154
 
{
155
 
        gchar *ptr = g_strrstr (cSoFilePath, "/");
156
 
        if (ptr == NULL)
157
 
                ptr = cSoFilePath;
158
 
        else
159
 
                ptr ++;
160
 
        if (strncmp (ptr, "lib", 3) == 0)
161
 
                ptr += 3;
162
 
 
163
 
        if (strncmp (ptr, "cd-", 3) == 0)
164
 
                ptr += 3;
165
 
        else if (strncmp (ptr, "cd_", 3) == 0)
166
 
                ptr += 3;
167
 
 
168
 
        gchar *cModuleName = g_strdup (ptr);
169
 
 
170
 
        ptr = g_strrstr (cModuleName, ".so");
171
 
        if (ptr != NULL)
172
 
                *ptr = '\0';
173
 
 
174
 
        //ptr = cModuleName;
175
 
        //while ((ptr = g_strrstr (ptr, "-")) != NULL)
176
 
        //      *ptr = '_';
177
 
 
178
 
        return cModuleName;
179
 
}
180
 
 
181
 
gchar *cairo_dock_check_module_conf_file (CairoDockVisitCard *pVisitCard)
182
 
{
183
 
        if (pVisitCard->cConfFileName == NULL)
184
 
                return NULL;
185
 
        
186
 
        int r;
187
 
        gchar *cUserDataDirPath = g_strdup_printf ("%s/plug-ins/%s", g_cCurrentThemePath, pVisitCard->cUserDataDir);
188
 
        if (! g_file_test (cUserDataDirPath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
189
 
        {
190
 
                cd_message ("directory %s doesn't exist, it will be added.", cUserDataDirPath);
191
 
                
192
 
                gchar *command = g_strdup_printf ("mkdir -p %s", cUserDataDirPath);
193
 
                r = system (command);
194
 
                g_free (command);
195
 
        }
196
 
        
197
 
        gchar *cConfFilePath = g_strdup_printf ("%s/%s", cUserDataDirPath, pVisitCard->cConfFileName);
198
 
        if (! g_file_test (cConfFilePath, G_FILE_TEST_EXISTS))
199
 
        {
200
 
                cd_message ("no conf file %s, we will take the default one", cConfFilePath);
201
 
                gchar *command = g_strdup_printf ("cp %s/%s %s", pVisitCard->cShareDataDir, pVisitCard->cConfFileName, cConfFilePath);
202
 
                r = system (command);
203
 
                g_free (command);
204
 
        }
205
 
        
206
 
        if (! g_file_test (cConfFilePath, G_FILE_TEST_EXISTS))  // la copie ne s'est pas bien passee.
207
 
        {
208
 
                cd_warning ("couldn't copy %s/%s in %s; check permissions and file's existence", pVisitCard->cShareDataDir, pVisitCard->cConfFileName, cUserDataDirPath);
209
 
                g_free (cUserDataDirPath);
210
 
                g_free (cConfFilePath);
211
 
                return NULL;
212
 
        }
213
 
        
214
 
        g_free (cUserDataDirPath);
215
 
        return cConfFilePath;
216
 
}
217
 
 
218
 
void cairo_dock_free_visit_card (CairoDockVisitCard *pVisitCard)
219
 
{
220
 
        g_free (pVisitCard);  // toutes les chaines sont statiques.
221
 
}
222
 
 
223
 
static void cairo_dock_open_module (CairoDockModule *pCairoDockModule, GError **erreur)
224
 
{
225
 
        //\__________________ On ouvre le .so.
226
 
        GModule *module = g_module_open (pCairoDockModule->cSoFilePath, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
227
 
        if (!module)
228
 
        {
229
 
                g_set_error (erreur, 1, 1, "while opening module '%s' : (%s)", pCairoDockModule->cSoFilePath, g_module_error ());
230
 
                return ;
231
 
        }
232
 
        pCairoDockModule->pModule = module;
233
 
 
234
 
        //\__________________ On identifie le module.
235
 
        gboolean bSymbolFound;
236
 
        CairoDockModulePreInit function_pre_init = NULL;
237
 
        bSymbolFound = g_module_symbol (module, "pre_init", (gpointer) &function_pre_init);
238
 
        if (bSymbolFound && function_pre_init != NULL)
239
 
        {
240
 
                pCairoDockModule->pVisitCard = g_new0 (CairoDockVisitCard, 1);
241
 
                pCairoDockModule->pInterface = g_new0 (CairoDockModuleInterface, 1);
242
 
                gboolean bModuleLoaded = function_pre_init (pCairoDockModule->pVisitCard, pCairoDockModule->pInterface);
243
 
                if (! bModuleLoaded)
244
 
                {
245
 
                        cairo_dock_free_visit_card (pCairoDockModule->pVisitCard);
246
 
                        pCairoDockModule->pVisitCard = NULL;
247
 
                        cd_debug ("module '%s' has not been loaded", pCairoDockModule->cSoFilePath);  // peut arriver a xxx-integration.
248
 
                        return ;
249
 
                }
250
 
        }
251
 
        else
252
 
        {
253
 
                pCairoDockModule->pVisitCard = NULL;
254
 
                g_set_error (erreur, 1, 1, "this module ('%s') does not have the common entry point 'pre_init', it may be broken or icompatible with cairo-dock", pCairoDockModule->cSoFilePath);
255
 
                return ;
256
 
        }
257
 
        
258
 
        //\__________________ On verifie sa compatibilite.
259
 
        CairoDockVisitCard *pVisitCard = pCairoDockModule->pVisitCard;
260
 
        if (! g_bEasterEggs &&
261
 
                (pVisitCard->iMajorVersionNeeded > g_iMajorVersion || (pVisitCard->iMajorVersionNeeded == g_iMajorVersion && pVisitCard->iMinorVersionNeeded > g_iMinorVersion) || (pVisitCard->iMajorVersionNeeded == g_iMajorVersion && pVisitCard->iMinorVersionNeeded == g_iMinorVersion && pVisitCard->iMicroVersionNeeded > g_iMicroVersion)))
262
 
        {
263
 
                g_set_error (erreur, 1, 1, "this module ('%s') needs at least Cairo-Dock v%d.%d.%d, but Cairo-Dock is in v%d.%d.%d (%s)\n  It will be ignored", pCairoDockModule->cSoFilePath, pVisitCard->iMajorVersionNeeded, pVisitCard->iMinorVersionNeeded, pVisitCard->iMicroVersionNeeded, g_iMajorVersion, g_iMinorVersion, g_iMicroVersion, CAIRO_DOCK_VERSION);
264
 
                cairo_dock_free_visit_card (pCairoDockModule->pVisitCard);
265
 
                pCairoDockModule->pVisitCard = NULL;
266
 
                return ;
267
 
        }
268
 
        if (! g_bEasterEggs &&
269
 
                pVisitCard->cDockVersionOnCompilation != NULL && strcmp (pVisitCard->cDockVersionOnCompilation, CAIRO_DOCK_VERSION) != 0)  // separation des versions en easter egg.
270
 
        {
271
 
                g_set_error (erreur, 1, 1, "this module ('%s') was compiled with Cairo-Dock v%s, but Cairo-Dock is in v%s\n  It will be ignored", pCairoDockModule->cSoFilePath, pVisitCard->cDockVersionOnCompilation, CAIRO_DOCK_VERSION);
272
 
                cairo_dock_free_visit_card (pCairoDockModule->pVisitCard);
273
 
                pCairoDockModule->pVisitCard = NULL;
274
 
                return ;
275
 
        }
276
 
 
277
 
        if (pVisitCard->cModuleName == NULL)
278
 
                pVisitCard->cModuleName = cairo_dock_extract_default_module_name_from_path (pCairoDockModule->cSoFilePath);
279
 
 
280
 
        if (cairo_dock_module_is_auto_loaded (pCairoDockModule))  // c'est un module qui soit ne peut etre activer et/ou desactiver, soit s'est lie a un module interne; on l'activera donc automatiquement.
281
 
        {
282
 
                s_AutoLoadedModules = g_list_prepend (s_AutoLoadedModules, pCairoDockModule);
283
 
        }
284
 
}
285
 
 
286
 
static void cairo_dock_close_module (CairoDockModule *module)
287
 
{
288
 
        if (module->pModule)
289
 
                g_module_close (module->pModule);
290
 
        
291
 
        g_free (module->pInterface);
292
 
        module->pInterface = NULL;
293
 
        
294
 
        cairo_dock_free_visit_card (module->pVisitCard);
295
 
        module->pVisitCard = NULL;
296
 
        
297
 
        g_free (module->cConfFilePath);
298
 
        module->cConfFilePath = NULL;
299
 
}
300
 
 
301
 
 
302
 
 
303
 
CairoDockModule * cairo_dock_load_module (gchar *cSoFilePath, GError **erreur)  // cSoFilePath vers un fichier de la forme 'libtruc.so'. Le module est rajoute dans la table des modules.
304
 
{
305
 
        //g_print ("%s (%s)\n", __func__, cSoFilePath);
306
 
        if (cSoFilePath == NULL)  // g_module_open () plante si 'cSoFilePath' est NULL.
307
 
        {
308
 
                g_set_error (erreur, 1, 1, "%s () : no such module", __func__);
309
 
                return NULL;
310
 
        }
311
 
 
312
 
        CairoDockModule *pCairoDockModule = g_new0 (CairoDockModule, 1);
313
 
        pCairoDockModule->cSoFilePath = g_strdup (cSoFilePath);
314
 
 
315
 
        GError *tmp_erreur = NULL;
316
 
        cairo_dock_open_module (pCairoDockModule, &tmp_erreur);
317
 
        if (tmp_erreur != NULL)
318
 
        {
319
 
                g_propagate_error (erreur, tmp_erreur);
320
 
                g_free (pCairoDockModule);
321
 
                return NULL;
322
 
        }
323
 
 
324
 
        if (s_hModuleTable != NULL && pCairoDockModule->pVisitCard != NULL)
325
 
                g_hash_table_insert (s_hModuleTable, (gpointer)pCairoDockModule->pVisitCard->cModuleName, pCairoDockModule);
326
 
 
327
 
        return pCairoDockModule;
328
 
}
329
 
 
330
 
gboolean cairo_dock_register_module (CairoDockModule *pModule)
331
 
{
332
 
        g_return_val_if_fail (s_hModuleTable != NULL && pModule->pVisitCard != NULL && pModule->pVisitCard->cModuleName != NULL, FALSE);
333
 
        
334
 
        if (g_hash_table_lookup (s_hModuleTable, pModule->pVisitCard->cModuleName) != NULL)
335
 
        {
336
 
                cd_warning ("a module with the name '%s' is already registered", pModule->pVisitCard->cModuleName);
337
 
                return FALSE;
338
 
        }
339
 
        
340
 
        if (pModule->pVisitCard->cDockVersionOnCompilation == NULL)
341
 
                pModule->pVisitCard->cDockVersionOnCompilation = CAIRO_DOCK_VERSION;
342
 
        g_hash_table_insert (s_hModuleTable, (gpointer)pModule->pVisitCard->cModuleName, pModule);
343
 
        return TRUE;
344
 
}
345
 
 
346
 
 
347
 
void cairo_dock_preload_module_from_directory (const gchar *cModuleDirPath, GError **erreur)
348
 
{
349
 
        cd_message ("%s (%s)", __func__, cModuleDirPath);
350
 
        GError *tmp_erreur = NULL;
351
 
        GDir *dir = g_dir_open (cModuleDirPath, 0, &tmp_erreur);
352
 
        if (tmp_erreur != NULL)
353
 
        {
354
 
                g_propagate_error (erreur, tmp_erreur);
355
 
                return ;
356
 
        }
357
 
 
358
 
        CairoDockModule *pModule;
359
 
        const gchar *cFileName;
360
 
        GString *sFilePath = g_string_new ("");
361
 
        do
362
 
        {
363
 
                cFileName = g_dir_read_name (dir);
364
 
                if (cFileName == NULL)
365
 
                        break ;
366
 
                
367
 
                if (g_str_has_suffix (cFileName, ".so"))
368
 
                {
369
 
                        g_string_printf (sFilePath, "%s/%s", cModuleDirPath, cFileName);
370
 
                        pModule = cairo_dock_load_module (sFilePath->str, &tmp_erreur);
371
 
                        if (tmp_erreur != NULL)
372
 
                        {
373
 
                                cd_warning (tmp_erreur->message);
374
 
                                g_error_free (tmp_erreur);
375
 
                                tmp_erreur = NULL;
376
 
                        }
377
 
                }
378
 
        }
379
 
        while (1);
380
 
        g_string_free (sFilePath, TRUE);
381
 
        g_dir_close (dir);
382
 
}
383
 
 
384
 
 
385
 
 
386
 
void cairo_dock_activate_modules_from_list (gchar **cActiveModuleList, double fTime)
387
 
{
388
 
        //\_______________ On active les modules auto-charges en premier.
389
 
        GError *erreur = NULL;
390
 
        gchar *cModuleName;
391
 
        CairoDockModule *pModule;
392
 
        GList *m;
393
 
        for (m = s_AutoLoadedModules; m != NULL; m = m->next)
394
 
        {
395
 
                pModule = m->data;
396
 
                pModule->fLastLoadingTime = fTime;
397
 
                if (pModule->pInstancesList == NULL)  // on ne les active qu'une seule fois. Si lors d'un changement de theme on re-active les modules, ceux-la resteront inchanges.
398
 
                {
399
 
                        cairo_dock_activate_module (pModule, &erreur);
400
 
                        if (erreur != NULL)
401
 
                        {
402
 
                                cd_warning (erreur->message);
403
 
                                g_error_free (erreur);
404
 
                                erreur = NULL;
405
 
                        }
406
 
                }
407
 
        }
408
 
        
409
 
        if (cActiveModuleList == NULL)
410
 
                return ;
411
 
        
412
 
        //\_______________ On active tous les autres.
413
 
        int i;
414
 
        GList *pNotFoundModules = NULL;
415
 
        for (i = 0; cActiveModuleList[i] != NULL; i ++)
416
 
        {
417
 
                cModuleName = cActiveModuleList[i];
418
 
                pModule = g_hash_table_lookup (s_hModuleTable, cModuleName);
419
 
                if (pModule == NULL)
420
 
                {
421
 
                        cd_debug ("No such module (%s)", cModuleName);
422
 
                        pNotFoundModules = g_list_prepend (pNotFoundModules, cModuleName);
423
 
                        continue ;
424
 
                }
425
 
                
426
 
                pModule->fLastLoadingTime = fTime;
427
 
                if (pModule->pInstancesList == NULL)
428
 
                {
429
 
                        cairo_dock_activate_module (pModule, &erreur);
430
 
                        if (erreur != NULL)
431
 
                        {
432
 
                                cd_warning (erreur->message);
433
 
                                g_error_free (erreur);
434
 
                                erreur = NULL;
435
 
                        }
436
 
                }
437
 
                else
438
 
                {
439
 
                        cairo_dock_reload_module (pModule, FALSE);
440
 
                }
441
 
        }
442
 
}
443
 
 
444
 
static void _cairo_dock_deactivate_one_old_module (gchar *cModuleName, CairoDockModule *pModule, double *fTime)
445
 
{
446
 
        if (pModule->fLastLoadingTime < *fTime)
447
 
                cairo_dock_deactivate_module (pModule);
448
 
}
449
 
void cairo_dock_deactivate_old_modules (double fTime)
450
 
{
451
 
        g_hash_table_foreach (s_hModuleTable, (GHFunc) _cairo_dock_deactivate_one_old_module, &fTime);
452
 
}
453
 
 
454
 
 
455
 
 
456
 
void cairo_dock_free_module (CairoDockModule *module)
457
 
{
458
 
        if (module == NULL)
459
 
                return ;
460
 
        cd_debug ("%s (%s)", __func__, module->pVisitCard->cModuleName);
461
 
 
462
 
        cairo_dock_deactivate_module (module);
463
 
 
464
 
        cairo_dock_close_module (module);
465
 
 
466
 
        cairo_dock_free_visit_card (module->pVisitCard);
467
 
        g_free (module->cSoFilePath);
468
 
        g_free (module);
469
 
}
470
 
 
471
 
void cairo_dock_unregister_module (const gchar *cModuleName)
472
 
{
473
 
        g_return_if_fail (cModuleName != NULL);
474
 
        g_hash_table_remove (s_hModuleTable, cModuleName);
475
 
}
476
 
 
477
 
GKeyFile *cairo_dock_pre_read_module_instance_config (CairoDockModuleInstance *pInstance, CairoDockMinimalAppletConfig *pMinimalConfig)
478
 
{
479
 
        g_return_val_if_fail (pInstance != NULL, NULL);
480
 
        if (pInstance->cConfFilePath == NULL)  // peut arriver avec xxx-integration par exemple.
481
 
                return NULL;
482
 
        gchar *cInstanceConfFilePath = pInstance->cConfFilePath;
483
 
        CairoDockModule *pModule = pInstance->pModule;
484
 
        
485
 
        GError *erreur = NULL;
486
 
        GKeyFile *pKeyFile = cairo_dock_open_key_file (cInstanceConfFilePath);
487
 
        if (pKeyFile == NULL)
488
 
                return NULL;
489
 
 
490
 
        /**gboolean bNeedsUpgrade = cairo_dock_conf_file_needs_update (pKeyFile, pModule->pVisitCard->cModuleVersion);
491
 
        if (bNeedsUpgrade)
492
 
        {
493
 
                cairo_dock_flush_conf_file (pKeyFile, cInstanceConfFilePath, pModule->pVisitCard->cShareDataDir, pModule->pVisitCard->cConfFileName);
494
 
                g_key_file_free (pKeyFile);
495
 
                pKeyFile = cairo_dock_open_key_file (cInstanceConfFilePath);
496
 
                if (pKeyFile == NULL)
497
 
                        return NULL;
498
 
        }*/
499
 
 
500
 
        if (! g_key_file_has_group (pKeyFile, "Icon"))  // ce module n'a pas d'icone, ce n'est donc pas une applet.
501
 
        {
502
 
                pMinimalConfig->iDesiredIconWidth = -1;
503
 
                pMinimalConfig->iDesiredIconHeight = -1;
504
 
                return pKeyFile;
505
 
        }
506
 
        
507
 
        gboolean bUseless;
508
 
        cairo_dock_get_size_key_value_helper (pKeyFile, "Icon", "icon ", bUseless, pMinimalConfig->iDesiredIconWidth, pMinimalConfig->iDesiredIconHeight);
509
 
        
510
 
        if (pMinimalConfig->iDesiredIconWidth == 0/* || pMinimalConfig->iDesiredIconWidth > myIcons.tIconAuthorizedWidth[CAIRO_DOCK_APPLET]*/)
511
 
                pMinimalConfig->iDesiredIconWidth = myIcons.tIconAuthorizedWidth[CAIRO_DOCK_APPLET];
512
 
        if (pMinimalConfig->iDesiredIconHeight == 0/* || pMinimalConfig->iDesiredIconHeight > myIcons.tIconAuthorizedHeight[CAIRO_DOCK_APPLET]*/)
513
 
                pMinimalConfig->iDesiredIconHeight = myIcons.tIconAuthorizedHeight[CAIRO_DOCK_APPLET];
514
 
        pMinimalConfig->cLabel = cairo_dock_get_string_key_value (pKeyFile, "Icon", "name", NULL, NULL, NULL, NULL);
515
 
        pMinimalConfig->cIconFileName = cairo_dock_get_string_key_value (pKeyFile, "Icon", "icon", NULL, NULL, NULL, NULL);
516
 
        pMinimalConfig->fOrder = cairo_dock_get_double_key_value (pKeyFile, "Icon", "order", NULL, CAIRO_DOCK_LAST_ORDER, NULL, NULL);
517
 
        if (pMinimalConfig->fOrder == 0 || pMinimalConfig->fOrder == CAIRO_DOCK_LAST_ORDER)
518
 
        {
519
 
                pMinimalConfig->fOrder = ++ s_iMaxOrder;
520
 
                g_key_file_set_double (pKeyFile, "Icon", "order", pMinimalConfig->fOrder);
521
 
                //g_print ("set order\n");
522
 
                cairo_dock_write_keys_to_file (pKeyFile, cInstanceConfFilePath);
523
 
        }
524
 
        else
525
 
        {
526
 
                s_iMaxOrder = MAX (s_iMaxOrder, pMinimalConfig->fOrder);
527
 
        }
528
 
        pMinimalConfig->cDockName = cairo_dock_get_string_key_value (pKeyFile, "Icon", "dock name", NULL, NULL, NULL, NULL);
529
 
        
530
 
        CairoDeskletAttribute *pDeskletAttribute = &pMinimalConfig->deskletAttribute;
531
 
        if (! g_key_file_has_group (pKeyFile, "Desklet"))  // cette applet ne peut pas se detacher.
532
 
        {
533
 
                pDeskletAttribute->iDeskletWidth = -1;
534
 
                pDeskletAttribute->iDeskletHeight = -1;
535
 
        }
536
 
        else
537
 
        {
538
 
                pMinimalConfig->bIsDetached = cairo_dock_get_boolean_key_value (pKeyFile, "Desklet", "initially detached", NULL, FALSE, NULL, NULL);
539
 
                pDeskletAttribute->bDeskletUseSize = cairo_dock_get_boolean_key_value (pKeyFile, "Desklet", "use size", NULL, TRUE, NULL, NULL);
540
 
                
541
 
                //pDeskletAttribute->iDeskletWidth = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "width", NULL, 92, NULL, NULL);
542
 
                //pDeskletAttribute->iDeskletHeight = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "height", NULL, 92, NULL, NULL);
543
 
                cairo_dock_get_size_key_value_helper (pKeyFile, "Desklet", "", bUseless, pDeskletAttribute->iDeskletWidth, pDeskletAttribute->iDeskletHeight);
544
 
                //g_print ("desklet : %dx%d\n", pDeskletAttribute->iDeskletWidth, pDeskletAttribute->iDeskletHeight);
545
 
                if (pDeskletAttribute->iDeskletWidth == 0)
546
 
                        pDeskletAttribute->iDeskletWidth = 96;
547
 
                if (pDeskletAttribute->iDeskletHeight == 0)
548
 
                        pDeskletAttribute->iDeskletHeight = 96;
549
 
                
550
 
                pDeskletAttribute->iDeskletPositionX = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "x position", NULL, 0, NULL, NULL);
551
 
                pDeskletAttribute->iDeskletPositionY = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "y position", NULL, 0, NULL, NULL);
552
 
                /*pDeskletAttribute->bKeepBelow = cairo_dock_get_boolean_key_value (pKeyFile, "Desklet", "keep below", NULL, FALSE, NULL, NULL);
553
 
                pDeskletAttribute->bKeepAbove = cairo_dock_get_boolean_key_value (pKeyFile, "Desklet", "keep above", NULL, FALSE, NULL, NULL);
554
 
                pDeskletAttribute->bOnWidgetLayer = cairo_dock_get_boolean_key_value (pKeyFile, "Desklet", "on widget layer", NULL, FALSE, NULL, NULL);*/
555
 
                pDeskletAttribute->iAccessibility = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "accessibility", NULL, 0, NULL, NULL);
556
 
                pDeskletAttribute->bOnAllDesktops = cairo_dock_get_boolean_key_value (pKeyFile, "Desklet", "sticky", NULL, TRUE, NULL, NULL);
557
 
                pDeskletAttribute->iNumDesktop = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "num desktop", NULL, -1, NULL, NULL);
558
 
                pDeskletAttribute->bPositionLocked = cairo_dock_get_boolean_key_value (pKeyFile, "Desklet", "locked", NULL, FALSE, NULL, NULL);
559
 
                /*pDeskletAttribute->bNoInput = cairo_dock_get_boolean_key_value (pKeyFile, "Desklet", "no input", NULL, FALSE, NULL, NULL);*/  // 2.1.4
560
 
                pDeskletAttribute->iRotation = cairo_dock_get_double_key_value (pKeyFile, "Desklet", "rotation", NULL, 0, NULL, NULL);
561
 
                pDeskletAttribute->iDepthRotationY = cairo_dock_get_double_key_value (pKeyFile, "Desklet", "depth rotation y", NULL, 0, NULL, NULL);
562
 
                pDeskletAttribute->iDepthRotationX = cairo_dock_get_double_key_value (pKeyFile, "Desklet", "depth rotation x", NULL, 0, NULL, NULL);
563
 
                
564
 
                gchar *cDecorationTheme = cairo_dock_get_string_key_value (pKeyFile, "Desklet", "decorations", NULL, NULL, NULL, NULL);
565
 
                if (cDecorationTheme == NULL || strcmp (cDecorationTheme, "personnal") == 0)
566
 
                {
567
 
                        //g_print ("on recupere les decorations personnelles au desklet\n");
568
 
                        CairoDeskletDecoration *pUserDeskletDecorations = g_new0 (CairoDeskletDecoration, 1);
569
 
                        pDeskletAttribute->pUserDecoration = pUserDeskletDecorations;
570
 
                        
571
 
                        pUserDeskletDecorations->cBackGroundImagePath = cairo_dock_get_string_key_value (pKeyFile, "Desklet", "bg desklet", NULL, NULL, NULL, NULL);
572
 
                        pUserDeskletDecorations->cForeGroundImagePath = cairo_dock_get_string_key_value (pKeyFile, "Desklet", "fg desklet", NULL, NULL, NULL, NULL);
573
 
                        pUserDeskletDecorations->iLoadingModifier = CAIRO_DOCK_FILL_SPACE;
574
 
                        pUserDeskletDecorations->fBackGroundAlpha = cairo_dock_get_double_key_value (pKeyFile, "Desklet", "bg alpha", NULL, 1.0, NULL, NULL);
575
 
                        pUserDeskletDecorations->fForeGroundAlpha = cairo_dock_get_double_key_value (pKeyFile, "Desklet", "fg alpha", NULL, 1.0, NULL, NULL);
576
 
                        pUserDeskletDecorations->iLeftMargin = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "left offset", NULL, CAIRO_DOCK_FM_SORT_BY_NAME, NULL, NULL);
577
 
                        pUserDeskletDecorations->iTopMargin = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "top offset", NULL, CAIRO_DOCK_FM_SORT_BY_NAME, NULL, NULL);
578
 
                        pUserDeskletDecorations->iRightMargin = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "right offset", NULL, CAIRO_DOCK_FM_SORT_BY_NAME, NULL, NULL);
579
 
                        pUserDeskletDecorations->iBottomMargin = cairo_dock_get_integer_key_value (pKeyFile, "Desklet", "bottom offset", NULL, CAIRO_DOCK_FM_SORT_BY_NAME, NULL, NULL);
580
 
                        g_free (cDecorationTheme);
581
 
                }
582
 
                else
583
 
                {
584
 
                        //g_print ("decorations : %s\n", cDecorationTheme);
585
 
                        pDeskletAttribute->cDecorationTheme = cDecorationTheme;
586
 
                }
587
 
        }
588
 
        return pKeyFile;
589
 
}
590
 
 
591
 
void cairo_dock_free_minimal_config (CairoDockMinimalAppletConfig *pMinimalConfig)
592
 
{
593
 
        if (pMinimalConfig == NULL)
594
 
                return;
595
 
        g_free (pMinimalConfig->cLabel);
596
 
        g_free (pMinimalConfig->cIconFileName);
597
 
        g_free (pMinimalConfig->cDockName);
598
 
        g_free (pMinimalConfig->deskletAttribute.cDecorationTheme);
599
 
        cairo_dock_free_desklet_decoration (pMinimalConfig->deskletAttribute.pUserDecoration);
600
 
        g_free (pMinimalConfig);
601
 
}
602
 
 
603
 
void cairo_dock_activate_module (CairoDockModule *module, GError **erreur)
604
 
{
605
 
        g_return_if_fail (module != NULL);
606
 
        cd_message ("%s (%s)", __func__, module->pVisitCard->cModuleName);
607
 
 
608
 
        if (module->pInstancesList != NULL)
609
 
        {
610
 
                cd_warning ("module %s already activated", module->pVisitCard->cModuleName);
611
 
                g_set_error (erreur, 1, 1, "%s () : module %s is already active !", __func__, module->pVisitCard->cModuleName);
612
 
                return ;
613
 
        }
614
 
 
615
 
        g_free (module->cConfFilePath);
616
 
        module->cConfFilePath = cairo_dock_check_module_conf_file (module->pVisitCard);
617
 
        
618
 
        gchar *cInstanceFilePath = NULL;
619
 
        int j = 0;
620
 
        do
621
 
        {
622
 
                if (j == 0)
623
 
                        cInstanceFilePath = g_strdup (module->cConfFilePath);
624
 
                else
625
 
                        cInstanceFilePath = g_strdup_printf ("%s-%d",  module->cConfFilePath, j);
626
 
                
627
 
                if (cInstanceFilePath != NULL && ! g_file_test (cInstanceFilePath, G_FILE_TEST_EXISTS))  // la 1ere condition est pour xxx-integration par exemple .
628
 
                {
629
 
                        g_free (cInstanceFilePath);
630
 
                        break ;
631
 
                }
632
 
                
633
 
                cairo_dock_instanciate_module (module, cInstanceFilePath);  // prend possession de 'cInstanceFilePath'.
634
 
                
635
 
                j ++;
636
 
        } while (1);
637
 
        
638
 
        if (j == 0)
639
 
        {
640
 
                g_set_error (erreur, 1, 1, "%s () : no instance of module %s could be created", __func__, module->pVisitCard->cModuleName);
641
 
                return ;
642
 
        }
643
 
}
644
 
 
645
 
 
646
 
void cairo_dock_deactivate_module (CairoDockModule *module)
647
 
{
648
 
        g_return_if_fail (module != NULL);
649
 
        cd_debug ("%s (%s, %s)", __func__, module->pVisitCard->cModuleName, module->cConfFilePath);
650
 
        g_list_foreach (module->pInstancesList, (GFunc) cairo_dock_stop_module_instance, NULL);
651
 
        g_list_foreach (module->pInstancesList, (GFunc) cairo_dock_free_module_instance, NULL);
652
 
        g_list_free (module->pInstancesList);
653
 
        module->pInstancesList = NULL;
654
 
}
655
 
 
656
 
 
657
 
void cairo_dock_reload_module_instance (CairoDockModuleInstance *pInstance, gboolean bReloadAppletConf)
658
 
{
659
 
        g_return_if_fail (pInstance != NULL);
660
 
        CairoDockModule *module = pInstance->pModule;
661
 
        cd_message ("%s (%s, %d)", __func__, module->pVisitCard->cModuleName, bReloadAppletConf);
662
 
        
663
 
        GError *erreur = NULL;
664
 
        CairoContainer *pCurrentContainer = pInstance->pContainer;
665
 
        pInstance->pContainer = NULL;
666
 
        CairoDock *pCurrentDock = pInstance->pDock;
667
 
        pInstance->pDock = NULL;
668
 
        CairoDesklet *pCurrentDesklet = pInstance->pDesklet;
669
 
        pInstance->pDesklet = NULL;
670
 
        gchar *cOldDockName = NULL;
671
 
        
672
 
        CairoContainer *pNewContainer = NULL;
673
 
        CairoDock *pNewDock = NULL;
674
 
        CairoDesklet *pNewDesklet = NULL;
675
 
        
676
 
        //\______________ On recharge la config minimale.
677
 
        gboolean bModuleReloaded = FALSE;
678
 
        Icon *pIcon = pInstance->pIcon;
679
 
        GKeyFile *pKeyFile = NULL;
680
 
        CairoDockMinimalAppletConfig *pMinimalConfig = NULL;
681
 
        if (bReloadAppletConf && pInstance->cConfFilePath != NULL)
682
 
        {
683
 
                pMinimalConfig = g_new0 (CairoDockMinimalAppletConfig, 1);
684
 
                pKeyFile = cairo_dock_pre_read_module_instance_config (pInstance, pMinimalConfig);
685
 
                
686
 
                if (pMinimalConfig->iDesiredIconWidth > -1)  // c'est une applet.
687
 
                {
688
 
                        //\______________ On met a jour les champs 'nom' et 'image' de l'icone.
689
 
                        if (pIcon != NULL)
690
 
                        {
691
 
                                // on gere le changement de nom de son sous-dock.
692
 
                                if (pIcon->cName != NULL && pIcon->pSubDock != NULL && cairo_dock_strings_differ (pIcon->cName, pMinimalConfig->cLabel))
693
 
                                {
694
 
                                        gchar *cNewName = cairo_dock_get_unique_dock_name (pMinimalConfig->cLabel);
695
 
                                        cd_debug ("* le sous-dock %s prend le nom '%s'", pIcon->cName, cNewName);
696
 
                                        if (strcmp (pIcon->cName, cNewName) != 0)
697
 
                                                cairo_dock_rename_dock (pIcon->cName, NULL, cNewName);
698
 
                                        g_free (pMinimalConfig->cLabel);
699
 
                                        pMinimalConfig->cLabel = cNewName;
700
 
                                }
701
 
                                
702
 
                                g_free (pIcon->cName);
703
 
                                pIcon->cName = pMinimalConfig->cLabel;
704
 
                                pMinimalConfig->cLabel = NULL;  // astuce.
705
 
                                g_free (pIcon->cFileName);
706
 
                                pIcon->cFileName = pMinimalConfig->cIconFileName;
707
 
                                pMinimalConfig->cIconFileName = NULL;
708
 
                        }
709
 
                        
710
 
                        // on recupere son dock (cree au besoin).
711
 
                        if (!pMinimalConfig->bIsDetached)  // elle est desormais dans un dock.
712
 
                        {
713
 
                                const gchar *cDockName = (pMinimalConfig->cDockName != NULL ? pMinimalConfig->cDockName : CAIRO_DOCK_MAIN_DOCK_NAME);
714
 
                                pNewDock = cairo_dock_search_dock_from_name (cDockName);
715
 
                                if (pNewDock == NULL)  // c'est un nouveau dock.
716
 
                                {
717
 
                                        pNewDock = cairo_dock_create_new_dock (cDockName, NULL);
718
 
                                }
719
 
                                pNewContainer = CAIRO_CONTAINER (pNewDock);
720
 
                        }
721
 
                        
722
 
                        // on la detache de son dock si son container a change.
723
 
                        if (pCurrentDock != NULL && (pMinimalConfig->bIsDetached || pNewDock != pCurrentDock))
724
 
                        {
725
 
                                cd_message ("le container a change (%s -> %s)", pIcon->cParentDockName, pMinimalConfig->bIsDetached ? "desklet" : pMinimalConfig->cDockName);
726
 
                                cOldDockName = g_strdup (pIcon->cParentDockName);
727
 
                                cairo_dock_detach_icon_from_dock (pIcon, pCurrentDock, myIcons.iSeparateIcons);
728
 
                        }
729
 
                        
730
 
                        // on recupere son desklet (cree au besoin).
731
 
                        if (pMinimalConfig->bIsDetached)
732
 
                        {
733
 
                                if (pCurrentDesklet == NULL)  // c'est un nouveau desklet.
734
 
                                        pNewDesklet = cairo_dock_create_desklet (pIcon, NULL, pMinimalConfig->deskletAttribute.iAccessibility);
735
 
                                else
736
 
                                        pNewDesklet = pCurrentDesklet;
737
 
                                cairo_dock_configure_desklet (pNewDesklet, &pMinimalConfig->deskletAttribute);
738
 
                                pNewContainer = CAIRO_CONTAINER (pNewDesklet);
739
 
                        }
740
 
                }
741
 
        }
742
 
        else
743
 
        {
744
 
                pNewContainer = pCurrentContainer;
745
 
                pNewDock = pCurrentDock;
746
 
                pNewDesklet = pCurrentDesklet;
747
 
        }
748
 
        pInstance->pContainer = pNewContainer;
749
 
        pInstance->pDock = pNewDock;
750
 
        pInstance->pDesklet = pNewDesklet;
751
 
        
752
 
        //\_______________________ On insere l'icone dans son nouveau dock, et on s'assure que sa taille respecte les tailles par defaut.
753
 
        if (pNewDock != NULL && pIcon != NULL)  // l'icone est desormais dans un dock.
754
 
        {
755
 
                // on recupere la taille voulue.
756
 
                if (pMinimalConfig == NULL)  // on recupere sa taille, car elle peut avoir change (si c'est la taille par defaut, ou si elle est devenue trop grande).
757
 
                {
758
 
                        pMinimalConfig = g_new0 (CairoDockMinimalAppletConfig, 1);
759
 
                        pKeyFile = cairo_dock_pre_read_module_instance_config (pInstance, pMinimalConfig);
760
 
                        g_key_file_free (pKeyFile);
761
 
                        pKeyFile = NULL;
762
 
                }
763
 
                pIcon->fWidth = pMinimalConfig->iDesiredIconWidth;
764
 
                pIcon->fHeight = pMinimalConfig->iDesiredIconHeight;
765
 
                
766
 
                // on charge l'icone a la bonne taille.
767
 
                cairo_dock_load_one_icon_from_scratch (pIcon, pNewContainer);
768
 
                
769
 
                // on insere l'icone dans le dock ou on met a jour celui-ci.
770
 
                if (pNewDock != pCurrentDock)  // on l'insere dans son nouveau dock.
771
 
                {
772
 
                        cairo_dock_insert_icon_in_dock (pIcon, pNewDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
773
 
                        pIcon->cParentDockName = g_strdup (pMinimalConfig->cDockName != NULL ? pMinimalConfig->cDockName : CAIRO_DOCK_MAIN_DOCK_NAME);
774
 
                        cairo_dock_start_icon_animation (pIcon, pNewDock);
775
 
                }
776
 
                else  // le dock n'a pas change, on le met a jour.
777
 
                {
778
 
                        pIcon->fWidth *= pNewContainer->fRatio;
779
 
                        pIcon->fHeight *= pNewContainer->fRatio;
780
 
                        
781
 
                        if (bReloadAppletConf)
782
 
                        {
783
 
                                cairo_dock_update_dock_size (pNewDock);
784
 
                                cairo_dock_calculate_dock_icons (pNewDock);
785
 
                                gtk_widget_queue_draw (pNewContainer->pWidget);
786
 
                        }
787
 
                }
788
 
        }
789
 
        
790
 
        //\_______________________ On recharge la config.
791
 
        if (pKeyFile != NULL)
792
 
        {
793
 
                cairo_dock_read_module_config (pKeyFile, pInstance);
794
 
        }
795
 
        gboolean bCanReload = TRUE;
796
 
        if (pInstance->pDrawContext != NULL)
797
 
        {
798
 
                cairo_destroy (pInstance->pDrawContext);
799
 
                //g_print ("on detruit le ctx de %s (%x)\n", pInstance->cConfFilePath, pInstance->pDrawContext);
800
 
        }
801
 
        if (pInstance->pDock)
802
 
        {
803
 
                //g_print ("dans un dock\n");
804
 
                if (pInstance->pIcon->pIconBuffer == NULL)
805
 
                {
806
 
                        cd_warning ("invalid applet's icon buffer");
807
 
                        pInstance->pDrawContext = NULL;
808
 
                }
809
 
                else
810
 
                        pInstance->pDrawContext = cairo_create (pInstance->pIcon->pIconBuffer);
811
 
                if (cairo_status (pInstance->pDrawContext) != CAIRO_STATUS_SUCCESS)
812
 
                {
813
 
                        cd_warning ("couldn't initialize drawing context, applet won't be reloaded !");
814
 
                        bCanReload = FALSE;
815
 
                }
816
 
        }
817
 
        else
818
 
        {
819
 
                //g_print ("dans un desklet\n");
820
 
                pInstance->pDrawContext = NULL;
821
 
        }
822
 
 
823
 
        //\_______________________ On recharge l'instance.
824
 
        if (bCanReload && module->pInterface->reloadModule != NULL)
825
 
                bModuleReloaded = module->pInterface->reloadModule (pInstance, pCurrentContainer, pKeyFile);
826
 
        
827
 
        if (pNewContainer != pCurrentContainer && pNewDock != NULL && pCurrentDock != NULL && pIcon != NULL && pIcon->pSubDock != NULL)
828
 
        {
829
 
                cairo_dock_synchronize_one_sub_dock_position (pIcon->pSubDock, pNewDock, TRUE);
830
 
        }
831
 
        
832
 
        if (pNewDock != NULL && pNewDock->iRefCount != 0)  // on redessine l'icone pointant sur le sous-dock contenant l'applet, au cas ou son image aurait change.
833
 
        {
834
 
                cairo_dock_redraw_subdock_content (pNewDock);
835
 
        }
836
 
        
837
 
        if (pNewDock || pCurrentDock)
838
 
                cairo_dock_refresh_launcher_gui ();
839
 
        
840
 
        //\_______________________ On nettoie derriere nous.
841
 
        cairo_dock_free_minimal_config (pMinimalConfig);
842
 
        if (pKeyFile != NULL)
843
 
                g_key_file_free (pKeyFile);
844
 
        
845
 
        if (pCurrentDesklet != NULL && pCurrentDesklet != pNewDesklet)
846
 
                cairo_dock_free_desklet (pCurrentDesklet);
847
 
        if (pCurrentDock != NULL && pCurrentDock != pNewDock)
848
 
        {
849
 
                if (pCurrentDock->iRefCount == 0 && pCurrentDock->icons == NULL && !pCurrentDock->bIsMainDock)  // dock principal vide.
850
 
                {
851
 
                        cairo_dock_destroy_dock (pCurrentDock, cOldDockName, NULL, NULL);
852
 
                }
853
 
                else
854
 
                {
855
 
                        cairo_dock_update_dock_size (pCurrentDock);
856
 
                        cairo_dock_calculate_dock_icons (pCurrentDock);
857
 
                        gtk_widget_queue_draw (pCurrentContainer->pWidget);
858
 
                }
859
 
        }
860
 
        g_free (cOldDockName);
861
 
}
862
 
 
863
 
void cairo_dock_reload_module (CairoDockModule *pModule, gboolean bReloadAppletConf)
864
 
{
865
 
        GList *pElement;
866
 
        CairoDockModuleInstance *pInstance;
867
 
        for (pElement = pModule->pInstancesList; pElement != NULL; pElement = pElement->next)
868
 
        {
869
 
                pInstance = pElement->data;
870
 
                cairo_dock_reload_module_instance (pInstance, bReloadAppletConf);
871
 
        }
872
 
}
873
 
 
874
 
 
875
 
static void _cairo_dock_deactivate_one_module (gchar *cModuleName, CairoDockModule *pModule, gpointer data)
876
 
{
877
 
        cairo_dock_deactivate_module (pModule);
878
 
}
879
 
void cairo_dock_deactivate_all_modules (void)
880
 
{
881
 
        g_hash_table_foreach (s_hModuleTable, (GHFunc) _cairo_dock_deactivate_one_module, NULL);
882
 
}
883
 
 
884
 
 
885
 
void cairo_dock_activate_module_and_load (const gchar *cModuleName)
886
 
{
887
 
        if (g_pMainDock == NULL)
888
 
                return ;
889
 
        CairoDockModule *pModule = cairo_dock_find_module_from_name (cModuleName);
890
 
        g_return_if_fail (pModule != NULL);
891
 
        
892
 
        pModule->fLastLoadingTime = 0;
893
 
        if (pModule->pInstancesList == NULL)
894
 
        {
895
 
                GError *erreur = NULL;
896
 
                cairo_dock_activate_module (pModule, &erreur);
897
 
                if (erreur != NULL)
898
 
                {
899
 
                        cd_warning (erreur->message);
900
 
                        g_error_free (erreur);
901
 
                }
902
 
        }
903
 
        else
904
 
        {
905
 
                cairo_dock_reload_module (pModule, FALSE);
906
 
        }
907
 
        
908
 
        GList *pElement;
909
 
        CairoDockModuleInstance *pInstance;
910
 
        for (pElement = pModule->pInstancesList; pElement != NULL; pElement = pElement->next)
911
 
        {
912
 
                pInstance = pElement->data;
913
 
                if (pInstance->pDock)
914
 
                {
915
 
                        cairo_dock_update_dock_size (pInstance->pDock);
916
 
                        gtk_widget_queue_draw (pInstance->pDock->container.pWidget);
917
 
                }
918
 
        }
919
 
        
920
 
        cairo_dock_update_conf_file_with_active_modules ();
921
 
}
922
 
 
923
 
void cairo_dock_deactivate_module_instance_and_unload (CairoDockModuleInstance *pInstance)
924
 
{
925
 
        g_return_if_fail (pInstance != NULL);
926
 
        cd_message ("%s (%s)", __func__, pInstance->cConfFilePath);
927
 
        
928
 
        Icon *pIcon = pInstance->pIcon;  // l'instance va etre detruite.
929
 
        CairoDock *pDock = pInstance->pDock;
930
 
        if (pDock)
931
 
        {
932
 
                cairo_dock_remove_icon_from_dock (pDock, pInstance->pIcon);  // desinstancie le module et tout.
933
 
                cairo_dock_update_dock_size (pDock);
934
 
                gtk_widget_queue_draw (pDock->container.pWidget);
935
 
        }
936
 
        else
937
 
        {
938
 
                cairo_dock_deinstanciate_module (pInstance);
939
 
                if (pIcon)
940
 
                        pIcon->pModuleInstance = NULL;
941
 
        }
942
 
        cairo_dock_free_icon (pIcon);
943
 
}
944
 
 
945
 
void cairo_dock_deactivate_module_and_unload (const gchar *cModuleName)
946
 
{
947
 
        if (g_pMainDock == NULL)
948
 
                return ;
949
 
        CairoDockModule *pModule = cairo_dock_find_module_from_name (cModuleName);
950
 
        g_return_if_fail (pModule != NULL);
951
 
        
952
 
        GList *pElement = pModule->pInstancesList, *pNextElement;
953
 
        CairoDockModuleInstance *pInstance;
954
 
        cd_debug ("%d instance(s) a arreter", g_list_length (pModule->pInstancesList));
955
 
        //for (pElement = pModule->pInstancesList; pElement != NULL; pElement = pElement->next)
956
 
        while (pElement != NULL)
957
 
        {
958
 
                pInstance = pElement->data;
959
 
                pNextElement = pElement->next;
960
 
                cairo_dock_deactivate_module_instance_and_unload (pInstance);
961
 
                pElement = pNextElement;
962
 
        }
963
 
        
964
 
        cairo_dock_update_conf_file_with_active_modules ();
965
 
}
966
 
 
967
 
 
968
 
CairoDockModule *cairo_dock_find_module_from_name (const gchar *cModuleName)
969
 
{
970
 
        //g_print ("%s (%s)\n", __func__, cModuleName);
971
 
        g_return_val_if_fail (cModuleName != NULL, NULL);
972
 
        return g_hash_table_lookup (s_hModuleTable, cModuleName);
973
 
}
974
 
 
975
 
 
976
 
 
977
 
static gboolean _cairo_dock_for_one_desklet (gchar *cModuleName, CairoDockModule *pModule, gpointer *data)
978
 
{
979
 
        GList *pElement;
980
 
        CairoDockModuleInstance *pInstance;
981
 
        for (pElement = pModule->pInstancesList; pElement != NULL; pElement = pElement->next)
982
 
        {
983
 
                pInstance = pElement->data;
984
 
                if (pInstance->pDesklet)
985
 
                {
986
 
                        CairoDockForeachDeskletFunc pCallback = data[0];
987
 
                        gpointer user_data = data[1];
988
 
                        
989
 
                        if (pCallback (pInstance->pDesklet, pInstance, user_data))
990
 
                        {
991
 
                                data[2] = pInstance;
992
 
                                return TRUE;
993
 
                        }
994
 
                }
995
 
                
996
 
        }
997
 
        
998
 
        return FALSE;
999
 
}
1000
 
CairoDockModuleInstance *cairo_dock_foreach_desklet (CairoDockForeachDeskletFunc pCallback, gpointer user_data)
1001
 
{
1002
 
        gpointer data[3] = {pCallback, user_data, NULL};
1003
 
        g_hash_table_find (s_hModuleTable, (GHRFunc) _cairo_dock_for_one_desklet, data);
1004
 
        return data[2];
1005
 
}
1006
 
 
1007
 
CairoDockModule *cairo_dock_foreach_module (GHRFunc pCallback, gpointer user_data)
1008
 
{
1009
 
        return g_hash_table_find (s_hModuleTable, (GHRFunc) pCallback, user_data);
1010
 
}
1011
 
 
1012
 
static int _sort_module_by_alphabetical_order (CairoDockModule *m1, CairoDockModule *m2)
1013
 
{
1014
 
        if (!m1 || !m1->pVisitCard || !m1->pVisitCard->cModuleName)
1015
 
                return 1;
1016
 
        if (!m2 || !m2->pVisitCard || !m2->pVisitCard->cModuleName)
1017
 
                return -1;
1018
 
        return g_ascii_strncasecmp (dgettext (m1->pVisitCard->cGettextDomain, m1->pVisitCard->cModuleName),
1019
 
                dgettext (m2->pVisitCard->cGettextDomain, m2->pVisitCard->cModuleName),
1020
 
                -1);
1021
 
}
1022
 
CairoDockModule *cairo_dock_foreach_module_in_alphabetical_order (GCompareFunc pCallback, gpointer user_data)
1023
 
{
1024
 
        GList *pModuleList = g_hash_table_get_values (s_hModuleTable);
1025
 
        pModuleList = g_list_sort (pModuleList, (GCompareFunc) _sort_module_by_alphabetical_order);
1026
 
        
1027
 
        CairoDockModule *pModule = (CairoDockModule *)g_list_find_custom (pModuleList, user_data, pCallback);
1028
 
        
1029
 
        g_list_free (pModuleList);
1030
 
        return pModule;
1031
 
}
1032
 
 
1033
 
 
1034
 
 
1035
 
static void _cairo_dock_write_one_module_name (gchar *cModuleName, CairoDockModule *pModule, GString *pString)
1036
 
{
1037
 
        if (pModule->pInstancesList != NULL && ! cairo_dock_module_is_auto_loaded (pModule) && pModule->cSoFilePath != NULL)
1038
 
        {
1039
 
                g_string_append_printf (pString, "%s;", cModuleName);
1040
 
        }
1041
 
}
1042
 
gchar *cairo_dock_list_active_modules (void)
1043
 
{
1044
 
        GString *pString = g_string_new ("");
1045
 
        
1046
 
        g_hash_table_foreach (s_hModuleTable, (GHFunc) _cairo_dock_write_one_module_name, pString);
1047
 
        
1048
 
        if (pString->len > 0)
1049
 
                pString->str[pString->len-1] = '\0';
1050
 
        
1051
 
        gchar *cModuleNames = pString->str;
1052
 
        g_string_free (pString, FALSE);
1053
 
        return cModuleNames;
1054
 
}
1055
 
 
1056
 
void cairo_dock_update_conf_file_with_active_modules (void)
1057
 
{
1058
 
        gchar *cModuleNames = cairo_dock_list_active_modules ();
1059
 
        
1060
 
        cairo_dock_update_conf_file (g_cConfFile,
1061
 
                G_TYPE_STRING, "System", "modules", cModuleNames,
1062
 
                G_TYPE_INVALID);
1063
 
        g_free (cModuleNames);
1064
 
}
1065
 
 
1066
 
 
1067
 
void cairo_dock_update_module_instance_order (CairoDockModuleInstance *pModuleInstance, double fOrder)
1068
 
{
1069
 
        cd_message ("%s <- %.2f", pModuleInstance->pModule->pVisitCard->cModuleName, fOrder);
1070
 
        cairo_dock_update_conf_file (pModuleInstance->cConfFilePath,
1071
 
                G_TYPE_DOUBLE, "Icon", "order", fOrder,
1072
 
                G_TYPE_INVALID);
1073
 
}
1074
 
 
1075
 
 
1076
 
/*
1077
 
* Cree une nouvelle instance d'un module. Cree l'icone et le container associe, et les place ou il faut.
1078
 
*/
1079
 
CairoDockModuleInstance *cairo_dock_instanciate_module (CairoDockModule *pModule, gchar *cConfFilePath)  // prend possession de 'cConfFilePah'.
1080
 
{
1081
 
        g_return_val_if_fail (pModule != NULL, NULL);
1082
 
        cd_message ("%s (%s)", __func__, cConfFilePath);
1083
 
        
1084
 
        //\____________________ On cree une instance du module.
1085
 
        //CairoDockModuleInstance *pInstance = g_new0 (CairoDockModuleInstance, 1);
1086
 
        CairoDockModuleInstance *pInstance = calloc (1, sizeof (CairoDockModuleInstance) + pModule->pVisitCard->iSizeOfConfig + pModule->pVisitCard->iSizeOfData);
1087
 
        pInstance->pModule = pModule;
1088
 
        pInstance->cConfFilePath = cConfFilePath;
1089
 
        /*if (pModule->pVisitCard->iSizeOfConfig > 0)
1090
 
                pInstance->pConfig = g_new0 (gpointer, pModule->pVisitCard->iSizeOfConfig);
1091
 
        if (pModule->pVisitCard->iSizeOfData > 0)
1092
 
                pInstance->pData = g_new0 (gpointer, pModule->pVisitCard->iSizeOfData);*/
1093
 
        
1094
 
        CairoDockMinimalAppletConfig *pMinimalConfig = g_new0 (CairoDockMinimalAppletConfig, 1);
1095
 
        GKeyFile *pKeyFile = cairo_dock_pre_read_module_instance_config (pInstance, pMinimalConfig);
1096
 
        g_return_val_if_fail (cConfFilePath == NULL || pKeyFile != NULL, NULL);  // protection en cas de fichier de conf illisible.
1097
 
        pModule->pInstancesList = g_list_prepend (pModule->pInstancesList, pInstance);
1098
 
        
1099
 
        //\____________________ On cree le container de l'instance, ainsi que son icone.
1100
 
        CairoContainer *pContainer = NULL;
1101
 
        CairoDock *pDock = NULL;
1102
 
        CairoDesklet *pDesklet = NULL;
1103
 
        Icon *pIcon = NULL;
1104
 
        
1105
 
        if (pMinimalConfig->iDesiredIconWidth > 0)  // le module a une icone, c'est donc une applet.
1106
 
        {
1107
 
                pInstance->bCanDetach = pMinimalConfig->deskletAttribute.iDeskletWidth > 0;
1108
 
                pModule->bCanDetach = pInstance->bCanDetach;  // pas encore clair ...
1109
 
                
1110
 
                // on trouve/cree son container.
1111
 
                if (pModule->bCanDetach && pMinimalConfig->bIsDetached)
1112
 
                {
1113
 
                        pDesklet = cairo_dock_create_desklet (NULL, NULL, pMinimalConfig->deskletAttribute.iAccessibility);
1114
 
                        cairo_dock_configure_desklet (pDesklet, &pMinimalConfig->deskletAttribute);
1115
 
                        /*g_print ("transparence du desklet...\n");
1116
 
                        while (gtk_events_pending ())  // pour la transparence initiale.
1117
 
                                gtk_main_iteration ();*/
1118
 
                        pContainer = CAIRO_CONTAINER (pDesklet);
1119
 
                }
1120
 
                else
1121
 
                {
1122
 
                        const gchar *cDockName = (pMinimalConfig->cDockName != NULL ? pMinimalConfig->cDockName : CAIRO_DOCK_MAIN_DOCK_NAME);
1123
 
                        pDock = cairo_dock_search_dock_from_name (cDockName);
1124
 
                        if (pDock == NULL)
1125
 
                        {
1126
 
                                pDock = cairo_dock_create_new_dock (cDockName, NULL);
1127
 
                        }
1128
 
                        pContainer = CAIRO_CONTAINER (pDock);
1129
 
                }
1130
 
                
1131
 
                // on cree son icone.
1132
 
                pIcon = cairo_dock_create_icon_for_applet (pMinimalConfig,
1133
 
                        pInstance,
1134
 
                        pContainer);
1135
 
                if (pDesklet)
1136
 
                {
1137
 
                        pDesklet->pIcon = pIcon;
1138
 
                        gtk_window_set_title (GTK_WINDOW(pContainer->pWidget), pInstance->pModule->pVisitCard->cModuleName);
1139
 
                        ///gtk_widget_queue_draw (pContainer->pWidget);
1140
 
                }
1141
 
                cairo_dock_free_minimal_config (pMinimalConfig);
1142
 
        }
1143
 
 
1144
 
        //\____________________ On initialise l'instance.
1145
 
        if (pDock)
1146
 
        {
1147
 
                pIcon->fWidth *= pDock->container.fRatio;
1148
 
                pIcon->fHeight *= pDock->container.fRatio;
1149
 
        }
1150
 
        
1151
 
        pInstance->pIcon = pIcon;
1152
 
        pInstance->pDock = pDock;
1153
 
        pInstance->pDesklet = pDesklet;
1154
 
        pInstance->pContainer = pContainer;
1155
 
        
1156
 
        if (pKeyFile)
1157
 
                cairo_dock_read_module_config (pKeyFile, pInstance);
1158
 
        
1159
 
        gboolean bCanInit = TRUE;
1160
 
        if (pDock)
1161
 
        {
1162
 
                if (pIcon != NULL)
1163
 
                {
1164
 
                        if (pIcon->pIconBuffer == NULL)
1165
 
                        {
1166
 
                                cd_warning ("icon's buffer is NULL, applet won't be able to draw to it !");
1167
 
                                pInstance->pDrawContext = NULL;
1168
 
                        }
1169
 
                        else
1170
 
                                pInstance->pDrawContext = cairo_create (pIcon->pIconBuffer);
1171
 
                        if (cairo_status (pInstance->pDrawContext) != CAIRO_STATUS_SUCCESS)
1172
 
                        {
1173
 
                                cd_warning ("couldn't initialize drawing context, applet won't be able to draw itself !");
1174
 
                                bCanInit = FALSE;
1175
 
                        }
1176
 
                }
1177
 
        }
1178
 
        else
1179
 
                pInstance->pDrawContext = NULL;
1180
 
        if (bCanInit && pModule->pInterface->initModule)
1181
 
                pModule->pInterface->initModule (pInstance, pKeyFile);
1182
 
        
1183
 
        if (pDock)
1184
 
        {
1185
 
                pIcon->fWidth /= pDock->container.fRatio;
1186
 
                pIcon->fHeight /= pDock->container.fRatio;
1187
 
                cairo_dock_insert_icon_in_dock (pIcon, pDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
1188
 
        }
1189
 
        else if (pDesklet && pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0)  // peut arriver si le desklet a fini de se redimensionner avant l'init.
1190
 
                gtk_widget_queue_draw (pDesklet->container.pWidget);
1191
 
        if (pKeyFile != NULL)
1192
 
                g_key_file_free (pKeyFile);
1193
 
        return pInstance;
1194
 
}
1195
 
 
1196
 
/*
1197
 
* Detruit une instance de module et libere les resources associees.
1198
 
*/
1199
 
void cairo_dock_free_module_instance (CairoDockModuleInstance *pInstance)
1200
 
{
1201
 
        g_free (pInstance->cConfFilePath);
1202
 
        /**g_free (pInstance->pConfig);
1203
 
        g_free (pInstance->pData);*/
1204
 
        g_free (pInstance);
1205
 
}
1206
 
 
1207
 
/*
1208
 
* Stoppe une instance d'un module en vue de la detruire.
1209
 
*/
1210
 
void cairo_dock_stop_module_instance (CairoDockModuleInstance *pInstance)
1211
 
{
1212
 
        if (pInstance->pModule->pInterface->stopModule != NULL)
1213
 
                pInstance->pModule->pInterface->stopModule (pInstance);
1214
 
        
1215
 
        if (pInstance->pModule->pInterface->reset_data != NULL)
1216
 
                pInstance->pModule->pInterface->reset_data (pInstance);
1217
 
        
1218
 
        if (pInstance->pModule->pInterface->reset_config != NULL)
1219
 
                pInstance->pModule->pInterface->reset_config (pInstance);
1220
 
        
1221
 
        if (pInstance->pDesklet)
1222
 
                cairo_dock_free_desklet (pInstance->pDesklet);
1223
 
        if (pInstance->pDrawContext != NULL)
1224
 
                cairo_destroy (pInstance->pDrawContext);
1225
 
        
1226
 
        if (pInstance->pIcon != NULL)
1227
 
                pInstance->pIcon->pModuleInstance = NULL;
1228
 
}
1229
 
/*
1230
 
* Stoppe une instance d'un module, et la detruit.
1231
 
*/
1232
 
void cairo_dock_deinstanciate_module (CairoDockModuleInstance *pInstance)
1233
 
{
1234
 
        cairo_dock_stop_module_instance (pInstance);
1235
 
        
1236
 
        pInstance->pModule->pInstancesList = g_list_remove (pInstance->pModule->pInstancesList, pInstance);
1237
 
        
1238
 
        cairo_dock_free_module_instance (pInstance);
1239
 
}
1240
 
 
1241
 
/*
1242
 
* Stoppe une instance d'un module, et la supprime.
1243
 
*/
1244
 
void cairo_dock_remove_module_instance (CairoDockModuleInstance *pInstance)
1245
 
{
1246
 
        cd_message ("%s (%s)", __func__, pInstance->cConfFilePath);
1247
 
        //\_________________ Si c'est la derniere instance, on desactive le module.
1248
 
        if (pInstance->pModule->pInstancesList->next == NULL)
1249
 
        {
1250
 
                cairo_dock_deactivate_module_and_unload (pInstance->pModule->pVisitCard->cModuleName);
1251
 
                return ;
1252
 
        }
1253
 
        
1254
 
        //\_________________ On efface le fichier de conf de cette instance.
1255
 
        cd_debug ("on efface %s", pInstance->cConfFilePath);
1256
 
        g_remove (pInstance->cConfFilePath);
1257
 
        
1258
 
        //\_________________ On supprime cette instance (on le fait maintenant, pour que son fichier de conf n'existe plus lors du 'stop'.
1259
 
        gchar *cConfFilePath = pInstance->cConfFilePath;
1260
 
        pInstance->cConfFilePath = NULL;
1261
 
        CairoDockModule *pModule = pInstance->pModule;
1262
 
        cairo_dock_deactivate_module_instance_and_unload (pInstance);  // pInstance n'est plus.
1263
 
        
1264
 
        //\_________________ Si c'est pas la derniere instance, la derniere instance prend sa place.
1265
 
        int iNbInstances = g_list_length (pModule->pInstancesList)+1;  // nombre d'instances avant suppression.
1266
 
        gchar *str = strrchr (cConfFilePath, '-');
1267
 
        if (str == NULL || atoi (str+1) != iNbInstances-1)
1268
 
        {
1269
 
                gchar *cLastInstanceFilePath = g_strdup_printf ("%s-%d", pModule->cConfFilePath, iNbInstances-1);
1270
 
                
1271
 
                CairoDockModuleInstance *pOneInstance;
1272
 
                GList *pElement;
1273
 
                for (pElement = pModule->pInstancesList; pElement != NULL; pElement = pElement->next)
1274
 
                {
1275
 
                        pOneInstance = pElement->data;
1276
 
                        if (strcmp (pOneInstance->cConfFilePath, cLastInstanceFilePath) == 0)
1277
 
                        {
1278
 
                                gchar *cCommand = g_strdup_printf ("mv \"%s\" \"%s\"", cLastInstanceFilePath, cConfFilePath);
1279
 
                                int r = system (cCommand);
1280
 
                                g_free (cCommand);
1281
 
                                
1282
 
                                g_free (pOneInstance->cConfFilePath);
1283
 
                                pOneInstance->cConfFilePath = cConfFilePath;
1284
 
                                cConfFilePath = NULL;
1285
 
                                break ;
1286
 
                        }
1287
 
                }
1288
 
                
1289
 
                g_free (cLastInstanceFilePath);
1290
 
        }
1291
 
        g_free (cConfFilePath);
1292
 
}
1293
 
 
1294
 
void cairo_dock_add_module_instance (CairoDockModule *pModule)
1295
 
{
1296
 
        if (pModule->pInstancesList == NULL)
1297
 
        {
1298
 
                cd_warning ("This module has not been instanciated yet");
1299
 
                return ;
1300
 
        }
1301
 
        int iNbInstances = g_list_length (pModule->pInstancesList);
1302
 
        gchar *cInstanceFilePath = g_strdup_printf ("%s-%d", pModule->cConfFilePath, iNbInstances);
1303
 
        if (! g_file_test (cInstanceFilePath, G_FILE_TEST_EXISTS))
1304
 
        {
1305
 
                gchar *cCommand = g_strdup_printf ("cp %s/%s %s", pModule->pVisitCard->cShareDataDir, pModule->pVisitCard->cConfFileName, cInstanceFilePath);
1306
 
                cd_debug (cCommand);
1307
 
                int r = system (cCommand);
1308
 
                g_free (cCommand);
1309
 
        }
1310
 
        
1311
 
        CairoDockModuleInstance *pNewInstance = cairo_dock_instanciate_module (pModule, cInstanceFilePath);  // prend le 'cInstanceFilePath'.
1312
 
        
1313
 
        if (pNewInstance != NULL && pNewInstance->pDock)
1314
 
        {
1315
 
                cairo_dock_update_dock_size (pNewInstance->pDock);
1316
 
        }
1317
 
}
1318
 
 
1319
 
 
1320
 
void cairo_dock_read_module_config (GKeyFile *pKeyFile, CairoDockModuleInstance *pInstance)
1321
 
{
1322
 
        CairoDockModuleInterface *pInterface = pInstance->pModule->pInterface;
1323
 
        CairoDockVisitCard *pVisitCard = pInstance->pModule->pVisitCard;
1324
 
        
1325
 
        gboolean bFlushConfFileNeeded = FALSE;
1326
 
        if (pInterface->read_conf_file != NULL)
1327
 
        {       
1328
 
                if (pInterface->reset_config != NULL)
1329
 
                        pInterface->reset_config (pInstance);
1330
 
                if (pVisitCard->iSizeOfConfig != 0)
1331
 
                        memset (((gpointer)pInstance)+sizeof(CairoDockModuleInstance), 0, pVisitCard->iSizeOfConfig);
1332
 
                
1333
 
                bFlushConfFileNeeded = g_key_file_has_group (pKeyFile, "Desklet") && ! g_key_file_has_key (pKeyFile, "Desklet", "accessibility", NULL);  // petit hack des familles ^_^
1334
 
                bFlushConfFileNeeded |= pInterface->read_conf_file (pInstance, pKeyFile);
1335
 
        }
1336
 
        if (! bFlushConfFileNeeded)
1337
 
                bFlushConfFileNeeded = cairo_dock_conf_file_needs_update (pKeyFile, pVisitCard->cModuleVersion);
1338
 
        if (bFlushConfFileNeeded)
1339
 
                cairo_dock_flush_conf_file (pKeyFile, pInstance->cConfFilePath, pVisitCard->cShareDataDir, pVisitCard->cConfFileName);
1340
 
}
1341
 
 
1342
 
 
1343
 
static int s_iNbUsedSlots = 0;
1344
 
static CairoDockModuleInstance *s_pUsedSlots[CAIRO_DOCK_NB_DATA_SLOT+1];
1345
 
gboolean cairo_dock_reserve_data_slot (CairoDockModuleInstance *pInstance)
1346
 
{
1347
 
        g_return_val_if_fail (s_iNbUsedSlots < CAIRO_DOCK_NB_DATA_SLOT, FALSE);
1348
 
        if (s_iNbUsedSlots == 0)
1349
 
                memset (s_pUsedSlots, 0, (CAIRO_DOCK_NB_DATA_SLOT+1) * sizeof (CairoDockModuleInstance*));
1350
 
        
1351
 
        if (pInstance->iSlotID == 0)
1352
 
        {
1353
 
                s_iNbUsedSlots ++;
1354
 
                if (s_pUsedSlots[s_iNbUsedSlots] == NULL)
1355
 
                {
1356
 
                        pInstance->iSlotID = s_iNbUsedSlots;
1357
 
                        s_pUsedSlots[s_iNbUsedSlots] = pInstance;
1358
 
                }
1359
 
                else
1360
 
                {
1361
 
                        int i;
1362
 
                        for (i = 1; i < s_iNbUsedSlots; i ++)
1363
 
                        {
1364
 
                                if (s_pUsedSlots[i] == NULL)
1365
 
                                {
1366
 
                                        pInstance->iSlotID = i;
1367
 
                                        s_pUsedSlots[i] = pInstance;
1368
 
                                        break ;
1369
 
                                }
1370
 
                        }
1371
 
                }
1372
 
        }
1373
 
        return TRUE;
1374
 
}
1375
 
 
1376
 
void cairo_dock_release_data_slot (CairoDockModuleInstance *pInstance)
1377
 
{
1378
 
        if (pInstance->iSlotID == 0)
1379
 
                return;
1380
 
        s_iNbUsedSlots --;
1381
 
        s_pUsedSlots[pInstance->iSlotID] = NULL;
1382
 
        pInstance->iSlotID = 0;
1383
 
}
1384
 
 
1385
 
 
1386
 
 
1387
 
#define REGISTER_INTERNAL_MODULE(cGroupName) \
1388
 
        pModule = g_new0 (CairoDockInternalModule, 1);\
1389
 
        cairo_dock_pre_init_##cGroupName (pModule);\
1390
 
        g_hash_table_insert (pModuleTable, (gpointer)pModule->cModuleName, pModule)
1391
 
void cairo_dock_preload_internal_modules (GHashTable *pModuleTable)
1392
 
{
1393
 
        cd_message ("");
1394
 
        CairoDockInternalModule *pModule;
1395
 
        
1396
 
        REGISTER_INTERNAL_MODULE (Position);
1397
 
        REGISTER_INTERNAL_MODULE (Accessibility);
1398
 
        REGISTER_INTERNAL_MODULE (System);
1399
 
        REGISTER_INTERNAL_MODULE (TaskBar);
1400
 
        REGISTER_INTERNAL_MODULE (Background);
1401
 
        REGISTER_INTERNAL_MODULE (Icons);
1402
 
        REGISTER_INTERNAL_MODULE (Labels);
1403
 
        REGISTER_INTERNAL_MODULE (Dialogs);
1404
 
        REGISTER_INTERNAL_MODULE (Indicators);
1405
 
        REGISTER_INTERNAL_MODULE (Views);
1406
 
        REGISTER_INTERNAL_MODULE (Desklets);
1407
 
}
1408
 
 
1409
 
void cairo_dock_reload_internal_module_from_keyfile (CairoDockInternalModule *pModule, GKeyFile *pKeyFile)
1410
 
{
1411
 
        gpointer *pPrevConfig = g_memdup (pModule->pConfig, pModule->iSizeOfConfig);
1412
 
        memset (pModule->pConfig, 0, pModule->iSizeOfConfig);
1413
 
        
1414
 
        pModule->get_config (pKeyFile, pModule->pConfig);
1415
 
        
1416
 
        if (g_pMainDock != NULL)  // si on est en mode maintenance, inutile de recharger.
1417
 
                pModule->reload (pPrevConfig, pModule->pConfig);
1418
 
        
1419
 
        if (pModule->reset_config)
1420
 
                pModule->reset_config (pPrevConfig);
1421
 
        g_free (pPrevConfig);
1422
 
}
1423
 
 
1424
 
void cairo_dock_reload_internal_module (CairoDockInternalModule *pModule, const gchar *cConfFilePath)
1425
 
{
1426
 
        g_return_if_fail (pModule != NULL);
1427
 
        GKeyFile *pKeyFile = cairo_dock_open_key_file (cConfFilePath);
1428
 
        if (pKeyFile == NULL)
1429
 
                return;
1430
 
        
1431
 
        cairo_dock_reload_internal_module_from_keyfile (pModule, pKeyFile);
1432
 
        
1433
 
        g_key_file_free (pKeyFile);
1434
 
}
1435
 
 
1436
 
CairoDockInternalModule *cairo_dock_find_internal_module_from_name (const gchar *cModuleName)
1437
 
{
1438
 
        //g_print ("%s (%s)\n", __func__, cModuleName);
1439
 
        g_return_val_if_fail (cModuleName != NULL, NULL);
1440
 
        return g_hash_table_lookup (s_hInternalModuleTable, cModuleName);
1441
 
}
1442
 
 
1443
 
gboolean cairo_dock_get_internal_module_config (CairoDockInternalModule *pModule, GKeyFile *pKeyFile)
1444
 
{
1445
 
        if (pModule->reset_config)
1446
 
        {
1447
 
                pModule->reset_config (pModule->pConfig);
1448
 
        }
1449
 
        memset (pModule->pConfig, 0, pModule->iSizeOfConfig);
1450
 
        return pModule->get_config (pKeyFile, pModule->pConfig);
1451
 
}
1452
 
 
1453
 
static void _cairo_dock_get_one_internal_module_config (gchar *cModuleName, CairoDockInternalModule *pModule, gpointer *data)
1454
 
{
1455
 
        GKeyFile *pKeyFile = data[0];
1456
 
        gboolean *bFlushConfFileNeeded = data[1];
1457
 
        *bFlushConfFileNeeded |= cairo_dock_get_internal_module_config (pModule, pKeyFile);
1458
 
}
1459
 
gboolean cairo_dock_get_global_config (GKeyFile *pKeyFile)
1460
 
{
1461
 
        gboolean bFlushConfFileNeeded = FALSE;
1462
 
        gpointer data[2] = {pKeyFile, &bFlushConfFileNeeded};
1463
 
        g_hash_table_foreach (s_hInternalModuleTable, (GHFunc) _cairo_dock_get_one_internal_module_config, data);
1464
 
        return bFlushConfFileNeeded;
1465
 
}
1466
 
 
1467
 
 
1468
 
void cairo_dock_popup_module_instance_description (CairoDockModuleInstance *pModuleInstance)
1469
 
{
1470
 
        gchar *cDescription = g_strdup_printf ("%s (v%s) by %s\n%s",
1471
 
                pModuleInstance->pModule->pVisitCard->cModuleName,
1472
 
                pModuleInstance->pModule->pVisitCard->cModuleVersion,
1473
 
                pModuleInstance->pModule->pVisitCard->cAuthor,
1474
 
                dgettext (pModuleInstance->pModule->pVisitCard->cGettextDomain,
1475
 
                        pModuleInstance->pModule->pVisitCard->cDescription));
1476
 
        
1477
 
        cairo_dock_show_temporary_dialog_with_icon (cDescription, pModuleInstance->pIcon, pModuleInstance->pContainer, 0, pModuleInstance->pModule->pVisitCard->cIconFilePath);
1478
 
        g_free (cDescription);
1479
 
}
1480
 
 
1481
 
 
1482
 
void cairo_dock_attach_to_another_module (CairoDockVisitCard *pVisitCard, const gchar *cOtherModuleName)
1483
 
{
1484
 
        CairoDockInternalModule *pInternalModule = cairo_dock_find_internal_module_from_name (cOtherModuleName);
1485
 
        g_return_if_fail (pInternalModule != NULL && pInternalModule->iCategory == pVisitCard->iCategory && pVisitCard->cInternalModule == NULL);
1486
 
        
1487
 
        pInternalModule->pExternalModules = g_list_prepend (pInternalModule->pExternalModules, (gpointer)pVisitCard->cModuleName);
1488
 
        pVisitCard->cInternalModule = cOtherModuleName;
1489
 
}
1490
 
 
1491
 
 
1492
 
int cairo_dock_get_nb_modules (void)
1493
 
{
1494
 
        return g_hash_table_size (s_hModuleTable);
1495
 
}