changeset 2222:2d9042b24d0b

Merge branch 'ke-lua' Mostly implementing lua integration. * ke-lua: Revert "call notify functions in in an idle call" Implementing some usefull data structures for lua First usable lua callback Using common path for lua files Overlay info with lua Adding support for lua scripting
author Klaus Ethgen <Klaus@Ethgen.de>
date Tue, 02 Oct 2012 22:27:22 +0100
parents 9063024ebc5a (current diff) 59b559f747a7 (diff)
children bd7591bd8dc2
files
diffstat 7 files changed, 365 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/configure.in	Sun Sep 23 11:19:36 2012 +0200
+++ b/configure.in	Tue Oct 02 22:27:22 2012 +0100
@@ -478,6 +478,33 @@
 AC_SUBST(LIBCHAMPLAIN_GTK_CFLAGS)
 AC_SUBST(LIBCHAMPLAIN_GTK_LIBS)
 
+#  Lua support
+# ----------------------------------------------------------------------
+
+AC_ARG_ENABLE([lua],
+  AC_HELP_STRING([--disable-lua], [disable lua support]),
+    [liblua=$enableval], [liblua=auto])
+
+if test "x${liblua}" != "xno"; then
+  PKG_CHECK_MODULES(LUA, lua5.1 >= 5.1,
+    [
+      HAVE_LUA=yes
+      AC_DEFINE(HAVE_LUA, 1, [define to enable lua support])
+    ],
+    [
+      HAVE_LUA=no
+      AC_MSG_WARN([$LUA_PKG_ERRORS])
+    ])
+else
+  HAVE_LUA=disabled
+fi
+
+AM_CONDITIONAL(HAVE_LUA, [test "x$HAVE_LUA" = xyes])
+AC_SUBST(LUA_CFLAGS)
+AC_SUBST(LUA_LIBS)
+
+# ----------------------------------------------------------------------
+
 AH_TOP([
 /** \file
  * \short autogenerated definition by autoheader.
@@ -551,7 +578,7 @@
   Gtk:           $GTK_CFLAGS
   Glib:          $GLIB_CFLAGS
   Thread:        $GTHREAD_LIBS
-  Others:	 $JPEG_LIBS $TIFF_LIBS $LCMS_LIBS $EXIV2_LIBS $CLUTTER_LIBS $CLUTTER_GTK_LIBS $LIBCHAMPLAIN_LIBS $LIBCHAMPLAIN_GTK_LIBS
+  Others:	 $JPEG_LIBS $TIFF_LIBS $LCMS_LIBS $EXIV2_LIBS $CLUTTER_LIBS $CLUTTER_GTK_LIBS $LIBCHAMPLAIN_LIBS $LIBCHAMPLAIN_GTK_LIBS $LUA_LIBS
 
 Localization:
   NLS support:   $USE_NLS
@@ -570,6 +597,7 @@
   Clutter:       $HAVE_CLUTTER
   Libchamplain:		$HAVE_LIBCHAMPLAIN
   Libchamplain-gtk:	$HAVE_LIBCHAMPLAIN_GTK
+  Lua:	         $HAVE_LUA
 
 Documentation:
   Doxygen:       $DOXYGEN
--- a/src/Makefile.am	Sun Sep 23 11:19:36 2012 +0200
+++ b/src/Makefile.am	Tue Oct 02 22:27:22 2012 +0100
@@ -7,6 +7,7 @@
 	$(EXIV2_CFLAGS)			\
 	$(LIBCHAMPLAIN_CFLAGS)		\
 	$(LIBCHAMPLAIN_GTK_CFLAGS)	\
+	$(LUA_CFLAGS)			\
 	$(CLUTTER_CFLAGS)		\
 	$(CLUTTER_GTK_CFLAGS)	\
 	-I$(top_srcdir)			\
@@ -19,6 +20,7 @@
 	$(EXIV2_CFLAGS)			\
 	$(LIBCHAMPLAIN_CFLAGS)		\
 	$(LIBCHAMPLAIN_GTK_CFLAGS)	\
+	$(LUA_CFLAGS)			\
 	$(CLUTTER_CFLAGS)		\
 	$(CLUTTER_GTK_CFLAGS)	\
 	-I$(top_srcdir)			\
@@ -257,9 +259,10 @@
 	view_file_icon.c	\
 	view_file_icon.h	\
 	window.c	\
-	window.h
+	window.h	\
+	lua.c
 
-geeqie_LDADD = $(GTK_LIBS) $(GLIB_LIBS) $(INTLLIBS) $(JPEG_LIBS) $(TIFF_LIBS) $(LCMS_LIBS) $(EXIV2_LIBS) $(LIBCHAMPLAIN_LIBS) $(LIBCHAMPLAIN_GTK_LIBS) $(CLUTTER_LIBS) $(CLUTTER_GTK_LIBS)
+geeqie_LDADD = $(GTK_LIBS) $(GLIB_LIBS) $(INTLLIBS) $(JPEG_LIBS) $(TIFF_LIBS) $(LCMS_LIBS) $(EXIV2_LIBS) $(LIBCHAMPLAIN_LIBS) $(LIBCHAMPLAIN_GTK_LIBS) $(LUA_LIBS) $(CLUTTER_LIBS) $(CLUTTER_GTK_LIBS)
 
 EXTRA_DIST = \
 	$(extra_SLIK)
--- a/src/filedata.c	Sun Sep 23 11:19:36 2012 +0200
+++ b/src/filedata.c	Tue Oct 02 22:27:22 2012 +0100
@@ -2638,12 +2638,6 @@
    implementation in view_file_list.c */
 
 
-typedef struct _NotifyIdleData NotifyIdleData;
-
-struct _NotifyIdleData {
-	FileData *fd;
-	NotifyType type;
-};
 
 
 typedef struct _NotifyData NotifyData;
@@ -2717,29 +2711,17 @@
 }
 
 
-gboolean file_data_send_notification_idle_cb(gpointer data)
+void file_data_send_notification(FileData *fd, NotifyType type)
 {
-	NotifyIdleData *nid = (NotifyIdleData *)data;
 	GList *work = notify_func_list;
 
 	while (work)
 		{
 		NotifyData *nd = (NotifyData *)work->data;
 
-		nd->func(nid->fd, nid->type, nd->data);
+		nd->func(fd, type, nd->data);
 		work = work->next;
 		}
-	file_data_unref(nid->fd);
-	g_free(nid);
-	return FALSE;
-}
-
-void file_data_send_notification(FileData *fd, NotifyType type)
-{
-	NotifyIdleData *nid = g_new0(NotifyIdleData, 1);
-	nid->fd = file_data_ref(fd);
-	nid->type = type;
-	g_idle_add_full(G_PRIORITY_HIGH, file_data_send_notification_idle_cb, nid, NULL);
 }
 
 static GHashTable *file_data_monitor_pool = NULL;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/glua.h	Tue Oct 02 22:27:22 2012 +0100
@@ -0,0 +1,35 @@
+/** \file
+ * \short LUA implementation
+ * \author Klaus Ethgen <Klaus@Ethgen.de>
+ */
+
+/*
+ *  This file is a part of Geeqie project (http://geeqie.sourceforge.net/).
+ *  Copyright (C) 2008 - 2010 The Geeqie Team
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either version 2 of the License, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ */
+
+#ifndef __GLUA_H
+#define __GLUA_H
+
+#ifdef HAVE_LUA
+
+#include <glib.h>
+#include "main.h"
+
+void lua_init(void);
+
+gchar *lua_callvalue(FileData *fd, const gchar *file, const gchar *function);
+
+#endif
+#endif
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
--- a/src/image-overlay.c	Sun Sep 23 11:19:36 2012 +0200
+++ b/src/image-overlay.c	Tue Oct 02 22:27:22 2012 +0100
@@ -25,6 +25,7 @@
 #include "pixbuf_util.h"
 #include "ui_fileops.h"
 #include "image-load.h"
+#include "glua.h"
 
 /*
  *----------------------------------------------------------------------------
@@ -318,6 +319,17 @@
 			{
 			data = metadata_read_string(imd->image_fd, COMMENT_KEY, METADATA_PLAIN);
 			}
+#ifdef HAVE_LUA
+		else if (strncmp(name, "lua/", 4) == 0)
+			{
+			gchar *tmp;
+			tmp = strchr(name+4, '/');
+			if (!tmp)
+				break;
+			*tmp = '\0';
+			data = lua_callvalue(imd->image_fd, name+4, tmp+1);
+			}
+#endif
 		else
 			{
 			data = g_strdup(g_hash_table_lookup(vars, name));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lua.c	Tue Oct 02 22:27:22 2012 +0100
@@ -0,0 +1,277 @@
+/** \file
+ * \short LUA implementation
+ * \author Klaus Ethgen <Klaus@Ethgen.de>
+ */
+
+/*
+ *  This file is a part of Geeqie project (http://geeqie.sourceforge.net/).
+ *  Copyright (C) 2008 - 2010 The Geeqie Team
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either version 2 of the License, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_LUA
+
+#define _XOPEN_SOURCE
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#include <stdio.h>
+#include <glib.h>
+#include <string.h>
+#include <time.h>
+
+#include "main.h"
+#include "glua.h"
+#include "ui_fileops.h"
+#include "exif.h"
+
+static lua_State *L; /** The LUA object needed for all operations (NOTE: That is
+		       * a upper-case variable to match the documentation!) */
+
+static FileData *lua_check_image(lua_State *L, int index)
+{
+	FileData **fd;
+	luaL_checktype(L, index, LUA_TUSERDATA);
+	fd = (FileData **)luaL_checkudata(L, index, "Image");
+	if (fd == NULL) luaL_typerror(L, index, "Image");
+	return *fd;
+}
+
+static int lua_image_get_exif(lua_State *L)
+{
+	FileData *fd;
+	ExifData *exif;
+	ExifData **exif_data;
+
+	fd = lua_check_image(L, 1);
+	exif = exif_read_fd(fd);
+
+	exif_data = (ExifData **)lua_newuserdata(L, sizeof(ExifData *));
+	luaL_getmetatable(L, "Exif");
+	lua_setmetatable(L, -2);
+
+	*exif_data = exif;
+
+	return 1;
+}
+
+static int lua_image_get_path(lua_State *L)
+{
+	FileData *fd;
+
+	fd = lua_check_image(L, 1);
+	lua_pushstring(L, fd->path);
+	return 1;
+}
+
+static int lua_image_get_name(lua_State *L)
+{
+	FileData *fd;
+
+	fd = lua_check_image(L, 1);
+	lua_pushstring(L, fd->name);
+	return 1;
+}
+
+static int lua_image_get_extension(lua_State *L)
+{
+	FileData *fd;
+
+	fd = lua_check_image(L, 1);
+	lua_pushstring(L, fd->extension);
+	return 1;
+}
+
+static int lua_image_get_date(lua_State *L)
+{
+	FileData *fd;
+
+	fd = lua_check_image(L, 1);
+	lua_pushnumber(L, fd->date);
+	return 1;
+}
+
+static int lua_image_get_size(lua_State *L)
+{
+	FileData *fd;
+
+	fd = lua_check_image(L, 1);
+	lua_pushnumber(L, fd->size);
+	return 1;
+}
+
+static ExifData *lua_check_exif(lua_State *L, int index)
+{
+	ExifData **exif;
+	luaL_checktype(L, index, LUA_TUSERDATA);
+	exif = (ExifData **)luaL_checkudata(L, index, "Exif");
+	if (exif == NULL) luaL_typerror(L, index, "Exif");
+	return *exif;
+}
+
+/* Interface for EXIF data */
+static int lua_exif_get_datum(lua_State *L)
+{
+	const gchar *key;
+	gchar *value = NULL;
+	ExifData *exif;
+	struct tm tm;
+	time_t datetime;
+
+	exif = lua_check_exif(L, 1);
+	key = luaL_checkstring(L, 2);
+	if (key == (gchar*)NULL || key[0] == '\0')
+		{
+		lua_pushnil(L);
+		return 1;
+		}
+	if (!exif)
+		{
+		lua_pushnil(L);
+		return 1;
+		}
+	value = exif_get_data_as_text(exif, key);
+	if (strcmp(key, "Exif.Photo.DateTimeOriginal") == 0)
+		{
+		memset(&tm, 0, sizeof(tm));
+		if (value && strptime(value, "%Y:%m:%d %H:%M:%S", &tm))
+			{
+			datetime = mktime(&tm);
+			lua_pushnumber(L, datetime);
+			return 1;
+			}
+		else
+			{
+			lua_pushnil(L);
+			return 1;
+			}
+		} // if (strcmp(key, "Exif.Photo.Da...
+	lua_pushstring(L, value);
+	return 1;
+}
+
+/**
+ * \brief Initialize the lua interpreter.
+ */
+void lua_init(void)
+{
+	L = luaL_newstate();
+	luaL_openlibs(L); /* Open all libraries for lua programms */
+
+	/* Now create custom methodes to do something */
+	static const luaL_Reg meta_methods[] = {
+			{NULL, NULL}
+	};
+
+	/* The Image metatable and methodes */
+	static const luaL_Reg image_methods[] = {
+			{"get_path", lua_image_get_path},
+			{"get_name", lua_image_get_name},
+			{"get_extension", lua_image_get_extension},
+			{"get_date", lua_image_get_date},
+			{"get_size", lua_image_get_size},
+			{"get_exif", lua_image_get_exif},
+			{NULL, NULL}
+	};
+	luaL_register(L, "Image", image_methods);
+	luaL_newmetatable(L, "Image");
+	luaL_register(L, NULL, meta_methods);
+	lua_pushliteral(L, "__index");
+	lua_pushvalue(L, -3);
+	lua_settable(L, -3);
+	lua_pushliteral(L, "__metatable");
+	lua_pushvalue(L, -3);
+	lua_settable(L, -3);
+	lua_pop(L, 1);
+	lua_pop(L, 1);
+
+	/* The Exif table and methodes */
+	static const luaL_Reg exif_methods[] = {
+			{"get_datum", lua_exif_get_datum},
+			{NULL, NULL}
+	};
+	luaL_register(L, "Exif", exif_methods);
+	luaL_newmetatable(L, "Exif");
+	luaL_register(L, NULL, meta_methods);
+	lua_pushliteral(L, "__index");
+	lua_pushvalue(L, -3);
+	lua_settable(L, -3);
+	lua_pushliteral(L, "__metatable");
+	lua_pushvalue(L, -3);
+	lua_settable(L, -3);
+	lua_pop(L, 1);
+	lua_pop(L, 1);
+}
+
+/**
+ * \brief Call a lua function to get a single value.
+ */
+gchar *lua_callvalue(FileData *fd, const gchar *file, const gchar *function)
+{
+	gint result;
+	gchar *data = NULL;
+	gchar *dir;
+	gchar *path;
+	FileData **image_data;
+	gchar *tmp;
+	GError *error = NULL;
+
+	/* Collection Table (Dummy at the moment) */
+	lua_newtable(L);
+	lua_setglobal(L, "Collection");
+
+	/* Current Image */
+	image_data = (FileData **)lua_newuserdata(L, sizeof(FileData *));
+	luaL_getmetatable(L, "Image");
+	lua_setmetatable(L, -2);
+	lua_setglobal(L, "Image");
+
+	*image_data = fd;
+	if (file[0] == '\0')
+		{
+		result = luaL_dostring(L, function);
+		}
+	else
+		{
+		dir = g_build_filename(get_rc_dir(), "lua", NULL);
+		path = g_build_filename(dir, file, NULL);
+		result = luaL_dofile(L, path);
+		g_free(path);
+		g_free(dir);
+		}
+
+	if (result)
+		{
+		data = g_strdup_printf("Error running lua script: %s", lua_tostring(L, -1));
+		return data;
+		}
+	data = g_strdup(lua_tostring(L, -1));
+	tmp = g_locale_to_utf8(data, strlen(data), NULL, NULL, &error);
+	if (error)
+		{
+		log_printf("Error converting lua output from locale to UTF-8: %s\n", error->message);
+		g_error_free(error);
+		}
+	else
+		{
+		g_free(data);
+		data = g_strdup(tmp);
+		} // if (error) { ... } else
+	return data;
+}
+
+#endif
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
--- a/src/main.c	Sun Sep 23 11:19:36 2012 +0200
+++ b/src/main.c	Tue Oct 02 22:27:22 2012 +0100
@@ -46,6 +46,7 @@
 #include "exif.h"
 #include "histogram.h"
 #include "pixbuf_util.h"
+#include "glua.h"
 
 #ifdef HAVE_CLUTTER
 #include <clutter-gtk/clutter-gtk.h>
@@ -756,6 +757,10 @@
 
 	exif_init();
 
+#ifdef HAVE_LUA
+	lua_init();
+#endif
+
 	/* setup random seed for random slideshow */
 	srand(time(NULL));