~ubuntu-branches/ubuntu/oneiric/cairo-dock/oneiric

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mto: (18.1.1 cairo-dock) (19.1.1 cairo-dock)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20100809232612-pocdxliaxjdetm37
Tags: upstream-2.2.0~0beta4
ImportĀ upstreamĀ versionĀ 2.2.0~0beta4

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