( t m ) replaced with trademark symbol
[rfk] / rfk.c
diff --git a/rfk.c b/rfk.c
index c091dd4..55be231 100644 (file)
--- a/rfk.c
+++ b/rfk.c
@@ -46,7 +46,7 @@ const GdkColor black = { 0, };
 /* Random object descriptions.                                  */
 /****************************************************************/
 
-char *
+static char *
 description (void)
 {
   int r;
@@ -56,8 +56,8 @@ description (void)
       r = random() % nki_count;
     }
   while (used[r]);
-
   used[r] = TRUE;
+
   return g_slist_nth_data (nki, r);
 }
 
@@ -65,7 +65,7 @@ description (void)
 /* Placing objects.                                             */
 /****************************************************************/
 
-void
+static void
 place_in_arena_at_xy (GtkWidget *item, int x, int y)
 {
   arena[x][y] = item;
@@ -82,7 +82,7 @@ place_in_arena_at_xy (GtkWidget *item, int x, int y)
     }
 }
 
-void
+static void
 place_in_arena_randomly (GtkWidget *item)
 {
   int x, y;
@@ -101,7 +101,7 @@ place_in_arena_randomly (GtkWidget *item)
 /* Labels representing things the robot might find.             */
 /****************************************************************/
 
-GtkWidget *
+static GtkWidget *
 random_character (gchar *description)
 {
   gchar character[2] = { random() % ('~'-'!') + '!', 0 };
@@ -125,7 +125,7 @@ random_character (gchar *description)
 /* Talking back to the user.                                    */
 /****************************************************************/
 
-void
+static void
 show_message (const char *message)
 {
   HildonNote* note = HILDON_NOTE
@@ -139,7 +139,8 @@ show_message (const char *message)
 /****************************************************************/
 /* Loading the non-kitten objects.                              */
 /****************************************************************/
-void
+
+static void
 ensure_messages_loaded (void)
 {
   FILE *nki_file = NULL;
@@ -184,11 +185,9 @@ ensure_messages_loaded (void)
     }
 
   fclose (nki_file);
-
-  used = g_malloc0 (nki_count);
 }
 
-void
+static void
 load_images (void)
 {
   robot_pic = gdk_pixbuf_new_from_file ("/usr/share/rfk/rfk-robot.png", NULL);
@@ -199,6 +198,7 @@ load_images (void)
 /****************************************************************/
 /* Stop doing that, and do something else.                      */
 /****************************************************************/
+
 static void
 switch_state (StateOfPlay new_state)
 {
@@ -216,15 +216,73 @@ switch_state (StateOfPlay new_state)
 }
 
 /****************************************************************/
+/* Things we need DBus for: online help, and vibration.         */
+/****************************************************************/
+
+static void
+call_dbus (DBusBusType type,
+          char *name,
+          char *path,
+          char *interface,
+          char *method,
+          char *parameter)
+{
+  DBusGConnection *connection;
+  GError *error = NULL;
+
+  DBusGProxy *proxy;
+
+  connection = dbus_g_bus_get (type,
+                               &error);
+  if (connection == NULL)
+    {
+      show_message (error->message);
+      g_error_free (error);
+      return;
+    }
+
+  proxy = dbus_g_proxy_new_for_name (connection, name, path, interface);
+
+  error = NULL;
+  if (!dbus_g_proxy_call (proxy, method, &error,
+                         G_TYPE_STRING, parameter,
+                         G_TYPE_INVALID,
+                         G_TYPE_INVALID))
+    {
+      show_message (error->message);
+      g_error_free (error);
+    }
+}
+
+static gboolean
+get_help (gpointer button, gpointer data)
+{
+  call_dbus (DBUS_BUS_SESSION,
+            "com.nokia.osso_browser",
+            "/com/nokia/osso_browser/request",
+            "com.nokia.osso_browser",
+            "load_url",
+            "/usr/share/rfk/help.html");
+  return FALSE;
+}
+
+static void
+vibrate (void)
+{
+  call_dbus (DBUS_BUS_SYSTEM,
+            "com.nokia.mce",
+            "/com/nokia/mce/request",
+            "com.nokia.mce.request",
+            "req_vibrator_pattern_activate",
+            "PatternIncomingMessage");
+}
+
+/****************************************************************/
 /* The ending animation.                                        */
 /****************************************************************/
 
 gboolean animation_running = FALSE;
 
-/*
-static gboolean
-love_animation_draw
-*/
 static gboolean
 ending_animation_quit (gpointer data)
 {
@@ -294,14 +352,20 @@ ending_animation_draw (GtkWidget *widget, GdkEventExpose *event, gpointer data)
       gdk_draw_pixbuf (GDK_DRAWABLE(widget->window),
                       gc,
                       scaled_love_pic, 0, 0,
-                      robot_x + gdk_pixbuf_get_width (robot_pic), all_y,
+                      robot_x + gdk_pixbuf_get_width (robot_pic) +
+                      (gdk_pixbuf_get_width (love_pic)-love_size)/2,
+                      all_y + (gdk_pixbuf_get_height (love_pic)-love_size)/2,
                       -1, -1,
                       GDK_RGB_DITHER_NONE, 0, 0);
 
-      love_size ++;
+      love_size += 10;
 
       if (love_size >= gdk_pixbuf_get_width (love_pic))
        {
+         /* all done! */
+         
+         vibrate ();
+         
          animation_running = FALSE;
 
          g_timeout_add (2000, ending_animation_quit, NULL);
@@ -366,7 +430,7 @@ direction directions[] = {
   { GDK_Up,        'k',  0, -1 }
 };
 
-gboolean
+static gboolean
 move_robot (guint8 whichway)
 {
   GtkWidget *new_space;
@@ -417,7 +481,7 @@ move_robot (guint8 whichway)
 /* Event handlers.                                              */
 /****************************************************************/
 
-gboolean
+static gboolean
 on_window_clicked (GtkWidget      *widget,
                   GdkEventButton *event,
                   gpointer        user_data)
@@ -443,7 +507,7 @@ on_window_clicked (GtkWidget      *widget,
   return TRUE;
 }
 
-gboolean
+static gboolean
 on_key_pressed (GtkWidget      *widget,
                GdkEventKey    *event,
                gpointer        user_data)
@@ -481,54 +545,35 @@ on_key_pressed (GtkWidget      *widget,
        }
     }
 
-  return FALSE;
-}
-
-/****************************************************************/
-/* Online help.                                                 */
-/****************************************************************/
-gboolean
-get_help (gpointer button, gpointer data)
-{
-  DBusGConnection *connection;
-  GError *error = NULL;
-
-  DBusGProxy *proxy;
-
-  connection = dbus_g_bus_get (DBUS_BUS_SESSION,
-                               &error);
-  if (connection == NULL)
+  if (keyval=='d' && event->state & GDK_CONTROL_MASK)
     {
-      show_message (error->message);
-      g_error_free (error);
-      return FALSE;
+      /* secret debugging key */
+      show_message (gtk_label_get_text (GTK_LABEL (kitten)));
     }
 
-  proxy = dbus_g_proxy_new_for_name (connection,
-                                     "com.nokia.osso_browser",
-                                     "/com/nokia/osso_browser/request",
-                                     "com.nokia.osso_browser");
-
-  error = NULL;
-  if (!dbus_g_proxy_call (proxy, "load_url", &error,
-                         G_TYPE_STRING, "/usr/share/rfk/help.html",
-                         G_TYPE_INVALID,
-                         G_TYPE_INVALID))
-    {
-      show_message (error->message);
-      g_error_free (error);
-      return FALSE;
-    }
   return FALSE;
 }
 
-void
+static void
 play_game (gpointer button, gpointer data)
 {
   switch_state (STATE_PLAYING);
 }
 
 static void
+restart (gpointer button, gpointer data)
+{
+  if (current_state == STATE_EPILOGUE)
+    {
+      show_message ("Have patience while robotfindskitten.");
+    }
+  else
+    {
+      switch_state (STATE_PROLOGUE);
+    }
+}
+
+static void
 set_up_board (void)
 {
   guint x, y;
@@ -553,6 +598,9 @@ set_up_board (void)
     {
       /* make everything new */
   
+      g_free (used);
+      used = g_malloc0 (nki_count * sizeof(gboolean));
+
       robot = gtk_label_new ("#");
       g_object_ref (robot);
       kitten = random_character ("You found kitten!  Way to go, robot!");
@@ -583,7 +631,7 @@ set_up_widgets (void)
 {
   GtkWidget *middle = gtk_hbox_new (FALSE, 0);
   GtkWidget *buttons = gtk_hbox_new (TRUE, 0);
-  GtkWidget *explain = NULL, *help_button, *play_button, *intro;
+  GtkWidget *explain = NULL, *button, *intro;
   const char *explanation =
     "In this game, you are robot (#). "
     "Your job is to find kitten. This task is complicated "
@@ -595,10 +643,11 @@ set_up_widgets (void)
   GKeyFile *desktop = g_key_file_new ();
   gchar *version;
   guint x, y;
+  HildonAppMenu *menu = HILDON_APP_MENU (hildon_app_menu_new ());
   
   /* The window */
 
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  window = hildon_window_new ();
   gtk_window_set_title (GTK_WINDOW (window), "robotfindskitten");
   gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &black);
   g_signal_connect (G_OBJECT (window), "button-press-event", G_CALLBACK (on_window_clicked), NULL);
@@ -607,6 +656,9 @@ set_up_widgets (void)
 
   /* The prologue */
 
+  /* Get the rather odd version string.  The RFK spec says that
+   * it should read v<major>.<minor>.<number-of-NKIs>.
+   */
   if (g_key_file_load_from_file (desktop,
                                 "/usr/share/applications/hildon/rfk.desktop",
                                 G_KEY_FILE_NONE,
@@ -622,18 +674,30 @@ set_up_widgets (void)
       version = g_strdup("");
     }
 
-  help_button = hildon_button_new_with_text (HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_THUMB_HEIGHT,
+  button = hildon_button_new_with_text (HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_THUMB_HEIGHT,
                                             HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
-                                            "Help", NULL);
-  g_signal_connect (help_button, "clicked", G_CALLBACK (get_help), NULL);
+                                            "Play", NULL);
+  g_signal_connect (button, "clicked", G_CALLBACK (play_game), NULL);
 
-  play_button = hildon_button_new_with_text (HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_THUMB_HEIGHT,
+  gtk_box_pack_end (GTK_BOX (buttons), button, TRUE, TRUE, 0);
+
+  button = hildon_button_new_with_text (HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_THUMB_HEIGHT,
                                             HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
-                                            "Play", NULL);
-  g_signal_connect (play_button, "clicked", G_CALLBACK (play_game), NULL);
+                                            "Help", NULL);
+  g_signal_connect (button, "clicked", G_CALLBACK (get_help), NULL);
+  gtk_box_pack_end (GTK_BOX (buttons), button, TRUE, TRUE, 0);
+
+  /* and another help button, this time for the menu */
+  button = gtk_button_new_with_label ("Help");
+  g_signal_connect (button, "clicked", G_CALLBACK (get_help), NULL);
+  hildon_app_menu_append (menu, GTK_BUTTON (button));
+
+  button = gtk_button_new_with_label ("Restart");
+  g_signal_connect (button, "clicked", G_CALLBACK (restart), NULL);
+  hildon_app_menu_append (menu, GTK_BUTTON (button));
 
-  gtk_box_pack_end (GTK_BOX (buttons), play_button, TRUE, TRUE, 0);
-  gtk_box_pack_end (GTK_BOX (buttons), help_button, TRUE, TRUE, 0);
+  gtk_widget_show_all (GTK_WIDGET (menu));
+  hildon_window_set_app_menu (HILDON_WINDOW (window), menu);
 
   explain = gtk_label_new (explanation);
   gtk_label_set_line_wrap (GTK_LABEL (explain), TRUE);