summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlliver Schinagl <oliver@schinagl.nl>2016-03-11 08:11:32 (GMT)
committerOlliver Schinagl <oliver@schinagl.nl>2016-03-18 20:46:27 (GMT)
commit32fb990072022f7668930473e07c3ae0eb3d8215 (patch)
tree79736e547aea85e597f403e24f84f06cb19c6541
parent6cd8ff8f7101091559fa60535cb26d7c30b23fdf (diff)
downloadengagement-32fb990072022f7668930473e07c3ae0eb3d8215.zip
engagement-32fb990072022f7668930473e07c3ae0eb3d8215.tar.gz
engagement-32fb990072022f7668930473e07c3ae0eb3d8215.tar.bz2
Add initial plugin header
This patch adds the first preliminary draft plugin description. It is missing many things, most importantly documentation. More importantly it is likely not yet complete. Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
-rw-r--r--configure.ac1
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/include/Makefile.am6
-rw-r--r--src/include/engagement/plugin.h78
-rw-r--r--src/lib/Makefile.am5
-rw-r--r--src/lib/plugin.c74
7 files changed, 164 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index e8b8193..4396242 100644
--- a/configure.ac
+++ b/configure.ac
@@ -94,6 +94,7 @@ packaging/pkgbuild/Makefile
po/Makefile.in
src/Makefile
src/bin/Makefile
+src/include/Makefile
src/lib/Makefile
src/tests/Makefile
doc/engagement.1
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2708812..7269d3e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,2 +1,3 @@
src/bin/engagement.c
src/bin/engagement_private.h
+src/lib/plugin.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 15871c9..b52407c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
MAINTAINERCLEANFILES = Makefile.in
-SUBDIRS = lib bin tests
+SUBDIRS = include lib bin tests
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
new file mode 100644
index 0000000..6a1282d
--- /dev/null
+++ b/src/include/Makefile.am
@@ -0,0 +1,6 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+includesdir = $(includedir)/engagement
+includes_HEADERS = engagement/plugin.h
+
+EXTRA_DIST = gettext.h
diff --git a/src/include/engagement/plugin.h b/src/include/engagement/plugin.h
new file mode 100644
index 0000000..7bd7fa6
--- /dev/null
+++ b/src/include/engagement/plugin.h
@@ -0,0 +1,78 @@
+/*
+ * (c) Copyright 2016 Olliver Schinagl
+ * Author: Olliver Schinagl <oliver@schinagl.nl>
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ */
+
+/** \file
+ * Common header to describe the generic plugin API.
+ */
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/**
+ * @defgroup Plugins
+ * @ingroup engagement
+ *
+ * Generic plugin API
+ */
+
+#define PLUGIN_MAGIC 0 /* TODO pick plugin magic */
+#define PLUGIN_VERSION_MAJOR 0 /* TODO replace with version from src? @ENGAGEMENT_VERSION_MAJOR@ */
+#define PLUGIN_VERSION_MINOR 0 /* TODO replace with version from src? */
+
+#define PLUGIN_SYMBOL "calendar_plugin" /* TODO use generic name */
+
+#define PLUGIN_INIT(plugin)
+
+enum plugin_type {
+ PLUGIN_TYPE_CALENDAR,
+ PLUGIN_TYPE_DIRECTORY,
+};
+
+struct plugin_info {
+ const char *name;
+ const char *summary;
+ const char *description;
+ const char *help;
+ const char *author;
+ const char *email;
+ const char *url;
+};
+
+struct plugin_version {
+ uint8_t major;
+ uint8_t minor;
+ uint32_t micro;
+};
+
+struct plugin {
+ uint32_t magic;
+ void *_handle;
+ enum plugin_type type;
+ const char *id;
+ struct plugin_version version;
+ struct plugin_info info;
+ void *dependencies; /* Unused/reserved */
+ bool (*load)(void);
+ bool (*unload)(void);
+ void *ui; /* struct plugin_ui ui; Unused/reserved */
+ void *ops;
+ void *priv;
+};
+
+struct plugin *plugin_load(const char *path);
+int plugin_unload(struct plugin *plugin);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _PLUGIN_H_ */
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 0eaf568..fc64133 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -3,6 +3,7 @@ MAINTAINERCLEANFILES = Makefile.in
AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
-I$(top_builddir)/src/lib \
+-I$(top_srcdir)/src/include \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EFL_CFLAGS@ \
@@ -13,6 +14,6 @@ lib_LTLIBRARIES = libengagement.la
includes_HEADERS = engagement.h
includesdir = $(includedir)/engagement-@VMAJ@
-libengagement_la_SOURCES = engagement.c
-libengagement_la_LIBADD = @EFL_LIBS@ -lm
+libengagement_la_SOURCES = engagement.c plugin.c
+libengagement_la_LIBADD = @EFL_LIBS@ @LIBDL@
libengagement_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
diff --git a/src/lib/plugin.c b/src/lib/plugin.c
new file mode 100644
index 0000000..09df8de
--- /dev/null
+++ b/src/lib/plugin.c
@@ -0,0 +1,74 @@
+/*
+ * (c) Copyright 2016 Olliver Schinagl
+ * Author: Olliver Schinagl <oliver@schinagl.nl>
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <dlfcn.h>
+
+#include <engagement/plugin.h>
+
+struct plugin *plugin_load(const char *path)
+{
+ struct plugin *plugin;
+ void *handle;
+
+ handle = dlopen(path, RTLD_LAZY); /* TODO check if RTLD_LAZY is what we want */
+ if (!handle) {
+ // TODO EINA_LOG
+ fprintf(stderr, "dlopen failed: %s\n", dlerror());
+ return NULL;
+ }
+
+ /* TODO use macro's to allow for static inclusion */
+ /* TODO use dlvsym() if available */
+ plugin = (struct plugin *)dlsym(handle, PLUGIN_SYMBOL);
+ if(!plugin) {
+ // TODO EINA_LOG
+ fprintf(stderr, "dlsym failed%s\n", dlerror());
+ return NULL;
+ }
+
+ if (plugin->magic != PLUGIN_MAGIC) {
+ // TODO EINA_LOG
+ fprintf(stderr, "Failed to init plugin, magic mismatch, plugin corrupt?\n");
+ return NULL;
+ }
+ plugin->_handle = handle;
+
+ if (plugin->load)
+ plugin->load();
+
+ return plugin;
+}
+
+int plugin_unload(struct plugin *plugin)
+{
+ int error;
+
+ if (!plugin) {
+ // TODO EINA_LOG
+ fprintf(stderr, "Cannot unload plugin %p.\n", plugin);
+ return -EFAULT;
+ }
+
+ if (plugin->unload)
+ plugin->unload();
+
+ if (!plugin->_handle) {
+ // TODO EINA_LOG
+ fprintf(stderr, "Error, no handle for plugin %s\n",
+ plugin->info.name);
+ return -EFAULT;
+ }
+ error = dlclose(plugin->_handle);
+ if (error)
+ // TODO EINA_LOG
+ fprintf(stderr, "Failed to close %s\n", dlerror());
+
+ return error;
+}