Tizen 2.0 Release
[profile/ivi/ecore.git] / src / lib / ecore_win32 / ecore_win32_event.c
index 4b0b342..4476b2b 100644 (file)
@@ -1,7 +1,3 @@
-/*
- * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
- */
-
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
 #undef WIN32_LEAN_AND_MEAN
 #include <windowsx.h>
 
-#include "Ecore.h"
+#include <Eina.h>
+#include <Ecore.h>
+#include <Ecore_Input.h>
+
 #include "Ecore_Win32.h"
 #include "ecore_win32_private.h"
 
 
+typedef enum
+{
+   ECORE_WIN32_KEY_MASK_LSHIFT = 1 << 0,
+   ECORE_WIN32_KEY_MASK_RSHIFT = 1 << 1,
+   ECORE_WIN32_KEY_MASK_LCONTROL = 1 << 2,
+   ECORE_WIN32_KEY_MASK_RCONTROL = 1 << 3,
+   ECORE_WIN32_KEY_MASK_LMENU = 1 << 4,
+   ECORE_WIN32_KEY_MASK_RMENU = 1 << 5
+} Ecore_Win32_Key_Mask;
+
 /***** Private declarations *****/
 
 
-static Ecore_Win32_Window *_ecore_win32_mouse_down_last_window = NULL;
-static Ecore_Win32_Window *_ecore_win32_mouse_down_last_last_window = NULL;
-static double              _ecore_win32_mouse_down_last_time = 0;
-static double              _ecore_win32_mouse_down_last_last_time = 0;
-static int                 _ecore_win32_mouse_down_did_triple = 0;
-static int                 _ecore_win32_mouse_up_count = 0;
+static Ecore_Win32_Window  *_ecore_win32_mouse_down_last_window = NULL;
+static Ecore_Win32_Window  *_ecore_win32_mouse_down_last_last_window = NULL;
+static long                 _ecore_win32_mouse_down_last_time = 0  ;
+static long                 _ecore_win32_mouse_down_last_last_time = 0  ;
+static int                  _ecore_win32_mouse_down_did_triple = 0;
+static int                  _ecore_win32_mouse_up_count = 0;
+static Ecore_Win32_Key_Mask _ecore_win32_key_mask = 0;
 
 static void _ecore_win32_event_free_key_down(void *data,
                                              void *ev);
@@ -35,15 +45,18 @@ static void _ecore_win32_event_free_key_down(void *data,
 static void _ecore_win32_event_free_key_up(void *data,
                                            void *ev);
 
-static int  _ecore_win32_event_keystroke_get(int    key,
-                                             char **keyname,
-                                             char **keysymbol,
-                                             char **keycompose);
+static int  _ecore_win32_event_keystroke_get(Ecore_Win32_Callback_Data *msg,
+                                             Eina_Bool                  is_down,
+                                             char                     **keyname,
+                                             char                     **keysymbol,
+                                             char                     **keycompose,
+                                             unsigned int              *modifiers);
 
-static int  _ecore_win32_event_char_get(int    key,
-                                        char **keyname,
-                                        char **keysymbol,
-                                        char **keycompose);
+static int  _ecore_win32_event_char_get(int           key,
+                                        char        **keyname,
+                                        char        **keysymbol,
+                                        char        **keycompose,
+                                        unsigned int *modifiers);
 
 
 /***** Global functions definitions *****/
@@ -52,94 +65,94 @@ void
 _ecore_win32_event_handle_key_press(Ecore_Win32_Callback_Data *msg,
                                     int                        is_keystroke)
 {
-   Ecore_Win32_Event_Key_Down *e;
+   Ecore_Event_Key *e;
 
-   e = (Ecore_Win32_Event_Key_Down *)malloc(sizeof(Ecore_Win32_Event_Key_Down));
+   INF("key pressed");
+
+   e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key));
    if (!e) return;
 
    if (is_keystroke)
      {
-        if (!_ecore_win32_event_keystroke_get(LOWORD(msg->window_param),
-                                              &e->keyname,
-                                              &e->keysymbol,
-                                              &e->keycompose))
+        if (!_ecore_win32_event_keystroke_get(msg,
+                                              EINA_TRUE,
+                                              (char **)&e->keyname,
+                                              (char **)&e->key,
+                                              (char **)&e->string,
+                                              &e->modifiers))
           {
              free(e);
              return;
           }
-        goto store_key;
      }
    else
      {
         if (!_ecore_win32_event_char_get(LOWORD(msg->window_param),
-                                         &e->keyname,
-                                         &e->keysymbol,
-                                         &e->keycompose))
+                                         (char **)&e->keyname,
+                                         (char **)&e->key,
+                                         (char **)&e->string,
+                                         &e->modifiers))
           {
              free(e);
              return;
           }
      }
 
- store_key:
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
    if (!e->window)
      {
         free(e);
         return;
      }
-   e->time = (double)msg->time / 1000.0;
+   e->event_window = e->window;
+   e->timestamp = msg->timestamp;
 
-   _ecore_win32_event_last_time = e->time;
+   _ecore_win32_event_last_time = e->timestamp;
 
-   ecore_event_add(ECORE_WIN32_EVENT_KEY_DOWN, e, _ecore_win32_event_free_key_down, NULL);
+   ecore_event_add(ECORE_EVENT_KEY_DOWN, e, _ecore_win32_event_free_key_down, NULL);
 }
 
 void
