12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165 |
- /* SLang Screen management routines */
- #include "slinclud.h"
- #include <stdio.h>
- #include <string.h>
- #include "slang.h"
- #include "_slang.h"
- typedef struct
- {
- int n; /* number of chars written last time */
- int flags; /* line untouched, etc... */
- SLsmg_Char_Type *old, *neew;
- #ifndef IBMPC_SYSTEM
- unsigned long old_hash, new_hash;
- #endif
- }
- Screen_Type;
- #define TOUCHED 0x1
- #define TRASHED 0x2
- static int Screen_Trashed;
- static Screen_Type SL_Screen[SLTT_MAX_SCREEN_ROWS];
- static int Start_Col, Start_Row;
- static unsigned int Screen_Cols, Screen_Rows;
- static int This_Row, This_Col;
- static SLsmg_Color_Type This_Color;
- static int UTF8_Mode = -1;
- #if SLTT_HAS_NON_BCE_SUPPORT && !defined(IBMPC_SYSTEM)
- #define REQUIRES_NON_BCE_SUPPORT 1
- static int Bce_Color_Offset;
- #endif
- int SLsmg_Newline_Behavior = SLSMG_NEWLINE_IGNORED;
- int SLsmg_Backspace_Moves = 0;
- #if SLSMG_HAS_EMBEDDED_ESCAPE
- /* If non-zero, interpret escape sequences ESC [ x m as an embedded set color
- * sequence. The 'x' is a decimal integer that specifies the color. The sequence
- * ends at m. Examples: \e[3m --> set color 3. \e[272m --> color=272.
- * Note: These escape sequences are NOT ANSI, though similar. ANSI permits
- * sequences such as \e[32;44m to set the foreground to green/blue. This interface
- * will support such sequences, _but_ in will map such squences to the sum of
- * the colors: \e[32;44m --> color (32+44)=76.
- *
- * In addition to 'm', ']' is also supported.
- */
- static int Embedded_Escape_Mode = 0;
- int SLsmg_embedded_escape_mode (int mode)
- {
- int old_mode = Embedded_Escape_Mode;
- Embedded_Escape_Mode = mode;
- return old_mode;
- }
- /* This function gets called with u pointing at what may be '['. If it sucessfully
- * parses the escape sequence, *up and the color will be updated.
- */
- static int parse_embedded_escape (SLuchar_Type *u, SLuchar_Type *umax,
- SLsmg_Color_Type default_color,
- SLuchar_Type **up, SLsmg_Color_Type *colorp)
- {
- unsigned int val;
- SLuchar_Type ch;
- if ((u < umax) && (*u != '['))
- return -1;
- u++;
- if ((u < umax) && ((*u == 'm') || (*u == ']')))
- {
- *colorp = default_color; /* ESC[m */
- *up = u+1;
- return 0;
- }
- val = 0;
- while ((u < umax)
- && (((ch = *u) >= '0') && (ch <= '9')))
- {
- val = 10*val + (ch - '0');
- u++;
- }
- if ((u < umax) && ((*u == 'm') || (*u == ']')) && (val <= SLSMG_MAX_COLORS))
- {
- # ifdef REQUIRES_NON_BCE_SUPPORT
- val += Bce_Color_Offset;
- #endif
- *colorp = (SLsmg_Color_Type) val;
- *up = u + 1;
- return 0;
- }
- return -1;
- }
- static void parse_embedded_set_color (SLuchar_Type *u, SLuchar_Type *umax,
- SLsmg_Color_Type default_color)
- {
- SLsmg_Color_Type color = default_color;
- while (u < umax)
- {
- if (*u++ == 033)
- (void) parse_embedded_escape (u, umax, default_color, &u, &color);
- }
- if (color == default_color)
- return;
-
- #ifdef REQUIRES_NON_BCE_SUPPORT
- color -= Bce_Color_Offset;
- #endif
- SLsmg_set_color (color);
- }
- #endif
- /* Backward compatibility. Not used. */
- /* int SLsmg_Newline_Moves; */
- static int *tt_Screen_Rows = NULL;
- static int *tt_Screen_Cols = NULL;
- static int *tt_unicode_ok;
-
- static void (*tt_normal_video)(void);
- static void (*tt_goto_rc)(int, int);
- static void (*tt_cls) (void);
- static void (*tt_del_eol) (void);
- static void (*tt_smart_puts) (SLsmg_Char_Type *, SLsmg_Char_Type *, int, int);
- static int (*tt_flush_output) (void);
- static int (*tt_reset_video) (void);
- static int (*tt_init_video) (void);
- #ifndef IBMPC_SYSTEM
- static void (*tt_set_scroll_region)(int, int);
- static void (*tt_reverse_index)(int);
- static void (*tt_reset_scroll_region)(void);
- static void (*tt_delete_nlines)(int);
- #endif
- #ifndef IBMPC_SYSTEM
- static int *tt_Term_Cannot_Scroll;
- static int *tt_Has_Alt_Charset;
- static char **tt_Graphics_Char_Pairs;
- #else
- static int *tt_Has_Alt_Charset = NULL;
- static char **tt_Graphics_Char_Pairs = NULL;
- #endif
- static int Smg_Inited;
- /* This is necessary because the windoze run-time linker cannot perform
- * relocations on its own.
- */
- static void init_tt_symbols (void)
- {
- tt_Screen_Rows = &SLtt_Screen_Rows;
- tt_Screen_Cols = &SLtt_Screen_Cols;
- tt_unicode_ok = &_pSLtt_UTF8_Mode;
-
- tt_normal_video = SLtt_normal_video;
- tt_goto_rc = SLtt_goto_rc;
- tt_cls = SLtt_cls;
- tt_del_eol = SLtt_del_eol;
- tt_smart_puts = SLtt_smart_puts;
- tt_flush_output = SLtt_flush_output;
- tt_reset_video = SLtt_reset_video;
- tt_init_video = SLtt_init_video;
- #ifndef IBMPC_SYSTEM
- tt_set_scroll_region = SLtt_set_scroll_region;
- tt_reverse_index = SLtt_reverse_index;
- tt_reset_scroll_region = SLtt_reset_scroll_region;
- tt_delete_nlines = SLtt_delete_nlines;
- #endif
- #ifndef IBMPC_SYSTEM
- tt_Term_Cannot_Scroll = &SLtt_Term_Cannot_Scroll;
- tt_Has_Alt_Charset = &SLtt_Has_Alt_Charset;
- tt_Graphics_Char_Pairs = &SLtt_Graphics_Char_Pairs;
- #else
- tt_Has_Alt_Charset = NULL;
- tt_Graphics_Char_Pairs = NULL;
- #endif
- }
- /* Unicode box drawing characters */
- /* This lookup table is indexed by the vt100 characters */
- static SLwchar_Type ACS_Map[128];
- typedef struct
- {
- unsigned char vt100_char;
- unsigned char ascii;
- SLwchar_Type unicode;
- }
- ACS_Def_Type;
- static SLCONST ACS_Def_Type UTF8_ACS_Map[] =
- {
- {'+', '>', 0x2192 }, /* RIGHTWARDS ARROW */
- {',', '<', 0x2190 }, /* LEFTWARDS ARROW */
- {'-', '^', 0x2191 }, /* UPWARDS ARROW */
- {'.', 'v', 0x2193 }, /* DOWNWARDS ARROW */
- {'0', '#', 0x25AE }, /* BLACK VERTICAL RECTANGLE */
- {'`', '+', 0x25C6 }, /* BLACK DIAMOND */
- {'a', ':', 0x2592 }, /* MEDIUM SHADE */
- {'f', '\'', 0x00B0 },/* DEGREE SIGN */
- {'g', '#', 0x00B1 }, /* PLUS-MINUS SIGN */
- {'h', '#', 0x2592 }, /* MEDIUM SHADE */
- {'i', '#', 0x2603 }, /* SNOWMAN */
- {'j', '+', 0x2518 }, /* BOX DRAWINGS LIGHT UP AND LEFT */
- {'k', '+', 0x2510 }, /* BOX DRAWINGS LIGHT DOWN AND LEFT */
- {'l', '+', 0x250c }, /* BOX DRAWINGS LIGHT DOWN AND RIGHT */
- {'m', '+', 0x2514 }, /* BOX DRAWINGS LIGHT UP AND RIGHT */
- {'n', '+', 0x253C }, /* BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
- {'o', '~', 0x23BA }, /* HORIZONTAL SCAN LINE-1 */
- {'p', '-', 0x23BB }, /* HORIZONTAL SCAN LINE-3 (ncurses addition) */
- {'q', '-', 0x2500 }, /* BOX DRAWINGS LIGHT HORIZONTAL */
- {'r', '-', 0x23BC }, /* HORIZONTAL SCAN LINE-7 (ncurses addition) */
- {'s', '_', 0x23BD }, /* HORIZONTAL SCAN LINE-9 */
- {'t', '+', 0x251C }, /* BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
- {'u', '+', 0x2524 }, /* BOX DRAWINGS LIGHT VERTICAL AND LEFT */
- {'v', '+', 0x2534 }, /* BOX DRAWINGS LIGHT UP AND HORIZONTAL */
- {'w', '+', 0x252C }, /* BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
- {'x', '|', 0x2502 }, /* BOX DRAWINGS LIGHT VERTICAL */
- {'y', '<', 0x2264 }, /* LESS-THAN OR EQUAL TO (ncurses addition) */
- {'z', '>', 0x2265 }, /* GREATER-THAN OR EQUAL TO (ncurses addition) */
- {'{', '*', 0x03C0 }, /* GREEK SMALL LETTER PI (ncurses addition) */
- {'|', '!', 0x2260 }, /* NOT EQUAL TO (ncurses addition) */
- {'}', 'f', 0x00A3 }, /* POUND SIGN (ncurses addition) */
- {'~', 'o', 0x00B7 }, /* MIDDLE DOT */
- {0, 0, 0}
- };
- #define ACS_MODE_NONE -1
- #define ACS_MODE_AUTO 0
- #define ACS_MODE_UNICODE 1
- #define ACS_MODE_TERMINFO 2
- #define ACS_MODE_ASCII 3
- static int Current_ACS_Mode = ACS_MODE_NONE;
- static void init_acs (int mode)
- {
- unsigned int i;
- SLCONST ACS_Def_Type *acs;
- if (Current_ACS_Mode == mode)
- return;
- for (i = 0; i < 0x80; i++)
- ACS_Map[i] = ' ';
- if (mode == ACS_MODE_AUTO)
- {
- if (UTF8_Mode &&
- (tt_unicode_ok != NULL) && (*tt_unicode_ok > 0))
- mode = ACS_MODE_UNICODE;
- else
- mode = ACS_MODE_TERMINFO;
- }
- switch (mode)
- {
- case ACS_MODE_UNICODE:
- SLsmg_Display_Eight_Bit = 0xA0;
- acs = UTF8_ACS_Map;
- while (acs->vt100_char != 0)
- {
- ACS_Map[acs->vt100_char] = acs->unicode;
- acs++;
- }
- break;
-
- case ACS_MODE_TERMINFO:
- if ((tt_Has_Alt_Charset != NULL)
- && *tt_Has_Alt_Charset
- && (tt_Graphics_Char_Pairs != NULL)
- && (*tt_Graphics_Char_Pairs != NULL))
- {
- unsigned char *p = (unsigned char *) *tt_Graphics_Char_Pairs;
- unsigned char *pmax = p + strlen ((char *) p);
-
- while (p < pmax)
- {
- unsigned char ch = *p++;
- ACS_Map[ch & 0x7F] = *p++;
- }
- break;
- }
- mode = ACS_MODE_ASCII;
- /* drop */
- case ACS_MODE_ASCII:
- default:
- acs = UTF8_ACS_Map;
- while (acs->vt100_char != 0)
- {
- ACS_Map[acs->vt100_char] = acs->ascii;
- acs++;
- }
- break;
- }
- Current_ACS_Mode = mode;
- }
- static void blank_line (SLsmg_Char_Type *c, unsigned int n, SLwchar_Type wch)
- {
- SLsmg_Char_Type *cmax = c + n;
- SLsmg_Color_Type color = This_Color;
- memset ((char *)c, 0, n*sizeof(SLsmg_Char_Type));
- while (c < cmax)
- {
- c->nchars = 1;
- c->wchars[0] = wch;
- c->color = color;
- c++;
- }
- }
- static void clear_region (int row, int n, SLwchar_Type ch)
- {
- int i;
- int imax = row + n;
- if (imax > (int) Screen_Rows) imax = (int) Screen_Rows;
- if (row < 0)
- row = 0;
- for (i = row; i < imax; i++)
- {
- blank_line (SL_Screen[i].neew, Screen_Cols, ch);
- SL_Screen[i].flags |= TOUCHED;
- }
- }
- void SLsmg_erase_eol (void)
- {
- int r, c;
- if (Smg_Inited == 0) return;
- c = This_Col - Start_Col;
- r = This_Row - Start_Row;
- if ((r < 0) || (r >= (int)Screen_Rows)) return;
- if (c < 0) c = 0; else if (c >= (int)Screen_Cols) return;
- blank_line (SL_Screen[This_Row].neew + c , Screen_Cols - c, 0x20);
- SL_Screen[This_Row].flags |= TOUCHED;
- }
- static void scroll_up (void)
- {
- unsigned int i, imax;
- SLsmg_Char_Type *neew;
- neew = SL_Screen[0].neew;
- imax = Screen_Rows - 1;
- for (i = 0; i < imax; i++)
- {
- SL_Screen[i].neew = SL_Screen[i + 1].neew;
- SL_Screen[i].flags |= TOUCHED;
- }
- SL_Screen[i].neew = neew;
- SL_Screen[i].flags |= TOUCHED;
- blank_line (neew, Screen_Cols, 0x20);
- This_Row--;
- }
- void SLsmg_gotorc (int r, int c)
- {
- This_Row = r;
- This_Col = c;
- }
- int SLsmg_get_row (void)
- {
- return This_Row;
- }
- int SLsmg_get_column (void)
- {
- return This_Col;
- }
- void SLsmg_erase_eos (void)
- {
- if (Smg_Inited == 0) return;
- SLsmg_erase_eol ();
- clear_region (This_Row + 1, (int)Screen_Rows, 0x20);
- }
- static int This_Alt_Char;
- void SLsmg_set_char_set (int i)
- {
- #ifdef IBMPC_SYSTEM
- (void) i;
- #else
- if (i != 0)
- This_Alt_Char = SLSMG_ACS_MASK;
- else This_Alt_Char = 0;
- This_Color &= SLSMG_COLOR_MASK;
- This_Color |= This_Alt_Char;
- #endif
- }
- void SLsmg_set_color (SLsmg_Color_Type color)
- {
- #ifdef REQUIRES_NON_BCE_SUPPORT
- color += Bce_Color_Offset;
- #endif
- This_Color = color | This_Alt_Char;
- }
- void SLsmg_reverse_video (void)
- {
- SLsmg_set_color (1);
- }
- void SLsmg_normal_video (void)
- {
- SLsmg_set_color (0);
- }
- static int point_visible (int col_too)
- {
- return ((This_Row >= Start_Row) && (This_Row < Start_Row + (int)Screen_Rows)
- && ((col_too == 0)
- || ((This_Col >= Start_Col)
- && (This_Col < Start_Col + (int)Screen_Cols))));
- }
- #define NEXT_CHAR_CELL \
- { \
- if (p < pmax) \
- { \
- if ((p->nchars != i) || (p->color != color)) flags |= TOUCHED; \
- p->nchars = i; \
- p->color = color; \
- p++; \
- } \
- i = 0; \
- col++; \
- } (void) 0
- #define ADD_TO_CHAR_CELL(wc) \
- { \
- if ((p < pmax) && (p->wchars[i] != wc)) \
- { \
- p->wchars[i] = wc; \
- flags |= TOUCHED; \
- } \
- i++; \
- } (void) 0
- #define ADD_CHAR_OR_BREAK(ch) \
- if (col >= start_col) \
- { \
- if (i != 0) NEXT_CHAR_CELL; \
- if (last_was_double_width) \
- { \
- last_was_double_width = 0; \
- NEXT_CHAR_CELL; \
- } \
- if (col >= max_col) break; \
- ADD_TO_CHAR_CELL(ch); \
- } \
- else col++
- void SLsmg_write_chars (unsigned char *u, unsigned char *umax)
- {
- SLsmg_Char_Type *p, *pmax;
- SLsmg_Color_Type color;
- int flags;
- int col, start_col, max_col;
- int newline_flag;
- int utf8_mode = UTF8_Mode;
- unsigned char display_8bit;
- int last_was_double_width = 0;
- int alt_char_set_flag;
- unsigned int i;
- #if SLSMG_HAS_EMBEDDED_ESCAPE
- SLsmg_Color_Type default_color;
- #endif
- if (Smg_Inited == 0) return;
-
- display_8bit = (unsigned char) SLsmg_Display_Eight_Bit;
- if (utf8_mode)
- display_8bit = 0xA0;
- color = This_Color;
- /* If we are using unicode characters for the line drawing characters, then
- * do not attempt to use the terminals alternate character set
- */
- alt_char_set_flag = (color & SLSMG_ACS_MASK);
- if (Current_ACS_Mode == ACS_MODE_UNICODE)
- color = color & ~SLSMG_ACS_MASK;
-
- #if SLSMG_HAS_EMBEDDED_ESCAPE
- default_color = color; /* used for ESC[m */
- #endif
- top: /* get here only on newline */
- newline_flag = 0;
- start_col = Start_Col;
- if (point_visible (0) == 0) return;
- col = This_Col;
- max_col = start_col + Screen_Cols;
- p = SL_Screen[This_Row - Start_Row].neew;
- pmax = p + Screen_Cols;
- if (col >= start_col)
- {
- p += (col - start_col);
- if ((p < pmax) && (p->nchars == 0))
- {
- /* It looks like we are about to overwrite the right side of a
- * double width character.
- */
- if (col > start_col)
- {
- p--;
- p->nchars = 1;
- p->wchars[0] = ' ';
- p++;
- }
- }
- }
-
-
- flags = SL_Screen[This_Row - Start_Row].flags;
- i = 0;
-
- while (u < umax)
- {
- SLwchar_Type wc;
- unsigned int width, nconsumed;
- if (*u < (SLuchar_Type) 0x80) /* ASCII */
- {
- unsigned char ch;
- ch = (unsigned char) *u++;
- if (alt_char_set_flag)
- {
- wc = ACS_Map[ch];
- ADD_CHAR_OR_BREAK(wc);
- continue;
- }
- if ((ch >= (SLuchar_Type)0x20) && (ch < (SLuchar_Type)0x7F))
- {
- ADD_CHAR_OR_BREAK(ch);
- continue;
- }
-
- if ((ch == '\t') && (SLsmg_Tab_Width > 0))
- {
- do
- {
- if (col < start_col)
- col++;
- else
- {
- ADD_CHAR_OR_BREAK(' ');
- NEXT_CHAR_CELL;
- }
- }
- while (col % SLsmg_Tab_Width);
- continue;
- }
-
- if ((ch == '\n')
- && (SLsmg_Newline_Behavior != SLSMG_NEWLINE_PRINTABLE))
- {
- newline_flag = 1;
- break;
- }
-
- if ((ch == 0x8) && SLsmg_Backspace_Moves)
- {
- if (col != 0)
- {
- if (i != 0)
- {
- NEXT_CHAR_CELL;
- col--;
- p--;
- }
- col--;
- p--;
- }
- continue;
- }
- #if SLSMG_HAS_EMBEDDED_ESCAPE
- if ((ch == 033) && Embedded_Escape_Mode)
- {
- SLsmg_Color_Type next_color;
- if (0 == parse_embedded_escape (u, umax, default_color, &u, &next_color))
- {
- if (i != 0)
- NEXT_CHAR_CELL;
- color = next_color;
- continue;
- }
- }
- #endif
- ADD_CHAR_OR_BREAK('^');
- if (ch == 127) ch = '?'; else ch = ch + '@';
- ADD_CHAR_OR_BREAK (ch);
- continue;
- }
- nconsumed = 1;
- if ((utf8_mode == 0)
- || (NULL == SLutf8_decode (u, umax, &wc, &nconsumed)))
- {
- unsigned int ii, jj;
- unsigned char hexbuf[8];
-
- if ((utf8_mode == 0)
- && display_8bit && (*u >= display_8bit))
- {
- ADD_CHAR_OR_BREAK(*u);
- }
- else for (ii = 0; ii < nconsumed; ii++)
- {
- sprintf ((char *)hexbuf, "<%02X>", u[ii]);
- for (jj = 0; jj < 4; jj++)
- {
- ADD_CHAR_OR_BREAK (hexbuf[jj]);
- }
- }
- u += nconsumed;
- continue;
- }
- u += nconsumed;
- if (wc < (SLwchar_Type)display_8bit)
- {
- unsigned char hexbuf[8];
- unsigned int jj;
- sprintf ((char *)hexbuf, "<%02X>", (unsigned char) wc);
- for (jj = 0; jj < 4; jj++)
- {
- ADD_CHAR_OR_BREAK (hexbuf[jj]);
- }
- continue;
- }
- width = SLwchar_wcwidth (wc);
- if (width == 0)
- {
- /* Combining character--- must follow non-zero width char */
- if (i == 0)
- continue;
- if (i < SLSMG_MAX_CHARS_PER_CELL)
- {
- ADD_TO_CHAR_CELL (wc);
- }
- continue;
- }
- if (width == 2)
- {
- if (col + 2 <= start_col)
- {
- col += 2;
- continue;
- }
- if (col + 2 > max_col)
- {
- ADD_CHAR_OR_BREAK('>');
- break;
- }
-
- if (col == start_col - 1)
- {
- /* double width character is clipped at left part of screen.
- * So, display right edge as a space */
- col++;
- ADD_CHAR_OR_BREAK('<');
- continue;
- }
- ADD_CHAR_OR_BREAK(wc);
- last_was_double_width = 1;
- continue;
- }
- ADD_CHAR_OR_BREAK(wc);
- }
-
- if (i != 0)
- {
- NEXT_CHAR_CELL;
- }
- if (last_was_double_width)
- {
- if (col < max_col)
- NEXT_CHAR_CELL;
- last_was_double_width = 0;
- }
- else if ((col < max_col) && (p->nchars == 0))
- {
- /* The left side of a double with character was overwritten */
- p->nchars = 1;
- p->wchars[0] = ' ';
- }
- SL_Screen[This_Row - Start_Row].flags = flags;
- This_Col = col;
- /* Why would u be NULL here?? */
- if (SLsmg_Newline_Behavior == SLSMG_NEWLINE_IGNORED)
- {
- #if SLSMG_HAS_EMBEDDED_ESCAPE
- if (Embedded_Escape_Mode && (u != NULL))
- parse_embedded_set_color (u, umax, default_color);
- #endif
- return;
- }
- if (newline_flag == 0)
- {
- #if SLSMG_HAS_EMBEDDED_ESCAPE
- SLuchar_Type *usave = u;
- #endif
- if (u == NULL)
- return;
- while (u < umax)
- {
- if (*u == '\n') break;
- u++;
- }
- if (u >= umax)
- {
- #if SLSMG_HAS_EMBEDDED_ESCAPE
- if (Embedded_Escape_Mode)
- parse_embedded_set_color (usave, umax, default_color);
- #endif
- return;
- }
- u++;
- }
- This_Row++;
- This_Col = 0;
- if (This_Row == Start_Row + (int)Screen_Rows)
- {
- if (SLsmg_Newline_Behavior == SLSMG_NEWLINE_SCROLLS) scroll_up ();
- }
- goto top;
- }
- void SLsmg_write_nchars (char *str, unsigned int len)
- {
- SLsmg_write_chars ((unsigned char *) str, (unsigned char *)str + len);
- }
- void SLsmg_write_string (char *str)
- {
- SLsmg_write_chars ((unsigned char *)str,
- (unsigned char *)str + strlen (str));
- }
- void SLsmg_write_nstring (char *str, unsigned int n)
- {
- unsigned int width;
- unsigned char *blank = (unsigned char *)" ";
- unsigned char *u = (unsigned char *)str;
- /* Avoid a problem if a user accidently passes a negative value */
- if ((int) n < 0)
- return;
- if (u == NULL) width = 0;
- else
- {
- unsigned char *umax;
-
- width = strlen ((char *)u);
- if (UTF8_Mode)
- umax = SLutf8_skip_chars (u, u+width, n, &width, 0);
- else
- {
- if (width > n) width = n;
- umax = u + width;
- }
- SLsmg_write_chars (u, umax);
- }
- while (width++ < n) SLsmg_write_chars (blank, blank+1);
- }
- void SLsmg_write_wrapped_string (SLuchar_Type *u, int r, int c,
- unsigned int dr, unsigned int dc,
- int fill)
- {
- int maxc = (int) dc;
- unsigned char *p, *pmax;
- int utf8_mode = UTF8_Mode;
- if ((dr == 0) || (dc == 0)) return;
- p = u;
- pmax = u + strlen ((char *)u);
-
- dc = 0;
- while (1)
- {
- unsigned char ch = *p;
- if ((ch == 0) || (ch == '\n'))
- {
- int diff;
- diff = maxc - (int) dc;
- SLsmg_gotorc (r, c);
- SLsmg_write_chars (u, p);
- if (fill && (diff > 0))
- {
- unsigned char *blank = (unsigned char *)" ";
- while (diff--) SLsmg_write_chars (blank, blank+1);
- }
- if ((ch == 0) || (dr == 1)) break;
- r++;
- dc = 0;
- dr--;
- p++;
- u = p;
- continue;
- }
- if ((int) dc == maxc)
- {
- SLsmg_gotorc (r, c);
- SLsmg_write_chars (u, p);
- if (dr == 1) break;
- r++;
- dc = 0;
- dr--;
- u = p;
- continue;
- }
- dc++;
- if (utf8_mode)
- p = SLutf8_skip_chars (p, pmax, 1, NULL, 0);
- else
- p++;
- }
- }
- int SLsmg_Tab_Width = 8;
- /* Minimum value for which eight bit char is displayed as is. */
- #ifndef IBMPC_SYSTEM
- int SLsmg_Display_Eight_Bit = 160;
- #else
- int SLsmg_Display_Eight_Bit = 128;
- #endif
- void SLsmg_write_char (SLwchar_Type ch)
- {
- unsigned char u[SLUTF8_MAX_MBLEN];
- unsigned char *umax;
- if ((ch < 0x80) || (UTF8_Mode == 0))
- {
- u[0] = (unsigned char) ch;
- SLsmg_write_chars (u, u+1);
- return;
- }
- if (NULL == (umax = SLutf8_encode (ch, u, SLUTF8_MAX_MBLEN)))
- return;
- SLsmg_write_chars (u, umax);
- }
- static int Cls_Flag;
- void SLsmg_cls (void)
- {
- int tac;
- if (Smg_Inited == 0) return;
- tac = This_Alt_Char; This_Alt_Char = 0;
- SLsmg_set_color (0);
- clear_region (0, (int)Screen_Rows, 0x20);
- This_Alt_Char = tac;
- SLsmg_set_color (0);
- Cls_Flag = 1;
- }
- #if 0
- static void do_copy (SLsmg_Char_Type *a, SLsmg_Char_Type *b)
- {
- SLsmg_Char_Type *amax = a + Screen_Cols;
- while (a < amax) *a++ = *b++;
- }
- #endif
- #ifndef IBMPC_SYSTEM
- int SLsmg_Scroll_Hash_Border = 0;
- static unsigned long compute_hash (SLsmg_Char_Type *c, unsigned int n)
- {
- SLsmg_Char_Type *csave, *cmax;
- int is_blank = 2;
- c += SLsmg_Scroll_Hash_Border;
- csave = c;
- cmax = c + (n - SLsmg_Scroll_Hash_Border);
- while ((c < cmax) && is_blank)
- {
- if ((c->wchars[0] != 32) || (c->nchars != 1))
- is_blank--;
- c++;
- }
- if (is_blank) return 0;
- return _pSLstring_hash ((unsigned char *)csave, (unsigned char *)cmax);
- }
- static unsigned long Blank_Hash;
- static int try_scroll_down (int rmin, int rmax)
- {
- int i, r1, r2, di, j;
- unsigned long hash;
- int did_scroll;
- SLsmg_Color_Type color;
- SLsmg_Char_Type *tmp;
- int ignore;
- did_scroll = 0;
- for (i = rmax; i > rmin; i--)
- {
- hash = SL_Screen[i].new_hash;
- if (hash == Blank_Hash) continue;
- if ((hash == SL_Screen[i].old_hash)
- #if 0
- || ((i + 1 < Screen_Rows) && (hash == SL_Screen[i + 1].old_hash))
- || ((i - 1 > rmin) && (SL_Screen[i].old_hash == SL_Screen[i - 1].new_hash))
- #endif
- )
- continue;
- for (j = i - 1; j >= rmin; j--)
- {
- if (hash == SL_Screen[j].old_hash) break;
- }
- if (j < rmin) continue;
- r2 = i; /* end scroll region */
- di = i - j;
- j--;
- ignore = 0;
- while ((j >= rmin) && (SL_Screen[j].old_hash == SL_Screen[j + di].new_hash))
- {
- if (SL_Screen[j].old_hash == Blank_Hash) ignore++;
- j--;
- }
- r1 = j + 1;
- /* If this scroll only scrolls this line into place, don't do it.
- */
- if ((di > 1) && (r1 + di + ignore == r2)) continue;
- /* If there is anything in the scrolling region that is ok, abort the
- * scroll.
- */
- for (j = r1; j <= r2; j++)
- {
- if ((SL_Screen[j].old_hash != Blank_Hash)
- && (SL_Screen[j].old_hash == SL_Screen[j].new_hash))
- {
- /* See if the scroll is happens to scroll this one into place. */
- if ((j + di > r2) || (SL_Screen[j].old_hash != SL_Screen[j + di].new_hash))
- break;
- }
- }
- if (j <= r2) continue;
- color = This_Color; This_Color = 0;
- did_scroll = 1;
- (*tt_normal_video) ();
- (*tt_set_scroll_region) (r1, r2);
- (*tt_goto_rc) (0, 0);
- (*tt_reverse_index) (di);
- (*tt_reset_scroll_region) ();
- /* Now we have a hole in the screen.
- * Make the virtual screen look like it.
- *
- * Note that if the terminal does not support BCE, then we have
- * no idea what color the hole is. So, for this case, we do not
- * want to add Bce_Color_Offset to This_Color since if Bce_Color_Offset
- * is non-zero, then This_Color = 0 does not match any valid color
- * obtained by adding Bce_Color_Offset.
- */
- for (j = r1; j <= r2; j++) SL_Screen[j].flags = TOUCHED;
- while (di--)
- {
- tmp = SL_Screen[r2].old;
- for (j = r2; j > r1; j--)
- {
- SL_Screen[j].old = SL_Screen[j - 1].old;
- SL_Screen[j].old_hash = SL_Screen[j - 1].old_hash;
- }
- SL_Screen[r1].old = tmp;
- blank_line (SL_Screen[r1].old, Screen_Cols, 0x20);
- SL_Screen[r1].old_hash = Blank_Hash;
- r1++;
- }
- This_Color = color;
- }
- return did_scroll;
- }
- static int try_scroll_up (int rmin, int rmax)
- {
- int i, r1, r2, di, j;
- unsigned long hash;
- int did_scroll;
- SLsmg_Color_Type color;
- SLsmg_Char_Type *tmp;
- int ignore;
- did_scroll = 0;
- for (i = rmin; i < rmax; i++)
- {
- hash = SL_Screen[i].new_hash;
- if (hash == Blank_Hash) continue;
- if (hash == SL_Screen[i].old_hash)
- continue;
- /* find a match further down screen */
- for (j = i + 1; j <= rmax; j++)
- {
- if (hash == SL_Screen[j].old_hash) break;
- }
- if (j > rmax) continue;
- r1 = i; /* beg scroll region */
- di = j - i; /* number of lines to scroll */
- j++; /* since we know this is a match */
- /* find end of scroll region */
- ignore = 0;
- while ((j <= rmax) && (SL_Screen[j].old_hash == SL_Screen[j - di].new_hash))
- {
- if (SL_Screen[j].old_hash == Blank_Hash) ignore++;
- j++;
- }
- r2 = j - 1; /* end of scroll region */
- /* If this scroll only scrolls this line into place, don't do it.
- */
- if ((di > 1) && (r1 + di + ignore == r2)) continue;
- /* If there is anything in the scrolling region that is ok, abort the
- * scroll.
- */
- for (j = r1; j <= r2; j++)
- {
- if ((SL_Screen[j].old_hash != Blank_Hash)
- && (SL_Screen[j].old_hash == SL_Screen[j].new_hash))
- {
- if ((j - di < r1) || (SL_Screen[j].old_hash != SL_Screen[j - di].new_hash))
- break;
- }
- }
- if (j <= r2) continue;
- did_scroll = 1;
- /* See the above comments about BCE */
- color = This_Color; This_Color = 0;
- (*tt_normal_video) ();
- (*tt_set_scroll_region) (r1, r2);
- (*tt_goto_rc) (0, 0); /* relative to scroll region */
- (*tt_delete_nlines) (di);
- (*tt_reset_scroll_region) ();
- /* Now we have a hole in the screen. Make the virtual screen look
- * like it.
- */
- for (j = r1; j <= r2; j++) SL_Screen[j].flags = TOUCHED;
- while (di--)
- {
- tmp = SL_Screen[r1].old;
- for (j = r1; j < r2; j++)
- {
- SL_Screen[j].old = SL_Screen[j + 1].old;
- SL_Screen[j].old_hash = SL_Screen[j + 1].old_hash;
- }
- SL_Screen[r2].old = tmp;
- blank_line (SL_Screen[r2].old, Screen_Cols, ' ');
- SL_Screen[r2].old_hash = Blank_Hash;
- r2--;
- }
- This_Color = color;
- }
- return did_scroll;
- }
- static void try_scroll (void)
- {
- int r1, rmin, rmax;
- int num_up, num_down;
- /* find region limits. */
- for (rmax = Screen_Rows - 1; rmax > 0; rmax--)
- {
- if (SL_Screen[rmax].new_hash != SL_Screen[rmax].old_hash)
- {
- r1 = rmax - 1;
- if ((r1 == 0)
- || (SL_Screen[r1].new_hash != SL_Screen[r1].old_hash))
- break;
- rmax = r1;
- }
- }
- for (rmin = 0; rmin < rmax; rmin++)
- {
- if (SL_Screen[rmin].new_hash != SL_Screen[rmin].old_hash)
- {
- r1 = rmin + 1;
- if ((r1 == rmax)
- || (SL_Screen[r1].new_hash != SL_Screen[r1].old_hash))
- break;
- rmin = r1;
- }
- }
- /* Below, we have two scrolling algorithms. The first has the effect of
- * scrolling lines down. This is usually appropriate when one moves
- * up the display, e.g., with the UP arrow. The second algorithm is
- * appropriate for going the other way. It is important to choose the
- * correct one.
- */
- num_up = 0;
- for (r1 = rmin; r1 < rmax; r1++)
- {
- if (SL_Screen[r1].new_hash == SL_Screen[r1 + 1].old_hash)
- num_up++;
- }
- num_down = 0;
- for (r1 = rmax; r1 > rmin; r1--)
- {
- if (SL_Screen[r1 - 1].old_hash == SL_Screen[r1].new_hash)
- num_down++;
- }
- if (num_up > num_down)
- {
- if (try_scroll_up (rmin, rmax))
- return;
- (void) try_scroll_down (rmin, rmax);
- }
- else
- {
- if (try_scroll_down (rmin, rmax))
- return;
- (void) try_scroll_up (rmin, rmax);
- }
- }
- #endif /* NOT IBMPC_SYSTEM */
- #ifdef REQUIRES_NON_BCE_SUPPORT
- static void adjust_colors (void)
- {
- int bce;
- unsigned int i;
- bce = Bce_Color_Offset;
- Bce_Color_Offset = _pSLtt_get_bce_color_offset ();
- if (bce == Bce_Color_Offset)
- return;
- for (i = 0; i < Screen_Rows; i++)
- {
- SLsmg_Char_Type *s, *smax;
- SL_Screen[i].flags |= TRASHED;
- s = SL_Screen[i].neew;
- smax = s + Screen_Cols;
- while (s < smax)
- {
- SLsmg_Color_Type color = s->color;
- int acs = color & SLSMG_ACS_MASK;
- color = (color & SLSMG_COLOR_MASK) + (Bce_Color_Offset - bce);
- if (color < SLSMG_MAX_COLORS)
- s->color = color | acs;
- s++;
- }
- }
- }
- #endif
- void SLsmg_refresh (void)
- {
- unsigned int i;
- #ifndef IBMPC_SYSTEM
- int trashed = 0;
- #endif
- int r, c;
- if (Smg_Inited == 0) return;
-
- if (Screen_Trashed)
- {
- Cls_Flag = 1;
- for (i = 0; i < Screen_Rows; i++)
- SL_Screen[i].flags |= TRASHED;
- #ifdef REQUIRES_NON_BCE_SUPPORT
- adjust_colors ();
- #endif
- }
- #ifndef IBMPC_SYSTEM
- for (i = 0; i < Screen_Rows; i++)
- {
- if (SL_Screen[i].flags == 0) continue;
- SL_Screen[i].new_hash = compute_hash (SL_Screen[i].neew, Screen_Cols);
- trashed = 1;
- }
- #endif
- if (Cls_Flag)
- {
- (*tt_normal_video) (); (*tt_cls) ();
- }
- #ifndef IBMPC_SYSTEM
- else if (trashed && (*tt_Term_Cannot_Scroll == 0)) try_scroll ();
- #endif
- for (i = 0; i < Screen_Rows; i++)
- {
- if (SL_Screen[i].flags == 0) continue;
- if (Cls_Flag || SL_Screen[i].flags & TRASHED)
- {
- SLsmg_Color_Type color = This_Color;
- if (Cls_Flag == 0)
- {
- (*tt_goto_rc) (i, 0);
- (*tt_del_eol) ();
- }
- This_Color = 0;
- blank_line (SL_Screen[i].old, Screen_Cols, 0x20);
- This_Color = color;
- }
- (*tt_smart_puts) (SL_Screen[i].neew, SL_Screen[i].old, Screen_Cols, i);
- memcpy ((char *) SL_Screen[i].old, (char *) SL_Screen[i].neew,
- Screen_Cols * sizeof (SLsmg_Char_Type));
- SL_Screen[i].flags = 0;
- #ifndef IBMPC_SYSTEM
- SL_Screen[i].old_hash = SL_Screen[i].new_hash;
- #endif
- }
- r = This_Row - Start_Row;
- c = This_Col - Start_Col;
- if (r < 0)
- {
- r = 0;
- c = 0;
- }
- else if (r >= (int)Screen_Rows)
- {
- r = (int)Screen_Rows;
- c = (int)Screen_Cols-1;
- }
- if (c < 0)
- c = 0;
- else if (c >= (int)Screen_Cols)
- c = (int)Screen_Cols-1;
- (*tt_goto_rc) (r,c);
- (void) (*tt_flush_output) ();
- Cls_Flag = 0;
- Screen_Trashed = 0;
- }
- static int compute_clip (int row, int n, int box_start, int box_end,
- int *rmin, int *rmax)
- {
- int row_max;
- if (n < 0) return 0;
- if (row >= box_end) return 0;
- row_max = row + n;
- if (row_max <= box_start) return 0;
- if (row < box_start) row = box_start;
- if (row_max >= box_end) row_max = box_end;
- *rmin = row;
- *rmax = row_max;
- return 1;
- }
- void SLsmg_touch_lines (int row, unsigned int n)
- {
- int i;
- int r1, r2;
- /* Allow this function to be called even when we are not initialied.
- * Calling this function is useful after calling SLtt_set_color
- * to force the display to be redrawn
- */
- if (Smg_Inited == 0)
- return;
- if (0 == compute_clip (row, (int) n, Start_Row, Start_Row + Screen_Rows, &r1, &r2))
- return;
- r1 -= Start_Row;
- r2 -= Start_Row;
- for (i = r1; i < r2; i++)
- {
- SL_Screen[i].flags |= TRASHED;
- }
- }
- void SLsmg_touch_screen (void)
- {
- Screen_Trashed = 1;
- }
- #ifndef IBMPC_SYSTEM
- # define BLOCK_SIGNALS SLsig_block_signals ()
- # define UNBLOCK_SIGNALS SLsig_unblock_signals ()
- #else
- # define BLOCK_SIGNALS (void)0
- # define UNBLOCK_SIGNALS (void)0
- #endif
- static int Smg_Suspended;
- int SLsmg_suspend_smg (void)
- {
- BLOCK_SIGNALS;
- if (Smg_Suspended == 0)
- {
- (*tt_reset_video) ();
- Smg_Suspended = 1;
- }
- UNBLOCK_SIGNALS;
- return 0;
- }
- int SLsmg_resume_smg (void)
- {
- BLOCK_SIGNALS;
- if (Smg_Suspended == 0)
- {
- UNBLOCK_SIGNALS;
- return 0;
- }
- Smg_Suspended = 0;
- if (-1 == (*tt_init_video) ())
- {
- UNBLOCK_SIGNALS;
- return -1;
- }
- Cls_Flag = 1;
- SLsmg_touch_screen ();
- SLsmg_refresh ();
- UNBLOCK_SIGNALS;
- return 0;
- }
-
- static void reset_smg (void)
- {
- unsigned int i;
- if (Smg_Inited == 0)
- return;
- for (i = 0; i < Screen_Rows; i++)
- {
- SLfree ((char *)SL_Screen[i].old);
- SLfree ((char *)SL_Screen[i].neew);
- SL_Screen[i].old = SL_Screen[i].neew = NULL;
- }
- This_Alt_Char = This_Color = 0;
- Smg_Inited = 0;
- }
- static int init_smg (void)
- {
- unsigned int i, len;
- SLsmg_Char_Type *old, *neew;
- Smg_Inited = 0;
- #ifdef REQUIRES_NON_BCE_SUPPORT
- Bce_Color_Offset = _pSLtt_get_bce_color_offset ();
- #endif
-
- Screen_Rows = *tt_Screen_Rows;
- if (Screen_Rows > SLTT_MAX_SCREEN_ROWS)
- Screen_Rows = SLTT_MAX_SCREEN_ROWS;
- Screen_Cols = *tt_Screen_Cols;
- This_Col = This_Row = Start_Col = Start_Row = 0;
- This_Alt_Char = 0;
- SLsmg_set_color (0);
- Cls_Flag = 1;
-
- init_acs (ACS_MODE_AUTO);
- len = Screen_Cols + 3;
- for (i = 0; i < Screen_Rows; i++)
- {
- if ((NULL == (old = (SLsmg_Char_Type *) SLmalloc (sizeof(SLsmg_Char_Type) * len)))
- || ((NULL == (neew = (SLsmg_Char_Type *) SLmalloc (sizeof(SLsmg_Char_Type) * len)))))
- {
- SLfree ((char *) old);
- return -1;
- }
- blank_line (old, len, ' ');
- blank_line (neew, len, ' ');
- SL_Screen[i].old = old;
- SL_Screen[i].neew = neew;
- SL_Screen[i].flags = 0;
- #ifndef IBMPC_SYSTEM
- Blank_Hash = compute_hash (old, Screen_Cols);
- SL_Screen[i].new_hash = SL_Screen[i].old_hash = Blank_Hash;
- #endif
- }
-
- _pSLtt_color_changed_hook = SLsmg_touch_screen;
- Screen_Trashed = 1;
- Smg_Inited = 1;
- return 0;
- }
- int SLsmg_init_smg (void)
- {
- int ret;
- BLOCK_SIGNALS;
- if (tt_Screen_Rows == NULL)
- init_tt_symbols ();
- if (Smg_Inited)
- SLsmg_reset_smg ();
- if (UTF8_Mode == -1)
- UTF8_Mode = _pSLutf8_mode;
- if (-1 == (*tt_init_video) ())
- {
- UNBLOCK_SIGNALS;
- return -1;
- }
-
- if (-1 == (ret = init_smg ()))
- (void) (*tt_reset_video)();
- UNBLOCK_SIGNALS;
- return ret;
- }
- int SLsmg_reinit_smg (void)
- {
- int ret;
- if (Smg_Inited == 0)
- return SLsmg_init_smg ();
- BLOCK_SIGNALS;
- reset_smg ();
- ret = init_smg ();
- UNBLOCK_SIGNALS;
- return ret;
- }
- void SLsmg_reset_smg (void)
- {
- if (Smg_Inited == 0)
- return;
-
- BLOCK_SIGNALS;
- reset_smg ();
- (*tt_reset_video)();
- UNBLOCK_SIGNALS;
- }
- void SLsmg_vprintf (char *fmt, va_list ap)
- {
- char buf[1024];
- if (Smg_Inited == 0) return;
- (void) SLvsnprintf (buf, sizeof (buf), fmt, ap);
- SLsmg_write_string (buf);
- }
- void SLsmg_printf (char *fmt, ...)
- {
- va_list ap;
- char *f;
- if (Smg_Inited == 0) return;
- va_start(ap, fmt);
- f = fmt;
- while (*f && (*f != '%'))
- f++;
- if (f != fmt)
- SLsmg_write_chars ((SLuchar_Type *)fmt, (SLuchar_Type *)f);
- if (*f != 0)
- SLsmg_vprintf (f, ap);
- va_end (ap);
- }
- void SLsmg_set_screen_start (int *r, int *c)
- {
- int orow = Start_Row, oc = Start_Col;
- if (Smg_Inited == 0) return;
- if (c == NULL) Start_Col = 0;
- else
- {
- Start_Col = *c;
- *c = oc;
- }
- if (r == NULL) Start_Row = 0;
- else
- {
- Start_Row = *r;
- *r = orow;
- }
- }
- void SLsmg_draw_object (int r, int c, SLwchar_Type object)
- {
- This_Row = r; This_Col = c;
- if (Smg_Inited == 0) return;
- if (point_visible (1))
- {
- int color = This_Color;
- This_Color |= SLSMG_ACS_MASK;
- SLsmg_write_char (object);
- This_Color = color;
- }
- This_Col = c + 1;
- }
- void SLsmg_draw_hline (unsigned int n)
- {
- static unsigned char hbuf[16];
- int cmin, cmax;
- int final_col = This_Col + (int) n;
- int save_color;
- if (Smg_Inited == 0) return;
- if ((This_Row < Start_Row) || (This_Row >= Start_Row + (int)Screen_Rows)
- || (0 == compute_clip (This_Col, n, Start_Col, Start_Col + (int)Screen_Cols,
- &cmin, &cmax)))
- {
- This_Col = final_col;
- return;
- }
- n = (unsigned int)(cmax - cmin);
- save_color = This_Color;
- This_Color |= SLSMG_ACS_MASK;
- This_Col = cmin;
-
- if (hbuf[0] == 0)
- {
- SLMEMSET ((char *) hbuf, SLSMG_HLINE_CHAR, 16);
- }
- while (n)
- {
- SLsmg_write_char (SLSMG_HLINE_CHAR);
- n--;
- }
- This_Color = save_color;
- This_Col = final_col;
- }
- void SLsmg_draw_vline (int n)
- {
- int c = This_Col, rmin, rmax;
- int final_row = This_Row + n;
- int save_color;
- if (Smg_Inited == 0) return;
- if (((c < Start_Col) || (c >= Start_Col + (int)Screen_Cols))
- || (0 == compute_clip (This_Row, n, Start_Row,
- Start_Row + (int)Screen_Rows,
- &rmin, &rmax)))
- {
- This_Row = final_row;
- return;
- }
- save_color = This_Color;
- This_Color |= SLSMG_ACS_MASK;
- for (This_Row = rmin; This_Row < rmax; This_Row++)
- {
- This_Col = c;
- SLsmg_write_char (SLSMG_VLINE_CHAR);
- }
- This_Col = c; This_Row = final_row;
- This_Color = save_color;
- }
- void SLsmg_draw_box (int r, int c, unsigned int dr, unsigned int dc)
- {
- if (Smg_Inited == 0) return;
- if (!dr || !dc) return;
- This_Row = r; This_Col = c;
- dr--; dc--;
- SLsmg_draw_hline (dc);
- SLsmg_draw_vline (dr);
- This_Row = r; This_Col = c;
- SLsmg_draw_vline (dr);
- SLsmg_draw_hline (dc);
- SLsmg_draw_object (r, c, SLSMG_ULCORN_CHAR);
- SLsmg_draw_object (r, c + (int) dc, SLSMG_URCORN_CHAR);
- SLsmg_draw_object (r + (int) dr, c, SLSMG_LLCORN_CHAR);
- SLsmg_draw_object (r + (int) dr, c + (int) dc, SLSMG_LRCORN_CHAR);
- This_Row = r; This_Col = c;
- }
- void SLsmg_fill_region (int r, int c, unsigned int dr, unsigned int dc, SLwchar_Type wch)
- {
- static unsigned char buf[16];
- unsigned char ubuf[16*SLUTF8_MAX_MBLEN];
- unsigned char *b, *bmax;
- int count;
- int dcmax, rmax;
- unsigned int wchlen;
- if (Smg_Inited == 0) return;
- SLsmg_gotorc (r, c);
- r = This_Row; c = This_Col;
- dcmax = Screen_Cols - This_Col;
- if (dcmax < 0)
- return;
- if (dc > (unsigned int) dcmax) dc = (unsigned int) dcmax;
- rmax = This_Row + (int)dr;
- if (rmax > (int)Screen_Rows) rmax = (int)Screen_Rows;
- if ((wch < 0x80)
- || (UTF8_Mode == 0))
- {
- if (buf[0] != (unsigned char) wch)
- memset ((char *) buf, (unsigned char) wch, sizeof(buf));
- b = buf;
- bmax = buf + sizeof (buf);
- wchlen = 1;
- }
- else
- {
- unsigned int i;
- b = ubuf;
- bmax = SLutf8_encode (wch, b, SLUTF8_MAX_MBLEN);
- if (bmax == NULL)
- {
- bmax = ubuf;
- *bmax++ = '?';
- }
- wchlen = (unsigned int) (bmax - b);
- for (i = 1; i < 16; i++)
- {
- memcpy (bmax, b, wchlen);
- bmax += wchlen;
- }
- }
- for (This_Row = r; This_Row < rmax; This_Row++)
- {
- This_Col = c;
- count = dc / 16;
- SLsmg_write_chars (b, b + wchlen * (dc % 16));
- while (count-- > 0)
- {
- SLsmg_write_chars (b, bmax);
- }
- }
- This_Row = r;
- }
- void SLsmg_forward (int n)
- {
- This_Col += n;
- }
- void
- SLsmg_set_color_in_region (int color, int r, int c, unsigned int dr, unsigned int dc)
- {
- int cmax, rmax;
- if (Smg_Inited == 0) return;
- c -= Start_Col;
- r -= Start_Row;
- cmax = c + (int) dc;
- rmax = r + (int) dr;
- if (cmax > (int)Screen_Cols) cmax = (int)Screen_Cols;
- if (rmax > (int)Screen_Rows) rmax = (int)Screen_Rows;
- if (c < 0) c = 0;
- if (r < 0) r = 0;
- #ifdef REQUIRES_NON_BCE_SUPPORT
- if (Bce_Color_Offset)
- color += Bce_Color_Offset;
- #endif
- while (r < rmax)
- {
- SLsmg_Char_Type *cell, *cell_max;
- SL_Screen[r].flags |= TOUCHED;
- cell = SL_Screen[r].neew;
- cell_max = cell + cmax;
- cell += c;
- while (cell < cell_max)
- {
- int acs = cell->color & SLSMG_ACS_MASK;
- cell->color = color | acs;
- cell++;
- }
- r++;
- }
- }
- void SLsmg_set_terminal_info (SLsmg_Term_Type *tt)
- {
- if (tt == NULL) /* use default */
- return;
- if ((tt->tt_normal_video == NULL)
- || (tt->tt_goto_rc == NULL)
- || (tt->tt_cls == NULL)
- || (tt->tt_del_eol == NULL)
- || (tt->tt_smart_puts == NULL)
- || (tt->tt_flush_output == NULL)
- || (tt->tt_reset_video == NULL)
- || (tt->tt_init_video == NULL)
- #ifndef IBMPC_SYSTEM
- || (tt->tt_set_scroll_region == NULL)
- || (tt->tt_reverse_index == NULL)
- || (tt->tt_reset_scroll_region == NULL)
- || (tt->tt_delete_nlines == NULL)
- /* Variables */
- || (tt->tt_term_cannot_scroll == NULL)
- || (tt->tt_has_alt_charset == NULL)
- #if 0 /* These can be NULL */
- || (tt->tt_use_blink_for_acs == NULL)
- || (tt->tt_graphic_char_pairs == NULL)
- #endif
- || (tt->tt_screen_cols == NULL)
- || (tt->tt_screen_rows == NULL)
- #endif
- )
- SLang_exit_error ("The Terminal not powerful enough for S-Lang's SLsmg interface");
- tt_normal_video = tt->tt_normal_video;
- tt_goto_rc = tt->tt_goto_rc;
- tt_cls = tt->tt_cls;
- tt_del_eol = tt->tt_del_eol;
- tt_smart_puts = tt->tt_smart_puts;
- tt_flush_output = tt->tt_flush_output;
- tt_reset_video = tt->tt_reset_video;
- tt_init_video = tt->tt_init_video;
- #ifndef IBMPC_SYSTEM
- tt_set_scroll_region = tt->tt_set_scroll_region;
- tt_reverse_index = tt->tt_reverse_index;
- tt_reset_scroll_region = tt->tt_reset_scroll_region;
- tt_delete_nlines = tt->tt_delete_nlines;
- tt_Term_Cannot_Scroll = tt->tt_term_cannot_scroll;
- #endif
- tt_Has_Alt_Charset = tt->tt_has_alt_charset;
- tt_Screen_Cols = tt->tt_screen_cols;
- tt_Screen_Rows = tt->tt_screen_rows;
- tt_unicode_ok = tt->unicode_ok;
- }
- /* The following routines are partially supported. */
- void SLsmg_write_color_chars (SLsmg_Char_Type *s, unsigned int len)
- {
- #if 1
- SLsmg_write_raw (s, len);
- #else
- SLsmg_Char_Type *smax, sh;
- char buf[32], *b, *bmax;
- int color, save_color;
- if (Smg_Inited == 0) return;
- smax = s + len;
- b = buf;
- bmax = b + sizeof (buf);
- save_color = This_Color;
- while (s < smax)
- {
- sh = *s++;
- color = SLSMG_EXTRACT_COLOR(sh);
- #ifdef REQUIRES_NON_BCE_SUPPORT
- if (Bce_Color_Offset)
- {
- if (color & 0x80)
- color = ((color & 0x7F) + Bce_Color_Offset) | 0x80;
- else
- color = ((color & 0x7F) + Bce_Color_Offset) & 0x7F;
- }
- #endif
- if ((color != This_Color) || (b == bmax))
- {
- if (b != buf)
- {
- SLsmg_write_nchars (buf, (int) (b - buf));
- b = buf;
- }
- This_Color = color;
- }
- *b++ = (char) SLSMG_EXTRACT_CHAR(sh);
- }
- if (b != buf)
- SLsmg_write_nchars (buf, (unsigned int) (b - buf));
- This_Color = save_color;
- #endif
- }
- unsigned int SLsmg_strwidth (SLuchar_Type *u, SLuchar_Type *umax)
- {
- unsigned char display_8bit;
- int utf8_mode = UTF8_Mode;
- int col;
- if (u == NULL)
- return 0;
- display_8bit = (unsigned char) SLsmg_Display_Eight_Bit;
- if (utf8_mode)
- display_8bit = 0xA0;
- col = This_Col;
- while (u < umax)
- {
- SLuchar_Type ch;
- unsigned int nconsumed;
- SLwchar_Type wc;
- ch = *u;
- if (ch < 0x80)
- {
- u++;
- if ((ch >= 0x20) && (ch != 0x7F))
- {
- col++;
- continue;
- }
-
- if ((ch == '\t') && (SLsmg_Tab_Width > 0))
- {
- if (col >= 0)
- col = (1 + col/SLsmg_Tab_Width) * SLsmg_Tab_Width;
- else
- col = ((col + 1)/SLsmg_Tab_Width) * SLsmg_Tab_Width;
-
- continue;
- }
- if ((ch == '\n')
- && (SLsmg_Newline_Behavior != SLSMG_NEWLINE_PRINTABLE))
- break;
-
- if ((ch == 0x8) && SLsmg_Backspace_Moves)
- {
- col--;
- continue;
- }
- #if SLSMG_HAS_EMBEDDED_ESCAPE
- if ((ch == 033) && Embedded_Escape_Mode)
- {
- SLsmg_Color_Type color;
- if (0 == parse_embedded_escape (u, umax, 0, &u, &color))
- continue;
- }
- #endif
- col += 2;
- continue;
- }
-
- nconsumed = 1;
- if ((utf8_mode == 0)
- || (NULL == SLutf8_decode (u, umax, &wc, &nconsumed)))
- {
- if ((utf8_mode == 0)
- && (display_8bit && (*u >= display_8bit)))
- col++;
- else
- col += 4*nconsumed;
- u += nconsumed;
- continue;
- }
- u += nconsumed;
- if (wc < (SLwchar_Type)display_8bit)
- {
- col += 4;
- continue;
- }
- col += SLwchar_wcwidth (wc);
- }
-
- if (col < This_Col)
- return 0;
- return (unsigned int) (col - This_Col);
- }
- /* If the string u were written at the current positition, this function
- * returns the number of bytes necessary to reach the specified width.
- */
- unsigned int SLsmg_strbytes (SLuchar_Type *u, SLuchar_Type *umax, unsigned int width)
- {
- SLuchar_Type *ustart;
- unsigned char display_8bit;
- int utf8_mode = UTF8_Mode;
- int col, col_max;
- if (u == NULL)
- return 0;
- display_8bit = (unsigned char) SLsmg_Display_Eight_Bit;
- if (utf8_mode)
- display_8bit = 0xA0;
- col = This_Col;
- col_max = col + width;
- ustart = u;
- while (u < umax)
- {
- SLuchar_Type ch;
- SLwchar_Type wc;
- unsigned int nconsumed = 1;
- ch = *u;
- if (ch < 0x80)
- {
- if ((ch >= 0x20) && (ch != 0x7F))
- col++;
- else if ((ch == '\t') && (SLsmg_Tab_Width > 0))
- {
- if (col >= 0)
- col = (1 + col/SLsmg_Tab_Width) * SLsmg_Tab_Width;
- else
- col = ((col + 1)/SLsmg_Tab_Width) * SLsmg_Tab_Width;
- }
- else if ((ch == '\n')
- && (SLsmg_Newline_Behavior != SLSMG_NEWLINE_PRINTABLE))
- break;
- else if ((ch == 0x8) && SLsmg_Backspace_Moves)
- col--;
- #if SLSMG_HAS_EMBEDDED_ESCAPE
- else if ((ch == 033) && Embedded_Escape_Mode)
- {
- SLsmg_Color_Type color;
- SLuchar_Type *u1 = u+1;
- if (-1 == parse_embedded_escape (u1, umax, 0, &u1, &color))
- col += 2;
- nconsumed = (u1 - u);
- }
- #endif
- else col += 2;
- }
- else if ((utf8_mode == 0)
- || (NULL == SLutf8_decode (u, umax, &wc, &nconsumed)))
- {
- if ((utf8_mode == 0)
- && (display_8bit && (*u >= display_8bit)))
- col++;
- else
- col += 4*nconsumed; /* <XX> */
- }
- else if (wc < (SLwchar_Type)display_8bit)
- col += 4;
- else col += SLwchar_wcwidth (wc);
-
- if (col >= col_max)
- break;
-
- u += nconsumed;
- }
- return (unsigned int) (u - ustart);
- }
- unsigned int SLsmg_read_raw (SLsmg_Char_Type *buf, unsigned int len)
- {
- unsigned int r, c;
- if (Smg_Inited == 0) return 0;
- if (0 == point_visible (1)) return 0;
- r = (unsigned int) (This_Row - Start_Row);
- c = (unsigned int) (This_Col - Start_Col);
- if (c + len > (unsigned int) Screen_Cols)
- len = (unsigned int) Screen_Cols - c;
- memcpy ((char *) buf, (char *) (SL_Screen[r].neew + c), len * sizeof (SLsmg_Char_Type));
- return len;
- }
- unsigned int SLsmg_write_raw (SLsmg_Char_Type *buf, unsigned int len)
- {
- unsigned int r, c;
- SLsmg_Char_Type *dest;
- if (Smg_Inited == 0) return 0;
- if (0 == point_visible (1)) return 0;
- r = (unsigned int) (This_Row - Start_Row);
- c = (unsigned int) (This_Col - Start_Col);
- if (c + len > (unsigned int) Screen_Cols)
- len = (unsigned int) Screen_Cols - c;
- dest = SL_Screen[r].neew + c;
- if (0 != memcmp ((char *) dest, (char *) buf, len * sizeof (SLsmg_Char_Type)))
- {
- memcpy ((char *) dest, (char *) buf, len * sizeof (SLsmg_Char_Type));
- SL_Screen[r].flags |= TOUCHED;
- }
- return len;
- }
- int SLsmg_char_at (SLsmg_Char_Type *cp)
- {
- if (Smg_Inited == 0) return -1;
- if (point_visible (1))
- {
- SLsmg_Char_Type *c = &SL_Screen[This_Row - Start_Row].neew[This_Col - Start_Col];
- if (c->nchars == 0)
- return -1;
- *cp = *c;
- return 0;
- }
- return -1;
- }
- int SLsmg_utf8_enable (int mode)
- {
- if (mode == -1)
- mode = _pSLutf8_mode;
-
- return UTF8_Mode = mode;
- }
- int SLsmg_is_utf8_mode (void)
- {
- int mode = UTF8_Mode;
- if (mode == -1)
- mode = _pSLutf8_mode;
- return mode;
- }
|