Statistics
| Revision:

root / src / plugin.c @ 2811

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,
168
                             G_TYPE_NONE,
169
                             4,
170
                             G_TYPE_POINTER,
171
                             G_TYPE_POINTER,
172
                             G_TYPE_STRING,
173
                             G_TYPE_STRING);
174
}
175
176
void syl_plugin_signal_connect(const gchar *name, GCallback callback,
177
                               gpointer data)
178
{
179
        g_signal_connect(plugin_obj, name, callback, data);
180
}
181
182
void syl_plugin_signal_disconnect(gpointer func, gpointer data)
183
{
184
        g_signal_handlers_disconnect_by_func(plugin_obj, func, data);
185
}
186
187
void syl_plugin_signal_emit(const gchar *name, ...)
188
{
189
        guint signal_id;
190
191
        if (g_signal_parse_name(name, G_TYPE_FROM_INSTANCE(plugin_obj), &signal_id, NULL, FALSE)) {
192
                 \
193
                                va_list var_args;
194
                va_start(var_args, name);
195
                g_signal_emit_valist(plugin_obj, signal_id, 0, var_args);
196
                va_end(var_args);
197
        } else
198
                g_warning("%s: signal '%s' not found", G_STRLOC, name);
199
}
200
201
gint syl_plugin_init_lib(void)
202
{
203
        if (!g_module_supported()) {
204
                g_warning("Plug-in is not supported.");
205
                return -1;
206
        }
207
208
        if (!sym_table) {
209
                sym_table = g_hash_table_new(g_str_hash, g_str_equal);
210
        }
211
212
        if (!plugin_obj) {
213
                plugin_obj = g_object_new(SYL_TYPE_PLUGIN, NULL);
214
        }
215
216
        return 0;
217
}
218
219
gint syl_plugin_load(const gchar *name)
220
{
221
        GModule *module;
222
        SylPluginLoadFunc load_func = NULL;
223
        gchar *file;
224
225
        g_return_val_if_fail(name != NULL, -1);
226
227
        debug_print("syl_plugin_load: loading %s\n", name);
228
229
        if (!g_path_is_absolute(name))
230
                file = g_strconcat(PLUGINDIR, G_DIR_SEPARATOR_S, name, NULL);
231
        else
232
                file = g_strdup(name);
233
234
        module = g_module_open(file, G_MODULE_BIND_LAZY);
235
        if (!module) {
236
                g_warning("Cannot open module: %s: %s", name, g_module_error());
237
                g_free(file);
238
                return -1;
239
        }
240
        if (g_slist_find(module_list, module)) {
241
                g_warning("Module %s is already loaded", name);
242
                g_free(file);
243
                return -1;
244
        }
245
246
        if (g_module_symbol(module, "plugin_load", (gpointer *)&load_func)) {
247
                if (!syl_plugin_check_version(module)) {
248
                        g_warning("Version check failed. Skipping: %s", name);
249
                        g_module_close(module);
250
                        g_free(file);
251
                        return -1;
252
                }
253
254
                debug_print("calling plugin_load() in %s\n",
255
                            g_module_name(module));
256
                load_func();
257
                module_list = g_slist_prepend(module_list, module);
258
                g_signal_emit(plugin_obj, plugin_signals[PLUGIN_LOAD], 0, module);
259
        } else {
260
                g_warning("Cannot get symbol: %s: %s", name, g_module_error());
261
                g_module_close(module);
262
                g_free(file);
263
                return -1;
264
        }
265
266
        g_free(file);
267
268
        return 0;
269
}
270
271
gint syl_plugin_load_all(const gchar *dir)
272
{
273
        GDir *d;
274
        const gchar *dir_name;
275
        gchar *path;
276
        gint count = 0;
277
278
        g_return_val_if_fail(dir != NULL, -1);
279
280
        debug_print("loading plugins from directory: %s\n", dir);
281
282
        if ((d = g_dir_open(dir, 0, NULL)) == NULL) {
283
                debug_print("failed to open directory: %s\n", dir);
284
                return -1;
285
        }
286
287
        while ((dir_name = g_dir_read_name(d)) != NULL) {
288
                if (!g_str_has_suffix(dir_name, "." G_MODULE_SUFFIX))
289
                        continue;
290
                path = g_strconcat(dir, G_DIR_SEPARATOR_S, dir_name, NULL);
291
                if (syl_plugin_load(path) == 0)
292
                        count++;
293
                g_free(path);
294
        }
295
296
        g_dir_close(d);
297
298
        return count;
299
}
300
301
void syl_plugin_unload_all(void)
302
{
303
        GSList *cur;
304
305
        for (cur = module_list; cur != NULL; cur = cur->next) {
306
                GModule *module = (GModule *)cur->data;
307
                SylPluginUnloadFunc unload_func = NULL;
308
309
                if (g_module_symbol(module, "plugin_unload",
310
                                    (gpointer *)&unload_func)) {
311
                        g_signal_emit(plugin_obj, plugin_signals[PLUGIN_UNLOAD],
312
                                      0, module);
313
                        debug_print("calling plugin_unload() in %s\n",
314
                                    g_module_name(module));
315
                        unload_func();
316
                } else {
317
                        g_warning("Cannot get symbol: %s", g_module_error());
318
                }
319
                if (!g_module_close(module)) {
320
                        g_warning("Module unload failed: %s", g_module_error());
321
                }
322
        }
323
324
        g_slist_free(module_list);
325
        module_list = NULL;
326
}
327
328
GSList *syl_plugin_get_module_list(void)
329
{
330
        return module_list;
331
}
332
333
SylPluginInfo *syl_plugin_get_info(GModule *module)
334
{
335
        SylPluginInfo * (*plugin_info_func)(void);
336
337
        g_return_val_if_fail(module != NULL, NULL);
338
339
        debug_print("getting plugin information of %s\n",
340
                    g_module_name(module));
341
342
        if (g_module_symbol(module, "plugin_info",
343
                            (gpointer *)&plugin_info_func)) {
344
                debug_print("calling plugin_info() in %s\n",
345
                            g_module_name(module));
346
                return plugin_info_func();
347
        } else {
348
                g_warning("Cannot get symbol: %s: %s", g_module_name(module),
349
                          g_module_error());
350
                return NULL;
351
        }
352
}
353
354
gboolean syl_plugin_check_version(GModule *module)
355
{
356
        gint (*version_func)(void);
357
        gint ver;
358
        gint a_major;
359
        gint a_minor;
360
        gint p_major;
361
        gint p_minor;
362
363
        g_return_val_if_fail(module != NULL, FALSE);
364
365
        if (g_module_symbol(module, "plugin_interface_version",
366
                            (gpointer *)&version_func)) {
367
                debug_print("calling plugin_interface_version() in %s\n",
368
                            g_module_name(module));
369
                ver = version_func();
370
        } else {
371
                g_warning("Cannot get symbol: %s: %s", g_module_name(module),
372
                          g_module_error());
373
                return FALSE;
374
        }
375
376
        a_major = SYL_PLUGIN_INTERFACE_VERSION & 0xff00;
377
        a_minor = SYL_PLUGIN_INTERFACE_VERSION & 0x00ff;
378
        p_major = ver & 0xff00;
379
        p_minor = ver & 0x00ff;
380
        if (a_major == p_major && a_minor >= p_minor) {
381
                debug_print("Version OK: plugin: %d, app: %d\n",
382
                            ver, SYL_PLUGIN_INTERFACE_VERSION);
383
                return TRUE;
384
        } else {
385
                g_warning("Plugin interface version mismatch: plugin: %d, app: %d", ver, SYL_PLUGIN_INTERFACE_VERSION);
386
                return FALSE;
387
        }
388
}
389
390
gint syl_plugin_add_symbol(const gchar *name, gpointer sym)
391
{
392
        g_hash_table_insert(sym_table, (gpointer)name, sym);
393
        return 0;
394
}
395
396
gpointer syl_plugin_lookup_symbol(const gchar *name)
397
{
398
        return g_hash_table_lookup(sym_table, name);
399
}
400
401
const gchar *syl_plugin_get_prog_version(void)
402
{
403
        gpointer sym;
404
405
        sym = syl_plugin_lookup_symbol("prog_version");
406
        return (gchar *)sym;
407
}
408
409
void syl_plugin_main_window_lock(void)
410
{
411
        CALL_VOID_POINTER(syl_plugin_main_window_get,
412
                          "main_window_lock");
413
}
414
415
void syl_plugin_main_window_unlock(void)
416
{
417
        CALL_VOID_POINTER(syl_plugin_main_window_get,
418
                          "main_window_unlock");
419
}
420
421
gpointer syl_plugin_main_window_get(void)
422
{
423
        gpointer (*func)(void);
424
425
        func = syl_plugin_lookup_symbol("main_window_get");
426
        return SAFE_CALL_RET(func);
427
}
428
429
void syl_plugin_main_window_popup(gpointer mainwin)
430
{
431
        void (*func)(gpointer);
432
433
        func = syl_plugin_lookup_symbol("main_window_popup");
434
        SAFE_CALL_ARG1(func, mainwin);
435
}
436
437
GtkWidget *syl_plugin_main_window_get_statusbar(void)
438
{
439
        gpointer widget;
440
441
        widget = syl_plugin_lookup_symbol("main_window_statusbar");
442
        return GTK_WIDGET(widget);
443
}
444
445
void syl_plugin_app_will_exit(gboolean force)
446
{
447
        void (*func)(gboolean);
448
449
        func = syl_plugin_lookup_symbol("app_will_exit");
450
        SAFE_CALL_ARG1(func, force);
451
}
452
453
static GtkItemFactory *get_item_factory(const gchar *path)
454
{
455
        GtkItemFactory *ifactory;
456
457
        if (!path)
458
                return NULL;
459
460
        if (strncmp(path, "<Main>", 6) == 0)
461
                ifactory = syl_plugin_lookup_symbol("main_window_menu_factory");
462
        else if (strncmp(path, "<MailFolder>", 12) == 0)
463
                ifactory = syl_plugin_lookup_symbol("folderview_mail_popup_factory");
464
        else if (strncmp(path, "<IMAPFolder>", 12) == 0)
465
                ifactory = syl_plugin_lookup_symbol("folderview_imap_popup_factory");
466
        else if (strncmp(path, "<NewsFolder>", 12) == 0)
467
                ifactory = syl_plugin_lookup_symbol("folderview_news_popup_factory");
468
        else if (strncmp(path, "<SummaryView>", 13) == 0)
469
                ifactory = syl_plugin_lookup_symbol("summaryview_popup_factory");
470
        else
471
                ifactory = syl_plugin_lookup_symbol("main_window_menu_factory");
472
473
        return ifactory;
474
}
475
476
gint syl_plugin_add_menuitem(const gchar *parent, const gchar *label,
477
                             SylPluginCallbackFunc func, gpointer data)
