luaobject: remove prefix##_push_item()
[awesome.git] / luaa.c
blob520f15d658f37f598c841810ec5e2bc6fb4edea1
1 /*
2 * luaa.c - Lua configuration management
4 * Copyright © 2008-2009 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #define _GNU_SOURCE
24 #include <ev.h>
26 #include <lua.h>
27 #include <lauxlib.h>
28 #include <lualib.h>
30 #include <basedir_fs.h>
32 #include "awesome.h"
33 #include "timer.h"
34 #include "awesome-version-internal.h"
35 #include "ewmh.h"
36 #include "luaa.h"
37 #include "spawn.h"
38 #include "tag.h"
39 #include "client.h"
40 #include "screen.h"
41 #include "event.h"
42 #include "selection.h"
43 #include "window.h"
44 #include "common/xcursor.h"
45 #include "common/buffer.h"
47 #ifdef WITH_DBUS
48 extern const struct luaL_reg awesome_dbus_lib[];
49 #endif
50 extern const struct luaL_reg awesome_hooks_lib[];
51 extern const struct luaL_reg awesome_keygrabber_lib[];
52 extern const struct luaL_reg awesome_mousegrabber_lib[];
53 extern const struct luaL_reg awesome_root_lib[];
54 extern const struct luaL_reg awesome_image_methods[];
55 extern const struct luaL_reg awesome_image_meta[];
56 extern const struct luaL_reg awesome_mouse_methods[];
57 extern const struct luaL_reg awesome_mouse_meta[];
58 extern const struct luaL_reg awesome_screen_methods[];
59 extern const struct luaL_reg awesome_screen_meta[];
60 extern const struct luaL_reg awesome_client_methods[];
61 extern const struct luaL_reg awesome_client_meta[];
62 extern const struct luaL_reg awesome_tag_methods[];
63 extern const struct luaL_reg awesome_tag_meta[];
64 extern const struct luaL_reg awesome_widget_methods[];
65 extern const struct luaL_reg awesome_widget_meta[];
66 extern const struct luaL_reg awesome_wibox_methods[];
67 extern const struct luaL_reg awesome_wibox_meta[];
69 /** Quit awesome.
70 * \param L The Lua VM state.
71 * \return The number of elements pushed on stack.
73 static int
74 luaA_quit(lua_State *L __attribute__ ((unused)))
76 ev_unloop(globalconf.loop, 1);
77 return 0;
80 /** Execute another application, probably a window manager, to replace
81 * awesome.
82 * \param L The Lua VM state.
83 * \return The number of elements pushed on stack.
84 * \luastack
85 * \lparam The command line to execute.
87 static int
88 luaA_exec(lua_State *L)
90 const char *cmd = luaL_checkstring(L, 1);
92 awesome_atexit();
94 a_exec(cmd);
95 return 0;
98 /** Restart awesome.
100 static int
101 luaA_restart(lua_State *L __attribute__ ((unused)))
103 awesome_restart();
104 return 0;
107 /** UTF-8 aware string length computing.
108 * \param L The Lua VM state.
109 * \return The number of elements pushed on stack.
111 static int
112 luaA_mbstrlen(lua_State *L)
114 const char *cmd = luaL_checkstring(L, 1);
115 lua_pushnumber(L, (ssize_t) mbstowcs(NULL, NONULL(cmd), 0));
116 return 1;
119 /** Overload standard Lua next function to use __next key on metatable.
120 * \param L The Lua VM state.
121 * \return The number of elements pushed on stack.
123 static int
124 luaAe_next(lua_State *L)
126 if(luaL_getmetafield(L, 1, "__next"))
128 lua_insert(L, 1);
129 lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
130 return lua_gettop(L);
133 luaL_checktype(L, 1, LUA_TTABLE);
134 lua_settop(L, 2);
135 if(lua_next(L, 1))
136 return 2;
137 lua_pushnil(L);
138 return 1;
141 /** Overload lua_next() function by using __next metatable field
142 * to get next elements.
143 * \param L The Lua VM stack.
144 * \param idx The index number of elements in stack.
145 * \return 1 if more elements to come, 0 otherwise.
148 luaA_next(lua_State *L, int idx)
150 if(luaL_getmetafield(L, idx, "__next"))
152 /* if idx is relative, reduce it since we got __next */
153 if(idx < 0) idx--;
154 /* copy table and then move key */
155 lua_pushvalue(L, idx);
156 lua_pushvalue(L, -3);
157 lua_remove(L, -4);
158 lua_pcall(L, 2, 2, 0);
159 /* next returned nil, it's the end */
160 if(lua_isnil(L, -1))
162 /* remove nil */
163 lua_pop(L, 2);
164 return 0;
166 return 1;
168 else if(lua_istable(L, idx))
169 return lua_next(L, idx);
170 /* remove the key */
171 lua_pop(L, 1);
172 return 0;
175 /** Generic pairs function.
176 * \param L The Lua VM state.
177 * \return The number of elements pushed on stack.
179 static int
180 luaA_generic_pairs(lua_State *L)
182 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
183 lua_pushvalue(L, 1); /* state, */
184 lua_pushnil(L); /* and initial value */
185 return 3;
188 /** Overload standard pairs function to use __pairs field of metatables.
189 * \param L The Lua VM state.
190 * \return The number of elements pushed on stack.
192 static int
193 luaAe_pairs(lua_State *L)
195 if(luaL_getmetafield(L, 1, "__pairs"))
197 lua_insert(L, 1);
198 lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
199 return lua_gettop(L);
202 luaL_checktype(L, 1, LUA_TTABLE);
203 return luaA_generic_pairs(L);
206 static int
207 luaA_ipairs_aux(lua_State *L)
209 int i = luaL_checkint(L, 2) + 1;
210 luaL_checktype(L, 1, LUA_TTABLE);
211 lua_pushinteger(L, i);
212 lua_rawgeti(L, 1, i);
213 return (lua_isnil(L, -1)) ? 0 : 2;
216 /** Overload standard ipairs function to use __ipairs field of metatables.
217 * \param L The Lua VM state.
218 * \return The number of elements pushed on stack.
220 static int
221 luaAe_ipairs(lua_State *L)
223 if(luaL_getmetafield(L, 1, "__ipairs"))
225 lua_insert(L, 1);
226 lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
227 return lua_gettop(L);
230 luaL_checktype(L, 1, LUA_TTABLE);
231 lua_pushvalue(L, lua_upvalueindex(1));
232 lua_pushvalue(L, 1);
233 lua_pushinteger(L, 0); /* and initial value */
234 return 3;
237 /** Enhanced type() function which recognize awesome objects.
238 * \param L The Lua VM state.
239 * \return The number of arguments pushed on the stack.
241 static int
242 luaAe_type(lua_State *L)
244 luaL_checkany(L, 1);
245 lua_pushstring(L, luaA_typename(L, 1));
246 return 1;
249 /** Replace various standards Lua functions with our own.
250 * \param L The Lua VM state.
252 static void
253 luaA_fixups(lua_State *L)
255 /* export string.wlen */
256 lua_getglobal(L, "string");
257 lua_pushcfunction(L, luaA_mbstrlen);
258 lua_setfield(L, -2, "wlen");
259 lua_pop(L, 1);
260 /* replace next */
261 lua_pushliteral(L, "next");
262 lua_pushcfunction(L, luaAe_next);
263 lua_settable(L, LUA_GLOBALSINDEX);
264 /* replace pairs */
265 lua_pushliteral(L, "pairs");
266 lua_pushcfunction(L, luaAe_next);
267 lua_pushcclosure(L, luaAe_pairs, 1); /* pairs get next as upvalue */
268 lua_settable(L, LUA_GLOBALSINDEX);
269 /* replace ipairs */
270 lua_pushliteral(L, "ipairs");
271 lua_pushcfunction(L, luaA_ipairs_aux);
272 lua_pushcclosure(L, luaAe_ipairs, 1);
273 lua_settable(L, LUA_GLOBALSINDEX);
274 /* replace type */
275 lua_pushliteral(L, "type");
276 lua_pushcfunction(L, luaAe_type);
277 lua_settable(L, LUA_GLOBALSINDEX);
278 /* set selection */
279 lua_pushliteral(L, "selection");
280 lua_pushcfunction(L, luaA_selection_get);
281 lua_settable(L, LUA_GLOBALSINDEX);
284 /** __next function for wtable objects.
285 * \param L The Lua VM state.
286 * \return The number of elements pushed on stack.
288 static int
289 luaA_wtable_next(lua_State *L)
291 /* upvalue 1 is content table */
292 if(lua_next(L, lua_upvalueindex(1)))
293 return 2;
294 lua_pushnil(L);
295 return 1;
298 /** __ipairs function for wtable objects.
299 * \param L The Lua VM state.
300 * \return The number of elements pushed on stack.
302 static int
303 luaA_wtable_ipairs(lua_State *L)
305 /* push ipairs_aux */
306 lua_pushvalue(L, lua_upvalueindex(2));
307 /* push content table */
308 lua_pushvalue(L, lua_upvalueindex(1));
309 lua_pushinteger(L, 0); /* and initial value */
310 return 3;
313 /** Index function of wtable objects.
314 * \param L The Lua VM state.
315 * \return The number of elements pushed on stack.
317 static int
318 luaA_wtable_index(lua_State *L)
320 size_t len;
321 const char *buf;
323 lua_pushvalue(L, 2);
324 /* check for size, waiting lua 5.2 and __len on tables */
325 if((buf = lua_tolstring(L, -1, &len)))
326 if(a_tokenize(buf, len) == A_TK_LEN)
328 lua_pushnumber(L, lua_objlen(L, lua_upvalueindex(1)));
329 return 1;
331 lua_pop(L, 1);
333 /* upvalue 1 is content table */
334 lua_rawget(L, lua_upvalueindex(1));
335 return 1;
338 /** Newndex function of wtable objects.
339 * \param L The Lua VM state.
340 * \return The number of elements pushed on stack.
342 static int
343 luaA_wtable_newindex(lua_State *L)
345 bool invalid = false;
347 /* push key on top */
348 lua_pushvalue(L, 2);
349 /* get current key value in content table */
350 lua_rawget(L, lua_upvalueindex(1));
351 /* if value is a widget, notify change */
352 if(lua_istable(L, -1) || luaA_toudata(L, -1, "widget"))
353 invalid = true;
355 lua_pop(L, 1); /* remove value */
357 /* if new value is a widget or a table */
358 if(lua_istable(L, 3))
360 luaA_table2wtable(L);
361 invalid = true;
363 else if(!invalid && luaA_toudata(L, 3, "widget"))
364 invalid = true;
366 /* upvalue 1 is content table */
367 lua_rawset(L, lua_upvalueindex(1));
369 if(invalid)
370 luaA_wibox_invalidate_byitem(L, lua_topointer(L, 1));
372 return 0;
375 /** Convert the top element of the stack to a proxied wtable.
376 * \param L The Lua VM state.
378 void
379 luaA_table2wtable(lua_State *L)
381 if(!lua_istable(L, -1))
382 return;
384 lua_newtable(L); /* create *real* content table */
385 lua_createtable(L, 0, 5); /* metatable */
386 lua_pushvalue(L, -2); /* copy content table */
387 lua_pushcfunction(L, luaA_ipairs_aux); /* push ipairs aux */
388 lua_pushcclosure(L, luaA_wtable_ipairs, 2);
389 lua_pushvalue(L, -3); /* copy content table */
390 lua_pushcclosure(L, luaA_wtable_next, 1); /* __next has the content table as upvalue */
391 lua_pushvalue(L, -4); /* copy content table */
392 lua_pushcclosure(L, luaA_wtable_index, 1); /* __index has the content table as upvalue */
393 lua_pushvalue(L, -5); /* copy content table */
394 lua_pushcclosure(L, luaA_wtable_newindex, 1); /* __newindex has the content table as upvalue */
395 /* set metatable field with just pushed closure */
396 lua_setfield(L, -5, "__newindex");
397 lua_setfield(L, -4, "__index");
398 lua_setfield(L, -3, "__next");
399 lua_setfield(L, -2, "__ipairs");
400 /* set metatable impossible to touch */
401 lua_pushliteral(L, "wtable");
402 lua_setfield(L, -2, "__metatable");
403 /* set new metatable on original table */
404 lua_setmetatable(L, -3);
406 /* initial key */
407 lua_pushnil(L);
408 /* go through original table */
409 while(lua_next(L, -3))
411 /* if convert value to wtable */
412 luaA_table2wtable(L);
413 /* copy key */
414 lua_pushvalue(L, -2);
415 /* move key before value */
416 lua_insert(L, -2);
417 /* set same value in content table */
418 lua_rawset(L, -4);
419 /* copy key */
420 lua_pushvalue(L, -1);
421 /* push the new value :-> */
422 lua_pushnil(L);
423 /* set orig[k] = nil */
424 lua_rawset(L, -5);
426 /* remove content table */
427 lua_pop(L, 1);
430 /** Look for an item: table, function, etc.
431 * \param L The Lua VM state.
432 * \param item The pointer item.
434 bool
435 luaA_hasitem(lua_State *L, const void *item)
437 lua_pushnil(L);
438 while(luaA_next(L, -2))
440 if(lua_topointer(L, -1) == item)
442 /* remove value and key */
443 lua_pop(L, 2);
444 return true;
446 if(lua_istable(L, -1))
447 if(luaA_hasitem(L, item))
449 /* remove key and value */
450 lua_pop(L, 2);
451 return true;
453 /* remove value */
454 lua_pop(L, 1);
456 return false;
459 /** Browse a table pushed on top of the index, and put all its table and
460 * sub-table into an array.
461 * \param L The Lua VM state.
462 * \param elems The elements array.
463 * \return False if we encounter an elements already in list.
465 static bool
466 luaA_isloop_check(lua_State *L, cptr_array_t *elems)
468 if(lua_istable(L, -1))
470 const void *object = lua_topointer(L, -1);
472 /* Check that the object table is not already in the list */
473 for(int i = 0; i < elems->len; i++)
474 if(elems->tab[i] == object)
475 return false;
477 /* push the table in the elements list */
478 cptr_array_append(elems, object);
480 /* look every object in the "table" */
481 lua_pushnil(L);
482 while(luaA_next(L, -2))
484 if(!luaA_isloop_check(L, elems))
486 /* remove key and value */
487 lua_pop(L, 2);
488 return false;
490 /* remove value, keep key for next iteration */
491 lua_pop(L, 1);
494 return true;
497 /** Check if a table is a loop. When using tables as direct acyclic digram,
498 * this is useful.
499 * \param L The Lua VM state.
500 * \param idx The index of the table in the stack
501 * \return True if the table loops.
503 bool
504 luaA_isloop(lua_State *L, int idx)
506 /* elems is an elements array that we will fill with all array we
507 * encounter while browsing the tables */
508 cptr_array_t elems;
510 cptr_array_init(&elems);
512 /* push table on top */
513 lua_pushvalue(L, idx);
515 bool ret = luaA_isloop_check(L, &elems);
517 /* remove pushed table */
518 lua_pop(L, 1);
520 cptr_array_wipe(&elems);
522 return !ret;
525 /** awesome global table.
526 * \param L The Lua VM state.
527 * \return The number of elements pushed on stack.
528 * \luastack
529 * \lfield font The default font.
530 * \lfield font_height The default font height.
531 * \lfield conffile The configuration file which has been loaded.
533 static int
534 luaA_awesome_index(lua_State *L)
536 if(luaA_usemetatable(L, 1, 2))
537 return 1;
539 size_t len;
540 const char *buf = luaL_checklstring(L, 2, &len);
542 switch(a_tokenize(buf, len))
544 case A_TK_FONT:
546 char *font = pango_font_description_to_string(globalconf.font->desc);
547 lua_pushstring(L, font);
548 g_free(font);
550 break;
551 case A_TK_FONT_HEIGHT:
552 lua_pushnumber(L, globalconf.font->height);
553 break;
554 case A_TK_CONFFILE:
555 lua_pushstring(L, globalconf.conffile);
556 break;
557 case A_TK_FG:
558 luaA_pushxcolor(L, globalconf.colors.fg);
559 break;
560 case A_TK_BG:
561 luaA_pushxcolor(L, globalconf.colors.bg);
562 break;
563 case A_TK_VERSION:
564 lua_pushliteral(L, AWESOME_VERSION);
565 break;
566 case A_TK_RELEASE:
567 lua_pushliteral(L, AWESOME_RELEASE);
568 break;
569 default:
570 return 0;
573 return 1;
576 /** Newindex function for the awesome global table.
577 * \param L The Lua VM state.
578 * \return The number of elements pushed on stack.
580 static int
581 luaA_awesome_newindex(lua_State *L)
583 if(luaA_usemetatable(L, 1, 2))
584 return 1;
586 size_t len;
587 const char *buf = luaL_checklstring(L, 2, &len);
589 switch(a_tokenize(buf, len))
591 case A_TK_FONT:
593 const char *newfont = luaL_checkstring(L, 3);
594 draw_font_delete(&globalconf.font);
595 globalconf.font = draw_font_new(newfont);
596 /* refresh all wiboxes */
597 foreach(wibox, globalconf.wiboxes)
598 (*wibox)->need_update = true;
599 foreach(c, globalconf.clients)
600 if((*c)->titlebar)
601 (*c)->titlebar->need_update = true;
603 break;
604 case A_TK_FG:
605 if((buf = luaL_checklstring(L, 3, &len)))
606 xcolor_init_reply(xcolor_init_unchecked(&globalconf.colors.fg, buf, len));
607 break;
608 case A_TK_BG:
609 if((buf = luaL_checklstring(L, 3, &len)))
610 xcolor_init_reply(xcolor_init_unchecked(&globalconf.colors.bg, buf, len));
611 break;
612 default:
613 return 0;
616 return 0;
619 /** Add a global signal.
620 * \param L The Lua VM state.
621 * \return The number of elements pushed on stack.
622 * \luastack
623 * \lparam A string with the event name.
624 * \lparam The function to call.
626 static int
627 luaA_awesome_add_signal(lua_State *L)
629 const char *name = luaL_checkstring(L, 1);
630 luaA_checkfunction(L, 2);
631 signal_add(&global_signals, name, luaA_object_ref(L, 2));
632 return 0;
635 /** Remove a global signal.
636 * \param L The Lua VM state.
637 * \return The number of elements pushed on stack.
638 * \luastack
639 * \lparam A string with the event name.
640 * \lparam The function to call.
642 static int
643 luaA_awesome_remove_signal(lua_State *L)
645 const char *name = luaL_checkstring(L, 1);
646 luaA_checkfunction(L, 2);
647 const void *func = lua_topointer(L, 2);
648 signal_remove(&global_signals, name, func);
649 luaA_object_unref(L, (void *) func);
650 return 0;
653 /** Emit a global signal.
654 * \param L The Lua VM state.
655 * \return The number of elements pushed on stack.
656 * \luastack
657 * \lparam A string with the event name.
658 * \lparam The function to call.
660 static int
661 luaA_awesome_emit_signal(lua_State *L)
663 const char *name = luaL_checkstring(L, 1);
664 signal_t *sigfound = signal_array_getbyid(&global_signals,
665 a_strhash((const unsigned char *) name));
666 if(sigfound)
668 int nargs = lua_gettop(L) - 1;
669 foreach(ref, sigfound->sigfuncs)
671 for(int i = 0; i < nargs; i++)
672 lua_pushvalue(L, - nargs);
673 luaA_object_push(L, (void *) *ref);
674 luaA_dofunction(L, nargs, 0);
677 return 0;
680 /** Initialize the Lua VM
681 * \param xdg An xdg handle to use to get XDG basedir.
683 void
684 luaA_init(xdgHandle* xdg)
686 lua_State *L;
687 static const struct luaL_reg awesome_lib[] =
689 { "quit", luaA_quit },
690 { "exec", luaA_exec },
691 { "spawn", luaA_spawn },
692 { "restart", luaA_restart },
693 { "add_signal", luaA_awesome_add_signal },
694 { "remove_signal", luaA_awesome_remove_signal },
695 { "emit_signal", luaA_awesome_emit_signal },
696 { "__index", luaA_awesome_index },
697 { "__newindex", luaA_awesome_newindex },
698 { NULL, NULL }
701 L = globalconf.L = luaL_newstate();
703 luaL_openlibs(L);
705 luaA_fixups(L);
707 luaA_object_setup(L);
709 /* Export awesome lib */
710 luaA_openlib(L, "awesome", awesome_lib, awesome_lib);
712 /* Export root lib */
713 luaL_register(L, "root", awesome_root_lib);
714 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
716 /* Export hooks lib */
717 luaL_register(L, "hooks", awesome_hooks_lib);
718 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
720 #ifdef WITH_DBUS
721 /* Export D-Bus lib */
722 luaL_register(L, "dbus", awesome_dbus_lib);
723 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
724 #endif
726 /* Export keygrabber lib */
727 luaL_register(L, "keygrabber", awesome_keygrabber_lib);
728 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
730 /* Export mousegrabber lib */
731 luaL_register(L, "mousegrabber", awesome_mousegrabber_lib);
732 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
734 /* Export screen */
735 luaA_openlib(L, "screen", awesome_screen_methods, awesome_screen_meta);
737 /* Export mouse */
738 luaA_openlib(L, "mouse", awesome_mouse_methods, awesome_mouse_meta);
740 /* Export button */
741 button_class_setup(L);
743 /* Export image */
744 luaA_class_setup(L, &image_class, "image", (lua_class_allocator_t) image_new,
745 awesome_image_methods, awesome_image_meta);
747 /* Export tag */
748 luaA_class_setup(L, &tag_class, "tag", (lua_class_allocator_t) tag_new,
749 awesome_tag_methods, awesome_tag_meta);
751 /* Export wibox */
752 luaA_class_setup(L, &wibox_class, "wibox", (lua_class_allocator_t) wibox_new,
753 awesome_wibox_methods, awesome_wibox_meta);
755 /* Export widget */
756 luaA_class_setup(L, &widget_class, "widget", (lua_class_allocator_t) widget_new,
757 awesome_widget_methods, awesome_widget_meta);
759 /* Export client */
760 luaA_class_setup(L, &client_class, "client", (lua_class_allocator_t) client_new,
761 awesome_client_methods, awesome_client_meta);
763 /* Export keys */
764 key_class_setup(L);
766 /* Export timer */
767 timer_class_setup(L);
769 /* init hooks */
770 globalconf.hooks.manage = LUA_REFNIL;
771 globalconf.hooks.unmanage = LUA_REFNIL;
772 globalconf.hooks.focus = LUA_REFNIL;
773 globalconf.hooks.unfocus = LUA_REFNIL;
774 globalconf.hooks.mouse_enter = LUA_REFNIL;
775 globalconf.hooks.mouse_leave = LUA_REFNIL;
776 globalconf.hooks.clients = LUA_REFNIL;
777 globalconf.hooks.tags = LUA_REFNIL;
778 globalconf.hooks.tagged = LUA_REFNIL;
779 globalconf.hooks.property = LUA_REFNIL;
780 globalconf.hooks.timer = LUA_REFNIL;
781 globalconf.hooks.exit = LUA_REFNIL;
783 /* add Lua lib path (/usr/share/awesome/lib by default) */
784 lua_getglobal(L, "package");
785 if (LUA_TTABLE != lua_type(L, 1))
787 warn("package is not a table");
788 return;
790 lua_getfield(L, 1, "path");
791 if (LUA_TSTRING != lua_type(L, 2))
793 warn("package.path is not a string");
794 lua_pop(L, 1);
795 return;
797 lua_pushliteral(L, ";" AWESOME_LUA_LIB_PATH "/?.lua");
798 lua_pushliteral(L, ";" AWESOME_LUA_LIB_PATH "/?/init.lua");
799 lua_concat(L, 3); /* concatenate with package.path */
801 /* add XDG_CONFIG_DIR as include path */
802 const char * const *xdgconfigdirs = xdgSearchableConfigDirectories(xdg);
803 for(; *xdgconfigdirs; xdgconfigdirs++)
805 size_t len = a_strlen(*xdgconfigdirs);
806 lua_pushliteral(L, ";");
807 lua_pushlstring(L, *xdgconfigdirs, len);
808 lua_pushliteral(L, "/awesome/?.lua");
809 lua_concat(L, 3);
811 lua_pushliteral(L, ";");
812 lua_pushlstring(L, *xdgconfigdirs, len);
813 lua_pushliteral(L, "/awesome/?/init.lua");
814 lua_concat(L, 3);
816 lua_concat(L, 3); /* concatenate with package.path */
818 lua_setfield(L, 1, "path"); /* package.path = "concatenated string" */
821 static bool
822 luaA_loadrc(const char *confpath, bool run)
824 if(!luaL_loadfile(globalconf.L, confpath))
826 if(run)
828 if(lua_pcall(globalconf.L, 0, LUA_MULTRET, 0))
829 fprintf(stderr, "%s\n", lua_tostring(globalconf.L, -1));
830 else
832 globalconf.conffile = a_strdup(confpath);
833 return true;
836 else
837 lua_pop(globalconf.L, 1);
838 return true;
840 else
841 fprintf(stderr, "%s\n", lua_tostring(globalconf.L, -1));
843 return false;
846 /** Load a configuration file.
847 * \param xdg An xdg handle to use to get XDG basedir.
848 * \param confpatharg The configuration file to load.
849 * \param run Run the configuration file.
851 bool
852 luaA_parserc(xdgHandle* xdg, const char *confpatharg, bool run)
854 char *confpath = NULL;
855 bool ret = false;
857 /* try to load, return if it's ok */
858 if(confpatharg)
860 if(luaA_loadrc(confpatharg, run))
862 ret = true;
863 goto bailout;
865 else if(!run)
866 goto bailout;
869 confpath = xdgConfigFind("awesome/rc.lua", xdg);
871 char *tmp = confpath;
873 /* confpath is "string1\0string2\0string3\0\0" */
874 while(*tmp)
876 if(luaA_loadrc(tmp, run))
878 ret = true;
879 goto bailout;
881 else if(!run)
882 goto bailout;
883 tmp += a_strlen(tmp) + 1;
886 bailout:
888 p_delete(&confpath);
890 return ret;
893 void
894 luaA_on_timer(EV_P_ ev_timer *w, int revents)
896 if(globalconf.hooks.timer != LUA_REFNIL)
897 luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.timer, 0, 0);
900 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80