2069 lines
62 KiB
C
2069 lines
62 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#undef WIN32_LEAN_AND_MEAN
|
|
#include <windowsx.h>
|
|
|
|
#include <evil_private.h> /* evil_utf16_to_utf8() */
|
|
#include <Eina.h>
|
|
#include <Ecore.h>
|
|
#include <Ecore_Input.h>
|
|
|
|
#include "Ecore_Win32.h"
|
|
#include "ecore_win32_private.h"
|
|
#include "ecore_win32_keysym_table.h"
|
|
|
|
#define ECORE_WIN32_VK_IS_EXTENDED(p) ((HIWORD(p) & KF_EXTENDED) == KF_EXTENDED)
|
|
#define ECORE_WIN32_VK_IS_REPEATED(p) ((HIWORD(p) & KF_REPEAT) == KF_REPEAT)
|
|
#define ECORE_WIN32_VK_IS_PRESSED(vk) ((GetKeyState(vk) & KF_UP) == KF_UP)
|
|
#define ECORE_WIN32_VK_IS_TOGGLED(vk) ((GetKeyState(vk) & 0x0001) == 0x0001)
|
|
|
|
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;
|
|
|
|
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 Eina_Bool _ecore_win32_ctrl_fake = EINA_FALSE;
|
|
static Eina_Bool _ecore_win32_clipboard_has_data = EINA_FALSE;
|
|
|
|
static unsigned int
|
|
_ecore_win32_modifiers_get(void)
|
|
{
|
|
unsigned int modifiers = 0;
|
|
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_SHIFT))
|
|
modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
|
|
|
|
if (_ecore_win32_ctrl_fake && !ECORE_WIN32_VK_IS_PRESSED(VK_RMENU))
|
|
{
|
|
_ecore_win32_ctrl_fake = EINA_FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_CONTROL))
|
|
modifiers |= ECORE_EVENT_MODIFIER_CTRL;
|
|
}
|
|
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_LMENU))
|
|
modifiers |= ECORE_EVENT_MODIFIER_ALT;
|
|
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_RMENU))
|
|
modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
|
|
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_LWIN))
|
|
modifiers |= ECORE_EVENT_MODIFIER_WIN;
|
|
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_RWIN))
|
|
modifiers |= ECORE_EVENT_MODIFIER_WIN;
|
|
|
|
if (ECORE_WIN32_VK_IS_TOGGLED(VK_SCROLL))
|
|
modifiers |= ECORE_EVENT_LOCK_SCROLL;
|
|
|
|
if (ECORE_WIN32_VK_IS_TOGGLED(VK_NUMLOCK))
|
|
modifiers |= ECORE_EVENT_LOCK_NUM;
|
|
|
|
if (ECORE_WIN32_VK_IS_TOGGLED(VK_CAPITAL))
|
|
modifiers |= ECORE_EVENT_LOCK_CAPS;
|
|
|
|
return modifiers;
|
|
}
|
|
|
|
static void
|
|
_ecore_win32_modifiers_alt_save(BYTE *kbd_state, unsigned short *modifiers)
|
|
{
|
|
if (kbd_state[VK_LMENU] & 128)
|
|
{
|
|
*modifiers |= 1 << 0;
|
|
kbd_state[VK_LMENU] &= ~128;
|
|
}
|
|
if (kbd_state[VK_RMENU] & 128)
|
|
{
|
|
*modifiers |= 1 << 1;
|
|
kbd_state[VK_RMENU] &= ~128;
|
|
}
|
|
if (kbd_state[VK_MENU] & 128)
|
|
{
|
|
*modifiers |= 1 << 2;
|
|
kbd_state[VK_MENU] &= ~128;
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ecore_win32_modifiers_alt_restore(BYTE *kbd_state, unsigned short modifiers)
|
|
{
|
|
if ((modifiers & (1 << 0)) == (1 << 0))
|
|
kbd_state[VK_LMENU] |= 128;
|
|
if ((modifiers & (1 << 1)) == (1 << 1))
|
|
kbd_state[VK_RMENU] |= 128;
|
|
if ((modifiers & (1 << 2)) == (1 << 2))
|
|
kbd_state[VK_MENU] |= 128;
|
|
}
|
|
|
|
static void
|
|
_ecore_win32_modifiers_ctrl_save(BYTE *kbd_state, unsigned short *modifiers)
|
|
{
|
|
if (kbd_state[VK_LCONTROL] & 128)
|
|
{
|
|
*modifiers |= 1 << 3;
|
|
kbd_state[VK_LCONTROL] &= ~128;
|
|
}
|
|
if (kbd_state[VK_RCONTROL] & 128)
|
|
{
|
|
*modifiers |= 1 << 4;
|
|
kbd_state[VK_RCONTROL] &= ~128;
|
|
}
|
|
if (kbd_state[VK_CONTROL] & 128)
|
|
{
|
|
*modifiers |= 1 << 5;
|
|
kbd_state[VK_CONTROL] &= ~128;
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ecore_win32_modifiers_ctrl_restore(BYTE *kbd_state, unsigned short modifiers)
|
|
{
|
|
if ((modifiers & (1 << 3)) == (1 << 3))
|
|
kbd_state[VK_LCONTROL] |= 128;
|
|
if ((modifiers & (1 << 4)) == (1 << 4))
|
|
kbd_state[VK_RCONTROL] |= 128;
|
|
if ((modifiers & (1 << 5)) == (1 << 5))
|
|
kbd_state[VK_CONTROL] |= 128;
|
|
}
|
|
|
|
static void
|
|
_ecore_win32_modifiers_shift_save(BYTE *kbd_state, unsigned short *modifiers)
|
|
{
|
|
if (kbd_state[VK_LSHIFT] & 128)
|
|
{
|
|
*modifiers |= 1 << 6;
|
|
kbd_state[VK_LSHIFT] &= ~128;
|
|
}
|
|
if (kbd_state[VK_RSHIFT] & 128)
|
|
{
|
|
*modifiers |= 1 << 7;
|
|
kbd_state[VK_RSHIFT] &= ~128;
|
|
}
|
|
if (kbd_state[VK_SHIFT] & 128)
|
|
{
|
|
*modifiers |= 1 << 8;
|
|
kbd_state[VK_SHIFT] &= ~128;
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ecore_win32_modifiers_shift_restore(BYTE *kbd_state, unsigned short modifiers)
|
|
{
|
|
if ((modifiers & (1 << 6)) == (1 << 6))
|
|
kbd_state[VK_LSHIFT] |= 128;
|
|
if ((modifiers & (1 << 7)) == (1 << 7))
|
|
kbd_state[VK_RSHIFT] |= 128;
|
|
if ((modifiers & (1 << 8)) == (1 << 8))
|
|
kbd_state[VK_SHIFT] |= 128;
|
|
}
|
|
|
|
static void
|
|
_ecore_win32_modifiers_win_save(BYTE *kbd_state, unsigned short *modifiers)
|
|
{
|
|
if (kbd_state[VK_LWIN] & 128)
|
|
{
|
|
*modifiers |= 1 << 9;
|
|
kbd_state[VK_LWIN] &= ~128;
|
|
}
|
|
if (kbd_state[VK_RWIN] & 128)
|
|
{
|
|
*modifiers |= 1 << 10;
|
|
kbd_state[VK_RWIN] &= ~128;
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ecore_win32_modifiers_win_restore(BYTE *kbd_state, unsigned short modifiers)
|
|
{
|
|
if ((modifiers & (1 << 9)) == (1 << 9))
|
|
kbd_state[VK_LWIN] |= 128;
|
|
if ((modifiers & (1 << 10)) == (1 << 10))
|
|
kbd_state[VK_RWIN] |= 128;
|
|
}
|
|
|
|
static uint32_t
|
|
_ecore_win32_keysym_offset_get(uint32_t keysym)
|
|
{
|
|
uint32_t start;
|
|
uint32_t end;
|
|
|
|
/*
|
|
* statistically, there are more chance to press a key with
|
|
* keysym between 0 and 255
|
|
*/
|
|
if (keysym < 256)
|
|
{
|
|
start = 0;
|
|
end = 255;
|
|
}
|
|
else
|
|
{
|
|
start = 256;
|
|
end = sizeof(_ecore_win32_name_to_keysym) / sizeof(ecore_win32_name_keysym) - 1;
|
|
}
|
|
|
|
do {
|
|
uint32_t m = (start + end) / 2;
|
|
|
|
if (_ecore_win32_name_to_keysym[m].keysym == keysym)
|
|
return _ecore_win32_name_to_keysym[m].offset;
|
|
else
|
|
{
|
|
if (keysym > _ecore_win32_name_to_keysym[m].keysym)
|
|
start = m + 1;
|
|
else
|
|
end = m - 1;
|
|
}
|
|
} while (start <= end);
|
|
|
|
return 0xffffffff;
|
|
}
|
|
|
|
static const char *
|
|
_ecore_win32_diacritic_get(WCHAR wc)
|
|
{
|
|
switch (wc)
|
|
{
|
|
case 0x0060: /* grave accent */
|
|
return "dead_grave";
|
|
case 0x00b4: /* acute accent */
|
|
return "dead_acute";
|
|
case 0x005e: /* circumflex_accent */
|
|
return "dead_circumflex";
|
|
case 0x007e: /* tilde_accent */
|
|
return "dead_tilde";
|
|
case 0x00a8: /* diaeresis_accent */
|
|
return "dead_diaeresis";
|
|
/*
|
|
* FIXME: add more diacritics
|
|
* needs more langages and keyboards
|
|
* see http://en.wikipedia.org/wiki/Diacritic
|
|
*/
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static Ecore_Event_Key *
|
|
_ecore_win32_event_keystroke_get(Ecore_Win32_Callback_Data *msg,
|
|
Eina_Bool is_down)
|
|
{
|
|
Ecore_Event_Key *e;
|
|
char string[2] = { 0, 0 };
|
|
const char *keyname = NULL;
|
|
const char *key = NULL;
|
|
char *compose = NULL;
|
|
unsigned char free_compose = 0;
|
|
|
|
switch (msg->window_param)
|
|
{
|
|
/* VK_LBUTTON: 0x01 : not launched by message */
|
|
/* VK_RBUTTON: 0x02 : not launched by message */
|
|
/* VK_CANCEL: 0x03 : FIXME: what to do ? */
|
|
/* VK_MBUTTON: 0x04 : not launched by message */
|
|
/* VK_XBUTTON1: 0x05 : not launched by message */
|
|
/* VK_XBUTTON2: 0x06 : not launched by message */
|
|
|
|
/* 0x07 : undefined */
|
|
|
|
case VK_BACK: /* 0x08 */
|
|
keyname = "BackSpace";
|
|
key = "BackSpace";
|
|
compose = "\b";
|
|
break;
|
|
case VK_TAB: /* 0x09 */
|
|
keyname = "Tab";
|
|
key = "Tab";
|
|
compose = "\t";
|
|
break;
|
|
|
|
/* 0x0A - 0x0B : reserved */
|
|
|
|
case VK_CLEAR: /* 0x0C */
|
|
keyname = "KP_Begin";
|
|
key = "KP_Begin";
|
|
compose = NULL;
|
|
break;
|
|
case VK_RETURN: /* 0x0D */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "KP_Enter";
|
|
key = "KP_Enter";
|
|
}
|
|
else
|
|
{
|
|
keyname = "Return";
|
|
key = "Return";
|
|
}
|
|
compose = "\n";
|
|
break;
|
|
|
|
/* 0x0E - 0x0F : undefined */
|
|
|
|
case VK_SHIFT: /* 0x10 */
|
|
{
|
|
if (is_down)
|
|
{
|
|
if (ECORE_WIN32_VK_IS_REPEATED(msg->data_param))
|
|
return NULL;
|
|
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_LSHIFT))
|
|
{
|
|
_ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LSHIFT;
|
|
keyname = "Shift_L";
|
|
key = "Shift_L";
|
|
compose = NULL;
|
|
}
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_RSHIFT))
|
|
{
|
|
_ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RSHIFT;
|
|
keyname = "Shift_R";
|
|
key = "Shift_R";
|
|
compose = NULL;
|
|
}
|
|
}
|
|
else /* is_up */
|
|
{
|
|
if (!ECORE_WIN32_VK_IS_PRESSED(VK_LSHIFT) &&
|
|
(_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LSHIFT))
|
|
{
|
|
keyname = "Shift_L";
|
|
key = "Shift_L";
|
|
compose = NULL;
|
|
_ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LSHIFT;
|
|
}
|
|
if (!ECORE_WIN32_VK_IS_PRESSED(VK_RSHIFT) &&
|
|
(_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RSHIFT))
|
|
{
|
|
keyname = "Shift_R";
|
|
key = "Shift_R";
|
|
compose = NULL;
|
|
_ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RSHIFT;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case VK_CONTROL: /* 0x11 */
|
|
{
|
|
if (is_down)
|
|
{
|
|
/* We check if Ctrl has be thrown because of AltGr being stroke */
|
|
if (!ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
BOOL res;
|
|
MSG next_msg;
|
|
|
|
/*
|
|
* we check if the next message
|
|
* - is a WM_KEYDOWN
|
|
* - has the same timestamp than the Ctrl one
|
|
* - is the key press of the Alt key
|
|
*/
|
|
res = PeekMessage(&next_msg, msg->window,
|
|
WM_KEYDOWN, WM_KEYDOWN,
|
|
PM_NOREMOVE);
|
|
if (res &&
|
|
(next_msg.wParam == VK_MENU) &&
|
|
(next_msg.time == msg->timestamp) &&
|
|
ECORE_WIN32_VK_IS_EXTENDED(next_msg.lParam))
|
|
{
|
|
INF("discard left Ctrl key press (sent by AltGr key press)");
|
|
_ecore_win32_ctrl_fake = EINA_TRUE;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (ECORE_WIN32_VK_IS_REPEATED(msg->data_param))
|
|
return NULL;
|
|
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_LCONTROL))
|
|
{
|
|
_ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LCONTROL;
|
|
keyname = "Control_L";
|
|
key = "Control_L";
|
|
compose = NULL;
|
|
break;
|
|
}
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_RCONTROL))
|
|
{
|
|
_ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RCONTROL;
|
|
keyname = "Control_R";
|
|
key = "Control_R";
|
|
compose = NULL;
|
|
break;
|
|
}
|
|
}
|
|
else /* is_up */
|
|
{
|
|
/* We check if Ctrl has be thrown because of AltGr being stroke */
|
|
if (!ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
BOOL res;
|
|
MSG next_msg;
|
|
|
|
/*
|
|
* we check if the next message
|
|
* - is a WM_KEYUP or WM_SYSKEYUP
|
|
* - has the same timestamp than the Ctrl one
|
|
* - is the key press of the Alt key
|
|
*/
|
|
res = PeekMessage(&next_msg, msg->window,
|
|
WM_KEYUP, WM_SYSKEYUP,
|
|
PM_NOREMOVE);
|
|
if (res &&
|
|
((next_msg.message == WM_KEYUP) ||
|
|
(next_msg.message == WM_SYSKEYUP)) &&
|
|
(next_msg.wParam == VK_MENU) &&
|
|
(next_msg.time == msg->timestamp) &&
|
|
ECORE_WIN32_VK_IS_EXTENDED(next_msg.lParam))
|
|
{
|
|
INF("discard left Ctrl key press (sent by AltGr key press)");
|
|
_ecore_win32_ctrl_fake = EINA_TRUE;
|
|
return NULL;
|
|
}
|
|
}
|
|
if (!ECORE_WIN32_VK_IS_PRESSED(VK_LCONTROL) &&
|
|
(_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LCONTROL))
|
|
{
|
|
keyname = "Control_L";
|
|
key = "Control_L";
|
|
compose = NULL;
|
|
_ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LCONTROL;
|
|
break;
|
|
}
|
|
if (!ECORE_WIN32_VK_IS_PRESSED(VK_LCONTROL) &&
|
|
(_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RCONTROL))
|
|
{
|
|
keyname = "Control_R";
|
|
key = "Control_R";
|
|
compose = NULL;
|
|
_ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RCONTROL;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case VK_MENU: /* 0x12 */
|
|
{
|
|
if (is_down)
|
|
{
|
|
if (ECORE_WIN32_VK_IS_REPEATED(msg->data_param))
|
|
return NULL;
|
|
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_LMENU))
|
|
{
|
|
_ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LMENU;
|
|
keyname = "Alt_L";
|
|
key = "Alt_L";
|
|
compose = NULL;
|
|
}
|
|
if (ECORE_WIN32_VK_IS_PRESSED(VK_RMENU))
|
|
{
|
|
_ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RMENU;
|
|
keyname = "ISO_Level3_Shift";
|
|
key = "ISO_Level3_Shift";
|
|
compose = NULL;
|
|
}
|
|
}
|
|
else /* is_up */
|
|
{
|
|
if (!ECORE_WIN32_VK_IS_PRESSED(VK_LMENU) &&
|
|
(_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LMENU))
|
|
{
|
|
keyname = "Alt_L";
|
|
key = "Alt_L";
|
|
compose = NULL;
|
|
_ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LMENU;
|
|
}
|
|
if (!ECORE_WIN32_VK_IS_PRESSED(VK_RMENU) &&
|
|
(_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RMENU))
|
|
{
|
|
keyname = "ISO_Level3_Shift";
|
|
key = "ISO_Level3_Shift";
|
|
compose = NULL;
|
|
_ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RMENU;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case VK_PAUSE: /* 0x13 */
|
|
keyname = "Pause";
|
|
key = "Pause";
|
|
compose = NULL;
|
|
break;
|
|
case VK_CAPITAL: /* 0x14 */
|
|
keyname = "Caps_Lock";
|
|
key = "Caps_Lock";
|
|
compose = NULL;
|
|
break;
|
|
|
|
/* VK_KANA: 0x15 : IME Kana mode */
|
|
/* VK_HANGUEL: 0x15 : IME Hanguel mode (maintained for compatibility; use VK_HANGUL) */
|
|
/* VK_HANGUL: 0x15 : IME Hangul mode */
|
|
|
|
/* 0x16 : undefined */
|
|
|
|
/* VK_JUNJA: 0x17 : IME Junja mode */
|
|
/* VK_FINAL: 0x18 : IME final mode */
|
|
/* VK_HANJA: 0x19 : IME Hanja mode */
|
|
/* VK_KANJI: 0x19 : IME Kanji mode */
|
|
|
|
/* 0x1A : undefined */
|
|
|
|
case VK_ESCAPE: /* 0x1B */
|
|
keyname = "Escape";
|
|
key = "Escape";
|
|
string[0] = 0x1b;
|
|
compose = string;
|
|
break;
|
|
|
|
/* VK_CONVERT: 0x1C : IME convert */
|
|
/* VK_NONCONVERT: 0x1D : IME nonconvert */
|
|
/* VK_ACCEPT: 0x1E : IME accept */
|
|
/* VK_MODECHANGE: 0x1F : IME mode change request */
|
|
|
|
case VK_SPACE: /* 0x20 */
|
|
keyname = "space";
|
|
key = "space";
|
|
compose = " ";
|
|
break;
|
|
|
|
case VK_PRIOR: /* 0x21 */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "Prior";
|
|
key = "Prior";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_Prior";
|
|
key = "KP_Prior";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
case VK_NEXT: /* 0x22 */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "Next";
|
|
key = "Next";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_Next";
|
|
key = "KP_Next";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
case VK_END: /* 0x23 */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "End";
|
|
key = "End";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_End";
|
|
key = "KP_End";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
case VK_HOME: /* 0x24 */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "Home";
|
|
key = "Home";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_HOME";
|
|
key = "KP_HOME";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
case VK_LEFT: /* 0x25 */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "Left";
|
|
key = "Left";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_Left";
|
|
key = "KP_Left";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
case VK_UP: /* 0x26 */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "Up";
|
|
key = "Up";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_Up";
|
|
key = "KP_Up";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
case VK_RIGHT: /* 0x27 */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "Right";
|
|
key = "Right";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_Right";
|
|
key = "KP_Right";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
case VK_DOWN: /* 0x28 */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "Down";
|
|
key = "Down";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_Down";
|
|
key = "KP_Down";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
|
|
/* VK_SELECT: 0x29 : SELECT key (for a menu ? on rare keyboards ?) */
|
|
/* VK_PRINT: 0x2A : PRINT key on old IBM PC XT and AT, maybe also on Nokia keyboards */
|
|
/* VK_EXECUTE: 0x2B : EXECUTE key (for a menu ? on rare keyboards ?) */
|
|
/* VK_SNAPSHOT: 0x2C : EXECUTE key (for a menu ? on rare keyboards ?) */
|
|
|
|
case VK_INSERT: /* 0x2D */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "Insert";
|
|
key = "Insert";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_Insert";
|
|
key = "KP_Insert";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
case VK_DELETE: /* 0x2E */
|
|
if (ECORE_WIN32_VK_IS_EXTENDED(msg->data_param))
|
|
{
|
|
keyname = "Delete";
|
|
key = "Delete";
|
|
string[0] = 0x7f;
|
|
compose = string;
|
|
}
|
|
else
|
|
{
|
|
keyname = "KP_Delete";
|
|
key = "KP_Delete";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
|
|
/* VK_HELP: 0x2F : HELP key (for a menu ? on rare keyboards ?) */
|
|
|
|
/* case 0x30: 0 key (default case) */
|
|
/* case 0x31: 1 key (default case) */
|
|
/* case 0x32: 2 key (default case) */
|
|
/* case 0x33: 3 key (default case) */
|
|
/* case 0x34: 4 key (default case) */
|
|
/* case 0x35: 5 key (default case) */
|
|
/* case 0x36: 6 key (default case) */
|
|
/* case 0x37: 7 key (default case) */
|
|
/* case 0x38: 8 key (default case) */
|
|
/* case 0x39: 9 key (default case) */
|
|
|
|
/* 0x3A - 0x40 : undefined */
|
|
|
|
/* case 0x41: A key (default case) */
|
|
/* case 0x42: B key (default case) */
|
|
/* case 0x43: C key (default case) */
|
|
/* case 0x44: D key (default case) */
|
|
/* case 0x45: E key (default case) */
|
|
/* case 0x46: F key (default case) */
|
|
/* case 0x47: G key (default case) */
|
|
/* case 0x48: H key (default case) */
|
|
/* case 0x49: I key (default case) */
|
|
/* case 0x4a: J key (default case) */
|
|
/* case 0x4b: K key (default case) */
|
|
/* case 0x4c: L key (default case) */
|
|
/* case 0x4d: M key (default case) */
|
|
/* case 0x4e: N key (default case) */
|
|
/* case 0x4f: O key (default case) */
|
|
/* case 0x50: P key (default case) */
|
|
/* case 0x51: Q key (default case) */
|
|
/* case 0x52: R key (default case) */
|
|
/* case 0x53: S key (default case) */
|
|
/* case 0x54: T key (default case) */
|
|
/* case 0x55: U key (default case) */
|
|
/* case 0x56: V key (default case) */
|
|
/* case 0x57: W key (default case) */
|
|
/* case 0x58: X key (default case) */
|
|
/* case 0x59: Y key (default case) */
|
|
/* case 0x5a: Z key (default case) */
|
|
|
|
case VK_LWIN: /* 0x5B */
|
|
{
|
|
if (is_down)
|
|
{
|
|
if (ECORE_WIN32_VK_IS_REPEATED(msg->data_param))
|
|
return NULL;
|
|
|
|
keyname = "Super_L";
|
|
key = "Super_L";
|
|
compose = NULL;
|
|
}
|
|
else /* is_up */
|
|
{
|
|
keyname = "Super_L";
|
|
key = "Super_L";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
}
|
|
case VK_RWIN: /* 0x5C */
|
|
{
|
|
if (is_down)
|
|
{
|
|
if (ECORE_WIN32_VK_IS_REPEATED(msg->data_param))
|
|
return NULL;
|
|
|
|
keyname = "Super_R";
|
|
key = "Super_R";
|
|
compose = NULL;
|
|
}
|
|
else /* is_up */
|
|
{
|
|
keyname = "Super_R";
|
|
key = "Super_R";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
}
|
|
case VK_APPS: /* 0x5D Menu key on some keyboards, or via the 'function' modifier */
|
|
keyname = "Menu";
|
|
key = "Menu";
|
|
compose = NULL;
|
|
break;
|
|
|
|
/* 0x5E : reserved */
|
|
|
|
/* case VK_SLEEP: 0x5F SLEEP key (not hookable, the computer goes to sleep immediatly...) */
|
|
|
|
case VK_NUMPAD0: /* 0x60 */
|
|
keyname = "KP_Insert";
|
|
key = "KP_0";
|
|
compose = "0";
|
|
break;
|
|
case VK_NUMPAD1: /* 0x61 */
|
|
keyname = "KP_End";
|
|
key = "KP_1";
|
|
compose = "1";
|
|
break;
|
|
case VK_NUMPAD2: /* 0x62 */
|
|
keyname = "KP_Down";
|
|
key = "KP_2";
|
|
compose = "2";
|
|
break;
|
|
case VK_NUMPAD3: /* 0x63 */
|
|
keyname = "KP_Next";
|
|
key = "KP_3";
|
|
compose = "3";
|
|
break;
|
|
case VK_NUMPAD4: /* 0x64 */
|
|
keyname = "KP_Left";
|
|
key = "KP_4";
|
|
compose = "4";
|
|
break;
|
|
case VK_NUMPAD5: /* 0x65 */
|
|
keyname = "KP_Begin";
|
|
key = "KP_5";
|
|
compose = "5";
|
|
break;
|
|
case VK_NUMPAD6: /* 0x66 */
|
|
keyname = "KP_Right";
|
|
key = "KP_6";
|
|
compose = "6";
|
|
break;
|
|
case VK_NUMPAD7: /* 0x67 */
|
|
keyname = "KP_HOME";
|
|
key = "KP_7";
|
|
compose = "7";
|
|
break;
|
|
case VK_NUMPAD8: /* 0x68 */
|
|
keyname = "KP_Up";
|
|
key = "KP_8";
|
|
compose = "8";
|
|
break;
|
|
case VK_NUMPAD9: /* 0x69 */
|
|
keyname = "KP_Prior";
|
|
key = "KP_9";
|
|
compose = "9";
|
|
break;
|
|
case VK_MULTIPLY: /* 0x6A */
|
|
keyname = "KP_Multiply";
|
|
key = "KP_Multiply";
|
|
compose = "*";
|
|
break;
|
|
case VK_ADD: /* 0x6A */
|
|
keyname = "KP_Add";
|
|
key = "KP_Add";
|
|
compose = "+";
|
|
break;
|
|
/* VK_SEPARATOR : 0x6C : FIXME depending on layout : */
|
|
/* . or , for the separator in a floating point number*/
|
|
case VK_SUBTRACT: /* 0x6D */
|
|
keyname = "KP_Subtract";
|
|
key = "KP_Subtract";
|
|
compose = "-";
|
|
break;
|
|
case VK_DECIMAL: /* 0x6E */
|
|
/* '.' key with num lock on */
|
|
keyname = "KP_Delete";
|
|
key = "KP_Decimal";
|
|
/* Value of 'compose' may depend on the layout */
|
|
compose = ".";
|
|
break;
|
|
case VK_DIVIDE: /* 0x6F */
|
|
keyname = "KP_Divide";
|
|
key = "KP_Divide";
|
|
compose = "/";
|
|
break;
|
|
case VK_F1: /* 0x70 */
|
|
keyname = "F1";
|
|
key = "F1";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F2: /* 0x71 */
|
|
keyname = "F2";
|
|
key = "F2";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F3: /* 0x72 */
|
|
keyname = "F3";
|
|
key = "F3";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F4: /* 0x73 */
|
|
keyname = "F4";
|
|
key = "F4";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F5: /* 0x74 */
|
|
keyname = "F5";
|
|
key = "F5";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F6: /* 0x75 */
|
|
keyname = "F6";
|
|
key = "F6";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F7: /* 0x76 */
|
|
keyname = "F7";
|
|
key = "F7";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F8: /* 0x77 */
|
|
keyname = "F8";
|
|
key = "F8";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F9: /* 0x78 */
|
|
keyname = "F9";
|
|
key = "F9";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F10: /* 0x79 */
|
|
keyname = "F10";
|
|
key = "F10";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F11: /* 0x7A */
|
|
keyname = "F11";
|
|
key = "F11";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F12: /* 0x7B */
|
|
keyname = "F12";
|
|
key = "F12";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F13: /* 0x7C */
|
|
keyname = "F13";
|
|
key = "F13";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F14: /* 0x7D */
|
|
keyname = "F14";
|
|
key = "F14";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F15: /* 0x7E */
|
|
keyname = "F15";
|
|
key = "F15";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F16: /* 0x7F */
|
|
keyname = "F16";
|
|
key = "F16";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F17: /* 0x80 */
|
|
keyname = "F17";
|
|
key = "F17";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F18: /* 0x81 */
|
|
keyname = "F18";
|
|
key = "F18";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F19: /* 0x82 */
|
|
keyname = "F19";
|
|
key = "F19";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F20: /* 0x83 */
|
|
keyname = "F20";
|
|
key = "F20";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F21: /* 0x84 */
|
|
keyname = "F21";
|
|
key = "F21";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F22: /* 0x85 */
|
|
keyname = "F22";
|
|
key = "F22";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F23: /* 0x86 */
|
|
keyname = "F23";
|
|
key = "F23";
|
|
compose = NULL;
|
|
break;
|
|
case VK_F24: /* 0x87 */
|
|
keyname = "F24";
|
|
key = "F24";
|
|
compose = NULL;
|
|
break;
|
|
|
|
/* 0x88 - 0x8F : unassigned */
|
|
|
|
case VK_NUMLOCK: /* 0x90 */
|
|
keyname = "Num_Lock";
|
|
key = "Num_Lock";
|
|
compose = NULL;
|
|
break;
|
|
case VK_SCROLL: /* 0x91 */
|
|
keyname = "Scroll_Lock";
|
|
key = "Scroll_Lock";
|
|
compose = NULL;
|
|
break;
|
|
|
|
/* 0x92 - 0x96 : OEM specific */
|
|
|
|
/* 0x97 - 0x9F : unassigned */
|
|
|
|
/* VK_LSHIT: 0xA0 : not launched by message */
|
|
/* VK_RSHIT: 0xA1 : not launched by message */
|
|
/* VK_LCONTROL: 0xA2 : not launched by message */
|
|
/* VK_RCONTROL: 0xA3 : not launched by message */
|
|
/* VK_LMENU: 0xA4 : not launched by message */
|
|
/* VK_RMENU: 0xA5 : not launched by message */
|
|
|
|
case VK_BROWSER_BACK: /* 0xA6 */
|
|
keyname = "XF86Back";
|
|
key = "XF86Back";
|
|
compose = NULL;
|
|
break;
|
|
case VK_BROWSER_FORWARD: /* 0xA7 */
|
|
keyname = "XF86Forward";
|
|
key = "XF86Forward";
|
|
compose = NULL;
|
|
break;
|
|
case VK_BROWSER_REFRESH: /* 0xA8 */
|
|
keyname = "XF86Forward";
|
|
key = "XF86Forward";
|
|
compose = NULL;
|
|
break;
|
|
case VK_BROWSER_STOP: /* 0xA9 */
|
|
keyname = "XF86Stop";
|
|
key = "XF86Stop";
|
|
compose = NULL;
|
|
break;
|
|
case VK_BROWSER_SEARCH: /* 0xAA */
|
|
keyname = "XF86Search";
|
|
key = "XF86Search";
|
|
compose = NULL;
|
|
break;
|
|
case VK_BROWSER_FAVORITES: /* 0xAB */
|
|
keyname = "XF86Favorites";
|
|
key = "XF86Favorites";
|
|
compose = NULL;
|
|
break;
|
|
case VK_BROWSER_HOME: /* 0xAC */
|
|
keyname = "XF86HomePage";
|
|
key = "XF86HomePage";
|
|
compose = NULL;
|
|
break;
|
|
|
|
case VK_VOLUME_MUTE: /* 0xAD */
|
|
keyname = "XF86AudioMute";
|
|
key = "XF86AudioMute";
|
|
compose = NULL;
|
|
break;
|
|
case VK_VOLUME_DOWN: /* 0xAE */
|
|
keyname = "XF86AudioLowerVolume";
|
|
key = "XF86AudioLowerVolume";
|
|
compose = NULL;
|
|
break;
|
|
case VK_VOLUME_UP: /* 0xAF */
|
|
keyname = "XF86AudioRaiseVolume";
|
|
key = "XF86AudioRaiseVolume";
|
|
compose = NULL;
|
|
break;
|
|
|
|
case VK_MEDIA_NEXT_TRACK: /* 0xB0 */
|
|
keyname = "XF86AudioNext";
|
|
key = "XF86AudioNext";
|
|
compose = NULL;
|
|
break;
|
|
case VK_MEDIA_PREV_TRACK: /* 0xB1 */
|
|
keyname = "XF86AudioPrev";
|
|
key = "XF86AudioPrev";
|
|
compose = NULL;
|
|
break;
|
|
case VK_MEDIA_STOP: /* 0xB2 */
|
|
keyname = "XF86AudioStop";
|
|
key = "XF86AudioStop";
|
|
compose = NULL;
|
|
break;
|
|
case VK_MEDIA_PLAY_PAUSE: /* 0xB3 */
|
|
{
|
|
if (ECORE_WIN32_VK_IS_TOGGLED(VK_MEDIA_PLAY_PAUSE))
|
|
{
|
|
keyname = "XF86AudioPlay";
|
|
key = "XF86AudioPlay";
|
|
compose = NULL;
|
|
}
|
|
else
|
|
{
|
|
keyname = "XF86AudioPause";
|
|
key = "XF86AudioPause";
|
|
compose = NULL;
|
|
}
|
|
break;
|
|
}
|
|
case VK_LAUNCH_MAIL: /* 0xB4 */
|
|
keyname = "XF86Mail";
|
|
key = "XF86Mail";
|
|
compose = NULL;
|
|
break;
|
|
|
|
/* VK_LAUNCH_MEDIA_SELECT: 0xB5 : select Media key */
|
|
/* VK_LAUNCH_APP1: 0xB6 : start application 1 key */
|
|
/* VK_LAUNCH_APP2: 0xB7 : start application 2 key */
|
|
|
|
/* 0xB8 - 0xB9 : reserved */
|
|
|
|
/* case VK_OEM1 : 0xBA : Used for miscellaneous characters; it can vary by keyboard. (default case) */
|
|
/* case VK_PLUS : 0xBB : For any country/region, the '+' key. (default case) */
|
|
/* case VK_COMMA : 0xBC : For any country/region, the ',' key. (default case) */
|
|
/* case VK_MINUS : 0xBD : For any country/region, the '-' key. (default case) */
|
|
/* case VK_PERIOD : 0xBE : For any country/region, the '.' key. (default case) */
|
|
/* case VK_OEM2 : 0xBF : Used for miscellaneous characters; it can vary by keyboard. (default case) */
|
|
/* case VK_OEM3 : 0xC0 : Used for miscellaneous characters; it can vary by keyboard. (default case) */
|
|
|
|
/* 0xC1 - 0xD7 : reserved */
|
|
|
|
/* 0xD8 - 0xDA : unassigned */
|
|
|
|
/* case VK_OEM4 : 0xDB : Used for miscellaneous characters; it can vary by keyboard. (default case) */
|
|
/* case VK_OEM5 : 0xDC : Used for miscellaneous characters; it can vary by keyboard. (default case) */
|
|
/* case VK_OEM6 : 0xDD : Used for miscellaneous characters; it can vary by keyboard. (default case) */
|
|
/* case VK_OEM7 : 0xDE : Used for miscellaneous characters; it can vary by keyboard. (default case) */
|
|
/* case VK_OEM8 : 0xDF : Used for miscellaneous characters; it can vary by keyboard. (default case) */
|
|
|
|
/* 0xE0 : reserved */
|
|
|
|
/* 0xE1 : OEM specific */
|
|
|
|
/* case VK_OEM102 : 0xE2 : Either the angle bracket key or the backslash key on the RT 102-key keyboard. (default case) */
|
|
|
|
/* 0xE3 - 0xE4 : OEM specific */
|
|
|
|
/* case VK_PROCESSKEY : 0xE5 : IME PROCESS key */
|
|
|
|
/* 0xE6 : OEM specific */
|
|
|
|
/* case VK_PACKET : 0xE7 : Used to pass Unicode characters as if they were keystrokes. */
|
|
|
|
/* 0xE8 : unassigned */
|
|
|
|
/* 0xE9 - 0xF5 : OEM specific */
|
|
|
|
/* case VK_ATTN : 0xF6 : Attn key */
|
|
/* case VK_CRSEL : 0xF7 : CrSel key */
|
|
/* case VK_EXSEL : 0xF8 : ExSel key */
|
|
/* case VK_EREOF : 0xF9 : Erase EOF key */
|
|
/* case VK_PLAY : 0xFA : Play key */
|
|
/* case VK_ZOOM : 0xFB : Zoom key */
|
|
|
|
/* case VK_NONAME : 0xFC : reserved */
|
|
|
|
/* case VK_PA1 : 0xFD : PA1 key */
|
|
/* case VK_OEM_CLEAR : 0xFE : Clear key */
|
|
default:
|
|
{
|
|
BYTE kbd_state[256];
|
|
WCHAR buf[4];
|
|
uint32_t offset;
|
|
int res;
|
|
unsigned short modifiers_save = 0;
|
|
Eina_Bool is_dead_key;
|
|
|
|
/*** compose and string field ***/
|
|
|
|
if (!GetKeyboardState(kbd_state))
|
|
return NULL;
|
|
|
|
/*
|
|
* Keep that trick in case it is necessary
|
|
char_value = MapVirtualKey(msg->window_param, MAPVK_VK_TO_CHAR);
|
|
_ecore_win32_is_dead_key = (char_value & 0x80000000) == 0x80000000;
|
|
*/
|
|
res = ToUnicode(msg->window_param,
|
|
MapVirtualKey(msg->window_param, MAPVK_VK_TO_CHAR),
|
|
kbd_state, buf, 4, 0);
|
|
if (res == -1)
|
|
{
|
|
/* dead key, but managed like normal key */
|
|
compose = evil_utf16_to_utf8(buf);
|
|
free_compose = 1;
|
|
}
|
|
else if (res == 0)
|
|
{
|
|
INF("No translatable character found, skipping");
|
|
if (msg->window_param >= 0x30 && msg->window_param <= 0x39)
|
|
{
|
|
compose = evil_utf16_to_utf8(buf);
|
|
free_compose = 1;
|
|
}
|
|
/* otherwise, compose is NULL */
|
|
}
|
|
else if (res >= 2)
|
|
{
|
|
/*
|
|
* Most common case : dead key which can not be composed,
|
|
* or proper symbol.
|
|
* Call ToUnicode again to get something sane.
|
|
*/
|
|
res = ToUnicode(msg->window_param,
|
|
MapVirtualKey(msg->window_param, MAPVK_VK_TO_CHAR),
|
|
kbd_state, buf, 4, 0);
|
|
if (!((res != 1) && (res != -1)))
|
|
{
|
|
compose = evil_utf16_to_utf8(buf);
|
|
free_compose = 1;
|
|
}
|
|
/* otherwise, compose is NULL */
|
|
}
|
|
else /* res == 1 : 1 char written to buf */
|
|
{
|
|
compose = evil_utf16_to_utf8(buf);
|
|
free_compose = 1;
|
|
}
|
|
|
|
/*** key field ***/
|
|
|
|
if (!_ecore_win32_ctrl_fake)
|
|
{
|
|
/* save modifiers for key */
|
|
modifiers_save = 0;
|
|
|
|
/* save Control modifier before getting key value */
|
|
_ecore_win32_modifiers_ctrl_save(kbd_state, &modifiers_save);
|
|
|
|
if (!SetKeyboardState(kbd_state))
|
|
goto _free_compose;
|
|
}
|
|
|
|
is_dead_key = EINA_FALSE;
|
|
res = ToUnicode(msg->window_param,
|
|
MapVirtualKey(msg->window_param, MAPVK_VK_TO_CHAR),
|
|
kbd_state, buf, 4, 0);
|
|
if (res == -1)
|
|
{
|
|
is_dead_key = EINA_TRUE;
|
|
}
|
|
else if (res == 0)
|
|
{
|
|
INF("No translatable character found, skipping");
|
|
if (msg->window_param >= 0x30 && msg->window_param <= 0x39)
|
|
{
|
|
buf[0] = msg->window_param;
|
|
}
|
|
}
|
|
else if (res >= 2)
|
|
{
|
|
/*
|
|
* Most common case : dead key which can not be composed,
|
|
* buf[0] is invalid and buf[1] is the dead key.
|
|
* Call ToUnicode again to get something sane.
|
|
*/
|
|
res = ToUnicode(msg->window_param,
|
|
MapVirtualKey(msg->window_param, MAPVK_VK_TO_CHAR),
|
|
kbd_state, buf, 4, 0);
|
|
if (res == -1)
|
|
is_dead_key = EINA_TRUE;
|
|
if ((res != 1) && (res != -1))
|
|
goto _free_compose;
|
|
}
|
|
|
|
if (is_dead_key)
|
|
key = _ecore_win32_diacritic_get(buf[0]);
|
|
else
|
|
{
|
|
offset = _ecore_win32_keysym_offset_get(buf[0]);
|
|
if (offset != 0xffffffff)
|
|
key = _ecore_win32_keysym_names + offset;
|
|
}
|
|
|
|
if (!_ecore_win32_ctrl_fake)
|
|
{
|
|
/* Restaure Control modifier */
|
|
_ecore_win32_modifiers_ctrl_restore(kbd_state, modifiers_save);
|
|
|
|
if (!SetKeyboardState(kbd_state))
|
|
goto _free_compose;
|
|
}
|
|
|
|
if (!key)
|
|
{
|
|
WRN("no keysym found for keycode %d\n", string[0]);
|
|
goto _free_compose;
|
|
}
|
|
|
|
/*** keyname field ***/
|
|
|
|
/* save modifiers for keyname */
|
|
modifiers_save = 0;
|
|
|
|
_ecore_win32_modifiers_alt_save(kbd_state, &modifiers_save);
|
|
_ecore_win32_modifiers_ctrl_save(kbd_state, &modifiers_save);
|
|
_ecore_win32_modifiers_shift_save(kbd_state, &modifiers_save);
|
|
_ecore_win32_modifiers_win_save(kbd_state, &modifiers_save);
|
|
|
|
if (!SetKeyboardState(kbd_state))
|
|
goto _free_compose;
|
|
|
|
is_dead_key = EINA_FALSE;
|
|
res = ToUnicode(msg->window_param,
|
|
MapVirtualKey(msg->window_param, MAPVK_VK_TO_CHAR),
|
|
kbd_state, buf, 4, 0);
|
|
|
|
if (res == -1)
|
|
{
|
|
is_dead_key = EINA_TRUE;
|
|
}
|
|
else if (res == 0)
|
|
{
|
|
INF("No translatable character found, skipping");
|
|
if (msg->window_param >= 0x30 && msg->window_param <= 0x39)
|
|
{
|
|
buf[0] = msg->window_param;
|
|
}
|
|
else buf[0] = 0;// return NULL;
|
|
}
|
|
else if (res >= 2)
|
|
{
|
|
/*
|
|
* Most common case : dead key which can not be composed,
|
|
* buf[0] is invalid and buf[1] is the dead key.
|
|
* Call ToUnicode again to get something sane.
|
|
*/
|
|
res = ToUnicode(msg->window_param,
|
|
MapVirtualKey(msg->window_param, MAPVK_VK_TO_CHAR),
|
|
kbd_state, buf, 4, 0);
|
|
if (res == -1)
|
|
is_dead_key = EINA_TRUE;
|
|
if ((res != 1) && (res != -1))
|
|
goto _free_compose;
|
|
}
|
|
|
|
if (is_dead_key)
|
|
keyname = _ecore_win32_diacritic_get(buf[0]);
|
|
else
|
|
{
|
|
offset = _ecore_win32_keysym_offset_get(buf[0]);
|
|
if (offset != 0xffffffff)
|
|
keyname = _ecore_win32_keysym_names + offset;
|
|
}
|
|
|
|
/* Restore modifiers */
|
|
_ecore_win32_modifiers_alt_restore(kbd_state, modifiers_save);
|
|
_ecore_win32_modifiers_ctrl_restore(kbd_state, modifiers_save);
|
|
_ecore_win32_modifiers_shift_restore(kbd_state, modifiers_save);
|
|
_ecore_win32_modifiers_win_restore(kbd_state, modifiers_save);
|
|
|
|
if (!SetKeyboardState(kbd_state))
|
|
goto _free_compose;
|
|
|
|
if (!keyname)
|
|
{
|
|
WRN("no keysym found for keycode %d\n", string[0]);
|
|
goto _free_compose;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!keyname || !key)
|
|
goto _free_compose;
|
|
|
|
e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key) +
|
|
strlen(keyname) + 1 +
|
|
strlen(key) + 1 +
|
|
(compose ? strlen(compose) : 0) + 1);
|
|
if (!e)
|
|
goto _free_compose;
|
|
|
|
e->keyname = (char *)(e + 1);
|
|
e->key = e->keyname + strlen(keyname) + 1;
|
|
e->compose = NULL;
|
|
if (compose)
|
|
e->compose = (e->key + strlen(key) + 1);
|
|
e->string = e->compose;
|
|
|
|
memcpy((char *)e->keyname, keyname, strlen(keyname));
|
|
memcpy((char *)e->key, key, strlen(key));
|
|
if (compose)
|
|
{
|
|
memcpy((char *)e->compose, compose, strlen(compose));
|
|
if (free_compose)
|
|
free(compose);
|
|
}
|
|
|
|
|
|
return e;
|
|
|
|
_free_compose:
|
|
if (free_compose)
|
|
free(compose);
|
|
return NULL;
|
|
}
|
|
|
|
/***** Global functions definitions *****/
|
|
|
|
void
|
|
_ecore_win32_event_handle_key_press(Ecore_Win32_Callback_Data *msg)
|
|
{
|
|
Ecore_Event_Key *e = NULL;
|
|
|
|
INF("key pressed");
|
|
|
|
e = _ecore_win32_event_keystroke_get(msg, EINA_TRUE);
|
|
if (!e)
|
|
return;
|
|
|
|
e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
|
|
if (!e->window)
|
|
{
|
|
free(e);
|
|
return;
|
|
}
|
|
e->root_window = (Ecore_Window)GetAncestor(msg->window, GA_ROOT);
|
|
e->event_window = e->window;
|
|
e->same_screen = 1;
|
|
e->timestamp = msg->timestamp;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_ecore_win32_event_last_time = e->timestamp;
|
|
|
|
ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL);
|
|
}
|
|
|
|
void
|
|
_ecore_win32_event_handle_key_release(Ecore_Win32_Callback_Data *msg)
|
|
{
|
|
Ecore_Event_Key *e;
|
|
|
|
INF("key released");
|
|
|
|
e = _ecore_win32_event_keystroke_get(msg, EINA_FALSE);
|
|
if (!e)
|
|
return;
|
|
|
|
e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA);
|
|
if (!e->window)
|
|
{
|
|
free(e);
|
|
return;
|
|
}
|
|
e->root_window = (Ecore_Window)GetAncestor(msg->window, GA_ROOT);
|
|
e->event_window = e->window;
|
|
e->same_screen = 1;
|
|
e->timestamp = msg->timestamp;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_ecore_win32_event_last_time = e->timestamp;
|
|
|
|
ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL);
|
|
}
|
|
|
|
void
|
|
_ecore_win32_event_handle_button_press(Ecore_Win32_Callback_Data *msg,
|
|
int button)
|
|
{
|
|
Ecore_Win32_Window *window;
|
|
RECT rect = { 0, 0, 0, 0 };
|
|
|
|
INF("mouse button pressed");
|
|
|
|
window = (Ecore_Win32_Window *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
|
|
if (!GetWindowRect(window->window, &rect))
|
|
ERR("GetWindowRect() failed!");
|
|
|
|
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) - rect.left;
|
|
e->y = GET_Y_LPARAM(msg->data_param) - rect.top;
|
|
e->root.x = rect.left;
|
|
e->root.y = rect.top;
|
|
e->timestamp = msg->timestamp;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_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->root.x = rect.left;
|
|
e->root.y = rect.top;
|
|
e->timestamp = msg->timestamp;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_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->root.x = rect.left;
|
|
e->root.y = rect.top;
|
|
e->timestamp = msg->timestamp;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
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;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_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;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_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;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
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;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_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 ;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_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;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_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;
|
|
e->modifiers = _ecore_win32_modifiers_get();
|
|
|
|
_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;
|
|
|
|
if (msg->window == ecore_win32_monitor_window)
|
|
return;
|
|
|
|
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;
|
|
|
|
if (msg->window == ecore_win32_monitor_window)
|
|
return;
|
|
|
|
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, Eina_Bool wmsize)
|
|
{
|
|
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(msg->window, &wi))
|
|
{
|
|
free(e);
|
|
return;
|
|
}
|
|
|
|
e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
|
|
if (!wmsize)
|
|
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_property_notify(Ecore_Win32_Callback_Data *msg)
|
|
{
|
|
Ecore_Win32_Event_Window_Property *e;
|
|
|
|
INF("window property");
|
|
|
|
e = calloc(1, sizeof(Ecore_Win32_Event_Window_Property));
|
|
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_PROPERTY, 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);
|
|
}
|
|
|
|
static void
|
|
_ecore_win32_event_free_selection_notify(void *data EINA_UNUSED, void *ev)
|
|
{
|
|
Ecore_Win32_Event_Selection_Notify *e;
|
|
|
|
e = (Ecore_Win32_Event_Selection_Notify *)ev;
|
|
if (e->data) free(e->data);
|
|
if (e->selection) free(e->selection);
|
|
free(e);
|
|
}
|
|
|
|
|
|
void
|
|
_ecore_win32_event_handle_selection_notify(Ecore_Win32_Callback_Data *msg)
|
|
{
|
|
Ecore_Win32_Event_Selection_Notify *e;
|
|
HGLOBAL global;
|
|
|
|
INF("selection_notify");
|
|
|
|
e = calloc(1, sizeof(Ecore_Win32_Event_Selection_Notify));
|
|
if (!e) return;
|
|
|
|
e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
|
|
e->timestamp = _ecore_win32_event_last_time;
|
|
|
|
/*
|
|
* we have data in clipboard but no data before,
|
|
* so data has just been added
|
|
*/
|
|
if (!_ecore_win32_clipboard_has_data)
|
|
{
|
|
/* in case someone else is owning the clipboard, we can't do anything */
|
|
if (!OpenClipboard(msg->window))
|
|
goto free_e;
|
|
|
|
if (IsClipboardFormatAvailable(CF_UNICODETEXT))
|
|
{
|
|
global = GetClipboardData(CF_UNICODETEXT);
|
|
if (global)
|
|
{
|
|
e->selection = strdup("text/plain;charset=utf-8");
|
|
if (e->selection)
|
|
{
|
|
wchar_t *d;
|
|
|
|
d = (wchar_t *)GlobalLock(global);
|
|
if (d)
|
|
e->data = evil_utf16_to_utf8(d);
|
|
|
|
GlobalUnlock(global);
|
|
if (e->data)
|
|
{
|
|
ecore_event_add(ECORE_WIN32_EVENT_SELECTION_NOTIFY,
|
|
e,
|
|
_ecore_win32_event_free_selection_notify,
|
|
NULL);
|
|
_ecore_win32_clipboard_has_data = EINA_TRUE;
|
|
CloseClipboard();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IsClipboardFormatAvailable(CF_TEXT))
|
|
{
|
|
global = GetClipboardData(CF_TEXT);
|
|
if (global)
|
|
{
|
|
e->selection = strdup("text/plain;charset=utf-8");
|
|
if (e->selection)
|
|
{
|
|
char *d;
|
|
|
|
d = (char *)GlobalLock(global);
|
|
if (d)
|
|
e->data = strdup(d);
|
|
|
|
GlobalUnlock(global);
|
|
if (e->data)
|
|
{
|
|
ecore_event_add(ECORE_WIN32_EVENT_SELECTION_NOTIFY, e, NULL, NULL);
|
|
|
|
_ecore_win32_clipboard_has_data = EINA_TRUE;
|
|
CloseClipboard();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
CloseClipboard();
|
|
}
|
|
/*
|
|
* otherwise, we have no more text data in clipboard and data before,
|
|
* so text data has just been removed
|
|
*/
|
|
else
|
|
{
|
|
if (!IsClipboardFormatAvailable(CF_UNICODETEXT) &&
|
|
!IsClipboardFormatAvailable(CF_TEXT))
|
|
{
|
|
ecore_event_add(ECORE_WIN32_EVENT_SELECTION_CLEAR, e, NULL, NULL);
|
|
_ecore_win32_clipboard_has_data = EINA_FALSE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
free_e:
|
|
if (e->data) free(e->data);
|
|
if (e->selection) free(e->selection);
|
|
free(e);
|
|
}
|