[clutter/android-enter-leave: 11/29] android: prevent mainloop from starving on events



commit 0890887714389ac13fac246fcb3a6d1ee8b50b46
Author: Lionel Landwerlin <llandwerlin gmail com>
Date:   Mon May 28 14:52:08 2012 +0100

    android: prevent mainloop from starving on events

 clutter/android/clutter-android-application.c |   37 ++++++++++++---------
 clutter/android/clutter-backend-android.c     |    4 ++
 clutter/android/clutter-event-android.c       |   43 +++++++++++++++++++++++-
 clutter/android/clutter-event-android.h       |    3 ++
 4 files changed, 69 insertions(+), 18 deletions(-)
---
diff --git a/clutter/android/clutter-android-application.c b/clutter/android/clutter-android-application.c
index d0b2f6d..e5057d8 100644
--- a/clutter/android/clutter-android-application.c
+++ b/clutter/android/clutter-android-application.c
@@ -35,11 +35,11 @@
 #include "clutter-marshal.h"
 #include "clutter-private.h"
 #include "clutter-device-manager-private.h"
-#include "clutter-event-private.h"
 #include "clutter-stage-private.h"
 
 #include "clutter-android-application-private.h"
 #include "clutter-android-keycodes.h"
+#include "clutter-event-android.h"
 #include "clutter-stage-android.h"
 
 #include "android_native_app_glue.h"
@@ -227,7 +227,7 @@ clutter_android_handle_cmd (struct android_app *app,
     }
 }
 
-static gboolean
+static ClutterEvent *
 translate_motion_event (AInputEvent *a_event)
 {
   int32_t action;
@@ -276,19 +276,17 @@ translate_motion_event (AInputEvent *a_event)
 
     default:
       g_message ("\tmeh? %i\n", action);
-      return FALSE;
+      return NULL;
     }
 
   event->any.stage =
     clutter_stage_manager_get_default_stage (clutter_stage_manager_get_default ());
   _clutter_input_device_set_stage (pointer_device, event->any.stage);
 
-  _clutter_event_push (event, FALSE);
-
-  return TRUE;
+  return event;
 }
 