478
{
479
        GtkItemFactory *ifactory;
480
        GtkWidget *menu;
481
        GtkWidget *menuitem;
482
483
        if (!parent)
484
                return -1;
485
486
        ifactory = get_item_factory(parent);
487
        if (!ifactory)
488
                return -1;
489
490
        menu = gtk_item_factory_get_widget(ifactory, parent);
491
        if (!menu)
492
                return -1;
493
494
        if (label)
495
                menuitem = gtk_menu_item_new_with_label(label);
496
        else {
497
                menuitem = gtk_menu_item_new();
498
                gtk_widget_set_sensitive(menuitem, FALSE);
499
        }
500
        gtk_widget_show(menuitem);
501
        gtk_menu_append(GTK_MENU(menu), menuitem);
502
        if (func)
503
                g_signal_connect(G_OBJECT(menuitem), "activate",
504
                                 G_CALLBACK(func), data);
505
506
        return 0;
507
}
508
509
gint syl_plugin_add_factory_item(const gchar *parent, const gchar *label,
510
                                 SylPluginCallbackFunc func, gpointer data)
511
{
512
        GtkItemFactory *ifactory;
513
        GtkItemFactoryEntry entry = {NULL, NULL, NULL, 0, NULL};
514
515
        if (!parent)
516
                return -1;
517
518
        ifactory = get_item_factory(parent);
519
        if (!ifactory)
520
                return -1;
521
522
        if (label) {
523
                entry.path = (gchar *)label;
524
                if (g_str_has_suffix(label, "/---"))
525
                        entry.item_type = "<Separator>";
526
                else
527
                        entry.item_type = NULL;
528
        } else {
529
                entry.path = "/---";
530
                entry.item_type = "<Separator>";
531
        }
532
        entry.callback = func;
533
        g_print("entry.path = %s\n", entry.path);
534
535
        gtk_item_factory_create_item(ifactory, &entry, data, 2);
536
537
        return 0;
538
}
539
540
void syl_plugin_menu_set_sensitive(const gchar *path, gboolean sensitive)
541
{
542
        GtkItemFactory *ifactory;
543
        GtkWidget *widget;
544
545
        g_return_if_fail(path != NULL);
546
547
        ifactory = get_item_factory(path);
548
        if (!ifactory)
549
                return;
550
551
        widget = gtk_item_factory_get_item(ifactory, path);
552
        gtk_widget_set_sensitive(widget, sensitive);
553
}
554
555
void syl_plugin_menu_set_sensitive_all(GtkMenuShell *menu_shell,
556
                                       gboolean sensitive)
