+static int
+grr_game_printf (grr_game_t *game, const char *fmt, ...)
+{
+ int msg_id;
+
+ va_list ap;
+
+ va_start (ap, fmt);
+ msg_id = grr_game_vprintf (game, fmt, ap);
+ va_end (ap);
+
+ return msg_id;
+}
+
+static int
+grr_game_vprintf (grr_game_t *game, const char *fmt, va_list ap)
+{
+ char *msg;
+ int msg_id;
+
+ grr_sprintf_alloc_va (&msg, fmt, ap);
+ if (msg == NULL)
+ return 0;
+
+ msg_id = grr_game_print (game, msg);
+
+ free (msg);
+
+ return msg_id;
+}
+
+static int
+grr_game_print (grr_game_t *game, const char *msg)
+{
+ GtkTextIter iter;
+ GtkTextMark *mark;
+
+ /* There might be a lighter way to do this, but this seems to
+ work. */
+
+ gtk_text_buffer_get_end_iter (game->message_buffer, &iter);
+
+ mark = gtk_text_buffer_get_mark (game->message_buffer, "end");
+
+ gtk_text_buffer_move_mark (game->message_buffer, mark, &iter);
+
+ gtk_text_buffer_insert (game->message_buffer, &iter, msg, -1);
+
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (game->message_view),
+ mark, 0.0, TRUE, 0.0, 1.0);
+
+ return ++game->msg_id;
+}
+