-static gboolean
+static ClutterEvent *
 translate_key_event (AInputEvent *a_event)
 {
   int32_t action;
@@ -328,11 +326,11 @@ translate_key_event (AInputEvent *a_event)
 
     case AKEY_EVENT_ACTION_MULTIPLE:
       g_message ("\tcomplex string");
-      return FALSE;
+      return NULL;
 
     default:
       g_message ("\tmeh? %i", action);
-      return FALSE;
+      return NULL;
     }
 
   _clutter_android_translate_key_event ((ClutterKeyEvent *) event,
@@ -344,11 +342,9 @@ translate_key_event (AInputEvent *a_event)
     clutter_stage_manager_get_default_stage (clutter_stage_manager_get_default ());
   _clutter_input_device_set_stage (keyboard_device, event->any.stage);
 
-  _clutter_event_push (event, FALSE);
-
   application->modifier_state = new_modifier_state;
 
-  return TRUE;
+  return event;
 }
 
 /**
@@ -358,20 +354,29 @@ static int32_t
 clutter_android_handle_input (struct android_app *app,
                               AInputEvent        *a_event)
 {
-  gboolean process = FALSE;
+  ClutterEvent *event = NULL;
 
   g_message ("input!");
 
   if (AInputEvent_getType (a_event) == AINPUT_EVENT_TYPE_KEY)
     {
-      process = translate_key_event (a_event);
+      event = translate_key_event (a_event);
     }
   else if (AInputEvent_getType (a_event) == AINPUT_EVENT_TYPE_MOTION)
     {
-      process = translate_motion_event (a_event);
+      event = translate_motion_event (a_event);
+    }
+
+  if (event != NULL)
+    {
+      ClutterBackendAndroid *backend = (ClutterBackendAndroid *) clutter_get_default_backend ();
+
+      _clutter_event_source_android_push_event (backend->android_source, event);
+
+      return TRUE;
     }
 
-  return (int32_t) process;
+  return FALSE;
 }
 
 void
diff --git a/clutter/android/clutter-backend-android.c b/clutter/android/clutter-backend-android.c
index ca9c90b..7a3c257 100644
--- a/clutter/android/clutter-backend-android.c
+++ b/clutter/android/clutter-backend-android.c
@@ -64,6 +64,10 @@ clutter_backend_android_init (ClutterBackendAndroid *backend_android)
 static void
 clutter_backend_android_dispose (GObject *object)
 {
+  ClutterBackendAndroid *backend_android = CLUTTER_BACKEND_ANDROID (object);
+
+  g_source_unref (backend_android->android_source);
+
   G_OBJECT_CLASS (clutter_backend_android_parent_class)->dispose (object);
 }
 
diff --git a/clutter/android/clutter-event-android.c b/clutter/android/clutter-event-android.c
index a68eccb..22876b8 100644
--- a/clutter/android/clutter-event-android.c
+++ b/clutter/android/clutter-event-android.c
@@ -28,15 +28,22 @@
 
 #include <stdint.h>
 #include <stdlib.h>
+#include <unistd.h>
 
-#include "clutter-event.h"
+#include <glib.h>
+
+#include "clutter-event-private.h"
 #include "clutter-main.h"
 
 #include "clutter-event-android.h"
 
+
 typedef struct _ClutterEventSourceAndroid
 {
   GSource source;
+  GPollFD pfd;
+
+  int pipe[2];
 } ClutterEventSourceAndroid;
 
 static gboolean
@@ -59,10 +66,11 @@ static gboolean
 clutter_event_source_android_check (GSource *base)
 {
   gboolean retval;
+  ClutterEventSourceAndroid *source = (ClutterEventSourceAndroid *) base;
 
   clutter_threads_enter ();
 
-  retval = clutter_events_pending ();
+  retval = clutter_events_pending () || source->pfd.revents;
 
   clutter_threads_leave ();
 
@@ -74,12 +82,20 @@ clutter_event_source_android_dispatch (GSource *base,
 				       GSourceFunc callback,
 				       gpointer data)
 {
+  ClutterEventSourceAndroid *source = (ClutterEventSourceAndroid *) base;
   ClutterEvent *event;
+  int dummy;
 
   clutter_threads_enter ();
 
   event = clutter_event_get ();
 
+  if (source->pfd.revents)
+    {
+      read (source->pipe[0], &dummy, sizeof (dummy));
+      source->pfd.revents = 0;
+    }
+
   if (event)
     {
       /* forward the event into clutter for emission etc. */
@@ -108,5 +124,28 @@ _clutter_event_source_android_new (void)
     g_source_new (&clutter_event_source_android_funcs,
                   sizeof (ClutterEventSourceAndroid));
 
+  if (pipe (source->pipe) == -1)
+    {
+      g_critical ("Cannot not create a pipe for event source");
+      g_source_unref (&source->source);
+      return NULL;
+    }
+
+  source->pfd.fd = source->pipe[0];
+  source->pfd.events = G_IO_IN | G_IO_ERR;
+  g_source_add_poll (&source->source, &source->pfd);
+
   return &source->source;
 }
+
+void
+_clutter_event_source_android_push_event (GSource *source,
+                                          ClutterEvent *event)
+{
+  ClutterEventSourceAndroid *asource = (ClutterEventSourceAndroid *) source;
+  const int dummy = 42;
+
+  _clutter_event_push (event, FALSE);
+
+  write (asource->pipe[1], &dummy, sizeof (dummy));
+}
diff --git a/clutter/android/clutter-event-android.h b/clutter/android/clutter-event-android.h
index 2265071..a8d47af 100644
--- a/clutter/android/clutter-event-android.h
+++ b/clutter/android/clutter-event-android.h
@@ -31,4 +31,7 @@
 
 GSource * _clutter_event_source_android_new (void);
 
+void _clutter_event_source_android_push_event (GSource *source,
+                                               ClutterEvent *event);
+
 #endif /* __CLUTTER_EVENT_ANDROID_H__ */



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