Statistics
| Revision:

root / src / plugin.c @ 2821

History | View | Annotate | Download (30.1 KB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2011 Hiroyuki Yamamoto
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 */
19

    
20
#include <glib.h>
21
#include <gmodule.h>
22
#include <gtk/gtk.h>
23

    
24
#include "plugin.h"
25
#include "utils.h"
26
#include "folder.h"
27
#include "sylpheed-marshal.h"
28

    
29
G_DEFINE_TYPE(SylPlugin, syl_plugin, G_TYPE_OBJECT);
30

    
31
enum {
32
        PLUGIN_LOAD,
33
        PLUGIN_UNLOAD,
34
        FOLDERVIEW_MENU_POPUP,
35
        SUMMARYVIEW_MENU_POPUP,
36
        COMPOSE_CREATED,
37
        COMPOSE_DESTROY,
38
        TEXTVIEW_MENU_POPUP,
39
        LAST_SIGNAL
40
};
41

    
42
#define GETFUNC(sym)        { func = syl_plugin_lookup_symbol(sym); }
43

    
44
#define SAFE_CALL(func_ptr)                { if (func_ptr) func_ptr(); }
45
#define SAFE_CALL_RET(func_ptr)                (func_ptr ? func_ptr() : NULL)
46
#define SAFE_CALL_RET_VAL(func_ptr, retval) \
47
                                        (func_ptr ? func_ptr() : retval)
48
#define SAFE_CALL_ARG1(func_ptr, arg1)        { if (func_ptr) func_ptr(arg1); }
49
#define SAFE_CALL_ARG1_RET(func_ptr, arg1) \
50
                                (func_ptr ? func_ptr(arg1) : NULL)
51
#define SAFE_CALL_ARG1_RET_VAL(func_ptr, arg1, retval) \
52
                                (func_ptr ? func_ptr(arg1) : retval)
53
#define SAFE_CALL_ARG2(func_ptr, arg1, arg2) \
54
                                { if (func_ptr) func_ptr(arg1, arg2); }
55
#define SAFE_CALL_ARG2_RET(func_ptr, arg1, arg2) \
56
                                (func_ptr ? func_ptr(arg1, arg2) : NULL)
57
#define SAFE_CALL_ARG2_RET_VAL(func_ptr, arg1, arg2, retval) \
58
                                (func_ptr ? func_ptr(arg1, arg2) : retval)
59
#define SAFE_CALL_ARG3(func_ptr, arg1, arg2, arg3) \
60
                                { if (func_ptr) func_ptr(arg1, arg2, arg3); }
61
#define SAFE_CALL_ARG3_RET(func_ptr, arg1, arg2, arg3) \
62
                                (func_ptr ? func_ptr(arg1, arg2, arg3) : NULL)
63
#define SAFE_CALL_ARG3_RET_VAL(func_ptr, arg1, arg2, arg3, retval) \
64
                                (func_ptr ? func_ptr(arg1, arg2, arg3) : retval)
65
#define SAFE_CALL_ARG4(func_ptr, arg1, arg2, arg3, arg4) \
66
                                { if (func_ptr) func_ptr(arg1, arg2, arg3); }
67
#define SAFE_CALL_ARG4_RET(func_ptr, arg1, arg2, arg3, arg4) \
68
                                (func_ptr ? func_ptr(arg1, arg2, arg3, arg4) : NULL)
69
#define SAFE_CALL_ARG4_RET_VAL(func_ptr, arg1, arg2, arg3, arg4, retval) \
70
                                (func_ptr ? func_ptr(arg1, arg2, arg3, arg4) : retval)
71

    
72
#define CALL_VOID_POINTER(getobj, sym)                \
73
{                                                \
74
        void (*func)(gpointer);                        \
75
        gpointer obj;                                \
76
        obj = getobj();                                \
77
        if (obj) {                                \
78
                GETFUNC(sym);                        \
79
                SAFE_CALL_ARG1(func, obj);        \
80
        }                                        \
81
}
82

    
83

    
84
static guint plugin_signals[LAST_SIGNAL] = { 0 };
85

    
86
static GHashTable *sym_table = NULL;
87
static GSList *module_list = NULL;
88
static GObject *plugin_obj = NULL;
89

    
90
static void syl_plugin_init(SylPlugin *self)
91
{
92
}
93

    
94
static void syl_plugin_class_init(SylPluginClass *klass)
95
{
96
        GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
97

    
98
        plugin_signals[PLUGIN_LOAD] =
99
                g_signal_new("plugin-load",
100
                             G_TYPE_FROM_CLASS(gobject_class),
101
                             G_SIGNAL_RUN_FIRST,
102
                             G_STRUCT_OFFSET(SylPluginClass, plugin_load),
103
                             NULL, NULL,
104
                             g_cclosure_marshal_VOID__POINTER,
105
                             G_TYPE_NONE,
106
                             1,
107
                             G_TYPE_POINTER);
108
        plugin_signals[PLUGIN_UNLOAD] =
109
                g_signal_new("plugin-unload",
110
                             G_TYPE_FROM_CLASS(gobject_class),
111
                             G_SIGNAL_RUN_FIRST,
112
                             G_STRUCT_OFFSET(SylPluginClass, plugin_unload),
113
                             NULL, NULL,
114
                             g_cclosure_marshal_VOID__POINTER,
115
                             G_TYPE_NONE,
116
                             1,
117
                             G_TYPE_POINTER);
118
        plugin_signals[FOLDERVIEW_MENU_POPUP] =
119
                g_signal_new("folderview-menu-popup",
120
                             G_TYPE_FROM_CLASS(gobject_class),
121
                             G_SIGNAL_RUN_FIRST,
122
                             G_STRUCT_OFFSET(SylPluginClass,
123
                                             folderview_menu_popup),
124
                             NULL, NULL,
125
                             g_cclosure_marshal_VOID__POINTER,
126
                             G_TYPE_NONE,
127
                             1,
128
                             G_TYPE_POINTER);
129
        plugin_signals[SUMMARYVIEW_MENU_POPUP] =
130
                g_signal_new("summaryview-menu-popup",
131
                             G_TYPE_FROM_CLASS(gobject_class),
132
                             G_SIGNAL_RUN_FIRST,
133
                             G_STRUCT_OFFSET(SylPluginClass,
134
                                             summaryview_menu_popup),
135
                             NULL, NULL,
136
                             g_cclosure_marshal_VOID__POINTER,
137
                             G_TYPE_NONE,
138
                             1,
139
                             G_TYPE_POINTER);
140
        plugin_signals[COMPOSE_CREATED] =
141
                g_signal_new("compose-created",
142
                             G_TYPE_FROM_CLASS(gobject_class),
143
                             G_SIGNAL_RUN_FIRST,
144
                             G_STRUCT_OFFSET(SylPluginClass, compose_created),
145
                             NULL, NULL,
146
                             g_cclosure_marshal_VOID__POINTER,
147
                             G_TYPE_NONE,
148
                             1,
149
                             G_TYPE_POINTER);
150
        plugin_signals[COMPOSE_DESTROY] =
151
                g_signal_new("compose-destroy",
152
                             G_TYPE_FROM_CLASS(gobject_class),
153
                             G_SIGNAL_RUN_FIRST,
154
                             G_STRUCT_OFFSET(SylPluginClass, compose_destroy),
155
                             NULL, NULL,
156
                             g_cclosure_marshal_VOID__POINTER,
157
                             G_TYPE_NONE,
158
                             1,
159
                             G_TYPE_POINTER);
160
        plugin_signals[TEXTVIEW_MENU_POPUP] =
161
                g_signal_new("textview-menu-popup",
162
                             G_TYPE_FROM_CLASS(gobject_class),
163
                             G_SIGNAL_RUN_FIRST,
164
                             G_STRUCT_OFFSET(SylPluginClass,
165
                                             textview_menu_popup),
166
                             NULL, NULL,
167
                             sylpheed_marshal_VOID__POINTER_POINTER_STRING_STRING_POINTER,
168
                             G_TYPE_NONE,
169
                             5,
170
                             G_TYPE_POINTER,
171
                             G_TYPE_POINTER,
172
                             G_TYPE_STRING,
173
                             G_TYPE_STRING,
174
                             G_TYPE_POINTER);
175
}
176

    
177
void syl_plugin_signal_connect(const gchar *name, GCallback callback,
178
                               gpointer data)
179
{
180
        g_signal_connect(plugin_obj, name, callback, data);
181
}
182

    
183
void syl_plugin_signal_disconnect(gpointer func, gpointer data)
184
{
185
        g_signal_handlers_disconnect_by_func(plugin_obj, func, data);
186
}
187

    
188
void syl_plugin_signal_emit(const gchar *name, ...)
189
{
190
        guint signal_id;
191

    
192
        if (g_signal_parse_name(name, G_TYPE_FROM_INSTANCE(plugin_obj), &signal_id, NULL, FALSE)) {
193
                 \
194
                                va_list var_args;
195
                va_start(var_args, name);
196
                g_signal_emit_valist(plugin_obj, signal_id, 0, var_args);
197
                va_end(var_args);
198
        } else
199
                g_warning("%s: signal '%s' not found", G_STRLOC, name);
200
}
201

    
202
gint syl_plugin_init_lib(void)
203
{
204
        if (!g_module_supported()) {
205
                g_warning("Plug-in is not supported.");
206
                return -1;
207
        }
208

    
209
        if (!sym_table) {
210
                sym_table = g_hash_table_new(g_str_hash, g_str_equal);
211
        }
212

    
213
        if (!plugin_obj) {
214
                plugin_obj = g_object_new(SYL_TYPE_PLUGIN, NULL);
215
        }
216

    
217
        return 0;
218
}
219

    
220
gint syl_plugin_load(const gchar *name)
221
{
222
        GModule *module;
223
        SylPluginLoadFunc load_func = NULL;
224
        gchar *file;
225

    
226
        g_return_val_if_fail(name != NULL, -1);
227

    
228
        debug_print("syl_plugin_load: loading %s\n", name);
229

    
230
        if (!g_path_is_absolute(name))
231
                file = g_strconcat(PLUGINDIR, G_DIR_SEPARATOR_S, name, NULL);
232
        else
233
                file = g_strdup(name);
234

    
235
        module = g_module_open(file, G_MODULE_BIND_LAZY);
236
        if (!module) {
237
                g_warning("Cannot open module: %s: %s", name, g_module_error());
238
                g_free(file);
239
                return -1;
240
        }
241
        if (g_slist_find(module_list, module)) {
242
                g_warning("Module %s is already loaded", name);
243
                g_free(file);
244
                return -1;
245
        }
246

    
247
        if (g_module_symbol(module, "plugin_load", (gpointer *)&load_func)) {
248
                if (!syl_plugin_check_version(module)) {
249
                        g_warning("Version check failed. Skipping: %s", name);
250
                        g_module_close(module);
251
                        g_free(file);
252
                        return -1;
253
                }
254

    
255
                debug_print("calling plugin_load() in %s\n",
256
                            g_module_name(module));
257
                load_func();
258
                module_list = g_slist_prepend(module_list, module);
259
                g_signal_emit(plugin_obj, plugin_signals[PLUGIN_LOAD], 0, module);
260
        } else {
261
                g_warning("Cannot get symbol: %s: %s", name, g_module_error());
262
                g_module_close(module);
263
                g_free(file);
264
                return -1;
265
        }
266

    
267
        g_free(file);
268

    
269
        return 0;
270
}
271

    
272
gint syl_plugin_load_all(const gchar *dir)
273
{
274
        GDir *d;
275
        const gchar *dir_name;
276
        gchar *path;
277
        gint count = 0;
278

    
279
        g_return_val_if_fail(dir != NULL, -1);
280

    
281
        debug_print("loading plugins from directory: %s\n", dir);
282

    
283
        if ((d = g_dir_open(dir, 0, NULL)) == NULL) {
284
                debug_print("failed to open directory: %s\n", dir);
285
                return -1;
286
        }
287

    
288
        while ((dir_name = g_dir_read_name(d)) != NULL) {
289
                if (!g_str_has_suffix(dir_name, "." G_MODULE_SUFFIX))
290
                        continue;
291
                path = g_strconcat(dir, G_DIR_SEPARATOR_S, dir_name, NULL);
292
                if (syl_plugin_load(path) == 0)
293
                        count++;
294
                g_free(path);
295
        }
296

    
297
        g_dir_close(d);
298

    
299
        return count;
300
}
301

    
302
void syl_plugin_unload_all(void)
303
{
304
        GSList *cur;
305

    
306
        for (cur = module_list; cur != NULL; cur = cur->next) {
307
                GModule *module = (GModule *)cur->data;
308
                SylPluginUnloadFunc unload_func = NULL;
309

    
310
                if (g_module_symbol(module, "plugin_unload",
311
                                    (gpointer *)&unload_func)) {
312
                        g_signal_emit(plugin_obj, plugin_signals[PLUGIN_UNLOAD],
313
                                      0, module);
314
                        debug_print("calling plugin_unload() in %s\n",
315
                                    g_module_name(module));
316
                        unload_func();
317
                } else {
318
                        g_warning("Cannot get symbol: %s", g_module_error());
319
                }
320
                if (!g_module_close(module)) {
321
                        g_warning("Module unload failed: %s", g_module_error());
322
                }
323
        }
324

    
325
        g_slist_free(module_list);
326
        module_list = NULL;
327
}
328

    
329
GSList *syl_plugin_get_module_list(void)
330
{
331
        return module_list;
332
}
333

    
334
SylPluginInfo *syl_plugin_get_info(GModule *module)
335
{
336
        SylPluginInfo * (*plugin_info_func)(void);
337

    
338
        g_return_val_if_fail(module != NULL, NULL);
339

    
340
        debug_print("getting plugin information of %s\n",
341
                    g_module_name(module));
342

    
343
        if (g_module_symbol(module, "plugin_info",
344
                            (gpointer *)&plugin_info_func)) {
345
                debug_print("calling plugin_info() in %s\n",
346
                            g_module_name(module));
347
                return plugin_info_func();
348
        } else {
349
                g_warning("Cannot get symbol: %s: %s", g_module_name(module),
350
                          g_module_error());
351
                return NULL;
352
        }
353
}
354

    
355
gboolean syl_plugin_check_version(GModule *module)
356
{
357
        gint (*version_func)(void);
358
        gint ver;
359
        gint a_major;
360
        gint a_minor;
361
        gint p_major;
362
        gint p_minor;
363

    
364
        g_return_val_if_fail(module != NULL, FALSE);
365

    
366
        if (g_module_symbol(module, "plugin_interface_version",
367
                            (gpointer *)&version_func)) {
368
                debug_print("calling plugin_interface_version() in %s\n",
369
                            g_module_name(module));
370
                ver = version_func();
371
        } else {
372
                g_warning("Cannot get symbol: %s: %s", g_module_name(module),
373
                          g_module_error());
374
                return FALSE;
375
        }
376

    
377
        a_major = SYL_PLUGIN_INTERFACE_VERSION & 0xff00;
378
        a_minor = SYL_PLUGIN_INTERFACE_VERSION & 0x00ff;
379
        p_major = ver & 0xff00;
380
        p_minor = ver & 0x00ff;
381
        if (a_major == p_major && a_minor >= p_minor) {
382
                debug_print("Version OK: plugin: %d, app: %d\n",
383
                            ver, SYL_PLUGIN_INTERFACE_VERSION);
384
                return TRUE;
385
        } else {
386
                g_warning("Plugin interface version mismatch: plugin: %d, app: %d", ver, SYL_PLUGIN_INTERFACE_VERSION);
387
                return FALSE;
388
        }
389
}
390

    
391
gint syl_plugin_add_symbol(const gchar *name, gpointer sym)
392
{
393
        g_hash_table_insert(sym_table, (gpointer)name, sym);
394
        return 0;
395
}
396

    
397
gpointer syl_plugin_lookup_symbol(const gchar *name)
398
{
399
        return g_hash_table_lookup(sym_table, name);
400
}
401

    
402
const gchar *syl_plugin_get_prog_version(void)
403
{
404
        gpointer sym;
405

    
406
        sym = syl_plugin_lookup_symbol("prog_version");
407
        return (gchar *)sym;
408
}
409

    
410
void syl_plugin_main_window_lock(void)
411
{
412
        CALL_VOID_POINTER(syl_plugin_main_window_get,
413
                          "main_window_lock");
414
}
415

    
416
void syl_plugin_main_window_unlock(void)
417
{
418
        CALL_VOID_POINTER(syl_plugin_main_window_get,
419
                          "main_window_unlock");
420
}
421

    
422
gpointer syl_plugin_main_window_get(void)
423
{
424
        gpointer (*func)(void);
425

    
426
        func = syl_plugin_lookup_symbol("main_window_get");
427
        return SAFE_CALL_RET(func);
428
}
429

    
430
void syl_plugin_main_window_popup(gpointer mainwin)
431
{
432
        void (*func)(gpointer);
433

    
434
        func = syl_plugin_lookup_symbol("main_window_popup");
435
        SAFE_CALL_ARG1(func, mainwin);
436
}
437

    
438
GtkWidget *syl_plugin_main_window_get_statusbar(void)
439
{
440
        gpointer widget;
441

    
442
        widget = syl_plugin_lookup_symbol("main_window_statusbar");
443
        return GTK_WIDGET(widget);
444
}
445

    
446
void syl_plugin_app_will_exit(gboolean force)
447
{
448
        void (*func)(gboolean);
449

    
450
        func = syl_plugin_lookup_symbol("app_will_exit");
451
        SAFE_CALL_ARG1(func, force);
452
}
453

    
454
static GtkItemFactory *get_item_factory(const gchar *path)
455
{
456
        GtkItemFactory *ifactory;
457

    
458
        if (!path)
459
                return NULL;
460

    
461
        if (strncmp(path, "<Main>", 6) == 0)
462
                ifactory = syl_plugin_lookup_symbol("main_window_menu_factory");
463
        else if (strncmp(path, "<MailFolder>", 12) == 0)
464
                ifactory = syl_plugin_lookup_symbol("folderview_mail_popup_factory");
465
        else if (strncmp(path, "<IMAPFolder>", 12) == 0)
466
                ifactory = syl_plugin_lookup_symbol("folderview_imap_popup_factory");
467
        else if (strncmp(path, "<NewsFolder>", 12) == 0)
468
                ifactory = syl_plugin_lookup_symbol("folderview_news_popup_factory");
469
        else if (strncmp(path, "<SummaryView>", 13) == 0)
470
                ifactory = syl_plugin_lookup_symbol("summaryview_popup_factory");
471
        else
472
                ifactory = syl_plugin_lookup_symbol("main_window_menu_factory");
473

    
474
        return ifactory;
475
}
476

    
477
gint syl_plugin_add_menuitem(const gchar *parent, const gchar *label,
478
                             SylPluginCallbackFunc func, gpointer data)
479
{
480
        GtkItemFactory *ifactory;
481
        GtkWidget *menu;
482
        GtkWidget *menuitem;
483

    
484
        if (!parent)
485
                return -1;
486

    
487
        ifactory = get_item_factory(parent);
488
        if (!ifactory)
489
                return -1;
490

    
491
        menu = gtk_item_factory_get_widget(ifactory, parent);
492
        if (!menu)
493
                return -1;
494

    
495
        if (label)
496
                menuitem = gtk_menu_item_new_with_label(label);
497
        else {
498
                menuitem = gtk_menu_item_new();
499
                gtk_widget_set_sensitive(menuitem, FALSE);
500
        }
501
        gtk_widget_show(menuitem);
502
        gtk_menu_append(GTK_MENU(menu), menuitem);
503
        if (func)
504
                g_signal_connect(G_OBJECT(menuitem), "activate",
505
                                 G_CALLBACK(func), data);
506

    
507
        return 0;
508
}
509

    
510
gint syl_plugin_add_factory_item(const gchar *parent, const gchar *label,
511
                                 SylPluginCallbackFunc func, gpointer data)
512
{
513
        GtkItemFactory *ifactory;
514
        GtkItemFactoryEntry entry = {NULL, NULL, NULL, 0, NULL};
515

    
516
        if (!parent)
517
                return -1;
518

    
519
        ifactory = get_item_factory(parent);
520
        if (!ifactory)
521
                return -1;
522

    
523
        if (label) {
524
                entry.path = (gchar *)label;
525
                if (g_str_has_suffix(label, "/---"))
526
                        entry.item_type = "<Separator>";
527
                else
528
                        entry.item_type = NULL;
529
        } else {
530
                entry.path = "/---";
531
                entry.item_type = "<Separator>";
532
        }
533
        entry.callback = func;
534
        g_print("entry.path = %s\n", entry.path);
535

    
536
        gtk_item_factory_create_item(ifactory, &entry, data, 2);
537

    
538
        return 0;
539
}
540

    
541
void syl_plugin_menu_set_sensitive(const gchar *path, gboolean sensitive)
542
{
543
        GtkItemFactory *ifactory;
544
        GtkWidget *widget;
545

    
546
        g_return_if_fail(path != NULL);
547

    
548
        ifactory = get_item_factory(path);
549
        if (!ifactory)
550
                return;
551

    
552
        widget = gtk_item_factory_get_item(ifactory, path);
553
        gtk_widget_set_sensitive(widget, sensitive);
554
}
555

    
556
void syl_plugin_menu_set_sensitive_all(GtkMenuShell *menu_shell,
557
                                       gboolean sensitive)
558
{
559
        GList *cur;
560

    
561
        for (cur = menu_shell->children; cur != NULL; cur = cur->next)
562
                gtk_widget_set_sensitive(GTK_WIDGET(cur->data), sensitive);
563
}
564

    
565
void syl_plugin_menu_set_active(const gchar *path, gboolean is_active)
566
{
567
        GtkItemFactory *ifactory;
568
        GtkWidget *widget;
569

    
570
        g_return_if_fail(path != NULL);
571

    
572
        ifactory = get_item_factory(path);
573
        if (!ifactory)
574
                return;
575

    
576
        widget = gtk_item_factory_get_item(ifactory, path);
577
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), is_active);
578
}
579

    
580
gpointer syl_plugin_folderview_get(void)
581
{
582
        gpointer (*func)(void);
583
        GETFUNC("folderview_get");
584
        return SAFE_CALL_RET(func);
585
}
586

    
587
void syl_plugin_folderview_add_sub_widget(GtkWidget *widget)
588
{
589
        void (*func)(gpointer, GtkWidget *);
590
        gpointer folderview;
591

    
592
        folderview = syl_plugin_folderview_get();
593
        if (folderview) {
594
                GETFUNC("folderview_add_sub_widget");
595
                SAFE_CALL_ARG2(func, folderview, widget);
596
        }
597
}
598

    
599
void syl_plugin_folderview_select(FolderItem *item)
600
{
601
        void (*func)(gpointer, FolderItem *);
602
        gpointer folderview;
603

    
604
        folderview = syl_plugin_folderview_get();
605
        if (folderview) {
606
                GETFUNC("folderview_select");
607
                SAFE_CALL_ARG2(func, folderview, item);
608
        }
609
}
610

    
611
void syl_plugin_folderview_unselect(void)
612
{
613
        CALL_VOID_POINTER(syl_plugin_folderview_get,
614
                          "folderview_unselect");
615
}
616

    
617
void syl_plugin_folderview_select_next_unread(void)
618
{
619
        CALL_VOID_POINTER(syl_plugin_folderview_get,
620
                          "folderview_select_next_unread");
621
}
622

    
623
FolderItem *syl_plugin_folderview_get_selected_item(void)
624
{
625
        FolderItem * (*func)(gpointer);
626
        gpointer folderview;
627

    
628
        folderview = syl_plugin_folderview_get();
629
        if (folderview) {
630
                GETFUNC("folderview_get_selected_item");
631
                return SAFE_CALL_ARG1_RET(func, folderview);
632
        }
633

    
634
        return NULL;
635
}
636

    
637
gint syl_plugin_folderview_check_new(Folder *folder)
638
{
639
        gint (*func)(Folder *);
640
        GETFUNC("folderview_check_new");
641
        return SAFE_CALL_ARG1_RET_VAL(func, folder, FALSE);
642
}
643

    
644
gint syl_plugin_folderview_check_new_item(FolderItem *item)
645
{
646
        gint (*func)(FolderItem *);
647
        GETFUNC("folderview_check_new_item");
648
        return SAFE_CALL_ARG1_RET_VAL(func, item, FALSE);
649
}
650

    
651
gint syl_plugin_folderview_check_new_all(void)
652
{
653
        gint (*func)(void);
654
        GETFUNC("folderview_check_new_all");
655
        return SAFE_CALL_RET_VAL(func, FALSE);
656
}
657

    
658
void syl_plugin_folderview_update_item(FolderItem *item,
659
                                       gboolean update_summary)
