EventServer tries event 61440 with virtual keyboard
#1
In my free time, I'm hacking together a ncurses ssh 'remote'. Basically trying to use EventServer to replace a keyboard. (For those days I lose the remote in the couch....).

I've got it working rather well for key presses, however when the virtual keyboard is up everything gets remapped to "61440".

Virtual Keyboard Up:
Code:
13:16:36 T:2689971520 M:5138317312   DEBUG: OnKey: 61525 pressed, trying keyboard action 61440
13:16:36 T:2689971520 M:5138317312   DEBUG: OnKey: 61523 pressed, trying keyboard action 61440
13:16:36 T:2689971520 M:5138313216   DEBUG: OnKey: 61524 pressed, trying keyboard action 61440
13:16:36 T:2689971520 M:5138292736   DEBUG: OnKey: 61512 pressed, trying keyboard action 61440
13:16:36 T:2689971520 M:5138292736   DEBUG: OnKey: 61452 pressed, trying keyboard action 61440
13:16:36 T:2689971520 M:5138157568   DEBUG: OnKey: 61454 pressed, trying keyboard action 61440
13:16:36 T:2689971520 M:5138157568   DEBUG: OnKey: 61520 pressed, trying keyboard action 61440
13:16:36 T:2689971520 M:5138145280   DEBUG: OnKey: 61522 pressed, trying keyboard action 61440
13:16:36 T:2689971520 M:5138145280   DEBUG: OnKey: 61507 pressed, trying keyboard action 61440
13:16:36 T:2689971520 M:5138128896   DEBUG: OnKey: 61511 pressed, trying keyboard action 61440
13:16:37 T:2689971520 M:5138137088   DEBUG: OnKey: 61519 pressed, trying keyboard action 61440
13:16:37 T:2689971520 M:5138137088   DEBUG: OnKey: 61512 pressed, trying keyboard action 61440
13:16:37 T:2689971520 M:5138132992   DEBUG: OnKey: 61524 pressed, trying keyboard action 61440
13:16:37 T:2689971520 M:5138190336   DEBUG: OnKey: 61508 pressed, trying keyboard action 61440
13:16:37 T:2689971520 M:5138190336   DEBUG: OnKey: 61513 pressed, trying keyboard action 61440

Home Menu:
Code:
13:16:45 T:2689971520 M:5141086208   DEBUG: OnKey: 61520 pressed, action is Play
13:16:45 T:2689971520 M:5141086208   DEBUG: OnKey: 61521 pressed, action is Queue
13:27:22 T:2689971520 M:5334847488   DEBUG: OnKey: 61467 pressed, action is PreviousMenu

The only buttons that seem to work are the arrow keys, but those I'm sending as R1 buttons.

Relevant Code:
Code:
case KEY_LEFT:
    xbmc.SendButton("left","R1",BTN_NO_REPEAT);
    break;
case KEY_RIGHT:
    xbmc.SendButton("right","R1",BTN_NO_REPEAT);
    break;
default:
    xbmc.SendButton(0xEFE0+ch,"KB",BTN_NO_REPEAT);
Reply
#2
I believe we send a "a keyboard key is pressed" along with the key id as a separate param during virtual keyboard, as this allows us to pass the direct keycode to the virtual keyboard class. See Application.cpp for how this is done (maybe in OnKey)

You'd have to do the same trick here - i.e. pass along the keycode.

Cheers,
Jonathan
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.


Image
Reply
#3
My C++ is really rusty.

"pressed, trying keyboard action" is printed in:
Application.cpp: bool CApplication::OnKey(const CKey& key)

Best I can figure is that the reason that 0xF000 is being printed for:
Code:
action = CAction(key.GetVKey() | KEY_VKEY);
CLog::Log(LOGDEBUG, "%s: %i pressed, trying keyboard action %i", __FUNCTION__, (int) key.GetButtonCode(), action.GetID());

key.GetVKey must be returning 0.

A CKey is created in bool CApplication:TonguerocessEventServer, line 2977
key = CKey(wKeyID); # wKeyID is a WORD.
return OnKey(key);

However, I can't find a constructor that only has 1 input:
Code:
CKey::CKey(void)
CKey::CKey(uint32_t buttonCode, uint8_t leftTrigger, uint8_t rightTrigger, float leftThumbX, float leftThumbY, float rightThumbX, float rightThumbY, float repeat)
CKey::CKey(uint32_t buttonCode, unsigned int held)
CKey::CKey(uint8_t vkey, wchar_t unicode, char ascii, uint32_t modifiers, unsigned int held)
CKey::CKey(const CKey& key)


If you're going to have a single input, doesn't other inputs have to be given a default? e.g. "unsigned int held=false"

These are inline functions:
Code:
inline uint8_t  GetVKey() const       { return m_vkey; }
inline wchar_t  GetUnicode() const    { return m_unicode; }
inline char     GetAscii() const      { return m_ascii; }

However with the CKey::CKey, it doesn't look like any of them are set:
Code:
CKey::CKey(uint32_t buttonCode, unsigned int held)
{
  Reset();
  m_buttonCode = buttonCode;
  m_held = held;
}