557
{
558
        GList *cur;
559
560
        for (cur = menu_shell->children; cur != NULL; cur = cur->next)
561
                gtk_widget_set_sensitive(GTK_WIDGET(cur->data), sensitive);
562
}
563
564
void syl_plugin_menu_set_active(const gchar *path, gboolean is_active)
565
{
566
        GtkItemFactory *ifactory;
567
        GtkWidget *widget;
568
569
        g_return_if_fail(path != NULL);
570
571
        ifactory = get_item_factory(path);
572
        if (!ifactory)
573
                return;
574
575
        widget = gtk_item_factory_get_item(ifactory, path);
576
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), is_active);
577
}
578
579
gpointer syl_plugin_folderview_get(void)
580
{
581
        gpointer (*func)(void);
582
        GETFUNC("folderview_get");
583
        return SAFE_CALL_RET(func);
584
}
585
586
void syl_plugin_folderview_add_sub_widget(GtkWidget *widget)
587
{
588
        void (*func)(gpointer, GtkWidget *);
589
        gpointer folderview;
590
591
        folderview = syl_plugin_folderview_get();
592
        if (folderview) {
593
                GETFUNC("folderview_add_sub_widget");
594
                SAFE_CALL_ARG2(func, folderview, widget);
595
        }
596
}
597
598
void syl_plugin_folderview_select(FolderItem *item)
599
{
600
        void (*func)(gpointer, FolderItem *);
601
        gpointer folderview;
602
603
        folderview = syl_plugin_folderview_get();
604
        if (folderview) {
605
                GETFUNC("folderview_select");
606
                SAFE_CALL_ARG2(func, folderview, item);
607
        }
608
}
609
610
void syl_plugin_folderview_unselect(void)
611
{
612
        CALL_VOID_POINTER(syl_plugin_folderview_get,
613
                          "folderview_unselect");
614
}
615
616
void syl_plugin_folderview_select_next_unread(void)
617
{
618
        CALL_VOID_POINTER(syl_plugin_folderview_get,
619
                          "folderview_select_next_unread");
620
}
621
622
FolderItem *syl_plugin_folderview_get_selected_item(void)
623
{
624
        FolderItem * (*func)(gpointer);
625
        gpointer folderview;
626
627
        folderview = syl_plugin_folderview_get();
628
        if (folderview) {
629
                GETFUNC("folderview_get_selected_item");
630
                return SAFE_CALL_ARG1_RET(func, folderview);
631
        }
632
633
        return NULL;
634
}
635
636
gint syl_plugin_folderview_check_new(Folder *folder)
637
{
638
        gint (*func)(Folder *);
639
        GETFUNC("folderview_check_new");
640
        return SAFE_CALL_ARG1_RET_VAL(func, folder, FALSE);
641
}
642
643
gint syl_plugin_folderview_check_new_item(FolderItem *item)
644
{
645
        gint (*func)(FolderItem *);
646
        GETFUNC("folderview_check_new_item");
647
        return SAFE_CALL_ARG1_RET_VAL(func, item, FALSE);
648
}
649
650
gint syl_plugin_folderview_check_new_all(void)
651
{
652
        gint (*func)(void);
653
        GETFUNC("folderview_check_new_all");
654
        return SAFE_CALL_RET_VAL(func, FALSE);
655
}
656
657
void syl_plugin_folderview_update_item(FolderItem *item,
658
                                       gboolean update_summary)