660
{
661
        void (*func)(FolderItem *, gboolean);
662
        GETFUNC("folderview_update_item");
663
        SAFE_CALL_ARG2(func, item, update_summary);
664
}
665

    
666
void syl_plugin_folderview_update_item_foreach(GHashTable *table,
667
                                               gboolean update_summary)
668
{
669
        void (*func)(GHashTable *, gboolean);
670
        GETFUNC("folderview_update_item_foreach");
671
        SAFE_CALL_ARG2(func, table, update_summary);
672
}
673

    
674
void syl_plugin_folderview_update_all_updated(gboolean update_summary)
675
{
676
        void (*func)(gboolean);
677
        GETFUNC("folderview_update_all_updated");
678
        SAFE_CALL_ARG1(func, update_summary);
679
}
680

    
681
void syl_plugin_folderview_check_new_selected(void)
682
{
683
        CALL_VOID_POINTER(syl_plugin_folderview_get,
684
                          "folderview_check_new_selected");
685
}
686

    
687
gpointer syl_plugin_summary_view_get(void)
688
{
689
        gpointer sym;
690

    
691
        sym = syl_plugin_lookup_symbol("summaryview");
692
        return sym;
693
}
694

    
695
void syl_plugin_summary_select_by_msgnum(guint msgnum)
696
{
697
        void (*func)(gpointer, guint);
698
        gpointer summary;
699

    
700
        summary = syl_plugin_summary_view_get();
701
        if (summary) {
702
                func = syl_plugin_lookup_symbol("summary_select_by_msgnum");
703
                SAFE_CALL_ARG2(func, summary, msgnum);
704
        }
705
}
706

    
707
gboolean syl_plugin_summary_select_by_msginfo(MsgInfo *msginfo)
708
{
709
        gboolean (*func)(gpointer, MsgInfo *);
710
        gpointer summary;
711

    
712
        summary = syl_plugin_summary_view_get();
713
        if (summary) {
714
                func = syl_plugin_lookup_symbol("summary_select_by_msginfo");
715
                return SAFE_CALL_ARG2_RET_VAL(func, summary, msginfo, FALSE);
716
        }
717

    
718
        return FALSE;
719
}
720

    
721
void syl_plugin_open_message(const gchar *folder_id, guint msgnum)
722
{
723
        FolderItem *item;
724
        MsgInfo *msginfo;
725

    
726
        item = folder_find_item_from_identifier(folder_id);
727
        msginfo = folder_item_get_msginfo(item, msgnum);
728

    
729
        if (msginfo) {
730
                if (!syl_plugin_summary_select_by_msginfo(msginfo)) {
731
                        syl_plugin_open_message_by_new_window(msginfo);
732
                }
733
                procmsg_msginfo_free(msginfo);
734
        }
735
}
736

    
737
void syl_plugin_summary_show_queued_msgs(void)
738
{
739
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
740
                          "summary_show_queued_msgs");
