lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


eFrom: leiradella@bigfoot.com

Hi All,

I'm writing a Lua interface to the LibVNCServer-0.6 library. The client
side that permits you to connect to a VNC server and send mouse and
keyboard events is working, but I'm having trouble passing multiple
arguments to a C function from Lua.

Here's the C function:

-----------------------------------8<-----------------------------------
/*
Sends one key down event to the server. Parameter can be number (treated
as key code) or string, where each character is sent as a key down
event.
*/
static int L_keyDown(lua_State *L) {
	clientUserData	*userData;
	int			ret, index, top;
	const char		*text;
	
	/* Check parameters. */
	userData = getClientUserData(L, 1);
	/* Iterate through all arguments. */
	top = lua_gettop(L);
	index = 2;
	do {
		printf("%d %d %s\n", index, top, 
			lua_typename(L, lua_type(L, index)));
		/* If the argument is a number, it's a key code. */
		if (lua_isnumber(L, index)) {
			/* Send key down event. */
			ret = SendKeyEvent(&userData->client, 
				lua_tonumber(L, index), TRUE) == TRUE;
			processMessages(userData);
		/* Otherwise it must be a string. */
		} else if (lua_isstring(L, index)) {
			text = lua_tostring(L, index);
			/* Repeat over all characters of the string. */
			while (*text && ret) {
				/* Send key down event. */
				ret = SendKeyEvent(&userData->client,
					*text++, TRUE) == TRUE;
				processMessages(userData);
			}
		} else
			luaL_argerror(L, index,
				"key code or string expected");
	} while (++index <= top && ret);
	/* Return boolean. */
	lua_pushboolean(L, ret);
	return 1;
}
-----------------------------------8<-----------------------------------

This functions receives the userdata of the VNC client structure and
zero or more numbers, which represent key codes like ALT or CONTROL, or
strings, where each character represents a key, and sends keydown events
of them to the VNC server.

In my Lua test program, I then write:

-----------------------------------8<-----------------------------------
c = rfb.newClient()
c:setCallbackFunction('handleCursorPos', handleCursorPos)
c:setCallbackFunction('softCursorLockArea', softCursorLockArea)
c:setCallbackFunction('softCursorUnlockScreen', softCursorUnlockScreen)
c:setCallbackFunction('gotFrameBufferUpdate', gotFrameBufferUpdate)
c:setCallbackFunction('getPassword', getPassword)
c:setCallbackFunction('bell', bell)
c:connect()
c:keyDown(rfb.ALT, rfb.TAB)
-----------------------------------8<-----------------------------------

Everything works fine, until the c:keyDown call. The first argument that
the C function receives is the user data, the second is the key code for
ALT (65513) and the third the key code for TAB (65289). What happens is
that the C function receives three arguments (like expected), but the
third argument is LUA_TNONE. The output of the test program is:

-----------------------------------8<-----------------------------------
2 3 number
3 3 no value
bin/lua: test.lua:44: bad argument #2 to `keyDown' (string expected, got no value)
stack traceback:
        [C]: in function `keyDown'
        test.lua:44: in main chunk
        [C]: ?
-----------------------------------8<-----------------------------------

The first two lines are the output of the printf inside L_keyDown. I can
check that rfb.TAB has the correct value (print(rfb.TAB) yields 65289.
If I change the key codes for string or mix them in the call the error
is exactly the same. If I add more arguments, lua_gettop returns the
correct number but the third argument is again a LUA_TNONE. The function
only works when there are only two arguments, the userdata and one
number or string.

I know I can work around this problem, but the question is: why it's not
working? Could someone enlight me? My build and test environment is
cygwin 5.1, gcc 3.3.3, lua-5.0.2 with an unmodified config file and a
Lua interpreter modified only to open the rfb library.

Thanks in advance,

Andre de Leiradella