659
{
660
        void (*func)(FolderItem *, gboolean);
661
        GETFUNC("folderview_update_item");
662
        SAFE_CALL_ARG2(func, item, update_summary);
663
}
664
665
void syl_plugin_folderview_update_item_foreach(GHashTable *table,
666
                                               gboolean update_summary)
667
{
668
        void (*func)(GHashTable *, gboolean);
669
        GETFUNC("folderview_update_item_foreach");
670
        SAFE_CALL_ARG2(func, table, update_summary);
671
}
672
673
void syl_plugin_folderview_update_all_updated(gboolean update_summary)
674
{
675
        void (*func)(gboolean);
676
        GETFUNC("folderview_update_all_updated");
677
        SAFE_CALL_ARG1(func, update_summary);
678
}
679
680
void syl_plugin_folderview_check_new_selected(void)
681
{
682
        CALL_VOID_POINTER(syl_plugin_folderview_get,
683
                          "folderview_check_new_selected");
684
}
685
686
gpointer syl_plugin_summary_view_get(void)
687
{
688
        gpointer sym;
689
690
        sym = syl_plugin_lookup_symbol("summaryview");
691
        return sym;
692
}
693
694
void syl_plugin_summary_select_by_msgnum(guint msgnum)
695
{
696
        void (*func)(gpointer, guint);
697
        gpointer summary;
698
699
        summary = syl_plugin_summary_view_get();
700
        if (summary) {
701
                func = syl_plugin_lookup_symbol("summary_select_by_msgnum");
702
                SAFE_CALL_ARG2(func, summary, msgnum);
703
        }
704
}
705
706
gboolean syl_plugin_summary_select_by_msginfo(MsgInfo *msginfo)
707
{
708
        gboolean (*func)(gpointer, MsgInfo *);
709
        gpointer summary;
710
711
        summary = syl_plugin_summary_view_get();
712
        if (summary) {
713
                func = syl_plugin_lookup_symbol("summary_select_by_msginfo");
714
                return SAFE_CALL_ARG2_RET_VAL(func, summary, msginfo, FALSE);
715
        }
716
717
        return FALSE;
718
}
719
720
void syl_plugin_open_message(const gchar *folder_id, guint msgnum)
721
{
722
        FolderItem *item;
723
        MsgInfo *msginfo;
724
725
        item = folder_find_item_from_identifier(folder_id);
726
        msginfo = folder_item_get_msginfo(item, msgnum);
727
728
        if (msginfo) {
729
                if (!syl_plugin_summary_select_by_msginfo(msginfo)) {
730
                        syl_plugin_open_message_by_new_window(msginfo);
731
                }
732
                procmsg_msginfo_free(msginfo);
733
        }
734
}
735
736
void syl_plugin_summary_show_queued_msgs(void)
737
{
738
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
739
                          "summary_show_queued_msgs");