741
}
742

    
743
void syl_plugin_summary_lock(void)
744
{
745
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
746
                          "summary_lock");
747
}
748

    
749
void syl_plugin_summary_unlock(void)
750
{
751
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
752
                          "summary_unlock");
753
}
754

    
755
gboolean syl_plugin_summary_is_locked(void)
756
{
757
        gboolean (*func)(gpointer);
758
        gpointer summary;
759

    
760
        summary = syl_plugin_summary_view_get();
761
        if (summary) {
762
                GETFUNC("summary_is_locked");
763
                return SAFE_CALL_ARG1_RET_VAL(func, summary, FALSE);
764
        }
765

    
766
        return FALSE;
767
}
768

    
769
gboolean syl_plugin_summary_is_read_locked(void)
770
{
771
        gboolean (*func)(gpointer);
772
        gpointer summary;
773

    
774
        summary = syl_plugin_summary_view_get();
775
        if (summary) {
776
                GETFUNC("summary_is_read_locked");
777
                return SAFE_CALL_ARG1_RET_VAL(func, summary, FALSE);
778
        }
779

    
780
        return FALSE;
781
}
782

    
783
void syl_plugin_summary_write_lock(void)
784
{
785
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
786
                          "summary_write_lock");
787
}
788

    
789
void syl_plugin_summary_write_unlock(void)
790
{
791
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
792
                          "summary_write_unlock");
