diff --git a/configure.ac.in b/configure.ac.in
index 2deabd9f..2398c103 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -324,6 +324,24 @@ if test x$want_rss = xyes; then
AC_DEFINE(RSS, 1, [Define if you want rss support])
fi
+dnl
+dnl Lua
+dnl
+
+AC_ARG_ENABLE([lua],
+ AC_HELP_STRING([--enable-lua], [enable if you want Lua scripting support @<:@default=no@:>@]),
+ [want_lua="$enableval"], [want_lua=no])
+#
+AM_CONDITIONAL(BUILD_LUA, test x$want_lua = xyes)
+if test x$want_lua = xyes; then
+ PKG_CHECK_MODULES(LUA, lua >= 5.1, [ ],[
+ PKG_CHECK_MODULES(LUA51, lua5.1 >= 5.1, [ ])
+ ])
+ CFLAGS="$CFLAGS $LUA_CFLAGS $LUA51_CFLAGS"
+ LIBS="$LIBS $LUA_LIBS $LUA51_LIBS"
+ AC_DEFINE(HAVE_LUA, 1, [Define if you want Lua scripting support])
+fi
+
dnl
dnl Wireless extensions
dnl
@@ -781,6 +799,7 @@ $PACKAGE $VERSION configured successfully:
hddtemp: $want_hddtemp
portmon: $want_portmon
RSS: $want_rss
+ Lua: $want_lua
wireless: $want_wlan
IBM: $want_ibm
nvidia: $want_nvidia
diff --git a/doc/config_settings.xml b/doc/config_settings.xml
index 7a2f80de..6818d83f 100644
--- a/doc/config_settings.xml
+++ b/doc/config_settings.xml
@@ -513,6 +513,13 @@
+
+
+
+ Loads the Lua scripts separated by spaces.
+
+
+
diff --git a/doc/variables.xml b/doc/variables.xml
index c2162935..6b49936b 100644
--- a/doc/variables.xml
+++ b/doc/variables.xml
@@ -2341,6 +2341,26 @@
+
+
+
+
+
+
+ Executes a Lua function with given parameters and prints the result value.
+
+
+
+
+
+
+
+
+
+ Executes a Lua function with given parameters and prints a bar. Expects result value to be an integer between 0 and 100.
+
+
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 61f202df..689ea800 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -107,6 +107,10 @@ if BUILD_RSS
rss = rss.c prss.c prss.h
endif
+if BUILD_LUA
+lua = llua.c llua.h
+endif
+
if BUILD_NVIDIA
nvidia = nvidia.c nvidia.h
endif
@@ -141,6 +145,7 @@ conky_SOURCES = \
$(port_monitors) \
$(eve) \
$(rss) \
+ $(lua) \
$(solaris) \
timed_thread.c \
timed_thread.h \
@@ -189,6 +194,7 @@ EXTRA_DIST = \
libtcp-portmon.c \
libtcp-portmon.h \
rss.h \
+ llua.h \
mail.h \
mixer.h \
moc.h \
diff --git a/src/conky.c b/src/conky.c
index e8cc412d..b81b7d88 100644
--- a/src/conky.c
+++ b/src/conky.c
@@ -196,6 +196,9 @@ static void print_version(void)
#ifdef RSS
" * RSS\n"
#endif /* RSS */
+#ifdef HAVE_LUA
+ " * Lua\n"
+#endif /* HAVE_LUA */
#ifdef HAVE_IWLIB
" * wireless\n"
#endif /* HAVE_IWLIB */
@@ -848,6 +851,14 @@ static void free_text_objects(struct text_object *root)
free(data.rss.uri);
free(data.rss.action);
break;
+#endif
+#ifdef HAVE_LUA
+ case OBJ_lua:
+ llua_close();
+ break;
+ case OBJ_lua_bar:
+ llua_close();
+ break;
#endif
case OBJ_pre_exec:
break;
@@ -2568,6 +2579,28 @@ static struct text_object *construct_text_object(const char *s,
"[act_par] [spaces in front]");
}
#endif
+#ifdef HAVE_LUA
+ END OBJ(lua, 0)
+ if(arg) {
+ obj->data.s = strndup(arg, text_buffer_size);
+ } else {
+ CRIT_ERR("lua needs arguments: [function parameters]");
+ }
+
+#ifdef X11
+ END OBJ(lua_bar, 0)
+ if(arg) {
+ arg = scan_bar(arg, &obj->a, &obj->b);
+ if(arg) {
+ obj->data.s = strndup(arg, text_buffer_size);
+ } else {
+ CRIT_ERR("lua_bar needs arguments: , [function parameters]");
+ }
+ } else {
+ CRIT_ERR("lua_bar needs arguments: , [function parameters]");
+ }
+#endif
+#endif
#ifdef HDDTEMP
END OBJ(hddtemp, 0)
if (scan_hddtemp(arg, &obj->data.hddtemp.dev,
@@ -4147,6 +4180,24 @@ static void generate_text_internal(char *p, int p_max_size,
}
}
#endif
+#ifdef HAVE_LUA
+ OBJ(lua) {
+ char *str = llua_getstring(obj->data.s);
+ if(str) {
+ snprintf(p, p_max_size, "%s", str);
+ free(str);
+ }
+ }
+
+#ifdef X11
+ OBJ(lua_bar) {
+ int per;
+ if(llua_getpercent(strdup(obj->data.s), &per)) {
+ new_bar(p, obj->a, obj->b, (per/100.0 * 255));
+ }
+ }
+#endif
+#endif
#ifdef HDDTEMP
OBJ(hddtemp) {
char *endptr, unit;
@@ -7653,6 +7704,20 @@ static void load_config_file(const char *f)
CONF_ERR;
}
}
+#ifdef HAVE_LUA
+ CONF("lua_load") {
+ llua_init();
+ if(value) {
+ char *ptr = strtok(value, " ");
+ while(ptr) {
+ llua_load(ptr);
+ ptr = strtok(NULL, " ");
+ }
+ } else {
+ CONF_ERR;
+ }
+ }
+#endif
CONF("color0"){}
CONF("color1"){}
diff --git a/src/conky.h b/src/conky.h
index b12952ec..a8206444 100644
--- a/src/conky.h
+++ b/src/conky.h
@@ -90,6 +90,10 @@ char *strndup(const char *s, size_t n);
#include "rss.h"
#endif
+#ifdef HAVE_LUA
+#include "llua.h"
+#endif
+
#ifdef TCP_PORT_MONITOR
#include "tcp-portmon.h"
#endif
diff --git a/src/llua.c b/src/llua.c
new file mode 100644
index 00000000..1d9070c2
--- /dev/null
+++ b/src/llua.c
@@ -0,0 +1,132 @@
+/* Conky, a system monitor, based on torsmo
+ *
+ * Any original torsmo code is licensed under the BSD license
+ *
+ * All code written since the fork of torsmo is licensed under the GPL
+ *
+ * Please see COPYING for details
+ *
+ * Copyright (c) 2007 Toni Spets
+ * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
+ * (see AUTHORS)
+ * All rights reserved.
+ *
+ * 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 3 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.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "conky.h"
+
+lua_State *lua_L = NULL;
+
+void llua_init()
+{
+ if(lua_L) return;
+ lua_L = lua_open();
+ luaL_openlibs(lua_L);
+}
+
+void llua_load(const char *script)
+{
+ int error;
+ error = luaL_loadfile(lua_L, script);
+ if(error) {
+ fprintf(stderr, "llua_load: %s\n", lua_tostring(lua_L, -1));
+ lua_pop(lua_L, 1);
+ } else {
+ lua_pcall(lua_L, 0, 0, 0);
+ }
+}
+
+char *llua_getstring(const char *args)
+{
+ char *ret = NULL;
+ char *tmp = strdup(args);
+ char func[64];
+ int parcount = 0;
+
+ if(!lua_L) return NULL;
+
+ char *ptr = strtok(tmp, " ");
+ if(!ptr) return NULL; /* function name missing */
+ snprintf(func, 64, "conky_%s", ptr);
+
+ lua_getglobal(lua_L, func);
+
+ ptr = strtok(NULL, " ");
+ while(ptr) {
+ lua_pushstring(lua_L, ptr);
+ ptr = strtok(NULL, " ");
+ parcount++;
+ }
+
+ if(lua_pcall(lua_L, parcount, 1, 0) != 0) {
+ fprintf(stderr, "llua: function %s execution failed: %s\n", func, lua_tostring(lua_L, -1));
+ lua_pop(lua_L, -1);
+ } else {
+ if(!lua_isstring(lua_L, -1)) {
+ fprintf(stderr, "llua: function %s didn't return a string, result discarded\n", func);
+ } else {
+ ret = strdup((char *)lua_tostring(lua_L, -1));
+ lua_pop(lua_L, 1);
+ }
+ }
+
+ free(tmp);
+
+ return ret;
+}
+
+int llua_getpercent(const char *args, int *per)
+{
+ char func[64];
+ char *tmp = strdup(args);
+ int parcount = 0;
+
+ if(!lua_L) return 0;
+
+ char *ptr = strtok(tmp, " ");
+ if(!ptr) return 0; /* function name missing */
+ snprintf(func, 64, "conky_%s", ptr);
+
+ lua_getglobal(lua_L, func);
+
+ ptr = strtok(NULL, " ");
+ while(ptr) {
+ lua_pushstring(lua_L, ptr);
+ ptr = strtok(NULL, " ");
+ parcount++;
+ }
+ free(tmp);
+
+ if(lua_pcall(lua_L, parcount, 1, 0) != 0) {
+ fprintf(stderr, "llua: function %s execution failed: %s\n", func, lua_tostring(lua_L, -1));
+ lua_pop(lua_L, -1);
+ } else {
+ if(!lua_isnumber(lua_L, -1)) {
+ fprintf(stderr, "llua: function %s didn't return a number (percent), result discarded\n", func);
+ } else {
+ *per = lua_tonumber(lua_L, -1);
+ lua_pop(lua_L, 1);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void llua_close()
+{
+ if(!lua_L) return;
+ lua_close(lua_L);
+ lua_L = NULL;
+}
diff --git a/src/llua.h b/src/llua.h
new file mode 100644
index 00000000..596f2b4d
--- /dev/null
+++ b/src/llua.h
@@ -0,0 +1,14 @@
+#ifndef LUA_H_
+#define LUA_H_
+
+#include
+#include
+#include
+
+void llua_init();
+void llua_load(const char *script);
+char *llua_getstring(const char *args);
+int llua_getpercent(const char *args, int *per);
+void llua_close();
+
+#endif /* LUA_H_*/
diff --git a/src/text_object.h b/src/text_object.h
index fe915a28..a4f13bcb 100644
--- a/src/text_object.h
+++ b/src/text_object.h
@@ -380,6 +380,10 @@ enum text_object_type {
#ifdef RSS
OBJ_rss,
#endif
+#ifdef HAVE_LUA
+ OBJ_lua,
+ OBJ_lua_bar,
+#endif
#ifdef TCP_PORT_MONITOR
OBJ_tcp_portmon,
#endif