| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,142 +0,0 @@ |
| 1 |
-#include <stdio.h> |
|
| 2 |
-#include <unistd.h> |
|
| 3 |
-#include <fcntl.h> |
|
| 4 |
-#include <stdlib.h> |
|
| 5 |
-#include <stdarg.h> |
|
| 6 |
-#include <termios.h> |
|
| 7 |
-#include <sys/ioctl.h> |
|
| 8 |
- |
|
| 9 |
-#include "tty.h" |
|
| 10 |
- |
|
| 11 |
-void tty_reset(tty_t *tty) {
|
|
| 12 |
- tcsetattr(tty->fdin, TCSANOW, &tty->original_termios); |
|
| 13 |
-} |
|
| 14 |
- |
|
| 15 |
-void tty_close(tty_t *tty) {
|
|
| 16 |
- tty_reset(tty); |
|
| 17 |
- fclose(tty->fout); |
|
| 18 |
- close(tty->fdin); |
|
| 19 |
-} |
|
| 20 |
- |
|
| 21 |
-void tty_init(tty_t *tty, const char *tty_filename) {
|
|
| 22 |
- tty->fdin = open(tty_filename, O_RDONLY); |
|
| 23 |
- if (tty->fdin < 0) {
|
|
| 24 |
- perror("Failed to open tty");
|
|
| 25 |
- exit(EXIT_FAILURE); |
|
| 26 |
- } |
|
| 27 |
- |
|
| 28 |
- tty->fout = fopen(tty_filename, "w"); |
|
| 29 |
- if (!tty->fout) {
|
|
| 30 |
- perror("Failed to open tty");
|
|
| 31 |
- exit(EXIT_FAILURE); |
|
| 32 |
- } |
|
| 33 |
- |
|
| 34 |
- if (setvbuf(tty->fout, NULL, _IOFBF, 4096)) {
|
|
| 35 |
- perror("setvbuf");
|
|
| 36 |
- exit(EXIT_FAILURE); |
|
| 37 |
- } |
|
| 38 |
- |
|
| 39 |
- if (tcgetattr(tty->fdin, &tty->original_termios)) {
|
|
| 40 |
- perror("tcgetattr");
|
|
| 41 |
- exit(EXIT_FAILURE); |
|
| 42 |
- } |
|
| 43 |
- |
|
| 44 |
- struct termios new_termios = tty->original_termios; |
|
| 45 |
- |
|
| 46 |
- /* |
|
| 47 |
- * Disable all of |
|
| 48 |
- * ICANON Canonical input (erase and kill processing). |
|
| 49 |
- * ECHO Echo. |
|
| 50 |
- * ISIG Signals from control characters |
|
| 51 |
- * ICRNL Conversion of CR characters into NL |
|
| 52 |
- */ |
|
| 53 |
- new_termios.c_iflag &= ~(ICRNL); |
|
| 54 |
- new_termios.c_lflag &= ~(ICANON | ECHO | ISIG); |
|
| 55 |
- |
|
| 56 |
- if (tcsetattr(tty->fdin, TCSANOW, &new_termios)) |
|
| 57 |
- perror("tcsetattr");
|
|
| 58 |
- |
|
| 59 |
- tty_getwinsz(tty); |
|
| 60 |
- |
|
| 61 |
- tty_setnormal(tty); |
|
| 62 |
-} |
|
| 63 |
- |
|
| 64 |
-void tty_getwinsz(tty_t *tty) {
|
|
| 65 |
- struct winsize ws; |
|
| 66 |
- if (ioctl(fileno(tty->fout), TIOCGWINSZ, &ws) == -1) {
|
|
| 67 |
- tty->maxwidth = 80; |
|
| 68 |
- tty->maxheight = 25; |
|
| 69 |
- } else {
|
|
| 70 |
- tty->maxwidth = ws.ws_col; |
|
| 71 |
- tty->maxheight = ws.ws_row; |
|
| 72 |
- } |
|
| 73 |
-} |
|
| 74 |
- |
|
| 75 |
-char tty_getchar(tty_t *tty) {
|
|
| 76 |
- char ch; |
|
| 77 |
- int size = read(tty->fdin, &ch, 1); |
|
| 78 |
- if (size < 0) {
|
|
| 79 |
- perror("error reading from tty");
|
|
| 80 |
- exit(EXIT_FAILURE); |
|
| 81 |
- } else if (size == 0) {
|
|
| 82 |
- /* EOF */ |
|
| 83 |
- exit(EXIT_FAILURE); |
|
| 84 |
- } else {
|
|
| 85 |
- return ch; |
|
| 86 |
- } |
|
| 87 |
-} |
|
| 88 |
- |
|
| 89 |
-static void tty_sgr(tty_t *tty, int code) {
|
|
| 90 |
- tty_printf(tty, "%c%c%im", 0x1b, '[', code); |
|
| 91 |
-} |
|
| 92 |
- |
|
| 93 |
-void tty_setfg(tty_t *tty, int fg) {
|
|
| 94 |
- if (tty->fgcolor != fg) {
|
|
| 95 |
- tty_sgr(tty, 30 + fg); |
|
| 96 |
- tty->fgcolor = fg; |
|
| 97 |
- } |
|
| 98 |
-} |
|
| 99 |
- |
|
| 100 |
-void tty_setinvert(tty_t *tty) {
|
|
| 101 |
- tty_sgr(tty, 7); |
|
| 102 |
-} |
|
| 103 |
- |
|
| 104 |
-void tty_setnormal(tty_t *tty) {
|
|
| 105 |
- tty_sgr(tty, 0); |
|
| 106 |
- tty->fgcolor = 9; |
|
| 107 |
-} |
|
| 108 |
- |
|
| 109 |
-void tty_newline(tty_t *tty) {
|
|
| 110 |
- tty_printf(tty, "%c%cK\n", 0x1b, '['); |
|
| 111 |
-} |
|
| 112 |
- |
|
| 113 |
-void tty_clearline(tty_t *tty) {
|
|
| 114 |
- tty_printf(tty, "%c%cK", 0x1b, '['); |
|
| 115 |
-} |
|
| 116 |
- |
|
| 117 |
-void tty_setcol(tty_t *tty, int col) {
|
|
| 118 |
- tty_printf(tty, "%c%c%iG", 0x1b, '[', col + 1); |
|
| 119 |
-} |
|
| 120 |
- |
|
| 121 |
-void tty_moveup(tty_t *tty, int i) {
|
|
| 122 |
- tty_printf(tty, "%c%c%iA", 0x1b, '[', i); |
|
| 123 |
-} |
|
| 124 |
- |
|
| 125 |
-void tty_printf(tty_t *tty, const char *fmt, ...) {
|
|
| 126 |
- va_list args; |
|
| 127 |
- va_start(args, fmt); |
|
| 128 |
- vfprintf(tty->fout, fmt, args); |
|
| 129 |
- va_end(args); |
|
| 130 |
-} |
|
| 131 |
- |
|
| 132 |
-void tty_flush(tty_t *tty) {
|
|
| 133 |
- fflush(tty->fout); |
|
| 134 |
-} |
|
| 135 |
- |
|
| 136 |
-size_t tty_getwidth(tty_t *tty) {
|
|
| 137 |
- return tty->maxwidth; |
|
| 138 |
-} |
|
| 139 |
- |
|
| 140 |
-size_t tty_getheight(tty_t *tty) {
|
|
| 141 |
- return tty->maxheight; |
|
| 142 |
-} |
Opening the tty may fail (for example if the wrong file is specified).
We now print an error and abort when this happens.
| ... | ... |
@@ -20,12 +20,26 @@ void tty_close(tty_t *tty) {
|
| 20 | 20 |
|
| 21 | 21 |
void tty_init(tty_t *tty, const char *tty_filename) {
|
| 22 | 22 |
tty->fdin = open(tty_filename, O_RDONLY); |
| 23 |
+ if (tty->fdin < 0) {
|
|
| 24 |
+ perror("Failed to open tty");
|
|
| 25 |
+ exit(EXIT_FAILURE); |
|
| 26 |
+ } |
|
| 27 |
+ |
|
| 23 | 28 |
tty->fout = fopen(tty_filename, "w"); |
| 24 |
- if (setvbuf(tty->fout, NULL, _IOFBF, 4096)) |
|
| 29 |
+ if (!tty->fout) {
|
|
| 30 |
+ perror("Failed to open tty");
|
|
| 31 |
+ exit(EXIT_FAILURE); |
|
| 32 |
+ } |
|
| 33 |
+ |
|
| 34 |
+ if (setvbuf(tty->fout, NULL, _IOFBF, 4096)) {
|
|
| 25 | 35 |
perror("setvbuf");
|
| 36 |
+ exit(EXIT_FAILURE); |
|
| 37 |
+ } |
|
| 26 | 38 |
|
| 27 |
- if (tcgetattr(tty->fdin, &tty->original_termios)) |
|
| 39 |
+ if (tcgetattr(tty->fdin, &tty->original_termios)) {
|
|
| 28 | 40 |
perror("tcgetattr");
|
| 41 |
+ exit(EXIT_FAILURE); |
|
| 42 |
+ } |
|
| 29 | 43 |
|
| 30 | 44 |
struct termios new_termios = tty->original_termios; |
| 31 | 45 |
|
I get a few reports of enter not working with fzy occasionally. This
usually occurrs after running a badly behaved program which doesn't
clean up the tty properly (looking at you, pry) after cleaning the
ICRNL flag.
This commit now always unsets ICRNL. This also could have been fixed by
ensuring ICRNL was set, but I believe this will give more control over
keybindings.
| ... | ... |
@@ -30,11 +30,13 @@ void tty_init(tty_t *tty, const char *tty_filename) {
|
| 30 | 30 |
struct termios new_termios = tty->original_termios; |
| 31 | 31 |
|
| 32 | 32 |
/* |
| 33 |
- * Disable both of |
|
| 33 |
+ * Disable all of |
|
| 34 | 34 |
* ICANON Canonical input (erase and kill processing). |
| 35 |
- * ECHO Enable echo. |
|
| 36 |
- * ISIG Enable signals from control characters |
|
| 35 |
+ * ECHO Echo. |
|
| 36 |
+ * ISIG Signals from control characters |
|
| 37 |
+ * ICRNL Conversion of CR characters into NL |
|
| 37 | 38 |
*/ |
| 39 |
+ new_termios.c_iflag &= ~(ICRNL); |
|
| 38 | 40 |
new_termios.c_lflag &= ~(ICANON | ECHO | ISIG); |
| 39 | 41 |
|
| 40 | 42 |
if (tcsetattr(tty->fdin, TCSANOW, &new_termios)) |
Apologies that this uses my preferred formatting style: mostly the same
as Linux, but without a break between function and brace. Adds spaces in
a few places they weren't before.
| ... | ... |
@@ -8,23 +8,23 @@ |
| 8 | 8 |
|
| 9 | 9 |
#include "tty.h" |
| 10 | 10 |
|
| 11 |
-void tty_reset(tty_t *tty){
|
|
| 11 |
+void tty_reset(tty_t *tty) {
|
|
| 12 | 12 |
tcsetattr(tty->fdin, TCSANOW, &tty->original_termios); |
| 13 | 13 |
} |
| 14 | 14 |
|
| 15 |
-void tty_close(tty_t *tty){
|
|
| 15 |
+void tty_close(tty_t *tty) {
|
|
| 16 | 16 |
tty_reset(tty); |
| 17 | 17 |
fclose(tty->fout); |
| 18 | 18 |
close(tty->fdin); |
| 19 | 19 |
} |
| 20 | 20 |
|
| 21 |
-void tty_init(tty_t *tty, const char *tty_filename){
|
|
| 21 |
+void tty_init(tty_t *tty, const char *tty_filename) {
|
|
| 22 | 22 |
tty->fdin = open(tty_filename, O_RDONLY); |
| 23 | 23 |
tty->fout = fopen(tty_filename, "w"); |
| 24 |
- if(setvbuf(tty->fout, NULL, _IOFBF, 4096)) |
|
| 24 |
+ if (setvbuf(tty->fout, NULL, _IOFBF, 4096)) |
|
| 25 | 25 |
perror("setvbuf");
|
| 26 | 26 |
|
| 27 |
- if(tcgetattr(tty->fdin, &tty->original_termios)) |
|
| 27 |
+ if (tcgetattr(tty->fdin, &tty->original_termios)) |
|
| 28 | 28 |
perror("tcgetattr");
|
| 29 | 29 |
|
| 30 | 30 |
struct termios new_termios = tty->original_termios; |
| ... | ... |
@@ -37,7 +37,7 @@ void tty_init(tty_t *tty, const char *tty_filename){
|
| 37 | 37 |
*/ |
| 38 | 38 |
new_termios.c_lflag &= ~(ICANON | ECHO | ISIG); |
| 39 | 39 |
|
| 40 |
- if(tcsetattr(tty->fdin, TCSANOW, &new_termios)) |
|
| 40 |
+ if (tcsetattr(tty->fdin, TCSANOW, &new_termios)) |
|
| 41 | 41 |
perror("tcsetattr");
|
| 42 | 42 |
|
| 43 | 43 |
tty_getwinsz(tty); |
| ... | ... |
@@ -45,82 +45,82 @@ void tty_init(tty_t *tty, const char *tty_filename){
|
| 45 | 45 |
tty_setnormal(tty); |
| 46 | 46 |
} |
| 47 | 47 |
|
| 48 |
-void tty_getwinsz(tty_t *tty){
|
|
| 48 |
+void tty_getwinsz(tty_t *tty) {
|
|
| 49 | 49 |
struct winsize ws; |
| 50 |
- if(ioctl(fileno(tty->fout), TIOCGWINSZ, &ws) == -1){
|
|
| 50 |
+ if (ioctl(fileno(tty->fout), TIOCGWINSZ, &ws) == -1) {
|
|
| 51 | 51 |
tty->maxwidth = 80; |
| 52 | 52 |
tty->maxheight = 25; |
| 53 |
- }else{
|
|
| 53 |
+ } else {
|
|
| 54 | 54 |
tty->maxwidth = ws.ws_col; |
| 55 | 55 |
tty->maxheight = ws.ws_row; |
| 56 | 56 |
} |
| 57 | 57 |
} |
| 58 | 58 |
|
| 59 |
-char tty_getchar(tty_t *tty){
|
|
| 59 |
+char tty_getchar(tty_t *tty) {
|
|
| 60 | 60 |
char ch; |
| 61 | 61 |
int size = read(tty->fdin, &ch, 1); |
| 62 |
- if(size < 0){
|
|
| 62 |
+ if (size < 0) {
|
|
| 63 | 63 |
perror("error reading from tty");
|
| 64 | 64 |
exit(EXIT_FAILURE); |
| 65 |
- }else if(size == 0){
|
|
| 65 |
+ } else if (size == 0) {
|
|
| 66 | 66 |
/* EOF */ |
| 67 | 67 |
exit(EXIT_FAILURE); |
| 68 |
- }else{
|
|
| 68 |
+ } else {
|
|
| 69 | 69 |
return ch; |
| 70 | 70 |
} |
| 71 | 71 |
} |
| 72 | 72 |
|
| 73 |
-static void tty_sgr(tty_t *tty, int code){
|
|
| 73 |
+static void tty_sgr(tty_t *tty, int code) {
|
|
| 74 | 74 |
tty_printf(tty, "%c%c%im", 0x1b, '[', code); |
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 |
-void tty_setfg(tty_t *tty, int fg){
|
|
| 78 |
- if(tty->fgcolor != fg){
|
|
| 77 |
+void tty_setfg(tty_t *tty, int fg) {
|
|
| 78 |
+ if (tty->fgcolor != fg) {
|
|
| 79 | 79 |
tty_sgr(tty, 30 + fg); |
| 80 | 80 |
tty->fgcolor = fg; |
| 81 | 81 |
} |
| 82 | 82 |
} |
| 83 | 83 |
|
| 84 |
-void tty_setinvert(tty_t *tty){
|
|
| 84 |
+void tty_setinvert(tty_t *tty) {
|
|
| 85 | 85 |
tty_sgr(tty, 7); |
| 86 | 86 |
} |
| 87 | 87 |
|
| 88 |
-void tty_setnormal(tty_t *tty){
|
|
| 88 |
+void tty_setnormal(tty_t *tty) {
|
|
| 89 | 89 |
tty_sgr(tty, 0); |
| 90 | 90 |
tty->fgcolor = 9; |
| 91 | 91 |
} |
| 92 | 92 |
|
| 93 |
-void tty_newline(tty_t *tty){
|
|
| 93 |
+void tty_newline(tty_t *tty) {
|
|
| 94 | 94 |
tty_printf(tty, "%c%cK\n", 0x1b, '['); |
| 95 | 95 |
} |
| 96 | 96 |
|
| 97 |
-void tty_clearline(tty_t *tty){
|
|
| 97 |
+void tty_clearline(tty_t *tty) {
|
|
| 98 | 98 |
tty_printf(tty, "%c%cK", 0x1b, '['); |
| 99 | 99 |
} |
| 100 | 100 |
|
| 101 |
-void tty_setcol(tty_t *tty, int col){
|
|
| 101 |
+void tty_setcol(tty_t *tty, int col) {
|
|
| 102 | 102 |
tty_printf(tty, "%c%c%iG", 0x1b, '[', col + 1); |
| 103 | 103 |
} |
| 104 | 104 |
|
| 105 |
-void tty_moveup(tty_t *tty, int i){
|
|
| 105 |
+void tty_moveup(tty_t *tty, int i) {
|
|
| 106 | 106 |
tty_printf(tty, "%c%c%iA", 0x1b, '[', i); |
| 107 | 107 |
} |
| 108 | 108 |
|
| 109 |
-void tty_printf(tty_t *tty, const char *fmt, ...){
|
|
| 109 |
+void tty_printf(tty_t *tty, const char *fmt, ...) {
|
|
| 110 | 110 |
va_list args; |
| 111 | 111 |
va_start(args, fmt); |
| 112 | 112 |
vfprintf(tty->fout, fmt, args); |
| 113 | 113 |
va_end(args); |
| 114 | 114 |
} |
| 115 | 115 |
|
| 116 |
-void tty_flush(tty_t *tty){
|
|
| 116 |
+void tty_flush(tty_t *tty) {
|
|
| 117 | 117 |
fflush(tty->fout); |
| 118 | 118 |
} |
| 119 | 119 |
|
| 120 |
-size_t tty_getwidth(tty_t *tty){
|
|
| 120 |
+size_t tty_getwidth(tty_t *tty) {
|
|
| 121 | 121 |
return tty->maxwidth; |
| 122 | 122 |
} |
| 123 | 123 |
|
| 124 |
-size_t tty_getheight(tty_t *tty){
|
|
| 124 |
+size_t tty_getheight(tty_t *tty) {
|
|
| 125 | 125 |
return tty->maxheight; |
| 126 | 126 |
} |
| ... | ... |
@@ -33,7 +33,7 @@ void tty_init(tty_t *tty, const char *tty_filename){
|
| 33 | 33 |
* Disable both of |
| 34 | 34 |
* ICANON Canonical input (erase and kill processing). |
| 35 | 35 |
* ECHO Enable echo. |
| 36 |
- * ISIG Disable signals from control characters |
|
| 36 |
+ * ISIG Enable signals from control characters |
|
| 37 | 37 |
*/ |
| 38 | 38 |
new_termios.c_lflag &= ~(ICANON | ECHO | ISIG); |
| 39 | 39 |
|
Allows us to interpret ^C through ^Z as control codes and handle them
properly.
Also fixes resetting termios after ^C
| ... | ... |
@@ -33,8 +33,9 @@ void tty_init(tty_t *tty, const char *tty_filename){
|
| 33 | 33 |
* Disable both of |
| 34 | 34 |
* ICANON Canonical input (erase and kill processing). |
| 35 | 35 |
* ECHO Enable echo. |
| 36 |
+ * ISIG Disable signals from control characters |
|
| 36 | 37 |
*/ |
| 37 |
- new_termios.c_lflag &= ~(ICANON | ECHO); |
|
| 38 |
+ new_termios.c_lflag &= ~(ICANON | ECHO | ISIG); |
|
| 38 | 39 |
|
| 39 | 40 |
if(tcsetattr(tty->fdin, TCSANOW, &new_termios)) |
| 40 | 41 |
perror("tcsetattr");
|
Still needs to be fixed on an exit due to ^C
Thanks @rtandy
| ... | ... |
@@ -12,6 +12,12 @@ void tty_reset(tty_t *tty){
|
| 12 | 12 |
tcsetattr(tty->fdin, TCSANOW, &tty->original_termios); |
| 13 | 13 |
} |
| 14 | 14 |
|
| 15 |
+void tty_close(tty_t *tty){
|
|
| 16 |
+ tty_reset(tty); |
|
| 17 |
+ fclose(tty->fout); |
|
| 18 |
+ close(tty->fdin); |
|
| 19 |
+} |
|
| 20 |
+ |
|
| 15 | 21 |
void tty_init(tty_t *tty, const char *tty_filename){
|
| 16 | 22 |
tty->fdin = open(tty_filename, O_RDONLY); |
| 17 | 23 |
tty->fout = fopen(tty_filename, "w"); |
| ... | ... |
@@ -43,8 +43,10 @@ void tty_getwinsz(tty_t *tty){
|
| 43 | 43 |
struct winsize ws; |
| 44 | 44 |
if(ioctl(fileno(tty->fout), TIOCGWINSZ, &ws) == -1){
|
| 45 | 45 |
tty->maxwidth = 80; |
| 46 |
+ tty->maxheight = 25; |
|
| 46 | 47 |
}else{
|
| 47 | 48 |
tty->maxwidth = ws.ws_col; |
| 49 |
+ tty->maxheight = ws.ws_row; |
|
| 48 | 50 |
} |
| 49 | 51 |
} |
| 50 | 52 |
|
| ... | ... |
@@ -112,3 +114,7 @@ void tty_flush(tty_t *tty){
|
| 112 | 114 |
size_t tty_getwidth(tty_t *tty){
|
| 113 | 115 |
return tty->maxwidth; |
| 114 | 116 |
} |
| 117 |
+ |
|
| 118 |
+size_t tty_getheight(tty_t *tty){
|
|
| 119 |
+ return tty->maxheight; |
|
| 120 |
+} |
| ... | ... |
@@ -16,9 +16,11 @@ void tty_reset(tty_t *tty){
|
| 16 | 16 |
void tty_init(tty_t *tty, const char *tty_filename){
|
| 17 | 17 |
tty->fdin = open(tty_filename, O_RDONLY); |
| 18 | 18 |
tty->fout = fopen(tty_filename, "w"); |
| 19 |
- setvbuf(tty->fout, NULL, _IOFBF, 4096); |
|
| 19 |
+ if(setvbuf(tty->fout, NULL, _IOFBF, 4096)) |
|
| 20 |
+ perror("setvbuf");
|
|
| 20 | 21 |
|
| 21 |
- tcgetattr(tty->fdin, &tty->original_termios); |
|
| 22 |
+ if(tcgetattr(tty->fdin, &tty->original_termios)) |
|
| 23 |
+ perror("tcgetattr");
|
|
| 22 | 24 |
|
| 23 | 25 |
struct termios new_termios = tty->original_termios; |
| 24 | 26 |
|
| ... | ... |
@@ -29,7 +31,8 @@ void tty_init(tty_t *tty, const char *tty_filename){
|
| 29 | 31 |
*/ |
| 30 | 32 |
new_termios.c_lflag &= ~(ICANON | ECHO); |
| 31 | 33 |
|
| 32 |
- tcsetattr(tty->fdin, TCSANOW, &new_termios); |
|
| 34 |
+ if(tcsetattr(tty->fdin, TCSANOW, &new_termios)) |
|
| 35 |
+ perror("tcsetattr");
|
|
| 33 | 36 |
|
| 34 | 37 |
tty_getwinsz(tty); |
| 35 | 38 |
|
| ... | ... |
@@ -1,8 +1,11 @@ |
| 1 |
+#define _GNU_SOURCE |
|
| 1 | 2 |
#include <stdio.h> |
| 2 | 3 |
#include <unistd.h> |
| 3 | 4 |
#include <fcntl.h> |
| 4 | 5 |
#include <stdlib.h> |
| 5 | 6 |
#include <stdarg.h> |
| 7 |
+#include <termios.h> |
|
| 8 |
+#include <sys/ioctl.h> |
|
| 6 | 9 |
|
| 7 | 10 |
#include "tty.h" |
| 8 | 11 |
|
| ... | ... |
@@ -28,9 +31,20 @@ void tty_init(tty_t *tty, const char *tty_filename){
|
| 28 | 31 |
|
| 29 | 32 |
tcsetattr(tty->fdin, TCSANOW, &new_termios); |
| 30 | 33 |
|
| 34 |
+ tty_getwinsz(tty); |
|
| 35 |
+ |
|
| 31 | 36 |
tty_setnormal(tty); |
| 32 | 37 |
} |
| 33 | 38 |
|
| 39 |
+void tty_getwinsz(tty_t *tty){
|
|
| 40 |
+ struct winsize ws; |
|
| 41 |
+ if(ioctl(fileno(tty->fout), TIOCGWINSZ, &ws) == -1){
|
|
| 42 |
+ tty->maxwidth = 80; |
|
| 43 |
+ }else{
|
|
| 44 |
+ tty->maxwidth = ws.ws_col; |
|
| 45 |
+ } |
|
| 46 |
+} |
|
| 47 |
+ |
|
| 34 | 48 |
char tty_getchar(tty_t *tty){
|
| 35 | 49 |
char ch; |
| 36 | 50 |
int size = read(tty->fdin, &ch, 1); |
| ... | ... |
@@ -92,3 +106,6 @@ void tty_flush(tty_t *tty){
|
| 92 | 106 |
fflush(tty->fout); |
| 93 | 107 |
} |
| 94 | 108 |
|
| 109 |
+size_t tty_getwidth(tty_t *tty){
|
|
| 110 |
+ return tty->maxwidth; |
|
| 111 |
+} |
| ... | ... |
@@ -10,9 +10,9 @@ void tty_reset(tty_t *tty){
|
| 10 | 10 |
tcsetattr(tty->fdin, TCSANOW, &tty->original_termios); |
| 11 | 11 |
} |
| 12 | 12 |
|
| 13 |
-void tty_init(tty_t *tty){
|
|
| 14 |
- tty->fdin = open("/dev/tty", O_RDONLY);
|
|
| 15 |
- tty->fout = fopen("/dev/tty", "w");
|
|
| 13 |
+void tty_init(tty_t *tty, const char *tty_filename){
|
|
| 14 |
+ tty->fdin = open(tty_filename, O_RDONLY); |
|
| 15 |
+ tty->fout = fopen(tty_filename, "w"); |
|
| 16 | 16 |
setvbuf(tty->fout, NULL, _IOFBF, 4096); |
| 17 | 17 |
|
| 18 | 18 |
tcgetattr(tty->fdin, &tty->original_termios); |
| ... | ... |
@@ -19,6 +19,11 @@ void tty_init(tty_t *tty){
|
| 19 | 19 |
|
| 20 | 20 |
struct termios new_termios = tty->original_termios; |
| 21 | 21 |
|
| 22 |
+ /* |
|
| 23 |
+ * Disable both of |
|
| 24 |
+ * ICANON Canonical input (erase and kill processing). |
|
| 25 |
+ * ECHO Enable echo. |
|
| 26 |
+ */ |
|
| 22 | 27 |
new_termios.c_lflag &= ~(ICANON | ECHO); |
| 23 | 28 |
|
| 24 | 29 |
tcsetattr(tty->fdin, TCSANOW, &new_termios); |
| ... | ... |
@@ -64,6 +64,10 @@ void tty_newline(tty_t *tty){
|
| 64 | 64 |
tty_printf(tty, "%c%cK\n", 0x1b, '['); |
| 65 | 65 |
} |
| 66 | 66 |
|
| 67 |
+void tty_clearline(tty_t *tty){
|
|
| 68 |
+ tty_printf(tty, "%c%cK", 0x1b, '['); |
|
| 69 |
+} |
|
| 70 |
+ |
|
| 67 | 71 |
void tty_setcol(tty_t *tty, int col){
|
| 68 | 72 |
tty_printf(tty, "%c%c%iG", 0x1b, '[', col + 1); |
| 69 | 73 |
} |
| ... | ... |
@@ -67,6 +67,10 @@ void tty_setcol(tty_t *tty, int col){
|
| 67 | 67 |
tty_printf(tty, "%c%c%iG", 0x1b, '[', col); |
| 68 | 68 |
} |
| 69 | 69 |
|
| 70 |
+void tty_moveup(tty_t *tty, int i){
|
|
| 71 |
+ tty_printf(tty, "%c%c%iA", 0x1b, '[', i); |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 70 | 74 |
void tty_printf(tty_t *tty, const char *fmt, ...){
|
| 71 | 75 |
va_list args; |
| 72 | 76 |
va_start(args, fmt); |
| ... | ... |
@@ -59,6 +59,14 @@ void tty_setnormal(tty_t *tty){
|
| 59 | 59 |
tty->fgcolor = 9; |
| 60 | 60 |
} |
| 61 | 61 |
|
| 62 |
+void tty_newline(tty_t *tty){
|
|
| 63 |
+ tty_printf(tty, "%c%cK\n", 0x1b, '['); |
|
| 64 |
+} |
|
| 65 |
+ |
|
| 66 |
+void tty_setcol(tty_t *tty, int col){
|
|
| 67 |
+ tty_printf(tty, "%c%c%iG", 0x1b, '[', col); |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 62 | 70 |
void tty_printf(tty_t *tty, const char *fmt, ...){
|
| 63 | 71 |
va_list args; |
| 64 | 72 |
va_start(args, fmt); |
| ... | ... |
@@ -2,6 +2,7 @@ |
| 2 | 2 |
#include <unistd.h> |
| 3 | 3 |
#include <fcntl.h> |
| 4 | 4 |
#include <stdlib.h> |
| 5 |
+#include <stdarg.h> |
|
| 5 | 6 |
|
| 6 | 7 |
#include "tty.h" |
| 7 | 8 |
|
| ... | ... |
@@ -39,7 +40,7 @@ char tty_getchar(tty_t *tty){
|
| 39 | 40 |
} |
| 40 | 41 |
|
| 41 | 42 |
static void tty_sgr(tty_t *tty, int code){
|
| 42 |
- fprintf(tty->fout, "%c%c%im", 0x1b, '[', code); |
|
| 43 |
+ tty_printf(tty, "%c%c%im", 0x1b, '[', code); |
|
| 43 | 44 |
} |
| 44 | 45 |
|
| 45 | 46 |
void tty_setfg(tty_t *tty, int fg){
|
| ... | ... |
@@ -58,3 +59,10 @@ void tty_setnormal(tty_t *tty){
|
| 58 | 59 |
tty->fgcolor = 9; |
| 59 | 60 |
} |
| 60 | 61 |
|
| 62 |
+void tty_printf(tty_t *tty, const char *fmt, ...){
|
|
| 63 |
+ va_list args; |
|
| 64 |
+ va_start(args, fmt); |
|
| 65 |
+ vfprintf(tty->fout, fmt, args); |
|
| 66 |
+ va_end(args); |
|
| 67 |
+} |
|
| 68 |
+ |
| ... | ... |
@@ -20,6 +20,8 @@ void tty_init(tty_t *tty){
|
| 20 | 20 |
new_termios.c_lflag &= ~(ICANON | ECHO); |
| 21 | 21 |
|
| 22 | 22 |
tcsetattr(tty->fdin, TCSANOW, &new_termios); |
| 23 |
+ |
|
| 24 |
+ tty_setnormal(tty); |
|
| 23 | 25 |
} |
| 24 | 26 |
|
| 25 | 27 |
char tty_getchar(tty_t *tty){
|
| ... | ... |
@@ -36,3 +38,23 @@ char tty_getchar(tty_t *tty){
|
| 36 | 38 |
} |
| 37 | 39 |
} |
| 38 | 40 |
|
| 41 |
+static void tty_sgr(tty_t *tty, int code){
|
|
| 42 |
+ fprintf(tty->fout, "%c%c%im", 0x1b, '[', code); |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+void tty_setfg(tty_t *tty, int fg){
|
|
| 46 |
+ if(tty->fgcolor != fg){
|
|
| 47 |
+ tty_sgr(tty, 30 + fg); |
|
| 48 |
+ tty->fgcolor = fg; |
|
| 49 |
+ } |
|
| 50 |
+} |
|
| 51 |
+ |
|
| 52 |
+void tty_setinvert(tty_t *tty){
|
|
| 53 |
+ tty_sgr(tty, 7); |
|
| 54 |
+} |
|
| 55 |
+ |
|
| 56 |
+void tty_setnormal(tty_t *tty){
|
|
| 57 |
+ tty_sgr(tty, 0); |
|
| 58 |
+ tty->fgcolor = 9; |
|
| 59 |
+} |
|
| 60 |
+ |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,38 @@ |
| 1 |
+#include <stdio.h> |
|
| 2 |
+#include <unistd.h> |
|
| 3 |
+#include <fcntl.h> |
|
| 4 |
+#include <stdlib.h> |
|
| 5 |
+ |
|
| 6 |
+#include "tty.h" |
|
| 7 |
+ |
|
| 8 |
+void tty_reset(tty_t *tty){
|
|
| 9 |
+ tcsetattr(tty->fdin, TCSANOW, &tty->original_termios); |
|
| 10 |
+} |
|
| 11 |
+ |
|
| 12 |
+void tty_init(tty_t *tty){
|
|
| 13 |
+ tty->fdin = open("/dev/tty", O_RDONLY);
|
|
| 14 |
+ tty->fout = fopen("/dev/tty", "w");
|
|
| 15 |
+ |
|
| 16 |
+ tcgetattr(tty->fdin, &tty->original_termios); |
|
| 17 |
+ |
|
| 18 |
+ struct termios new_termios = tty->original_termios; |
|
| 19 |
+ |
|
| 20 |
+ new_termios.c_lflag &= ~(ICANON | ECHO); |
|
| 21 |
+ |
|
| 22 |
+ tcsetattr(tty->fdin, TCSANOW, &new_termios); |
|
| 23 |
+} |
|
| 24 |
+ |
|
| 25 |
+char tty_getchar(tty_t *tty){
|
|
| 26 |
+ char ch; |
|
| 27 |
+ int size = read(tty->fdin, &ch, 1); |
|
| 28 |
+ if(size < 0){
|
|
| 29 |
+ perror("error reading from tty");
|
|
| 30 |
+ exit(EXIT_FAILURE); |
|
| 31 |
+ }else if(size == 0){
|
|
| 32 |
+ /* EOF */ |
|
| 33 |
+ exit(EXIT_FAILURE); |
|
| 34 |
+ }else{
|
|
| 35 |
+ return ch; |
|
| 36 |
+ } |
|
| 37 |
+} |
|
| 38 |
+ |