793
}
794

    
795
gboolean syl_plugin_summary_is_write_locked(void)
796
{
797
        gboolean (*func)(gpointer);
798
        gpointer summary;
799

    
800
        summary = syl_plugin_summary_view_get();
801
        if (summary) {
802
                GETFUNC("summary_is_write_locked");
803
                return SAFE_CALL_ARG1_RET_VAL(func, summary, FALSE);
804
        }
805

    
806
        return FALSE;
807
}
808

    
809
FolderItem *syl_plugin_summary_get_current_folder(void)
810
{
811
        FolderItem * (*func)(gpointer);
812
        gpointer summary;
813

    
814
        summary = syl_plugin_summary_view_get();
815
        if (summary) {
816
                GETFUNC("summary_get_current_folder");
817
                return SAFE_CALL_ARG1_RET(func, summary);
818
        }
819

    
820
        return NULL;
821
}
822

    
823
gint syl_plugin_summary_get_selection_type(void)
824
{
825
        gint (*func)(gpointer);
826
        gpointer summary;
827

    
828
        summary = syl_plugin_summary_view_get();
829
        if (summary) {
830
                GETFUNC("summary_get_selection_type");
831
                return SAFE_CALL_ARG1_RET_VAL(func, summary, 0);
832
        }
833

    
834
        return 0;
835
}
836

    
837
GSList *syl_plugin_summary_get_selected_msg_list(void)
838
{
839
        GSList * (*func)(gpointer);
840
        gpointer summary;
841

    
842
        summary = syl_plugin_summary_view_get();
843
        if (summary) {
844
                GETFUNC("summary_get_selected_msg_list");
845
                return SAFE_CALL_ARG1_RET(func, summary);
846
        }
847

    
848
        return NULL;
849
}
850

    
851
GSList *syl_plugin_summary_get_msg_list(void)
852
{
853
        GSList * (*func)(gpointer);
854
        gpointer summary;
855

    
856
        summary = syl_plugin_summary_view_get();
857
        if (summary) {
858
                GETFUNC("summary_get_msg_list");
859
                return SAFE_CALL_ARG1_RET(func, summary);
860
        }
861

    
862
        return NULL;
863
}
864

    
865
void syl_plugin_summary_redisplay_msg(void)
866
{
867
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
868
                          "summary_redisplay_msg");
