Skip to content

Extend Event Server to better emulate keyboard presses #1763

Closed
wants to merge 8 commits into from

4 participants

@jonfabe
jonfabe commented Nov 11, 2012

1) Implemented a new extended button packet in the event server to allow modifier keys to be sent.
-> Old button packet (PT_BUTTON) left unmodified for backward compatibility
-> New button backet (PT_BUTTON_EXTENDED) changes button code to 4 bytes instead of 2 bytes

2) Added additional logic to Key.cpp class to populate the m_vkey, m_ascii, and m_modifiers fields of the CKey class when an ASCII or VKEY is sent over the event server.

Taken together, these changes allow emulated keyboard presses to be sent over the event server to XBMC (and to be correctly handled).

These changes should have little to no impact on existing event server clients as it preserves the old functionality of the event server.
-> Exception: If an event client is sending an ASCII encoded value (has the flag 0xf100) between 0x61 and 0x7a and expecting it to be handled as a VKEY (flag 0xf000) instead (corresponding to numberpad operations) it will fail as this patch will change the lowercase ascii value to the correct VKey value (which corresponds to the uppercase equivalent ascii value). This shouldn't be a problem, however, as all the event server client would need to do is correct their implementation is to send the correct flag (0xf000) instead of the incorrect flag (0xf100).

@jmarshallnz
Team Kodi member

What is your goal here exactly? The code is even more convoluted than things currently are, which suggests that there's a much better way to do what you want to do.

@jonfabe
jonfabe commented Nov 11, 2012

For instance, say you have xbmc running on a device attached to your tv, without a keyboard (or mouse) attached and you want to interface with it, say from your laptop. If you're running xbmc on a full os its no problem, you can just use vnc or another program to essentially do a virtual KM switch and forward the keyboard and mouse to the device. If your running on a distro like OpenElec, however, you can't just install another program, so that leaves interfacing with xbmc directly.

The JSONRPC interface doesn't let you send key-presses to xbmc, only fill in text boxes, and the current EventServer interface will let you send key-presses, but no modifiers (the short it sends is only enough to send the key itself), and the key-presses themselves aren't interpreted the same way as an actual key-press on a keyboard attached directly to the system (the ascii fields and vkey fields don't get filled in and they need to be in order to be correctly interpreted by all the different parts of xbmc).

So in a nut shell thats what this aims to do, allow control of xbmc remotely as if you were sitting in front of the system and physically interacting with an attached keyboard, but instead doing it from a laptop, etc. that isn't physically attached to the system (without the expense of buying a wireless keyboard).

These changes seemed to be the easiest way to do this, reusing the existing input infrastructure and just populating the needed fields from the key-code that is sent to the event server.

@jmarshallnz
Team Kodi member

If you want to send unicode (for text input) then you can do that already.

If you want to send keys with modifiers, then I have no problem with the idea (though would suggest you look to something other than vkey insanity for it unless there really is no other way).

However, internal to XBMC there should be no more crazy KEY_VKEY/KEY_ASCII/other random bitmask shenanigans. Grab exactly what you need out of the event client so that you can directly set the fields on the CKey via

CKey(uint8_t vkey, wchar_t unicode, char ascii, uint32_t modifiers, unsigned int held)

@jonfabe
jonfabe commented Nov 15, 2012

Ok, so I looked into alternatives other then using the Vkey codes, and found I could use the unicode values for most keys and just had to run them through the ProccessKeyDown function to get the correctly populated CKey object. That left the non-unicode characters and certain unicode characters not defined currently in the XBMC_keytable (such as return, backspace, etc.), these keys seemed to best be handled by the SDL keycodes, since the same code which handles the unicode values could then be used to handle these as well (by just setting the unicode field to KEY_INVALID and letting the ProccessKeyDown function overwrite it with the correct value).

These changes get rid of all the bit-masking I was originally doing to accomplish the same thing, hopefully making it a bit easier to see the purpose now.

As an aside, this is probably the wrong place to ask this, but why are there both unicode and ascii values set on the CKey object instead of just the unicode? Is it just historical flotsam and jetsam still around waiting to be cleaned up or is it important to some other aspect of the code?

@jmarshallnz
Team Kodi member

The approach is starting to look much better.

I don't like it being passed through CKeyboardStat though, and I'm not sure it's necessary. From what I can tell, you do this primarily to get the vkey from the key name, (via key name -> keysym -> vkey). It seems to me that translating from key name direct to vkey would be best if you can - you have the modifier + unicode directly, so really don't need anything else other than the vkey, right?

And yes, the ascii thing should hopefully be no longer used, but may still be showing up in some places.

@jonfabe
jonfabe commented Nov 20, 2012

Well yes and no, for unicode values it will populate the ascii and vkey values (through the KeyTableLookupUnicode call) and for keysym values it will populate the ascii, vkey, and unicode values (through the KeyTableLookupSym call) - I ran into a few places while testing where CKey still needs the ascii value populated to function correctly (like when using shift+letter to jump in a menu), so it seemed best just to reuse the ProcessKeyDown function to make sure all the fields were populated correctly.

Additionally, the ProcessKeyDown function converts the SDL modifier values being sent to the EventServer into the internal XBMC modifier values used by CKey, but I only used the SDL values to begin with to be compatible with the ProcessKeyDown function, so its only a secondary concern.

That said, its not strictly necessary to run it through ProcessKeyDown, I could just call the keytable lookup functions directly and grab the needed values, but since ProcessKeyDown does this already it seemed like a waste to basically rewrite the same code elsewhere. Thoughts?

@FernetMenta
Team Kodi member

no activity for more than 2 years. will close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.