/
githubmirror
/
lzop
Обзор
Документация
Войти
/
githubmirror
/
lzop
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/s_curses.c
409 строк
8 KB
Andrew Branson
[aarch64] Update to 1.04. Fixes JB#39692
16 янв 2018, 14:13
16 янв 2018, 14:13
50c04b9
Код
Авторство
О чём код?
/* s_curses.c -- This file is part of the lzop file compressor. Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer All Rights Reserved. lzop and the LZO library are free software; you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Markus F.X.J. Oberhumer <markus@oberhumer.com> http://www.oberhumer.com/opensource/lzop/ */ #include "conf.h" #if defined(USE_SCREEN) && defined(USE_SCREEN_CURSES) #include "screen.h" #define this local_this #define mask_fg 0x0f #define mask_bg 0xf0 /************************************************************************* // direct screen access **************************************************************************/ #include <termios.h> #include <ncurses.h> #undef refresh #undef clear struct screen_data_t { WINDOW *w; int mode; int page; int cols; int rows; int cursor_x; int cursor_y; unsigned char attr; unsigned char init_attr; chtype empty_cell; }; static void s_refresh(screen_t *this) { wrefresh(this->data->w); } static __inline__ chtype make_cell(screen_t *this, int ch, int attr) { int fg = attr & mask_fg; chtype c = ch & 0xff; if (fg < 8) c |= COLOR_PAIR((fg + 0)); else c |= COLOR_PAIR(((fg & 7) + 0)) | A_BOLD; return c; } static int getMode(const screen_t *this) { return this->data->mode; } static int getPage(const screen_t *this) { return this->data->page; } static int getRows(const screen_t *this) { return this->data->rows; } static int getCols(const screen_t *this) { return this->data->cols; } static int getFg(const screen_t *this) { return this->data->attr & mask_fg; } static int getBg(const screen_t *this) { return this->data->attr & mask_bg; } static void setFg(screen_t *this, int fg) { this->data->attr = (this->data->attr & mask_bg) | (fg & mask_fg); } static void setBg(screen_t *this, int bg) { this->data->attr = (this->data->attr & mask_fg) | (bg & mask_bg); } /* private */ static __inline__ int gotoxy(screen_t *this, int x, int y) { if (wmove(this->data->w, this->data->w->_begy+y, this->data->w->_begx+x) != ERR) return 0; return -1; } static void setCursor(screen_t *this, int x, int y) { if (gotoxy(this,x,y) == 0) { this->data->cursor_x = x; this->data->cursor_y = y; } } static void getCursor(const screen_t *this, int *x, int *y) { if (x) *x = this->data->cursor_x; if (y) *y = this->data->cursor_y; } static void putCharAttr(screen_t *this, int ch, int attr, int x, int y) { if (gotoxy(this,x,y) == 0) waddch(this->data->w,make_cell(this,ch,attr)); } static void putChar(screen_t *this, int ch, int x, int y) { putCharAttr(this,ch,this->data->attr,x,y); } static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y) { while (*s) putCharAttr(this,*s++,attr,x++,y); } static void putString(screen_t *this, const char *s, int x, int y) { putStringAttr(this,s,this->data->attr,x,y); } static int init(screen_t *this, int fd) { int fg, bg; if (!this || !this->data) return -1; this->data->mode = -1; this->data->page = 0; if (fd < 0 || !acc_isatty(fd)) return -1; this->data->w = initscr(); if (!this->data->w) return -1; (void) noecho(); this->data->cols = this->data->w->_maxx - this->data->w->_begx + 1; this->data->rows = this->data->w->_maxy - this->data->w->_begy + 1; this->data->cursor_x = this->data->w->_curx; this->data->cursor_y = this->data->w->_cury; this->data->empty_cell = ' '; if (has_colors()) start_color(); fg = (this->data->w->_attrs); bg = (this->data->w->_bkgd); fg = PAIR_NUMBER(this->data->w->_attrs); bg = PAIR_NUMBER(this->data->w->_bkgd); if (has_colors() && COLORS >= 8 && COLOR_PAIRS >= 8) this->data->mode = 3; else this->data->mode = 7; if (this->data->mode == 3) { int i = 0; init_pair(i++, COLOR_BLACK, bg); init_pair(i++, COLOR_BLUE, bg); init_pair(i++, COLOR_GREEN, bg); init_pair(i++, COLOR_CYAN, bg); init_pair(i++, COLOR_RED, bg); init_pair(i++, COLOR_MAGENTA, bg); init_pair(i++, COLOR_YELLOW, bg); init_pair(i++, COLOR_WHITE, bg); } this->data->attr = (bg << 4) | fg; this->data->attr = 0x07; return 0; } static void finalize(screen_t *this) { #if 0 if (this->data->w) (void) endwin(); #endif UNUSED(this); } static void updateLineN(screen_t *this, const void *line, int y, int len) { if (len > 0 && len <= 2*this->data->cols) { int x; const unsigned char *l = line; for (x = 0; x < len / 2; x++, l += 2) { #if 1 if ((l[1] & mask_bg) != BG_BLACK) putCharAttr(this,'#',l[1] >> 4,x,y); else putCharAttr(this,l[0],l[1],x,y); #else putCharAttr(this,l[0],l[1],x,y); #endif } } } static void clearLine(screen_t *this, int y) { int x; for (x = 0; x < this->data->cols; x++) if (gotoxy(this,x,y) == 0) waddch(this->data->w,this->data->empty_cell); } static void s_clear(screen_t *this) { int y; for (y = 0; y < this->data->rows; y++) clearLine(this,y); } static int scrollUp(screen_t *this, int lines) { if (lines <= 0) return 0; if (lines >= this->data->rows) s_clear(this); else wscrl(this->data->w,lines); return lines; } static int getCursorShape(const screen_t *this) { UNUSED(this); return 0; } static void setCursorShape(screen_t *this, int shape) { UNUSED(this); UNUSED(shape); } static int kbhit(screen_t *this) { const int fd = STDIN_FILENO; const unsigned long usec = 0; struct timeval tv; fd_set fds; UNUSED(this); FD_ZERO(&fds); FD_SET(fd, &fds); tv.tv_sec = usec / 1000000; tv.tv_usec = usec % 1000000; return (select(fd + 1, &fds, NULL, NULL, &tv) > 0); } static int intro(screen_t *this, void (*show_frames)(screen_t *) ) { int shape; struct termios term_old, term_new; int term_r; term_r = tcgetattr(STDIN_FILENO, &term_old); if (term_r == 0) { term_new = term_old; term_new.c_lflag &= ~(ISIG | ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &term_new); } shape = getCursorShape(this); setCursorShape(this,0x2000); show_frames(this); if (this->data->rows > 24) setCursor(this,this->data->cursor_x,this->data->cursor_y+1); setCursorShape(this,shape); s_refresh(this); if (term_r == 0) tcsetattr(STDIN_FILENO, TCSANOW, &term_old); return 1; } static const screen_t driver = { sobject_destroy, finalize, init, s_refresh, getMode, getPage, getRows, getCols, getFg, getBg, getCursor, getCursorShape, setFg, setBg, setCursor, setCursorShape, putChar, putCharAttr, putString, putStringAttr, s_clear, clearLine, updateLineN, scrollUp, kbhit, intro, (struct screen_data_t *) 0 }; /* public constructor */ screen_t *screen_curses_construct(void) { return sobject_construct(&driver,sizeof(*driver.data)); } #endif /* defined(USE_SCREEN) && defined(USE_SCREEN_CURSES) */ /* vim:set ts=4 sw=4 et: */