color config for code blocks
[smdp.git] / src / viewer.c
index 56291db..20e4fb9 100644 (file)
@@ -1,8 +1,7 @@
 /*
  * Functions necessary to display a deck of slides in different color modes
- * using ncurses. Only white, red, and blue are supported, as they can be
- * faded in 256 color mode.
- * Copyright (C) 2016 Michael Goehler
+ * using ncurses.
+ * Copyright (C) 2018 Michael Goehler
  *
  * This file is part of mdp.
  *
 #include <unistd.h> // usleep
 #include <stdlib.h> // getenv
 #include "viewer.h"
-
-// color ramp for fading from black to color
-static short white_ramp[24] = { 16, 232, 233, 234, 235, 236,
-                               237, 238, 239, 240, 241, 242,
-                               244, 245, 246, 247, 248, 249,
-                               250, 251, 252, 253, 254, 255 };
-
-static short blue_ramp[24]  = { 16,  17,  17,  18,  18,  19,
-                                19,  20,  20,  21,  27,  33,
-                                32,  39,  38,  45,  44,  44,
-                                81,  81,  51,  51, 123, 123 };
-
-static short red_ramp[24]   = { 16,  52,  52,  53,  53,  89,
-                                89,  90,  90, 126, 127, 127,
-                               163, 163, 164, 164, 200, 200,
-                               201, 201, 207, 207, 213, 213 };
-
-// color ramp for fading from white to color
-static short white_ramp_invert[24] = { 15, 255, 254, 254, 252, 251,
-                                      250, 249, 248, 247, 246, 245,
-                                      243, 242, 241, 240, 239, 238,
-                                      237, 236, 235, 234, 233, 232};
-
-static short blue_ramp_invert[24]  = { 15, 231, 231, 195, 195, 159,
-                                      159, 123, 123,  87,  51,  44,
-                                       45,  38,  39,  32,  33,  33,
-                                       26,  26,  27,  27,  21,  21};
-
-static short red_ramp_invert[24]   = { 15, 231, 231, 224, 224, 225,
-                                      225, 218, 218, 219, 212, 213,
-                                      206, 207, 201, 200, 199, 199,
-                                      198, 198, 197, 197, 196, 196};
-
-int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reload, int noreload, int slidenum) {
-
-    int c = 0;          // char
-    int i = 0;          // iterate
-    int l = 0;          // line number
-    int lc = 0;         // line count
-    int sc = 1;         // slide count
-    int colors = 0;     // amount of colors supported
-    int fade = 0;       // disable color fading by default
-    int trans = -1;     // enable transparency if term supports it
-    int max_lines = 0;  // max lines per slide
-    int max_cols = 0;   // max columns per line
-    int offset;         // text offset
-    int stop = 0;       // passed stop bits per slide
+#include "config.h"
+
+int ncurses_display(deck_t *deck, int reload, int noreload, int slidenum) {
+
+    int c = 0;                // char
+    int i = 0;                // iterate
+    int l = 0;                // line number
+    int lc = 0;               // line count
+    int sc = 1;               // slide count
+    int colors = 0;           // amount of colors supported
+    int max_lines = 0;        // max lines per slide
+    int max_lines_slide = -1; // the slide that has the most lines
+    int max_cols = 0;         // max columns per line
+    int offset;               // text offset
+    int stop = 0;             // passed stop bits per slide
 
     // header line 1 is displayed at the top
     int bar_top = (deck->headers > 0) ? 1 : 0;
@@ -141,8 +108,13 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa
         }
 
         max_lines = MAX(lc, max_lines);
+        if (lc == max_lines) {
+            max_lines_slide = sc;
+        }
 
+        slide->lines_consumed = lc;
         slide = slide->next;
+        ++sc;
     }
 
     // not enough lines
@@ -152,7 +124,7 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa
         endwin();
 
         // print error
-        fwprintf(stderr, L"Error: Terminal height (%i lines) too small. Need at least %i lines.\n", LINES, max_lines + bar_top + bar_bottom);
+        fwprintf(stderr, L"Error: Terminal height (%i lines) too small. Need at least %i lines for slide #%i.\n", LINES, max_lines + bar_top + bar_bottom, max_lines_slide);
         fwprintf(stderr, L"You may need to add additional horizontal rules (---) to split your file in shorter slides.\n");
 
         // no reload
@@ -176,74 +148,30 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa
         start_color();
         use_default_colors();
 
-        // 256 color mode
-        if(COLORS == 256) {
-
-            if(notrans) {
-                if(invert) {
-                    trans = 15; // white in 256 color mode
-                } else {
-                    trans = 16; // black in 256 color mode
-                }
-            }
-
-            if(invert) {
-                init_pair(CP_WHITE, 232, trans);
-                init_pair(CP_BLUE, 21, trans);
-                init_pair(CP_RED, 196, trans);
-                init_pair(CP_BLACK, 15, 232);
-            } else {
-                init_pair(CP_WHITE, 255, trans);
-                init_pair(CP_BLUE, 123, trans);
-                init_pair(CP_RED, 213, trans);
-                init_pair(CP_BLACK, 16, 255);
-            }
-            init_pair(CP_YELLOW, 208, trans);
-
-            // enable color fading
-            if(!nofade)
-                fade = true;
-
-        // 8 color mode
-        } else {
-
-            if(notrans) {
-                if(invert) {
-                    trans = 7; // white in 8 color mode
-                } else {
-                    trans = 0; // black in 8 color mode
-                }
-            }
-
-            if(invert) {
-                init_pair(CP_WHITE, 0, trans);
-                init_pair(CP_BLACK, 7, 0);
-            } else {
-                init_pair(CP_WHITE, 7, trans);
-                init_pair(CP_BLACK, 0, 7);
-            }
-            init_pair(CP_BLUE, 4, trans);
-            init_pair(CP_RED, 1, trans);
-            init_pair(CP_YELLOW, 3, trans);
-        }
+        init_pair(CP_FG, FG_COLOR, BG_COLOR);
+        init_pair(CP_HEADER, HEADER_COLOR, BG_COLOR);
+        init_pair(CP_BOLD, BOLD_COLOR, BG_COLOR);
+        init_pair(CP_TITLE, TITLE_COLOR, BG_COLOR);
+        init_pair(CP_CODE, CODEFG_COLOR, CODEBG_COLOR);
 
         colors = 1;
     }
 
     // set background color for main window
     if(colors)
-        wbkgd(stdscr, COLOR_PAIR(CP_WHITE));
+        wbkgd(stdscr, COLOR_PAIR(CP_FG));
 
     // setup content window
     WINDOW *content = newwin(LINES - bar_top - bar_bottom, COLS, 0 + bar_top, 0);
 
     // set background color of content window
     if(colors)
-        wbkgd(content, COLOR_PAIR(CP_WHITE));
+        wbkgd(content, COLOR_PAIR(CP_FG));
 
     slide = deck->slide;
 
     // find slide to reload
+    sc = 1;
     while(reload > 1 && reload <= deck->slides) {
         slide = slide->next;
         sc++;
@@ -266,7 +194,7 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa
 
         // set main window text color
         if(colors)
-            wattron(stdscr, COLOR_PAIR(CP_YELLOW));
+            wattron(stdscr, COLOR_PAIR(CP_TITLE));
 
         // setup header
         if(bar_top) {
@@ -319,7 +247,8 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa
 
         // print lines
         while(line) {
-            add_line(content, l, (COLS - max_cols) / 2, line, max_cols, colors);
+            add_line(content, l + ((LINES - slide->lines_consumed - bar_top - bar_bottom) / 2),
+                     (COLS - max_cols) / 2, line, max_cols, colors);
 
             // raise stop counter if we pass a line having a stop bit
             if(CHECK_BIT(line->bits, IS_STOP))
@@ -334,8 +263,9 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa
         }
 
         // print pandoc URL references
-        // only if we already printed all lines of the current slide
-        if(!line) {
+        // only if we already printed all lines of the current slide (or output is stopped)
+        if(!line ||
+           stop > slide->stop) {
             int i, ymax;
             getmaxyx( content, ymax, i );
             for (i = 0; i < url_get_amount(); i++) {
@@ -351,157 +281,87 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa
         // compare virtual screen to physical screen and does the actual updates
         doupdate();
 
-        // fade in
-        if(fade)
-            fade_in(content, trans, colors, invert);
-
-        // re-enable fading after any undefined key press
-        if(COLORS == 256 && !nofade)
-            fade = true;
-
         // wait for user input
         c = getch();
 
         // evaluate user input
         i = 0;
-        switch(c) {
 
+        if (evaluate_binding(prev_slide_binding, c)) {
             // show previous slide or stop bit
-            case KEY_UP:
-            case KEY_LEFT:
-            case KEY_PPAGE:
-            case 8:   // BACKSPACE (ascii)
-            case 127: // BACKSPACE (xterm)
-            case 263: // BACKSPACE (getty)
-            case 'h':
-            case 'k':
-                if(stop > 1 || (stop == 1 && !line)) {
-                    // show current slide again
-                    // but stop one stop bit earlier
-                    slide->stop--;
-                    fade = false;
-                } else {
-                    if(slide->prev) {
-                        // show previous slide
-                        slide = slide->prev;
-                        sc--;
-                        //stop on first bullet point always
-                        if(slide->stop > 0)
-                            slide->stop = 0;
-                    } else {
-                        // do nothing
-                        fade = false;
-                    }
+            if(stop > 1 || (stop == 1 && !line)) {
+                // show current slide again
+                // but stop one stop bit earlier
+                slide->stop--;
+            } else {
+                if(slide->prev) {
+                    // show previous slide
+                    slide = slide->prev;
+                    sc--;
+                    //stop on first bullet point always
+                    if(slide->stop > 0)
+                        slide->stop = 0;
                 }
-                break;
-
+            }
+        } else if (evaluate_binding(next_slide_binding, c)) {
             // show next slide or stop bit
-            case KEY_DOWN:
-            case KEY_RIGHT:
-            case KEY_NPAGE:
-            case '\n': // ENTER
-            case ' ':  // SPACE
-            case 'j':
-            case 'l':
-                if(stop && line) {
-                    // show current slide again
-                    // but stop one stop bit later (or at end of slide)
-                    slide->stop++;
-                    fade = false;
-                } else {
-                    if(slide->next) {
-                        // show next slide
-                        slide = slide->next;
-                        sc++;
-                    } else {
-                        // do nothing
-                        fade = false;
-                    }
+            if(stop && line) {
+                // show current slide again
+                // but stop one stop bit later (or at end of slide)
+                slide->stop++;
+            } else {
+                if(slide->next) {
+                    // show next slide
+                    slide = slide->next;
+                    sc++;
                 }
-                break;
-
+            }
+        } else if (isdigit(c) && c != '0') {
             // show slide n
-            case '9':
-            case '8':
-            case '7':
-            case '6':
-            case '5':
-            case '4':
-            case '3':
-            case '2':
-            case '1':
-                i = get_slide_number(c);
-                if(i > 0 && i <= deck->slides) {
-                    while(sc != i) {
-                        // search forward
-                        if(sc < i) {
-                            if(slide->next) {
-                                slide = slide->next;
-                                sc++;
-                            }
-                        // search backward
-                        } else {
-                            if(slide->prev) {
-                                slide = slide->prev;
-                                sc--;
-                            }
+            i = get_slide_number(c);
+            if(i > 0 && i <= deck->slides) {
+                while(sc != i) {
+                    // search forward
+                    if(sc < i) {
+                        if(slide->next) {
+                            slide = slide->next;
+                            sc++;
+                        }
+                    // search backward
+                    } else {
+                        if(slide->prev) {
+                            slide = slide->prev;
+                            sc--;
                         }
                     }
-                } else {
-                    // disable fading if slide n doesn't exist
-                    fade = false;
                 }
-                break;
-
+            }        
+        } else if (evaluate_binding(first_slide_binding, c)) {
             // show first slide
-            case 'g':
-            case KEY_HOME:
-                slide = deck->slide;
-                sc = 1;
-                break;
-
+            slide = deck->slide;
+            sc = 1;
+        } else if (evaluate_binding(last_slide_binding, c)) {
             // show last slide
-            case 'G':
-            case KEY_END:
-                for(i = sc; i <= deck->slides; i++) {
-                    if(slide->next) {
-                            slide = slide->next;
-                            sc++;
-                    }
+            for(i = sc; i <= deck->slides; i++) {
+                if(slide->next) {
+                        slide = slide->next;
+                        sc++;
                 }
-                break;
-
+            }
+        } else if (evaluate_binding(reload_binding, c)) {
             // reload
-            case 'r':
-                if(noreload == 0) {
-                    // reload slide N
-                    reload = sc;
-                    slide = NULL;
-                } else {
-                    // disable fading if reload is not possible
-                    fade = false;
-                }
-                break;
-
-            // quit
-            case 'q':
-                // do not fade out on exit
-                fade = false;
-                // do not reload
-                reload = 0;
+            if(noreload == 0) {
+                // reload slide N
+                reload = sc;
                 slide = NULL;
-                break;
-
-            default:
-                // disable fading on undefined key press
-                fade = false;
-                break;
+            }
+        } else if (evaluate_binding(quit_binding, c)) {
+            // quit
+            // do not reload
+            reload = 0;
+            slide = NULL;
         }
 
-        // fade out
-        if(fade)
-            fade_out(content, trans, colors, invert);
-
         url_purge();
     }
 
@@ -517,51 +377,29 @@ int ncurses_display(deck_t *deck, int notrans, int nofade, int invert, int reloa
     return reload;
 }
 
-static const char *list_open1 = " |  ";
-static const char *list_open2 = " |  ";
-static const char *list_open3 = " |  ";
-static const char *list_head1 = " +- ";
-static const char *list_head2 = " +- ";
-static const char *list_head3 = " +- ";
-/*
-
-export MDP_LIST_OPEN3="    "
-export MDP_LIST_OPEN2="    "
-export MDP_LIST_OPEN3="    "
-export MDP_LIST_HEAD1=" ■  "
-export MDP_LIST_HEAD2=" ▫  "
-export MDP_LIST_HEAD3=" ●  "
-
-export MDP_LIST_OPEN2=" │  "
-export MDP_LIST_OPEN2=" │  "
-export MDP_LIST_OPEN3=" │  "
-export MDP_LIST_HEAD1=" ▇─ "
-export MDP_LIST_HEAD2=" ▓─ "
-export MDP_LIST_HEAD3=" ▒─ "
-*
-*/
 void setup_list_strings(void)
 {
     const char *str;
 
-    if ((str = getenv("MDP_LIST_OPEN")) != NULL) {
+    /* utf8 can require 6 bytes */
+    if ((str = getenv("MDP_LIST_OPEN")) != NULL && strlen(str) <= 4*6) {
         list_open1 = list_open2 = list_open3 = str;
     } else {
-        if ((str = getenv("MDP_LIST_OPEN1")) != NULL)
+        if ((str = getenv("MDP_LIST_OPEN1")) != NULL && strlen(str) <= 4*6)
             list_open1 = str;
-        if ((str = getenv("MDP_LIST_OPEN2")) != NULL)
+        if ((str = getenv("MDP_LIST_OPEN2")) != NULL && strlen(str) <= 4*6)
             list_open2 = str;
-        if ((str = getenv("MDP_LIST_OPEN3")) != NULL)
+        if ((str = getenv("MDP_LIST_OPEN3")) != NULL && strlen(str) <= 4*6)
             list_open3 = str;
     }
-    if ((str = getenv("MDP_LIST_HEAD")) != NULL) {
+    if ((str = getenv("MDP_LIST_HEAD")) != NULL && strlen(str) <= 4*6) {
         list_head1 = list_head2 = list_head3 = str;
     } else {
-        if ((str = getenv("MDP_LIST_HEAD1")) != NULL)
+        if ((str = getenv("MDP_LIST_HEAD1")) != NULL && strlen(str) <= 4*6)
             list_head1 = str;
-        if ((str = getenv("MDP_LIST_HEAD2")) != NULL)
+        if ((str = getenv("MDP_LIST_HEAD2")) != NULL && strlen(str) <= 4*6)
             list_head2 = str;
-        if ((str = getenv("MDP_LIST_HEAD3")) != NULL)
+        if ((str = getenv("MDP_LIST_HEAD3")) != NULL && strlen(str) <= 4*6)
             list_head3 = str;
     }
 }
@@ -578,8 +416,7 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
 
         // fill rest off line with spaces if we are in a code block
         if(CHECK_BIT(line->bits, IS_CODE) && colors) {
-            if(colors)
-                wattron(window, COLOR_PAIR(CP_BLACK));
+            wattron(window, COLOR_PAIR(CP_CODE));
             for(i = getcurx(window) - x; i < max_cols; i++)
                 wprintw(window, "%s", " ");
         }
@@ -659,14 +496,15 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
     // IS_CODE
     if(CHECK_BIT(line->bits, IS_CODE)) {
 
-        if (!CHECK_BIT(line->bits, IS_TILDE_CODE)) {
+        if (!CHECK_BIT(line->bits, IS_TILDE_CODE) &&
+            !CHECK_BIT(line->bits, IS_GFM_CODE)) {
             // set static offset for code
             offset = CODE_INDENT;
         }
 
-        // reverse color for code blocks
-        if(colors)
-            wattron(window, COLOR_PAIR(CP_BLACK));
+        // color for code block
+        if (colors)
+        wattron(window, COLOR_PAIR(CP_CODE));
 
         // print whole lines
         waddwstr(window, &line->text->value[offset]);
@@ -680,11 +518,11 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
         // IS_QUOTE
         if(CHECK_BIT(line->bits, IS_QUOTE)) {
             while(line->text->value[offset] == '>') {
-                // print a reverse color block
+                // print a code block
                 if(colors) {
-                    wattron(window, COLOR_PAIR(CP_BLACK));
+                    wattron(window, COLOR_PAIR(CP_CODE));
                     wprintw(window, "%s", " ");
-                    wattron(window, COLOR_PAIR(CP_WHITE));
+                    wattron(window, COLOR_PAIR(CP_FG));
                     wprintw(window, "%s", " ");
                 } else {
                     wprintw(window, "%s", ">");
@@ -711,7 +549,7 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
 
                 // set headline color
                 if(colors)
-                    wattron(window, COLOR_PAIR(CP_BLUE));
+                    wattron(window, COLOR_PAIR(CP_HEADER));
 
                 // enable underline for H1
                 if(CHECK_BIT(line->bits, IS_H1))
@@ -735,15 +573,14 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo
     }
 
     // fill rest off line with spaces
-    // we only need this if the color is inverted (e.g. code-blocks),
-    // to ensure the background fades too
+    // we only need this if the color is inverted (e.g. code-blocks)
     if(CHECK_BIT(line->bits, IS_CODE))
         for(i = getcurx(window) - x; i < max_cols; i++)
             wprintw(window, "%s", " ");
 
     // reset to default color
     if(colors)
-        wattron(window, COLOR_PAIR(CP_WHITE));
+        wattron(window, COLOR_PAIR(CP_FG));
     wattroff(window, A_UNDERLINE);
 }
 
@@ -774,7 +611,7 @@ void inline_display(WINDOW *window, const wchar_t *c, const int colors) {
                     // disable highlight
                     case L'*':
                         if(colors)
-                            wattron(window, COLOR_PAIR(CP_WHITE));
+                            wattron(window, COLOR_PAIR(CP_FG));
                         break;
                     // disable underline
                     case L'_':
@@ -783,7 +620,7 @@ void inline_display(WINDOW *window, const wchar_t *c, const int colors) {
                     // disable inline code
                     case L'`':
                         if(colors)
-                            wattron(window, COLOR_PAIR(CP_WHITE));
+                            wattron(window, COLOR_PAIR(CP_FG));
                         break;
                 }
 
@@ -820,7 +657,7 @@ void inline_display(WINDOW *window, const wchar_t *c, const int colors) {
 
                             // turn higlighting and underlining on
                             if (colors)
-                                wattron(window, COLOR_PAIR(CP_BLUE));
+                                wattron(window, COLOR_PAIR(CP_HEADER));
                             wattron(window, A_UNDERLINE);
 
                             start_link_name = i;
@@ -847,7 +684,7 @@ void inline_display(WINDOW *window, const wchar_t *c, const int colors) {
 
                             // turn highlighting and underlining off
                             wattroff(window, A_UNDERLINE);
-                            wattron(window, COLOR_PAIR(CP_WHITE));
+                            wattron(window, COLOR_PAIR(CP_FG));
 
                         } else {
                             wprintw(window, "[");
@@ -857,7 +694,7 @@ void inline_display(WINDOW *window, const wchar_t *c, const int colors) {
                         // enable highlight
                         case L'*':
                             if(colors)
-                                wattron(window, COLOR_PAIR(CP_RED));
+                                wattron(window, COLOR_PAIR(CP_BOLD));
                             break;
                         // enable underline
                         case L'_':
@@ -865,8 +702,7 @@ void inline_display(WINDOW *window, const wchar_t *c, const int colors) {
                             break;
                         // enable inline code
                         case L'`':
-                            if(colors)
-                                wattron(window, COLOR_PAIR(CP_BLACK));
+                            wattron(window, COLOR_PAIR(CP_CODE));
                             break;
                         // do nothing for backslashes
                     }
@@ -895,7 +731,7 @@ void inline_display(WINDOW *window, const wchar_t *c, const int colors) {
             // disable highlight
             case L'*':
                 if(colors)
-                    wattron(window, COLOR_PAIR(CP_WHITE));
+                    wattron(window, COLOR_PAIR(CP_FG));
                 break;
             // disable underline
             case L'_':
@@ -904,7 +740,7 @@ void inline_display(WINDOW *window, const wchar_t *c, const int colors) {
             // disable inline code
             case L'`':
                 if(colors)
-                    wattron(window, COLOR_PAIR(CP_WHITE));
+                    wattron(window, COLOR_PAIR(CP_FG));
                 break;
             // do nothing for backslashes
         }
@@ -913,66 +749,6 @@ void inline_display(WINDOW *window, const wchar_t *c, const int colors) {
     (stack->delete)(stack);
 }
 
-void fade_out(WINDOW *window, int trans, int colors, int invert) {
-    int i; // increment
-    if(colors && COLORS == 256) {
-        for(i = 22; i >= 0; i--) {
-
-            // dim color pairs
-            if(invert) {
-                init_pair(CP_WHITE, white_ramp_invert[i], trans);
-                init_pair(CP_BLUE, blue_ramp_invert[i], trans);
-                init_pair(CP_RED, red_ramp_invert[i], trans);
-                init_pair(CP_BLACK, 15, white_ramp_invert[i]);
-            } else {
-                init_pair(CP_WHITE, white_ramp[i], trans);
-                init_pair(CP_BLUE, blue_ramp[i], trans);
-                init_pair(CP_RED, red_ramp[i], trans);
-                init_pair(CP_BLACK, 16, white_ramp[i]);
-            }
-
-            // refresh virtual screen with new color
-            wnoutrefresh(window);
-
-            // compare virtual screen to physical screen and does the actual updates
-            doupdate();
-
-            // delay for our eyes to recognize the change
-            usleep(FADE_DELAY);
-        }
-    }
-}
-
-void fade_in(WINDOW *window, int trans, int colors, int invert) {
-    int i; // increment
-    if(colors && COLORS == 256) {
-        for(i = 0; i <= 23; i++) {
-
-            // brighten color pairs
-            if(invert) {
-                init_pair(CP_WHITE, white_ramp_invert[i], trans);
-                init_pair(CP_BLUE, blue_ramp_invert[i], trans);
-                init_pair(CP_RED, red_ramp_invert[i], trans);
-                init_pair(CP_BLACK, 15, white_ramp_invert[i]);
-            } else {
-                init_pair(CP_WHITE, white_ramp[i], trans);
-                init_pair(CP_BLUE, blue_ramp[i], trans);
-                init_pair(CP_RED, red_ramp[i], trans);
-                init_pair(CP_BLACK, 16, white_ramp[i]);
-            }
-
-            // refresh virtual screen with new color
-            wnoutrefresh(window);
-
-            // compare virtual screen to physical screen and does the actual updates
-            doupdate();
-
-            // delay for our eyes to recognize the change
-            usleep(FADE_DELAY);
-        }
-    }
-}
-
 int int_length (int val) {
     int l = 1;
     while(val > 9) {
@@ -984,7 +760,7 @@ int int_length (int val) {
 
 int get_slide_number(char init) {
     int retval = init - '0';
-    char c;
+    int c;
     // block for tenths of a second when using getch, ERR if no input
     halfdelay(GOTO_SLIDE_DELAY);
     while((c = getch()) != ERR) {
@@ -998,3 +774,14 @@ int get_slide_number(char init) {
     cbreak();       // go back to cbreak
     return retval;
 }
+
+bool evaluate_binding(const int bindings[], char c) {
+    int binding;
+    int ind = 0; 
+    while((binding = bindings[ind]) != 0) {
+        if (c == binding) return true;
+        ind++;
+    }
+    return false;
+}
+