Statistics
| Revision:

root / src / plugin.c @ 2886

History | View | Annotate | Download (30.6 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 "plugin-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
        COMPOSE_SEND,
40
        LAST_SIGNAL
41
};
42

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

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

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

    
84

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

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

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

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

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

    
192
void syl_plugin_signal_connect(const gchar *name, GCallback callback,
193
                               gpointer data)
194
{
195
        g_signal_connect(plugin_obj, name, callback, data);
196
}
197

    
198
void syl_plugin_signal_disconnect(gpointer func, gpointer data)
199
{
200
        g_signal_handlers_disconnect_by_func(plugin_obj, func, data);
201
}
202

    
203
void syl_plugin_signal_emit(const gchar *name, ...)
204
{
205
        guint signal_id;
206

    
207
        if (g_signal_parse_name(name, G_TYPE_FROM_INSTANCE(plugin_obj), &signal_id, NULL, FALSE)) {
208
                 \
209
                                va_list var_args;
210
                va_start(var_args, name);
211
                g_signal_emit_valist(plugin_obj, signal_id, 0, var_args);
212
                va_end(var_args);
213
        } else
214
                g_warning("%s: signal '%s' not found", G_STRLOC, name);
215
}
216

    
217
gint syl_plugin_init_lib(void)
218
{
219
        if (!g_module_supported()) {
220
                g_warning("Plug-in is not supported.");
221
                return -1;
222
        }
223

    
224
        if (!sym_table) {
225
                sym_table = g_hash_table_new(g_str_hash, g_str_equal);
226
        }
227

    
228
        if (!plugin_obj) {
229
                plugin_obj = g_object_new(SYL_TYPE_PLUGIN, NULL);
230
        }
231

    
232
        return 0;
233
}
234

    
235
gint syl_plugin_load(const gchar *name)
236
{
237
        GModule *module;
238
        SylPluginLoadFunc load_func = NULL;
239
        gchar *file;
240

    
241
        g_return_val_if_fail(name != NULL, -1);
242

    
243
        debug_print("syl_plugin_load: loading %s\n", name);
244

    
245
        if (!g_path_is_absolute(name))
246
                file = g_strconcat(PLUGINDIR, G_DIR_SEPARATOR_S, name, NULL);
247
        else
248
                file = g_strdup(name);
249

    
250
        module = g_module_open(file, G_MODULE_BIND_LAZY);
251
        if (!module) {
252
                g_warning("Cannot open module: %s: %s", name, g_module_error());
253
                g_free(file);
254
                return -1;
255
        }
256
        if (g_slist_find(module_list, module)) {
257
                g_warning("Module %s is already loaded", name);
258
                g_free(file);
259
                return -1;
260
        }
261

    
262
        if (g_module_symbol(module, "plugin_load", (gpointer *)&load_func)) {
263
                if (!syl_plugin_check_version(module)) {
264
                        g_warning("Version check failed. Skipping: %s", name);
265
                        g_module_close(module);
266
                        g_free(file);
267
                        return -1;
268
                }
269

    
270
                debug_print("calling plugin_load() in %s\n",
271
                            g_module_name(module));
272
                load_func();
273
                module_list = g_slist_prepend(module_list, module);
274
                g_signal_emit(plugin_obj, plugin_signals[PLUGIN_LOAD], 0, module);
275
        } else {
276
                g_warning("Cannot get symbol: %s: %s", name, g_module_error());
277
                g_module_close(module);
278
                g_free(file);
279
                return -1;
280
        }
281

    
282
        g_free(file);
283

    
284
        return 0;
285
}
286

    
287
gint syl_plugin_load_all(const gchar *dir)
288
{
289
        GDir *d;
290
        const gchar *dir_name;
291
        gchar *path;
292
        gint count = 0;
293

    
294
        g_return_val_if_fail(dir != NULL, -1);
295

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

    
298
        if ((d = g_dir_open(dir, 0, NULL)) == NULL) {
299
                debug_print("failed to open directory: %s\n", dir);
300
                return -1;
301
        }
302

    
303
        while ((dir_name = g_dir_read_name(d)) != NULL) {
304
                if (!g_str_has_suffix(dir_name, "." G_MODULE_SUFFIX))
305
                        continue;
306
                path = g_strconcat(dir, G_DIR_SEPARATOR_S, dir_name, NULL);
307
                if (syl_plugin_load(path) == 0)
308
                        count++;
309
                g_free(path);
310
        }
311

    
312
        g_dir_close(d);
313

    
314
        return count;
315
}
316

    
317
void syl_plugin_unload_all(void)
318
{
319
        GSList *cur;
320

    
321
        for (cur = module_list; cur != NULL; cur = cur->next) {
322
                GModule *module = (GModule *)cur->data;
323
                SylPluginUnloadFunc unload_func = NULL;
324

    
325
                if (g_module_symbol(module, "plugin_unload",
326
                                    (gpointer *)&unload_func)) {
327
                        g_signal_emit(plugin_obj, plugin_signals[PLUGIN_UNLOAD],
328
                                      0, module);
329
                        debug_print("calling plugin_unload() in %s\n",
330
                                    g_module_name(module));
331
                        unload_func();
332
                } else {
333
                        g_warning("Cannot get symbol: %s", g_module_error());
334
                }
335
                if (!g_module_close(module)) {
336
                        g_warning("Module unload failed: %s", g_module_error());
337
                }
338
        }
339

    
340
        g_slist_free(module_list);
341
        module_list = NULL;
342
}
343

    
344
GSList *syl_plugin_get_module_list(void)
345
{
346
        return module_list;
347
}
348

    
349
SylPluginInfo *syl_plugin_get_info(GModule *module)
350
{
351
        SylPluginInfo * (*plugin_info_func)(void);
352

    
353
        g_return_val_if_fail(module != NULL, NULL);
354

    
355
        debug_print("getting plugin information of %s\n",
356
                    g_module_name(module));
357

    
358
        if (g_module_symbol(module, "plugin_info",
359
                            (gpointer *)&plugin_info_func)) {
360
                debug_print("calling plugin_info() in %s\n",
361
                            g_module_name(module));
362
                return plugin_info_func();
363
        } else {
364
                g_warning("Cannot get symbol: %s: %s", g_module_name(module),
365
                          g_module_error());
366
                return NULL;
367
        }
368
}
369

    
370
gboolean syl_plugin_check_version(GModule *module)
371
{
372
        gint (*version_func)(void);
373
        gint ver;
374
        gint a_major;
375
        gint a_minor;
376
        gint p_major;
377
        gint p_minor;
378

    
379
        g_return_val_if_fail(module != NULL, FALSE);
380

    
381
        if (g_module_symbol(module, "plugin_interface_version",
382
                            (gpointer *)&version_func)) {
383
                debug_print("calling plugin_interface_version() in %s\n",
384
                            g_module_name(module));
385
                ver = version_func();
386
        } else {
387
                g_warning("Cannot get symbol: %s: %s", g_module_name(module),
388
                          g_module_error());
389
                return FALSE;
390
        }
391

    
392
        a_major = SYL_PLUGIN_INTERFACE_VERSION & 0xff00;
393
        a_minor = SYL_PLUGIN_INTERFACE_VERSION & 0x00ff;
394
        p_major = ver & 0xff00;
395
        p_minor = ver & 0x00ff;
396
        if (a_major == p_major && a_minor >= p_minor) {
397
                debug_print("Version OK: plugin: %d, app: %d\n",
398
                            ver, SYL_PLUGIN_INTERFACE_VERSION);
399
                return TRUE;
400
        } else {
401
                g_warning("Plugin interface version mismatch: plugin: %d, app: %d", ver, SYL_PLUGIN_INTERFACE_VERSION);
402
                return FALSE;
403
        }
404
}
405

    
406
gint syl_plugin_add_symbol(const gchar *name, gpointer sym)
407
{
408
        g_hash_table_insert(sym_table, (gpointer)name, sym);
409
        return 0;
410
}
411

    
412
gpointer syl_plugin_lookup_symbol(const gchar *name)
413
{
414
        return g_hash_table_lookup(sym_table, name);
415
}
416

    
417
const gchar *syl_plugin_get_prog_version(void)
418
{
419
        gpointer sym;
420

    
421
        sym = syl_plugin_lookup_symbol("prog_version");
422
        return (gchar *)sym;
423
}
424

    
425
void syl_plugin_main_window_lock(void)
426
{
427
        CALL_VOID_POINTER(syl_plugin_main_window_get,
428
                          "main_window_lock");
429
}
430

    
431
void syl_plugin_main_window_unlock(void)
432
{
433
        CALL_VOID_POINTER(syl_plugin_main_window_get,
434
                          "main_window_unlock");
435
}
436

    
437
gpointer syl_plugin_main_window_get(void)
438
{
439
        gpointer (*func)(void);
440

    
441
        func = syl_plugin_lookup_symbol("main_window_get");
442
        return SAFE_CALL_RET(func);
443
}
444

    
445
void syl_plugin_main_window_popup(gpointer mainwin)
446
{
447
        void (*func)(gpointer);
448

    
449
        func = syl_plugin_lookup_symbol("main_window_popup");
450
        SAFE_CALL_ARG1(func, mainwin);
451
}
452

    
453
GtkWidget *syl_plugin_main_window_get_statusbar(void)
454
{
455
        gpointer widget;
456

    
457
        widget = syl_plugin_lookup_symbol("main_window_statusbar");
458
        return GTK_WIDGET(widget);
459
}
460

    
461
void syl_plugin_app_will_exit(gboolean force)
462
{
463
        void (*func)(gboolean);
464

    
465
        func = syl_plugin_lookup_symbol("app_will_exit");
466
        SAFE_CALL_ARG1(func, force);
467
}
468

    
469
static GtkItemFactory *get_item_factory(const gchar *path)
470
{
471
        GtkItemFactory *ifactory;
472

    
473
        if (!path)
474
                return NULL;
475

    
476
        if (strncmp(path, "<Main>", 6) == 0)
477
                ifactory = syl_plugin_lookup_symbol("main_window_menu_factory");
478
        else if (strncmp(path, "<MailFolder>", 12) == 0)
479
                ifactory = syl_plugin_lookup_symbol("folderview_mail_popup_factory");
480
        else if (strncmp(path, "<IMAPFolder>", 12) == 0)
481
                ifactory = syl_plugin_lookup_symbol("folderview_imap_popup_factory");
482
        else if (strncmp(path, "<NewsFolder>", 12) == 0)
483
                ifactory = syl_plugin_lookup_symbol("folderview_news_popup_factory");
484
        else if (strncmp(path, "<SummaryView>", 13) == 0)
485
                ifactory = syl_plugin_lookup_symbol("summaryview_popup_factory");
486
        else
487
                ifactory = syl_plugin_lookup_symbol("main_window_menu_factory");
488

    
489
        return ifactory;
490
}
491

    
492
gint syl_plugin_add_menuitem(const gchar *parent, const gchar *label,
493
                             SylPluginCallbackFunc func, gpointer data)
