diff options
-rw-r--r-- | src/FbCommands.cc | 68 | ||||
-rw-r--r-- | src/FbCommands.hh | 22 |
2 files changed, 90 insertions, 0 deletions
diff --git a/src/FbCommands.cc b/src/FbCommands.cc index 2eb179f..3ece374 100644 --- a/src/FbCommands.cc +++ b/src/FbCommands.cc | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "MenuCreator.hh" | 31 | #include "MenuCreator.hh" |
32 | 32 | ||
33 | #include "FbTk/I18n.hh" | 33 | #include "FbTk/I18n.hh" |
34 | #include "FbTk/Luamm.hh" | ||
34 | #include "FbTk/Theme.hh" | 35 | #include "FbTk/Theme.hh" |
35 | #include "FbTk/Menu.hh" | 36 | #include "FbTk/Menu.hh" |
36 | #include "FbTk/CommandParser.hh" | 37 | #include "FbTk/CommandParser.hh" |
@@ -554,4 +555,71 @@ void DeiconifyCmd::execute() { | |||
554 | }; | 555 | }; |
555 | } | 556 | } |
556 | 557 | ||
558 | REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(lua, LuaCmd, void); | ||
559 | |||
560 | namespace { | ||
561 | const char LuaCmds[] = "FbCommands::LuaCmd"; | ||
562 | } | ||
563 | |||
564 | LuaCmd::LuaCmd(const std::string &chunk) { | ||
565 | lua::state &l = Fluxbox::instance()->lua(); | ||
566 | l.checkstack(1); | ||
567 | l.loadstring(chunk); | ||
568 | init(l); | ||
569 | } | ||
570 | |||
571 | LuaCmd::LuaCmd(lua::state &l) { | ||
572 | lua::stack_sentry s(l, -1); | ||
573 | if(l.isstring(-1)) { | ||
574 | const std::string &str = l.tostring(-1); | ||
575 | l.pop(); | ||
576 | l.loadstring(str); | ||
577 | } | ||
578 | init(l); | ||
579 | } | ||
580 | |||
581 | void LuaCmd::init(lua::state &l) { | ||
582 | lua::stack_sentry s(l, -1); | ||
583 | l.checkstack(2); | ||
584 | |||
585 | l.rawgetfield(lua::REGISTRYINDEX, LuaCmds); { | ||
586 | if(l.isnil(-1)) { | ||
587 | l.pop(); | ||
588 | l.newtable(); | ||
589 | |||
590 | l.pushvalue(-1); | ||
591 | l.rawsetfield(lua::REGISTRYINDEX, LuaCmds); | ||
592 | } | ||
593 | |||
594 | l.pushvalue(-2); | ||
595 | m_ref = l.ref(-2); | ||
596 | } l.pop(); | ||
597 | |||
598 | l.pop(); | ||
599 | } | ||
600 | |||
601 | LuaCmd::~LuaCmd() { | ||
602 | lua::state &l = Fluxbox::instance()->lua(); | ||
603 | l.checkstack(1); | ||
604 | lua::stack_sentry s(l); | ||
605 | |||
606 | l.rawgetfield(lua::REGISTRYINDEX, LuaCmds); { | ||
607 | l.unref(-1, m_ref); | ||
608 | } l.pop(); | ||
609 | } | ||
610 | |||
611 | void LuaCmd::execute() { | ||
612 | lua::state &l = Fluxbox::instance()->lua(); | ||
613 | l.checkstack(1); | ||
614 | lua::stack_sentry s(l); | ||
615 | |||
616 | l.rawgetfield(lua::REGISTRYINDEX, LuaCmds); { | ||
617 | assert(l.istable(-1)); | ||
618 | |||
619 | l.rawgeti(-1, m_ref); { | ||
620 | assert(! l.isnil(-1)); | ||
621 | } l.call(0, 0); | ||
622 | } l.pop(); | ||
623 | } | ||
624 | |||
557 | } // end namespace FbCommands | 625 | } // end namespace FbCommands |
diff --git a/src/FbCommands.hh b/src/FbCommands.hh index b6b1f7f..ef9812b 100644 --- a/src/FbCommands.hh +++ b/src/FbCommands.hh | |||
@@ -32,6 +32,10 @@ | |||
32 | #include "ClientPattern.hh" | 32 | #include "ClientPattern.hh" |
33 | #include "FocusableList.hh" | 33 | #include "FocusableList.hh" |
34 | 34 | ||
35 | namespace lua { | ||
36 | class state; | ||
37 | } | ||
38 | |||
35 | namespace FbCommands { | 39 | namespace FbCommands { |
36 | 40 | ||
37 | /// executes a system command | 41 | /// executes a system command |
@@ -218,6 +222,24 @@ private: | |||
218 | Destination m_dest; | 222 | Destination m_dest; |
219 | }; | 223 | }; |
220 | 224 | ||
225 | /// Command that runs a lua function | ||
226 | class LuaCmd: public FbTk::Command<void> { | ||
227 | public: | ||
228 | /// parses the string as a lua chunk | ||
229 | LuaCmd(const std::string &chunk); | ||
230 | |||
231 | /// expect the function to be on the lua stack (as a function or a string) | ||
232 | LuaCmd(lua::state &l); | ||
233 | |||
234 | ~LuaCmd(); | ||
235 | |||
236 | void execute(); | ||
237 | private: | ||
238 | int m_ref; | ||
239 | |||
240 | void init(lua::state &l); | ||
241 | }; | ||
242 | |||
221 | } // end namespace FbCommands | 243 | } // end namespace FbCommands |
222 | 244 | ||
223 | #endif // FBCOMMANDS_HH | 245 | #endif // FBCOMMANDS_HH |