740
}
741
742
void syl_plugin_summary_lock(void)
743
{
744
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
745
                          "summary_lock");
746
}
747
748
void syl_plugin_summary_unlock(void)
749
{
750
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
751
                          "summary_unlock");
752
}
753
754
gboolean syl_plugin_summary_is_locked(void)
755
{
756
        gboolean (*func)(gpointer);
757
        gpointer summary;
758
759
        summary = syl_plugin_summary_view_get();
760
        if (summary) {
761
                GETFUNC("summary_is_locked");
762
                return SAFE_CALL_ARG1_RET_VAL(func, summary, FALSE);
763
        }
764
765
        return FALSE;
766
}
767
768
gboolean syl_plugin_summary_is_read_locked(void)
769
{
770
        gboolean (*func)(gpointer);
771
        gpointer summary;
772
773
        summary = syl_plugin_summary_view_get();
774
        if (summary) {
775
                GETFUNC("summary_is_read_locked");
776
                return SAFE_CALL_ARG1_RET_VAL(func, summary, FALSE);
777
        }
778
779
        return FALSE;
780
}
781
782
void syl_plugin_summary_write_lock(void)
783
{
784
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
785
                          "summary_write_lock");
786
}
787
788
void syl_plugin_summary_write_unlock(void)
789
{
790
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
791
                          "summary_write_unlock");
792
}
793
794
gboolean syl_plugin_summary_is_write_locked(void)
795
{
796
        gboolean (*func)(gpointer);
797
        gpointer summary;
798
799
        summary = syl_plugin_summary_view_get();
800
        if (summary) {
801
                GETFUNC("summary_is_write_locked");
802
                return SAFE_CALL_ARG1_RET_VAL(func, summary, FALSE);
803
        }
804
805
        return FALSE;
806
}
807
808
FolderItem *syl_plugin_summary_get_current_folder(void)
809
{
810
        FolderItem * (*func)(gpointer);
811
        gpointer summary;
812
813
        summary = syl_plugin_summary_view_get();
814
        if (summary) {
815
                GETFUNC("summary_get_current_folder");
816
                return SAFE_CALL_ARG1_RET(func, summary);
817
        }
818
819
        return NULL;
820
}
821
822
gint syl_plugin_summary_get_selection_type(void)
823
{
824
        gint (*func)(gpointer);
825
        gpointer summary;
826
827
        summary = syl_plugin_summary_view_get();
828
        if (summary) {
829
                GETFUNC("summary_get_selection_type");
830
                return SAFE_CALL_ARG1_RET_VAL(func, summary, 0);
831
        }
832
833
        return 0;
834
}
835
836
GSList *syl_plugin_summary_get_selected_msg_list(void)
837
{
838
        GSList * (*func)(gpointer);
839
        gpointer summary;
840
841
        summary = syl_plugin_summary_view_get();
842
        if (summary) {
843
                GETFUNC("summary_get_selected_msg_list");
844
                return SAFE_CALL_ARG1_RET(func, summary);
845
        }
846
847
        return NULL;
848
}
849
850
GSList *syl_plugin_summary_get_msg_list(void)
851
{
852
        GSList * (*func)(gpointer);
853
        gpointer summary;
854
855
        summary = syl_plugin_summary_view_get();
856
        if (summary) {
857
                GETFUNC("summary_get_msg_list");
858
                return SAFE_CALL_ARG1_RET(func, summary);
859
        }
860
861
        return NULL;
862
}
863
864
void syl_plugin_summary_redisplay_msg(void)
865
{
866
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
867
                          "summary_redisplay_msg");
868
}
869
870
void syl_plugin_summary_open_msg(void)
871
{
872
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
873
                          "summary_open_msg");