494
{
495
        GtkItemFactory *ifactory;
496
        GtkWidget *menu;
497
        GtkWidget *menuitem;
498

    
499
        if (!parent)
500
                return -1;
501

    
502
        ifactory = get_item_factory(parent);
503
        if (!ifactory)
504
                return -1;
505

    
506
        menu = gtk_item_factory_get_widget(ifactory, parent);
507
        if (!menu)
508
                return -1;
509

    
510
        if (label)
511
                menuitem = gtk_menu_item_new_with_label(label);
512
        else {
513
                menuitem = gtk_menu_item_new();
514
                gtk_widget_set_sensitive(menuitem, FALSE);
515
        }
516
        gtk_widget_show(menuitem);
517
        gtk_menu_append(GTK_MENU(menu), menuitem);
518
        if (func)
519
                g_signal_connect(G_OBJECT(menuitem), "activate",
520
                                 G_CALLBACK(func), data);
521

    
522
        return 0;
523
}
524

    
525
gint syl_plugin_add_factory_item(const gchar *parent, const gchar *label,
526
                                 SylPluginCallbackFunc func, gpointer data)
527
{
528
        GtkItemFactory *ifactory;
529
        GtkItemFactoryEntry entry = {NULL, NULL, NULL, 0, NULL};
530

    
531
        if (!parent)
532
                return -1;
533

    
534
        ifactory = get_item_factory(parent);
535
        if (!ifactory)
536
                return -1;
537

    
538
        if (label) {
539
                entry.path = (gchar *)label;
540
                if (g_str_has_suffix(label, "/---"))
541
                        entry.item_type = "<Separator>";
542
                else
543
                        entry.item_type = NULL;
544
        } else {
545
                entry.path = "/---";
546
                entry.item_type = "<Separator>";
547
        }
548
        entry.callback = func;
549
        g_print("entry.path = %s\n", entry.path);
550

    
551
        gtk_item_factory_create_item(ifactory, &entry, data, 2);
552

    
553
        return 0;
554
}
555

    
556
void syl_plugin_menu_set_sensitive(const gchar *path, gboolean sensitive)
557
{
558
        GtkItemFactory *ifactory;
559
        GtkWidget *widget;
560

    
561
        g_return_if_fail(path != NULL);
562

    
563
        ifactory = get_item_factory(path);
564
        if (!ifactory)
565
                return;
566

    
567
        widget = gtk_item_factory_get_item(ifactory, path);
568
        gtk_widget_set_sensitive(widget, sensitive);
569
}
570

    
571
void syl_plugin_menu_set_sensitive_all(GtkMenuShell *menu_shell,
572
                                       gboolean sensitive)
