key: move grabbing code to window
[awesome.git] / luaa.c
blobf278cdaba10adbe38a423096342322fab6d435b4
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_mouse_methods[];
55 extern const struct luaL_reg awesome_mouse_meta[];
56 extern const struct luaL_reg awesome_screen_methods[];
57 extern const struct luaL_reg awesome_screen_meta[];
59 /** Quit awesome.
60 * \param L The Lua VM state.
61 * \return The number of elements pushed on stack.
63 static int
64 luaA_quit(lua_State *L __attribute__ ((unused)))
66 ev_unloop(globalconf.loop, 1);
67 return 0;
70 /** Execute another application, probably a window manager, to replace
71 * awesome.
72 * \param L The Lua VM state.
73 * \return The number of elements pushed on stack.
74 * \luastack
75 * \lparam The command line to execute.
77 static int
78 luaA_exec(lua_State *L)
80 const char *cmd = luaL_checkstring(L, 1);
82 awesome_atexit();
84 a_exec(cmd);
85 return 0;
88 /** Restart awesome.
90 static int
91 luaA_restart(lua_State *L __attribute__ ((unused)))
93 awesome_restart();
94 return 0;
97 /** UTF-8 aware string length computing.
98 * \param L The Lua VM state.
99 * \return The number of elements pushed on stack.
101 static int
102 luaA_mbstrlen(lua_State *L)
104 const char *cmd = luaL_checkstring(L, 1);
105 lua_pushnumber(L, (ssize_t) mbstowcs(NULL, NONULL(cmd), 0));
106 return 1;
109 /** Overload standard Lua next function to use __next key on metatable.
110 * \param L The Lua VM state.
111 * \return The number of elements pushed on stack.
113 static int
114 luaAe_next(lua_State *L)
116 if(luaL_getmetafield(L, 1, "__next"))
118 lua_insert(L, 1);
119 lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
120 return lua_gettop(L);
123 luaL_checktype(L, 1, LUA_TTABLE);
124 lua_settop(L, 2);
125 if(lua_next(L, 1))
126 return 2;
127 lua_pushnil(L);
128 return 1;
131 /** Overload lua_next() function by using __next metatable field
132 * to get next elements.
133 * \param L The Lua VM stack.
134 * \param idx The index number of elements in stack.
135 * \return 1 if more elements to come, 0 otherwise.
138 luaA_next(lua_State *L, int idx)
140 if(luaL_getmetafield(L, idx, "__next"))
142 /* if idx is relative, reduce it since we got __next */
143 if(idx < 0) idx--;
144 /* copy table and then move key */
145 lua_pushvalue(L, idx);
146 lua_pushvalue(L, -3);
147 lua_remove(L, -4);
148 lua_pcall(L, 2, 2, 0);
149 /* next returned nil, it's the end */
150 if(lua_isnil(L, -1))
152 /* remove nil */
153 lua_pop(L, 2);
154 return 0;
156 return 1;
158 else if(lua_istable(L, idx))
159 return lua_next(L, idx);
160 /* remove the key */
161 lua_pop(L, 1);
162 return 0;
165 /** Generic pairs function.
166 * \param L The Lua VM state.
167 * \return The number of elements pushed on stack.
169 static int
170 luaA_generic_pairs(lua_State *L)
172 lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
173 lua_pushvalue(L, 1); /* state, */
174 lua_pushnil(L); /* and initial value */
175 return 3;
178 /** Overload standard pairs function to use __pairs field of metatables.
179 * \param L The Lua VM state.
180 * \return The number of elements pushed on stack.
182 static int
183 luaAe_pairs(lua_State *L)
185 if(luaL_getmetafield(L, 1, "__pairs"))
187 lua_insert(L, 1);
188 lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
189 return lua_gettop(L);
192 luaL_checktype(L, 1, LUA_TTABLE);
193 return luaA_generic_pairs(L);
196 static int
197 luaA_ipairs_aux(lua_State *L)
199 int i = luaL_checkint(L, 2) + 1;
200 luaL_checktype(L, 1, LUA_TTABLE);
201 lua_pushinteger(L, i);
202 lua_rawgeti(L, 1, i);
203 return (lua_isnil(L, -1)) ? 0 : 2;
206 /** Overload standard ipairs function to use __ipairs field of metatables.
207 * \param L The Lua VM state.
208 * \return The number of elements pushed on stack.
210 static int
211 luaAe_ipairs(lua_State *L)
213 if(luaL_getmetafield(L, 1, "__ipairs"))
215 lua_insert(L, 1);
216 lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
217 return lua_gettop(L);
220 luaL_checktype(L, 1, LUA_TTABLE);
221 lua_pushvalue(L, lua_upvalueindex(1));
222 lua_pushvalue(L, 1);
223 lua_pushinteger(L, 0); /* and initial value */
224 return 3;
227 /** Enhanced type() function which recognize awesome objects.
228 * \param L The Lua VM state.
229 * \return The number of arguments pushed on the stack.
231 static int
232 luaAe_type(lua_State *L)
234 luaL_checkany(L, 1);
235 lua_pushstring(L, luaA_typename(L, 1));
236 return 1;
239 /** Modified version of os.execute() which use spawn code to reset signal
240 * handlers correctly before exec()'ing the new program.
241 * \param L The Lua VM state.
242 * \return The number of arguments pushed on stack.
244 static int
245 luaAe_os_execute(lua_State *L)
247 lua_pushinteger(L, spawn_system(luaL_optstring(L, 1, NULL)));
248 return 1;
251 /** Replace various standards Lua functions with our own.
252 * \param L The Lua VM state.
254 static void
255 luaA_fixups(lua_State *L)
257 /* export string.wlen */
258 lua_getglobal(L, "string");
259 lua_pushcfunction(L, luaA_mbstrlen);
260 lua_setfield(L, -2, "wlen");
261 lua_pop(L, 1);
262 /* replace os.execute */
263 lua_getglobal(L, "os");
264 lua_pushcfunction(L, luaAe_os_execute);
265 lua_setfield(L, -2, "execute");
266 lua_pop(L, 1);
267 /* replace next */
268 lua_pushliteral(L, "next");
269 lua_pushcfunction(L, luaAe_next);
270 lua_settable(L, LUA_GLOBALSINDEX);
271 /* replace pairs */
272 lua_pushliteral(L, "pairs");
273 lua_pushcfunction(L, luaAe_next);
274 lua_pushcclosure(L, luaAe_pairs, 1); /* pairs get next as upvalue */
275 lua_settable(L, LUA_GLOBALSINDEX);
276 /* replace ipairs */
277 lua_pushliteral(L, "ipairs");
278 lua_pushcfunction(L, luaA_ipairs_aux);
279 lua_pushcclosure(L, luaAe_ipairs, 1);
280 lua_settable(L, LUA_GLOBALSINDEX);
281 /* replace type */
282 lua_pushliteral(L, "type");
283 lua_pushcfunction(L, luaAe_type);
284 lua_settable(L, LUA_GLOBALSINDEX);
285 /* set selection */
286 lua_pushliteral(L, "selection");
287 lua_pushcfunction(L, luaA_selection_get);
288 lua_settable(L, LUA_GLOBALSINDEX);
291 /** __next function for wtable objects.
292 * \param L The Lua VM state.
293 * \return The number of elements pushed on stack.
295 static int
296 luaA_wtable_next(lua_State *L)
298 /* upvalue 1 is content table */
299 if(lua_next(L, lua_upvalueindex(1)))
300 return 2;
301 lua_pushnil(L);
302 return 1;
305 /** __ipairs function for wtable objects.
306 * \param L The Lua VM state.
307 * \return The number of elements pushed on stack.
309 static int
310 luaA_wtable_ipairs(lua_State *L)
312 /* push ipairs_aux */
313 lua_pushvalue(L, lua_upvalueindex(2));
314 /* push content table */
315 lua_pushvalue(L, lua_upvalueindex(1));
316 lua_pushinteger(L, 0); /* and initial value */
317 return 3;
320 /** Index function of wtable objects.
321 * \param L The Lua VM state.
322 * \return The number of elements pushed on stack.
324 static int
325 luaA_wtable_index(lua_State *L)
327 size_t len;
328 const char *buf;
330 lua_pushvalue(L, 2);
331 /* check for size, waiting lua 5.2 and __len on tables */
332 if((buf = lua_tolstring(L, -1, &len)))
333 if(a_tokenize(buf, len) == A_TK_LEN)
335 lua_pushnumber(L, lua_objlen(L, lua_upvalueindex(1)));
336 return 1;
338 lua_pop(L, 1);
340 /* upvalue 1 is content table */
341 lua_rawget(L, lua_upvalueindex(1));
342 return 1;
345 /** Newindex function of wtable objects.
346 * \param L The Lua VM state.
347 * \return The number of elements pushed on stack.
349 static int
350 luaA_wtable_newindex(lua_State *L)
352 bool invalid = false;
354 /* push key on top */
355 lua_pushvalue(L, 2);
356 /* get current key value in content table */
357 lua_rawget(L, lua_upvalueindex(1));
358 /* if value is a widget, notify change */
359 if(lua_istable(L, -1) || luaA_toudata(L, -1, &widget_class))
360 invalid = true;
362 lua_pop(L, 1); /* remove value */
364 /* if new value is a widget or a table */
365 if(lua_istable(L, 3))
367 luaA_table2wtable(L);
368 invalid = true;
370 else if(!invalid && luaA_toudata(L, 3, &widget_class))
371 invalid = true;
373 /* upvalue 1 is content table */
374 lua_rawset(L, lua_upvalueindex(1));
376 if(invalid)
377 luaA_wibox_invalidate_byitem(L, lua_topointer(L, 1));
379 return 0;
382 /** Convert the top element of the stack to a proxied wtable.
383 * \param L The Lua VM state.
385 void
386 luaA_table2wtable(lua_State *L)
388 if(!lua_istable(L, -1))
389 return;
391 lua_newtable(L); /* create *real* content table */
392 lua_createtable(L, 0, 5); /* metatable */
393 lua_pushvalue(L, -2); /* copy content table */
394 lua_pushcfunction(L, luaA_ipairs_aux); /* push ipairs aux */
395 lua_pushcclosure(L, luaA_wtable_ipairs, 2);
396 lua_pushvalue(L, -3); /* copy content table */
397 lua_pushcclosure(L, luaA_wtable_next, 1); /* __next has the content table as upvalue */
398 lua_pushvalue(L, -4); /* copy content table */
399 lua_pushcclosure(L, luaA_wtable_index, 1); /* __index has the content table as upvalue */
400 lua_pushvalue(L, -5); /* copy content table */
401 lua_pushcclosure(L, luaA_wtable_newindex, 1); /* __newindex has the content table as upvalue */
402 /* set metatable field with just pushed closure */
403 lua_setfield(L, -5, "__newindex");
404 lua_setfield(L, -4, "__index");
405 lua_setfield(L, -3, "__next");
406 lua_setfield(L, -2, "__ipairs");
407 /* set metatable impossible to touch */
408 lua_pushliteral(L, "wtable");
409 lua_setfield(L, -2, "__metatable");
410 /* set new metatable on original table */
411 lua_setmetatable(L, -3);
413 /* initial key */
414 lua_pushnil(L);
415 /* go through original table */
416 while(lua_next(L, -3))
418 /* if convert value to wtable */
419 luaA_table2wtable(L);
420 /* copy key */
421 lua_pushvalue(L, -2);
422 /* move key before value */
423 lua_insert(L, -2);
424 /* set same value in content table */
425 lua_rawset(L, -4);
426 /* copy key */
427 lua_pushvalue(L, -1);
428 /* push the new value :-> */
429 lua_pushnil(L);
430 /* set orig[k] = nil */
431 lua_rawset(L, -5);
433 /* remove content table */
434 lua_pop(L, 1);
437 /** Look for an item: table, function, etc.
438 * \param L The Lua VM state.
439 * \param item The pointer item.
441 bool
442 luaA_hasitem(lua_State *L, const void *item)
444 lua_pushnil(L);
445 while(luaA_next(L, -2))
447 if(lua_topointer(L, -1) == item)
449 /* remove value and key */
450 lua_pop(L, 2);
451 return true;
453 if(lua_istable(L, -1))
454 if(luaA_hasitem(L, item))
456 /* remove key and value */
457 lua_pop(L, 2);
458 return true;
460 /* remove value */
461 lua_pop(L, 1);
463 return false;
466 /** Browse a table pushed on top of the index, and put all its table and
467 * sub-table into an array.
468 * \param L The Lua VM state.
469 * \param elems The elements array.
470 * \return False if we encounter an elements already in list.
472 static bool
473 luaA_isloop_check(lua_State *L, cptr_array_t *elems)
475 if(lua_istable(L, -1))
477 const void *object = lua_topointer(L, -1);
479 /* Check that the object table is not already in the list */
480 for(int i = 0; i < elems->len; i++)
481 if(elems->tab[i] == object)
482 return false;
484 /* push the table in the elements list */
485 cptr_array_append(elems, object);
487 /* look every object in the "table" */
488 lua_pushnil(L);
489 while(luaA_next(L, -2))
491 if(!luaA_isloop_check(L, elems))
493 /* remove key and value */
494 lua_pop(L, 2);
495 return false;
497 /* remove value, keep key for next iteration */
498 lua_pop(L, 1);
501 return true;
504 /** Check if a table is a loop. When using tables as direct acyclic digram,
505 * this is useful.
506 * \param L The Lua VM state.
507 * \param idx The index of the table in the stack
508 * \return True if the table loops.
510 bool
511 luaA_isloop(lua_State *L, int idx)
513 /* elems is an elements array that we will fill with all array we
514 * encounter while browsing the tables */
515 cptr_array_t elems;
517 cptr_array_init(&elems);
519 /* push table on top */
520 lua_pushvalue(L, idx);
522 bool ret = luaA_isloop_check(L, &elems);
524 /* remove pushed table */
525 lua_pop(L, 1);
527 cptr_array_wipe(&elems);
529 return !ret;
532 /** awesome global table.
533 * \param L The Lua VM state.
534 * \return The number of elements pushed on stack.
535 * \luastack
536 * \lfield font The default font.
537 * \lfield font_height The default font height.
538 * \lfield conffile The configuration file which has been loaded.
540 static int
541 luaA_awesome_index(lua_State *L)
543 if(luaA_usemetatable(L, 1, 2))
544 return 1;
546 size_t len;
547 const char *buf = luaL_checklstring(L, 2, &len);
549 switch(a_tokenize(buf, len))
551 case A_TK_FONT:
553 char *font = pango_font_description_to_string(globalconf.font->desc);
554 lua_pushstring(L, font);
555 g_free(font);
557 break;
558 case A_TK_FONT_HEIGHT:
559 lua_pushnumber(L, globalconf.font->height);
560 break;
561 case A_TK_CONFFILE:
562 lua_pushstring(L, globalconf.conffile);
563 break;
564 case A_TK_FG:
565 luaA_pushxcolor(L, globalconf.colors.fg);
566 break;
567 case A_TK_BG:
568 luaA_pushxcolor(L, globalconf.colors.bg);
569 break;
570 case A_TK_VERSION:
571 lua_pushliteral(L, AWESOME_VERSION);
572 break;
573 case A_TK_RELEASE:
574 lua_pushliteral(L, AWESOME_RELEASE);
575 break;
576 default:
577 return 0;
580 return 1;
583 /** Newindex function for the awesome global table.
584 * \param L The Lua VM state.
585 * \return The number of elements pushed on stack.
587 static int
588 luaA_awesome_newindex(lua_State *L)
590 if(luaA_usemetatable(L, 1, 2))
591 return 1;
593 size_t len;
594 const char *buf = luaL_checklstring(L, 2, &len);
596 switch(a_tokenize(buf, len))
598 case A_TK_FONT:
600 const char *newfont = luaL_checkstring(L, 3);
601 draw_font_delete(&globalconf.font);
602 globalconf.font = draw_font_new(newfont);
603 /* refresh all wiboxes */
604 foreach(wibox, globalconf.wiboxes)
605 (*wibox)->need_update = true;
606 foreach(c, globalconf.clients)
607 if((*c)->titlebar)
608 (*c)->titlebar->need_update = true;
610 break;
611 case A_TK_FG:
612 if((buf = luaL_checklstring(L, 3, &len)))
613 xcolor_init_reply(xcolor_init_unchecked(&globalconf.colors.fg, buf, len));
614 break;
615 case A_TK_BG:
616 if((buf = luaL_checklstring(L, 3, &len)))
617 xcolor_init_reply(xcolor_init_unchecked(&globalconf.colors.bg, buf, len));
618 break;
619 default:
620 return 0;
623 return 0;
626 /** Add a global signal.
627 * \param L The Lua VM state.
628 * \return The number of elements pushed on stack.
629 * \luastack
630 * \lparam A string with the event name.
631 * \lparam The function to call.
633 static int
634 luaA_awesome_add_signal(lua_State *L)
636 const char *name = luaL_checkstring(L, 1);
637 luaA_checkfunction(L, 2);
638 signal_add(&global_signals, name, luaA_object_ref(L, 2));
639 return 0;
642 /** Remove a global signal.
643 * \param L The Lua VM state.
644 * \return The number of elements pushed on stack.
645 * \luastack
646 * \lparam A string with the event name.
647 * \lparam The function to call.
649 static int
650 luaA_awesome_remove_signal(lua_State *L)
652 const char *name = luaL_checkstring(L, 1);
653 luaA_checkfunction(L, 2);
654 const void *func = lua_topointer(L, 2);
655 signal_remove(&global_signals, name, func);
656 luaA_object_unref(L, (void *) func);
657 return 0;
660 /** Emit a global signal.
661 * \param L The Lua VM state.
662 * \return The number of elements pushed on stack.
663 * \luastack
664 * \lparam A string with the event name.
665 * \lparam The function to call.
667 static int
668 luaA_awesome_emit_signal(lua_State *L)
670 signal_object_emit(L, &global_signals, luaL_checkstring(L, 1), lua_gettop(L) - 1);
671 return 0;
674 static int
675 luaA_panic(lua_State *L)
677 warn("unprotected error in call to Lua API (%s), restarting awesome",
678 lua_tostring(L, -1));
679 awesome_restart();
680 return 0;
683 static int
684 luaA_dofunction_on_error(lua_State *L)
686 /* duplicate string error */
687 lua_pushvalue(L, -1);
688 /* emit error signal */
689 signal_object_emit(L, &global_signals, "debug::error", 1);
691 if(!luaL_dostring(L, "return debug.traceback(\"error while running function\", 3)"))
693 /* Move traceback before error */
694 lua_insert(L, -2);
695 /* Insert sentence */
696 lua_pushliteral(L, "\nerror: ");
697 /* Move it before error */
698 lua_insert(L, -2);
699 lua_concat(L, 3);
701 return 1;
704 /** Initialize the Lua VM
705 * \param xdg An xdg handle to use to get XDG basedir.
707 void
708 luaA_init(xdgHandle* xdg)
710 lua_State *L;
711 static const struct luaL_reg awesome_lib[] =
713 { "quit", luaA_quit },
714 { "exec", luaA_exec },
715 { "spawn", luaA_spawn },
716 { "restart", luaA_restart },
717 { "add_signal", luaA_awesome_add_signal },
718 { "remove_signal", luaA_awesome_remove_signal },
719 { "emit_signal", luaA_awesome_emit_signal },
720 { "__index", luaA_awesome_index },
721 { "__newindex", luaA_awesome_newindex },
722 { NULL, NULL }
725 L = globalconf.L = luaL_newstate();
727 /* Set panic function */
728 lua_atpanic(L, luaA_panic);
730 /* Set error handling function */
731 lualib_dofunction_on_error = luaA_dofunction_on_error;
733 luaL_openlibs(L);
735 luaA_fixups(L);
737 luaA_object_setup(L);
739 /* Export awesome lib */
740 luaA_openlib(L, "awesome", awesome_lib, awesome_lib);
742 /* Export root lib */
743 luaL_register(L, "root", awesome_root_lib);
744 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
746 /* Export hooks lib */
747 luaL_register(L, "hooks", awesome_hooks_lib);
748 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
750 #ifdef WITH_DBUS
751 /* Export D-Bus lib */
752 luaL_register(L, "dbus", awesome_dbus_lib);
753 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
754 #endif
756 /* Export keygrabber lib */
757 luaL_register(L, "keygrabber", awesome_keygrabber_lib);
758 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
760 /* Export mousegrabber lib */
761 luaL_register(L, "mousegrabber", awesome_mousegrabber_lib);
762 lua_pop(L, 1); /* luaL_register() leaves the table on stack */
764 /* Export screen */
765 luaA_openlib(L, "screen", awesome_screen_methods, awesome_screen_meta);
767 /* Export mouse */
768 luaA_openlib(L, "mouse", awesome_mouse_methods, awesome_mouse_meta);
770 /* Export button */
771 button_class_setup(L);
773 /* Export image */
774 image_class_setup(L);
776 /* Export tag */
777 tag_class_setup(L);
779 /* Export wibox */
780 wibox_class_setup(L);
782 /* Export widget */
783 widget_class_setup(L);
785 /* Export client */
786 client_class_setup(L);
788 /* Export keys */
789 key_class_setup(L);
791 /* Export timer */
792 timer_class_setup(L);
794 /* init hooks */
795 globalconf.hooks.manage = LUA_REFNIL;
796 globalconf.hooks.unmanage = LUA_REFNIL;
797 globalconf.hooks.focus = LUA_REFNIL;
798 globalconf.hooks.unfocus = LUA_REFNIL;
799 globalconf.hooks.mouse_enter = LUA_REFNIL;
800 globalconf.hooks.mouse_leave = LUA_REFNIL;
801 globalconf.hooks.clients = LUA_REFNIL;
802 globalconf.hooks.tags = LUA_REFNIL;
803 globalconf.hooks.tagged = LUA_REFNIL;
804 globalconf.hooks.property = LUA_REFNIL;
805 globalconf.hooks.timer = LUA_REFNIL;
806 globalconf.hooks.exit = LUA_REFNIL;
808 /* add Lua lib path (/usr/share/awesome/lib by default) */
809 lua_getglobal(L, "package");
810 if (LUA_TTABLE != lua_type(L, 1))
812 warn("package is not a table");
813 return;
815 lua_getfield(L, 1, "path");
816 if (LUA_TSTRING != lua_type(L, 2))
818 warn("package.path is not a string");
819 lua_pop(L, 1);
820 return;
822 lua_pushliteral(L, ";" AWESOME_LUA_LIB_PATH "/?.lua");
823 lua_pushliteral(L, ";" AWESOME_LUA_LIB_PATH "/?/init.lua");
824 lua_concat(L, 3); /* concatenate with package.path */
826 /* add XDG_CONFIG_DIR as include path */
827 const char * const *xdgconfigdirs = xdgSearchableConfigDirectories(xdg);
828 for(; *xdgconfigdirs; xdgconfigdirs++)
830 size_t len = a_strlen(*xdgconfigdirs);
831 lua_pushliteral(L, ";");
832 lua_pushlstring(L, *xdgconfigdirs, len);
833 lua_pushliteral(L, "/awesome/?.lua");
834 lua_concat(L, 3);
836 lua_pushliteral(L, ";");
837 lua_pushlstring(L, *xdgconfigdirs, len);
838 lua_pushliteral(L, "/awesome/?/init.lua");
839 lua_concat(L, 3);
841 lua_concat(L, 3); /* concatenate with package.path */
843 lua_setfield(L, 1, "path"); /* package.path = "concatenated string" */
846 static bool
847 luaA_loadrc(const char *confpath, bool run)
849 if(!luaL_loadfile(globalconf.L, confpath))
851 if(run)
853 if(lua_pcall(globalconf.L, 0, LUA_MULTRET, 0))
854 fprintf(stderr, "%s\n", lua_tostring(globalconf.L, -1));
855 else
857 globalconf.conffile = a_strdup(confpath);
858 return true;
861 else
862 lua_pop(globalconf.L, 1);
863 return true;
865 else
866 fprintf(stderr, "%s\n", lua_tostring(globalconf.L, -1));
868 return false;
871 /** Load a configuration file.
872 * \param xdg An xdg handle to use to get XDG basedir.
873 * \param confpatharg The configuration file to load.
874 * \param run Run the configuration file.
876 bool
877 luaA_parserc(xdgHandle* xdg, const char *confpatharg, bool run)
879 char *confpath = NULL;
880 bool ret = false;
882 /* try to load, return if it's ok */
883 if(confpatharg)
885 if(luaA_loadrc(confpatharg, run))
887 ret = true;
888 goto bailout;
890 else if(!run)
891 goto bailout;
894 confpath = xdgConfigFind("awesome/rc.lua", xdg);
896 char *tmp = confpath;
898 /* confpath is "string1\0string2\0string3\0\0" */
899 while(*tmp)
901 if(luaA_loadrc(tmp, run))
903 ret = true;
904 goto bailout;
906 else if(!run)
907 goto bailout;
908 tmp += a_strlen(tmp) + 1;
911 bailout:
913 p_delete(&confpath);
915 return ret;
918 void
919 luaA_on_timer(EV_P_ ev_timer *w, int revents)
921 if(globalconf.hooks.timer != LUA_REFNIL)
922 luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.timer, 0, 0);
926 luaA_class_index_miss_property(lua_State *L, lua_object_t *obj)
928 signal_object_emit(L, &global_signals, "debug::index::miss", 2);
929 return 0;
933 luaA_class_newindex_miss_property(lua_State *L, lua_object_t *obj)
935 signal_object_emit(L, &global_signals, "debug::newindex::miss", 3);
936 return 0;
939 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80