-_ecore_win32_event_handle_key_release(Ecore_Win32_Callback_Data *msg,
-                                      int                        is_keystroke)
+_ecore_win32_event_handle_key_release(Ecore_Win32_Callback_Data *msg)
 {
-   Ecore_Win32_Event_Key_Up *e;
+   Ecore_Event_Key *e;
+
+   INF("key released");
 
-   e = (Ecore_Win32_Event_Key_Up *)calloc(1, sizeof(Ecore_Win32_Event_Key_Up));
+   e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key));
    if (!e) return;
 
-   if (is_keystroke)
-     {
-        if (!_ecore_win32_event_keystroke_get(LOWORD(msg->window_param),
-                                              &e->keyname,
-                                              &e->keysymbol,
-                                              &e->keycompose))
-          {
-             free(e);
-             return;
-          }
-        goto store_key;
-     }
-   else
+   if (!_ecore_win32_event_keystroke_get(msg,
+                                         EINA_FALSE,
+                                         (char **)&e->keyname,
+                                         (char **)&e->key,
+                                         (char **)&e->string,
+                                         &e->modifiers))
      {
-        if (!_ecore_win32_event_char_get(LOWORD(msg->window_param),
-                                         &e->keyname,
-                                         &e->keysymbol,
-                                         &e->keycompose))
+        if (msg->discard_ctrl ||
+            !_ecore_win32_event_char_get(LOWORD(msg->window_param),
+                                         (char **)&e->keyname,
+                                         (char **)&e->key,
+                                         (char **)&e->string,
+                                         &e->modifiers))
           {
              free(e);
              return;
           }
      }
 
- store_key:
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
    if (!e->window)
      {
         free(e);
         return;
      }
-   e->time = (double)msg->time / 1000.0;
+   e->event_window = e->window;
+   e->timestamp = msg->timestamp;
 
-   _ecore_win32_event_last_time = e->time;
+   _ecore_win32_event_last_time = e->timestamp;
 
-   ecore_event_add(ECORE_WIN32_EVENT_KEY_UP, e, _ecore_win32_event_free_key_up, NULL);
+   ecore_event_add(ECORE_EVENT_KEY_UP, e, _ecore_win32_event_free_key_up, NULL);
 }
 
 void
@@ -148,74 +161,79 @@ _ecore_win32_event_handle_button_press(Ecore_Win32_Callback_Data *msg,
 {
    Ecore_Win32_Window *window;
 
-   window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   INF("mouse button pressed");
+
+   window = (Ecore_Win32_Window *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
 
    if (button > 3)
      {
-        Ecore_Win32_Event_Mouse_Wheel *e;
+        Ecore_Event_Mouse_Wheel *e;
 
-        e = (Ecore_Win32_Event_Mouse_Wheel *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Wheel));
+        e = (Ecore_Event_Mouse_Wheel *)calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
         if (!e) return;
 
-        e->window = window;
-       e->direction = 0;
+        e->window = (Ecore_Window)window;
+        e->event_window = e->window;
+        e->direction = 0;
         /* wheel delta is positive or negative, never 0 */
-       e->z = GET_WHEEL_DELTA_WPARAM(msg->window_param) > 0 ? -1 : 1;
-       e->x = GET_X_LPARAM(msg->data_param);
-       e->y = GET_Y_LPARAM(msg->data_param);
-        e->time = (double)msg->time / 1000.0;
+        e->z = GET_WHEEL_DELTA_WPARAM(msg->window_param) > 0 ? -1 : 1;
+        e->x = GET_X_LPARAM(msg->data_param);
+        e->y = GET_Y_LPARAM(msg->data_param);
+        e->timestamp = msg->timestamp;
 
-        _ecore_win32_event_last_time = e->time;
-        _ecore_win32_event_last_window = e->window;
+        _ecore_win32_event_last_time = e->timestamp;
+        _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
 
-        ecore_event_add(ECORE_WIN32_EVENT_MOUSE_WHEEL, e, NULL, NULL);
+        ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
      }
    else
      {
        {
-          Ecore_Win32_Event_Mouse_Move *e;
+          Ecore_Event_Mouse_Move *e;
 
-          e = (Ecore_Win32_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Move));
+          e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
           if (!e) return;
 
-          e->window = window;
+          e->window = (Ecore_Window)window;
+          e->event_window = e->window;
           e->x = GET_X_LPARAM(msg->data_param);
           e->y = GET_Y_LPARAM(msg->data_param);
-          e->time = (double)msg->time / 1000.0;
+          e->timestamp = msg->timestamp;
 
-          _ecore_win32_event_last_time = e->time;
-          _ecore_win32_event_last_window = e->window;
+          _ecore_win32_event_last_time = e->timestamp;
+          _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
 
-          ecore_event_add(ECORE_WIN32_EVENT_MOUSE_MOVE, e, NULL, NULL);
+          ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
        }
 
        {
-          Ecore_Win32_Event_Mouse_Button_Down *e;
+          Ecore_Event_Mouse_Button *e;
 
           if (_ecore_win32_mouse_down_did_triple)
             {
                _ecore_win32_mouse_down_last_window = NULL;
                _ecore_win32_mouse_down_last_last_window = NULL;
-               _ecore_win32_mouse_down_last_time = 0.0;
-               _ecore_win32_mouse_down_last_last_time = 0.0;
+               _ecore_win32_mouse_down_last_time = 0;
+               _ecore_win32_mouse_down_last_last_time = 0;
             }
 
-          e = (Ecore_Win32_Event_Mouse_Button_Down *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Button_Down));
+          e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button));
           if (!e) return;
 
-          e->window = window;
-          e->button = button;
+          e->window = (Ecore_Window)window;
+          e->event_window = e->window;
+          e->buttons = button;
           e->x = GET_X_LPARAM(msg->data_param);
           e->y = GET_Y_LPARAM(msg->data_param);
