#ifdef HAVE_CONFIG_H # include #endif #include #include /* for printf */ #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN #include #include #include #include #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 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); static void _ecore_win32_event_free_key_up(void *data, void *ev); 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, unsigned int *modifiers); /***** Global functions definitions *****/ void _ecore_win32_event_handle_key_press(Ecore_Win32_Callback_Data *msg, int is_keystroke) { Ecore_Event_Key *e; 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(msg, EINA_TRUE, (char **)&e->keyname, (char **)&e->key, (char **)&e->string, &e->modifiers)) { free(e); return; } } else { if (!_ecore_win32_event_char_get(LOWORD(msg->window_param), (char **)&e->keyname, (char **)&e->key, (char **)&e->string, &e->modifiers)) { free(e); return; } } e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA); if (!e->window) { free(e); return; } e->event_window = e->window; e->timestamp = msg->timestamp; _ecore_win32_event_last_time = e->timestamp; 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) { Ecore_Event_Key *e; INF("key released"); e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key)); if (!e) return; if (!_ecore_win32_event_keystroke_get(msg, EINA_FALSE, (char **)&e->keyname, (char **)&e->key, (char **)&e->string, &e->modifiers)) { 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; } } e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA); if (!e->window) { free(e); return; } e->event_window = e->window; e->timestamp = msg->timestamp; _ecore_win32_event_last_time = e->timestamp; ecore_event_add(ECORE_EVENT_KEY_UP, e, _ecore_win32_event_free_key_up, NULL); } void _ecore_win32_event_handle_button_press(Ecore_Win32_Callback_Data *msg, int button) { Ecore_Win32_Window *window; INF("mouse button pressed"); window = (Ecore_Win32_Window *)GetWindowLongPtr(msg->window, GWLP_USERDATA); if (button > 3) { Ecore_Event_Mouse_Wheel *e; e = (Ecore_Event_Mouse_Wheel *)calloc(1, sizeof(Ecore_Event_Mouse_Wheel)); if (!e) return; 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->timestamp = msg->timestamp; _ecore_win32_event_last_time = e->timestamp; _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window; ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL); } else { { Ecore_Event_Mouse_Move *e; e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move)); if (!e) return; 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->timestamp = msg->timestamp; _ecore_win32_event_last_time = e->timestamp; _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window; ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); } { 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; _ecore_win32_mouse_down_last_last_time = 0; } e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button)); if (!e) return; 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->timestamp = msg->timestamp; 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->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; } else _ecore_win32_mouse_down_did_triple = 0; if (!e->double_click && !e->triple_click) _ecore_win32_mouse_up_count = 0; _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 = (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->timestamp; } ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); } } } void _ecore_win32_event_handle_button_release(Ecore_Win32_Callback_Data *msg, int button) { Ecore_Win32_Window *window; INF("mouse button released"); window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA); { Ecore_Event_Mouse_Move *e; e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move)); if (!e) return; 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->timestamp = msg->timestamp; _ecore_win32_event_last_time = e->timestamp; _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window; ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); } { Ecore_Event_Mouse_Button *e; e = (Ecore_Event_Mouse_Button *)calloc(1, sizeof(Ecore_Event_Mouse_Button)); if (!e) return; 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->timestamp = msg->timestamp; _ecore_win32_mouse_up_count++; if ((_ecore_win32_mouse_up_count >= 2) && ((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->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->timestamp; _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window; ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL); } } void _ecore_win32_event_handle_motion_notify(Ecore_Win32_Callback_Data *msg) { Ecore_Event_Mouse_Move *e; INF("mouse moved"); e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move)); if (!e) return; 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->timestamp = msg->timestamp; ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); } void _ecore_win32_event_handle_enter_notify(Ecore_Win32_Callback_Data *msg) { { Ecore_Event_Mouse_Move *e; INF("mouse in"); e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move)); if (!e) return; e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA); e->event_window = e->window; e->x = msg->x; e->y = msg->y; e->timestamp = msg->timestamp; _ecore_win32_event_last_time = e->timestamp; _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window; ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); } { Ecore_Win32_Event_Mouse_In *e; e = (Ecore_Win32_Event_Mouse_In *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_In)); if (!e) return; e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA); e->x = msg->x; e->y = msg->y; e->timestamp = msg->timestamp ; _ecore_win32_event_last_time = e->timestamp; ecore_event_add(ECORE_WIN32_EVENT_MOUSE_IN, e, NULL, NULL); } } void _ecore_win32_event_handle_leave_notify(Ecore_Win32_Callback_Data *msg) { { Ecore_Event_Mouse_Move *e; INF("mouse out"); e = (Ecore_Event_Mouse_Move *)calloc(1, sizeof(Ecore_Event_Mouse_Move)); if (!e) return; e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA); e->event_window = e->window; e->x = msg->x; e->y = msg->y; e->timestamp = msg->timestamp; _ecore_win32_event_last_time = e->timestamp; _ecore_win32_event_last_window = (Ecore_Win32_Window *)e->window; ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); } { Ecore_Win32_Event_Mouse_Out *e; e = (Ecore_Win32_Event_Mouse_Out *)calloc(1, sizeof(Ecore_Win32_Event_Mouse_Out)); if (!e) return; e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA); e->x = msg->x; e->y = msg->y; e->timestamp = msg->timestamp; _ecore_win32_event_last_time = e->timestamp; ecore_event_add(ECORE_WIN32_EVENT_MOUSE_OUT, e, NULL, NULL); } } void _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); 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); } void _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); 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); } void _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 *)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; e->timestamp = _ecore_win32_event_last_time; ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DAMAGE, e, NULL, NULL); } void _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); e->timestamp = _ecore_win32_event_last_time; ecore_event_add(ECORE_WIN32_EVENT_WINDOW_CREATE, e, NULL, NULL); } void _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); 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); } void _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); e->timestamp = _ecore_win32_event_last_time; ecore_event_add(ECORE_WIN32_EVENT_WINDOW_SHOW, e, NULL, NULL); } void _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); e->timestamp = _ecore_win32_event_last_time; ecore_event_add(ECORE_WIN32_EVENT_WINDOW_HIDE, e, NULL, NULL); } void _ecore_win32_event_handle_configure_notify(Ecore_Win32_Callback_Data *msg) { WINDOWINFO wi; 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; window_pos = (WINDOWPOS *)msg->data_param; wi.cbSize = sizeof(WINDOWINFO); if (!GetWindowInfo(window_pos->hwnd, &wi)) { free(e); return; } 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->timestamp = _ecore_win32_event_last_time; ecore_event_add(ECORE_WIN32_EVENT_WINDOW_CONFIGURE, e, NULL, NULL); } void _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); e->width = rect.right - rect.left; e->height = rect.bottom - rect.top; e->timestamp = _ecore_win32_event_last_time; ecore_event_add(ECORE_WIN32_EVENT_WINDOW_RESIZE, e, NULL, NULL); } void _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); e->timestamp = _ecore_win32_event_last_time; ecore_event_add(ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL); } /***** Private functions definitions *****/ static void _ecore_win32_event_free_key_down(void *data EINA_UNUSED, void *ev) { Ecore_Event_Key *e; e = ev; 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 EINA_UNUSED, void *ev) { Ecore_Event_Key *e; e = ev; 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(Ecore_Win32_Callback_Data *msg, Eina_Bool is_down, char **keyname, char **keysymbol, char **keycompose, unsigned int *modifiers) { 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; *keycompose = NULL; switch (key) { /* Keystroke */ case VK_PRIOR: if (is_extended) { kn = "Prior"; ks = "Prior"; kc = NULL; } else { kn = "KP_Prior"; ks = "KP_9"; kc = "KP_Prior"; } break; case VK_NEXT: if (is_extended) { kn = "Next"; ks = "Next"; kc = NULL; } else { kn = "KP_Next"; ks = "KP_3"; kc = "KP_Next"; } break; case VK_END: if (is_extended) { kn = "End"; ks = "End"; kc = NULL; } else { kn = "KP_End"; ks = "KP_1"; kc = "KP_End"; } break; case VK_HOME: if (is_extended) { kn = "Home"; ks = "Home"; kc = NULL; } else { kn = "KP_Home"; ks = "KP_7"; kc = "KP_Home"; } break; case VK_LEFT: if (is_extended) { kn = "Left"; ks = "Left"; kc = NULL; } else { kn = "KP_Left"; ks = "KP_4"; kc = "KP_Left"; } break; case VK_UP: if (is_extended) { kn = "Up"; ks = "Up"; kc = NULL; } else { kn = "KP_Up"; ks = "KP_8"; kc = "KP_Up"; } break; case VK_RIGHT: if (is_extended) { kn = "Right"; ks = "Right"; kc = NULL; } else { kn = "KP_Right"; ks = "KP_6"; kc = "KP_Right"; } break; case VK_DOWN: if (is_extended) { kn = "Down"; ks = "Down"; kc = NULL; } else { kn = "KP_Down"; ks = "KP_2"; kc = "KP_Down"; } break; case VK_INSERT: if (is_extended) { kn = "Insert"; ks = "Insert"; kc = NULL; } else { kn = "KP_Insert"; ks = "KP_0"; kc = "KP_Insert"; } break; case VK_DELETE: 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"; kc = ""; break; case VK_F2: kn = "F2"; ks = "F2"; kc = ""; break; case VK_F3: kn = "F3"; ks = "F3"; kc = ""; break; case VK_F4: kn = "F4"; ks = "F4"; kc = ""; break; case VK_F5: kn = "F5"; ks = "F5"; kc = ""; break; case VK_F6: kn = "F6"; ks = "F6"; kc = ""; break; case VK_F7: kn = "F7"; ks = "F7"; kc = ""; break; case VK_F8: kn = "F8"; ks = "F8"; kc = ""; break; case VK_F9: kn = "F9"; ks = "F9"; kc = ""; break; case VK_F10: kn = "F10"; ks = "F10"; kc = ""; break; case VK_F11: kn = "F11"; ks = "F11"; kc = ""; break; case VK_F12: kn = "F12"; ks = "F12"; kc = ""; break; case VK_F13: kn = "F13"; ks = "F13"; kc = ""; break; case VK_F14: kn = "F14"; ks = "F14"; kc = ""; break; case VK_F15: kn = "F15"; ks = "F15"; kc = ""; break; case VK_F16: kn = "F16"; ks = "F16"; kc = ""; break; case VK_F17: kn = "F17"; ks = "F17"; kc = ""; break; case VK_F18: kn = "F18"; ks = "F18"; kc = ""; break; case VK_F19: kn = "F19"; ks = "F19"; kc = ""; break; case VK_F20: kn = "F20"; ks = "F20"; kc = ""; break; case VK_F21: kn = "F21"; ks = "F21"; kc = ""; break; case VK_F22: kn = "F22"; ks = "F22"; kc = ""; break; case VK_F23: kn = "F23"; ks = "F23"; kc = ""; break; case VK_F24: kn = "F24"; ks = "F24"; kc = ""; break; default: { /* 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); if (!*keysymbol) { free(*keyname); *keyname = NULL; return 0; } if (!kc) *keycompose = NULL; else { *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, unsigned int *modifiers) { 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: kn = "BackSpace"; ks = "BackSpace"; kc = "\b"; break; case VK_TAB: kn = "Tab"; ks = "Tab"; kc = "\t"; break; case 0x0a: /* Line feed (Shift + Enter) */ kn = "LineFeed"; ks = "LineFeed"; kc = "LineFeed"; break; case VK_RETURN: kn = "Return"; ks = "Return"; kc = "\n"; break; case VK_ESCAPE: kn = "Escape"; ks = "Escape"; kc = "\e"; break; case VK_SPACE: kn = "space"; ks = "space"; kc = " "; break; default: /* displayable characters */ buf[0] = key; buf[1] = '\0'; kn = buf; ks = buf; kc = buf; break; } *keyname = strdup(kn); if (!*keyname) return 0; *keysymbol = strdup(ks); if (!*keysymbol) { free(*keyname); *keyname = NULL; return 0; } *keycompose = strdup(kc); if (!*keycompose) { free(*keyname); free(*keysymbol); *keyname = NULL; *keysymbol = NULL; 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; }