869
}
870

    
871
void syl_plugin_summary_open_msg(void)
872
{
873
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
874
                          "summary_open_msg");
875
}
876

    
877
void syl_plugin_summary_view_source(void)
878
{
879
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
880
                          "summary_view_source");
881
}
882

    
883
void syl_plugin_summary_reedit(void)
884
{
885
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
886
                          "summary_reedit");
887
}
888

    
889
void syl_plugin_summary_update_selected_rows(void)
890
{
891
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
892
                          "summary_update_selected_rows");
893
}
894

    
895
void syl_plugin_summary_update_by_msgnum(guint msgnum)
896
{
897
        void (*func)(gpointer, guint);
898
        gpointer summary;
899

    
900
        summary = syl_plugin_summary_view_get();
901
        if (summary) {
902
                func = syl_plugin_lookup_symbol("summary_update_by_msgnum");
903
                SAFE_CALL_ARG2(func, summary, msgnum);
904
        }
905
}
906

    
907
gpointer syl_plugin_messageview_create_with_new_window(void)
908
{
909
        gpointer (*func)(void);
910

    
911
        func = syl_plugin_lookup_symbol("messageview_create_with_new_window");
912
        return SAFE_CALL_RET(func);
913
}
914

    
915
void syl_plugin_open_message_by_new_window(MsgInfo *msginfo)
916
{
917
        gpointer msgview;
918
        gpointer (*func)(gpointer, MsgInfo *, gboolean);
919

    
920
        msgview = syl_plugin_messageview_create_with_new_window();
921
        if (msgview) {
922
                func = syl_plugin_lookup_symbol("messageview_show");
923
                SAFE_CALL_ARG3(func, msgview, msginfo, FALSE);
924
        }
925
}
926

    
927

    
928
gpointer syl_plugin_compose_new(PrefsAccount *account, FolderItem *item,
929
                                const gchar *mailto, GPtrArray *attach_files)
