/* s_djgpp2.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 http://www.oberhumer.com/opensource/lzop/ */ #include "conf.h" #if defined(USE_SCREEN) && defined(__DJGPP__) #include "screen.h" #define this local_this #define mask_fg 0x0f #define mask_bg 0xf0 /************************************************************************* // direct screen access **************************************************************************/ #include #if 0 #include #endif #include #include #include #include #include #define dossel _go32_info_block.selector_for_linear_memory #define co80 _go32_info_block.linear_address_of_primary_screen #undef kbhit struct screen_data_t { int cols; int rows; int cursor_x; int cursor_y; unsigned char attr; unsigned char init_attr; unsigned char empty_attr; unsigned short empty_cell; }; static void refresh(screen_t *this) { UNUSED(this); } static __inline__ unsigned short make_cell(screen_t *this, int ch, int attr) { UNUSED(this); return ((attr & 0xff) << 8) | (ch & 0xff); } static int getMode(const screen_t *this) { UNUSED(this); return ScreenMode(); } static int getPage(const screen_t *this) { UNUSED(this); return _farpeekb(dossel, 0x462); } 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); } static void setCursor(screen_t *this, int x, int y) { if (x >= 0 && y >= 0 && x < this->data->cols && y < this->data->rows) { ScreenSetCursor(y,x); 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) { UNUSED(this); ScreenPutChar(ch,attr,x,y); } static void putChar(screen_t *this, int ch, int x, int y) { ScreenPutChar(ch,this->data->attr,x,y); } static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y) { UNUSED(this); ScreenPutString(s,attr,x,y); } static void putString(screen_t *this, const char *s, int x, int y) { ScreenPutString(s,this->data->attr,x,y); } /* private */ static void getChar(screen_t *this, int *ch, int *attr, int x, int y) { UNUSED(this); ScreenGetChar(ch,attr,x,y); } static int init(screen_t *this, int fd) { int mode; int attr; #if 0 /* force linkage of conio.o */ (void) _conio_kbhit(); #endif if (!this || !this->data) return -1; if (fd < 0 || !acc_isatty(fd)) return -1; mode = getMode(this); if (mode != 2 && mode != 3 && mode != 7) return -1; if (getPage(this) != 0) return -1; this->data->rows = ScreenRows(); this->data->cols = ScreenCols(); ScreenGetCursor(&this->data->cursor_y,&this->data->cursor_x); getChar(this,NULL,&attr,this->data->cursor_x,this->data->cursor_y); this->data->init_attr = attr; if (mode == 2 || mode == 3) { /* Does it normally blink when bg has its 3rd bit set? */ int b_mask = (_farpeekb(dossel, 0x465) & 0x20) ? 0x70 : 0xf0; attr = attr & (0x0f | b_mask); } this->data->attr = attr; this->data->empty_attr = attr; this->data->empty_cell = make_cell(this,' ',attr); return 0; } static void updateLineN(screen_t *this, const void *line, int y, int len) { if (y >= 0 && y < this->data->rows && len > 0 && len <= 2*this->data->cols) movedata(_my_ds(),(unsigned)line,dossel,co80+y*this->data->cols*2,len); } static void clearLine(screen_t *this, int y) { if (y >= 0 && y < this->data->rows) { unsigned sp = co80 + y * this->data->cols * 2; unsigned short a = this->data->empty_cell; int i = this->data->cols; _farsetsel(dossel); do { _farnspokew(sp, a); sp += 2; } while (--i); } } static void clear(screen_t *this) { unsigned char attr = ScreenAttrib; ScreenAttrib = this->data->empty_attr; ScreenClear(); ScreenAttrib = attr; } static int scrollUp(screen_t *this, int lines) { int sr = this->data->rows; int sc = this->data->cols; int y; if (lines <= 0) return 0; if (lines >= sr) clear(this); else { movedata(dossel,co80+lines*sc*2,dossel,co80,(sr-lines)*sc*2); for (y = sr - lines; y < sr; y++) clearLine(this,y); } return lines; } static int getCursorShape(const screen_t *this) { UNUSED(this); return _farpeekw(dossel, 0x460); } static void setCursorShape(screen_t *this, int shape) { __dpmi_regs r; r.h.ah = 0x01; r.h.al = getMode(this); r.x.cx = shape & 0x7f1f; __dpmi_int(0x10, &r); } static int s_kbhit(screen_t *this) { UNUSED(this); return kbhit(); } static int intro(screen_t *this, void (*show_frames)(screen_t *) ) { int shape; unsigned short old_flags = __djgpp_hwint_flags; if ((this->data->init_attr & mask_bg) != BG_BLACK) return 0; __djgpp_hwint_flags |= 3; while (kbhit()) (void) getkey(); shape = getCursorShape(this); setCursorShape(this,0x2000); show_frames(this); setCursorShape(this,shape); while (kbhit()) (void) getkey(); __djgpp_hwint_flags = old_flags; return 1; } static const screen_t driver = { sobject_destroy, 0, /* finalize, */ init, refresh, getMode, getPage, getRows, getCols, getFg, getBg, getCursor, getCursorShape, setFg, setBg, setCursor, setCursorShape, putChar, putCharAttr, putString, putStringAttr, clear, clearLine, updateLineN, scrollUp, s_kbhit, intro, (struct screen_data_t *) 0 }; /* public constructor */ screen_t *screen_djgpp2_construct(void) { return sobject_construct(&driver,sizeof(*driver.data)); } #endif /* defined(USE_SCREEN) && defined(__DJGPP__) */ /* vim:set ts=4 sw=4 et: */