+ x11_redraw_goal(data, -1);
+}
+
+static void do_input_move(struct app_state *state, int x, int y)
+{
+ uint_least32_t *gp = state->board.game, prev[4];
+
+ memcpy(prev, gp, sizeof prev);
+ if (game_do_move(&state->board, x, y) == 0) {
+ uint_least32_t mask;
+
+ if (game_check_goal(&state->board)) {
+ int_fast32_t ms = game_finish(&state->board);
+ unsigned min, sec;
+
+ /* Negative time just means clock jumps and
+ * display headaches. */
+ if (ms < 0)
+ ms = 0;
+
+ sec = ms / 1000, ms %= 1000;
+ min = sec / 60, sec %= 60;
+ printf("You won! Time was %u:%.2u:%.3u\n",
+ min, sec, (unsigned)ms);
+ }
+
+ /* Figure out which tiles changed */
+ prev[0] ^= gp[0];
+ prev[1] ^= gp[1];
+ prev[2] ^= gp[2];
+ mask = prev[0] | prev[1] | prev[2];
+
+ x11_redraw_game(state, mask);
+ }
+}
+
+static void set_view_goal(struct app_state *state, int view_goal)
+{
+ state->view_goal_on_game = view_goal;
+ x11_redraw_game(state, GOAL_MASK);