930
{
931
        gpointer (*func)(PrefsAccount *, FolderItem *, const gchar *,
932
                         GPtrArray *);
933

    
934
        func = syl_plugin_lookup_symbol("compose_new");
935
        return SAFE_CALL_ARG4_RET(func, account, item, mailto, attach_files);
936
}
937

    
938
void syl_plugin_compose_entry_set(gpointer compose, const gchar *text,
939
                                  gint type)
940
{
941
        void (*func)(gpointer, const gchar *, gint);
942

    
943
        func = syl_plugin_lookup_symbol("compose_entry_set");
944
        SAFE_CALL_ARG3(func, compose, text, type);
945
}
946

    
947
void syl_plugin_compose_entry_append(gpointer compose, const gchar *text,
948
                                     gint type)
949
{
950
        void (*func)(gpointer, const gchar *, gint);
951

    
952
        func = syl_plugin_lookup_symbol("compose_entry_append");
953
        SAFE_CALL_ARG3(func, compose, text, type);
954
}
955

    
956
gchar *syl_plugin_compose_entry_get_text(gpointer compose, gint type)
957
{
958
        gchar * (*func)(gpointer, gint);
959

    
960
        func = syl_plugin_lookup_symbol("compose_entry_get_text");
961
        return SAFE_CALL_ARG2_RET(func, compose, type);
962
}
963

    
964
void syl_plugin_compose_lock(gpointer compose)
965
{
966
        void (*func)(gpointer);
967

    
968
        func = syl_plugin_lookup_symbol("compose_lock");
969
        SAFE_CALL_ARG1(func, compose);
970
}
971

    
972
void syl_plugin_compose_unlock(gpointer compose)
973
{
974
        void (*func)(gpointer);
975

    
976
        func = syl_plugin_lookup_symbol("compose_unlock");
977
        SAFE_CALL_ARG1(func, compose);
978
}
979

    
980

    
981
FolderItem *syl_plugin_folder_sel(Folder *cur_folder, gint sel_type,
982
                                  const gchar *default_folder)
