[gnome-games] gamepad: Make gamepad emit Event objects
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] gamepad: Make gamepad emit Event objects
- Date: Sun, 14 May 2017 17:07:05 +0000 (UTC)
commit d942798ba376b48146e93becd490b83f53948773
Author: Adrien Plazas <kekun plazas laposte net>
Date: Sat May 13 23:35:43 2017 +0200
gamepad: Make gamepad emit Event objects
Replace the 'button-event' and 'axis-event' signals from Gamepad by the
'button-press-event', 'button-release-event', 'axis-event' and
'hat-event' ones sending Event objects after mapping them is the Gamepad
object has a mapping, or directly if it doesn't.
https://bugzilla.gnome.org/show_bug.cgi?id=782611
src/gamepad/gamepad.c | 288 +++++++++++++++++++++++++-----------------
src/gamepad/gamepad.vapi | 6 +-
src/retro/retro-gamepad.vala | 5 +-
3 files changed, 176 insertions(+), 123 deletions(-)
---
diff --git a/src/gamepad/gamepad.c b/src/gamepad/gamepad.c
index 196be99..178c16a 100644
--- a/src/gamepad/gamepad.c
+++ b/src/gamepad/gamepad.c
@@ -19,8 +19,10 @@ G_DEFINE_TYPE (GamesGamepad, games_gamepad, G_TYPE_OBJECT)
enum {
SIGNAL_EVENT,
- SIGNAL_BUTTON_EVENT,
+ SIGNAL_BUTTON_PRESS_EVENT,
+ SIGNAL_BUTTON_RELEASE_EVENT,
SIGNAL_AXIS_EVENT,
+ SIGNAL_HAT_EVENT,
SIGNAL_UNPLUGGED,
LAST_SIGNAL,
};
@@ -30,137 +32,175 @@ static guint signals[LAST_SIGNAL] = { 0 };
/* Private */
static void
-on_button_event (GamesRawGamepad *sender,
- GamesEventGamepadButton *games_event,
- gpointer data)
+forward_event (GamesGamepad *self,
+ GamesEvent *event)
{
- GamesGamepad *self;
- GamesGamepadInput event;
- gboolean value;
-
- self = GAMES_GAMEPAD (data);
-
- g_return_if_fail (self != NULL);
+ switch (event->type) {
+ case GAMES_EVENT_GAMEPAD_BUTTON_PRESS:
+ g_signal_emit (self, signals[SIGNAL_BUTTON_PRESS_EVENT], 0, event);
- if (self->mapping == NULL)
return;
+ case GAMES_EVENT_GAMEPAD_BUTTON_RELEASE:
+ g_signal_emit (self, signals[SIGNAL_BUTTON_RELEASE_EVENT], 0, event);
- switch (games_event->type) {
- case GAMES_EVENT_GAMEPAD_BUTTON_PRESS:
- value = TRUE;
+ return;
+ case GAMES_EVENT_GAMEPAD_AXIS:
+ g_signal_emit (self, signals[SIGNAL_AXIS_EVENT], 0, event);
- break;
- case GAMES_EVENT_GAMEPAD_BUTTON_RELEASE:
- value = FALSE;
+ return;
+ case GAMES_EVENT_GAMEPAD_HAT:
+ g_signal_emit (self, signals[SIGNAL_HAT_EVENT], 0, event);
- break;
+ return;
default:
- g_assert_not_reached ();
-
- break;
+ return;
}
+}
+
+static void
+map_button_event (GamesGamepad *self,
+ GamesEventGamepadButton *games_event)
+{
+ GamesGamepadInput destination;
+ GamesEvent *mapped_event;
+ guint signal;
+ gboolean pressed;
+
+ mapped_event = games_event_copy ((GamesEvent *) games_event);
games_gamepad_mapping_get_button_mapping (self->mapping,
games_event->index,
- &event);
+ &destination);
- switch (event.type) {
+ pressed = games_event->type == GAMES_EVENT_GAMEPAD_BUTTON_PRESS;
+
+ mapped_event->any.send_event = TRUE;
+ mapped_event->gamepad.hardware_type = destination.type;
+ mapped_event->gamepad.hardware_code = destination.code;
+
+ switch (destination.type) {
case EV_ABS:
- g_signal_emit (self,
- signals[SIGNAL_AXIS_EVENT],
- 0, event.code, value ? 1 : 0);
+ signal = SIGNAL_AXIS_EVENT;
+ mapped_event->gamepad_axis.index = 0; // FIXME How to set it properly?
+ mapped_event->gamepad_axis.value = pressed ? 1 : 0;
break;
case EV_KEY:
- g_signal_emit (self,
- signals[SIGNAL_BUTTON_EVENT],
- 0, event.code, value);
+ signal = pressed ? SIGNAL_BUTTON_PRESS_EVENT : SIGNAL_BUTTON_RELEASE_EVENT;
+ mapped_event->gamepad_button.index = 0; // FIXME How to set it properly?
+
break;
default:
- break;
+ games_event_free (mapped_event);
+
+ return;
}
+
+ g_signal_emit (self, signals[signal], 0, mapped_event);
+
+ games_event_free (mapped_event);
}
static void
-on_axis_event (GamesRawGamepad *sender,
- GamesEventGamepadAxis *games_event,
- gpointer data)
+map_axis_event (GamesGamepad *self,
+ GamesEventGamepadAxis *games_event)
{
- GamesGamepad *self;
- GamesGamepadInput event;
+ GamesGamepadInput destination;
+ GamesEvent *mapped_event;
+ guint signal;
+ gboolean pressed;
- self = GAMES_GAMEPAD (data);
+ mapped_event = games_event_copy ((GamesEvent *) games_event);
+ games_gamepad_mapping_get_axis_mapping (self->mapping, games_event->index, &destination);
- g_return_if_fail (self != NULL);
+ pressed = games_event->value > 0.;
- if (self->mapping == NULL)
- return;
+ mapped_event->any.send_event = TRUE;
+ mapped_event->gamepad.hardware_type = destination.type;
+ mapped_event->gamepad.hardware_code = destination.code;
- games_gamepad_mapping_get_axis_mapping (self->mapping, games_event->index, &event);
- switch (event.type) {
+ switch (destination.type) {
case EV_ABS:
- g_signal_emit (self, signals[SIGNAL_AXIS_EVENT],
- 0, event.code, games_event->value);
+ signal = SIGNAL_AXIS_EVENT;
+ mapped_event->gamepad_axis.index = 0; // FIXME How to set it properly?
+
break;
case EV_KEY:
- g_signal_emit (self, signals[SIGNAL_BUTTON_EVENT],
- 0, event.code, games_event->value > 0.);
+ signal = pressed ? SIGNAL_BUTTON_PRESS_EVENT : SIGNAL_BUTTON_RELEASE_EVENT;
+ mapped_event->gamepad_button.index = 0; // FIXME How to set it properly?
break;
default:
- break;
+ games_event_free (mapped_event);
+
+ return;
}
+
+ g_signal_emit (self, signals[signal], 0, mapped_event);
+
+ games_event_free (mapped_event);
}
static void
-on_hat_event (GamesRawGamepad *sender,
- GamesEventGamepadHat *games_event,
- gpointer data)
+map_hat_event (GamesGamepad *self,
+ GamesEventGamepadHat *games_event)
{
- GamesGamepad *self;
- GamesGamepadInput event;
+ GamesGamepadInput destination;
+ GamesEvent *mapped_event;
+ guint signal;
+ gboolean pressed;
- self = GAMES_GAMEPAD (data);
+ mapped_event = games_event_copy ((GamesEvent *) games_event);
+ games_gamepad_mapping_get_dpad_mapping (self->mapping,
+ games_event->index,
+ games_event->axis,
+ games_event->value,
+ &destination);
- g_return_if_fail (self != NULL);
+ pressed = abs (games_event->value);
- if (self->mapping == NULL) {
- if (games_event->index != 0)
- return;
+ mapped_event->any.send_event = TRUE;
+ mapped_event->gamepad.hardware_type = destination.type;
+ mapped_event->gamepad.hardware_code = destination.code;
- switch (games_event->axis) {
- case 0:
- g_signal_emit (self, signals[SIGNAL_BUTTON_EVENT],
- 0, BTN_DPAD_LEFT, games_event->value < 0);
- g_signal_emit (self, signals[SIGNAL_BUTTON_EVENT],
- 0, BTN_DPAD_RIGHT, games_event->value > 0);
-
- break;
- case 1:
- g_signal_emit (self, signals[SIGNAL_BUTTON_EVENT],
- 0, BTN_DPAD_UP, games_event->value < 0);
- g_signal_emit (self, signals[SIGNAL_BUTTON_EVENT],
- 0, BTN_DPAD_DOWN, games_event->value > 0);
+ switch (destination.type) {
+ case EV_ABS:
+ signal = SIGNAL_AXIS_EVENT;
+ mapped_event->gamepad_axis.index = 0; // FIXME How to set it properly?
+ mapped_event->gamepad_axis.value = abs (games_event->value);
- break;
- default:
- g_debug ("Unexpected axis number: %d.", games_event->axis);
+ break;
+ case EV_KEY:
+ signal = pressed ? SIGNAL_BUTTON_PRESS_EVENT : SIGNAL_BUTTON_RELEASE_EVENT;
+ mapped_event->gamepad_button.index = 0; // FIXME How to set it properly?
- break;
- }
+ break;
+ default:
+ games_event_free (mapped_event);
return;
}
- games_gamepad_mapping_get_dpad_mapping (self->mapping, games_event->index, games_event->axis,
games_event->value, &event);
- switch (event.type) {
- case EV_ABS:
- g_signal_emit (self, signals[SIGNAL_AXIS_EVENT],
- 0, event.code, (gdouble) abs (games_event->value));
+ g_signal_emit (self, signals[signal], 0, mapped_event);
+
+ games_event_free (mapped_event);
+}
+
+static void
+map_event (GamesGamepad *self,
+ GamesEvent *event)
+{
+ switch (event->type) {
+ case GAMES_EVENT_GAMEPAD_BUTTON_PRESS:
+ case GAMES_EVENT_GAMEPAD_BUTTON_RELEASE:
+ map_button_event (self, &event->gamepad_button);
break;
- case EV_KEY:
- g_signal_emit (self, signals[SIGNAL_BUTTON_EVENT],
- 0, event.code, (gboolean) abs (games_event->value));
+ case GAMES_EVENT_GAMEPAD_AXIS:
+ map_axis_event (self, &event->gamepad_axis);
+
+ break;
+ case GAMES_EVENT_GAMEPAD_HAT:
+ map_hat_event (self, &event->gamepad_hat);
break;
default:
@@ -182,25 +222,9 @@ on_event (GamesRawGamepad *sender,
g_signal_emit (self, signals[SIGNAL_EVENT], 0, event);
if (self->mapping == NULL)
- return;
-
- switch (event->type) {
- case GAMES_EVENT_GAMEPAD_BUTTON_PRESS:
- case GAMES_EVENT_GAMEPAD_BUTTON_RELEASE:
- on_button_event (sender, &event->gamepad_button, data);
-
- break;
- case GAMES_EVENT_GAMEPAD_AXIS:
- on_axis_event (sender, &event->gamepad_axis, data);
-
- break;
- case GAMES_EVENT_GAMEPAD_HAT:
- on_hat_event (sender, &event->gamepad_hat, data);
-
- break;
- default:
- break;
- }
+ forward_event (self, event);
+ else
+ map_event (self, event);
}
static void
@@ -282,38 +306,64 @@ static void games_gamepad_class_init (GamesGamepadClass *klass) {
GAMES_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
- * GamesGamepad::axis-event:
- * @button: the code representing the button
- * @value: %TRUE if the button is pressed, %FALSE otherwise
+ * GamesGamepad::button-press-event:
+ * @event: the event emitted by the gamepad
*
- * Emitted when a button is pressed/released.
+ * Emitted when a button is pressed.
*/
- signals[SIGNAL_BUTTON_EVENT] =
- g_signal_new ("button-event",
+ signals[SIGNAL_BUTTON_PRESS_EVENT] =
+ g_signal_new ("button-press-event",
GAMES_TYPE_GAMEPAD,
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
- NULL,
- G_TYPE_NONE, 2,
- G_TYPE_UINT,
- G_TYPE_BOOLEAN);
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GAMES_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ /**
+ * GamesGamepad::button-release-event:
+ * @event: the event emitted by the gamepad
+ *
+ * Emitted when a button is released.
+ */
+ signals[SIGNAL_BUTTON_RELEASE_EVENT] =
+ g_signal_new ("button-release-event",
+ GAMES_TYPE_GAMEPAD,
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GAMES_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GamesGamepad::axis-event:
- * @axis: the code representing the axis
- * @value: the value of the axis ranging from -1 to 1
+ * @event: the event emitted by the gamepad
*
- * Emitted when a standard axis' value changes.
+ * Emitted when a axis' value changes.
*/
signals[SIGNAL_AXIS_EVENT] =
g_signal_new ("axis-event",
GAMES_TYPE_GAMEPAD,
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
- NULL,
- G_TYPE_NONE, 2,
- G_TYPE_UINT,
- G_TYPE_DOUBLE);
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GAMES_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ /**
+ * GamesGamepad::hat-event:
+ * @event: the event emitted by the gamepad
+ *
+ * Emitted when a axis from a hat's value changes.
+ */
+ signals[SIGNAL_HAT_EVENT] =
+ g_signal_new ("hat-event",
+ GAMES_TYPE_GAMEPAD,
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GAMES_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* GamesGamepad::unplugged:
diff --git a/src/gamepad/gamepad.vapi b/src/gamepad/gamepad.vapi
index 1e2fd2a..e52b030 100644
--- a/src/gamepad/gamepad.vapi
+++ b/src/gamepad/gamepad.vapi
@@ -3,8 +3,10 @@
[CCode (cheader_filename = "gamepad.h")]
private class Games.Gamepad : GLib.Object {
public signal void event (Event event);
- public signal void button_event (uint button, bool value);
- public signal void axis_event (uint axis, double value);
+ public signal void button_press_event (Event event);
+ public signal void button_release_event (Event event);
+ public signal void axis_event (Event event);
+ public signal void hat_event (Event event);
public signal void unplugged ();
public Gamepad (RawGamepad raw_gamepad) throws GLib.Error;
}
diff --git a/src/retro/retro-gamepad.vala b/src/retro/retro-gamepad.vala
index abb9f15..537cc4e 100644
--- a/src/retro/retro-gamepad.vala
+++ b/src/retro/retro-gamepad.vala
@@ -15,8 +15,9 @@ private class Games.RetroGamepad: Object, Retro.InputDevice {
buttons = new bool[EventCode.KEY_MAX + 1];
axes = new int16[EventCode.ABS_MAX + 1];
- gamepad.button_event.connect ((button, value) => buttons[button] = value);
- gamepad.axis_event.connect ((axis, value) => axes[axis] = (int16) (value * int16.MAX));
+ gamepad.button_press_event.connect ((event) => buttons[event.gamepad.hardware_code] = true);
+ gamepad.button_release_event.connect ((event) => buttons[event.gamepad.hardware_code] =
false);
+ gamepad.axis_event.connect ((event) => axes[event.gamepad.hardware_code] = (int16)
(event.gamepad_axis.value * int16.MAX));
}
public void poll () {}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]