-          e->time = (double)msg->time / 1000.0;
+          e->timestamp = msg->timestamp;
 
-          if (((e->time - _ecore_win32_mouse_down_last_time) <= _ecore_win32_double_click_time) &&
-              (e->window == _ecore_win32_mouse_down_last_window))
+          if (((e->timestamp - _ecore_win32_mouse_down_last_time) <= (unsigned long)(1000 * _ecore_win32_double_click_time)) &&
+              (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window))
             e->double_click = 1;
 
-          if (((e->time - _ecore_win32_mouse_down_last_last_time) <= (2.0 * _ecore_win32_double_click_time)) &&
-              (e->window == _ecore_win32_mouse_down_last_window) &&
-              (e->window == _ecore_win32_mouse_down_last_last_window))
+          if (((e->timestamp - _ecore_win32_mouse_down_last_last_time) <= (unsigned long)(2 * 1000 * _ecore_win32_double_click_time)) &&
+              (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window) &&
+              (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_last_window))
             {
                e->triple_click = 1;
                _ecore_win32_mouse_down_did_triple = 1;
@@ -226,116 +244,123 @@ _ecore_win32_event_handle_button_press(Ecore_Win32_Callback_Data *msg,
           if (!e->double_click && !e->triple_click)
             _ecore_win32_mouse_up_count = 0;
 
-          _ecore_win32_event_last_time = e->time;
-          _ecore_win32_event_last_window = e->window;
+          _ecore_win32_event_last_time = e->timestamp;
+          _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
 
           if (!_ecore_win32_mouse_down_did_triple)
             {
                _ecore_win32_mouse_down_last_last_window = _ecore_win32_mouse_down_last_window;
-               _ecore_win32_mouse_down_last_window = e->window;
+               _ecore_win32_mouse_down_last_window = (Ecore_Win32_Window *)e->window;
                _ecore_win32_mouse_down_last_last_time = _ecore_win32_mouse_down_last_time;
-               _ecore_win32_mouse_down_last_time = e->time;
+               _ecore_win32_mouse_down_last_time = e->timestamp;
             }
 
-          ecore_event_add(ECORE_WIN32_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+          ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
        }
      }
-/*    printf (" * ecore event button press\n"); */
 }
 
 void
 _ecore_win32_event_handle_button_release(Ecore_Win32_Callback_Data *msg,
-                                         int                          button)
+                                         int                        button)
 {
    Ecore_Win32_Window *window;
 
-   window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   INF("mouse button released");
+
+   window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
 
    {
-      Ecore_Win32_Event_Mouse_Move *e;
+      Ecore_Event_Mouse_Move *e;
 
-      e = (Ecore_Win32_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Move));
+      e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
       if (!e) return;
 
-      e->window = window;
+      e->window = (Ecore_Window)window;
+      e->event_window = e->window;
       e->x = GET_X_LPARAM(msg->data_param);
       e->y = GET_Y_LPARAM(msg->data_param);
-      e->time = (double)msg->time / 1000.0;
+      e->timestamp = msg->timestamp;
 
-      _ecore_win32_event_last_time = e->time;
-      _ecore_win32_event_last_window = e->window;
+      _ecore_win32_event_last_time = e->timestamp;
+      _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
 
-      ecore_event_add(ECORE_WIN32_EVENT_MOUSE_MOVE, e, NULL, NULL);
+      ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
    }
 
    {
-      Ecore_Win32_Event_Mouse_Button_Up *e;
+      Ecore_Event_Mouse_Button *e;
 
-      e = (Ecore_Win32_Event_Mouse_Button_Up *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Button_Up));
+      e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button));
       if (!e) return;
 
-      e->window = window;
-      e->button = button;
+      e->window = (Ecore_Window)window;
+      e->event_window = e->window;
+      e->buttons = button;
       e->x = GET_X_LPARAM(msg->data_param);
       e->y = GET_Y_LPARAM(msg->data_param);
-      e->time = (double)msg->time / 1000.0;
+      e->timestamp = msg->timestamp;
 
       _ecore_win32_mouse_up_count++;
 
       if ((_ecore_win32_mouse_up_count >= 2) &&
-          ((e->time - _ecore_win32_mouse_down_last_time) <= _ecore_win32_double_click_time) &&
-          (e->window == _ecore_win32_mouse_down_last_window))
+          ((e->timestamp - _ecore_win32_mouse_down_last_time) <= (unsigned long)(1000 * _ecore_win32_double_click_time)) &&
+          (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window))
         e->double_click = 1;
 
       if ((_ecore_win32_mouse_up_count >= 3) &&
-          ((e->time - _ecore_win32_mouse_down_last_last_time) <= (2.0 * _ecore_win32_double_click_time)) &&
-          (e->window == _ecore_win32_mouse_down_last_window) &&
-          (e->window == _ecore_win32_mouse_down_last_last_window))
+          ((e->timestamp - _ecore_win32_mouse_down_last_last_time) <= (unsigned long)(2 * 1000 * _ecore_win32_double_click_time)) &&
+          (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_window) &&
+          (e->window == (Ecore_Window)_ecore_win32_mouse_down_last_last_window))
         e->triple_click = 1;
 
-      _ecore_win32_event_last_time = e->time;
-      _ecore_win32_event_last_window = e->window;
+      _ecore_win32_event_last_time = e->timestamp;
+      _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
 
-      ecore_event_add(ECORE_WIN32_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+      ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
    }