573
{
574
        GList *cur;
575

    
576
        for (cur = menu_shell->children; cur != NULL; cur = cur->next)
577
                gtk_widget_set_sensitive(GTK_WIDGET(cur->data), sensitive);
578
}
579

    
580
void syl_plugin_menu_set_active(const gchar *path, gboolean is_active)
581
{
582
        GtkItemFactory *ifactory;
583
        GtkWidget *widget;
584

    
585
        g_return_if_fail(path != NULL);
586

    
587
        ifactory = get_item_factory(path);
588
        if (!ifactory)
589
                return;
590

    
591
        widget = gtk_item_factory_get_item(ifactory, path);
592
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), is_active);
593
}
594

    
595
gpointer syl_plugin_folderview_get(void)
596
{
597
        gpointer (*func)(void);
598
        GETFUNC("folderview_get");
599
        return SAFE_CALL_RET(func);
600
}
601

    
602
void syl_plugin_folderview_add_sub_widget(GtkWidget *widget)
603
{
604
        void (*func)(gpointer, GtkWidget *);
605
        gpointer folderview;
606

    
607
        folderview = syl_plugin_folderview_get();
608
        if (folderview) {
609
                GETFUNC("folderview_add_sub_widget");
610
                SAFE_CALL_ARG2(func, folderview, widget);
611
        }
612
}
613

    
614
void syl_plugin_folderview_select(FolderItem *item)
615
{
616
        void (*func)(gpointer, FolderItem *);
617
        gpointer folderview;
618

    
619
        folderview = syl_plugin_folderview_get();
620
        if (folderview) {
621
                GETFUNC("folderview_select");
622
                SAFE_CALL_ARG2(func, folderview, item);
623
        }
624
}
625

    
626
void syl_plugin_folderview_unselect(void)
627
{
628
        CALL_VOID_POINTER(syl_plugin_folderview_get,
629
                          "folderview_unselect");
630
}
631

    
632
void syl_plugin_folderview_select_next_unread(void)
633
{
634
        CALL_VOID_POINTER(syl_plugin_folderview_get,
635
                          "folderview_select_next_unread");
636
}
637

    
638
FolderItem *syl_plugin_folderview_get_selected_item(void)
639
{
640
        FolderItem * (*func)(gpointer);
641
        gpointer folderview;
642

    
643
        folderview = syl_plugin_folderview_get();
644
        if (folderview) {
645
                GETFUNC("folderview_get_selected_item");
646
                return SAFE_CALL_ARG1_RET(func, folderview);
647
        }
648

    
649
        return NULL;
650
}
651

    
652
gint syl_plugin_folderview_check_new(Folder *folder)
653
{
654
        gint (*func)(Folder *);
655
        GETFUNC("folderview_check_new");
656
        return SAFE_CALL_ARG1_RET_VAL(func, folder, FALSE);
657
}
658

    
659
gint syl_plugin_folderview_check_new_item(FolderItem *item)
660
{
661
        gint (*func)(FolderItem *);
662
        GETFUNC("folderview_check_new_item");
663
        return SAFE_CALL_ARG1_RET_VAL(func, item, FALSE);
664
}
665

    
666
gint syl_plugin_folderview_check_new_all(void)
667
{
668
        gint (*func)(void);
669
        GETFUNC("folderview_check_new_all");
670
        return SAFE_CALL_RET_VAL(func, FALSE);
671
}
672

    
673
void syl_plugin_folderview_update_item(FolderItem *item,
674
                                       gboolean update_summary)