874
}
875
876
void syl_plugin_summary_view_source(void)
877
{
878
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
879
                          "summary_view_source");
880
}
881
882
void syl_plugin_summary_reedit(void)
883
{
884
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
885
                          "summary_reedit");
886
}
887
888
void syl_plugin_summary_update_selected_rows(void)
889
{
890
        CALL_VOID_POINTER(syl_plugin_summary_view_get,
891
                          "summary_update_selected_rows");
892
}
893
894
void syl_plugin_summary_update_by_msgnum(guint msgnum)
895
{
896
        void (*func)(gpointer, guint);
897
        gpointer summary;
898
899
        summary = syl_plugin_summary_view_get();
900
        if (summary) {
901
                func = syl_plugin_lookup_symbol("summary_update_by_msgnum");
902
                SAFE_CALL_ARG2(func, summary, msgnum);
903
        }
904
}
905
906
gpointer syl_plugin_messageview_create_with_new_window(void)
907
{
908
        gpointer (*func)(void);
909
910
        func = syl_plugin_lookup_symbol("messageview_create_with_new_window");
911
        return SAFE_CALL_RET(func);
912
}
913
914
void syl_plugin_open_message_by_new_window(MsgInfo *msginfo)
915
{
916
        gpointer msgview;
917
        gpointer (*func)(gpointer, MsgInfo *, gboolean);
918
919
        msgview = syl_plugin_messageview_create_with_new_window();
920
        if (msgview) {
921
                func = syl_plugin_lookup_symbol("messageview_show");
922
                SAFE_CALL_ARG3(func, msgview, msginfo, FALSE);
923
        }
924
}
925
926
927
gpointer syl_plugin_compose_new(PrefsAccount *account, FolderItem *item,
928
                                const gchar *mailto, GPtrArray *attach_files)
929
{
930
        gpointer (*func)(PrefsAccount *, FolderItem *, const gchar *,
931
                         GPtrArray *);
932
933
        func = syl_plugin_lookup_symbol("compose_new");
934
        return SAFE_CALL_ARG4_RET(func, account, item, mailto, attach_files);
935
}
936
937
void syl_plugin_compose_entry_set(gpointer compose, const gchar *text,
938
                                  gint type)
939
{
940
        void (*func)(gpointer, const gchar *, gint);
941
942
        func = syl_plugin_lookup_symbol("compose_entry_set");
943
        SAFE_CALL_ARG3(func, compose, text, type);
944
}
945
946
void syl_plugin_compose_entry_append(gpointer compose, const gchar *text,
947
                                     gint type)
948
{
949
        void (*func)(gpointer, const gchar *, gint);
950
951
        func = syl_plugin_lookup_symbol("compose_entry_append");
952
        SAFE_CALL_ARG3(func, compose, text, type);
953
}
954
955
gchar *syl_plugin_compose_entry_get_text(gpointer compose, gint type)
956
{
957
        gchar * (*func)(gpointer, gint);
958
959
        func = syl_plugin_lookup_symbol("compose_entry_get_text");
960
        return SAFE_CALL_ARG2_RET(func, compose, type);
961
}
962
963
void syl_plugin_compose_lock(gpointer compose)
964
{
965
        void (*func)(gpointer);
966
967
        func = syl_plugin_lookup_symbol("compose_lock");
968
        SAFE_CALL_ARG1(func, compose);
969
}
970
971
void syl_plugin_compose_unlock(gpointer compose)
972
{
973
        void (*func)(gpointer);
974
975
        func = syl_plugin_lookup_symbol("compose_unlock");
976
        SAFE_CALL_ARG1(func, compose);
977
}
978
979
980
FolderItem *syl_plugin_folder_sel(Folder *cur_folder, gint sel_type,
981
                                  const gchar *default_folder)
982
{
983
        FolderItem * (*func)(Folder *, gint, const gchar *);
984
985
        func = syl_plugin_lookup_symbol("foldersel_folder_sel");
986
        return SAFE_CALL_ARG3_RET(func, cur_folder, sel_type, default_folder);
987
}
988
989
FolderItem *syl_plugin_folder_sel_full(Folder *cur_folder, gint sel_type,
990
                                       const gchar *default_folder,
991
                                       const gchar *message)
992
{
993
        FolderItem * (*func)(Folder *, gint, const gchar *, const gchar *);
994
995
        func = syl_plugin_lookup_symbol("foldersel_folder_sel_full");
996
        return SAFE_CALL_ARG4_RET(func, cur_folder, sel_type, default_folder,
997
                                  message);
998
}
999
1000
gchar *syl_plugin_input_dialog(const gchar *title, const gchar *message,
1001
                               const gchar *default_string)