-
-/*    printf (" * ecore event button release\n"); */
 }
 
 void
 _ecore_win32_event_handle_motion_notify(Ecore_Win32_Callback_Data *msg)
 {
-   Ecore_Win32_Event_Mouse_Move *e;
+   Ecore_Event_Mouse_Move *e;
+
+   INF("mouse moved");
 
-   e = (Ecore_Win32_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Move));
+   e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
+   e->event_window = e->window;
    e->x = GET_X_LPARAM(msg->data_param);
    e->y = GET_Y_LPARAM(msg->data_param);
-   e->time = (double)msg->time / 1000.0;
+   e->timestamp = msg->timestamp;
 
-   ecore_event_add(ECORE_WIN32_EVENT_MOUSE_MOVE, e, NULL, NULL);
+   ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
 }
 
 void
 _ecore_win32_event_handle_enter_notify(Ecore_Win32_Callback_Data *msg)
 {
   {
-     Ecore_Win32_Event_Mouse_Move *e;
+     Ecore_Event_Mouse_Move *e;
+
+     INF("mouse in");
 
-     e = (Ecore_Win32_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Move));
+     e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
      if (!e) return;
 
-     e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+     e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
+     e->event_window = e->window;
      e->x = msg->x;
      e->y = msg->y;
-     e->time = (double)msg->time / 1000.0;
+     e->timestamp = msg->timestamp;
 
-     _ecore_win32_event_last_time = e->time;
-     _ecore_win32_event_last_window = e->window;
+     _ecore_win32_event_last_time = e->timestamp;
+     _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
 
-     ecore_event_add(ECORE_WIN32_EVENT_MOUSE_MOVE, e, NULL, NULL);
+     ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
   }
 
   {
@@ -344,12 +369,12 @@ _ecore_win32_event_handle_enter_notify(Ecore_Win32_Callback_Data *msg)
      e = (Ecore_Win32_Event_Mouse_In *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_In));
      if (!e) return;
 
-     e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+     e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
      e->x = msg->x;
      e->y = msg->y;
-     e->time = (double)msg->time / 1000.0;
+     e->timestamp = msg->timestamp ;
 
-     _ecore_win32_event_last_time = e->time;
+     _ecore_win32_event_last_time = e->timestamp;
 
      ecore_event_add(ECORE_WIN32_EVENT_MOUSE_IN, e, NULL, NULL);
   }
@@ -359,20 +384,23 @@ void
 _ecore_win32_event_handle_leave_notify(Ecore_Win32_Callback_Data *msg)
 {
   {
-     Ecore_Win32_Event_Mouse_Move *e;
+     Ecore_Event_Mouse_Move *e;
 
-     e = (Ecore_Win32_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Move));
+     INF("mouse out");
+
+     e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move));
      if (!e) return;
 
-     e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+     e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
+     e->event_window = e->window;
      e->x = msg->x;
      e->y = msg->y;
-     e->time = (double)msg->time / 1000.0;
+     e->timestamp = msg->timestamp;
 
-     _ecore_win32_event_last_time = e->time;
-     _ecore_win32_event_last_window = e->window;
+     _ecore_win32_event_last_time = e->timestamp;
+     _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window;
 
-     ecore_event_add(ECORE_WIN32_EVENT_MOUSE_MOVE, e, NULL, NULL);
+     ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
   }
 
   {
@@ -381,12 +409,12 @@ _ecore_win32_event_handle_leave_notify(Ecore_Win32_Callback_Data *msg)
      e = (Ecore_Win32_Event_Mouse_Out *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Out));
      if (!e) return;
 
-     e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+     e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
      e->x = msg->x;
      e->y = msg->y;
-     e->time = (double)msg->time / 1000.0;
+     e->timestamp = msg->timestamp;
 
-     _ecore_win32_event_last_time = e->time;
+     _ecore_win32_event_last_time = e->timestamp;
 
      ecore_event_add(ECORE_WIN32_EVENT_MOUSE_OUT, e, NULL, NULL);
   }
@@ -397,13 +425,15 @@ _ecore_win32_event_handle_focus_in(Ecore_Win32_Callback_Data *msg)
 {
    Ecore_Win32_Event_Window_Focus_In *e;
 
+   INF("focus in");
+
    e = (Ecore_Win32_Event_Window_Focus_In *)calloc(1, sizeof(Ecore_Win32_Event_Window_Focus_In));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
 
-   e->time = _ecore_win32_event_last_time;
-   _ecore_win32_event_last_time = e->time;
+   e->timestamp = _ecore_win32_event_last_time;
+   _ecore_win32_event_last_time = e->timestamp;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
 }
@@ -413,13 +443,15 @@ _ecore_win32_event_handle_focus_out(Ecore_Win32_Callback_Data *msg)
 {
    Ecore_Win32_Event_Window_Focus_Out *e;
 
+   INF("focus out");
+
    e = (Ecore_Win32_Event_Window_Focus_Out *)calloc(1, sizeof(Ecore_Win32_Event_Window_Focus_Out));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
 
-   e->time = _ecore_win32_event_last_time;
-   _ecore_win32_event_last_time = e->time;
+   e->timestamp = _ecore_win32_event_last_time;
+   _ecore_win32_event_last_time = e->timestamp;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
 }
