[Vm-dev] [Windows cog vm] [Keyboard events related] about keycode mapping

Guillermo Polito guillermopolito at gmail.com
Thu Jan 26 15:39:38 UTC 2012


turning the function into something like the one I paste below gives me the
following output in windows:

for p key:

key: 112 char: 112 type: keyDown
key: 112 char: 112 type: keystroke
key: 112 char: 112 type: keyUp

for shift + p key (being character 16 the shift key, since it is the
keycode in the platform, still different from the one in unix ¬¬):

key: 16 char: 16 type: keyDown
key: 80 char: 80 type: keyDown
key: 80 char: 80 type: keystroke
key: 80 char: 80 type: keyUp
key: 16 char: 16 type: keyUp

Regards,
Guille

int recordKeyboardEvent(MSG *msg) {
  sqKeyboardEvent *evt;
  int alt, shift, ctrl;
  int keyCode, virtCode, pressCode;

  if(!msg) return 0;

  alt = GetKeyState(VK_MENU) & 0x8000;
  shift = (GetKeyState(VK_SHIFT) & 0x8000);
  ctrl = GetKeyState(VK_CONTROL) & 0x8000;
  /* now the key code */
  virtCode = mapVirtualKey(msg->wParam);
  keyCode = msg->wParam;
  /* press code must differentiate */
  switch(msg->message) {
    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
      if(virtCode){
keyCode = virtCode;
      }else if(!shift && keyCode >= 0x41 && keyCode <= 0x5A){
  //If shift is not set and is a character we lowercase it
  keyCode = keyCode + 32;
  }else{
  keyCode = keymap[keyCode & 0xff];
  }
pressCode = EventKeyDown;
      /* filter out repeated meta keys */
      if(msg->lParam & 0x40000000) {
/* Bit 30 signifies the previous key state. */
if(msg->wParam == VK_SHIFT ||
   msg->wParam == VK_CONTROL ||
   msg->wParam == VK_MENU) {
  /* okay, it's a meta-key */
  return 1;
}
      }
      break;
    case WM_KEYUP:
    case WM_SYSKEYUP:
      if(virtCode){
keyCode = virtCode;
      }else if(!shift && keyCode >= 0x41 && keyCode <= 0x5A){
  //If shift is not set and is a character we lowercase it
  keyCode = keyCode + 32;
  }else{
  keyCode = keymap[keyCode & 0xff];
  }
      pressCode = EventKeyUp;
      break;
    case WM_CHAR:
    case WM_SYSCHAR:
      /* Note: VK_RETURN is recorded as virtual key ONLY */
      if(keyCode == 13) return 1;
      pressCode = EventKeyChar;
      break;
    default:
      pressCode = EventKeyChar;
  }
  /* remove Ctrl+Alt codes for international keyboards */
  if(ctrl && alt) {
    ctrl = 0;
    alt = 0;
  }

  /* first the basics */
  evt = (sqKeyboardEvent*) sqNextEventPut();
  evt->type = EventTypeKeyboard;
  evt->timeStamp = msg->time;
  evt->charCode = keyCode;
  evt->pressCode = pressCode;
  evt->modifiers = 0;
  evt->modifiers |= alt ? CommandKeyBit : 0;
  evt->modifiers |= shift ? ShiftKeyBit : 0;
  evt->modifiers |= ctrl ? CtrlKeyBit : 0;
  evt->windowIndex = msg->hwnd == stWindow ? 0 : (int) msg->hwnd;
  evt->utf32Code = keyCode;
  /* clean up reserved */
  evt->reserved1 = 0;
  /* note: several keys are not reported as character events;
     most noticably the mapped virtual keys. For those we
     generate extra character events here */
  if(pressCode == EventKeyDown && virtCode != 0) {
    /* generate extra character event */
    sqKeyboardEvent *extra = (sqKeyboardEvent*)sqNextEventPut();
    *extra = *evt;
    extra->pressCode = EventKeyChar;
  }
  return 1;
}

On Thu, Jan 26, 2012 at 12:07 PM, Guillermo Polito <
guillermopolito at gmail.com> wrote:

