diff options
author | Dan Nicholson <dbn.lists@gmail.com> | 2012-03-03 13:13:26 -0800 |
---|---|---|
committer | Dan Nicholson <dbn.lists@gmail.com> | 2012-03-03 13:13:26 -0800 |
commit | fb1f9f83b11cf5c5a42396b717259af8a33c1406 (patch) | |
tree | 5a3baea02321981661c537edcb1f6d0958af37ad /src | |
parent | 906afec0f48cf1db5bd24945ef7ff033c17336d3 (diff) |
Move plugin sources to src directory
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/evbp-mime.c | 88 | ||||
-rw-r--r-- | src/evbp-mime.h | 8 | ||||
-rw-r--r-- | src/evbp.c | 383 | ||||
-rw-r--r-- | src/evbp.h | 14 |
5 files changed, 501 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..1d58179 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,8 @@ +AM_CFLAGS = $(PLUGIN_CFLAGS) $(E_CFLAGS) + +plugindir = $(libdir)/mozilla/plugins +plugin_LTLIBRARIES = libevbp.la +libevbp_la_LDFLAGS = -avoid-version -module +libevbp_la_LIBADD = $(top_builddir)/previewer/libevpreviewer.la \ + $(PLUGIN_LIBS) +libevbp_la_SOURCES = evbp.c evbp.h evbp-mime.h evbp-mime.c diff --git a/src/evbp-mime.c b/src/evbp-mime.c new file mode 100644 index 0000000..1394990 --- /dev/null +++ b/src/evbp-mime.c @@ -0,0 +1,88 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "evbp-mime.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <evince-document.h> + +static const struct { + const gchar *mime; + const gchar *exts; +} mime_suffix[] = { + { "application/postscript", "ps" }, + { "application/x-bzpostscript", "ps.bz2" }, + { "application/x-gzpostscript", "ps.gz" }, + { "image/x-eps", "eps,epsi,epsf" }, + { "image/x-bzeps", "eps.bz2,epsi.bz2,epsf.bz2" }, + { "image/x-gzeps", "eps.gz,epsi.gz,epsf.gz" }, + { "image/tiff", "tif,tiff" }, + { "application/pdf", "pdf" }, + { "application/x-bzpdf", "pdf.bz2" }, + { "application/x-gzpdf", "pdf.gz" }, + { "application/x-ext-pdf", "pdf" }, + { "application/x-dvi", "dvi" }, + { "application/x-bzdvi", "dvi.bz2" }, + { "application/x-gzdvi", "dvi.gz" }, + { "application/x-cbr", "cbr" }, + { "application/x-cbz", "cbz" }, + { "application/x-cb7", "cb7" }, + { "application/x-cbt", "cbt" }, + { "image/vnd.djvu", "djvu,djv" }, +}; +static const int n_mime_suffix = sizeof(mime_suffix) / sizeof(mime_suffix[0]); + +static const gchar * +get_suffix(const gchar *type) +{ + int i; + + for (i = 0; i < n_mime_suffix; i++) + if (strcmp(type, mime_suffix[i].mime) == 0) + return mime_suffix[i].exts; + return ""; +} + +static void +add_one_mime(EvTypeInfo *type, gpointer udata) +{ + GString *mime_desc = udata; + const gchar **mime; + const gchar *suffix; + + for (mime = type->mime_types; *mime; mime++) { + suffix = get_suffix(*mime); + if (!suffix) + continue; + g_string_append_printf(mime_desc, "%s%s:%s:%s", + (mime_desc->len > 0) ? ";" : "", + *mime, suffix, type->desc); + } +} + +static GString * +build_mime_description(GList *types) +{ + GString *mimes = g_string_new(NULL); + + g_list_foreach(types, (GFunc)add_one_mime, mimes); + return mimes; +} + +GString * +evbp_get_mime_description(void) +{ + GList *types; + GString *mimes; + + types = ev_backends_manager_get_all_types_info(); + mimes = build_mime_description(types); + + g_list_foreach(types, (GFunc)g_free, NULL); + g_list_free(types); + + return mimes; +} diff --git a/src/evbp-mime.h b/src/evbp-mime.h new file mode 100644 index 0000000..807e4e9 --- /dev/null +++ b/src/evbp-mime.h @@ -0,0 +1,8 @@ +#ifndef EVBP_MIME_H +#define EVBP_MIME_H + +#include <glib.h> + +GString *evbp_get_mime_description(void); + +#endif /* _EVBP_PLUGIN_H */ diff --git a/src/evbp.c b/src/evbp.c new file mode 100644 index 0000000..4f95bf2 --- /dev/null +++ b/src/evbp.c @@ -0,0 +1,383 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "evbp.h" +#include "evbp-mime.h" +#include "evbp-debug.h" + +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <npapi.h> +#include <npfunctions.h> +#include <prtypes.h> +#include <glib.h> +#include <glib/gi18n.h> +#include <gtk/gtk.h> +#include <gdk/gdkx.h> +#include <evince-document.h> + +#ifdef PACKAGE_VERSION +#define EVBP_VERSION PACKAGE_VERSION +#else +#define EVBP_VERSION "" +#endif +#define EVBP_NAME "Evince Plugin" +#define EVBP_DESCRIPTION "Evince Browser Plugin " EVBP_VERSION + +static char *evbp_mime_string = NULL; +static const NPNetscapeFuncs *npn_funcs = NULL; +static gboolean evbp_is_initialized = FALSE; + +static gboolean +evbp_initialize(void) +{ + evbp_debug(NULL); + + /* Some backends don't handle repeated init */ + if (evbp_is_initialized) + return TRUE; + + /* Init glib threads asap */ + if (!g_thread_supported()) + g_thread_init(NULL); + +#ifdef ENABLE_NLS + /* Initialize the i18n stuff */ + bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + textdomain(GETTEXT_PACKAGE); +#endif + + /* Initialize gtk */ + gtk_init(NULL, NULL); + + /* Initialize evince */ + if (!ev_init()) + return FALSE; + ev_stock_icons_init(); + + evbp_is_initialized = TRUE; + return TRUE; +} + +static void +evbp_shutdown(void) +{ + evbp_debug(NULL); + + if (!evbp_is_initialized) + return; + + ev_shutdown(); + ev_stock_icons_shutdown(); + + evbp_is_initialized = FALSE; +} + +static NPError +evbp_new(NPMIMEType pluginType, NPP instance, uint16_t mode, + int16_t argc, char *argn[], char *argv[], + NPSavedData *saved) +{ + evbp_priv_t *priv; + + evbp_debug(NULL); + + /* create new private data */ + priv = npn_funcs->memalloc(sizeof(*priv)); + if (!priv) + return NPERR_OUT_OF_MEMORY_ERROR; + memset(priv, 0, sizeof(*priv)); + + /* link the structures */ + priv->npp = instance; + instance->pdata = priv; + + /* create new previewer */ + priv->pview = ev_previewer_new(); + + return NPERR_NO_ERROR; +} + +static NPError +evbp_destroy(NPP instance, NPSavedData** save) +{ + evbp_priv_t *priv = instance->pdata; + + evbp_debug(NULL); + + g_object_unref(priv->pview); + npn_funcs->memfree(instance->pdata); + instance->pdata = NULL; + + return NPERR_NO_ERROR; +} + +static NPError +evbp_set_window(NPP instance, NPWindow *window) +{ + evbp_priv_t *priv = instance->pdata; + GtkWidget *pview = priv->pview; + GdkNativeWindow id; + GtkWidget *plug; + + evbp_debug(NULL); + + /* If this is the same window we already have, don't create a + new plug */ + if (window == priv->window) { + evbp_debug("Same window; returning\n"); + return NPERR_NO_ERROR; + } + priv->window = window; + + /* Create a plug from the window id we were told about */ + id = (GdkNativeWindow)(unsigned long)window->window; + evbp_debug("Plugging previewer into window id %u\n", id); + plug = gtk_plug_new(id); + gtk_container_add(GTK_CONTAINER(plug), pview); + gtk_widget_show(pview); + gtk_widget_show(plug); + + return NPERR_NO_ERROR; +} + +static NPError +evbp_new_stream(NPP instance, NPMIMEType type, NPStream *stream, + NPBool seekable, uint16_t *stype) +{ + evbp_debug(NULL); + + /* fetch the url to a local file only */ + *stype = NP_ASFILEONLY; + + return NPERR_NO_ERROR; +} + +static NPError +evbp_destroy_stream(NPP instance, NPStream *stream, NPReason reason) +{ + evbp_debug(NULL); + + return NPERR_NO_ERROR; +} + +static int32_t +evbp_write_ready(NPP instance, NPStream *stream) +{ + evbp_debug(NULL); + + return 0; +} + +static int32_t +evbp_write(NPP instance, NPStream *stream, int32_t offset, int32_t len, + void *buffer) +{ + evbp_debug(NULL); + + return 0; +} + +static void +evbp_stream_as_file(NPP instance, NPStream *stream, const char *fname) +{ + evbp_priv_t *priv = instance->pdata; + EvPreviewer *pview = EV_PREVIEWER(priv->pview); + + evbp_debug(NULL); + + if (!g_file_test(fname, G_FILE_TEST_IS_REGULAR)) { + evbp_debug("Filename \"%s\" does not exist or is not a regular file", + fname); + return; + } + priv->filename = fname; + + ev_previewer_set_source_file(pview, fname); +} + +static void +evbp_print(NPP instance, NPPrint *platformPrint) +{ + evbp_debug(NULL); +} + +static int16_t +evbp_handle_event(NPP instance, void *event) +{ + evbp_debug(NULL); + + return 0; +} + +static void +evbp_url_notify(NPP instance, const char *url, NPReason reason, + void *notifyData) +{ + evbp_debug(NULL); +} + +static NPError +evbp_get_value(NPP instance, NPPVariable variable, void *value) +{ + NPError err = NPERR_NO_ERROR; + + evbp_debug(NULL); + + switch (variable) { + case NPPVpluginNameString: + *((char **)value) = EVBP_NAME; + break; + case NPPVpluginDescriptionString: + *((char **)value) = EVBP_DESCRIPTION; + break; + case NPPVpluginNeedsXEmbed: + /* Require XEmbed */ + *((PRBool *)value) = PR_TRUE; + break; + default: + err = NPERR_GENERIC_ERROR; + } + + return err; +} + +static NPError +evbp_set_value(NPP instance, NPNVariable variable, void *value) +{ + evbp_debug(NULL); + + return NPERR_GENERIC_ERROR; +} + +static NPError +save_npn_funcs(const NPNetscapeFuncs *funcs) +{ + evbp_debug(NULL); + + /* Check for valid structure and compatibility */ + if (!funcs) + return NPERR_INVALID_FUNCTABLE_ERROR; + if (funcs->version >> 8 > NP_VERSION_MAJOR) + return NPERR_INCOMPATIBLE_VERSION_ERROR; + if (funcs->size < sizeof(npn_funcs)) + return NPERR_INVALID_FUNCTABLE_ERROR; + + npn_funcs = funcs; + return NPERR_NO_ERROR; +} + +static NPError +fill_npp_funcs(NPPluginFuncs *funcs) +{ + evbp_debug(NULL); + + if (!funcs) + return NPERR_INVALID_FUNCTABLE_ERROR; + + /* Fill the browser's table */ + funcs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + funcs->size = sizeof(*funcs); + funcs->newp = evbp_new; + funcs->destroy = evbp_destroy; + funcs->setwindow = evbp_set_window; + funcs->newstream = evbp_new_stream; + funcs->destroystream = evbp_destroy_stream; + funcs->asfile = evbp_stream_as_file; + funcs->writeready = evbp_write_ready; + funcs->write = evbp_write; + funcs->print = evbp_print; + funcs->event = evbp_handle_event; + funcs->urlnotify = evbp_url_notify; + funcs->getvalue = evbp_get_value; + funcs->setvalue = evbp_set_value; + + return NPERR_NO_ERROR; +} + +NPError +NP_Initialize(NPNetscapeFuncs *nfuncs, NPPluginFuncs *pfuncs) +{ + NPError ret; + PRBool xembed = PR_FALSE; + NPNToolkitType toolkit = 0; + + evbp_debug(NULL); + + ret = save_npn_funcs(nfuncs); + if (ret != NPERR_NO_ERROR) + return ret; + + ret = fill_npp_funcs(pfuncs); + if (ret != NPERR_NO_ERROR) + return ret; + + /* Check that the browser supports XEmbed */ + ret = npn_funcs->getvalue(NULL, NPNVSupportsXEmbedBool, + (void *)&xembed); + if (ret != NPERR_NO_ERROR || xembed != PR_TRUE) + return NPERR_INCOMPATIBLE_VERSION_ERROR; + + /* Check that the toolkit is Gtk2 */ + ret = npn_funcs->getvalue(NULL, NPNVToolkit, (void *)&toolkit); + if (ret != NPERR_NO_ERROR || toolkit != NPNVGtk2) + return NPERR_INCOMPATIBLE_VERSION_ERROR; + + if (!evbp_initialize()) + return NPERR_MODULE_LOAD_FAILED_ERROR; + + return NPERR_NO_ERROR; +} + +char * +NP_GetPluginVersion(void) +{ + evbp_debug(NULL); + + return EVBP_VERSION; +} + +char * +NP_GetMIMEDescription(void) +{ + GString *mimes; + + evbp_debug(NULL); + + if (!evbp_initialize()) + return NULL; + + mimes = evbp_get_mime_description(); + if (evbp_mime_string) + g_free(evbp_mime_string); + evbp_mime_string = g_string_free(mimes, FALSE); + + return evbp_mime_string; +} + +NPError +NP_Shutdown(void) +{ + evbp_debug(NULL); + + if (evbp_mime_string) { + g_free(evbp_mime_string); + evbp_mime_string = NULL; + } + npn_funcs = NULL; + + evbp_shutdown(); + + return NPERR_NO_ERROR; +} + +NPError +NP_GetValue(void *instance, NPPVariable variable, void *value) +{ + evbp_debug(NULL); + + return evbp_get_value(NULL, variable, value); +} diff --git a/src/evbp.h b/src/evbp.h new file mode 100644 index 0000000..501a7e0 --- /dev/null +++ b/src/evbp.h @@ -0,0 +1,14 @@ +#ifndef EVBP_PLUGIN_H +#define EVBP_PLUGIN_H + +#include <npapi.h> +#include "previewer/ev-previewer.h" + +typedef struct evbp_priv { + NPP npp; + NPWindow *window; + const char *filename; + GtkWidget *pview; +} evbp_priv_t; + +#endif /* EVBP_PLUGIN_H */ |