| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/shell/platform/linux/fl_key_event.h" |
| |
| struct _FlKeyEvent { |
| GObject parent_instance; |
| |
| // Time in milliseconds. |
| guint32 time; |
| |
| // True if is a press event, otherwise a release event. |
| gboolean is_press; |
| |
| // Hardware keycode. |
| guint16 keycode; |
| |
| // Keyval. |
| guint keyval; |
| |
| // Modifier state. |
| GdkModifierType state; |
| |
| // Keyboard group. |
| guint8 group; |
| |
| // The original event. |
| GdkEvent* origin; |
| }; |
| |
| G_DEFINE_TYPE(FlKeyEvent, fl_key_event, G_TYPE_OBJECT) |
| |
| FlKeyEvent* fl_key_event_new(guint32 time, |
| gboolean is_press, |
| guint16 keycode, |
| guint keyval, |
| GdkModifierType state, |
| guint8 group) { |
| FlKeyEvent* self = |
| FL_KEY_EVENT(g_object_new(fl_key_event_get_type(), nullptr)); |
| |
| self->time = time; |
| self->is_press = is_press; |
| self->keycode = keycode; |
| self->keyval = keyval; |
| self->state = state; |
| self->group = group; |
| |
| return self; |
| } |
| |
| FlKeyEvent* fl_key_event_new_from_gdk_event(GdkEvent* event) { |
| FlKeyEvent* self = |
| FL_KEY_EVENT(g_object_new(fl_key_event_get_type(), nullptr)); |
| |
| GdkEventType type = gdk_event_get_event_type(event); |
| g_return_val_if_fail(type == GDK_KEY_PRESS || type == GDK_KEY_RELEASE, |
| nullptr); |
| |
| guint16 keycode = 0; |
| gdk_event_get_keycode(event, &keycode); |
| guint keyval = 0; |
| gdk_event_get_keyval(event, &keyval); |
| GdkModifierType state = static_cast<GdkModifierType>(0); |
| gdk_event_get_state(event, &state); |
| |
| self->time = gdk_event_get_time(event); |
| self->is_press = type == GDK_KEY_PRESS; |
| self->keycode = keycode; |
| self->keyval = keyval; |
| self->state = state; |
| self->group = event->key.group; |
| self->origin = event; |
| |
| return self; |
| } |
| |
| guint32 fl_key_event_get_time(FlKeyEvent* self) { |
| g_return_val_if_fail(FL_IS_KEY_EVENT(self), 0); |
| return self->time; |
| } |
| |
| gboolean fl_key_event_get_is_press(FlKeyEvent* self) { |
| g_return_val_if_fail(FL_IS_KEY_EVENT(self), FALSE); |
| return self->is_press; |
| } |
| |
| guint16 fl_key_event_get_keycode(FlKeyEvent* self) { |
| g_return_val_if_fail(FL_IS_KEY_EVENT(self), 0); |
| return self->keycode; |
| } |
| |
| guint fl_key_event_get_keyval(FlKeyEvent* self) { |
| g_return_val_if_fail(FL_IS_KEY_EVENT(self), 0); |
| return self->keyval; |
| } |
| |
| GdkModifierType fl_key_event_get_state(FlKeyEvent* self) { |
| g_return_val_if_fail(FL_IS_KEY_EVENT(self), static_cast<GdkModifierType>(0)); |
| return self->state; |
| } |
| |
| guint8 fl_key_event_get_group(FlKeyEvent* self) { |
| g_return_val_if_fail(FL_IS_KEY_EVENT(self), 0); |
| return self->group; |
| } |
| |
| GdkEvent* fl_key_event_get_origin(FlKeyEvent* self) { |
| g_return_val_if_fail(FL_IS_KEY_EVENT(self), nullptr); |
| return self->origin; |
| } |
| |
| uint64_t fl_key_event_hash(FlKeyEvent* self) { |
| g_return_val_if_fail(FL_IS_KEY_EVENT(self), 0); |
| |
| // Combine the event timestamp, the type of event, and the hardware keycode |
| // (scan code) of the event to come up with a unique id for this event that |
| // can be derived solely from the event data itself, so that we can identify |
| // whether or not we have seen this event already. |
| guint64 type = |
| static_cast<uint64_t>(self->is_press ? GDK_KEY_PRESS : GDK_KEY_RELEASE); |
| guint64 keycode = static_cast<uint64_t>(self->keycode); |
| return (self->time & 0xffffffff) | ((type & 0xffff) << 32) | |
| ((keycode & 0xffff) << 48); |
| } |
| |
| static void fl_key_event_dispose(GObject* object) { |
| FlKeyEvent* self = FL_KEY_EVENT(object); |
| |
| g_clear_pointer(&self->origin, gdk_event_free); |
| |
| G_OBJECT_CLASS(fl_key_event_parent_class)->dispose(object); |
| } |
| |
| static void fl_key_event_class_init(FlKeyEventClass* klass) { |
| G_OBJECT_CLASS(klass)->dispose = fl_key_event_dispose; |
| } |
| |
| static void fl_key_event_init(FlKeyEvent* self) {} |