From 145091f8019f53d3bc19c369793e835ce4a28972 Mon Sep 17 00:00:00 2001 From: Koxiaet <38139193+Koxiaet@users.noreply.github.com> Date: Wed, 23 Oct 2019 18:41:19 +0100 Subject: [PATCH] Add settitle, setcurshape, gettermsize, getch and getche (#3) * added Makefile, make functions static * added settitle, setcurshape, gettermsize * added getch and getche --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 2 + Makefile | 16 +++++ readme.md => README.md | 41 +++++++---- demo.c | 45 ++++++++++-- nocurses.h | 160 ++++++++++++++++++++++++++++++++++------- 6 files changed, 220 insertions(+), 44 deletions(-) delete mode 100644 .DS_Store create mode 100644 .gitignore create mode 100644 Makefile rename readme.md => README.md (50%) diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index eff60f7150e64885761650c0a7c81a25b7a122b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z-O8rihq>sK>o{>!I~hFG7g*;7y3=LB%Gdw1G5Rn$(~*lDE(|@)3L; zXLdJYvEWU_&cN@a3C#w=)v9F--4!%JN?6O71lj&u^lG63r> zm>Az*2mJOri`bYAgZ%6F$5EQK+wZ(qZ>+6vSSVZ8tv8anm-*Q&b^YlzTIYT?3XFas zW&El8!DTea@9dounPh&H45lhM3I`B!a}_0_%w0K4!c@)UX-5;~&fcBRyNB(TXcsM^ zwWDsgD4N#ZLFf3aKYn+!!7C`HxO;D!#4;JeNEKa05fTH$05L!e ztQZ64Ah0%9tZpio7$63IW&rmG0S(bHSZY*T2XuISMt=hl1$2B%APR$y!BQi5K)6l? z)T!J&F}O~Labe;dgQZ5D&bV3`<}oW*j~A|1hjF388Fw^NPYe(PiwxAYY2*2S3ct+K zNB&|8S;PP_@Xr|Fjh@$Yp(t~YQI1o;v9pe VMw|u5RXQMD1Qa3E5d*)#zz3{+PfY*- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f94719 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +demo diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c1cb19e --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +CC::=cc +PREFIX::=/usr/local + +all: + +install: nocurses.h + install -CD nocurses.h ${PREFIX}/include/nocurses.h + +uninstall: + rm ${PREFIX}/include/nocurses.h + +demo: demo.c nocurses.h + ${CC} -pthread -lm -o demo demo.c + +clean: + rm demo diff --git a/readme.md b/README.md similarity index 50% rename from readme.md rename to README.md index 3c4cec0..ee9a70f 100644 --- a/readme.md +++ b/README.md @@ -10,18 +10,23 @@ Here's a demo (demo.c file avaiable in the same repo): ![nocurses.h](img/nocurses.gif) ## Functions Provided -| Function | Description | Example | -|--------------------------|:--------------------------------------------------------------------------------------:|:--------------------:| -| pause() | Waits for the user to hit [ENTER]. | pause(); | -| clrscr() | Clears the screen. | clrscr(); | -| gotoxy(x, y) | Sets the cursor do the position x, y. Where x is the row number and y the line number. | gotoxy(10,25); | -| setfontcolor(color_name) | Sets the text color to one of the colors described on the color table below. | setfontcolor(RED); | -| setbgrcolor(color_name) | Sets the background color to one of the colors described on the color table below. | setbgrcolor(BLUE); | -| setfontbold(status) | Sets the bold attribute on or off. status can be TRUE or FALSE. | setfontbold(TRUE); | -| setunderline(status) | Sets the underline attribute on or off. status can be TRUE or FALSE. | setunderline(FALSE); | -| setblink(status) | Sets the blink attribute on or off. status can be TRUE or FALSE. | setblink(TRUE); | -| clrline() | Clears the row contents. | clrline(); | -| resetcolors() | Reset terminal to default colors. | clrline(); | +| Function | Description | Example | +|--------------------------|:--------------------------------------------------------------------------------------:|:------------------------:| +| wait() | Waits for the user to hit [ENTER]. | wait(); | +| clrscr() | Clears the screen. | clrscr(); | +| gotoxy(x, y) | Sets the cursor do the position x, y. Where x is the row number and y the line number. | gotoxy(10,25); | +| setfontcolor(color_name) | Sets the text color to one of the colors described on the color table below. | setfontcolor(RED); | +| setbgrcolor(color_name) | Sets the background color to one of the colors described on the color table below. | setbgrcolor(BLUE); | +| setfontbold(status) | Sets the bold attribute on or off. status can be TRUE or FALSE. | setfontbold(TRUE); | +| setunderline(status) | Sets the underline attribute on or off. status can be TRUE or FALSE. | setunderline(FALSE); | +| setblink(status) | Sets the blink attribute on or off. status can be TRUE or FALSE. | setblink(TRUE); | +| settitle(title) | Sets the title of the terminal. | settitle("Hello World"); | +| setcurshape(shape_name) | Sets the shape of the cursor in the terminal in the shape table below. | setcurshape(BAR); | +| gettermsize() | Gets the columns and rows of the terminal. | gettermsize(); | +| getch() | Gets a character without waiting for enter. | getch(); | +| getche() | Gets a character and echoes it without waiting for enter. | getche(); | +| clrline() | Clears the row contents. | clrline(); | +| resetcolors() | Reset terminal to default colors. | clrline(); | ## color_name @@ -39,4 +44,16 @@ Valid color names are: | CYAN | | WHITE | +## shape_name + +Valid shape names are: + +| shape_name | +|:---------------:| +| BLOCK_BLINK | +| BLOCK | +| UNDERLINE_BLINK | +| UNDERLINE | +| BAR_BLINK | +| BAR | diff --git a/demo.c b/demo.c index 9545899..5a707de 100644 --- a/demo.c +++ b/demo.c @@ -3,7 +3,7 @@ nocurses.h - nocurses library demo - Compile and run with: $gcc -pthread -lm -o demo demo.c && ./demo + Compile and run with: $ make demo && ./demo */ @@ -15,7 +15,7 @@ int i; int waiting(){ printf("\n\nHit ENTER to continue..."); - pause(); + wait(); clrscr(); return 0; } @@ -56,21 +56,22 @@ int main(void) { setfontcolor(WHITE); printf("\n\n\nHello! Welcome to nocurses.h demo!\nLet me present you its features... \n"); - waiting(); printf("The nocurses.h provides these set of functions:\n\n\ -pause()\n\ +wait()\n\ clrscr()\n\ setfontcolor(COLOR_NAME)\n\ setbgrcolor(COLOR_NAME)\n\ gotoxy(XPOS,YPOS)\n\ setfontbold(STATE)\n\ setunderline(STATE)\n\ -setblink(STATE)\n"); +setblink(STATE)\n\ +settitle(TITLE)\n\ +gettermsize()\n"); waiting(); - printf("I am using the pause() function to wait for your\ncommand."); + printf("I am using the wait() function to wait for your\ncommand."); waiting(); printf("See it? The screen was cleared with the clrscr() funciton."); @@ -105,10 +106,24 @@ setblink(STATE)\n"); resetcolors(); clrscr(); - printf("Now I used resetcolors()"); waiting(); + struct termsize size = gettermsize(); + printf("I can detect your terminal size.\n\nThis terminal is %d columns and %d rows, so one line should look like this:\n\n", size.cols, size.rows); + for (int i=0;i setblink(FALSE)\n\n"); waiting(); + settitle("nocurses demo"); + printf("Title is set to \"nocurses demo\" --> settitle(\"nocurses demo\")\n\n"); + waiting(); + + setcurshape(BLOCK); + printf("Cursor is set to BLOCK --> setcurshape(BLOCK)\n\n"); + waiting(); + + setcurshape(UNDERLINE); + printf("Cursor is set to UNDERLINE --> setcurshape(UNDERLINE)\n\n"); + waiting(); + + setcurshape(BAR); + printf("Cursor is set to BAR --> setcurshape(BAR)\n\n"); + waiting(); + printf("\n\nThat's all! Simple nocurses.h\n\nContribute with it on https://github.com/LionyxML/nocurses/\n\n"); waiting(); diff --git a/nocurses.h b/nocurses.h index 8f39b71..d841166 100644 --- a/nocurses.h +++ b/nocurses.h @@ -9,8 +9,19 @@ */ #include +#ifdef _WIN32 +# include +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) || defined(__linux__) +# ifndef __unix__ +# define __unix__ +# endif +# include +# include +# include +#endif + +#define ESC "\x1b" -#define ESC 27 #define BLACK 0 #define RED 1 #define GREEN 2 @@ -20,69 +31,168 @@ #define CYAN 6 #define WHITE 7 +#define BLOCK_BLINK 1 +#define BLOCK 2 +#define UNDERLINE_BLINK 3 +#define UNDERLINE 4 +#define BAR_BLINK 5 +#define BAR 6 + #define TRUE 1 #define FALSE 0 - -int bg_color = BLACK, - font_color = WHITE, - font_bold = FALSE; +struct termsize { + int cols; + int rows; +}; -void pause(){ - fgetc(stdin); +static int bg_color = BLACK, + font_color = WHITE, + font_bold = FALSE; + + +static void wait(){ + while (fgetc(stdin) != '\n'); } -void clrscr(){ - printf("%c[2J%c[?6h", ESC, ESC); +static void clrscr(){ + printf(ESC"[2J"ESC"[?6h"); } -void gotoxy(int x, int y){ - printf("%c[%d;%dH", ESC, y, x); +static void gotoxy(int x, int y){ + printf(ESC"[%d;%dH", y, x); } -void setfontcolor(int color){ - printf("%c[3%dm", ESC, color); +static void setfontcolor(int color){ + printf(ESC"[3%dm", color); font_color = color; } -void setbgrcolor(int color){ - printf("%c[4%dm", ESC, color); +static void setbgrcolor(int color){ + printf(ESC"[4%dm", color); bg_color = color; } -void setfontbold(int status){ - printf("%c[%dm", ESC, status); +static void setfontbold(int status){ + printf(ESC"[%dm", status); font_bold = status; setfontcolor(font_color); setbgrcolor(bg_color); } -void setunderline(int status){ +static void setunderline(int status){ if (status) status = 4; - printf("%c[%dm", ESC, status); + printf(ESC"[%dm", status); setfontcolor(font_color); setbgrcolor(bg_color); setfontbold(font_bold); } -void setblink(int status){ +static void setblink(int status){ if (status) status = 5; - printf("%c[%dm", ESC, status); + printf(ESC"[%dm", status); setfontcolor(font_color); setbgrcolor(bg_color); setfontbold(font_bold); } -void clrline(){ - printf("%c[2K%cE", ESC, ESC); +static void settitle(char const* title) { + printf(ESC"]0;%s\x7", title); } -void resetcolors(){ - printf("%c001b%c[0m", ESC, ESC); +static void setcurshape(int shape){ + // vt520/xterm-style; linux terminal uses ESC[?1;2;3c, not implemented + printf(ESC"[%d q", shape); +} + +static struct termsize gettermsize(){ + struct termsize size; +#ifdef _WIN32 + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + size.cols = csbi.srWindow.Right - csbi.srWindow.Left + 1; + size.rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; +#elif defined(__unix__) + struct winsize win; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &win); + size.cols = win.ws_col; + size.rows = win.ws_row; +#else + size.cols = 0; + size.rows = 0; +#endif + return size; +} + +static int getch(){ +#ifdef _WIN32 + HANDLE input = GetStdHandle(STD_INPUT_HANDLE); + if (h == NULL) return EOF; + + DWORD oldmode; + GetConsoleMode(input, &oldmode); + DWORD newmode = oldmode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); + SetConsoleMode(input, newmode); +#elif defined(__unix__) + struct termios oldattr, newattr; + tcgetattr(STDIN_FILENO, &oldattr); + + newattr = oldattr; + newattr.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newattr); +#endif + + int ch = getc(stdin); + +#ifdef _WIN32 + SetConsoleMode(input, oldmode); +#elif defined(__unix__) + tcsetattr(STDIN_FILENO, TCSANOW, &oldattr); +#endif + + return ch; +} + +static int getche(){ +#ifdef _WIN32 + HANDLE input = GetStdHandle(STD_INPUT_HANDLE); + if (h == NULL) return EOF; + + DWORD oldmode; + GetConsoleMode(input, &oldmode); + DWORD newmode = oldmode & ~ENABLE_LINE_INPUT; + SetConsoleMode(input, newmode); +#elif defined(__unix__) + struct termios oldattr, newattr; + tcgetattr(STDIN_FILENO, &oldattr); + + newattr = oldattr; + newattr.c_lflag &= ~ICANON; + tcsetattr(STDIN_FILENO, TCSANOW, &newattr); +#endif + + int ch = getc(stdin); + +#ifdef _WIN32 + SetConsoleMode(input, oldmode); +#elif defined(__unix__) + tcsetattr(STDIN_FILENO, TCSANOW, &oldattr); +#endif + + return ch; +} + +static void clrline(){ + printf(ESC"[2K"ESC"E"); +} + +static void resetcolors(){ + printf(ESC"001b"ESC"[0m"); }