Merge branch 'buttonlists' into 'master'
Buttonlists See merge request Librem5/squeekboard!145
This commit is contained in:
@ -63,14 +63,14 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_A
|
|||||||
|
|
||||||
static void on_button_pressed (struct squeek_button *button, struct squeek_view *view,
|
static void on_button_pressed (struct squeek_button *button, struct squeek_view *view,
|
||||||
EekGtkKeyboard *self);
|
EekGtkKeyboard *self);
|
||||||
static void on_button_released (struct squeek_button *button,
|
static void on_button_released (const struct squeek_button *button,
|
||||||
struct squeek_view *view,
|
struct squeek_view *view,
|
||||||
EekGtkKeyboard *self);
|
EekGtkKeyboard *self);
|
||||||
static void render_pressed_button (GtkWidget *widget, struct button_place *place);
|
static void render_pressed_button (GtkWidget *widget, struct button_place *place);
|
||||||
static void render_locked_button (GtkWidget *widget,
|
static void render_locked_button (GtkWidget *widget,
|
||||||
struct button_place *place);
|
struct button_place *place);
|
||||||
static void render_released_button (GtkWidget *widget,
|
static void render_released_button (GtkWidget *widget,
|
||||||
struct squeek_button *button);
|
const struct squeek_button *button);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_gtk_keyboard_real_realize (GtkWidget *self)
|
eek_gtk_keyboard_real_realize (GtkWidget *self)
|
||||||
@ -112,22 +112,20 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
|||||||
struct squeek_view *view = priv->keyboard->views[priv->keyboard->level];
|
struct squeek_view *view = priv->keyboard->views[priv->keyboard->level];
|
||||||
|
|
||||||
/* redraw pressed key */
|
/* redraw pressed key */
|
||||||
const GList *list = priv->keyboard->pressed_buttons;
|
const GList *list = priv->keyboard->pressed_keys;
|
||||||
for (const GList *head = list; head; head = g_list_next (head)) {
|
for (const GList *head = list; head; head = g_list_next (head)) {
|
||||||
struct button_place place = squeek_view_find_key(
|
struct button_place place = squeek_view_find_key(
|
||||||
view, squeek_button_get_key(head->data)
|
view, head->data
|
||||||
);
|
);
|
||||||
if (place.button)
|
if (place.button)
|
||||||
render_pressed_button (self, &place);
|
render_pressed_button (self, &place);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* redraw locked key */
|
/* redraw locked key */
|
||||||
list = priv->keyboard->locked_buttons;
|
list = priv->keyboard->locked_keys;
|
||||||
for (const GList *head = list; head; head = g_list_next (head)) {
|
for (const GList *head = list; head; head = g_list_next (head)) {
|
||||||
struct button_place place = squeek_view_find_key(
|
struct button_place place = squeek_view_find_key(
|
||||||
view, squeek_button_get_key(
|
view, ((EekModifierKey *)head->data)->key
|
||||||
((EekModifierKey *)head->data)->button
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
if (place.button)
|
if (place.button)
|
||||||
render_locked_button (self, &place);
|
render_locked_button (self, &place);
|
||||||
@ -160,7 +158,11 @@ static void depress(EekGtkKeyboard *self,
|
|||||||
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
|
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
|
||||||
|
|
||||||
if (button) {
|
if (button) {
|
||||||
eek_keyboard_press_button(priv->keyboard, button, time);
|
eek_keyboard_press_key(
|
||||||
|
priv->keyboard,
|
||||||
|
squeek_button_get_key(button),
|
||||||
|
time
|
||||||
|
);
|
||||||
on_button_pressed(button, view, self);
|
on_button_pressed(button, view, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,29 +175,42 @@ static void drag(EekGtkKeyboard *self,
|
|||||||
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
|
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
|
||||||
GList *list, *head;
|
GList *list, *head;
|
||||||
|
|
||||||
list = g_list_copy(priv->keyboard->pressed_buttons);
|
list = g_list_copy(priv->keyboard->pressed_keys);
|
||||||
|
|
||||||
if (button) {
|
if (button) {
|
||||||
gboolean found = FALSE;
|
gboolean found = FALSE;
|
||||||
|
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (head = list; head; head = g_list_next (head)) {
|
||||||
if (head->data == button) {
|
struct squeek_key *key = head->data;
|
||||||
|
if (squeek_button_has_key(button, key)) {
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
} else {
|
} else {
|
||||||
eek_keyboard_release_button(priv->keyboard, head->data, time);
|
eek_keyboard_release_key(priv->keyboard, key, time);
|
||||||
on_button_released(button, view, self);
|
// The released handler proceeds to ignore this info...
|
||||||
|
// let's do this for consistency nevertheless
|
||||||
|
struct button_place place = squeek_view_find_key(view, key);
|
||||||
|
on_button_released(place.button, view, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_list_free (list);
|
g_list_free (list);
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
eek_keyboard_press_button(priv->keyboard, button, time);
|
eek_keyboard_press_key(
|
||||||
|
priv->keyboard,
|
||||||
|
squeek_button_get_key(button),
|
||||||
|
time
|
||||||
|
);
|
||||||
|
|
||||||
on_button_pressed(button, view, self);
|
on_button_pressed(button, view, self);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (head = list; head; head = g_list_next (head)) {
|
||||||
eek_keyboard_release_button(priv->keyboard, head->data, time);
|
struct squeek_key *key = head->data;
|
||||||
on_button_released(head->data, view, self);
|
eek_keyboard_release_key(priv->keyboard, key, time);
|
||||||
|
// The released handler proceeds to ignore this info...
|
||||||
|
// let's do this for consistency nevertheless
|
||||||
|
struct button_place place = squeek_view_find_key(view, key);
|
||||||
|
on_button_released(place.button, view, self);
|
||||||
}
|
}
|
||||||
g_list_free (list);
|
g_list_free (list);
|
||||||
}
|
}
|
||||||
@ -207,11 +222,14 @@ static void release(EekGtkKeyboard *self, guint32 time)
|
|||||||
|
|
||||||
struct squeek_view *view = level_keyboard_current(priv->keyboard);
|
struct squeek_view *view = level_keyboard_current(priv->keyboard);
|
||||||
|
|
||||||
GList *list = g_list_copy(priv->keyboard->pressed_buttons);
|
GList *list = g_list_copy(priv->keyboard->pressed_keys);
|
||||||
for (GList *head = list; head; head = g_list_next (head)) {
|
for (GList *head = list; head; head = g_list_next (head)) {
|
||||||
struct squeek_button *button = head->data;
|
struct squeek_key *key = head->data;
|
||||||
eek_keyboard_release_button(priv->keyboard, button, time);
|
eek_keyboard_release_key(priv->keyboard, key, time);
|
||||||
on_button_released(button, view, self);
|
// The released handler proceeds to ignore this info...
|
||||||
|
// let's do this for consistency nevertheless
|
||||||
|
struct button_place place = squeek_view_find_key(view, key);
|
||||||
|
on_button_released(place.button, view, self);
|
||||||
}
|
}
|
||||||
g_list_free (list);
|
g_list_free (list);
|
||||||
}
|
}
|
||||||
@ -290,11 +308,11 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
|
|||||||
if (priv->keyboard) {
|
if (priv->keyboard) {
|
||||||
GList *head;
|
GList *head;
|
||||||
|
|
||||||
for (head = priv->keyboard->pressed_buttons; head; head = g_list_next (head)) {
|
for (head = priv->keyboard->pressed_keys; head; head = g_list_next (head)) {
|
||||||
/* Unlike other places where we call this, we don't call
|
/* Unlike other places where we call this, we don't call
|
||||||
on_button_released afterwards since we don't want to queue a
|
on_button_released afterwards since we don't want to queue a
|
||||||
redraw. */
|
redraw. */
|
||||||
eek_keyboard_release_button(priv->keyboard, head->data,
|
eek_keyboard_release_key(priv->keyboard, head->data,
|
||||||
gdk_event_get_time(NULL));
|
gdk_event_get_time(NULL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,8 +373,8 @@ eek_gtk_keyboard_dispose (GObject *object)
|
|||||||
if (priv->keyboard) {
|
if (priv->keyboard) {
|
||||||
GList *head;
|
GList *head;
|
||||||
|
|
||||||
for (head = priv->keyboard->pressed_buttons; head; head = g_list_next (head)) {
|
for (head = priv->keyboard->pressed_keys; head; head = g_list_next (head)) {
|
||||||
eek_keyboard_release_button(priv->keyboard, head->data,
|
eek_keyboard_release_key(priv->keyboard, head->data,
|
||||||
gdk_event_get_time(NULL));
|
gdk_event_get_time(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,9 +482,10 @@ render_locked_button (GtkWidget *widget, struct button_place *place)
|
|||||||
cairo_region_destroy (region);
|
cairo_region_destroy (region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: does it really redraw the entire keyboard?
|
||||||
static void
|
static void
|
||||||
render_released_button (GtkWidget *widget,
|
render_released_button (GtkWidget *widget,
|
||||||
struct squeek_button *button)
|
const struct squeek_button *button)
|
||||||
{
|
{
|
||||||
(void)button;
|
(void)button;
|
||||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||||
@ -515,7 +534,7 @@ on_button_pressed (struct squeek_button *button,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_button_released (struct squeek_button *button,
|
on_button_released (const struct squeek_button *button,
|
||||||
struct squeek_view *view,
|
struct squeek_view *view,
|
||||||
EekGtkKeyboard *self)
|
EekGtkKeyboard *self)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -55,10 +55,9 @@ eek_modifier_key_free (EekModifierKey *modkey)
|
|||||||
/// and instead refer to the contained symbols
|
/// and instead refer to the contained symbols
|
||||||
static guint
|
static guint
|
||||||
set_key_states (LevelKeyboard *keyboard,
|
set_key_states (LevelKeyboard *keyboard,
|
||||||
struct squeek_button *button,
|
struct squeek_key *key,
|
||||||
guint new_level)
|
guint new_level)
|
||||||
{
|
{
|
||||||
struct squeek_key *key = squeek_button_get_key(button);
|
|
||||||
// Keys locking rules hardcoded for the time being...
|
// Keys locking rules hardcoded for the time being...
|
||||||
const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
|
const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
|
||||||
// Lock the shift whenever it's pressed on the baselevel
|
// Lock the shift whenever it's pressed on the baselevel
|
||||||
@ -66,19 +65,19 @@ set_key_states (LevelKeyboard *keyboard,
|
|||||||
if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
|
if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
|
||||||
EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
|
EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
|
||||||
modifier_key->modifiers = 0;
|
modifier_key->modifiers = 0;
|
||||||
modifier_key->button = button;
|
modifier_key->key = key;
|
||||||
keyboard->locked_buttons =
|
keyboard->locked_keys =
|
||||||
g_list_prepend (keyboard->locked_buttons, modifier_key);
|
g_list_prepend (keyboard->locked_keys, modifier_key);
|
||||||
squeek_key_set_locked(key, true);
|
squeek_key_set_locked(key, true);
|
||||||
}
|
}
|
||||||
if (keyboard->level == 1) {
|
if (keyboard->level == 1) {
|
||||||
// Only shift is locked in this state, unlock on any key press
|
// Only shift is locked in this state, unlock on any key press
|
||||||
for (GList *head = keyboard->locked_buttons; head; ) {
|
for (GList *head = keyboard->locked_keys; head; ) {
|
||||||
EekModifierKey *modifier_key = head->data;
|
EekModifierKey *modifier_key = head->data;
|
||||||
GList *next = g_list_next (head);
|
GList *next = g_list_next (head);
|
||||||
keyboard->locked_buttons =
|
keyboard->locked_keys =
|
||||||
g_list_remove_link (keyboard->locked_buttons, head);
|
g_list_remove_link (keyboard->locked_keys, head);
|
||||||
squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
|
squeek_key_set_locked(modifier_key->key, false);
|
||||||
g_list_free1 (head);
|
g_list_free1 (head);
|
||||||
head = next;
|
head = next;
|
||||||
}
|
}
|
||||||
@ -89,13 +88,13 @@ set_key_states (LevelKeyboard *keyboard,
|
|||||||
|
|
||||||
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
|
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
|
||||||
static void
|
static void
|
||||||
set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
|
set_level_from_press (LevelKeyboard *keyboard, struct squeek_key *key)
|
||||||
{
|
{
|
||||||
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
|
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
|
||||||
guint level = keyboard->level;
|
guint level = keyboard->level;
|
||||||
/* Handle non-emitting keys */
|
/* Handle non-emitting keys */
|
||||||
if (button) {
|
if (key) {
|
||||||
const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(squeek_button_get_key(button)));
|
const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
|
||||||
if (g_strcmp0(name, "show_numbers") == 0) {
|
if (g_strcmp0(name, "show_numbers") == 0) {
|
||||||
level = 2;
|
level = 2;
|
||||||
} else if (g_strcmp0(name, "show_letters") == 0) {
|
} else if (g_strcmp0(name, "show_letters") == 0) {
|
||||||
@ -107,15 +106,14 @@ set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboard->level = set_key_states(keyboard, button, level);
|
keyboard->level = set_key_states(keyboard, key, level);
|
||||||
|
|
||||||
eek_layout_update_layout(keyboard);
|
eek_layout_update_layout(keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) {
|
void eek_keyboard_press_key(LevelKeyboard *keyboard, struct squeek_key *key, guint32 timestamp) {
|
||||||
struct squeek_key *key = squeek_button_get_key(button);
|
|
||||||
squeek_key_set_pressed(key, TRUE);
|
squeek_key_set_pressed(key, TRUE);
|
||||||
keyboard->pressed_buttons = g_list_prepend (keyboard->pressed_buttons, button);
|
keyboard->pressed_keys = g_list_prepend (keyboard->pressed_keys, key);
|
||||||
|
|
||||||
struct squeek_symbol *symbol = squeek_key_get_symbol(key);
|
struct squeek_symbol *symbol = squeek_key_get_symbol(key);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
@ -131,26 +129,26 @@ void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *bu
|
|||||||
emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp);
|
emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eek_keyboard_release_button(LevelKeyboard *keyboard,
|
void eek_keyboard_release_key(LevelKeyboard *keyboard,
|
||||||
struct squeek_button *button,
|
struct squeek_key *key,
|
||||||
guint32 timestamp) {
|
guint32 timestamp) {
|
||||||
for (GList *head = keyboard->pressed_buttons; head; head = g_list_next (head)) {
|
for (GList *head = keyboard->pressed_keys; head; head = g_list_next (head)) {
|
||||||
if (head->data == button) {
|
if (squeek_key_equal(head->data, key)) {
|
||||||
keyboard->pressed_buttons = g_list_remove_link (keyboard->pressed_buttons, head);
|
keyboard->pressed_keys = g_list_remove_link (keyboard->pressed_keys, head);
|
||||||
g_list_free1 (head);
|
g_list_free1 (head);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct squeek_symbol *symbol = squeek_button_get_symbol(button);
|
struct squeek_symbol *symbol = squeek_key_get_symbol(key);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
set_level_from_press (keyboard, button);
|
set_level_from_press (keyboard, key);
|
||||||
|
|
||||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||||
|
|
||||||
guint keycode = squeek_key_get_keycode (squeek_button_get_key(button));
|
guint keycode = squeek_key_get_keycode (key);
|
||||||
|
|
||||||
emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp);
|
emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ G_BEGIN_DECLS
|
|||||||
struct _EekModifierKey {
|
struct _EekModifierKey {
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
EekModifierType modifiers;
|
EekModifierType modifiers;
|
||||||
struct squeek_button *button;
|
struct squeek_key *key;
|
||||||
};
|
};
|
||||||
typedef struct _EekModifierKey EekModifierKey;
|
typedef struct _EekModifierKey EekModifierKey;
|
||||||
|
|
||||||
@ -49,8 +49,8 @@ struct _LevelKeyboard {
|
|||||||
size_t keymap_len; // length of the data inside keymap_fd
|
size_t keymap_len; // length of the data inside keymap_fd
|
||||||
GArray *outline_array;
|
GArray *outline_array;
|
||||||
|
|
||||||
GList *pressed_buttons; // struct squeek_button*
|
GList *pressed_keys; // struct squeek_key*
|
||||||
GList *locked_buttons; // struct squeek_button*
|
GList *locked_keys; // struct EekModifierKey*
|
||||||
|
|
||||||
/* Map button names to button objects: */
|
/* Map button names to button objects: */
|
||||||
GHashTable *names;
|
GHashTable *names;
|
||||||
@ -78,8 +78,8 @@ EekModifierKey *eek_modifier_key_copy
|
|||||||
void eek_modifier_key_free
|
void eek_modifier_key_free
|
||||||
(EekModifierKey *modkey);
|
(EekModifierKey *modkey);
|
||||||
|
|
||||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
|
void eek_keyboard_press_key(LevelKeyboard *keyboard, struct squeek_key *key, guint32 timestamp);
|
||||||
void eek_keyboard_release_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
|
void eek_keyboard_release_key(LevelKeyboard *keyboard, struct squeek_key *key, guint32 timestamp);
|
||||||
|
|
||||||
gchar * eek_keyboard_get_keymap
|
gchar * eek_keyboard_get_keymap
|
||||||
(LevelKeyboard *keyboard);
|
(LevelKeyboard *keyboard);
|
||||||
|
|||||||
@ -992,6 +992,7 @@ eek_renderer_find_button_by_position (EekRenderer *renderer,
|
|||||||
|
|
||||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
|
/* Transform from widget coordinates to keyboard coordinates */
|
||||||
EekPoint point = {
|
EekPoint point = {
|
||||||
.x = (x - priv->origin_x)/priv->scale,
|
.x = (x - priv->origin_x)/priv->scale,
|
||||||
.y = (y - priv->origin_y)/priv->scale,
|
.y = (y - priv->origin_y)/priv->scale,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef __KEYBOARD_H
|
#ifndef __KEYBOARD_H
|
||||||
#define __KYBOARD_H
|
#define __KEYBOARD_H
|
||||||
|
|
||||||
#include "stdbool.h"
|
#include "stdbool.h"
|
||||||
#include "inttypes.h"
|
#include "inttypes.h"
|
||||||
@ -19,6 +19,7 @@ uint32_t squeek_key_is_locked(struct squeek_key *key);
|
|||||||
void squeek_key_set_locked(struct squeek_key *key, uint32_t pressed);
|
void squeek_key_set_locked(struct squeek_key *key, uint32_t pressed);
|
||||||
uint32_t squeek_key_get_keycode(struct squeek_key *key);
|
uint32_t squeek_key_get_keycode(struct squeek_key *key);
|
||||||
void squeek_key_set_keycode(struct squeek_key *key, uint32_t keycode);
|
void squeek_key_set_keycode(struct squeek_key *key, uint32_t keycode);
|
||||||
|
uint32_t squeek_key_equal(struct squeek_key* key, struct squeek_key* key1);
|
||||||
|
|
||||||
struct squeek_symbol *squeek_key_get_symbol(struct squeek_key* key);
|
struct squeek_symbol *squeek_key_get_symbol(struct squeek_key* key);
|
||||||
const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_key *key);
|
const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_key *key);
|
||||||
|
|||||||
@ -47,6 +47,13 @@ pub mod c {
|
|||||||
unsafe { key.unwrap() }; // reference dropped
|
unsafe { key.unwrap() }; // reference dropped
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compares pointers to the data
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_key_equal(key: CKeyState, key2: CKeyState) -> u32 {
|
||||||
|
return Rc::ptr_eq(&key.clone_ref(), &key2.clone_ref()) as u32
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C"
|
pub extern "C"
|
||||||
fn squeek_key_is_pressed(key: CKeyState) -> u32 {
|
fn squeek_key_is_pressed(key: CKeyState) -> u32 {
|
||||||
|
|||||||
Reference in New Issue
Block a user