-/* Conky, a system monitor, based on torsmo
+/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
+ * vim: ts=4 sw=4 noet ai cindent syntax=c
+ *
+ * Conky, a system monitor, based on torsmo
*
* Copyright (c) 2009 Toni Spets
- * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
+ * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
#include "logging.h"
#include "build.h"
+#ifdef LUA_EXTRAS
+#include <tolua++.h>
+#endif /* LUA_EXTRAS */
+
#ifdef HAVE_SYS_INOTIFY_H
#include <sys/inotify.h>
static int llua_block_notify = 0;
#endif /* HAVE_SYS_INOTIFY_H */
-static char *draw_pre = 0;
-static char *draw_post = 0;
+static char *draw_pre_hook = 0;
+static char *draw_post_hook = 0;
+static char *startup_hook = 0;
+static char *shutdown_hook = 0;
lua_State *lua_L = NULL;
lua_error(L);
}
str = strdup(lua_tostring(L, 1));
- evaluate(str, buf);
+ evaluate(str, buf, max_user_text);
lua_pushstring(L, buf);
free(str);
free(buf);
return 1; /* number of results */
}
+static int llua_conky_set_update_interval(lua_State *L)
+{
+ int n = lua_gettop(L); /* number of arguments */
+ double value;
+ if (n != 1) {
+ lua_pushstring(L, "incorrect arguments, conky_set_update_interval(number) takes exactly 1 argument");
+ lua_error(L);
+ }
+ if (!lua_isnumber(L, 1)) {
+ lua_pushstring(L, "incorrect argument (expecting a number)");
+ lua_error(L);
+ }
+ value = lua_tonumber(L, 1);
+ set_update_interval(value);
+ return 0; /* number of results */
+}
+
void llua_init(void)
{
const char *libs = PACKAGE_LIBDIR"/lib?.so;";
lua_pushstring(lua_L, VERSION);
lua_setglobal(lua_L, "conky_version");
+ lua_pushstring(lua_L, BUILD_DATE);
+ lua_setglobal(lua_L, "conky_build_date");
+
+ lua_pushstring(lua_L, BUILD_ARCH);
+ lua_setglobal(lua_L, "conky_build_arch");
+
lua_pushstring(lua_L, current_config);
lua_setglobal(lua_L, "conky_config");
lua_pushcfunction(lua_L, &llua_conky_parse);
lua_setglobal(lua_L, "conky_parse");
+
+ lua_pushcfunction(lua_L, &llua_conky_set_update_interval);
+ lua_setglobal(lua_L, "conky_set_update_interval");
+
+#if defined(X11) && defined(LUA_EXTRAS)
+ /* register tolua++ user types */
+ tolua_open(lua_L);
+ tolua_usertype(lua_L, "Drawable");
+ tolua_usertype(lua_L, "Visual");
+ tolua_usertype(lua_L, "Display");
+#endif /* X11 */
}
void llua_load(const char *script)
to_real_path(path, script);
error = luaL_dofile(lua_L, path);
if (error) {
- ERR("llua_load: %s", lua_tostring(lua_L, -1));
+ NORM_ERR("llua_load: %s", lua_tostring(lua_L, -1));
lua_pop(lua_L, 1);
#ifdef HAVE_SYS_INOTIFY_H
} else if (!llua_block_notify && inotify_fd != -1) {
}
/*
- llua_do_call does a flexible call to any Lua function
- string: <function> [par1] [par2...]
- retc: the number of return values expected
-*/
-char *llua_do_call(const char *string, int retc)
+ llua_do_call does a flexible call to any Lua function
+string: <function> [par1] [par2...]
+retc: the number of return values expected
+ */
+static char *llua_do_call(const char *string, int retc)
{
static char func[64];
int argc = 0;
}
/* call only conky_ prefixed functions */
- snprintf(func, 64, "conky_%s", ptr);
+ if(strncmp(ptr, LUAPREFIX, strlen(LUAPREFIX)) == 0) {
+ snprintf(func, 64, "%s", ptr);
+ }else{
+ snprintf(func, 64, "%s%s", LUAPREFIX, ptr);
+ }
/* push the function name to stack */
lua_getglobal(lua_L, func);
free(tmp);
if(lua_pcall(lua_L, argc, retc, 0) != 0) {
- ERR("llua_do_call: function %s execution failed: %s", func, lua_tostring(lua_L, -1));
+ NORM_ERR("llua_do_call: function %s execution failed: %s", func, lua_tostring(lua_L, -1));
lua_pop(lua_L, -1);
return NULL;
}
return func;
}
+#if 0
/*
* same as llua_do_call() except passes everything after func as one arg.
*/
-char *llua_do_read_call(const char *function, const char *arg, int retc)
+static char *llua_do_read_call(const char *function, const char *arg, int retc)
{
static char func[64];
snprintf(func, 64, "conky_%s", function);
-
+
/* push the function name to stack */
lua_getglobal(lua_L, func);
lua_pushstring(lua_L, arg);
if (lua_pcall(lua_L, 1, retc, 0) != 0) {
- ERR("llua_do_call: function %s execution failed: %s", func, lua_tostring(lua_L, -1));
+ NORM_ERR("llua_do_call: function %s execution failed: %s", func, lua_tostring(lua_L, -1));
lua_pop(lua_L, -1);
return NULL;
}
return func;
}
+#endif
-char *llua_getstring(const char *args)
+/* call a function with args, and return a string from it (must be free'd) */
+static char *llua_getstring(const char *args)
{
char *func;
char *ret = NULL;
func = llua_do_call(args, 1);
if (func) {
if (!lua_isstring(lua_L, -1)) {
- ERR("llua_getstring: function %s didn't return a string, result discarded", func);
+ NORM_ERR("llua_getstring: function %s didn't return a string, result discarded", func);
} else {
ret = strdup(lua_tostring(lua_L, -1));
lua_pop(lua_L, 1);
return ret;
}
-char *llua_getstring_read(const char *function, const char *arg)
+#if 0
+/* call a function with args, and return a string from it (must be free'd) */
+static char *llua_getstring_read(const char *function, const char *arg)
{
char *func;
char *ret = NULL;
func = llua_do_read_call(function, arg, 1);
if (func) {
if(!lua_isstring(lua_L, -1)) {
- ERR("llua_getstring_read: function %s didn't return a string, result discarded", func);
+ NORM_ERR("llua_getstring_read: function %s didn't return a string, result discarded", func);
} else {
ret = strdup(lua_tostring(lua_L, -1));
lua_pop(lua_L, 1);
return ret;
}
+#endif
-int llua_getnumber(const char *args, double *ret)
+/* call a function with args, and put the result in ret */
+static int llua_getnumber(const char *args, double *ret)
{
char *func;
func = llua_do_call(args, 1);
if(func) {
if(!lua_isnumber(lua_L, -1)) {
- ERR("llua_getnumber: function %s didn't return a number, result discarded", func);
+ NORM_ERR("llua_getnumber: function %s didn't return a number, result discarded", func);
} else {
*ret = lua_tonumber(lua_L, -1);
lua_pop(lua_L, 1);
#ifdef HAVE_SYS_INOTIFY_H
llua_rm_notifies();
#endif /* HAVE_SYS_INOTIFY_H */
- if (draw_pre) {
- free(draw_pre);
- draw_pre = 0;
+ if (draw_pre_hook) {
+ free(draw_pre_hook);
+ draw_pre_hook = 0;
+ }
+ if (draw_post_hook) {
+ free(draw_post_hook);
+ draw_post_hook = 0;
}
- if (draw_post) {
- free(draw_post);
- draw_post = 0;
+ if (startup_hook) {
+ free(startup_hook);
+ startup_hook = 0;
+ }
+ if (shutdown_hook) {
+ free(shutdown_hook);
+ shutdown_hook = 0;
}
if(!lua_L) return;
lua_close(lua_L);
llua_block_notify = 1;
llua_load(head->name);
llua_block_notify = 0;
- ERR("Lua script '%s' reloaded", head->name);
+ NORM_ERR("Lua script '%s' reloaded", head->name);
if (mask & IN_IGNORED) {
/* for some reason we get IN_IGNORED here
* sometimes, so we need to re-add the watch */
}
#endif /* HAVE_SYS_INOTIFY_H */
+void llua_set_number(const char *key, double value)
+{
+ lua_pushnumber(lua_L, value);
+ lua_setfield(lua_L, -2, key);
+}
+
+void llua_set_startup_hook(const char *args)
+{
+ if (startup_hook) free(startup_hook);
+ startup_hook = strdup(args);
+}
+
+void llua_set_shutdown_hook(const char *args)
+{
+ if (shutdown_hook) free(shutdown_hook);
+ shutdown_hook = strdup(args);
+}
+
+void llua_startup_hook(void)
+{
+ if (!lua_L || !startup_hook) return;
+ llua_do_call(startup_hook, 0);
+}
+
+void llua_shutdown_hook(void)
+{
+ if (!lua_L || !shutdown_hook) return;
+ llua_do_call(shutdown_hook, 0);
+}
+
#ifdef X11
void llua_draw_pre_hook(void)
{
- if (!lua_L || !draw_pre) return;
- llua_do_call(draw_pre, 0);
+ if (!lua_L || !draw_pre_hook) return;
+ llua_do_call(draw_pre_hook, 0);
}
void llua_draw_post_hook(void)
{
- if (!lua_L || !draw_post) return;
- llua_do_call(draw_post, 0);
+ if (!lua_L || !draw_post_hook) return;
+ llua_do_call(draw_post_hook, 0);
}
void llua_set_draw_pre_hook(const char *args)
{
- draw_pre = strdup(args);
+ draw_pre_hook = strdup(args);
}
void llua_set_draw_post_hook(const char *args)
{
- draw_post = strdup(args);
-}
-
-void llua_set_long(const char *key, long value)
-{
- lua_pushnumber(lua_L, value);
- lua_setfield(lua_L, -2, key);
+ draw_post_hook = strdup(args);
}
-/* this function mostly copied from tolua++ source so that we could play nice
- * with tolua++ libs. tolua++ is provided 'as is'
- */
+#ifdef LUA_EXTRAS
void llua_set_userdata(const char *key, const char *type, void *value)
{
- if (value == NULL) {
- lua_pushnil(lua_L);
- } else {
- luaL_getmetatable(lua_L, type);
- lua_pushstring(lua_L,"tolua_ubox");
- lua_rawget(lua_L,-2); /* stack: mt ubox */
- if (lua_isnil(lua_L, -1)) {
- lua_pop(lua_L, 1);
- lua_pushstring(lua_L, "tolua_ubox");
- lua_rawget(lua_L, LUA_REGISTRYINDEX);
- }
- lua_pushlightuserdata(lua_L,value);
- lua_rawget(lua_L,-2); /* stack: mt ubox ubox[u] */
- if (lua_isnil(lua_L,-1)) {
- lua_pop(lua_L,1); /* stack: mt ubox */
- lua_pushlightuserdata(lua_L,value);
- *(void**)lua_newuserdata(lua_L,sizeof(void *)) = value; /* stack: mt ubox u newud */
- lua_pushvalue(lua_L,-1); /* stack: mt ubox u newud newud */
- lua_insert(lua_L,-4); /* stack: mt newud ubox u newud */
- lua_rawset(lua_L,-3); /* stack: mt newud ubox */
- lua_pop(lua_L,1); /* stack: mt newud */
- /*luaL_getmetatable(lua_L,type);*/
- lua_pushvalue(lua_L, -2); /* stack: mt newud mt */
- lua_setmetatable(lua_L,-2); /* stack: mt newud */
-
- } else {
- /* check the need of updating the metatable to a more specialized class */
- lua_insert(lua_L,-2); /* stack: mt ubox[u] ubox */
- lua_pop(lua_L,1); /* stack: mt ubox[u] */
- lua_pushstring(lua_L,"tolua_super");
- lua_rawget(lua_L,LUA_REGISTRYINDEX); /* stack: mt ubox[u] super */
- lua_getmetatable(lua_L,-2); /* stack: mt ubox[u] super mt */
- lua_rawget(lua_L,-2); /* stack: mt ubox[u] super super[mt] */
- if (lua_istable(lua_L,-1)) {
- lua_pushstring(lua_L,type); /* stack: mt ubox[u] super super[mt] type */
- lua_rawget(lua_L,-2); /* stack: mt ubox[u] super super[mt] flag */
- if (lua_toboolean(lua_L,-1) == 1) {
- /* if true */
- lua_pop(lua_L,3); /* mt ubox[u]*/
- lua_remove(lua_L, -2);
- return;
- }
- }
- /* type represents a more specilized type */
- /*luaL_getmetatable(lua_L,type); // stack: mt ubox[u] super super[mt] flag mt */
- lua_pushvalue(lua_L, -5); /* stack: mt ubox[u] super super[mt] flag mt */
- lua_setmetatable(lua_L,-5); /* stack: mt ubox[u] super super[mt] flag */
- lua_pop(lua_L,3); /* stack: mt ubox[u] */
- }
- lua_remove(lua_L, -2); /* stack: ubox[u]*/
- }
+ tolua_pushusertype(lua_L, value, type);
lua_setfield(lua_L, -2, key);
}
+#endif /* LUA_EXTRAS */
void llua_setup_window_table(int text_start_x, int text_start_y, int text_width, int text_height)
{
if (!lua_L) return;
lua_newtable(lua_L);
-
- llua_set_userdata("drawable", "Drawable", (void*)&window.drawable);
- llua_set_userdata("visual", "Visual", window.visual);
- llua_set_userdata("display", "Display", display);
+ if (output_methods & TO_X) {
+#ifdef LUA_EXTRAS
+ llua_set_userdata("drawable", "Drawable", (void*)&window.drawable);
+ llua_set_userdata("visual", "Visual", window.visual);
+ llua_set_userdata("display", "Display", display);
+#endif /* LUA_EXTRAS */
- llua_set_long("width", window.width);
- llua_set_long("height", window.height);
- llua_set_long("border_inner_margin", window.border_inner_margin);
- llua_set_long("border_outer_margin", window.border_outer_margin);
- llua_set_long("border_width", window.border_width);
- llua_set_long("text_start_x", text_start_x);
- llua_set_long("text_start_y", text_start_y);
- llua_set_long("text_width", text_width);
- llua_set_long("text_height", text_height);
+ llua_set_number("width", window.width);
+ llua_set_number("height", window.height);
+ llua_set_number("border_inner_margin", window.border_inner_margin);
+ llua_set_number("border_outer_margin", window.border_outer_margin);
+ llua_set_number("border_width", window.border_width);
- lua_setglobal(lua_L, "conky_window");
+ llua_set_number("text_start_x", text_start_x);
+ llua_set_number("text_start_y", text_start_y);
+ llua_set_number("text_width", text_width);
+ llua_set_number("text_height", text_height);
+
+ lua_setglobal(lua_L, "conky_window");
+ }
}
void llua_update_window_table(int text_start_x, int text_start_y, int text_width, int text_height)
lua_getglobal(lua_L, "conky_window");
if (lua_isnil(lua_L, -1)) {
/* window table isn't populated yet */
+ lua_pop(lua_L, 1);
return;
}
- llua_set_long("width", window.width);
- llua_set_long("height", window.height);
+ llua_set_number("width", window.width);
+ llua_set_number("height", window.height);
- llua_set_long("text_start_x", text_start_x);
- llua_set_long("text_start_y", text_start_y);
- llua_set_long("text_width", text_width);
- llua_set_long("text_height", text_height);
+ llua_set_number("text_start_x", text_start_x);
+ llua_set_number("text_start_y", text_start_y);
+ llua_set_number("text_width", text_width);
+ llua_set_number("text_height", text_height);
lua_setglobal(lua_L, "conky_window");
}
#endif /* X11 */
+void llua_setup_info(struct information *i, double u_interval)
+{
+ if (!lua_L) return;
+ lua_newtable(lua_L);
+
+ llua_set_number("update_interval", u_interval);
+ llua_set_number("uptime", i->uptime);
+
+ lua_setglobal(lua_L, "conky_info");
+}
+
+void llua_update_info(struct information *i, double u_interval)
+{
+ if (!lua_L) return;
+
+ lua_getglobal(lua_L, "conky_info");
+ if (lua_isnil(lua_L, -1)) {
+ /* window table isn't populated yet */
+ lua_pop(lua_L, 1);
+ return;
+ }
+
+ llua_set_number("update_interval", u_interval);
+ llua_set_number("uptime", i->uptime);
+
+ lua_setglobal(lua_L, "conky_info");
+}
+
+void print_lua(struct text_object *obj, char *p, int p_max_size)
+{
+ char *str = llua_getstring(obj->data.s);
+ if (str) {
+ snprintf(p, p_max_size, "%s", str);
+ free(str);
+ }
+}
+
+void print_lua_parse(struct text_object *obj, char *p, int p_max_size)
+{
+ char *str = llua_getstring(obj->data.s);
+ if (str) {
+ evaluate(str, p, p_max_size);
+ free(str);
+ }
+}
+
+void print_lua_bar(struct text_object *obj, char *p, int p_max_size)
+{
+ double per;
+ if (llua_getnumber(obj->data.s, &per)) {
+ new_bar(obj, p, p_max_size, (per/100.0 * 255));
+ }
+}
+
+#ifdef X11
+void print_lua_graph(struct text_object *obj, char *p, int p_max_size)
+{
+ double per;
+
+ if (!p_max_size)
+ return;
+
+ if (llua_getnumber(obj->data.s, &per)) {
+ new_graph(obj, p, p_max_size, per);
+ }
+}
+#endif /* X11 */
+
+void print_lua_gauge(struct text_object *obj, char *p, int p_max_size)
+{
+ double per;
+
+ if (!p_max_size)
+ return;
+
+ if (llua_getnumber(obj->data.s, &per)) {
+ new_gauge(obj, p, p_max_size, (per/100.0 * 255));
+ }
+}