diff --git a/src/conio/ciolib.c b/src/conio/ciolib.c index 37457c09d9119d1e535a02e5cc34c0003f766486..e93dcb87e182de73f0568d8099f33553eb494eea 100644 --- a/src/conio/ciolib.c +++ b/src/conio/ciolib.c @@ -266,7 +266,8 @@ static int try_curses_init(int mode) mode=CIOLIB_MODE_CURSES; cio_api.mode=mode; cio_api.puttext=curs_puttext; - cio_api.gettext=curs_gettext; + cio_api.vmem_puttext=curs_vmem_puttext; + cio_api.vmem_gettext=curs_vmem_gettext; cio_api.textattr=curs_textattr; cio_api.kbhit=curs_kbhit; cio_api.gotoxy=curs_gotoxy; @@ -283,6 +284,11 @@ static int try_curses_init(int mode) #if defined(NCURSES_VERSION_MAJOR) || defined (__NetBSD__) cio_api.ESCDELAY=&ESCDELAY; #endif + cio_api.setfont = curs_setfont; + cio_api.getfont = curs_getfont; + cio_api.setpalette = curs_setpalette; + cio_api.get_modepalette = curs_get_modepalette; + cio_api.set_modepalette = curs_set_modepalette; return(1); } return(0); diff --git a/src/conio/curs_cio.c b/src/conio/curs_cio.c index a5de0afee1df0b2c959a1c68a4e04c6597e4b9cf..89d11a2a88ce056b6670448c5b1a28c89538d99d 100644 --- a/src/conio/curs_cio.c +++ b/src/conio/curs_cio.c @@ -62,6 +62,9 @@ static int suspended = 0; static int mpress = 0; void curs_resume(void); +static int default_font=0; +static int current_font[4]={0, 0, 0, 0}; + static short curses_color(short color) { switch(color) @@ -102,11 +105,11 @@ static short curses_color(short color) return(0); } -static int _putch(unsigned char ch, BOOL refresh_now) +static int _putch(unsigned char ch, BOOL refresh_now, int cp) { int ret; cchar_t cha; - wchar_t wch[2] = {}; + wchar_t wch[2] = {0}; attr_t attr = 0; short cpair; @@ -312,7 +315,7 @@ static int _putch(unsigned char ch, BOOL refresh_now) wch[0]=ch; break; case CIOLIB_MODE_CURSES: - wch[0] = cpoint_from_cpchar_ext(getcodepage(), ch); + wch[0] = cpoint_from_cpchar_ext(cp, ch); break; } @@ -340,6 +343,50 @@ static int _putch(unsigned char ch, BOOL refresh_now) return(ret); } +int curs_vmem_puttext(int sx, int sy, int ex, int ey, struct vmem_cell *fill) +{ + int x,y; + int fillpos=0; + unsigned char attr; + unsigned char fill_char; + unsigned char orig_attr; + int oldx, oldy; + + if( sx < 1 + || sy < 1 + || ex < 1 + || ey < 1 + || sx > cio_textinfo.screenwidth + || sy > cio_textinfo.screenheight + || sx > ex + || sy > ey + || ex > cio_textinfo.screenwidth + || ey > cio_textinfo.screenheight + || fill==NULL) + return(0); + + curs_resume(); + getyx(stdscr,oldy,oldx); + orig_attr=lastattr; + for(y=sy-1;y<ey;y++) + { + for(x=sx-1;x<ex;x++) + { + fill_char=fill[fillpos].ch; + attr=fill[fillpos].legacy_attr; + textattr(attr); + move(y, x); + _putch(fill_char,FALSE,conio_fontdata[fill[fillpos].font].cp); + fillpos++; + } + } + textattr(orig_attr); + move(oldy, oldx); + if(!hold_update) + refresh(); + return(1); +} + int curs_puttext(int sx, int sy, int ex, int ey, void *fillbuf) { int x,y; @@ -350,7 +397,7 @@ int curs_puttext(int sx, int sy, int ex, int ey, void *fillbuf) int oldx, oldy; unsigned char *fill; - fill=fillbuf; + fill = fillbuf; if( sx < 1 || sy < 1 @@ -376,7 +423,7 @@ int curs_puttext(int sx, int sy, int ex, int ey, void *fillbuf) attr=fill[fillpos++]; textattr(attr); move(y, x); - _putch(fill_char,FALSE); + _putch(fill_char,FALSE,getcodepage()); } } textattr(orig_attr); @@ -386,7 +433,7 @@ int curs_puttext(int sx, int sy, int ex, int ey, void *fillbuf) return(1); } -int curs_gettext(int sx, int sy, int ex, int ey, void *fillbuf) +int curs_vmem_gettext(int sx, int sy, int ex, int ey, struct vmem_cell *fill) { int x,y; int fillpos=0; @@ -396,11 +443,12 @@ int curs_gettext(int sx, int sy, int ex, int ey, void *fillbuf) unsigned char thischar; int ext_char; struct text_info ti; - unsigned char *fill; attr_t attr; cchar_t cchar; + int fnt = current_font[0]; + int cp; + fd_set cp_checked; - fill=fillbuf; curs_resume(); gettextinfo(&ti); @@ -616,6 +664,7 @@ int curs_gettext(int sx, int sy, int ex, int ey, void *fillbuf) thischar=216; } } + fnt = 0; break; case CIOLIB_MODE_CURSES_IBM: if (ext_char == (ACS_UARROW & A_CHARTEXT)) @@ -626,13 +675,30 @@ int curs_gettext(int sx, int sy, int ex, int ey, void *fillbuf) { thischar=31; } + fnt = 0; break; case CIOLIB_MODE_CURSES: - thischar = cpchar_from_unicode_cpoint(CIOLIB_CP437, ext_char, '?'); + thischar = cpchar_from_unicode_cpoint(getcodepage(), ext_char, 0); + if (thischar == 0 && ext_char != 0) { + FD_ZERO(&cp_checked); + for (fnt = 0; fnt < 256; fnt++) { + cp = conio_fontdata[fnt].cp; + if (!FD_ISSET(cp, &cp_checked)) { + FD_SET(cp, &cp_checked); + thischar = cpchar_from_unicode_cpoint(cp, ext_char, 0); + if (thischar) + break; + } + } + if (fnt == 256) { + fnt = current_font[0]; + thischar = '?'; + } + } break; } } - fill[fillpos++]=(unsigned char)(thischar); + fill[fillpos].ch=(unsigned char)(thischar); attrib=0; if (attr & WA_BOLD) { if (thischar == ' ') @@ -649,7 +715,10 @@ int curs_gettext(int sx, int sy, int ex, int ey, void *fillbuf) colour=colour&0x7f; else colour=((colour&56)<<1)|(colour&7); - fill[fillpos++]=colour|attrib; + fill[fillpos].legacy_attr = colour|attrib; + attr2palette(attrib, &fill[fillpos].fg, &fill[fillpos].bg); + fill[fillpos].font = fnt; + fillpos++; } } move(oldy, oldx); @@ -836,6 +905,8 @@ int curs_initciolib(long inmode) if (COLORS >= 16) cio_api.options = CONIO_OPT_BRIGHT_BACKGROUND; + if (can_change_color()) + cio_api.options |= CONIO_OPT_PALETTE_SETTING; curs_textmode(0); return(1); } @@ -1078,16 +1149,80 @@ int curs_getch(void) #endif default: - // TODO: May not be right for wide... - ch = cpchar_from_unicode_cpoint(getcodepage(), ch, 0); + // Don't translate CTRL-x "keys"... + if (ch >= 32) + ch = cpchar_from_unicode_cpoint(getcodepage(), ch, 0); break; } } return(ch); } +static int +scale_integer_up(int from) +{ + int ret = from * 1000 / 256; + + if (ret < 0) + ret = 0; + if (ret > 1000) + ret = 1000; + return ret; +} + +static int +scale_integer_down(int from) +{ + int ret = from * 256 / 1000; + + if (ret < 0) + ret = 0; + if (ret > 255) + ret = 255; + return ret; +} + +int curs_setpalette(uint32_t entry, uint16_t r, uint16_t g, uint16_t b) +{ + if (!can_change_color()) + return 0; + init_color(entry, scale_integer_up(r>>8), scale_integer_up(g>>8), scale_integer_up(b>>8)); + return 1; +} + +int curs_set_modepalette(uint32_t p[16]) +{ + int i; + + if (!can_change_color()) + return 0; + for (i = 0; i < 16; i++) { + init_color(i, scale_integer_up((p[i] >> 16) & 0xff), scale_integer_up((p[i] >> 8) & 0xff), scale_integer_up((p[i]) & 0xff)); + } + return 1; +} + +int curs_get_modepalette(uint32_t p[16]) +{ + int i; + short r, g, b; + + if (!can_change_color()) + return 0; + for (i = 0; i < 16; i++) { + color_content(i, &r, &g, &b); + r = scale_integer_down(r); + g = scale_integer_down(g); + b = scale_integer_down(b); + p[i] = (r<<16) | (g<<8) | b; + } + return 1; +} + void curs_textmode(int mode) { + int vm; + curs_resume(); getmaxyx(stdscr, cio_textinfo.screenheight, cio_textinfo.screenwidth); if(has_colors()) @@ -1104,6 +1239,10 @@ void curs_textmode(int mode) cio_textinfo.curx=1; cio_textinfo.cury=1; + if(can_change_color() && (vm = find_vmode(mode)) != -1) { + curs_set_modepalette(palettes[vparams[vm].palette]); + } + return; } @@ -1150,3 +1289,42 @@ void curs_setvideoflags(int flags) flags &= ~CIOLIB_VIDEO_BGBRIGHT; vflags = flags; } + +int curs_setfont(int font, int force, int font_num) +{ + if (mode != CIOLIB_MODE_CURSES) + return 0; + + if(font < 0 || font>(sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)-2)) + return(0); + + switch(font_num) { + case 0: + default_font=font; + /* Fall-through */ + case 1: + current_font[0]=font; + break; + case 2: + case 3: + case 4: + current_font[font_num-1]=font; + break; + } + + return(1); +} + +int curs_getfont(int font_num) +{ + int ret; + + if (font_num == 0) + ret = default_font; + else if (font_num > 4) + ret = -1; + else + ret = current_font[font_num - 1]; + + return ret; +} diff --git a/src/conio/curs_cio.h b/src/conio/curs_cio.h index ae519145fda5f2390e3958a152b7e6f15b179266..994a7150f2b7efa77e88dadd12206688afe3eea8 100644 --- a/src/conio/curs_cio.h +++ b/src/conio/curs_cio.h @@ -50,8 +50,9 @@ #ifdef __cplusplus extern "C" { #endif -int curs_puttext(int sx, int sy, int ex, int ey, void *fill); -int curs_gettext(int sx, int sy, int ex, int ey, void *fill); +int curs_puttext(int sx, int sy, int ex, int ey, void *fillbuf); +int curs_vmem_puttext(int sx, int sy, int ex, int ey, struct vmem_cell *fillbuf); +int curs_vmem_gettext(int sx, int sy, int ex, int ey, struct vmem_cell *fillbuf); void curs_textattr(int attr); int curs_kbhit(void); void curs_gotoxy(int x, int y); @@ -66,6 +67,11 @@ int curs_showmouse(void); void curs_beep(void); int curs_getvideoflags(void); void curs_setvideoflags(int flags); +int curs_setfont(int font, int force, int font_num); +int curs_getfont(int font_num); +int curs_set_modepalette(uint32_t p[16]); +int curs_get_modepalette(uint32_t p[16]); +int curs_setpalette(uint32_t entry, uint16_t r, uint16_t g, uint16_t b); #ifdef __cplusplus } #endif