about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2017-05-19 00:09:18 -0700
committerKartik K. Agaram <vc@akkartik.com>2017-05-19 00:09:18 -0700
commit537ad74cccc709b14418114e177d595ce3812627 (patch)
treefd0f7779e54c207a6debee0e806f29820375222d
parentb6fa632e2f46467c76c7fb39c731cb17e8558ee0 (diff)
downloadmu-537ad74cccc709b14418114e177d595ce3812627.tar.gz
3862
As the finishing touch on commit 3860, completely decouple the termbox
API between moving the cursor and printing at the cursor.
-rw-r--r--080display.cc15
-rw-r--r--100trace_browser.cc46
-rw-r--r--termbox/termbox.c25
-rw-r--r--termbox/termbox.h8
4 files changed, 48 insertions, 46 deletions
diff --git a/080display.cc b/080display.cc
index b639c2a7..9f808a0c 100644
--- a/080display.cc
+++ b/080display.cc
@@ -127,7 +127,7 @@ case PRINT_CHARACTER_TO_DISPLAY: {
     bg_color = ingredients.at(2).at(0);
     if (bg_color == 0) bg_color = TB_BLACK;
   }
-  tb_change_cell(Display_column, Display_row, c, color, bg_color);
+  tb_print(c, color, bg_color);
   // track row and column, mimicking what happens on screen
   if (c == '\n') {
     if (Display_row < height-1) ++Display_row;  // otherwise we scroll and Display_row remains unchanged
@@ -145,7 +145,6 @@ case PRINT_CHARACTER_TO_DISPLAY: {
       if (Display_row < height-1) ++Display_row;
     }
   }
-  tb_set_cursor(Display_column, Display_row);
   break;
 }
 