675
{
676
        void (*func)(FolderItem *, gboolean);
677
        GETFUNC("folderview_update_item");
678
        SAFE_CALL_ARG2(func, item, update_summary);
679
}
680

    
681
void syl_plugin_folderview_update_item_foreach(GHashTable *table,
682
                                               gboolean update_summary)
683
{
684
        void (*func)(GHashTable *, gboolean);
685
        GETFUNC("folderview_update_item_foreach");
686
        SAFE_CALL_ARG2(func, table, update_summary);
687
}
688

    
689
void syl_plugin_folderview_update_all_updated(gboolean update_summary)
690
{
691
        void (*func)(gboolean);
692
        GETFUNC("folderview_update_all_updated");
693
        SAFE_CALL_ARG1(func, update_summary);
694
}
695

    
696
void syl_plugin_folderview_check_new_selected(void)
697
{
698
        CALL_VOID_POINTER(syl_plugin_folderview_get,
699
                          "folderview_check_new_selected");
700
}
701

    
702
gpointer syl_plugin_summary_view_get(void)
703
{
704
        gpointer sym;
705

    
706
        sym = syl_plugin_lookup_symbol("summaryview");
707
        return sym;
708
}
709

    
710
void syl_plugin_summary_select_by_msgnum(guint msgnum)
711
{
712
        void (*func)(gpointer, guint);
713
        gpointer summary;
714

    
715
        summary = syl_plugin_summary_view_get();
716
        if (summary) {
717
                func = syl_plugin_lookup_symbol("summary_select_by_msgnum");
718
                SAFE_CALL_ARG2(func, summary, msgnum);
719
        }
720
}
721

    
722
gboolean syl_plugin_summary_select_by_msginfo(MsgInfo *msginfo)
723
{
724
        gboolean (*func)(gpointer, MsgInfo *);
725
        gpointer summary;
726

    
727
        summary = syl_plugin_summary_view_get();
728
        if (summary) {
729
                func = syl_plugin_lookup_symbol("summary_select_by_msginfo");
730
                return SAFE_CALL_ARG2_RET_VAL(func, summary, msginfo, FALSE);
731
        }
732

    
733
        return FALSE;
734
}
735

    
736
void syl_plugin_open_message(const gchar *folder_id, guint msgnum)
737
{
738
        FolderItem *item;
739
        MsgInfo *msginfo;
740

    
741
        item = folder_find_item_from_identifier(folder_id);
742
        msginfo = folder_item_get_msginfo(item, msgnum);
743

    
744
        if (msginfo) {
745
                if (!syl_plugin_summary_select_by_msginfo(msginfo)) {
746
                        syl_plugin_open_message_by_new_window(msginfo);
747
                }
748
                procmsg_msginfo_free(msginfo);
749
        }
750
}
751

    
752
void syl_plugin_summary_show_queued_msgs(void)
753
{
754
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
755
                          "summary_show_queued_msgs");
