IDirectFBInputDevice caches the key states (up/down) by keeping track
of press and release events. This doesn't take into account that a key
may be pressed at the time the device is opened or that a key might
have changed state while the device was in suspend.

This change introduces code to the linux_input driver that queries
the keystates when the event thread is started and synthesizes key
events for all keys depending on the key state as reported by the
linux input layer.

Signed-off-by: Sven Neumann <s.neum...@raumfeld.com>
---
 inputdrivers/linux_input/linux_input.c |   39 ++++++++++++++++++++++++++++++-
 1 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/inputdrivers/linux_input/linux_input.c 
b/inputdrivers/linux_input/linux_input.c
index 17cd627..08b0d36 100644
--- a/inputdrivers/linux_input/linux_input.c
+++ b/inputdrivers/linux_input/linux_input.c
@@ -147,6 +147,7 @@ typedef struct {
      int                      fd;
      int                      quitpipe[2];
 
+     bool                     has_keys;
      bool                     has_leds;
      unsigned long            led_state[NBITS(LED_CNT)];
      DFBInputDeviceLockState  locks;
@@ -817,6 +818,39 @@ linux_input_EventThread( DirectThread *thread, void 
*driver_data )
           fsm_state.y.max = absinfo.maximum;
      }
 
+     /* Query key states. */
+     if (data->has_keys) {
+          unsigned long keybit[NBITS(KEY_CNT)];
+          unsigned long keystate[NBITS(KEY_CNT)];
+          int i;
+
+          /* get keyboard bits */
+          ioctl( data->fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit );
+
+          /* get key states */
+          ioctl( data->fd, EVIOCGKEY(sizeof(keystate)), keystate );
+
+          /* for each key,
+             synthetize a press or release event depending on the key state */
+          for (i=0; i<=KEY_CNT; i++) {
+               if (test_bit( i, keybit )) {
+                    const int key = translate_key( i );
+
+                    if (DFB_KEY_TYPE(key) == DIKT_IDENTIFIER) {
+                         DFBInputEvent devt;
+
+                         devt.type     = (test_bit( i, keystate )
+                                          ? DIET_KEYPRESS : DIET_KEYRELEASE);
+                         devt.flags    = DIEF_KEYID | DIEF_KEYCODE;
+                         devt.key_id   = key;
+                         devt.key_code = i;
+
+                         dfb_input_dispatch( data->device, &devt );
+                    }
+               }
+          }
+     }
+
      while (1) {
           DFBInputEvent devt = { .type = DIET_UNKNOWN };
 
@@ -1241,8 +1275,9 @@ driver_open_device( CoreInputDevice  *device,
           return D_OOM();
      }
 
-     data->fd     = fd;
-     data->device = device;
+     data->fd       = fd;
+     data->device   = device;
+     data->has_keys = (info->desc.caps & DICAPS_KEYS) != 0;
      data->touchpad = touchpad;
      data->vt_fd    = -1;
 
-- 
1.6.0.4

_______________________________________________
directfb-dev mailing list
directfb-dev@directfb.org
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to