@@ -429,18 +461,19 @@ _ecore_win32_event_handle_expose(Ecore_Win32_Callback_Data *msg)
 {
    Ecore_Win32_Event_Window_Damage *e;
 
+   INF("window expose");
+
    e = (Ecore_Win32_Event_Window_Damage *)calloc(1, sizeof(Ecore_Win32_Event_Window_Damage));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
 
    e->x = msg->update.left;
    e->y = msg->update.top;
    e->width = msg->update.right - msg->update.left;
    e->height = msg->update.bottom - msg->update.top;
-/*    printf (" * ecore : event expose %d %d\n", e->width, e->height); */
 
-   e->time = _ecore_win32_event_last_time;
+   e->timestamp = _ecore_win32_event_last_time;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
 }
@@ -450,12 +483,14 @@ _ecore_win32_event_handle_create_notify(Ecore_Win32_Callback_Data *msg)
 {
    Ecore_Win32_Event_Window_Create *e;
 
+   INF("window create notify");
+
    e = calloc(1, sizeof(Ecore_Win32_Event_Window_Create));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
 
-   e->time = _ecore_win32_event_last_time;
+   e->timestamp = _ecore_win32_event_last_time;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_CREATE, e, NULL, NULL);
 }
@@ -465,12 +500,14 @@ _ecore_win32_event_handle_destroy_notify(Ecore_Win32_Callback_Data *msg)
 {
    Ecore_Win32_Event_Window_Destroy *e;
 
+   INF("window destroy notify");
+
    e = calloc(1, sizeof(Ecore_Win32_Event_Window_Destroy));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
 
-   e->time = _ecore_win32_event_last_time;
+   e->timestamp = _ecore_win32_event_last_time;
    if (e->window == _ecore_win32_event_last_window) _ecore_win32_event_last_window = NULL;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DESTROY, e, NULL, NULL);
@@ -481,12 +518,14 @@ _ecore_win32_event_handle_map_notify(Ecore_Win32_Callback_Data *msg)
 {
    Ecore_Win32_Event_Window_Show *e;
 
+   INF("window map notify");
+
    e = calloc(1, sizeof(Ecore_Win32_Event_Window_Show));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
 
-   e->time = _ecore_win32_event_last_time;
+   e->timestamp = _ecore_win32_event_last_time;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_SHOW, e, NULL, NULL);
 }
@@ -496,12 +535,14 @@ _ecore_win32_event_handle_unmap_notify(Ecore_Win32_Callback_Data *msg)
 {
    Ecore_Win32_Event_Window_Hide *e;
 
+   INF("window unmap notify");
+
    e = calloc(1, sizeof(Ecore_Win32_Event_Window_Hide));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
 
-   e->time = _ecore_win32_event_last_time;
+   e->timestamp = _ecore_win32_event_last_time;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_HIDE, e, NULL, NULL);
 }
@@ -513,6 +554,8 @@ _ecore_win32_event_handle_configure_notify(Ecore_Win32_Callback_Data *msg)
    Ecore_Win32_Event_Window_Configure *e;
    WINDOWPOS                          *window_pos;
 
+   INF("window configure notify");
+
    e = calloc(1, sizeof(Ecore_Win32_Event_Window_Configure));
    if (!e) return;
 
@@ -524,14 +567,13 @@ _ecore_win32_event_handle_configure_notify(Ecore_Win32_Callback_Data *msg)
         return;
      }
 
-/*    printf ("_ecore_win32_event_handle_configure_notify\n"); */
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
-   e->abovewin = (void *)GetWindowLong(window_pos->hwndInsertAfter, GWL_USERDATA);
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
+   e->abovewin = (void *)GetWindowLongPtr(window_pos->hwndInsertAfter, GWLP_USERDATA);
    e->x = wi.rcClient.left;
    e->y = wi.rcClient.top;
    e->width = wi.rcClient.right - wi.rcClient.left;
    e->height = wi.rcClient.bottom - wi.rcClient.top;
-   e->time = _ecore_win32_event_last_time;
+   e->timestamp = _ecore_win32_event_last_time;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
 }
@@ -542,17 +584,18 @@ _ecore_win32_event_handle_resize(Ecore_Win32_Callback_Data *msg)
    RECT                             rect;
    Ecore_Win32_Event_Window_Resize *e;
 
+   INF("window resize");
+
    if (!GetClientRect(msg->window, &rect))
      return;
 
    e = calloc(1, sizeof(Ecore_Win32_Event_Window_Resize));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
    e->width = rect.right - rect.left;
    e->height = rect.bottom - rect.top;
-   e->time = _ecore_win32_event_last_time;
-/*    printf (" * _ecore_win32_event_handle_resize %d %d\n", e->width, e->height); */
+   e->timestamp = _ecore_win32_event_last_time;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_RESIZE, e, NULL, NULL);
 }
@@ -562,11 +605,13 @@ _ecore_win32_event_handle_delete_request(Ecore_Win32_Callback_Data *msg)
 {
    Ecore_Win32_Event_Window_Delete_Request *e;
 
+   INF("window delete request");
+
    e = calloc(1, sizeof(Ecore_Win32_Event_Window_Delete_Request));
    if (!e) return;
 
-   e->window = (void *)GetWindowLong(msg->window, GWL_USERDATA);
-   e->time = _ecore_win32_event_last_time;
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
+   e->timestamp = _ecore_win32_event_last_time;
 
    ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
 }
@@ -575,40 +620,51 @@ _ecore_win32_event_handle_delete_request(Ecore_Win32_Callback_Data *msg)
 /***** Private functions definitions *****/
 
 static void