756
}
757

    
758
void syl_plugin_summary_lock(void)
759
{
760
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
761
                          "summary_lock");
762
}
763

    
764
void syl_plugin_summary_unlock(void)
765
{
766
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
767
                          "summary_unlock");
768
}
769

    
770
gboolean syl_plugin_summary_is_locked(void)
771
{
772
        gboolean (*func)(gpointer);
773
        gpointer summary;
774

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

    
781
        return FALSE;
782
}
783

    
784
gboolean syl_plugin_summary_is_read_locked(void)
785
{
786
        gboolean (*func)(gpointer);
787
        gpointer summary;
788

    
789
        summary = syl_plugin_summary_view_get();
790
        if (summary) {
791
                GETFUNC("summary_is_read_locked");
792
                return SAFE_CALL_ARG1_RET_VAL(func, summary, FALSE);
793
        }
794

    
795
        return FALSE;
796
}
797

    
798
void syl_plugin_summary_write_lock(void)
799
{
800
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
801
                          "summary_write_lock");
802
}
803

    
804
void syl_plugin_summary_write_unlock(void)
805
{
806
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
807
                          "summary_write_unlock");
808
}
809

    
810
gboolean syl_plugin_summary_is_write_locked(void)
811
{
812
        gboolean (*func)(gpointer);
813
        gpointer summary;
814

    
815
        summary = syl_plugin_summary_view_get();
816
        if (summary) {
817
                GETFUNC("summary_is_write_locked");
818
                return SAFE_CALL_ARG1_RET_VAL(func, summary, FALSE);
819
        }
820

    
821
        return FALSE;
822
}
823

    
824
FolderItem *syl_plugin_summary_get_current_folder(void)
825
{
826
        FolderItem * (*func)(gpointer);
827
        gpointer summary;
828

    
829
        summary = syl_plugin_summary_view_get();
830
        if (summary) {
831
                GETFUNC("summary_get_current_folder");
832
                return SAFE_CALL_ARG1_RET(func, summary);
833
        }
834

    
835
        return NULL;
836
}
837

    
838
gint syl_plugin_summary_get_selection_type(void)
839
{
840
        gint (*func)(gpointer);
841
        gpointer summary;
842

    
843
        summary = syl_plugin_summary_view_get();
844
        if (summary) {
845
                GETFUNC("summary_get_selection_type");
846
                return SAFE_CALL_ARG1_RET_VAL(func, summary, 0);
847
        }
848

    
849
        return 0;
850
}
851

    
852
GSList *syl_plugin_summary_get_selected_msg_list(void)
853
{
854
        GSList * (*func)(gpointer);
855
        gpointer summary;
856

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

    
863
        return NULL;
864
}
865

    
866
GSList *syl_plugin_summary_get_msg_list(void)
867
{
868
        GSList * (*func)(gpointer);
869
        gpointer summary;
870

    
871
        summary = syl_plugin_summary_view_get();
872
        if (summary) {
873
                GETFUNC("summary_get_msg_list");
874
                return SAFE_CALL_ARG1_RET(func, summary);
875
        }
876

    
877
        return NULL;
878
}
879

    
880
void syl_plugin_summary_redisplay_msg(void)
881
{
882
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
883
                          "summary_redisplay_msg");
884
}
885

    
886
void syl_plugin_summary_open_msg(void)
887
{
888
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
889
                          "summary_open_msg");
890
}
891

    
892
void syl_plugin_summary_view_source(void)
893
{
894
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
895
                          "summary_view_source");
896
}
897

    
898
void syl_plugin_summary_reedit(void)
899
{
900
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
901
                          "summary_reedit");
