From c03fe0d1dc69b0322853d4ca4862ece10d942f66 Mon Sep 17 00:00:00 2001
From: Bradley Smith
Date: Wed, 12 Mar 2008 17:10:36 +0000
Subject: Make UI update in a loop, and thread out input.

Signed-off-by: Bradley Smith <brad@brad-smith.co.uk>
---
 include/userinterface.h |  2 ++
 lib/x11plugin.c         | 17 +++++++++++++----
 src/Makefile.am         |  2 +-
 src/main.c              | 26 +++++++++++++++++++-------
 src/userinterface.c     |  5 +++++
 5 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/include/userinterface.h b/include/userinterface.h
index ef86f74..c67d364 100644
--- a/include/userinterface.h
+++ b/include/userinterface.h
@@ -53,6 +53,7 @@ struct _UserInterfaceClass {
                          gint y,
                          gint thing);
 
+  void  (* user_interface_run)            (UserInterface *ui);
   void  (* user_interface_draw)           (UserInterface *ui);
 
   void  (* user_interface_update_status)  (UserInterface *ui,
@@ -134,6 +135,7 @@ void    user_interface_add_thing        (UserInterface *ui,
                      gint y,
                      gint thing);
 
+void    user_interface_run              (UserInterface *ui);
 void    user_interface_draw             (UserInterface *ui);
 
 void    user_interface_update_status    (UserInterface *ui,
diff --git a/lib/x11plugin.c b/lib/x11plugin.c
index 0d9436b..b46b5cd 100644
--- a/lib/x11plugin.c
+++ b/lib/x11plugin.c
@@ -118,6 +118,8 @@ x11_plugin_constructor (GType type,
 
   x11 = X11_PLUGIN (object);
 
+  XInitThreads();
+
   if ((x11->dpy = XOpenDisplay ("")) == NULL) {
     g_printf ("Couldn't open the X Server Display!\n");
     exit (1);       /* Exit nicely isn't needed yet, and causes segfault */
@@ -147,7 +149,7 @@ x11_plugin_constructor (GType type,
   XSetWMHints (x11->dpy, x11->x_win, &wmhints);
 
   XSelectInput (x11->dpy, x11->x_win,
-      KeyPressMask | KeyReleaseMask | StructureNotifyMask
+      ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask
       | FocusChangeMask);
 
   XMapWindow (x11->dpy, x11->x_win);
@@ -597,12 +599,15 @@ inline void x11_plugin_update_status (X11Plugin *x11,
 				   glong score,
 				   glong shields)
 {
+  x11_update_status (x11, s, energy, score, shields);
+}
+
+inline void x11_plugin_run(X11Plugin* x11)
+{
   XEvent ev;
   XClientMessageEvent* evt;
 
-  x11_update_status (x11, s, energy, score, shields);
-
-  while (XPending (x11->dpy))
+  while (TRUE)
   {
     XNextEvent (x11->dpy, &ev);
 
@@ -625,6 +630,9 @@ inline void x11_plugin_update_status (X11Plugin *x11,
           exit(0);
         }
         break;
+      case Expose:
+        x11_plugin_draw(x11);
+        break;
     }
   }
 
@@ -752,6 +760,7 @@ static void x11_plugin_interface_init (gpointer g_iface, gpointer iface_data)
 				               gint thing))
 	  			    x11_plugin_add_thing;
 
+  klass->user_interface_run = (void(*)(UserInterface *ui)) x11_plugin_run;
   klass->user_interface_draw = (void (*) (UserInterface *ui)) x11_plugin_draw;
   klass->user_interface_update_status = (void (*) (UserInterface *ui,
 				  	 	   const gchar *s,
diff --git a/src/Makefile.am b/src/Makefile.am
index 865a5de..8cdb716 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,4 +26,4 @@ INCLUDES = $(GLIB2_CFLAGS) $(GUILE_CFLAGS) -I$(top_builddir)/include \
 	   -DSCRIPTS_PATH=\"$(schemedir)\"
 
 gnurobots_SOURCES = main.c api.c map.c grobot.c userinterface.c
-gnurobots_LDFLAGS = $(GLIB2_LIBS) $(GUILE_LDFLAGS) -lltdl
+gnurobots_LDFLAGS = $(GLIB2_LIBS) $(GUILE_LDFLAGS) -lltdl -lgthread-2.0
diff --git a/src/main.c b/src/main.c
index ed5378a..2dd9c16 100644
--- a/src/main.c
+++ b/src/main.c
@@ -59,6 +59,7 @@ Map *map;
 GModule *plugin;
 
 UserInterface *load_ui_module (gchar *module_name, Map *map);
+gpointer callback(gpointer data);
 SCM catch_handler (void *data, SCM tag, SCM throw_args);
 gint is_file_readable (const gchar *filename);
 
@@ -331,6 +332,7 @@ main_prog (void *closure, gint argc, gchar *argv[])
 
   /* draw the map */
   user_interface_draw (ui);
+  user_interface_update_status (ui, "", -1, -1, -1);
 
   if (strlen (robot_program) != 0)
   {
@@ -342,16 +344,19 @@ main_prog (void *closure, gint argc, gchar *argv[])
   else
   {
     gchar buff[BUFF_LEN];
-    SCM value;
 
-    g_printf ("Robot program not specified. Entering interactive mode..\n");
-    user_interface_update_status (ui, "", -1, -1, -1);
-    while (1)
+    g_thread_init(NULL);
+
+    g_printf("Robot program not specified. Entering interactive mode..\n");
+
+    g_thread_create(callback, NULL, FALSE, NULL);
+
+    while(1)
     {
       user_interface_get_string (ui, "guile> ", buff, BUFF_LEN);
-      value = scm_internal_catch (SCM_BOOL_T,
-                  (scm_t_catch_body) scm_c_eval_string,
-                  (void *) buff, catch_handler, NULL);
+
+      scm_internal_catch (SCM_BOOL_T, (scm_t_catch_body) scm_c_eval_string,
+            (void *) buff, catch_handler, NULL);
     }
   }
 
@@ -359,6 +364,13 @@ main_prog (void *closure, gint argc, gchar *argv[])
   exit_nicely ();
 }
 
+gpointer callback(gpointer data)
+{
+  user_interface_run(ui);
+
+  return NULL;
+}
+
 /************************************************************************
  * SCM catch_handler (void *data, SCM tag, SCM throw_args);             *
  *                                                                      *
diff --git a/src/userinterface.c b/src/userinterface.c
index 8cee000..f31591f 100644
--- a/src/userinterface.c
+++ b/src/userinterface.c
@@ -88,6 +88,11 @@ user_interface_add_thing (UserInterface * ui, gint x, gint y, gint thing)
   USER_INTERFACE_GET_CLASS (ui)->user_interface_add_thing (ui, x, y, thing);
 }
 
+void user_interface_run(UserInterface* ui)
+{
+  USER_INTERFACE_GET_CLASS(ui)->user_interface_run(ui);
+}
+
 void
 user_interface_draw (UserInterface * ui)
 {
-- 
cgit v1.1