]> git.cworth.org Git - mnemon/commitdiff
Add support for image-based challenges
authorCarl Worth <cworth@cworth.org>
Fri, 27 Mar 2009 22:05:08 +0000 (15:05 -0700)
committerCarl Worth <cworth@cworth.org>
Fri, 27 Mar 2009 22:05:08 +0000 (15:05 -0700)
The support right now is extremely cheesy. It depends on two
external programs (xli and killall), and also uses system()
to execute them with the shell (ick). Oh, and it will also
indiscriminately kill any innocent xli processes that happen
to get in the way. Clearly it's a pretty ugly hack.

mnemon.c

index 5ce736433eed2cff4c931dde86a39c490f8f15f0..d0a960909d43eb5ea8539fa67f78bb1b1c530812 100644 (file)
--- a/mnemon.c
+++ b/mnemon.c
@@ -55,6 +55,11 @@ typedef enum {
     CATEGORY_ORDER_SEQUENTIAL
 } category_order_t;
 
+typedef enum {
+    CHALLENGE_TYPE_TEXT,
+    CHALLENGE_TYPE_IMAGE
+} challenge_type_t;
+
 typedef struct _category {
     char *name;
     int items_size;
@@ -66,6 +71,8 @@ typedef struct _category {
     /* Support categories where responses are timed (0.0 == disable). */
     double time_limit;
     int bin_zero_head;
+    /* Support challenges of non-text types (image, audio, etc.) */
+    challenge_type_t challenge_type;
 } category_t;
 
 typedef struct _mnemon {
@@ -193,6 +200,7 @@ category_init (category_t *category,
     category->order = CATEGORY_ORDER_RANDOM;
     category->time_limit = 0.0;
     category->bin_zero_head = 0;
+    category->challenge_type = CHALLENGE_TYPE_TEXT;
 }
 
 static void
@@ -262,6 +270,17 @@ category_print (category_t *category,
     fprintf (file, "time = %f\n\n",
             category->time_limit);
 
+    fprintf (file, "challenge = ");
+    switch (category->challenge_type) {
+    case CHALLENGE_TYPE_TEXT:
+       fprintf (file, "text");
+       break;
+    case CHALLENGE_TYPE_IMAGE:
+       fprintf (file, "image");
+       break;
+    }
+    fprintf (file, "\n\n");
+
     for (i = 0; i < category->num_items; i++) {
        item = &category->items[i];
        if (i != 0)
@@ -618,6 +637,16 @@ mnemon_load_category (mnemon_t             *mnemon,
                         value, path, line_count);
                exit (1);
            }
+       } else if (strcmp (name, "challenge") == 0) {
+           if (strcmp (value, "text") == 0) {
+               category->challenge_type = CHALLENGE_TYPE_TEXT;
+           } else if (strcmp (value, "image") == 0) {
+               category->challenge_type = CHALLENGE_TYPE_IMAGE;
+           } else {
+               fprintf (stderr, "Unknown value for \"challenge\" option \"%s\" at %s:%d\n",
+                        value, path, line_count);
+               exit (1);
+           }
        } else {
            fprintf (stderr, "Unknown option %s at %s:%d\n",
                     name, path, line_count);
@@ -1102,6 +1131,35 @@ mnemon_handle_response (mnemon_t *mnemon,
     bin_add_item (bin, item);
 }
 
+static void
+mnemon_show_image (mnemon_t *mnemon, const char *filename)
+{
+    char *command;
+
+    /* XXX: Yes, shelling out to system is total cheese. The planned
+     * fix here is to bring graphical display in process, (or at least
+     * have a custom external program that accepts image filenames on
+     * stdin.
+     */
+    xasprintf (&command, "xli -gamma 2.2 %s >/dev/null 2>&1 &",
+              filename);
+    system (command);
+    free (command);
+}
+
+static void
+mnemon_hide_image (mnemon_t *mnemon)
+{
+    char * command;
+
+    /* XXX: And this is just embarrassing (obviously wrong in several
+     * ways). Hopefully I'll amend away any commit that includes this.
+     */
+    xasprintf (&command, "killall xli");
+    system (command);
+    free (command);
+}
+
 static void
 mnemon_do_challenges (mnemon_t *mnemon)
 {
@@ -1156,13 +1214,30 @@ mnemon_do_challenges (mnemon_t *mnemon)
                response = readline ("The next one is timed. Press enter when ready:");
                free (response);
            }
-               
-           printf ("%s\n", item->challenge);
+
+           switch (category->challenge_type) {
+           case CHALLENGE_TYPE_TEXT:
+               printf ("%s\n", item->challenge);
+               break;
+           case CHALLENGE_TYPE_IMAGE:
+               {
+                   char *absolute_filename;
+
+                   xasprintf (&absolute_filename, "%s/%s",
+                              mnemon->dir_name, item->challenge);
+                   mnemon_show_image (mnemon, absolute_filename);
+                   free (absolute_filename);
+               }
+               break;
+           }
 
            gettimeofday (&start, NULL);
            response = readline ("> ");
            gettimeofday (&end, NULL);
 
+           if (category->challenge_type == CHALLENGE_TYPE_IMAGE)
+               mnemon_hide_image (mnemon);
+
            /* Terminate on EOF */
            if (response == NULL) {
                printf ("\n");