1002
{
1003
        gchar * (*func)(const gchar *, const gchar *, const gchar *);
1004
1005
        func = syl_plugin_lookup_symbol("input_dialog");
1006
        return SAFE_CALL_ARG3_RET(func, title, message, default_string);
1007
}
1008
1009
gchar *syl_plugin_input_dialog_with_invisible(const gchar *title,
1010
                                              const gchar *message,
1011
                                              const gchar *default_string)
1012
{
1013
        gchar * (*func)(const gchar *, const gchar *, const gchar *);
1014
1015
        func = syl_plugin_lookup_symbol("input_dialog_with_invisible");
1016
        return SAFE_CALL_ARG3_RET(func, title, message, default_string);
1017
}
1018
1019
void syl_plugin_manage_window_set_transient(GtkWindow *window)
1020
{
1021
        void (*func)(GtkWindow *);
1022
1023
        func = syl_plugin_lookup_symbol("manage_window_set_transient");
1024
        SAFE_CALL_ARG1(func, window);
1025
}
1026
1027
void syl_plugin_manage_window_signals_connect(GtkWindow *window)
1028
{
1029
        void (*func)(GtkWindow *);
1030
1031
        func = syl_plugin_lookup_symbol("manage_window_signals_connect");
1032
        SAFE_CALL_ARG1(func, window);
1033
}
1034
1035
GtkWidget *syl_plugin_manage_window_get_focus_window(void)
1036
{
1037
        GtkWidget * (*func)(void);
1038
1039
        func = syl_plugin_lookup_symbol("manage_window_get_focus_window");
1040
        return SAFE_CALL_RET(func);
1041
}
1042
1043
void syl_plugin_inc_mail(void)
1044
{
1045
        void (*func)(gpointer);
1046
1047
        func = syl_plugin_lookup_symbol("inc_mail");
1048
        SAFE_CALL_ARG1(func, syl_plugin_main_window_get());
1049
}
1050
1051
gboolean syl_plugin_inc_is_active(void)
1052
{
1053
        gboolean (*func)(void);
1054
1055
        func = syl_plugin_lookup_symbol("inc_is_active");
1056
        return SAFE_CALL_RET_VAL(func, FALSE);
1057
}
1058
1059
void syl_plugin_inc_lock(void)
1060
{
1061
        void (*func)(void);
1062
1063
        func = syl_plugin_lookup_symbol("inc_lock");
1064
        SAFE_CALL(func);
1065
}
1066
1067
void syl_plugin_inc_unlock(void)
1068
{
1069
        void (*func)(void);
1070
1071
        func = syl_plugin_lookup_symbol("inc_unlock");
1072
        SAFE_CALL(func);
1073
}
1074
1075
void syl_plugin_update_check(gboolean show_dialog_always)
1076
{
1077
        void (*func)(gboolean);
1078
1079
        func = syl_plugin_lookup_symbol("update_check");
1080
        SAFE_CALL_ARG1(func, show_dialog_always);
1081
}
1082
1083
void syl_plugin_update_check_set_check_url(const gchar *url)
1084
{
1085
        void (*func)(const gchar *);
1086
1087
        func = syl_plugin_lookup_symbol("update_check_set_check_url");
1088
        SAFE_CALL_ARG1(func, url);
1089
}
1090
1091
const gchar *syl_plugin_update_check_get_check_url(void)
1092
{
1093
        const gchar * (*func)(void);
1094
1095
        func = syl_plugin_lookup_symbol("update_check_get_check_url");
1096
        return SAFE_CALL_RET(func);
1097
}
1098
1099
void syl_plugin_update_check_set_download_url(const gchar *url)
1100
{
1101
        void (*func)(const gchar *);
1102
1103
        func = syl_plugin_lookup_symbol("update_check_set_download_url");
1104
        SAFE_CALL_ARG1(func, url);
1105
}
1106
1107
const gchar *syl_plugin_update_check_get_download_url(void)
1108
{
1109
        const gchar * (*func)(void);
1110
1111
        func = syl_plugin_lookup_symbol("update_check_get_download_url");
1112
        return SAFE_CALL_RET(func);
1113
}
1114
1115
void syl_plugin_update_check_set_jump_url(const gchar *url)
1116
{
1117
        void (*func)(const gchar *);
1118
1119
        func = syl_plugin_lookup_symbol("update_check_set_jump_url");
1120
        SAFE_CALL_ARG1(func, url);
1121
}
1122
1123
const gchar *syl_plugin_update_check_get_jump_url(void)
1124
{
1125
        const gchar * (*func)(void);
1126
1127
        func = syl_plugin_lookup_symbol("update_check_get_jump_url");
1128
        return SAFE_CALL_RET(func);
1129
}
1130
1131
void syl_plugin_update_check_set_check_plugin_url(const gchar *url)
1132
{
1133
        void (*func)(const gchar *);
1134
1135
        func = syl_plugin_lookup_symbol("update_check_set_check_plugin_url");
1136
        SAFE_CALL_ARG1(func, url);
1137
}
1138
1139
const gchar *syl_plugin_update_check_get_check_plugin_url(void)
1140
{
1141
        const gchar * (*func)(void);
1142
1143
        func = syl_plugin_lookup_symbol("update_check_get_check_plugin_url");
1144
        return SAFE_CALL_RET(func);
1145
}
1146
1147
void syl_plugin_update_check_set_jump_plugin_url(const gchar *url)
1148
{
1149
        void (*func)(const gchar *);
1150
1151
        func = syl_plugin_lookup_symbol("update_check_set_jump_plugin_url");
1152
        SAFE_CALL_ARG1(func, url);
1153
}
1154
1155
const gchar *syl_plugin_update_check_get_jump_plugin_url(void)
1156
{
1157
        const gchar * (*func)(void);
1158
1159
        func = syl_plugin_lookup_symbol("update_check_get_jump_plugin_url");
1160
        return SAFE_CALL_RET(func);
1161
}
1162
1163
gint syl_plugin_alertpanel_full(const gchar *title, const gchar *message,
1164
                                gint type, gint default_value,
1165
                                gboolean can_disable,
1166
                                const gchar *btn1_label,
1167
                                const gchar *btn2_label,
1168
                                const gchar *btn3_label)
