gdkevents-win32.c: Split out keyboard and IME events

...from gdk_event_translate(), as that function is getting too big and
makes it harder to track things.
This commit is contained in:
Chun-wei Fan
2024-11-15 18:58:54 +08:00
parent 37fc7ec3af
commit 80b3a34dab

View File

@@ -1718,103 +1718,23 @@ _gdk_win32_surface_fill_min_max_info (GdkSurface *surface,
return TRUE;
}
#define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
GDK_BUTTON2_MASK | \
GDK_BUTTON3_MASK | \
GDK_BUTTON4_MASK | \
GDK_BUTTON5_MASK)
static gboolean
gdk_event_translate (MSG *msg,
int *ret_valp)
handle_keyboard_event (GdkDisplay *display,
GdkSurface *surface,
MSG *msg,
int *ret_valp,
gboolean *goto_done)
{
RECT rect;
POINT point;
MINMAXINFO *mmi;
HWND hwnd;
HIMC himc;
WINDOWPOS *hwndpos;
gboolean ignore_leave;
GdkEvent *event;
GdkDisplay *display;
GdkSurface *surface = NULL;
GdkWin32Surface *impl;
GdkWin32Display *win32_display;
GdkSurface *new_surface;
GdkDeviceGrabInfo *keyboard_grab = NULL;
GdkDeviceGrabInfo *pointer_grab = NULL;
GdkSurface *grab_surface = NULL;
crossing_cb_t crossing_cb = NULL;
int button;
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
GdkWin32Keymap *win32_keymap;
GdkTranslatedKey translated;
gboolean return_val = FALSE;
int i;
display = gdk_display_get_default ();
win32_display = GDK_WIN32_DISPLAY (display);
if (win32_display->filters)
{
/* Apply display filters */
GdkWin32MessageFilterReturn result = apply_message_filters (display, msg, ret_valp, &win32_display->filters);
if (result == GDK_WIN32_MESSAGE_FILTER_REMOVE)
return TRUE;
}
surface = gdk_win32_display_handle_table_lookup_ (display, msg->hwnd);
if (surface == NULL)
{
/* XXX Handle WM_QUIT here ? */
if (msg->message == WM_QUIT)
{
GDK_NOTE (EVENTS, g_print (" %d", (int) msg->wParam));
exit (msg->wParam);
}
else if (msg->message == WM_CREATE)
{
surface = (GdkSurface*) (((LPCREATESTRUCTW) msg->lParam)->lpCreateParams);
GDK_SURFACE_HWND (surface) = msg->hwnd;
}
else
{
GDK_NOTE (EVENTS, g_print (" (no GdkSurface)"));
}
return FALSE;
}
keyboard_grab = _gdk_display_get_last_device_grab (display,
win32_display->device_manager->core_keyboard);
pointer_grab = _gdk_display_get_last_device_grab (display,
win32_display->device_manager->core_pointer);
g_object_ref (surface);
/* surface's refcount has now been increased, so code below should
* not just return from this function, but instead goto done (or
* break out of the big switch). To protect against forgetting this,
* #define return to a syntax error...
*/
#define return GOTO_DONE_INSTEAD
if (msg->message == win32_display->event_record->aerosnap_message)
_gdk_win32_surface_handle_aerosnap (surface,
(GdkWin32AeroSnapCombo) msg->wParam);
switch (msg->message)
{
case WM_INPUTLANGCHANGE:
{
GdkWin32Keymap *win32_keymap;
GdkTranslatedKey translated;
HKL input_locale;
win32_keymap = GDK_WIN32_KEYMAP (gdk_display_get_keymap (display));
@@ -1848,7 +1768,6 @@ gdk_event_translate (MSG *msg,
_gdk_win32_append_event (event);
}
break;
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
GDK_NOTE (EVENTS,
@@ -1865,32 +1784,23 @@ gdk_event_translate (MSG *msg,
/* Let the system handle Alt-Tab, Alt-Space and Alt-F4 unless
* the keyboard is grabbed.
*/
if (!keyboard_grab &&
if (!_gdk_display_get_last_device_grab (display, win32_display->device_manager->core_keyboard) &&
(msg->wParam == VK_TAB ||
msg->wParam == VK_SPACE ||
msg->wParam == VK_F4))
break;
/* Jump to code in common with WM_KEYUP and WM_KEYDOWN */
goto keyup_or_down;
G_GNUC_FALLTHROUGH;
case WM_KEYUP:
case WM_KEYDOWN:
GDK_NOTE (EVENTS,
g_print (" %s ch:%.02x %s",
_gdk_win32_key_to_string (msg->lParam),
(int) msg->wParam,
decode_key_lparam (msg->lParam)));
keyup_or_down:
{
GdkWin32Keymap *win32_keymap;
GdkModifierType state;
guint keyval;
guint16 keycode;
guint8 group;
gboolean is_modifier;
GdkTranslatedKey translated;
GdkTranslatedKey no_lock;
BYTE key_state[256];
GArray *translation;
@@ -1899,6 +1809,16 @@ gdk_event_translate (MSG *msg,
int effective_group = 0;
GdkModifierType consumed = 0;
char *composed = NULL;
GdkWin32Surface *impl;
if (msg->message == WM_KEYUP || msg->message == WM_KEYDOWN)
{
GDK_NOTE (EVENTS,
g_print (" %s ch:%.02x %s",
_gdk_win32_key_to_string (msg->lParam),
(int) msg->wParam,
decode_key_lparam (msg->lParam)));
}
/* Ignore key messages intended for the IME */
if (msg->wParam == VK_PROCESSKEY || win32_display->event_record->in_ime_composition)
@@ -1906,9 +1826,7 @@ gdk_event_translate (MSG *msg,
/* Ignore autorepeats on modifiers */
if (msg->message == WM_KEYDOWN &&
(msg->wParam == VK_MENU ||
msg->wParam == VK_CONTROL ||
msg->wParam == VK_SHIFT) &&
(msg->wParam == VK_MENU || msg->wParam == VK_CONTROL || msg->wParam == VK_SHIFT) &&
((HIWORD(msg->lParam) & KF_REPEAT) >= 1))
break;
@@ -2005,6 +1923,7 @@ gdk_event_translate (MSG *msg,
if (msg->message == WM_KEYDOWN && msg->wParam == VK_SHIFT)
{
int pressed_shift = msg->lParam & 0xffffff; /* mask shift modifier */
if (win32_display->event_record->both_shift_pressed[0] == 0)
win32_display->event_record->both_shift_pressed[0] = pressed_shift;
else if (win32_display->event_record->both_shift_pressed[0] != pressed_shift)
@@ -2035,9 +1954,7 @@ gdk_event_translate (MSG *msg,
if (msg->wParam == VK_MENU)
state &= ~GDK_ALT_MASK;
event = gdk_key_event_new ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
? GDK_KEY_PRESS
: GDK_KEY_RELEASE,
event = gdk_key_event_new ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) ? GDK_KEY_PRESS : GDK_KEY_RELEASE,
surface,
win32_display->device_manager->core_keyboard,
_gdk_win32_get_next_tick (msg->time),
@@ -2060,7 +1977,7 @@ gdk_event_translate (MSG *msg,
{
/* To prevent beeps, don't let DefWindowProcW() be called */
return_val = TRUE;
goto done;
*goto_done = TRUE;
}
break;
@@ -2071,12 +1988,13 @@ gdk_event_translate (MSG *msg,
case WM_IME_ENDCOMPOSITION:
win32_display->event_record->in_ime_composition = FALSE;
break;
case WM_IME_COMPOSITION:
{
BYTE key_state[256];
wchar_t wbuf[100];
int ccount = 0;
HIMC himc;
int i;
/* On Win2k WM_IME_CHAR doesn't work correctly for non-Unicode
* applications. Thus, handle WM_IME_COMPOSITION with
@@ -2152,6 +2070,120 @@ gdk_event_translate (MSG *msg,
return_val = TRUE;
}
break;
default:
g_warning ("Maybe this was reached because this is not a keyboard-related event");
g_assert_not_reached ();
}
return return_val;
}
#define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
GDK_BUTTON2_MASK | \
GDK_BUTTON3_MASK | \
GDK_BUTTON4_MASK | \
GDK_BUTTON5_MASK)
static gboolean
gdk_event_translate (MSG *msg,
int *ret_valp)
{
RECT rect;
POINT point;
MINMAXINFO *mmi;
HWND hwnd;
WINDOWPOS *hwndpos;
gboolean ignore_leave;
GdkEvent *event;
GdkDisplay *display;
GdkSurface *surface = NULL;
GdkWin32Surface *impl;
GdkWin32Display *win32_display;
GdkSurface *new_surface;
GdkDeviceGrabInfo *keyboard_grab = NULL;
GdkDeviceGrabInfo *pointer_grab = NULL;
GdkSurface *grab_surface = NULL;
crossing_cb_t crossing_cb = NULL;
int button;
gboolean return_val = FALSE;
gboolean goto_done = FALSE;
display = gdk_display_get_default ();
win32_display = GDK_WIN32_DISPLAY (display);
if (win32_display->filters)
{
/* Apply display filters */
GdkWin32MessageFilterReturn result = apply_message_filters (display, msg, ret_valp, &win32_display->filters);
if (result == GDK_WIN32_MESSAGE_FILTER_REMOVE)
return TRUE;
}
surface = gdk_win32_display_handle_table_lookup_ (display, msg->hwnd);
if (surface == NULL)
{
/* XXX Handle WM_QUIT here ? */
if (msg->message == WM_QUIT)
{
GDK_NOTE (EVENTS, g_print (" %d", (int) msg->wParam));
exit (msg->wParam);
}
else if (msg->message == WM_CREATE)
{
surface = (GdkSurface*) (((LPCREATESTRUCTW) msg->lParam)->lpCreateParams);
GDK_SURFACE_HWND (surface) = msg->hwnd;
}
else
{
GDK_NOTE (EVENTS, g_print (" (no GdkSurface)"));
}
return FALSE;
}
keyboard_grab = _gdk_display_get_last_device_grab (display,
win32_display->device_manager->core_keyboard);
pointer_grab = _gdk_display_get_last_device_grab (display,
win32_display->device_manager->core_pointer);
g_object_ref (surface);
/* surface's refcount has now been increased, so code below should
* not just return from this function, but instead goto done (or
* break out of the big switch). To protect against forgetting this,
* #define return to a syntax error...
*/
#define return GOTO_DONE_INSTEAD
if (msg->message == win32_display->event_record->aerosnap_message)
_gdk_win32_surface_handle_aerosnap (surface,
(GdkWin32AeroSnapCombo) msg->wParam);
switch (msg->message)
{
/* keyboard inpout related events (including IME events) */
case WM_INPUTLANGCHANGE:
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_KEYDOWN:
case WM_SYSCHAR:
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
case WM_IME_COMPOSITION:
return_val = handle_keyboard_event (display, surface, msg, ret_valp, &goto_done);
if (goto_done)
goto done;
break;
case WM_LBUTTONDOWN:
button = 1;