From: Laurent Mazet Date: Thu, 3 Oct 2024 06:50:48 +0000 (+0200) Subject: init ncurses version X-Git-Tag: v2.0~13 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=5025b7bf6cfdc5e7ee636bc38d46197cb951050b;p=display.git init ncurses version --- diff --git a/makefile b/makefile index 7c570fa..f1694f2 100644 --- a/makefile +++ b/makefile @@ -11,7 +11,7 @@ INCLUDES = #OFLAGS += -minline-all-stringops -fsingle-precision-constant #OFLAGS += -malign-double CFLAGS += -W -Wall -Wextra -g -#CFLAGS += -std=c99 -D_XOPEN_SOURCE=500 +CFLAGS += -std=c99 -D_XOPEN_SOURCE=500 CFLAGS += $(OFLAGS) $(INCLUDES) $(OPTIONS) LDFLAGS += -g $(LDOPTS) $(OPTIONS) @@ -35,7 +35,7 @@ endif # Targets ALLEXE = -ALLEXE += display +ALLEXE += display ndisplay SHELL = bash diff --git a/ndisplay.c b/ndisplay.c new file mode 100644 index 0000000..fae2fdd --- /dev/null +++ b/ndisplay.c @@ -0,0 +1,220 @@ +/* depend: */ +/* cflags: */ +/* linker: color.o debug.o image.o pnm.o -lncursesw */ +/* doslnk: color.o debug.o image.o pnm.o -lpdc~2 */ +/* winlnk: color.o debug.o image.o pnm.o -lpdcursesw */ + +#include +#include +#include + +#include "color.h" +#include "debug.h" +#include "image.h" +#include "pnm.h" + +#define min(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) + +#define KEY_ESC 0x1b + +/* static variables */ +char *progname = NULL; +char *version = "0.1"; + +int colormap = 2; +float gf[3] = { 1.0f, 1.0f, 1.0f }; +int mode = 0; + +char *help = + " Move up\n" + " Move left\n" + " Move down\n" + " Move right\n" + " Quit\n" + ; + +int usage (int ret) +{ + FILE *fd = ret ? stderr : stdout; + fprintf (fd, "usage: %s [-g gamma] [-h] [-t|-w] [-v int] \n", progname); + fprintf (fd, " -g: gamma correction (%.1f:%.1f:%.1f)\n", gf[0], gf[1], gf[2]); + fprintf (fd, " -h: help message\n"); + fprintf (fd, " -t: thin mode (%s)\n", (mode == 0) ? "on" : "off"); + fprintf (fd, " -v: verbose level (%d)\n", verbose); + fprintf (fd, " -w: wide mode (%s)\n", (mode == 1) ? "on" : "off"); + fprintf (fd, "%s version %s\n", progname, version); + + return ret; +} + +/* main function */ +int main (int argc, char *argv[]) +{ + char *filename = NULL; + + /* get basename */ + char *pt = progname = argv[0]; + while (*pt) { + if ((*pt == '/') || (*pt == '\\')) { + progname = pt + 1; + } + pt++; + } + + /* process argument */ + while (argc-- > 1) { + char *arg = *(++argv); + if (arg[0] != '-') { + filename = arg; + continue; + } + char c = arg[1]; + switch (c) { + case 'g': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + VERBOSE (ERROR, fprintf (stderr, "%s: no gamma specified\n", progname)); + return usage (1); + } + gf[0] = strtof (arg, &pt); + if (*pt == '\0') { + gf[1] = gf[2] = gf[0]; + } else if (*pt == ':') { + gf[1] = strtof (pt + 1, &pt); + if (*pt == ':') { + gf[2] = strtof (pt + 1, &pt); + } else { + gf[2] = 0; + } + } else { + gf[1] = gf[2] = 0; + } + break; + case 't': + mode = 0; + break; + case 'v': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + VERBOSE (ERROR, fprintf (stderr, "%s: missing verbose level\n", progname)); + return usage (1); + } + verbose = atoi (arg); + break; + case 'w': + mode = 1; + break; + case 'h': + default: + return usage (c != 'h'); + } + } + + /* check */ + if ((colormap < 0) || (colormap > 3)) { + VERBOSE (ERROR, fprintf (stderr, "incorrect colormap (%d)\n", colormap)); + return 1; + } + if ((gf[0] <= 0) || (gf[1] <= 0) || (gf[2] <= 0)) { + VERBOSE (ERROR, fprintf (stderr, "incorrect gamma (%.1f:%.1f;%.1f)\n", gf[0], gf[1], gf[2])); + return 1; + } + if (filename == NULL) { + VERBOSE (ERROR, fprintf (stderr, "no file specified\n")); + return 1; + } + + /* main process */ + image_t *image = readpnm (filename); + + /* init curses window */ + initscr (); + noecho (); + cbreak (); + nonl (); + keypad (stdscr, TRUE); + curs_set (0); + start_color (); + + /* cursor definition */ + int xcursor = 0; + int ycursor = 0; + + /* init colormap */ + int c; + for (c = 0; c < 256; c++) { + init_pair (c, 0, c); + } + + /* event loop */ + int stop = 0; + while (!stop) { + + int width = min (image->width - xcursor, COLS); + int height = min (image->height - ycursor, LINES); + int x, y; + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + + int ind = (x + xcursor) + image->width * (y + ycursor); + color_t *color = findcolor (image->red[ind], image->green[ind], image->blue[ind], colormap); + //color_t *color = findcolor (correction (image->red[ind], gf[0]), correction (image->green[ind], gf[1]), correction (image->blue[ind], gf[2]), colormap); + attron (COLOR_PAIR (color->code)); + + move (y, x); + cchar_t tmp; + wchar_t tmp_wchar[2] = {0}; + tmp_wchar[0] = (wchar_t) ' '; + setcchar (&tmp, tmp_wchar, A_NORMAL, 0, NULL); + add_wch (&tmp); + } + } + refresh (); + attron (COLOR_PAIR (0)); + + switch (getch ()) { + case KEY_UP: + case 'i': + if (image->height - ycursor > LINES) { + ycursor--; + } + break; + case KEY_LEFT: + case 'j': + if (image->width - xcursor > COLS) { + xcursor--; + } + break; + case KEY_DOWN: + case 'k': + if (ycursor < 0) { + ycursor++; + } + break; + case KEY_RIGHT: + case 'l': + if (xcursor < 0) { + xcursor++; + } + break; + case KEY_ESC: + case 'q': + stop = 1; + break; + } + } + + /* cleaning before quiting */ + endwin (); + freeimage (image); + + return 0; +} + +/* test: ndisplay.exe -h | grep usage */ +/* test: ndisplay.exe -s 2>&1 | grep 'no scale' */ +/* test: ndisplay.exe -s 4 2>&1 | grep incorrect */ +/* test: ndisplay.exe -v 2>&1 | grep missing */ +/* test: ndisplay.exe _ 2>&1 | grep invalid */ + +/* vim: set ts=4 sw=4 et: */