983
{
984
        FolderItem * (*func)(Folder *, gint, const gchar *);
985

    
986
        func = syl_plugin_lookup_symbol("foldersel_folder_sel");
987
        return SAFE_CALL_ARG3_RET(func, cur_folder, sel_type, default_folder);
988
}
989

    
990
FolderItem *syl_plugin_folder_sel_full(Folder *cur_folder, gint sel_type,
991
                                       const gchar *default_folder,
992
                                       const gchar *message)
993
{
994
        FolderItem * (*func)(Folder *, gint, const gchar *, const gchar *);
995

    
996
        func = syl_plugin_lookup_symbol("foldersel_folder_sel_full");
997
        return SAFE_CALL_ARG4_RET(func, cur_folder, sel_type, default_folder,
998
                                  message);
999
}
1000

    
1001
gchar *syl_plugin_input_dialog(const gchar *title, const gchar *message,
1002
                               const gchar *default_string)
1003
{
1004
        gchar * (*func)(const gchar *, const gchar *, const gchar *);
1005

    
1006
        func = syl_plugin_lookup_symbol("input_dialog");
1007
        return SAFE_CALL_ARG3_RET(func, title, message, default_string);
1008
}
1009

    
1010
gchar *syl_plugin_input_dialog_with_invisible(const gchar *title,
1011
                                              const gchar *message,
1012
                                              const gchar *default_string)
1013
{
1014
        gchar * (*func)(const gchar *, const gchar *, const gchar *);
1015

    
1016
        func = syl_plugin_lookup_symbol("input_dialog_with_invisible");
1017
        return SAFE_CALL_ARG3_RET(func, title, message, default_string);
1018
}
1019

    
1020
void syl_plugin_manage_window_set_transient(GtkWindow *window)
1021
{
1022
        void (*func)(GtkWindow *);
1023

    
1024
        func = syl_plugin_lookup_symbol("manage_window_set_transient");
1025
        SAFE_CALL_ARG1(func, window);
1026
}
1027

    
1028
void syl_plugin_manage_window_signals_connect(GtkWindow *window)
1029
{
1030
        void (*func)(GtkWindow *);
1031

    
1032
        func = syl_plugin_lookup_symbol("manage_window_signals_connect");
1033
        SAFE_CALL_ARG1(func, window);
1034
}
1035

    
1036
GtkWidget *syl_plugin_manage_window_get_focus_window(void)
1037
{
1038
        GtkWidget * (*func)(void);
1039

    
1040
        func = syl_plugin_lookup_symbol("manage_window_get_focus_window");
1041
        return SAFE_CALL_RET(func);
1042
}
1043

    
1044
void syl_plugin_inc_mail(void)
1045
{
1046
        void (*func)(gpointer);
1047

    
1048
        func = syl_plugin_lookup_symbol("inc_mail");
1049
        SAFE_CALL_ARG1(func, syl_plugin_main_window_get());
1050
}
1051

    
1052
gboolean syl_plugin_inc_is_active(void)
1053
{
1054
        gboolean (*func)(void);
1055

    
1056
        func = syl_plugin_lookup_symbol("inc_is_active");
1057
        return SAFE_CALL_RET_VAL(func, FALSE);
1058
}
1059

    
1060
void syl_plugin_inc_lock(void)
1061
{
1062
        void (*func)(void);
1063

    
1064
        func = syl_plugin_lookup_symbol("inc_lock");
1065
        SAFE_CALL(func);
1066
}
1067

    
1068
void syl_plugin_inc_unlock(void)
1069
{
1070
        void (*func)(void);
1071

    
1072
        func = syl_plugin_lookup_symbol("inc_unlock");
1073
        SAFE_CALL(func);
1074
}
1075

    
1076
void syl_plugin_update_check(gboolean show_dialog_always)
1077
{
1078
        void (*func)(gboolean);
1079

    
1080
        func = syl_plugin_lookup_symbol("update_check");
1081
        SAFE_CALL_ARG1(func, show_dialog_always);
1082
}
1083

    
1084
void syl_plugin_update_check_set_check_url(const gchar *url)
1085
{
1086
        void (*func)(const gchar *);
1087

    
1088
        func = syl_plugin_lookup_symbol("update_check_set_check_url");
1089
        SAFE_CALL_ARG1(func, url);
1090
}
1091

    
1092
const gchar *syl_plugin_update_check_get_check_url(void)
1093
{
1094
        const gchar * (*func)(void);
1095

    
1096
        func = syl_plugin_lookup_symbol("update_check_get_check_url");
1097
        return SAFE_CALL_RET(func);
1098
}
1099

    
1100
void syl_plugin_update_check_set_download_url(const gchar *url)
1101
{
1102
        void (*func)(const gchar *);
1103

    
1104
        func = syl_plugin_lookup_symbol("update_check_set_download_url");
1105
        SAFE_CALL_ARG1(func, url);
1106
}
1107

    
1108
const gchar *syl_plugin_update_check_get_download_url(void)
1109
{
1110
        const gchar * (*func)(void);
1111

    
1112
        func = syl_plugin_lookup_symbol("update_check_get_download_url");
1113
        return SAFE_CALL_RET(func);
1114
}
1115

    
1116
void syl_plugin_update_check_set_jump_url(const gchar *url)
1117
{
1118
        void (*func)(const gchar *);
1119

    
1120
        func = syl_plugin_lookup_symbol("update_check_set_jump_url");
1121
        SAFE_CALL_ARG1(func, url);
1122
}
1123

    
1124
const gchar *syl_plugin_update_check_get_jump_url(void)
1125
{
1126
        const gchar * (*func)(void);
1127

    
1128
        func = syl_plugin_lookup_symbol("update_check_get_jump_url");
1129
        return SAFE_CALL_RET(func);
1130
}
1131

    
1132
void syl_plugin_update_check_set_check_plugin_url(const gchar *url)
1133
{
1134
        void (*func)(const gchar *);
1135

    
1136
        func = syl_plugin_lookup_symbol("update_check_set_check_plugin_url");
1137
        SAFE_CALL_ARG1(func, url);
1138
}
1139

    
1140
const gchar *syl_plugin_update_check_get_check_plugin_url(void)
1141
{
1142
        const gchar * (*func)(void);
1143

    
1144
        func = syl_plugin_lookup_symbol("update_check_get_check_plugin_url");
1145
        return SAFE_CALL_RET(func);
1146
}
1147

    
1148
void syl_plugin_update_check_set_jump_plugin_url(const gchar *url)
1149
{
1150
        void (*func)(const gchar *);
1151

    
1152
        func = syl_plugin_lookup_symbol("update_check_set_jump_plugin_url");
1153
        SAFE_CALL_ARG1(func, url);
1154
}
1155

    
1156
const gchar *syl_plugin_update_check_get_jump_plugin_url(void)
1157
{
1158
        const gchar * (*func)(void);
1159

    
1160
        func = syl_plugin_lookup_symbol("update_check_get_jump_plugin_url");
1161
        return SAFE_CALL_RET(func);
1162
}
1163

    
1164
gint syl_plugin_alertpanel_full(const gchar *title, const gchar *message,
1165
                                gint type, gint default_value,
1166
                                gboolean can_disable,
1167
                                const gchar *btn1_label,
1168
                                const gchar *btn2_label,
1169
                                const gchar *btn3_label)