902
}
903

    
904
void syl_plugin_summary_update_selected_rows(void)
905
{
906
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
907
                          "summary_update_selected_rows");
908
}
909

    
910
void syl_plugin_summary_update_by_msgnum(guint msgnum)
911
{
912
        void (*func)(gpointer, guint);
913
        gpointer summary;
914

    
915
        summary = syl_plugin_summary_view_get();
916
        if (summary) {
917
                func = syl_plugin_lookup_symbol("summary_update_by_msgnum");
918
                SAFE_CALL_ARG2(func, summary, msgnum);
919
        }
920
}
921

    
922
gpointer syl_plugin_messageview_create_with_new_window(void)
923
{
924
        gpointer (*func)(void);
925

    
926
        func = syl_plugin_lookup_symbol("messageview_create_with_new_window");
927
        return SAFE_CALL_RET(func);
928
}
929

    
930
void syl_plugin_open_message_by_new_window(MsgInfo *msginfo)
931
{
932
        gpointer msgview;
933
        gpointer (*func)(gpointer, MsgInfo *, gboolean);
934

    
935
        msgview = syl_plugin_messageview_create_with_new_window();
936
        if (msgview) {
937
                func = syl_plugin_lookup_symbol("messageview_show");
938
                SAFE_CALL_ARG3(func, msgview, msginfo, FALSE);
939
        }
940
}
941

    
942

    
943
gpointer syl_plugin_compose_new(PrefsAccount *account, FolderItem *item,
944
                                const gchar *mailto, GPtrArray *attach_files)
945
{
946
        gpointer (*func)(PrefsAccount *, FolderItem *, const gchar *,
947
                         GPtrArray *);
948

    
949
        func = syl_plugin_lookup_symbol("compose_new");
950
        return SAFE_CALL_ARG4_RET(func, account, item, mailto, attach_files);
951
}
952

    
953
void syl_plugin_compose_entry_set(gpointer compose, const gchar *text,
954
                                  gint type)
955
{
956
        void (*func)(gpointer, const gchar *, gint);
957

    
958
        func = syl_plugin_lookup_symbol("compose_entry_set");
959
        SAFE_CALL_ARG3(func, compose, text, type);
960
}
961

    
962
void syl_plugin_compose_entry_append(gpointer compose, const gchar *text,
963
                                     gint type)
964
{
965
        void (*func)(gpointer, const gchar *, gint);
966

    
967
        func = syl_plugin_lookup_symbol("compose_entry_append");
968
        SAFE_CALL_ARG3(func, compose, text, type);
969
}
970

    
971
gchar *syl_plugin_compose_entry_get_text(gpointer compose, gint type)
972
{
973
        gchar * (*func)(gpointer, gint);
974

    
975
        func = syl_plugin_lookup_symbol("compose_entry_get_text");
976
        return SAFE_CALL_ARG2_RET(func, compose, type);
977
}
978

    
979
void syl_plugin_compose_lock(gpointer compose)
980
{
981
        void (*func)(gpointer);
982

    
983
        func = syl_plugin_lookup_symbol("compose_lock");
984
        SAFE_CALL_ARG1(func, compose);
985
}
986

    
987
void syl_plugin_compose_unlock(gpointer compose)
988
{
989
        void (*func)(gpointer);
990

    
991
        func = syl_plugin_lookup_symbol("compose_unlock");
992
        SAFE_CALL_ARG1(func, compose);
993
}
994

    
995

    
996
FolderItem *syl_plugin_folder_sel(Folder *cur_folder, gint sel_type,
997
                                  const gchar *default_folder)
998
{
999
        FolderItem * (*func)(Folder *, gint, const gchar *);
1000

    
1001
        func = syl_plugin_lookup_symbol("foldersel_folder_sel");
1002
        return SAFE_CALL_ARG3_RET(func, cur_folder, sel_type, default_folder);
1003
}
1004

    
1005
FolderItem *syl_plugin_folder_sel_full(Folder *cur_folder, gint sel_type,
1006
                                       const gchar *default_folder,
1007
                                       const gchar *message)
1008
{
1009
        FolderItem * (*func)(Folder *, gint, const gchar *, const gchar *);
1010

    
1011
        func = syl_plugin_lookup_symbol("foldersel_folder_sel_full");
1012
        return SAFE_CALL_ARG4_RET(func, cur_folder, sel_type, default_folder,
1013
                                  message);
1014
}
1015

    
1016
gchar *syl_plugin_input_dialog(const gchar *title, const gchar *message,
1017
                               const gchar *default_string)
