1 | /** |
2 | * Copyright (c) 2006-2023 LOVE Development Team |
3 | * |
4 | * This software is provided 'as-is', without any express or implied |
5 | * warranty. In no event will the authors be held liable for any damages |
6 | * arising from the use of this software. |
7 | * |
8 | * Permission is granted to anyone to use this software for any purpose, |
9 | * including commercial applications, and to alter it and redistribute it |
10 | * freely, subject to the following restrictions: |
11 | * |
12 | * 1. The origin of this software must not be misrepresented; you must not |
13 | * claim that you wrote the original software. If you use this software |
14 | * in a product, an acknowledgment in the product documentation would be |
15 | * appreciated but is not required. |
16 | * 2. Altered source versions must be plainly marked as such, and must not be |
17 | * misrepresented as being the original software. |
18 | * 3. This notice may not be removed or altered from any source distribution. |
19 | **/ |
20 | |
21 | #include "common/config.h" |
22 | |
23 | #include "wrap_Keyboard.h" |
24 | |
25 | #include "sdl/Keyboard.h" |
26 | |
27 | namespace love |
28 | { |
29 | namespace keyboard |
30 | { |
31 | |
32 | #define instance() (Module::getInstance<Keyboard>(Module::M_KEYBOARD)) |
33 | |
34 | int w_setKeyRepeat(lua_State *L) |
35 | { |
36 | instance()->setKeyRepeat(luax_checkboolean(L, 1)); |
37 | return 0; |
38 | } |
39 | |
40 | int w_hasKeyRepeat(lua_State *L) |
41 | { |
42 | luax_pushboolean(L, instance()->hasKeyRepeat()); |
43 | return 1; |
44 | } |
45 | |
46 | int w_isDown(lua_State *L) |
47 | { |
48 | Keyboard::Key k; |
49 | |
50 | bool istable = lua_istable(L, 1); |
51 | int num = istable ? (int) luax_objlen(L, 1) : lua_gettop(L); |
52 | |
53 | std::vector<Keyboard::Key> keylist; |
54 | keylist.reserve(num); |
55 | |
56 | if (istable) |
57 | { |
58 | for (int i = 0; i < num; i++) |
59 | { |
60 | lua_rawgeti(L, 1, i + 1); |
61 | |
62 | const char *name = luaL_checkstring(L, -1); |
63 | if (!Keyboard::getConstant(name, k)) |
64 | return luax_enumerror(L, "key constant" , name); |
65 | |
66 | keylist.push_back(k); |
67 | lua_pop(L, 1); |
68 | } |
69 | } |
70 | else |
71 | { |
72 | for (int i = 0; i < num; i++) |
73 | { |
74 | const char *name = luaL_checkstring(L, i + 1); |
75 | if (!Keyboard::getConstant(name, k)) |
76 | return luax_enumerror(L, "key constant" , name); |
77 | |
78 | keylist.push_back(k); |
79 | } |
80 | } |
81 | |
82 | luax_pushboolean(L, instance()->isDown(keylist)); |
83 | return 1; |
84 | } |
85 | |
86 | int w_isScancodeDown(lua_State *L) |
87 | { |
88 | Keyboard::Scancode scancode; |
89 | |
90 | bool istable = lua_istable(L, 1); |
91 | int num = istable ? (int) luax_objlen(L, 1) : lua_gettop(L); |
92 | |
93 | std::vector<Keyboard::Scancode> scancodelist; |
94 | scancodelist.reserve(num); |
95 | |
96 | if (istable) |
97 | { |
98 | for (int i = 0; i < num; i++) |
99 | { |
100 | lua_rawgeti(L, 1, i + 1); |
101 | |
102 | const char *name = luaL_checkstring(L, -1); |
103 | if (!Keyboard::getConstant(name, scancode)) |
104 | return luax_enumerror(L, "scancode" , name); |
105 | |
106 | scancodelist.push_back(scancode); |
107 | lua_pop(L, 1); |
108 | } |
109 | } |
110 | else |
111 | { |
112 | for (int i = 0; i < num; i++) |
113 | { |
114 | const char *name = luaL_checkstring(L, i + 1); |
115 | if (!Keyboard::getConstant(name, scancode)) |
116 | return luax_enumerror(L, "scancode" , name); |
117 | |
118 | scancodelist.push_back(scancode); |
119 | } |
120 | } |
121 | |
122 | luax_pushboolean(L, instance()->isScancodeDown(scancodelist)); |
123 | return 1; |
124 | } |
125 | |
126 | int w_getScancodeFromKey(lua_State *L) |
127 | { |
128 | const char *keystr = luaL_checkstring(L, 1); |
129 | Keyboard::Key key; |
130 | if (!Keyboard::getConstant(keystr, key)) |
131 | return luax_enumerror(L, "key constant" , keystr); |
132 | |
133 | Keyboard::Scancode scancode = instance()->getScancodeFromKey(key); |
134 | |
135 | const char *scancodestr; |
136 | if (!Keyboard::getConstant(scancode, scancodestr)) |
137 | return luaL_error(L, "Unknown scancode." ); |
138 | |
139 | lua_pushstring(L, scancodestr); |
140 | return 1; |
141 | } |
142 | |
143 | int w_getKeyFromScancode(lua_State *L) |
144 | { |
145 | const char *scancodestr = luaL_checkstring(L, 1); |
146 | Keyboard::Scancode scancode; |
147 | if (!Keyboard::getConstant(scancodestr, scancode)) |
148 | return luax_enumerror(L, "scancode" , scancodestr); |
149 | |
150 | Keyboard::Key key = instance()->getKeyFromScancode(scancode); |
151 | |
152 | const char *keystr; |
153 | if (!Keyboard::getConstant(key, keystr)) |
154 | return luaL_error(L, "Unknown key constant" ); |
155 | |
156 | lua_pushstring(L, keystr); |
157 | return 1; |
158 | } |
159 | |
160 | int w_setTextInput(lua_State *L) |
161 | { |
162 | bool enable = luax_checkboolean(L, 1); |
163 | |
164 | if (lua_gettop(L) <= 1) |
165 | instance()->setTextInput(enable); |
166 | else |
167 | { |
168 | double x = luaL_checknumber(L, 2); |
169 | double y = luaL_checknumber(L, 3); |
170 | double w = luaL_checknumber(L, 4); |
171 | double h = luaL_checknumber(L, 5); |
172 | instance()->setTextInput(enable, x, y, w, h); |
173 | } |
174 | |
175 | return 0; |
176 | } |
177 | |
178 | int w_hasTextInput(lua_State *L) |
179 | { |
180 | luax_pushboolean(L, instance()->hasTextInput()); |
181 | return 1; |
182 | } |
183 | |
184 | int w_hasScreenKeyboard(lua_State *L) |
185 | { |
186 | luax_pushboolean(L, instance()->hasScreenKeyboard()); |
187 | return 1; |
188 | } |
189 | |
190 | // List of functions to wrap. |
191 | static const luaL_Reg functions[] = |
192 | { |
193 | { "setKeyRepeat" , w_setKeyRepeat }, |
194 | { "hasKeyRepeat" , w_hasKeyRepeat }, |
195 | { "setTextInput" , w_setTextInput }, |
196 | { "hasTextInput" , w_hasTextInput }, |
197 | { "hasScreenKeyboard" , w_hasScreenKeyboard }, |
198 | { "isDown" , w_isDown }, |
199 | { "isScancodeDown" , w_isScancodeDown }, |
200 | { "getScancodeFromKey" , w_getScancodeFromKey }, |
201 | { "getKeyFromScancode" , w_getKeyFromScancode }, |
202 | { 0, 0 } |
203 | }; |
204 | |
205 | extern "C" int luaopen_love_keyboard(lua_State *L) |
206 | { |
207 | Keyboard *instance = instance(); |
208 | if (instance == nullptr) |
209 | { |
210 | luax_catchexcept(L, [&](){ instance = new love::keyboard::sdl::Keyboard(); }); |
211 | } |
212 | else |
213 | instance->retain(); |
214 | |
215 | WrappedModule w; |
216 | w.module = instance; |
217 | w.name = "keyboard" ; |
218 | w.type = &Module::type; |
219 | w.functions = functions; |
220 | w.types = 0; |
221 | |
222 | return luax_register_module(L, w); |
223 | } |
224 | |
225 | } // keyboard |
226 | } // love |
227 | |