1170
{
1171
        gint (*func)(const gchar *, const gchar *, gint, gint, gboolean,
1172
                        const gchar *, const gchar *, const gchar *);
1173

    
1174
        GETFUNC("alertpanel_full");
1175
        return func ? func(title, message, type, default_value, can_disable,
1176
                           btn1_label, btn2_label, btn3_label) : -1;
1177
}
1178

    
1179
gint syl_plugin_alertpanel(const gchar *title, const gchar *message,
1180
                           const gchar *btn1_label,
1181
                           const gchar *btn2_label,
1182
                           const gchar *btn3_label)
1183
{
1184
        gint (*func)(const gchar *, const gchar *,
1185
                        const gchar *, const gchar *, const gchar *);
1186

    
1187
        GETFUNC("alertpanel");
1188
        return func ? func(title, message, btn1_label, btn2_label, btn3_label)
1189
                : -1;
1190
}
1191

    
1192
void syl_plugin_alertpanel_message(const gchar *title, const gchar *message,
1193
                                   gint type)
1194
{
1195
        void (*func)(const gchar *, const gchar *, gint);
1196

    
1197
        GETFUNC("alertpanel_message");
1198
        SAFE_CALL_ARG3(func, title, message, type);
1199
}
1200

    
1201
gint syl_plugin_alertpanel_message_with_disable(const gchar *title,
1202
                                                const gchar *message,
1203
                                                gint type)
1204
{
1205
        gint (*func)(const gchar *, const gchar *, gint);
1206

    
1207
        GETFUNC("alertpanel_message_with_disable");
1208
        return SAFE_CALL_ARG3_RET_VAL(func, title, message, type, 0);
1209
}
1210

    
1211
gint syl_plugin_send_message(const gchar *file, PrefsAccount *ac,
1212
                             GSList *to_list)
1213
{
1214
        gint (*func)(const gchar *, PrefsAccount *, GSList *);
1215

    
1216
        GETFUNC("send_message");
1217
        return SAFE_CALL_ARG3_RET_VAL(func, file, ac, to_list, -1);
1218
}
1219

    
1220
gint syl_plugin_send_message_queue_all(FolderItem *queue, gboolean save_msgs,
1221
                                       gboolean filter_msgs)
1222
{
1223
        gint (*func)(FolderItem *, gboolean, gboolean);
1224

    
1225
        GETFUNC("send_message_queue_all");
1226
        return SAFE_CALL_ARG3_RET_VAL(func, queue, save_msgs, filter_msgs, -1);
1227
}
1228

    
1229
gint syl_plugin_send_message_set_reply_flag(const gchar *reply_target,
1230
                                            const gchar *msgid)
1231
{
1232
        gint (*func)(const gchar *, const gchar *);
1233

    
1234
        GETFUNC("send_message_set_reply_flag");
1235
        return SAFE_CALL_ARG2_RET_VAL(func, reply_target, msgid, -1);
1236
}
1237

    
1238
gint syl_plugin_send_message_set_forward_flags(const gchar *forward_targets)
1239
{
1240
        gint (*func)(const gchar *);
1241

    
1242
        GETFUNC("send_message_set_forward_flags");
1243
        return SAFE_CALL_ARG1_RET_VAL(func, forward_targets, -1);
1244
}