-_ecore_win32_event_free_key_down(void *data,
+_ecore_win32_event_free_key_down(void *data __UNUSED__,
                                  void *ev)
 {
-   Ecore_Win32_Event_Key_Down *e;
+   Ecore_Event_Key *e;
 
    e = ev;
-   if (e->keyname) free(e->keyname);
-   if (e->keysymbol) free(e->keysymbol);
-   if (e->keycompose) free(e->keycompose);
+   if (e->keyname) free((char *)e->keyname);
+   if (e->key) free((char *)e->key);
+   if (e->string) free((char *)e->string);
    free(e);
 }
 
 static void
-_ecore_win32_event_free_key_up(void *data,
+_ecore_win32_event_free_key_up(void *data __UNUSED__,
                                void *ev)
 {
-   Ecore_Win32_Event_Key_Up *e;
+   Ecore_Event_Key *e;
 
    e = ev;
-   if (e->keyname) free(e->keyname);
-   if (e->keysymbol) free(e->keysymbol);
-   if (e->keycompose) free(e->keycompose);
+   if (e->keyname) free((char *)e->keyname);
+   if (e->key) free((char *)e->key);
+   if (e->string) free((char *)e->string);
    free(e);
 }
 
 static int
-_ecore_win32_event_keystroke_get(int    key,
-                                 char **keyname,
-                                 char **keysymbol,
-                                 char **keycompose)
+_ecore_win32_event_keystroke_get(Ecore_Win32_Callback_Data *msg,
+                                 Eina_Bool     is_down,
+                                 char        **keyname,
+                                 char        **keysymbol,
+                                 char        **keycompose,
+                                 unsigned int *modifiers)
 {
-  char *kn;
-  char *ks;
-  char *kc;
+  WCHAR buf[3];
+  char delete_string[2] = { 0x7f, 0 };
+  char *kn = NULL;
+  char *ks = NULL;
+  char *kc = NULL;
+  int key;
+  int is_extended;
+  int previous_key_state;
+
+  key = msg->window_param;
+  is_extended = msg->data_param & 0x01000000;
+  previous_key_state = msg->data_param & 0x40000000;
 
   *keyname = NULL;
   *keysymbol = NULL;
@@ -618,55 +674,337 @@ _ecore_win32_event_keystroke_get(int    key,
      {
        /* Keystroke */
      case VK_PRIOR:
-       kn = "KP_Prior";
-       ks = "KP_Prior";
-       kc = "";
+       if (is_extended)
+         {
+            kn = "Prior";
+            ks = "Prior";
+            kc = NULL;
+         }
+       else
+         {
+            kn = "KP_Prior";
+            ks = "KP_9";
+            kc = "KP_Prior";
+         }
        break;
      case VK_NEXT:
-       kn = "KP_Next";
-       ks = "KP_Next";
-       kc = "";
+       if (is_extended)
+         {
+            kn = "Next";
+            ks = "Next";
+            kc = NULL;
+         }
+       else
+         {
+            kn = "KP_Next";
+            ks = "KP_3";
+            kc = "KP_Next";
+         }
        break;
      case VK_END:
-       kn = "KP_End";
-       ks = "KP_End";
-       kc = "";
+       if (is_extended)
+         {
+            kn = "End";
+            ks = "End";
+            kc = NULL;
+         }
+       else
+         {
+            kn = "KP_End";
+            ks = "KP_1";
+            kc = "KP_End";
+         }
        break;
      case VK_HOME:
-       kn = "KP_Home";
-       ks = "KP_Home";
-       kc = "";
+       if (is_extended)
+         {
+            kn = "Home";
+            ks = "Home";
+            kc = NULL;
+         }
+       else
+         {
+            kn = "KP_Home";
+            ks = "KP_7";
+            kc = "KP_Home";
+         }
        break;
      case VK_LEFT:
-       kn = "KP_Left";
-       ks = "KP_Left";
-       kc = "";
+       if (is_extended)
+         {
+            kn = "Left";
+            ks = "Left";
+            kc = NULL;
+         }
+       else
+         {
+            kn = "KP_Left";
+            ks = "KP_4";
+            kc = "KP_Left";
+         }
        break;
      case VK_UP:
-       kn = "KP_Up";
-       ks = "KP_Up";
-       kc = "";
+       if (is_extended)
+         {
+            kn = "Up";
+            ks = "Up";
+            kc = NULL;
+         }
+       else
+         {
+            kn = "KP_Up";
+            ks = "KP_8";
+            kc = "KP_Up";
+         }
        break;
      case VK_RIGHT:
-       kn = "KP_Right";
-       ks = "KP_Right";
-       kc = "";
+       if (is_extended)
+         {
+           kn = "Right";
+           ks = "Right";
+           kc = NULL;
+         }
+       else
+         {
+           kn = "KP_Right";
+           ks = "KP_6";
+           kc = "KP_Right";
+         }
        break;
      case VK_DOWN:
-       kn = "KP_Down";
-       ks = "KP_Down";
-       kc = "";
+       if (is_extended)
+         {
+           kn = "Down";
+           ks = "Down";
+           kc = NULL;
+         }
+       else
+         {
+           kn = "KP_Down";
+           ks = "KP_2";
+           kc = "KP_Down";
+         }
        break;
      case VK_INSERT:
-       kn = "KP_Insert";
-       ks = "KP_Insert";
-       kc = "";
+       if (is_extended)
+         {
+           kn = "Insert";
+           ks = "Insert";
+           kc = NULL;
+         }
+       else
+         {
+           kn = "KP_Insert";
+           ks = "KP_0";
+           kc = "KP_Insert";
+         }
        break;
      case VK_DELETE:
-       kn = "KP_Delete";
-       ks = "KP_Delete";
-       kc = "";
+       if (is_extended)
+         {
+           kn = "Delete";
+           ks = "Delete";
+           kc = delete_string;
+         }
+       else
+         {
+           kn = "KP_Delete";
+           ks = "KP_Decimal";
+           kc = "KP_Delete";
+         }
        break;
+     case VK_SHIFT:
+       {
+          SHORT res;
+
+          if (is_down)
+            {
+               if (previous_key_state) return 0;
+               res = GetKeyState(VK_LSHIFT);
+               if (res & 0x8000)
+                 {
+                    _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LSHIFT;
+                    kn = "Shift_L";
+                    ks = "Shift_L";
+                    kc = "";
+                 }
+               res = GetKeyState(VK_RSHIFT);
+               if (res & 0x8000)
+                 {
+                    _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RSHIFT;
+                    kn = "Shift_R";
+                    ks = "Shift_R";
+                    kc = "";
+                 }
+               *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT;
+            }
+          else /* is_up */
+            {
+               res = GetKeyState(VK_LSHIFT);
+               if (!(res & 0x8000) &&
+                   (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LSHIFT))
+                 {
+                    kn = "Shift_L";
+                    ks = "Shift_L";
+                    kc = "";
+                    _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LSHIFT;
+                 }
+               res = GetKeyState(VK_RSHIFT);
+               if (!(res & 0x8000) &&
+                   (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RSHIFT))
+                 {
+                    kn = "Shift_R";
+                    ks = "Shift_R";
+                    kc = "";
+                    _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RSHIFT;
+                 }
+               *modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+            }
+          break;
+       }
+     case VK_CONTROL:
+       {
+          SHORT res;
+
+          if (msg->discard_ctrl)
+            return 0;
+
+          if (is_down)
+            {
+               if (previous_key_state) return 0;
+               res = GetKeyState(VK_LCONTROL);
+               if (res & 0x8000)
+                 {
+                    _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LCONTROL;
+                    kn = "Control_L";
+                    ks = "Control_L";
+                    kc = "";
+                    break;
+                 }
+               res = GetKeyState(VK_RCONTROL);
+               if (res & 0x8000)
+                 {
+                    _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RCONTROL;
+                    kn = "Control_R";
+                    ks = "Control_R";
+                    kc = "";
+                    break;
+                 }
+               *modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+            }
+          else /* is_up */
+            {
+               res = GetKeyState(VK_LCONTROL);
+               if (!(res & 0x8000) &&
+                   (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LCONTROL))
+                 {
+                    kn = "Control_L";
+                    ks = "Control_L";
+                    kc = "";
+                    _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LCONTROL;
+                    break;
+                 }
+               res = GetKeyState(VK_RCONTROL);
+               if (!(res & 0x8000) &&
+                   (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RCONTROL))
+                 {
+                    kn = "Control_R";
+                    ks = "Control_R";
+                    kc = "";
+                    _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RCONTROL;
+                    break;
+                 }
+               *modifiers &= ~ECORE_EVENT_MODIFIER_CTRL;
+            }
+          break;
+       }
+     case VK_MENU:
+       {
+          SHORT res;
+
+          if (is_down)
+            {
+               if (previous_key_state) return 0;
+               res = GetKeyState(VK_LMENU);
+               if (res & 0x8000)
+                 {
+                    _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LMENU;
+                    kn = "Alt_L";
+                    ks = "Alt_L";
+                    kc = "";
+                 }
+               res = GetKeyState(VK_RMENU);
+               if (res & 0x8000)
+                 {
+                    _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RMENU;
+                    kn = "Alt_R";
+                    ks = "Alt_R";
+                    kc = "";
+                 }
+               *modifiers |= ECORE_EVENT_MODIFIER_ALT;
+            }
+          else /* is_up */
+            {
+               res = GetKeyState(VK_LMENU);
+               if (!(res & 0x8000) &&
+                   (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LMENU))
+                 {
+                    kn = "Alt_L";
+                    ks = "Alt_L";
+                    kc = "";
+                    _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LMENU;
+                 }
+               res = GetKeyState(VK_RMENU);
+               if (!(res & 0x8000) &&
+                   (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RMENU))
+                 {
+                    kn = "Alt_R";
+                    ks = "Alt_R";
+                    kc = "";
+                    _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RMENU;
+                 }
+               *modifiers &= ~ECORE_EVENT_MODIFIER_ALT;
+            }
+          break;
+       }
+     case VK_LWIN:
+       {
+          if (is_down)
+            {
+               if (previous_key_state) return 0;
+               kn = "Super_L";
+               ks = "Super_L";
+               kc = "";
+               *modifiers |= ECORE_EVENT_MODIFIER_WIN;
+            }
+          else /* is_up */
+            {
+               kn = "Super_L";
+               ks = "Super_L";
+               kc = "";
+               *modifiers &= ~ECORE_EVENT_MODIFIER_WIN;
+            }
+          break;
+       }
+     case VK_RWIN:
+       {
+          if (is_down)
+            {
+               if (previous_key_state) return 0;
+               kn = "Super_R";
+               ks = "Super_R";
+               kc = "";
+               *modifiers |= ECORE_EVENT_MODIFIER_WIN;
+            }
+          else /* is_up */
+            {
+               kn = "Super_R";
+               ks = "Super_R";
+               kc = "";
+               *modifiers &= ~ECORE_EVENT_MODIFIER_WIN;
+            }
+          break;
+       }
      case VK_F1:
        kn = "F1";
        ks = "F1";
@@ -788,9 +1126,53 @@ _ecore_win32_event_keystroke_get(int    key,
        kc = "";
        break;
      default:
-       /* other non keystroke characters */
-       return 0;
+       {
+          /* other non keystroke characters */
+          BYTE kbd_state[256];
+          int res;
+
+          if (is_down)
+            return 0;
+
+          if (!GetKeyboardState(kbd_state))
+            return 0;
+
+           res = ToUnicode(msg->window_param,
+                           MapVirtualKey(msg->window_param, 2),
+                           kbd_state, buf, 3, 0);
+           if (res == 1)
+             {
+               /* FIXME: might be troublesome for non european languages */
+               /* in that case, UNICODE should be used, I guess */
+               buf[1] = '\0';
+               kn = (char *)buf;
+               ks = (char *)buf;
+               kc = (char *)buf;
+
+               res = GetAsyncKeyState(VK_SHIFT);
+               if (res & 0x8000)
+                 *modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+               else
+                 *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT;
+
+               res = GetKeyState(VK_CONTROL);
+               if (res & 0x8000)
+                 *modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+               else
+                 *modifiers &= ~ECORE_EVENT_MODIFIER_CTRL;
+
+               res = GetKeyState(VK_MENU);
+               if (res & 0x8000)
+                 *modifiers |= ECORE_EVENT_MODIFIER_ALT;
+               else
+                 *modifiers &= ~ECORE_EVENT_MODIFIER_ALT;
+
+               break;
+             }
+           return 0;
+         }
      }
+
    *keyname = strdup(kn);
    if (!*keyname) return 0;
    *keysymbol = strdup(ks);
@@ -800,69 +1182,88 @@ _ecore_win32_event_keystroke_get(int    key,
         *keyname = NULL;
         return 0;
      }
-   *keycompose = strdup(kc);
-   if (!*keycompose)
+   if (!kc)
+     *keycompose = NULL;
+   else
      {
-        free(*keyname);
-        free(*keysymbol);
-        *keyname = NULL;
-        *keysymbol = NULL;
-        return 0;
+        *keycompose = strdup(kc);
+        if (!*keycompose)
+          {
+             free(*keyname);
+             free(*keysymbol);
+             *keyname = NULL;
+             *keysymbol = NULL;
+             return 0;
+          }
      }
 
    return 1;
 }
 
 static int
-_ecore_win32_event_char_get(int    key,
-                            char **keyname,
-                            char **keysymbol,
-                            char **keycompose)
+_ecore_win32_event_char_get(int           key,
+                            char        **keyname,
+                            char        **keysymbol,
+                            char        **keycompose,
+                            unsigned int *modifiers)
 {
-  char kn[32];
-  char ks[32];
-  char *kc;
+  char *kn = NULL;
+  char *ks = NULL;
+  char *kc = NULL;
+  char buf[2];
+  SHORT res;
 
   *keyname = NULL;
   *keysymbol = NULL;
   *keycompose = NULL;
 
+   /* check control charaters such as ^a(key:1), ^z(key:26) */
+   if ((key > 0) && (key < 27) &&
+       ((GetKeyState(VK_CONTROL) & 0x8000) ||
+        (GetKeyState(VK_CONTROL) & 0x8000))) key += 96;
+
    switch (key)
      {
+     case VK_PROCESSKEY:
+      break;
      case VK_BACK:
-       strncpy(kn, "Backspace", 32);
-       strncpy(ks, "Backspace", 32);
-       kc = "";
+       kn = "BackSpace";
+       ks = "BackSpace";
+       kc = "\b";
        break;
      case VK_TAB:
-       strncpy(kn, "Tab", 32);
-       strncpy(ks, "Tab", 32);
-       kc = "";
+       kn = "Tab";
+       ks = "Tab";
+       kc = "\t";
        break;
      case 0x0a:
        /* Line feed (Shift + Enter) */
-       strncpy(kn, "LineFeed", 32);
-       strncpy(ks, "LineFeed", 32);
-       kc = "";
+       kn = "LineFeed";
+       ks = "LineFeed";
+       kc = "LineFeed";
        break;
      case VK_RETURN:
-       strncpy(kn, "Return", 32);
-       strncpy(ks, "Return", 32);
-       kc = "";
+       kn = "Return";
+       ks = "Return";
+       kc = "\n";
        break;
      case VK_ESCAPE:
-       strncpy(kn, "Escape", 32);
-       strncpy(ks, "Escape", 32);
-       kc = "";
+       kn = "Escape";
+       ks = "Escape";
+       kc = "\e";
+       break;
+     case VK_SPACE:
+       kn = "space";
+       ks = "space";
+       kc = " ";
        break;
      default:
        /* displayable characters */
-       printf (" * key : %d\n", key);
-       kn[0] = (TCHAR)key;
-       kn[1] = '\0';
-       ks[0] = (TCHAR)key;
-       ks[1] = '\0';
-       kc = "";
+       buf[0] = key;
+       buf[1] = '\0';
+       kn = buf;
+       ks = buf;
+       kc = buf;
        break;
      }
    *keyname = strdup(kn);
@@ -884,5 +1285,23 @@ _ecore_win32_event_char_get(int    key,
         return 0;
      }
 
+   res = GetAsyncKeyState(VK_SHIFT);
+   if (res & 0x8000)
+     *modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+   else
+     *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT;
+
+   res = GetKeyState(VK_CONTROL);
+   if (res & 0x8000)
+     *modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+   else
+     *modifiers &= ~ECORE_EVENT_MODIFIER_CTRL;
+
+   res = GetKeyState(VK_MENU);
+   if (res & 0x8000)
+     *modifiers |= ECORE_EVENT_MODIFIER_ALT;
+   else
+     *modifiers &= ~ECORE_EVENT_MODIFIER_ALT;
+
    return 1;
 }