[retro-gtk] retro-controller: Add 'state-changed' signal



commit a7ff5d924d99aa86eb3dab5e645163256c5806c9
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Tue Jan 14 14:50:04 2020 +0500

    retro-controller: Add 'state-changed' signal
    
    This will allow controllers to push their state in future. This should be
    emitted every time input state changes in any way.

 retro-gtk/retro-controller.c           | 23 +++++++++++++++
 retro-gtk/retro-controller.h           |  1 +
 retro-gtk/retro-core-view-controller.c |  6 ++++
 retro-gtk/retro-core-view.c            | 51 ++++++++++++++++++++++++++++++++++
 tests/retro-test-controller.c          | 20 +++++++++----
 5 files changed, 96 insertions(+), 5 deletions(-)
---
diff --git a/retro-gtk/retro-controller.c b/retro-gtk/retro-controller.c
index 0dba314..9dae85b 100644
--- a/retro-gtk/retro-controller.c
+++ b/retro-gtk/retro-controller.c
@@ -4,9 +4,24 @@
 
 G_DEFINE_INTERFACE (RetroController, retro_controller, G_TYPE_OBJECT);
 
+enum {
+  SIG_STATE_CHANGED_SIGNAL,
+  N_SIGNALS,
+};
+
+static guint signals[N_SIGNALS];
+
 static void
 retro_controller_default_init (RetroControllerInterface *iface)
 {
+  signals[SIG_STATE_CHANGED_SIGNAL] =
+    g_signal_new ("state-changed",
+                  G_TYPE_FROM_INTERFACE (iface),
+                  G_SIGNAL_RUN_FIRST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  0);
 }
 
 /**
@@ -151,3 +166,11 @@ retro_controller_set_rumble_state (RetroController   *self,
 
   iface->set_rumble_state (self, effect, strength);
 }
+
+void
+retro_controller_emit_state_changed (RetroController *self)
+{
+  g_return_if_fail (RETRO_IS_CONTROLLER (self));
+
+  g_signal_emit (self, signals[SIG_STATE_CHANGED_SIGNAL], 0);
+}
diff --git a/retro-gtk/retro-controller.h b/retro-gtk/retro-controller.h
index 5688336..8c8a6ca 100644
--- a/retro-gtk/retro-controller.h
+++ b/retro-gtk/retro-controller.h
@@ -40,5 +40,6 @@ gboolean retro_controller_get_supports_rumble (RetroController *self);
 void retro_controller_set_rumble_state (RetroController   *self,
                                         RetroRumbleEffect  effect,
                                         guint16            strength);
+void retro_controller_emit_state_changed (RetroController *self);
 
 G_END_DECLS
diff --git a/retro-gtk/retro-core-view-controller.c b/retro-gtk/retro-core-view-controller.c
index 37c5548..eb62f40 100644
--- a/retro-gtk/retro-core-view-controller.c
+++ b/retro-gtk/retro-core-view-controller.c
@@ -135,5 +135,11 @@ retro_core_view_controller_new (RetroCoreView       *view,
   g_weak_ref_init (&self->view, view);
   self->controller_type = controller_type;
 
+  g_signal_connect_object (view,
+                           "controller-state-changed",
+                           G_CALLBACK (retro_controller_emit_state_changed),
+                           self,
+                           G_CONNECT_SWAPPED);
+
   return self;
 }
diff --git a/retro-gtk/retro-core-view.c b/retro-gtk/retro-core-view.c
index 994335c..2d15aa1 100644
--- a/retro-gtk/retro-core-view.c
+++ b/retro-gtk/retro-core-view.c
@@ -45,6 +45,13 @@ enum {
 
 static GParamSpec *properties [N_PROPS];
 
+enum {
+  SIG_CONTROLLER_STATE_CHANGED_SIGNAL,
+  N_SIGNALS,
+};
+
+static guint signals [N_SIGNALS];
+
 /* Private */
 
 static void
@@ -151,6 +158,8 @@ retro_core_view_grab (RetroCoreView *self,
 
   recenter_pointer (self);
 
+  g_signal_emit (self, signals[SIG_CONTROLLER_STATE_CHANGED_SIGNAL], 0);
+
   g_object_unref (cursor);
 }
 
@@ -169,14 +178,20 @@ retro_core_view_ungrab (RetroCoreView *self)
 
   g_clear_object (&self->grabbed_device);
   g_clear_object (&self->grabbed_screen);
+
+  g_signal_emit (self, signals[SIG_CONTROLLER_STATE_CHANGED_SIGNAL], 0);
 }
 
+static gboolean retro_core_view_get_key_state (RetroCoreView *self,
+                                               guint16        hardware_keycode);
+
 static gboolean
 retro_core_view_on_key_press_event (GtkWidget   *source,
                                     GdkEventKey *event,
                                     gpointer     data)
 {
   RetroCoreView *self = RETRO_CORE_VIEW (data);
+  gboolean changed;
 
   g_return_val_if_fail (RETRO_IS_CORE_VIEW (self), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
@@ -186,9 +201,14 @@ retro_core_view_on_key_press_event (GtkWidget   *source,
       retro_core_view_get_is_pointer_grabbed (self))
     retro_core_view_ungrab (self);
 
+  changed = !retro_core_view_get_key_state (self, event->hardware_keycode);
+
   set_input_pressed (self->key_state, event->hardware_keycode);
   set_input_pressed (self->keyval_state, event->keyval);
 
+  if (changed)
+    g_signal_emit (self, signals[SIG_CONTROLLER_STATE_CHANGED_SIGNAL], 0);
+
   return FALSE;
 }
 
@@ -205,6 +225,8 @@ retro_core_view_on_key_release_event (GtkWidget   *source,
   set_input_released (self->key_state, event->hardware_keycode);
   set_input_released (self->keyval_state, event->keyval);
 
+  g_signal_emit (self, signals[SIG_CONTROLLER_STATE_CHANGED_SIGNAL], 0);
+
   return FALSE;
 }
 
@@ -239,6 +261,8 @@ retro_core_view_on_button_press_event (GtkWidget      *source,
                                                    &self->pointer_y);
   }
 
