X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=mnemon.c;h=87e1fd08b6530089cca9d12270405d0b1569d1c7;hb=4afda67e5f06fd1a8e77459355a325a42cd2d594;hp=33f2c260132a6efff082da9989da5ca6be6ef739;hpb=565b76aa595b6a9ed43219b590cf2e10afcf7e9a;p=mnemon diff --git a/mnemon.c b/mnemon.c index 33f2c26..87e1fd0 100644 --- a/mnemon.c +++ b/mnemon.c @@ -35,6 +35,12 @@ #include #include +#define ASSERT_NOT_REACHED \ +do { \ + static const int NOT_REACHED = 0; \ + assert (NOT_REACHED); \ +} while (0) + typedef int bool_t; typedef struct _item { @@ -55,6 +61,12 @@ typedef enum { CATEGORY_ORDER_SEQUENTIAL } category_order_t; +typedef enum { + CHALLENGE_TYPE_TEXT, + CHALLENGE_TYPE_IMAGE, + CHALLENGE_TYPE_AUDIO +} challenge_type_t; + typedef struct _category { char *name; int items_size; @@ -66,6 +78,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 +207,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 +277,20 @@ 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; + case CHALLENGE_TYPE_AUDIO: + fprintf (file, "audio"); + break; + } + fprintf (file, "\n\n"); + for (i = 0; i < category->num_items; i++) { item = &category->items[i]; if (i != 0) @@ -618,6 +647,18 @@ 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 if (strcmp (value, "audio") == 0) { + category->challenge_type = CHALLENGE_TYPE_AUDIO; + } 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); @@ -1113,6 +1154,60 @@ mnemon_handle_response (mnemon_t *mnemon, bin_add_item (bin, item); } +static void +mnemon_show_challenge (mnemon_t *mnemon, + challenge_type_t challenge_type, + const char *challenge) +{ + const char *program; + char *command; + + if (challenge_type == CHALLENGE_TYPE_TEXT) { + printf ("%s\n", challenge); + return; + } + + /* 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. + */ + switch (challenge_type) { + case CHALLENGE_TYPE_TEXT: + ASSERT_NOT_REACHED; + break; + case CHALLENGE_TYPE_IMAGE: + program = "xli -gamma 2.2"; + break; + case CHALLENGE_TYPE_AUDIO: + program = "play"; + break; + } + + xasprintf (&command, "%s %s/%s >/dev/null 2>&1 &", + program, + mnemon->dir_name, + challenge); + system (command); + free (command); +} + +static void +mnemon_hide_challenge (mnemon_t *mnemon, challenge_type_t challenge_type) +{ + char * command; + + if (challenge_type != CHALLENGE_TYPE_IMAGE) + return; + + /* 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) { @@ -1164,13 +1259,16 @@ mnemon_do_challenges (mnemon_t *mnemon) response = readline ("The next one is timed. Press enter when ready:"); free (response); } - - printf ("%s\n", item->challenge); + + mnemon_show_challenge (mnemon, category->challenge_type, + item->challenge); gettimeofday (&start, NULL); response = readline ("> "); gettimeofday (&end, NULL); + mnemon_hide_challenge (mnemon, category->challenge_type); + /* Terminate on EOF */ if (response == NULL) { printf ("\n");