diff options
Diffstat (limited to 'ui.c')
-rw-r--r-- | ui.c | 116 |
1 files changed, 88 insertions, 28 deletions
@@ -11,12 +11,19 @@ #include <ncurses.h> -#define LINE_LEN 0x10 +#include "format.h" + +#define LINE_LEN 0x10 /* Number of bytes in a line */ + +#define LINENO_DIGITS 8 /* length of line numbers */ +#define LINENO_WIDTH (LINENO_DIGITS + 2) /* for padding */ + +#define INFO_HEIGHT 10 /* Height of the info panel */ // int screen_height, screen_width; struct screen { - WINDOW *lineno, *hex, *chr; + WINDOW *lineno, *hex, *chr, *info; int top_address; void *mem; size_t mem_len; @@ -32,47 +39,81 @@ void draw_lines() { } } -void draw_hex() { +void draw_hex(struct segment *current) { + for (int y = 0; y < LINES; y++) { for (int x = 0; x < LINE_LEN; x++) { + size_t addr = screen.top_address + y * LINE_LEN + x; + if (addr < 0 || addr >= screen.mem_len) continue; + if (current->start <= addr && addr < current->end) { + wattron(screen.hex, COLOR_PAIR(1)); + } if (screen.hy == y && screen.hx == x) { wattron(screen.hex, A_REVERSE); } mvwprintw(screen.hex, y, x * 2 + (x/2), "%02x", - 0xFF & ((char*) screen.mem)[screen.top_address + y * LINE_LEN + x]); + 0xFF & ((char*) screen.mem)[addr]); if (screen.hy == y && screen.hx == x) { wattroff(screen.hex, A_REVERSE); } + if (current->start <= addr && addr < current->end) { + wattroff(screen.hex, COLOR_PAIR(1)); + } } wrefresh(screen.hex); } } -void draw_chr() { +void draw_chr(struct segment *current) { for (int y = 0; y < LINES; y++) { for (int x = 0; x < LINE_LEN; x++) { + size_t addr = screen.top_address + y * LINE_LEN + x; + if (addr < 0 || addr >= screen.mem_len) continue; + if (current->start <= addr && addr < current->end) { + wattron(screen.chr, COLOR_PAIR(1)); + } if (screen.hy == y && screen.hx == x) { wattron(screen.chr, A_REVERSE); } - char c = ((char*) screen.mem)[screen.top_address + y * LINE_LEN + x]; + char c = ((char*) screen.mem)[addr]; mvwprintw(screen.chr, y, x, "%c", isprint(c) ? c : '.'); if (screen.hy == y && screen.hx == x) { wattroff(screen.chr, A_REVERSE); } + if (current->start <= addr && addr < current->end) { + wattroff(screen.chr, COLOR_PAIR(1)); + } } wrefresh(screen.chr); } } +void draw_info(struct segment *current) { + werase(screen.info); + wmove(screen.info, 0, 0); + whline(screen.info, '-', COLS); + + // size_t mem_addr = screen.top_address + screen.hy * LINE_LEN + screen.hx; + mvwprintw(screen.info, 1, 0, current->description); + + + wrefresh(screen.info); +} + void draw_screen() { + struct segment current = get_segment( + screen.mem, + screen.mem_len, + screen.top_address + screen.hy * LINE_LEN + screen.hx); draw_lines(); - draw_hex(); - draw_chr(); + draw_hex(¤t); + draw_chr(¤t); + draw_info(¤t); /* TODO end at end of file */ } -int main() { +int main(int argc, char *argv[]) { /* Terminal supporting mouse movements */ setenv("TERM", "xterm-1003", true); @@ -84,16 +125,28 @@ int main() { curs_set(0); start_color(); - - // getmaxyx(stdscr, screen_height, screen_width); + init_pair(1, COLOR_RED, COLOR_BLACK); keypad(stdscr, true); - screen.lineno = newwin(0, 10, 0, 0); - screen.hex = newwin(0, (int) ceil(LINE_LEN * 2.5), 0, 10); - screen.chr = newwin(0, LINE_LEN, 0, 10 + (int) ceil(LINE_LEN * 2.5)); + const int HEX_WIDTH = (int) ceil(LINE_LEN * 2.5); + + { + int h = LINES - INFO_HEIGHT; + screen.lineno = newwin(h, LINENO_WIDTH, 0, 0); + screen.hex = newwin(h, HEX_WIDTH, 0, LINENO_WIDTH); + screen.chr = newwin(h, LINE_LEN, 0, LINENO_WIDTH + HEX_WIDTH); + screen.info = newwin(0, 0, h, 0); + } + + char *filename; + if (argc == 1) { + filename = "payload.gz"; + } else { + filename = argv[1]; + } - int fd = open("payload.gz", O_RDONLY); + int fd = open(filename, O_RDONLY); struct stat statbuf; if (fstat(fd, &statbuf) == -1) { goto end; @@ -110,11 +163,11 @@ int main() { int ch; MEVENT event; - while (1) { + while (true) { ch = wgetch(stdscr); switch (ch) { case KEY_MOUSE: - wmove(stdscr, 0, 0); + // wmove(stdscr, 0, 0); switch (getmouse(&event)) { case OK: if (event.bstate & BUTTON4_PRESSED) { @@ -124,12 +177,17 @@ int main() { screen.top_address += LINE_LEN; } - if (event.x >= 10 && event.x < 10 + (int) ceil(LINE_LEN * 2.5)) { - screen.hx = (int) ((event.x - 10) / 2.5); - screen.hy = event.y; - } else if (event.x >= 10 + (int) ceil(LINE_LEN * 2.5) && event.x < (int) ceil(LINE_LEN * 2.5) + 10 + LINE_LEN) { - screen.hx = event.x - (10 + (int) ceil(LINE_LEN * 2.5)); - screen.hy = event.y; + if (event.y >= 0 && event.y < LINES - INFO_HEIGHT) { + if (event.x >= LINENO_WIDTH && event.x < LINENO_WIDTH + HEX_WIDTH) { + screen.hx = (int) ((event.x - LINENO_WIDTH) / 2.5); + screen.hy = event.y; + } else if (event.x >= LINENO_WIDTH + HEX_WIDTH && event.x < HEX_WIDTH + LINENO_WIDTH + LINE_LEN) { + screen.hx = event.x - (LINENO_WIDTH + HEX_WIDTH); + screen.hy = event.y; + } else { + screen.hx = -1; + screen.hy = -1; + } } else { screen.hx = -1; screen.hy = -1; @@ -141,16 +199,17 @@ int main() { // wprintw(win, "err"); break; } + draw_screen(); refresh(); break; case KEY_RESIZE: - wresize(screen.lineno, LINES, 0); - wresize(screen.hex, LINES, 0); - wresize(screen.chr, LINES, 0); + wresize(screen.lineno, LINES - INFO_HEIGHT, 0); + wresize(screen.hex, LINES - INFO_HEIGHT, 0); + wresize(screen.chr, LINES - INFO_HEIGHT, 0); draw_screen(); - mvprintw(0, 0, "%ix%i", COLS, LINES); - refresh(); + // mvprintw(0, 0, "%ix%i", COLS, LINES); + // refresh(); break; case KEY_ENTER: goto end; @@ -162,6 +221,7 @@ end: delwin(screen.lineno); delwin(screen.hex); delwin(screen.chr); + delwin(screen.info); endwin(); return 0; } |