1018
{
1019
        gchar * (*func)(const gchar *, const gchar *, const gchar *);
1020

    
1021
        func = syl_plugin_lookup_symbol("input_dialog");
1022
        return SAFE_CALL_ARG3_RET(func, title, message, default_string);
1023
}
1024

    
1025
gchar *syl_plugin_input_dialog_with_invisible(const gchar *title,
1026
                                              const gchar *message,
1027
                                              const gchar *default_string)
1028
{
1029
        gchar * (*func)(const gchar *, const gchar *, const gchar *);
1030

    
1031
        func = syl_plugin_lookup_symbol("input_dialog_with_invisible");
1032
        return SAFE_CALL_ARG3_RET(func, title, message, default_string);
1033
}
1034

    
1035
void syl_plugin_manage_window_set_transient(GtkWindow *window)
1036
{
1037
        void (*func)(GtkWindow *);
1038

    
1039
        func = syl_plugin_lookup_symbol("manage_window_set_transient");
1040
        SAFE_CALL_ARG1(func, window);
1041
}
1042

    
1043
void syl_plugin_manage_window_signals_connect(GtkWindow *window)
1044
{
1045
        void (*func)(GtkWindow *);
1046

    
1047
        func = syl_plugin_lookup_symbol("manage_window_signals_connect");
1048
        SAFE_CALL_ARG1(func, window);
1049
}
1050

    
1051
GtkWidget *syl_plugin_manage_window_get_focus_window(void)
1052
{
1053
        GtkWidget * (*func)(void);
1054

    
1055
        func = syl_plugin_lookup_symbol("manage_window_get_focus_window");
1056
        return SAFE_CALL_RET(func);
1057
}
1058

    
1059
void syl_plugin_inc_mail(void)
1060
{
1061
        void (*func)(gpointer);
1062

    
1063
        func = syl_plugin_lookup_symbol("inc_mail");
1064
        SAFE_CALL_ARG1(func, syl_plugin_main_window_get());
1065
}
1066

    
1067
gboolean syl_plugin_inc_is_active(void)
1068
{
1069
        gboolean (*func)(void);
1070

    
1071
        func = syl_plugin_lookup_symbol("inc_is_active");
1072
        return SAFE_CALL_RET_VAL(func, FALSE);
1073
}
1074

    
1075
void syl_plugin_inc_lock(void)
1076
{
1077
        void (*func)(void);
1078

    
1079
        func = syl_plugin_lookup_symbol("inc_lock");
1080
        SAFE_CALL(func);
1081
}
1082

    
1083
void syl_plugin_inc_unlock(void)
1084
{
1085
        void (*func)(void);
1086

    
1087
        func = syl_plugin_lookup_symbol("inc_unlock");
1088
        SAFE_CALL(func);
1089
}
1090

    
1091
void syl_plugin_update_check(gboolean show_dialog_always)
1092
{
1093
        void (*func)(gboolean);
1094

    
1095
        func = syl_plugin_lookup_symbol("update_check");
1096
        SAFE_CALL_ARG1(func, show_dialog_always);
1097
}
1098

    
1099
void syl_plugin_update_check_set_check_url(const gchar *url)
1100
{
1101
        void (*func)(const gchar *);
1102

    
1103
        func = syl_plugin_lookup_symbol("update_check_set_check_url");
1104
        SAFE_CALL_ARG1(func, url);
1105
}
1106

    
1107
const gchar *syl_plugin_update_check_get_check_url(void)
1108
{
1109
        const gchar * (*func)(void);
1110

    
1111
        func = syl_plugin_lookup_symbol("update_check_get_check_url");
1112
        return SAFE_CALL_RET(func);
1113
}
1114

    
1115
void syl_plugin_update_check_set_download_url(const gchar *url)
1116
{
1117
        void (*func)(const gchar *);
1118

    
1119
        func = syl_plugin_lookup_symbol("update_check_set_download_url");
1120
        SAFE_CALL_ARG1(func, url);
1121
}
1122

    
1123
const gchar *syl_plugin_update_check_get_download_url(void)
1124
{
1125
        const gchar * (*func)(void);
1126

    
1127
        func = syl_plugin_lookup_symbol("update_check_get_download_url");
1128
        return SAFE_CALL_RET(func);
1129
}
1130

    
1131
void syl_plugin_update_check_set_jump_url(const gchar *url)
1132
{
1133
        void (*func)(const gchar *);
1134

    
1135
        func = syl_plugin_lookup_symbol("update_check_set_jump_url");
1136
        SAFE_CALL_ARG1(func, url);
1137
}
1138

    
1139
const gchar *syl_plugin_update_check_get_jump_url(void)
1140
{
1141
        const gchar * (*func)(void);
1142

    
1143
        func = syl_plugin_lookup_symbol("update_check_get_jump_url");
1144
        return SAFE_CALL_RET(func);
1145
}
1146

    
1147
void syl_plugin_update_check_set_check_plugin_url(const gchar *url)
1148
{
1149
        void (*func)(const gchar *);
1150

    
1151
        func = syl_plugin_lookup_symbol("update_check_set_check_plugin_url");
1152
        SAFE_CALL_ARG1(func, url);
1153
}
1154

    
1155
const gchar *syl_plugin_update_check_get_check_plugin_url(void)
1156
{
1157
        const gchar * (*func)(void);
1158

    
1159
        func = syl_plugin_lookup_symbol("update_check_get_check_plugin_url");
1160
        return SAFE_CALL_RET(func);
1161
}
1162

    
1163
void syl_plugin_update_check_set_jump_plugin_url(const gchar *url)
1164
{
1165
        void (*func)(const gchar *);
1166

    
1167
        func = syl_plugin_lookup_symbol("update_check_set_jump_plugin_url");
1168
        SAFE_CALL_ARG1(func, url);
1169
}
1170

    
1171
const gchar *syl_plugin_update_check_get_jump_plugin_url(void)
1172
{
1173
        const gchar * (*func)(void);
1174

    
1175
        func = syl_plugin_lookup_symbol("update_check_get_jump_plugin_url");
1176
        return SAFE_CALL_RET(func);
1177
}
1178

    
1179
gint syl_plugin_alertpanel_full(const gchar *title, const gchar *message,
1180
                                gint type, gint default_value,
1181
                                gboolean can_disable,
1182
                                const gchar *btn1_label,
1183
                                const gchar *btn2_label,
1184
                                const gchar *btn3_label)