@@ -435,9 +434,8 @@ case CLEAR_LINE_ON_DISPLAY: {
 case CLEAR_LINE_ON_DISPLAY: {
   CHECK_SCREEN;
   int width = tb_width();
-  for (int x = Display_column;  x < width;  ++x) {
-    tb_change_cell(x, Display_row, ' ', TB_WHITE, TB_BLACK);
-  }
+  for (int x = Display_column;  x < width;  ++x)
+    cout << ' ';
   tb_set_cursor(Display_column, Display_row);
   break;
 }
@@ -460,9 +458,10 @@ case CLEAR_DISPLAY_FROM: {
   int right = ingredients.at(3).at(0);
   int height=tb_height();
   for (/*nada*/;  row < height;  ++row, column=left) {  // start column from left in every inner loop except first
-    for (/*nada*/;  column <= right;  ++column) {
-      tb_change_cell(column, row, ' ', TB_WHITE, TB_BLACK);
-    }
+    tb_set_cursor(column, row);
+    for (/*nada*/;  column <= right;  ++column)
+      cout << ' ';
   }
+  tb_set_cursor(Display_column, Display_row);
   break;
 }
diff --git a/100trace_browser.cc b/100trace_browser.cc
index ffa66b41..8b0f949e 100644
--- a/100trace_browser.cc
+++ b/100trace_browser.cc
@@ -113,6 +113,7 @@ void start_trace_browser() {
       Visible.insert(i);
   }
   tb_init();
+  tb_clear();
   Display_row = Display_column = 0;
   Top_of_screen = 0;
   refresh_screen_rows();
@@ -271,11 +272,10 @@ bool start_search_editor(search_direction dir) {
   const int bottom_screen_line = tb_height()-1;
   // run a little editor just in the last line of the screen
   clear_line(bottom_screen_line);
-  tb_set_cursor(0, bottom_screen_line);
   int col = 0;  // screen column of cursor on bottom line. also used to update pattern.
-  tb_change_cell(col, bottom_screen_line, '/', TB_WHITE, TB_BLACK);
-  ++col;
   tb_set_cursor(col, bottom_screen_line);
+  tb_print('/', TB_WHITE, TB_BLACK);
+  ++col;
   string pattern;
   while (true) {
     int key = read_key();
@@ -311,45 +311,46 @@ bool start_search_editor(search_direction dir) {
     }
     else if (key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2) {
       if (col > /*slash*/1) {
+        assert(col <= SIZE(pattern)+1);
         --col;
         // update pattern
         pattern.erase(col-/*slash*/1, /*len*/1);
         // update screen
-        if (col > SIZE(pattern)) {
-          tb_change_cell(col, bottom_screen_line, ' ', TB_WHITE, TB_BLACK);
-        }
-        else {
-          assert(col <= SIZE(pattern));
-          for (int x = col;  x < SIZE(pattern)+/*skip slash*/1;  ++x)
-            tb_change_cell(x, bottom_screen_line, pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
-          tb_change_cell(SIZE(pattern)+/*skip slash*/1, bottom_screen_line, ' ', TB_WHITE, TB_BLACK);
-        }
+        tb_set_cursor(col, bottom_screen_line);
+        for (int x = col;  x < SIZE(pattern)+/*skip slash*/1;  ++x)
+          tb_print(pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
+        tb_print(' ', TB_WHITE, TB_BLACK);
         tb_set_cursor(col, bottom_screen_line);
       }
     }
     else if (key == TB_KEY_CTRL_K) {
       int old_pattern_size = SIZE(pattern);
       pattern.erase(col-/*slash*/1, SIZE(pattern) - (col-/*slash*/1));
+      tb_set_cursor(col, bottom_screen_line);
       for (int x = col;  x < old_pattern_size+/*slash*/1;  ++x)
-        tb_change_cell(x, bottom_screen_line, ' ', TB_WHITE, TB_BLACK);
+        tb_print(' ', TB_WHITE, TB_BLACK);
       tb_set_cursor(col, bottom_screen_line);
     }
     else if (key == TB_KEY_CTRL_U) {
       int old_pattern_size = SIZE(pattern);
       pattern.erase(0, col-/*slash*/1);
+      col = /*skip slash*/1;
+      tb_set_cursor(col, bottom_screen_line);
       for (int x = /*slash*/1;  x < SIZE(pattern)+/*skip slash*/1;  ++x)
-        tb_change_cell(x, bottom_screen_line, pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
+        tb_print(pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
       for (int x = SIZE(pattern)+/*slash*/1;  x < old_pattern_size+/*skip slash*/1;  ++x)
-        tb_change_cell(x, bottom_screen_line, ' ', TB_WHITE, TB_BLACK);
-      tb_set_cursor(/*start of pattern skipping slash*/1, bottom_screen_line);
+        tb_print(' ', TB_WHITE, TB_BLACK);
+      tb_set_cursor(col, bottom_screen_line);
     }
     else if (key < 128) {  // ascii only
       // update pattern
       char c = static_cast<char>(key);
+      assert(col-1 >= 0);
+      assert(col-1 <= SIZE(pattern));
       pattern.insert(col-/*slash*/1, /*num*/1, c);
       // update screen
       for (int x = col;  x < SIZE(pattern)+/*skip slash*/1;  ++x)
-        tb_change_cell(x, bottom_screen_line, pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
+        tb_print(pattern.at(x-/*slash*/1), TB_WHITE, TB_BLACK);
       ++col;
       tb_set_cursor(col, bottom_screen_line);
     }
@@ -391,8 +392,10 @@ void search_previous(const string& pat) {
 }
 
 void clear_line(int screen_row) {
+  tb_set_cursor(0, screen_row);
   for (int col = 0;  col < tb_width();  ++col)
-    tb_change_cell(col, screen_row, ' ', TB_WHITE, TB_BLACK);
+    tb_print(' ', TB_WHITE, TB_BLACK);
+  tb_set_cursor(0, screen_row);
 }
 
 // update Trace_indices for each screen_row on the basis of Top_of_screen and Visible
@@ -450,6 +453,7 @@ void render_line(int screen_row, const string& s, bool cursor_line) {
   int color = TB_WHITE;
   int background_color = cursor_line ? /*subtle grey*/240 : TB_BLACK;
   vector<pair<size_t, size_t> > highlight_ranges = find_all_occurrences(s, Current_search_pattern);
+  tb_set_cursor(0, screen_row);
   for (col = 0;  col < tb_width() && col+Left_of_screen < SIZE(s);  ++col) {
     char c = s.at(col+Left_of_screen);  // todo: unicode
     if (c == '\n') c = ';';  // replace newlines with semi-colons
@@ -457,12 +461,12 @@ void render_line(int screen_row, const string& s, bool cursor_line) {
     if (c == '\1') { color = /*red*/1;  c = ' '; }
     if (c == '\2') { color = TB_WHITE;  c = ' '; }
     if (in_range(highlight_ranges, col+Left_of_screen))
-      tb_change_cell(col, screen_row, c, TB_BLACK, /*yellow*/11);
+      tb_print(c, TB_BLACK, /*yellow*/11);
     else
-      tb_change_cell(col, screen_row, c, color, background_color);
+      tb_print(c, color, background_color);
   }
   for (;  col < tb_width();  ++col)
-    tb_change_cell(col, screen_row, ' ', TB_WHITE, background_color);
+    tb_print(' ', TB_WHITE, background_color);
 }
 
 vector<pair<size_t, size_t> > find_all_occurrences(const string& s, const string& pat) {
diff --git a/termbox/termbox.c b/termbox/termbox.c
index 46584a19..c97f03d5 100644
--- a/termbox/termbox.c
+++ b/termbox/termbox.c
@@ -45,7 +45,6 @@ static uint16_t foreground = TB_WHITE;
 static void update_size(void);
 static void update_term_size(void);
 static void send_attr(uint16_t fg, uint16_t bg);
-static void send_char(int x, int y, uint32_t c);
 static void send_clear(void);
 static void sigwinch_handler(int xxx);
 static int wait_fill_event(struct tb_event *event, struct timeval *timeout);
@@ -99,6 +98,7 @@ int tb_init(void)
   bytebuffer_puts(&output_buffer, funcs[T_ENTER_KEYPAD]);
   bytebuffer_puts(&output_buffer, funcs[T_ENTER_MOUSE]);
   bytebuffer_puts(&output_buffer, funcs[T_ENTER_BRACKETED_PASTE]);
+  bytebuffer_flush(&output_buffer, inout);
 
   update_term_size();
   return 0;
@@ -130,11 +130,20 @@ int tb_is_active(void)
   return termw != -1;
 }
 
-void tb_change_cell(int x, int y, uint32_t ch, uint16_t fg, uint16_t bg)
+void tb_print(uint32_t ch, uint16_t fg, uint16_t bg)
 {
   assert(termw != -1);
   send_attr(fg, bg);
-  send_char(x, y, ch);
+  if (ch == 0) {
+    // replace 0 with whitespace
+    bytebuffer_puts(&output_buffer, " ");
+  }
+  else {
+    char buf[7];
+    int bw = tb_utf8_unicode_to_char(buf, ch);
+    buf[bw] = '\0';
+    bytebuffer_puts(&output_buffer, buf);
+  }
   bytebuffer_flush(&output_buffer, inout);
 }
 
@@ -265,16 +274,6 @@ static void send_attr(uint16_t fg, uint16_t bg)
   }
 }
 
-static void send_char(int x, int y, uint32_t c)
-{
-  char buf[7];
-  int bw = tb_utf8_unicode_to_char(buf, c);
-  buf[bw] = '\0';
-  tb_set_cursor(x, y);
-  if(!c) buf[0] = ' '; // replace 0 with whitespace
-  bytebuffer_puts(&output_buffer, buf);
-}
-
 const char* to_unicode(uint32_t c)
 {
   static char buf[7];
diff --git a/termbox/termbox.h b/termbox/termbox.h
index 97306142..43b326cb 100644
--- a/termbox/termbox.h
+++ b/termbox/termbox.h
@@ -37,16 +37,16 @@ int tb_is_active(void);
 int tb_width(void);
 int tb_height(void);
 
-/* Clear the internal screen state using either TB_DEFAULT or the
- * color/attributes set by tb_set_clear_attributes(). */
+/* Clear the screen using either TB_DEFAULT or the color/attributes set by
+ * tb_set_clear_attributes(). */
 void tb_clear(void);
 void tb_set_clear_attributes(uint16_t fg, uint16_t bg);
 
 /* Move the cursor. Upper-left character is (0, 0). */
 void tb_set_cursor(int cx, int cy);
 
-/* Modify a specific cell of the screen. */
-void tb_change_cell(int x, int y, uint32_t ch, uint16_t fg, uint16_t bg);
+/* Modify the screen at the cursor. */
+void tb_print(uint32_t ch, uint16_t fg, uint16_t bg);
 
 /*** 2. Controlling keyboard events. */