> More on, in the unix vm, the behavior is the following:
>
> when pressing p:
>
> key: 112 char: 112 type: keyDown
> key: 112 char: 112 type: keystroke
> key: 112 char: 112 type: keyUp
>
> when pressing shift + p (P):
> key: 254 char: 254 type: keyDown
> key: 80 char: 80 type: keyDown
> key: 80 char: 80 type: keystroke
> key: 80 char: 80 type: keyUp
>
>
> F1, after adding support for Function keys,
> key: 16 char: 16 type: keyDown
> key: 16 char: 16 type: keyUp
>
> While in the windows vm:
>
> when pressing p (the problematic one):
>
> key: 80 char: 80 type: keyDown
> key: 112 char: 112 type: keystroke
> key: 80 char: 80 type: keyUp
>
> when pressing shift + p (P) works the same, since P char value is the same
> as P virtual key value:
>
> key: 16 char: 16 type: keyDown
> key: 80 char: 80 type: keyDown
> key: 80 char: 80 type: keystroke
> key: 80 char: 80 type: keyUp
>
>
> F1, without touching the code, shares the same keycode than p:
>
> key: 112 char: 112 type: keyDown
> key: 112 char: 112 type: keyUp
>
> Guille
>
>
> On Thu, Jan 26, 2012 at 11:43 AM, Guillermo Polito <
> guillermopolito at gmail.com> wrote:
>
>> The question is:
>>
>> Should KeyDown, KeyUp and KeyChar events for the same key produce the
>> same keyCode?  I think yes.  Because the keyCode indicates the key pressed
>> in the keyboard. Doesn't it?
>>
>> Now, utf32Code should be only used on KeyChar events, and I don't care
>> about them.
>>
>> How does it work now?
>>
>> (KeyDown, KeyUp) and KeyChar events send different keyCodes to the image.
>>
>> Ok, right now works because in no place in the image keyDown: is handled,
>> but that's no excuse :).
>>
>> Regards,
>> Guille
>>
>> On Thu, Jan 26, 2012 at 11:17 AM, Guillermo Polito <
>> guillermopolito at gmail.com> wrote:
>>
>>> Sure!
>>>
>>> I'm not generating Char events for F11 ;).  Since F11 does not generate
>>> Char events.
>>>
>>> The problem is that the *p* key generates the same KeyDown event than
>>> F11 for the vm.  I'm only fixing that:
>>>
>>> KeyDown and KeyUp events for p key and F1 keys have different keyCodes.
>>>  I'm not sure if there will still be collisions, but right now, they are
>>> with the code as it is.
>>>
>>> Guille
>>>
>>> On Thu, Jan 26, 2012 at 11:02 AM, Andreas Raab <andreas.raab at gmx.de>wrote:
>>>
>>>>
>>>>  On 1/26/2012 14:52, Guillermo Polito wrote:
>>>>
>>>>
>>>>
>>>> Hi!
>>>>
>>>>  I was playing to add Function Ket support in the windows vm (yep,
>>>> always the same :P), and looking at the code, I saw this in the
>>>> recordKeyboardEvent:
>>>>
>>>>  evt = (sqKeyboardEvent*) sqNextEventPut();
>>>>   evt->type = EventTypeKeyboard;
>>>>   evt->timeStamp = msg->time;
>>>> *  evt->charCode = keymap[keyCode & 0xff];*
>>>>  *
>>>> *
>>>> the problem with that line is that KeyDown and KeyUp events send
>>>> VirtualKeycodes as keycodes and the Char event sends a unicode char value.
>>>>  And, it makes collisions, since for example
>>>>
>>>>  $p char value is 112
>>>> and F1 virtual code value is 112 too :P
>>>>
>>>>
>>>> http://msdn.microsoft.com/en-us/library/windows/desktop/ms646276(v=vs.85).aspx
>>>>
>>>> http://msdn.microsoft.com/en-us/library/windows/desktop/ms646281(v=vs.85).aspx
>>>>
>>>> http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
>>>>
>>>>  And so with other keys, having the same keycode in the image side
>>>> with different keys...
>>>>
>>>>  I'm trying a solution like this, providing in a Char event the
>>>> keycode without mapping to the image:
>>>>
>>>>  ...
>>>>      case WM_CHAR:
>>>>     case WM_SYSCHAR:
>>>>       /* Note: VK_RETURN is recorded as virtual key ONLY */
>>>>       if(keyCode == 13) return 1;
>>>>     *  charCode = keyCode;*
>>>>       pressCode = EventKeyChar;
>>>>       break
>>>> ...
>>>>  evt->timeStamp = msg->time;
>>>>  *  evt->charCode = charCode? charCode : keymap[keyCode & 0xff];*
>>>>    evt->pressCode = pressCode;
>>>>  ...
>>>>
>>>>  changing only the bold lines, and It seems to work.
>>>>
>>>>  What do you think?
>>>>
>>>>
>>>> The change makes no sense (it will break most non-ascii input like
>>>> accents, umlauts, etc). You really shouldn't be using character events for
>>>> handling function keys. There is no 'F11 Character' in any character
>>>> encoding world-wide so trying to represent F11 as a character is completely
>>>> futile. You need to use keyDown and keyUp events, since F11 & friends are
>>>> KEYs not CHARACTERs.
>>>>
>>>> Cheers,
>>>>   - Andreas
>>>>
>>>>
>>>>  Guille
>>>>
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20120126/79432442/attachment.htm


More information about the Vm-dev mailing list