It does look like it is set with this constructor:
Code:
CKey::CKey(uint8_t vkey, wchar_t unicode, char ascii, uint32_t modifiers, unsigned int held)
{
  Reset();
  if (vkey) // FIXME: This needs cleaning up - should we always use the unicode key where available?
    m_buttonCode = vkey | KEY_VKEY;
  else
    m_buttonCode = KEY_UNICODE;
  m_buttonCode |= modifiers;
  m_vkey = vkey;
  m_unicode = unicode;
  m_ascii = ascii;
  m_modifiers = modifiers;
  m_held = held;
}

Would the first constructor be accidentally called, thus not setting m_vkey? Then when .GetVKey gets ORed with KEY_VKEY, only KEY_VKEY is being set.
Reply
#4
It's calling the first non-trivial constructor - see Key.h for the inline settings to 0.

It should probably be calling the one you suggest, though I'm not sure exactly what wKeyID is (i.e. is it vkey?)

You're definitely on the right track though!

Cheers,
Jonathan
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.


Image
Reply
#5
wKeyID is what the EventServer returns:

Code:
WORD wKeyID = es->GetButtonCode(joystickName, isAxis, fAmount);

Then if the joystickName is of length 0, it forks into checking if it is an analog input.
Which seems to be what I'm seeing with the code. I'm trying out the python client for some rapid prototyping.
Code:
packet= PacketBUTTON(map_name="KB", button_name="right")
packet= PacketBUTTON(map_name="R1", button_name="right")

In a Keyboard popup, the first one does nothing and just sends the ambiguous 61440.

I'm downloading source and going to populate the heck out of that function with debug code.
Reply
#6
Well, last night was fun.

wKeyID and everything following is 0 when the virtual keyboard is up.

On a gigabit network XBMC is quite snapy over X11, although the sound still comes out where it's setup in.
Definitely the largest thing I've ever run in gdb/ddd.
Reply
#7
Somebody's been fixing some things. Smile

I found the 'root' of the problem. When key comes from the 'honest' keyboard, it looks like this:
Code:
Key: (const CKey &) @0xbfffe18c: {_vptr.CKey = 0x8bdc2d0, m_buttonCode = 61505, m_vkey = 65 'A', m_unicode = 97 L'a', m_ascii = 97 'a', m_modifiers = 0, m_held = 0, m_leftTrigger = 0 '\000', m_rightTrigger = 0 '\000', m_leftThumbX = 0, m_leftThumbY = 0, m_rightThumbX = 0, m_rightThumbY = 0, m_repeat = 0, m_fromHttpApi = false}

When it comes in over EventServer, it looks like this:
Code:
(const CKey &) @0xbfffe250: {_vptr.CKey = 0x8bdc2d0, m_buttonCode = 61505, m_vkey = 0 '\000', m_unicode = 0 L'\000', m_ascii = 0 '\000', m_modifiers = 0, m_held = 0, m_leftTrigger = 0 '\000', m_rightTrigger = 0 '\000', m_leftThumbX = 0, m_leftThumbY = 0, m_rightThumbX = 0, m_rightThumbY = 0, m_repeat = 0, m_fromHttpApi = false}

The action looks the same:
Code:
Action: {m_id = 0, m_name = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >> = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x18637bc ""}}, <No data fields>}, static max_amounts = 4, m_amount = {1, 0, 0, 0}, m_repeat = 0, m_holdTime = 0, m_buttonCode = 0, m_unicode = 0 L'\000'}

mButtonCode is the same, so it 'behaves' the same everywhere except when the virtual keyboard is up because of this logic:
Code:
bool useKeyboard = key.FromKeyboard() && (iWin == WINDOW_DIALOG_KEYBOARD || iWin == WINDOW_DIALOG_NUMERIC);
...
if (useKeyboard) {
...
if (!action.GetID())
      {
        // keyboard entry - pass the keys through directly
        if (key.GetFromHttpApi())
          action = CAction(key.GetButtonCode() != KEY_INVALID ? key.GetButtonCode() : 0, key.GetUnicode());
        else
        { // see if we've got an ascii key
          if (key.GetUnicode())
            action = CAction(key.GetAscii() | KEY_ASCII, key.GetUnicode());
          else
            action = CAction(key.GetVKey() | KEY_VKEY);
        }
      }

Except the ASCII and VKey are both 0, so that's why it just is returning KEY_VKEY.
----
Not sure if it qualifies 'bug' but EventServer is sending events as char. So anything with a modifier key in it, the modifier key gets stripped. (Shift+=0x20000, Ctrl+=0x10000).
With the program I'm building the modifier keys don't get sent over the wire so I can't create a ckey with them.
Code:
CKey(m_VKey, m_wUnicode, m_cAscii, m_Modifiers, m_keyHoldTime);

Once this is should pave the way for "remote keyboards" to be anything from terminals (my app) to QWERTY keyboards on Androids/iPhone.
----
It's been a while since I did any C/C++, and definitely not on a project of this size. I tried creating a patch with 'svn update' then 'svn diff > keyboard.patch', except it decided it wanted to include a TON of other random stuff. I tried to cut it down, hopefully this works: http://pastebin.com/MHsJt6b4
Reply
#8
http://trac.xbmc.org/ticket/10817
Reply
#9
Thanks - will take a nosy.
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.


Image
Reply

Logout Mark Read Team Forum Stats Members Help
EventServer tries event 61440 with virtual keyboard0