1169
{
1170
        gint (*func)(const gchar *, const gchar *, gint, gint, gboolean,
1171
                        const gchar *, const gchar *, const gchar *);
1172
1173
        GETFUNC("alertpanel_full");
1174
        return func ? func(title, message, type, default_value, can_disable,
1175
                           btn1_label, btn2_label, btn3_label) : -1;
1176
}
1177
1178
gint syl_plugin_alertpanel(const gchar *title, const gchar *message,
1179
                           const gchar *btn1_label,
1180
                           const gchar *btn2_label,
1181
                           const gchar *btn3_label)
1182
{
1183
        gint (*func)(const gchar *, const gchar *,
1184
                        const gchar *, const gchar *, const gchar *);
1185
1186
        GETFUNC("alertpanel");
1187
        return func ? func(title, message, btn1_label, btn2_label, btn3_label)
1188
                : -1;
1189
}
1190
1191
void syl_plugin_alertpanel_message(const gchar *title, const gchar *message,
1192
                                   gint type)
1193
{
1194
        void (*func)(const gchar *, const gchar *, gint);
1195
1196
        GETFUNC("alertpanel_message");
1197
        SAFE_CALL_ARG3(func, title, message, type);
1198
}
1199
1200
gint syl_plugin_alertpanel_message_with_disable(const gchar *title,
1201
                                                const gchar *message,
1202
                                                gint type)
1203
{
1204
        gint (*func)(const gchar *, const gchar *, gint);
1205
1206
        GETFUNC("alertpanel_message_with_disable");
1207
        return SAFE_CALL_ARG3_RET_VAL(func, title, message, type, 0);
1208
}
1209
1210
gint syl_plugin_send_message(const gchar *file, PrefsAccount *ac,
1211
                             GSList *to_list)
1212
{
1213
        gint (*func)(const gchar *, PrefsAccount *, GSList *);
1214
1215
        GETFUNC("send_message");
1216
        return SAFE_CALL_ARG3_RET_VAL(func, file, ac, to_list, -1);
1217
}
1218
1219
gint syl_plugin_send_message_queue_all(FolderItem *queue, gboolean save_msgs,
1220
                                       gboolean filter_msgs)
1221
{
1222
        gint (*func)(FolderItem *, gboolean, gboolean);
1223
1224
        GETFUNC("send_message_queue_all");
1225
        return SAFE_CALL_ARG3_RET_VAL(func, queue, save_msgs, filter_msgs, -1);
1226
}
1227
1228
gint syl_plugin_send_message_set_reply_flag(const gchar *reply_target,
1229
                                            const gchar *msgid)
1230
{
1231
        gint (*func)(const gchar *, const gchar *);
1232
1233
        GETFUNC("send_message_set_reply_flag");
1234
        return SAFE_CALL_ARG2_RET_VAL(func, reply_target, msgid, -1);
1235
}
1236
1237
gint syl_plugin_send_message_set_forward_flags(const gchar *forward_targets)
1238
{
1239
        gint (*func)(const gchar *);
1240
1241
        GETFUNC("send_message_set_forward_flags");
1242
        return SAFE_CALL_ARG1_RET_VAL(func, forward_targets, -1);
1243
}