1185
{
1186
        gint (*func)(const gchar *, const gchar *, gint, gint, gboolean,
1187
                        const gchar *, const gchar *, const gchar *);
1188

    
1189
        GETFUNC("alertpanel_full");
1190
        return func ? func(title, message, type, default_value, can_disable,
1191
                           btn1_label, btn2_label, btn3_label) : -1;
1192
}
1193

    
1194
gint syl_plugin_alertpanel(const gchar *title, const gchar *message,
1195
                           const gchar *btn1_label,
1196
                           const gchar *btn2_label,
1197
                           const gchar *btn3_label)
1198
{
1199
        gint (*func)(const gchar *, const gchar *,
1200
                        const gchar *, const gchar *, const gchar *);
1201

    
1202
        GETFUNC("alertpanel");
1203
        return func ? func(title, message, btn1_label, btn2_label, btn3_label)
1204
                : -1;
1205
}
1206

    
1207
void syl_plugin_alertpanel_message(const gchar *title, const gchar *message,
1208
                                   gint type)
1209
{
1210
        void (*func)(const gchar *, const gchar *, gint);
1211

    
1212
        GETFUNC("alertpanel_message");
1213
        SAFE_CALL_ARG3(func, title, message, type);
1214
}
1215

    
1216
gint syl_plugin_alertpanel_message_with_disable(const gchar *title,
1217
                                                const gchar *message,
1218
                                                gint type)
1219
{
1220
        gint (*func)(const gchar *, const gchar *, gint);
1221

    
1222
        GETFUNC("alertpanel_message_with_disable");
1223
        return SAFE_CALL_ARG3_RET_VAL(func, title, message, type, 0);
1224
}
1225

    
1226
gint syl_plugin_send_message(const gchar *file, PrefsAccount *ac,
1227
                             GSList *to_list)
1228
{
1229
        gint (*func)(const gchar *, PrefsAccount *, GSList *);
1230

    
1231
        GETFUNC("send_message");
1232
        return SAFE_CALL_ARG3_RET_VAL(func, file, ac, to_list, -1);
1233
}
1234

    
1235
gint syl_plugin_send_message_queue_all(FolderItem *queue, gboolean save_msgs,
1236
                                       gboolean filter_msgs)
1237
{
1238
        gint (*func)(FolderItem *, gboolean, gboolean);
1239

    
1240
        GETFUNC("send_message_queue_all");
1241
        return SAFE_CALL_ARG3_RET_VAL(func, queue, save_msgs, filter_msgs, -1);
1242
}
1243

    
1244
gint syl_plugin_send_message_set_reply_flag(const gchar *reply_target,
1245
                                            const gchar *msgid)
1246
{
1247
        gint (*func)(const gchar *, const gchar *);
1248

    
1249
        GETFUNC("send_message_set_reply_flag");
1250
        return SAFE_CALL_ARG2_RET_VAL(func, reply_target, msgid, -1);
1251
}
1252

    
1253
gint syl_plugin_send_message_set_forward_flags(const gchar *forward_targets)
1254
{
1255
        gint (*func)(const gchar *);
1256

    
1257
        GETFUNC("send_message_set_forward_flags");
1258
        return SAFE_CALL_ARG1_RET_VAL(func, forward_targets, -1);
1259
}