+  g_signal_emit (self, signals[SIG_CONTROLLER_STATE_CHANGED_SIGNAL], 0);
+
   return FALSE;
 }
 
@@ -254,6 +278,8 @@ retro_core_view_on_button_release_event (GtkWidget      *source,
 
   set_input_released (self->mouse_button_state, event->button);
 
+  g_signal_emit (self, signals[SIG_CONTROLLER_STATE_CHANGED_SIGNAL], 0);
+
   return FALSE;
 }
 
@@ -273,6 +299,8 @@ retro_core_view_on_focus_out_event (GtkWidget     *source,
   reset_input (self->key_state);
   reset_input (self->mouse_button_state);
 
+  g_signal_emit (self, signals[SIG_CONTROLLER_STATE_CHANGED_SIGNAL], 0);
+
   return FALSE;
 }
 
@@ -305,6 +333,8 @@ retro_core_view_on_motion_notify_event (GtkWidget      *source,
 
   }
 
+  g_signal_emit (self, signals[SIG_CONTROLLER_STATE_CHANGED_SIGNAL], 0);
+
   return FALSE;
 }
 
@@ -458,6 +488,27 @@ retro_core_view_class_init (RetroCoreViewClass *klass)
                                      N_PROPS,
                                      properties);
 
+  /**
+   * RetroCoreView::controller-state-changed:
+   * @self: the #RetroCoreView
+   *
+   * The ::controller-state-changed signal is emitted when a key is pressed
+   * or released, mouse pointer is moved, or a mouse button is pressed or
+   * released.
+   *
+   * Applications should not connect to it.
+   *
+   * Stability: Private
+   */
+  signals[SIG_CONTROLLER_STATE_CHANGED_SIGNAL] =
+    g_signal_new ("controller-state-changed",
+                  RETRO_TYPE_CORE_VIEW,
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE,
+                  0);
+
   gtk_widget_class_set_css_name (widget_class, "retrocoreview");
 }
 
diff --git a/tests/retro-test-controller.c b/tests/retro-test-controller.c
index 059cc17..7c8df6f 100644
--- a/tests/retro-test-controller.c
+++ b/tests/retro-test-controller.c
@@ -199,28 +199,38 @@ retro_test_controller_set_input_state (RetroTestController  *self,
 
   switch (state->type & RETRO_CONTROLLER_TYPE_TYPE_MASK) {
   case RETRO_CONTROLLER_TYPE_JOYPAD:
-    if (state->id < RETRO_JOYPAD_ID_COUNT)
+    if (state->id < RETRO_JOYPAD_ID_COUNT) {
       self->state[RETRO_CONTROLLER_TYPE_JOYPAD][state->id] = state->value;
+      retro_controller_emit_state_changed (RETRO_CONTROLLER (self));
+    }
 
     break;
   case RETRO_CONTROLLER_TYPE_MOUSE:
-    if (state->id < RETRO_MOUSE_ID_COUNT)
+    if (state->id < RETRO_MOUSE_ID_COUNT) {
       self->state[RETRO_CONTROLLER_TYPE_MOUSE][state->id] = state->value;
+      retro_controller_emit_state_changed (RETRO_CONTROLLER (self));
+    }
 
     break;
   case RETRO_CONTROLLER_TYPE_LIGHTGUN:
-    if (state->id < RETRO_LIGHTGUN_ID_COUNT)
+    if (state->id < RETRO_LIGHTGUN_ID_COUNT) {
       self->state[RETRO_CONTROLLER_TYPE_LIGHTGUN][state->id] = state->value;
+      retro_controller_emit_state_changed (RETRO_CONTROLLER (self));
+    }
 
     break;
   case RETRO_CONTROLLER_TYPE_ANALOG:
-    if (state->id < RETRO_ANALOG_ID_COUNT && state->index < RETRO_ANALOG_INDEX_COUNT)
+    if (state->id < RETRO_ANALOG_ID_COUNT && state->index < RETRO_ANALOG_INDEX_COUNT) {
       self->state[RETRO_CONTROLLER_TYPE_ANALOG][RETRO_ANALOG_ID_INDEX (state->id, state->index)] = 
state->value;
+      retro_controller_emit_state_changed (RETRO_CONTROLLER (self));
+    }
 
     break;
   case RETRO_CONTROLLER_TYPE_POINTER:
-    if (state->id < RETRO_POINTER_ID_COUNT)
+    if (state->id < RETRO_POINTER_ID_COUNT) {
       self->state[RETRO_CONTROLLER_TYPE_POINTER][state->id] = state->value;
+      retro_controller_emit_state_changed (RETRO_CONTROLLER (self));
+    }
 
     break;
   case RETRO_CONTROLLER_TYPE_NONE:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]