home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso
/
altsrc
/
articles
/
10825
< prev
next >
Wrap
Internet Message Format
|
1994-07-11
|
63KB
Path: wupost!psuvax1!news.pop.psu.edu!news.cac.psu.edu!howland.reston.ans.net!EU.net!sunic!news.funet.fi!hydra.Helsinki.FI!news.helsinki.fi!not-for-mail
From: Kari.Hurtta@Helsinki.FI (Kari E. Hurtta)
Newsgroups: alt.sources
Subject: kehpager V1.2 (part 09/14)
Followup-To: alt.sources.d
Date: 9 Jul 1994 14:22:16 +0300
Organization: University of Helsinki
Lines: 2149
Sender: hurtta@cc.Helsinki.FI
Message-ID: <2vm198$hlp@plootu.Helsinki.FI>
Reply-To: "Kari E. Hurtta" <Kari.Hurtta@Helsinki.FI>
NNTP-Posting-Host: plootu.helsinki.fi
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
Title: kehpager V1.2 - Charset aware pager for VTxxx terminals
Archive-Name: kehpager0120/part09
Author: Kari E. Hurtta <Kari.Hurtta@Helsinki.FI>
Part: 09/14
Environment: Ansi C, SunOS 4.1.2 (OS/MP 4.1B), 4.1.3, 5.2, 5.3,
HP-UX A.09.01, IRIX 4.0.5 (?), FreeBSD (?), NetBSD(?),
386BSD(?), VTxxx
#!/bin/sh
# this is part 9 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file content.c continued
#
CurArch=9
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file content.c"
sed 's/^X//' << 'SHAR_EOF' >> content.c
X }
X}
X
Xstatic void ER_center_enter (content *CT, struct er_STACK *current) {
X if (CT->c.enriched.stack_top->nofill) return;
X
X force_line_break(CT);
X current->justify = JUST_center;
X}
X
Xstatic void ER_center_exit (content *CT, struct er_STACK *current) {
X if (CT->c.enriched.stack_top->nofill) return;
X
X force_line_break(CT);
X}
X
Xstatic void ER_flushleft_enter (content *CT, struct er_STACK *current) {
X if (CT->c.enriched.stack_top->nofill) return;
X
X force_line_break(CT);
X current->justify = JUST_left;
X}
X
Xstatic void ER_flushleft_exit (content *CT, struct er_STACK *current) {
X if (CT->c.enriched.stack_top->nofill) return;
X
X force_line_break(CT);
X}
X
Xstatic void ER_flushright_enter (content *CT, struct er_STACK *current) {
X if (CT->c.enriched.stack_top->nofill) return;
X
X force_line_break(CT);
X current->justify = JUST_right;
X}
X
Xstatic void ER_flushright_exit (content *CT, struct er_STACK *current) {
X if (CT->c.enriched.stack_top->nofill) return;
X
X force_line_break(CT);
X}
X
Xstatic void ER_flushboth_enter (content *CT, struct er_STACK *current) {
X if (CT->c.enriched.stack_top->nofill) return;
X
X force_line_break(CT);
X current->justify = JUST_both;
X}
X
Xstatic void ER_flushboth_exit (content *CT, struct er_STACK *current) {
X if (CT->c.enriched.stack_top->nofill) return;
X
X force_line_break(CT);
X}
X
Xstatic void ER_excerpt_enter (content *CT, struct er_STACK *current) {
X force_line_break(CT);
X
X current->excerpt_count++;
X current->excerpt_flag = current->attrib_flag;;
X}
X
Xstatic void ER_excerpt_exit (content *CT, struct er_STACK *current) {
X
X force_line_break(CT);
X}
X
Xstatic void RT_signature_enter (content *CT, struct er_STACK *current) {
X CHAR_IDX mapped[2];
X force_line_break(CT);
X do_line_break(CT);
X
X current -> attrib_flag = FL_DIM;
X current->nofill = 1;
X current->justify = JUST_left;
X current->force_wrap = 0;
X
X map_input(MAP_ASCII,2,rCs("--"),mapped);
X
X print_to_window(CT->win,
X CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X 2,mapped);
X CT->last_line_X += 2;
X
X CT->c.enriched.spc_count = 0;
X
X do_line_break(CT);
X
X}
X
Xstatic void RT_signature_exit (content *CT, struct er_STACK *current) {
X force_line_break(CT);
X do_line_break(CT);
X
X}
X
X
Xstatic void RT_paragraph_enter (content *CT, struct er_STACK *current) {
X force_line_break(CT);
X
X current -> pindent = 3;
X
X}
X
Xstatic void RT_paragraph_exit (content *CT, struct er_STACK *current) {
X current -> pindent = 0;
X force_line_break(CT);
X do_line_break(CT);
X CT->c.enriched.no_nl = 1;
X}
X
X
Xstatic void attrib_update(content *CT) {
X int A,I,S,J,E1,E2,W;
X
X get_line_status(CT->win,CT->last_line_Y,&A,&I,&S,&J,&E1,&E2,&W);
X if (A != CT->c.enriched.stack_top->pindent ||
X I != CT->c.enriched.stack_top->indent ||
X S != CT->c.enriched.stack_top->submargin ||
X E1 != CT->c.enriched.stack_top->excerpt_count ||
X E2 != CT->c.enriched.stack_top->excerpt_flag ||
X W != CT->c.enriched.stack_top->force_wrap) {
X A = CT->c.enriched.stack_top->pindent;
X I = CT->c.enriched.stack_top->indent;
X S = CT->c.enriched.stack_top->submargin;
X E1 = CT->c.enriched.stack_top->excerpt_count;
X E2 = CT->c.enriched.stack_top->excerpt_flag;
X W = CT->c.enriched.stack_top->force_wrap;
X set_line_status(CT->win,CT->last_line_Y,A,I,S,J,E1,E2,W);
X }
X}
X
Xstatic void RT_superscript_enter (content *CT, struct er_STACK *current) {
X
X if (0 == CT->last_line_X)
X attrib_update(CT);
X print_to_window(CT->win,
X CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X 1,&CH_SUP_M);
X CT->last_line_X++;
X CT->c.enriched.spc_count = 0;
X}
X
Xstatic void RT_superscript_exit (content *CT, struct er_STACK *current) {
X
X if (0 == CT->last_line_X)
X attrib_update(CT);
X print_to_window(CT->win,
X CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X 1,&CH_END_M);
X CT->last_line_X++;
X CT->c.enriched.spc_count = 0;
X}
X
X
Xstatic void RT_subscript_enter (content *CT, struct er_STACK *current) {
X
X if (0 == CT->last_line_X)
X attrib_update(CT);
X print_to_window(CT->win,
X CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X 1,&CH_SUB_M);
X CT->last_line_X++;
X CT->c.enriched.spc_count = 0;
X}
X
Xstatic void RT_subscript_exit (content *CT, struct er_STACK *current) {
X
X if (0 == CT->last_line_X)
X attrib_update(CT);
X print_to_window(CT->win,
X CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X 1,&CH_END_M);
X CT->last_line_X++;
X CT->c.enriched.spc_count = 0;
X}
X
X#define ER_main_f 0
X#define ER_unknown_f 1
X#define ER_verbatim_f 2
X#define RT_comment_f 3
X
X#define M_er 1
X#define M_rt 2
X
Xstatic struct ER_functions {
X int mode;
X char *name;
X ER_function *enter_region;
X ER_function *exit_region;
X} ER_functions[] = {
X { M_er|M_rt, NULL, ER_main_enter, ER_main_exit },
X { M_er|M_rt, NULL, ER_unknown_enter, ER_unknown_exit },
X { M_er, "Verbatim", ER_verbatim_enter, ER_verbatim_exit },
X { M_rt, "Comment", RT_comment_enter, RT_comment_exit },
X
X { M_er|M_rt, "Bold", ER_bold_enter, ER_bold_exit },
X { M_er|M_rt, "Italic", ER_underline_enter, ER_underline_exit },
X { M_er|M_rt, "Underline",ER_underline_enter, ER_underline_exit },
X { M_er|M_rt, "Indent", ER_indent_enter, ER_indent_exit },
X { M_er|M_rt, "IndentRight",ER_indentright_enter,ER_indentright_exit },
X { M_er, "Param", ER_param_enter, ER_param_exit },
X { M_er, "NoFill", ER_nofill_enter, ER_nofill_exit },
X { M_er|M_rt, "Center", ER_center_enter, ER_center_exit },
X { M_er|M_rt, "FlushLeft",ER_flushleft_enter, ER_flushleft_exit },
X { M_er|M_rt, "FlushRight",ER_flushright_enter,ER_flushright_exit },
X { M_er, "FlushBoth",ER_flushboth_enter, ER_flushboth_exit },
X { M_er|M_rt, "Excerpt", ER_excerpt_enter, ER_excerpt_exit },
X { M_rt, "Paragraph",RT_paragraph_enter, RT_paragraph_exit },
X { M_rt, "Signature",RT_signature_enter, RT_signature_exit },
X { M_rt, "Heading", RT_reject_enter, RT_reject_exit },
X { M_rt, "Footing", RT_reject_enter, RT_reject_exit },
X { M_rt, "Subscript", RT_subscript_enter, RT_subscript_exit },
X { M_rt, "Superscript",RT_superscript_enter,RT_superscript_exit },
X
X};
X
Xstatic void push_er_stack(content *CT, int fnc,CHAR *main) {
X struct er_STACK *prev = CT->c.enriched.stack_top;
X struct er_STACK *new = (struct er_STACK *) MALLOC(sizeof (struct er_STACK));
X CHAR *ptr = main ? concat_text(NULL,main) : NULL;
X
X if (DEBUG_ENRICHED) {
X print_debug("ENRICHED/RICHTEXT: -> %d: %s",fnc,Cs(main) ? Cs(main) : "");
X }
X
X new-> previous = prev;
X new-> er_function = fnc;
X new-> name = ptr;
X new-> cs = NULL_chtable;
X if (prev) {
X copy_table(&(new -> cs),&(prev -> cs));
X new -> indent = prev -> indent;
X new -> pindent = prev -> pindent;
X new -> submargin = prev -> submargin;
X new -> param = prev -> param;
X new -> justify = prev -> justify;
X new -> nofill = prev -> nofill;
X new -> excerpt_count = prev -> excerpt_count;
X new -> excerpt_flag = prev -> excerpt_flag;
X new -> force_wrap = prev -> force_wrap;
X new -> attrib_flag = prev -> attrib_flag;
X } else {
X copy_table(&(new -> cs),&(CT -> cs));
X new -> indent = 0;
X new -> pindent = 0;
X new -> submargin = 0;
X new -> param = 0;
X new -> justify = enable_fulljust ? JUST_both : JUST_left;
X new -> nofill = 0;
X new -> excerpt_count = 0;
X new -> excerpt_flag = 0;
X new -> force_wrap = 1;
X new -> attrib_flag = 0;
X }
X CT->c.enriched.stack_top = new;
X if (2 == CT->c.enriched.stack_top->param && fnc != RT_comment_f) {
X if (DEBUG_ENRICHED)
X print_debug("ENRICHED/RICHTEXT -> richtext comment: enter not executed");
X
X } else {
X ER_functions[fnc].enter_region(CT,new);
X }
X}
X
Xstatic void pop_er_stack(content *CT) {
X struct er_STACK *current = CT->c.enriched.stack_top;
X struct er_STACK *prev = current->previous;
X
X if (DEBUG_ENRICHED) {
X print_debug("ENRICHED/RICHTEXT <- %d: %s",
X current->er_function,Cs(current->name) ?
X Cs(current->name) : "");
X }
X
X
X if (2 == CT->c.enriched.stack_top->param &&
X current->er_function != RT_comment_f) {
X if (DEBUG_ENRICHED)
X print_debug("ENRICHED/RICHTEXT <- richtext comment: exit not executed");
X
X } else {
X ER_functions[current->er_function].exit_region(CT,current);
X }
X close_table(&(current->cs));
X if (current->name) FREE(current->name);
X FREE((void *)current);
X CT->c.enriched.stack_top = prev;
X}
X
Xstatic void unroll_er_stack(content *CT, int fnc) {
X while(CT->c.enriched.stack_top->er_function != fnc &&
X CT->c.enriched.stack_top->previous != NULL)
X pop_er_stack(CT);
X}
X
Xstatic void unroll_er_stack_n(content *CT, CHAR *fnc) {
X while((!CT->c.enriched.stack_top->name ||
X 0 != strcasecmp(Cs(CT->c.enriched.stack_top->name),Cs(fnc))) &&
X CT->c.enriched.stack_top->previous != NULL)
X pop_er_stack(CT);
X}
X
Xstatic int ER_basic_handle(content *CT,int len, CHAR *buffer,int flush) {
X CT->c.enriched.no_nl = 0;
X if (1 < CT->c.enriched.stack_top->param) {
X /* richtext comment or heading/footing - ignore */
X
X return len;
X } else if (CT->c.enriched.stack_top->param) {
X /* param not currently stored */
X
X /* mast also add handling for multibyte text to here !!! */
X
X return len;
X } else {
X int ret,mlen;
X CHAR_IDX *mapped = (CHAR_IDX *)MALLOC(len * sizeof(CHAR_IDX));
X
X if (CT->last_line_X == 0) {
X attrib_update(CT);
X }
X
X /* in richtext (but not in enriched) changin of charset is possible */
X ret=map2_input(&(CT->c.enriched.stack_top->cs),len,buffer,
X &mlen,mapped,CT->multi,flush);
X if (0 == ret) {
X CT->multi = !CT->multi;
X FREE(mapped);
X return 0;
X }
X else if (ret <0) {
X StrSet2(&(CT->multi_buffer),len,buffer);
X FREE(mapped);
X return -1;
X }
X
X print_to_window(CT->win,
X CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X mlen,mapped);
X CT->last_line_X += mlen;
X CT->c.enriched.spc_count = 0;
X
X FREE(mapped);
X return ret;
X }
X}
X
Xstatic int ER_handle_multi(content *CT,int len, CHAR *buffer,int flush) {
X int ret = ER_basic_handle(CT,len,buffer,flush);
X if (ret < 0) return len;
X return ret;
X}
X
X
Xstatic int handle_common(content *CT,int len, CHAR *buffer,
X CHAR **ch1, CHAR **ch2,
X int (*handle_it)(content *CT,CHAR ch),
X int (*handle_sp)(content *CT,CHAR ch)) {
X CHAR *ch3;
X
X for ((*ch2) = (*ch1);
X (*ch2) < buffer + len && handle_it(CT,*(*ch2));
X (*ch2)++);
X
X ch3 = (*ch2);
X for (; (*ch2) < buffer + len && !handle_sp(CT,*(*ch2)); (*ch2)++);
X
X if ((*ch2) != ch3) {
X int ret = ER_basic_handle(CT,(*ch2)-ch3,ch3,0);
X if (ret < 0) { CrashMe ("multibyte store with no multi data"); }
X if (0 == ret) return 0;
X (*ch2) = ch3 + ret;
X }
X return 1;
X}
X
Xstatic void add_space(content *CT) {
X if (CT->last_line_X == 0) {
X attrib_update(CT);
X }
X CT->c.enriched.spc_count++;
X if (CT->c.enriched.spc_count == 1 || CT->c.enriched.verbatim ||
X CT->c.enriched.stack_top->nofill)
X print_to_window(CT->win,CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X 1,&CH_SPC);
X else
X print_to_window(CT->win,CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X 1,&CH_SPC_C);
X CT->last_line_X++;
X CT->c.enriched.no_nl = 0;
X}
X
X/* Enriched content-type --------------------------------------------------- */
X
Xstatic int er_special_char(content *CT,CHAR ch) {
X if (' ' == ch) return 1;
X if (StrLEN(CT->c.enriched.cmd_buffer) > 1) return 0;
X if ('<' == ch) return 1;
X return 0;
X}
X
Xstatic int cmd_handle(content *CT,CHAR ch) {
X if (0 == StrLEN(CT->c.enriched.cmd_buffer)) return 0;
X if (1 == StrLEN(CT->c.enriched.cmd_buffer) && '<' == ch) return 0;
X if (1 == StrLEN(CT->c.enriched.cmd_buffer) && '/' == ch) {
X StrAdd(&(CT->c.enriched.cmd_buffer),ch);
X return 1;
X }
X if (isdigit(ch) || ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')
X || '-' == ch) {
X StrAdd(&(CT->c.enriched.cmd_buffer),ch);
X return 1;
X }
X
X
X if (CT->c.enriched.verbatim && '>' == ch &&
X 0 == strncasecmp("</verbatim",
X Cs(StrPTR(CT->c.enriched.cmd_buffer)),10)) {
X
X if (DEBUG_ENRICHED) {
X print_debug("ENRICHED token: </verbatim>");
X }
X
X
X unroll_er_stack(CT,ER_verbatim_f);
X if (CT->c.enriched.stack_top->previous != NULL)
X pop_er_stack(CT);
X
X StrFree(&(CT->c.enriched.cmd_buffer));
X return 1;
X }
X
X if (!CT->c.enriched.verbatim && '>' == ch) {
X CHAR *ptr;
X int neg = 0;
X
X ptr = StrPTR(CT->c.enriched.cmd_buffer);
X
X if (DEBUG_ENRICHED) {
X print_debug("ENRICHED token: %s>",ptr);
X }
X
X ptr++;
X
X if ('/' == *ptr) {
X neg = 1;
X ptr++;
X }
X
X if (neg) {
X unroll_er_stack_n(CT,ptr);
X if (CT->c.enriched.stack_top->previous != NULL)
X pop_er_stack(CT);
X } else {
X int fnc = ER_unknown_f,i;
X
X for (i = 0; i < sizeof(ER_functions) / sizeof(struct ER_functions); i++)
X if ((ER_functions[i].mode & M_er) == M_er &&
X ER_functions[i].name &&
X 0 == strcasecmp(Cs(ptr),ER_functions[i].name))
X fnc = i;
X
X push_er_stack(CT,fnc,ptr);
X }
X
X StrFree(&(CT->c.enriched.cmd_buffer));
X return 1;
X }
X
X flush_cmd_buffer(CT);
X return 0;
X}
X
Xstatic int ER_handle(content *CT,int len, CHAR *buffer) {
X CHAR *ch1,*ch2;
X
X set_win_prompt(-1,-1,-1);
X
X if (1 == CT->c.enriched.nl_count) {
X add_space(CT);
X }
X CT->c.enriched.nl_count = 0;
X
X for (ch1 = buffer; ch1 < buffer + len; ch1 = ch2) {
X
X if (!handle_common(CT,len,buffer,&ch1,&ch2,cmd_handle,er_special_char))
X break;
X
X for (;ch2 < buffer + len && er_special_char(CT,*ch2); ch2++) {
X if (' ' == *ch2) add_space(CT);
X else if (StrLEN(CT->c.enriched.cmd_buffer)) {
X if (CT->c.enriched.stack_top->param) {
X /* param not currently stored */
X
X StrFree(&(CT->c.enriched.cmd_buffer));
X } else {
X if (CT->c.enriched.verbatim)
X StrAdd(&(CT->c.enriched.cmd_buffer),'<');
X flush_cmd_buffer(CT);
X }
X } else StrAdd(&(CT->c.enriched.cmd_buffer),'<');
X }
X scroll_it(CT->win); /* for autowrap */
X }
X return ch1-buffer;
X}
X
Xstatic void ER_handle_eoln(content *CT) {
X CT->c.enriched.no_nl = 0;
X
X if (CT->c.enriched.verbatim || CT->c.enriched.stack_top->nofill) {
X do_line_break(CT);
X return;
X }
X
X if (CT->c.enriched.stack_top->param) {
X /* Storing of param not implemented */
X return;
X }
X
X CT->c.enriched.nl_count++;
X if (CT->c.enriched.nl_count > 1) {
X do_line_break(CT);
X }
X}
X
Xstatic void ER_init (content *CT) {
X CT->c.enriched.magic = CT_enriched;
X StrInit(&(CT->c.enriched.cmd_buffer),60);
X CT->c.enriched.nl_count = 0;
X CT->c.enriched.spc_count = 1; /* eats spaces also in beginning of line */
X CT->c.enriched.no_nl = 0;
X CT->c.enriched.verbatim = 0;
X CT->c.enriched.stack_top = NULL;
X push_er_stack(CT,ER_main_f,NULL);
X}
X
Xstatic void ER_exit(content *CT) {
X
X if(StrLEN(CT->c.enriched.cmd_buffer))
X flush_cmd_buffer(CT);
X StrFree(&(CT->c.enriched.cmd_buffer));
X
X justification_update(CT);
X
X unroll_er_stack(CT,ER_main_f);
X pop_er_stack(CT);
X if (NULL != CT->c.enriched.stack_top) {
X CrashMe("ER_exit: stack not empty - FATAL error ");
X }
X CT->c.enriched.magic = -1;
X}
X
Xstatic void ER_update(content *CT) {
X justification_update(CT);
X}
X
X/* Richtext content-type --------------------------------------------- */
X
Xstatic int rt_special_char(content *CT,CHAR ch) {
X if (' ' == ch) return 1;
X if (StrLEN(CT->c.enriched.cmd_buffer) > 0) return 0;
X if ('<' == ch) return 1;
X return 0;
X}
X
Xstatic int rt_cmd_handle(content *CT,CHAR ch) {
X if (0 == StrLEN(CT->c.enriched.cmd_buffer)) return 0;
X
X if (1 == StrLEN(CT->c.enriched.cmd_buffer) && '/' == ch) {
X StrAdd(&(CT->c.enriched.cmd_buffer),ch);
X return 1;
X }
X if (isdigit(ch) || ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')
X || '-' == ch) {
X StrAdd(&(CT->c.enriched.cmd_buffer),ch);
X return 1;
X }
X
X if ('>' == ch) {
X CHAR *ptr;
X int neg = 0;
X
X ptr = StrPTR(CT->c.enriched.cmd_buffer);
X
X
X if (DEBUG_ENRICHED) {
X print_debug("RICHTEXT token: %s>",ptr);
X }
X
X ptr++;
X
X if (0 == strcasecmp(Cs(ptr),"lt")) {
X if (CT->last_line_X == 0)
X attrib_update(CT);
X
X print_to_window(CT->win,CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X 1,&CH_LT);
X CT->last_line_X++;
X CT->c.enriched.spc_count = 0;
X
X StrFree(&(CT->c.enriched.cmd_buffer));
X return 1;
X
X } else if (0 == strcasecmp(Cs(ptr),"nl") ||
X 0 == strcasecmp(Cs(ptr),"np")) {
X do_line_break(CT);
X CT->c.enriched.no_nl = 1;
X
X if (0 == strcasecmp(Cs(ptr),"np")) {
X print_to_window(CT->win,
X CT->last_line_X+1,
X CT->last_line_Y,
X CT->c.enriched.stack_top->attrib_flag,
X 1,&CH_NP);
X CT->last_line_X += 1;
X }
X
X StrFree(&(CT->c.enriched.cmd_buffer));
X return 1;
X }
X CT->c.enriched.no_nl = 0;
X
X if ('/' == *ptr) {
X neg = 1;
X ptr++;
X }
X
X if (neg) {
X unroll_er_stack_n(CT,ptr);
X if (CT->c.enriched.stack_top->previous != NULL)
X pop_er_stack(CT);
X } else {
X int fnc = ER_unknown_f,i;
X
X for (i = 0; i < sizeof(ER_functions) / sizeof(struct ER_functions); i++)
X if ((ER_functions[i].mode & M_rt) == M_rt &&
X ER_functions[i].name &&
X 0 == strcasecmp(Cs(ptr),ER_functions[i].name))
X fnc = i;
X
X push_er_stack(CT,fnc,ptr);
X
X if (fnc == ER_unknown_f) {
X int map = find_mime_map(ptr);
X if (-1 != map) {
X if (!open_table(&(CT->c.enriched.stack_top->cs),map,NULL))
X copy_table(&(CT->c.enriched.stack_top->cs), &(CT->cs));
X }
X }
X }
X
X StrFree(&(CT->c.enriched.cmd_buffer));
X return 1;
X }
X
X flush_cmd_buffer(CT);
X return 0;
X
X}
X
Xstatic void RT_init (content *CT) {
X CT->c.enriched.magic = CT_richtext;
X StrInit(&(CT->c.enriched.cmd_buffer),40);
X CT->c.enriched.nl_count = 0;
X CT->c.enriched.spc_count = 1; /* eat spacesc also in beginning of line */
X CT->c.enriched.no_nl = 0;
X CT->c.enriched.verbatim = 0;
X CT->c.enriched.stack_top = NULL;
X push_er_stack(CT,ER_main_f,NULL);
X}
X
Xstatic void RT_handle_eoln(content *CT) {
X if (CT->c.enriched.stack_top->param) return;
X if (!CT->c.enriched.no_nl) add_space(CT);
X CT->c.enriched.no_nl = 0;
X}
X
Xstatic int RT_handle(content *CT,int len, CHAR *buffer) {
X CHAR *ch1,*ch2;
X
X set_win_prompt(-1,-1,-1);
X
X for (ch1 = buffer; ch1 < buffer + len; ch1 = ch2) {
X
X if (!handle_common(CT,len,buffer,&ch1,&ch2,rt_cmd_handle,rt_special_char))
X break;
X
X for (;ch2 < buffer + len && rt_special_char(CT,*ch2); ch2++) {
X if (' ' == *ch2) add_space(CT);
X else StrAdd(&(CT->c.enriched.cmd_buffer),'<');
X }
X scroll_it(CT->win); /* for autowrap */
X }
X return ch1-buffer;
X}
X
X
X/* NULL content-type ------------------------------------------------- */
X
Xstatic void NL_init (content *CT) {
X CrashMe("NL_init");
X}
X
Xstatic void NL_handle_eoln(content *CT) {
X CrashMe("NL_handle_eoln");
X}
X
X
Xstatic void NL_exit(content *CT) {
X CrashMe("NL_exit");
X}
X
Xstatic void NL_update(content *CT) {
X CrashMe("NL_update");
X}
X
Xstatic int NL_handle(content *CT,int len, CHAR *buffer) {
X CrashMe("NL_handle");
X}
X
Xstatic int NL_handle_multi(content *CT,int len, CHAR *buffer, int flush) {
X CrashMe("NL_handle_multi");
X}
X
X/* ------------------------------------------------------------------- */
X
Xstatic content content_models[] = {
X /* CT_plain */
X { CT_plain, NULL, -1, -1, 0,
X PL_init, PL_handle, PL_handle_multi,
X PL_handle_eoln, PL_exit, PL_update, 1, 0 },
X /* CT_terminal */
X { CT_terminal, NULL, -1, -1, 0,
X TR_init, TR_handle, TR_handle_multi,
X TR_handle_eoln, TR_exit, TR_update, 1, 0 },
X /* CT_enriched */
X { CT_enriched, NULL, -1, -1, 0,
X ER_init, ER_handle, ER_handle_multi,
X ER_handle_eoln, ER_exit, ER_update, 1, 0 },
X /* CT_richtext */
X { CT_richtext, NULL, -1, -1, 0,
X RT_init, RT_handle, ER_handle_multi,
X RT_handle_eoln, ER_exit, ER_update, 1, 0 },
X};
X
Xconst content NULL_content =
X{ -1, NULL, -1, 0, 0,
X NL_init, NL_handle, NL_handle_multi,
X NL_handle_eoln, NL_exit, NL_update, 1, 0 };
X
Xstatic struct CN {
X int mime;
X char *name;
X int content;
X} ct_names[] = {
X { 0, "Terminal", CT_terminal },
X { 0, "Plain", CT_plain },
X { 1, "Text/Plain", CT_plain },
X { 0, "Enriched", CT_enriched },
X { 1, "Text/Enriched",CT_enriched },
X { 0, "Richtext", CT_richtext },
X { 1, "Text/Richtext",CT_richtext },
X
X { -1, NULL, -1 }
X};
X
Xint search_content(CHAR *name,int mime) {
X int i;
X for (i=0; NULL != ct_names[i].name; i++)
X if ((!mime || ct_names[i].mime) &&
X 0 == strcasecmp(Cs(name),ct_names[i].name))
X return ct_names[i].content;
X return -1;
X}
X
XCHAR *content_name(int content, int mime) {
X int i;
X for (i=0; NULL != ct_names[i].name; i++)
X if (mime == ct_names[i].mime &&
X content == ct_names[i].content)
X return rCs(ct_names[i].name);
X return rCs("Unknown");
X}
X
XINLINE static void turn_flag(content *CT) {
X if (!CT->cs_flag) {
X StrInit(&(CT->multi_buffer),10);
X CT->cs=NULL_chtable;
X CT->cs_flag=1;
X }
X}
X
Xvoid init_content(int content_type,int *fp,int win,
X int cs, CHAR *cs_param,
X content *CT) {
X *CT = content_models[content_type];
X turn_flag(CT);
X CT->fp = fp;
X CT->win=win;
X if (!open_table(&(CT->cs),cs,cs_param)) {
X int ok = 0;
X if (cs_param) {
X if (open_table(&(CT->cs),cs,NULL)) {
X print_notify("(%s) Unsupported charset: %s; %s\n"
X " Using charset: %s",
X prog,map_name(cs,0),cs_param,
X map_name(cs,0));
X ok = 1;
X } else {
X print_notify("(%s) Unsupported charset: %s; %s\n"
X "\tUsing charset: %s",
X prog,map_name(cs,0),cs_param,
X map_name(MAP_ASCII,0));
X }
X }
X else
X print_notify("(%s) Unsupported charset: %s\n",
X "\tUsing charset: %s",
X prog,map_name(cs,0),
X map_name(MAP_ASCII,0));
X if (!ok && !open_table(&(CT->cs),MAP_ASCII,NULL))
X CrashMe("Opening of Ascii failed !");
X }
X CT->multi = 0;
X CT->last_line_Y = 1;
X CT->last_line_X = 0;
X clear_window(CT->win);
X CT->init(CT);
X}
X
X
Xvoid handle_content(content *CT, int len, CHAR *buffer) {
X int ret=0;
X int rlen=len;
X CHAR *rbuffer = buffer,*ptr;
X turn_flag(CT);
X if (StrLEN(CT->multi_buffer) > 0) {
X rbuffer = MALLOC(len+StrLEN(CT->multi_buffer));
X memcpy((void *)rbuffer,(void *)buffer,len);
X memcpy((void *)(rbuffer+len),(void *)StrPTR(CT->multi_buffer),
X StrLEN(CT->multi_buffer));
X rlen = len + StrLEN(CT->multi_buffer);
X StrFree(&(CT->multi_buffer));
X }
X
X for (ptr=rbuffer;ptr < rbuffer+rlen; ptr += ret) {
X if (CT->multi)
X ret=CT->handle_multi(CT,rlen-(ptr-rbuffer),ptr,0);
X else
X ret=CT->handle(CT,rlen-(ptr-rbuffer),ptr);
X }
X
X if (rbuffer != buffer) FREE(rbuffer);
X}
X
Xstatic void flush_pending_multi(content *CT) {
X if (StrLEN(CT->multi_buffer) > 0) {
X int ret=0;
X CHAR *ptr;
X for (ptr=StrPTR(CT->multi_buffer);
X ptr < StrPTR(CT->multi_buffer)+StrLEN(CT->multi_buffer); ptr += ret) {
X if (!CT->multi) { CrashMe("Pending data with no multi mode!!"); }
X ret=CT->handle_multi(CT,
X StrLEN(CT->multi_buffer)
X -(ptr-StrPTR(CT->multi_buffer)),ptr,1);
X }
X StrFree(&(CT->multi_buffer));
X }
X}
X
Xvoid eoln_content(content *CT) {
X turn_flag(CT);
X flush_pending_multi(CT);
X CT->handle_eoln(CT);
X}
X
Xvoid exit_content(content *CT) {
X turn_flag(CT);
X flush_pending_multi(CT);
X turn_flag(CT);
X}
X
Xvoid update_content(content *CT) { /* shoft eof - eof detected, but
X here can be more data incoming
X when reread */
X turn_flag(CT);
X /* can here to be flush_pending_multi(CT) ? */
X CT->update(CT);
X}
SHAR_EOF
echo "File content.c is complete"
chmod 0644 content.c || echo "restore of content.c fails"
echo "x - extracting content.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > content.h &&
X/* file: content.h
X *
X * kehpager, Charset aware pager, Kari E. Hurtta
X *
X * Copyright (c) 1993, 1994 Kari E. Hurtta
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms. This software is provided 'as is'
X * and without any warranty.
X */
X
X#define CT_plain 0
X#define CT_terminal 1
X#define CT_enriched 2
X#define CT_richtext 3
X
Xtypedef struct CT content;
Xstruct CT {
X int ct;
X int *fp;
X int win;
X int cs_flag;
X int multi;
X void (* init)(content *CT);
X int (* handle)(content *CT,int len, CHAR *buffer);
X int (* handle_multi)(content *CT,int len, CHAR *buffer,int flush);
X void (* handle_eoln)(content *CT);
X void (* exit)(content *CT);
X void (* update)(content *CT);
X int last_line_Y;
X int last_line_X;
X union {
X struct {
X int magic;
X int attrib_char_flag;
X int owerwrite;
X String attrib_buffer;
X
X } terminal;
X int plain;
X struct { /* both Enriched and Richtext uses this same structure */
X int magic;
X String cmd_buffer;
X int nl_count;
X int spc_count;
X int verbatim;
X int no_nl; /* used by richtext */
X struct er_STACK {
X struct er_STACK *previous;
X int indent;
X int pindent; /* used by richtext */
X chtable cs; /* used by richtext */
X int submargin;
X int param; /* 2 = richtext comment */
X int nofill;
X int justify;
X int excerpt_count;
X int excerpt_flag;
X int attrib_flag;
X int force_wrap;
X int er_function;
X CHAR *name;
X } *stack_top;
X } enriched;
X } c;
X chtable cs;
X String multi_buffer;
X};
X
Xextern const content NULL_content;
X
Xextern void init_content(int content_type,int *fp,int win,
X int cs, CHAR *cs_param,
X content *CT);
Xextern void handle_content(content *CT, int len, unsigned char *buffer);
Xextern void eoln_content(content *CT);
Xextern void exit_content(content *CT);
Xextern void update_content(content *CT);
Xextern int search_content(CHAR *name,int mime);
Xextern CHAR *content_name(int content, int mime);
X
Xextern void scroll_it(int win);
X
Xextern int enable_fulljust;
X
SHAR_EOF
chmod 0444 content.h || echo "restore of content.h fails"
echo "x - extracting control.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > control.c &&
X/* file: control.c
X *
X * kehpager, Charset aware pager, Kari E. Hurtta
X *
X * Copyright (c) 1993, 1994 Kari E. Hurtta
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms. This software is provided 'as is'
X * and without any warranty.
X */
X
X#include <string.h>
X#include <stdio.h>
X#include <stdarg.h>
X
X
X#include "kehpager.h"
X#include "memory.h"
X#include "charset.h"
X
X#include "control.h"
X#include "terminal.h"
X#include "esc.h"
X#include "rc.h"
X#include "env.h"
X
Xvolatile int need_redraw = 0;
Xvolatile int pager_state = 0;
Xvolatile int down_line = 1; /* !! */
Xstatic int vt_type = -1;
Xstatic terminal_type_pass = 0;
X/* 1 = asking terminal type
X 2 = trying multinational
X 3 = ask attributes
X */
X
X#define READY_PASS (4)
X
X#define SET_PASS(a) { terminal_type_pass = (a); \
X if (DEBUG_TERM) print_debug("Terminal pass: %d",terminal_type_pass); }
X
Xstatic int in_panic = 0;
X#define PANIC(text) if (!in_panic) { \
X in_panic = 1; reset_terminal_state(); \
X print_notify("(%s) " #text,prog); \
X close_files(); close_terminal(); exit(1); }
X
Xstatic int wait_count = 0;
X
X#define ASKED { wait_count++; \
X if (DEBUG_TERM) print_debug("wait_count: %d",wait_count); }
X#define GOT { if (DEBUG_TERM) print_debug("wait_count: %d",wait_count); \
X if (wait_count && !--wait_count) pass_4(); }
X
Xstatic int saved_personality = -1;
Xstatic int saved_multinational = -1;
Xstatic int saved_autowrap = -1;
Xstatic int saved_application = -1;
Xstatic int saved_language = -1;
Xstatic int saved_legend = -1; /* 1 = data processing keys */
Xstatic int saved_newline = -1;
X
Xstatic int default_personality = 0;
Xstatic int default_multinational = -1;
Xstatic int default_autowrap = 1;
Xstatic int default_application = 0;
Xint default_language = -1;
Xstatic int default_legend = 0; /* 1 = data processing keys */
Xstatic int default_newline = 0;
X
Xstatic int default_latin1 = 0;
X
Xstatic int set_vt100_is_G2 = 0;
Xstatic int set_vt100_is_ncr = 0;
X
Xint set_xterm_latin1 = 1;
Xint query_terminal_size = 1;
Xint limit_query = 0;
Xint force_mode = 0; /* 1 = National
X * 2 = Multinational
X */
X
Xint timer_per_char = 1;
Xstatic int timer_id_1 = 50;
Xstatic int timer_id_2 = 50;
Xstatic int timer_states_1 = 30;
Xstatic int timer_states_2 = 10;
Xstatic int use_technical = 1;
X
Xstatic int n_SUP = 0;
Xstatic int n_DISAB = 1;
X
Xinit_item control_items[] = {
X { &n_SUP, "force.feature.enabled", V_ATTR },
X { &n_DISAB, "force.feature.disabled", V_ATTR },
X { &default_personality, "exit.personality_8bit", V_BOOL },
X { &default_multinational, "exit.multinational", V_BOOL },
X { &default_autowrap, "exit.autowrap", V_BOOL },
X { &default_application, "exit.application_cursor_keys", V_BOOL },
X { &default_legend, "exit.data_processing_keys", V_BOOL },
X { &default_latin1, "exit.vt300.8bit_latin1",V_BOOL },
X { &default_newline, "exit.newline", V_BOOL },
X { &default_language, "use.keyboard_language", V_NUM },
X { &set_vt100_is_G2, "use.vt100.G2_available", V_BOOL },
X { &set_vt100_is_ncr, "use.vt100.national_available", V_BOOL },
X { &use_technical, "use.technical", V_BOOL },
X { &limit_query, "use.limited.queries", V_BOOL },
X { &query_terminal_size, "use.query_size", V_BOOL },
X { &set_xterm_latin1, "force.xterm.latin1", V_BOOL },
X { &force_mode, "force.mode", V_MODE },
X { &timer_per_char, "timer.per_char", V_TIMER },
X { &timer_id_1, "timer.identification", V_TIMER },
X { &timer_id_2, "timer.test_8bit", V_TIMER },
X { &timer_states_1, "timer.states_first", V_TIMER },
X { &timer_states_2, "timer.states_interval", V_TIMER },
X { NULL, NULL, V_LAST }
X};
X
Xstatic int starting_line = -1;
Xstatic int starting_col = -1;
Xstatic int pos_count = 0;
X
X/*
Xstatic int saved_undef(int value,int def) {
X if (-1 == value) value = def;
X return value;
X}
X*/
X
Xstatic int saved(int value,int def) {
X if (-1 == value) value = def;
X if (-1 == value) value = 0;
X return value;
X}
X
Xstatic int neg_undef(int value) {
X if (-1 == value) return -1;
X return !value;
X}
X
Xstatic int have_8bit_clean = 0;
Xstatic int use_national = -1;
Xstatic int keyboard_language = -1;
X /* 1 North American
X * 6 Finnish
X */
X
Xstatic int xterm_latin1_magic = -1;
X
Xstatic int GL_set = -1;
Xstatic int GR_set = -1;
Xstatic int FLAGS_set = -1;
X
Xstatic long PRIM_attr = 0;
Xstatic long OPT_attr = 0;
Xstatic long SUP_attr = 0;
Xstatic long DISAB_attr = 0;
X
Xstatic long *attrs[] = { &SUP_attr, &DISAB_attr };
X
X
X#define HAVE(x) ((x) == ((x) & (SUP_attr | PRIM_attr | OPT_attr) \
X & ~DISAB_attr))
X#define SUPPOSE(x) (SUP_attr |= (x))
X
X#define ATR_insdel (1L<<0) /* Insert/delete characters/lines */
X/* #define ATR_xxx (1L<<1) */
X#define ATR_cs_latin1 (1L<<2) /* (14) Have Latin/1 and possible some other
X * Latin charset
X */
X#define ATR_cs_technical (1L<<3) /* (15) Have technical character set */
X#define ATR_cs_ncr (1L<<4) /* (9) Have national charsets */
X#define ATR_soft_char (1L<<5) /* (7) Have shoft characters */
X#define ATR_132 (1L<<6) /* (1) Have 132 columns */
X#define ATR_sel_erase (1L<<7) /* (6) Have selective erase */
X#define ATR_def_key (1L<<8) /* (8) Have user defined keys */
X/* #define ATR_windows (1L<<9) (18) Have user windows */
X/* #define ATR_2_sess (1L<<10) (19) Have two sessions */
X#define ATR_hor_scroll (1L<<11) /* (21) Have horizontal scrolling */
X#define ATR_ReGIS (1L<<12) /* (3) Have ReGIS graphics */
X#define ATR_SIXEL (1L<<13) /* (4) Have SIXEL graphics */
X/* #define ATR_status_d (1L<<14) (11) Status display */
X#define ATR_printer (1L<<15) /* (2) Printer port */
X#define ATR_cs_multinational (1L<<16) /* Have multinational */
X#define ATR_G2 (1L<<17) /* Have G2 & G3 available */
X#define ATR_vt100_magic (1L<<18) /* Unnamed negative feature */
X#define ATR_C1_controls (1L<<19) /* Have C1 controls */
X#define ATR_terminal_rq (1L<<20) /* Terminal interrogation commands
X * DECRQM, DECRQSS, ...
X */
X
Xstatic struct features {
X long flag;
X char *name;
X} ftrtable[] = {
X { ATR_vt100_magic, "(vt100 magic)" },
X { ATR_insdel, "Ins/Del characters/lines" },
X { ATR_G2, "Banks G2 & G3 (changeable)" },
X { ATR_cs_latin1, "Latin/1 charset" },
X { ATR_cs_multinational, "Multinational charset" },
X { ATR_cs_technical, "Technical charset" },
X { ATR_C1_controls, "C1 control characters" },
X { ATR_cs_ncr, "National charset" },
X { ATR_soft_char, "Shoft characters" },
X { ATR_132, "132 columns" },
X { ATR_sel_erase, "Selective erase" },
X { ATR_def_key, "User defined keys" },
X { ATR_hor_scroll, "Horizontal scrolling" },
X { ATR_ReGIS, "ReGIS graphic" },
X { ATR_SIXEL, "SIXEL graphic" },
X { ATR_printer, "Printer port" },
X { ATR_terminal_rq, "Terminal interrogation commands" },
X { -1, NULL }
X};
X
Xstatic long flag_name (CHAR *s) {
X int i;
X for (i = 0; -1 != ftrtable[i].flag; i++)
X if (0 == strcasecmp(ftrtable[i].name,Cs(s))) return ftrtable[i].flag;
X return -1;
X}
X
Xint map_attribute(CHAR *value,int *ptr) {
X long flag;
X long *fp = attrs[*ptr];
X if (0 == strcasecmp("None",Cs(value)))
X (*fp) = 0L;
X else {
X flag = flag_name(value);
X if (-1 == flag) return -1;
X (*fp) |= flag;
X }
X return *ptr;
X}
X
Xstatic void do_magic() {
X if (HAVE(ATR_vt100_magic)) {
X if (set_vt100_is_G2) SUPPOSE(ATR_G2);
X if (set_vt100_is_ncr) SUPPOSE(ATR_cs_ncr);
X }
X}
X
Xstatic CHAR * ftr_string(long features) {
X CHAR *ptr = NULL;
X int i;
X for (i = 0; -1 != ftrtable[i].flag; i++)
X if (ftrtable[i].flag & features) {
X if (ptr) ptr = concat_text(ptr,rCs(", "));
X ptr = concat_text(ptr,rCs(ftrtable[i].name));
X }
X if (!ptr)
X ptr = concat_text(ptr,rCs("None"));
X return ptr;
X}
X
Xtypedef struct ftr {
X int basic;
X int pos;
X int value;
X long flags;
X} ftrs;
X
Xstatic ftrs DA_table[] = {
X { -1, -1, 1, ATR_132 },
X { -1, -1, 2, ATR_printer },
X { -1, -1, 3, ATR_ReGIS },
X { -1, -1, 4, ATR_SIXEL },
X { -1, -1, 5, 0 /* AVO option (132 char wide) NOT installed */ },
X { -1, -1, 6, ATR_sel_erase },
X { -1, -1, 7, ATR_soft_char },
X { -1, -1, 8, ATR_def_key },
X { -1, -1, 9, ATR_cs_ncr },
X { -1, -1, 10, 0 /* Text ruling vector */ },
X { -1, -1, 11, 0 /* 25th Status line */ },
X { -1, -1, 12, 0 /* Terminal is a VT125 */ },
X { -1, -1, 13, 0 /* Local editing mode */ },
X { 63, -1, 14, ATR_cs_latin1 /* 8-bit characters */ },
X { 62, -1, -1, ATR_cs_multinational },
X { -1, -1, 15, ATR_cs_technical /* Technical character set */ },
X { -1, -1, 16, 0 /* Locator device port (ReGIS) [=mouse?] */ },
X { -1, -1, 17, 0 /* Terminal state reports */ },
X { -1, -1, 18, 0 /* Windowing capability */ },
X { -1, -1, 19, 0 /* Dual sessions */ },
X { -1, -1, 21, ATR_hor_scroll /* Horizontal scrolling */ },
X { -1, -1, 29, 0 /* ANSI text locator [=mouse?] */ },
X
X { 61, -1, -1, ATR_insdel },
X { 61, -1, -1, ATR_G2 },
X { 62, -1, -1, ATR_C1_controls },
X { 63, -1, -1, ATR_terminal_rq },
X { -1, -1, -1, -1 }
X};
X
Xstatic ftrs vt100_table[] = {
X { 0, -1, ATR_vt100_magic },
X { -1, 1, 0, 0 /* NO options */ },
X { -1, 1, 1, 0 /* Processor Option (STP) */ },
X { -1, 1, 2, ATR_132 | ATR_insdel /* Advanced Video Option (AVO) */ },
X { -1, 1, 3, ATR_132 | ATR_insdel /* AVO and STP */ },
X { -1, 1, 4, 0 /* Graphics Option (GPO) */ },
X { -1, 1, 5, 0 /* GPO and STP */ },
X { -1, 1, 6, ATR_132 | ATR_insdel /* GPO and AVO */ },
X { -1, 1, 7, ATR_132 | ATR_insdel /* GPO, AVO, and STP */ },
X /* I don't know if these are correct - don't seem to formed from bits: */
X { -1, 1, 9, ATR_printer | ATR_132 | ATR_insdel /* PP and AVO */ },
X { -1, 1, 11, ATR_printer | ATR_132 | ATR_insdel /* PP, GPO and AVO */ },
X /* VT125 uses: */
X { -1, 2, 0, 0 /* No printer present */ },
X { -1, 2, 1, ATR_printer /* printer present */ },
X { -1, -1, -1, -1 }
X};
X
Xstatic ftrs LPC02_table[] = {
X { -1, -1, 1, ATR_ReGIS /* ReGIS graphics software loaded */ },
X { -1, -1, 2, ATR_SIXEL /* Color Sixel graphics software loaded */ },
X { -1, -1, 3, 0 /* NAPLPS ???? */ },
X { -1, -1, 4, 0 /* GIDIS */ },
X
X { -1, -1, -1, -1 }
X};
X
Xstatic ftrs basic_table[] = {
X { 0, -1, -1, ATR_vt100_magic },
X { 0, -1, -1, ATR_insdel },
X { -1, -1, 4, ATR_SIXEL },
X { -1, -1, 3, ATR_ReGIS },
X { -1, -1, 2, ATR_printer },
X { -1, -1, 1, ATR_132 },
X { -1, -1, -1, -1 }
X};
X
Xstatic struct lvl {
X int type;
X ftrs *table;
X char *name;
X} levels[] = {
X { 1, vt100_table, "VT100" },
X { 2, vt100_table, "VT102" },
X { 3, vt100_table, "DECwrite IV" },
X { 4, vt100_table, "VT132" },
X { 5, vt100_table, "VK100" },
X { 6, basic_table, "VT102" },
X { 7, basic_table, "VT131" },
X { 12, vt100_table, "VT125" },
X { 28, LPC02_table, "LPC01 (Unsupported)" },
X { 37, LPC02_table, "LG02 (Unsupported)" },
X { 61, DA_table, "Level 1 (VT100 series)" },
X { 62, DA_table, "Level 2 (VT200 series)" },
X { 63, DA_table, "Level 3 (VT300 series)" },
X { 64, DA_table, "Level 4 (VT400 series)" },
X /* These are unsupported, because basic features for
X * these levels is not know
X */
X { 65, DA_table, "Level 5 (Unsupported)" },
X { 66, DA_table, "Level 6 (Unsupported)" },
X { 67, DA_table, "Level 7 (Unsupported)" },
X { 68, DA_table, "Level 8 (Unsupported)" },
X { 69, DA_table, "Level 9 (Unsupported)" },
X { -1, NULL, NULL }
X };
X
Xstatic void parse_DEC_DA (CHAR * S) {
X char *level,*ptr;
X int L,i,pos;
X static ftrs *table;
X
X PRIM_attr = 0;
X OPT_attr = 0;
X if (NULL == (level = strtok(Cs(S),";")) ||
X 0 == (vt_type = atoi(level))) {
X print_notify("Warning: Unsupported DA response");
X vt_type = -1;
X return;
X }
X L=-1;
X for (i = 0; -1 != levels[i].type; i++)
X if (vt_type == levels[i].type) {
X L = i;
X break;
X }
X if (-1 == L) {
X print_notify("Warning: Unknown terminal model (type/level field=%d)",
X vt_type);
X return;
X }
X table = levels[L].table;
X /* Calculate primary features */
X for (i = 0; -1 != table[i].flags; i++)
X if (-1 != table[i].basic &&
X vt_type >= table[i].basic)
X PRIM_attr |= table[i].flags;
X if (DEBUG_TERM) {
X CHAR *P = ftr_string(PRIM_attr);
X if (strlen(Cs(P)) < ERROR_LEN -20)
X print_debug("Primary features: %s",P);
X else
X print_debug("Primary features list too long to print...");
X free(P);
X }
X /* Calculate optional features */
X pos=0;
X for (ptr = strtok(NULL,";"); NULL != ptr; ptr = strtok(NULL,";")) {
X int val = atoi(ptr);
X pos++;
X for (i = 0; -1 != table[i].flags; i++)
X if (-1 != table[i].value &&
X val == table[i].value &&
X (-1 == table[i].pos || pos == table[i].pos))
X OPT_attr |= table[i].flags;
X }
X if (DEBUG_TERM) {
X CHAR *P = ftr_string(OPT_attr);
X if (strlen(Cs(P)) < ERROR_LEN -20)
X print_debug("Optional features: %s",P);
X else
X print_debug("Optional features list too long to print...");
X free(P);
X }
X}
X
Xstatic CHAR * terminal_type(void) {
X CHAR *ptr=NULL;
X int i;
X if (-1 == vt_type) {
X ptr = concat_text(ptr,rCs("Undefined"));
X } else {
X CHAR T[10];
X sprintf(Cs(T),"(%d) ",vt_type);
X ptr = concat_text(ptr,T);
X for (i = 0; -1 != levels[i].type; i++)
X if (vt_type == levels[i].type)
X ptr = concat_text(ptr,rCs(levels[i].name));
X }
X return ptr;
X}
X
Xlong hazards = 0L;
X
Xstatic struct Hazard {
X long value;
X char *text;
X} hazard_table[] = {
X { HAZ_wrap, "Terminal may wrap in right" },
X { HAZ_national, "Terminal is always in national mode" },
X { HAZ_ONLCR, "Tty driver may wrap LF -> CR LF on output" },
X { HAZ_TAB, "Tty driver may expand TAB -> SPCs on output" },
X { HAZ_newline, "Terminal is always in newline mode (LF produces new line, "
X " RETURN produces CR LF)" },
X { HAZ_application, "Cursor keys are always in application mode" },
X
X { -1, NULL }
X};
X
Xstatic CHAR * terminal_hazards(void) {
X CHAR *ptr=NULL;
X int i;
X for (i = 0; -1 != hazard_table[i].value; i++)
X if (HAZ_MAY(hazard_table[i].value)) {
X if (ptr) ptr = concat_text(ptr,rCs(", "));
X ptr = concat_text(ptr,rCs(hazard_table[i].text));
X }
X if (!ptr) ptr = concat_text(ptr,rCs("None"));
X return ptr;
X}
X
Xstruct termitem kehpager_term[] = {
X { "type", &vt_type },
X { "s.personality", &saved_personality },
X { "s.multinational", &saved_multinational },
X { "d.multinational", &default_multinational },
X { "s.application", &saved_application },
X { "s.language", &saved_language },
X { "s.legend", &saved_legend },
X { "s.autowrap", &saved_autowrap },
X { "u.8bit_clean", &have_8bit_clean },
X { NULL, NULL }
X};
X
Xstruct termitem2 kehpager_term2[] = {
X { "attr.prim", &PRIM_attr },
X { "attr.supp", &SUP_attr },
X { "attr.opt", &OPT_attr },
X { "attr.hazards", &hazards },
X { NULL, NULL }
X};
X
X#define A_ASCII 1
X#define A_8bit 2
X#define A_8bit_n (A_ASCII | A_8bit)
X#define A_96set 4
X
Xstruct one_set {
X int language;
X char *set;
X char *name;
X long flags;
X int use_latin;
X int area;
X int charset;
X} sets[] = {
X
X /* National character sets */
X { 1, "B", "ASCII", 0 , -1 , A_ASCII, MAP_ASCII }, /* 0 */
X { 2, "A", "UK-ASCII", 0 , -1 , 0, MAP_UK },
X { 4, "9", "French Canadian", ATR_cs_ncr, -1 , 0, MAP_CAN },
X { 6, "5", "Finnish", ATR_cs_ncr, -1 , 0, MAP_FINNISH },
X { 7, "K", "German", ATR_cs_ncr, -1 , 0, MAP_GER },
X { 9, "Y", "Italian", ATR_cs_ncr, -1 , 0, MAP_ITAL },
X { 5, "E", "Danish", ATR_cs_ncr, -1 , 0, MAP_NOR },
X { 13,"E", "Norwegian", ATR_cs_ncr, -1 , 0, MAP_NOR },
X { 12,"7", "Swedish", ATR_cs_ncr, -1 , 0, MAP_SWE },
X { 3, "R", "Flemish", ATR_cs_ncr, -1 , 0, MAP_BEL },
X { 14,"R", "French/Belgian", ATR_cs_ncr, -1 , 0, MAP_BEL },
X { 15,"Z", "Spanish", ATR_cs_ncr, -1 , 0, MAP_SPA },
X
X { -1, ">", "Technical", ATR_cs_technical, -1, 0, MAP_TECHNICAL },
X { -1, "<", "Multinational" , ATR_cs_multinational
X , 0 , A_8bit_n, MAP_MULTINATIONAL },
X { -1, "%5", "Multinational", ATR_cs_multinational | ATR_cs_latin1
X , -1, A_8bit_n, MAP_MULTINATIONAL },
X
X { -1, "<", "Latin/1", ATR_cs_latin1 , 1 , A_8bit_n, MAP_LATIN1 }, /* Must be last -1 */
X { -1, "0", "Special", 0 , -1 , 0, MAP_SPECIAL } /* Must be last */
X
X};
X
X#define SET_NUM (sizeof (sets) / sizeof (struct one_set))
X
Xint find_set_by_name (CHAR *name, int is_8bit) {
X int i,result=-1;
X for (i = 0; i < SET_NUM; i++) {
X if (-1 != result && 0 == strcmp(sets[i].name,sets[result].name) &&
X HAVE(sets[i].flags)) result = -1;
X if (0 == strcasecmp(sets[i].name,Cs(name)) &&
X HAVE(sets[i].flags) &&
X (0 == (sets[i].area & A_8bit) || is_8bit)) result = i;
X }
X return result;
X}
X
Xint find_set_by_language (int language, int is_8bit) {
X int i,result=-1;
X for (i = 0; i < SET_NUM; i++) {
X if (-1 != result && 0 == strcmp(sets[i].name,sets[result].name) &&
X HAVE(sets[i].flags)) result = -1;
X if (sets[i].language == language &&
X HAVE(sets[i].flags) &&
X (0 == (sets[i].area & A_8bit) || is_8bit)) result = i;
X }
X return result;
X}
X
Xtypedef pattern[4];
X
X/* G0 -> national | national | ascii | ascii
X * G1 -> special | ascii | special | special
X * G2 -> ascii | | multinational | latin/1
X * G3 -> uk-ascii | | latin/1 |
X */
X
Xstatic pattern default_sets = { -1, (SET_NUM -1), -1, 0 };
Xstatic pattern used_sets = { -1, (SET_NUM -1), -1, -1 };
X
Xstatic void set_mode(char *frm, ...) {
X va_list args;
X CHAR buffer[MAX_OUTPUT+1],*ptr,*ptr2=NULL;
X CHAR sbuffer[MAX_OUTPUT+1];
X
X va_start(args,frm);
X vsprintf(Cs(buffer),frm,args);
X va_end(args);
X
X ptr = map_buffer(buffer,!personality_8bit,sbuffer,MAX_OUTPUT);
X print_to_terminal(ptr);
X
X if (DEBUG_TERM) {
X String S;
X S.buffer = ptr;
X S.len = strlen(Cs(ptr));
X S.alloced=0;
X char2names(&S,&ptr2);
X print_debug("To terminal: %s",ptr2);
X FREE(ptr2);
X }
X
X if (ptr != sbuffer) FREE(ptr);
X
X}
X
Xstatic void clear_attr_conflict(int *flag) {
X
X if (((*flag) & (FL_BOLD | FL_DIM)) == (FL_BOLD | FL_DIM))
X (*flag) &= ~(FL_BOLD | FL_DIM);
X
X}
X
Xint sum_fl_attr(int flags, int new) {
X flags |= new;
X clear_attr_conflict(&flags);
X flags |= new;
X return flags;
X}
X
Xstatic void set_attr(int flags) {
X CHAR buffer[32];
X char tmp[4];
X
X buffer[0] = '\0';
X
X#define ADD_VAL(p) { sprintf(tmp,"%d",p); \
X if ('\0' != buffer[0]) strcat(Cs(buffer),";"); \
X strcat(Cs(buffer),tmp); }
X
X clear_attr_conflict(&flags);
X
X if (0 == flags && 0 != FLAGS_set) {
X set_mode("%cm",CSI);
X FLAGS_set = 0;
X return;
X }
X
X if (-1 == FLAGS_set) { ADD_VAL(0); FLAGS_set = 0; }
X if (FLAGS_set & ~flags) {ADD_VAL(0); FLAGS_set = 0; }
X
X if (FL_BOLD & flags & ~FLAGS_set) { ADD_VAL(1); FLAGS_set |= FL_BOLD; }
X if (FL_DIM & flags & ~FLAGS_set) { ADD_VAL(2); FLAGS_set |= FL_DIM; }
X if (FL_UNDER & flags & ~FLAGS_set) { ADD_VAL(4); FLAGS_set |= FL_UNDER; }
X if (FL_REVERSE & flags & ~FLAGS_set) { ADD_VAL(7); FLAGS_set |= FL_REVERSE; }
X if (FL_BLINK & flags & ~FLAGS_set) { ADD_VAL(5); FLAGS_set |= FL_BLINK; }
X
X if ('\0' == buffer[0]) return;
X
X set_mode("%c%sm",CSI,buffer);
X
X#undef ADD_VAL
X}
X
X
Xstatic int set_banks(int GL, int GR) {
X int flag = 1;
X if (-1 != GL && GL != GL_set) switch(GL) {
X case 0: set_mode("%c",SI); GL_set = 0; break;
X case 1: set_mode("%c",SO); GL_set = 1; break;
X case 2:
X if (HAVE(ATR_cs_latin1) || HAVE(ATR_cs_multinational)) {
X set_mode("%cn",ESC); GL_set = 2; }
X else { set_mode("%cN",ESC); flag = 0; } break;
X case 3:
X if (HAVE(ATR_cs_latin1) || HAVE(ATR_cs_multinational)) {
X set_mode("%co",ESC); GL_set = 3; }
X else { set_mode("%cO",ESC); flag = 0; } break;
X }
X
X if (-1 != GR && GR != GR_set) switch(GR) {
X case 0:
X PANIC("Software failure: trying map GR to G0");
X break;
X case 1: set_mode("%c~",ESC); GR_set = 1; break;
X case 2: set_mode("%c}",ESC); GR_set = 2; break;
X case 3: set_mode("%c|",ESC); GR_set = 3; break;
X }
X return flag;
X}
X
Xstatic int X_set = -1, Y_set = -1;
Xstatic int X_hard = -1, Y_hard = -1;
X
Xstatic void print_viaset(int set, CHAR *buffer) {
X int i, bank = -1, left,len = strlen(Cs(buffer));
X int lo = 0, hi = 0, GL,GR,repeat,maxx=columns;
X CHAR *c;
X
X if (HAZ_MAY(HAZ_wrap) && Y_set == lines) maxx = columns-1;
X
X if (X_set > maxx) X_set = -1;
X if (-1 == X_set) return;
X left = maxx - X_set +1;
X
X for (i = 0; i < 4; i++) if (used_sets[i]==set) { bank = i; break; }
X if (-1 == bank) {
X PANIC("Charset not in any bank!");
X bank = 0;
X }
X for (c= buffer; *c; c++)
X if (*c & 128) hi = 1;
X else lo = 1;
X GL = lo ? bank : -1;
X GR = hi ? bank : -1;
X repeat = !set_banks(GL,GR);
X if (repeat) for (c=buffer;*c && left ;c++,set_banks(GL,GR)) {
X CHAR tbuffer[2];
X tbuffer[0] = *c; tbuffer[1] = 0;
X print_to_terminal(tbuffer);
X if (DEBUG_TERM) {
X print_debug("Text to terminal: %s",tbuffer);
X }
X X_set++; left--;
X } else if (left < len) {
X CHAR sbuffer[MAX_OUTPUT+1];
X CHAR *tbuffer = left < MAX_OUTPUT ? sbuffer : MALLOC(left+1);
X
X memcpy((void *)tbuffer,(void *)buffer,left);
X tbuffer[left] = '\0';
X print_to_terminal(tbuffer);
X
X if (tbuffer != sbuffer) FREE(tbuffer);
X
X if (DEBUG_TERM) {
X print_debug("Text to terminal: %s",tbuffer);
X }
X X_set += left;
X } else {
X print_to_terminal(buffer);
X if (DEBUG_TERM) {
X print_debug("Text to terminal: %s",buffer);
X }
X X_set += len;
X }
X if (HAZ_MAY(HAZ_wrap) && X_set == columns) {
X X_set = -1;
X Y_set = -1;
X } else if (X_set > columns) X_set = -1;
X}
X
Xstatic void change_banks(pattern char_sets) {
X int i;
X /* Set char sets */
X
X for (i = 0; i < 4; i++) if (-1 != char_sets[i]) {
X if (sets[char_sets[i]].area & A_96set) {
X if (i == 0)
X PANIC("Can't assign 96 char sets to bank 0 !");
X set_mode("%c%c%s",ESC,"\0-./"[i],sets[char_sets[i]].set);
X } else
X set_mode("%c%c%s",ESC,"()*+"[i],sets[char_sets[i]].set);
X }
X}
X
Xstatic void change_state(int setup,
X int personality,
X int multinational,
X int autowrap,
X int application,
X pattern char_sets,
X int legend,
X int new_line) {
X int use_latin1 = -1, i;
X static int latin1_prev = -1;
X
X for (i = 0; i < 4; i++) if (-1 != char_sets[i])
X if (-1 != sets[char_sets[i]].use_latin)
X use_latin1 = sets[char_sets[i]].use_latin;
X
X set_mode("%c%c%c!p",CAN,ST,CSI); /* shoft reset */
X
X if (HAVE(ATR_C1_controls)) {
X set_mode("%c[%d;%d\"p",ESC,vt_type,personality ? 2 : 1);
X
X if (-1 != multinational) {
X set_mode ("%c?42%c",CSI,multinational ? 'l' : 'h');
X personality_8bit = personality && multinational;
X } else
X personality_8bit = 0;
X
X } else {
X if (-1 != multinational)
X set_mode ("%c?42%c",CSI,multinational ? 'l' : 'h');
X personality_8bit = 0;
X }
X
X if (-1 != autowrap)
X set_mode ("%c?7%c",CSI,autowrap ? 'h' : 'l');
X if (-1 != application)
X set_mode ("%c?1%c",CSI,application ? 'h' : 'l' );
X set_mode ("%c?68%c",CSI,legend ? 'h' : 'l' );
X
X /* Insert mode off, New line mode off,
X Control excution on
X */
X set_mode ("%c4;13l",CSI);
X /* Local echo off */
X set_mode ("%c12h",CSI);
X
X if (-1 != new_line)
X set_mode("%c20%c",CSI,new_line ? 'h' : 'l');
X
X /* Set Latin/1 mode */
X if (-1 != use_latin1 && (latin1_prev != use_latin1 || setup)) {
X set_mode("%c%s%c",DCS,use_latin1 ? "1!uA" : "0!u%5" , ST);
X latin1_prev = use_latin1; /* for avoid garbage when suspending */
X } else if (-1 == use_latin1 && -1 != default_latin1 &&
X -1 != latin1_prev && latin1_prev != default_latin1) {
X set_mode("%c%s%c",DCS,default_latin1 ? "1!uA" : "0!u%5" , ST);
X latin1_prev = default_latin1;
X }
X
X change_banks(char_sets);
X}
X
Xstatic int Y1_set = -1;
Xstatic int Y2_set = -1;
Xstatic int Y1_region = -1;
Xstatic int Y2_region = -1;
X
Xstatic void set_region(int Y1, int Y2) {
X if (-1 == Y1 || -1 == Y2) {
X Y1 = 1; Y2 = lines;
X }
X if (DEBUG_CURSOR) {
X print_debug("Region to (Y1,Y2) = (%d,%d) from (%d,%d)",
X Y1,Y2,Y1_set,Y2_set);
X }
X if (Y1 != Y1_set || Y2 != Y2_set) {
X set_mode("%c%d;%dr",CSI,Y1,Y2);
X Y1_set = Y1; Y2_set = Y2;
X Y_set = -1;
X }
X}
X
Xstatic void update_region(void) {
X int Y1 = Y1_region, Y2=Y2_region;
X
X if (Y1 > lines) PANIC("Software failure/Region out of screen");
X if (Y2 > lines) Y2 = lines;
X
X if (-1 == Y1) {
X Y1 = -1; Y2 = -1;
X }
X set_region(Y1,Y2);
X}
X
Xstatic void check_region(void) {
X if (-1 != Y1_region || -1 != Y2_region)
X PANIC("Software error/Regions not supported here!");
X}
X
Xstatic int is_region(int line) {
X if (-1 == Y1_region || -1 == Y2_region) return 0;
X if (line < Y1_region || line > Y2_region)
X PANIC("Software error/Line out of region");
X return 1;
X}
X
Xvoid set_margins(int Y1, int Y2) {
X if (Y1 > Y2) PANIC("Software failure/set_margins: Y1 > Y2");
X
X Y1_region = Y1; Y2_region = Y2;
X}
X
Xstatic void set_down_line(int line) {
X if (DEBUG_CURSOR) {
X print_debug("Down line to %d from %d",line,down_line);
X }
X down_line = line;
X}
X
Xstatic void goto_XY(int X, int Y) {
X
X if (-1 == X_set && -1 == Y_set) {
X /* Origin mode off */
X set_mode ("%c?6l",CSI);
X }
X
X if (-1 == Y1_set || -1 == Y2_set)
X set_region(-1,-1);
X
X if (Y < Y1_set || Y > Y2_set)
X PANIC("Software error/Going out of region");
X
X if (DEBUG_CURSOR) {
X print_debug("Cursor to (X,Y) = (%d,%d) from (%d,%d)",X,Y,X_set,Y_set);
X }
X
X if (X == X_set && Y == Y_set) return;
X if (Y >= down_line) set_down_line(Y+1);
X
X if (Y == Y_set && X == X_set-1) {
X set_mode("%c",BS);
X X_set--;
X return;
X }
X
X if (1 == Y && 1 == X) {
X set_mode("%cH",CSI);
X X_set = 1;
X Y_set = 1;
X return;
X }
X
X if (Y == Y_set+1 && X == X_set) {
X /* IND is two characters in 7-bit output !! */
X if (personality_8bit || HAZ_MAY(HAZ_ONLCR) ||
X HAZ_MAY(HAZ_newline)) set_mode("%c",IND);
X else set_mode("%c",LF);
X Y_set++;
X return;
X }
X
X if (Y == Y_set+1 && X == 1 && -1 != X_set) {
X set_mode("%c",NEL);
X Y_set++;
X X_set = 1;
X return;
X }
X
X if (Y == Y_set && -1 != X_set) {
X if (1 == X) set_mode("%c",CR);
X else if (X < X_set) set_mode("%c%dD",CSI,X_set-X);
X else set_mode("%c%dC",CSI,X-X_set);
X X_set = X; return;
X }
X if (X == X_set && -1 != Y_set && Y_set >= Y1_set && Y_set <= Y2_set) {
X if (Y < Y_set) set_mode("%c%dA",CSI,Y_set-Y);
X else set_mode("%c%dB",CSI,Y-Y_set);
X Y_set = Y; return;
X }
X set_mode("%c%d;%dH",CSI,Y,X); X_set = X; Y_set = Y;
X}
X
Xstatic void update_hard(void) {
X set_region(-1,-1);
X if (-1 != X_hard && -1 != Y_hard &&
X X_hard <= columns && Y_hard <= lines) goto_XY(X_hard,Y_hard);
X}
X
Xvoid reset_terminal_state(void) {
X pager_state = 0;
X change_state(0,
X saved(saved_personality,default_personality),
X saved(saved_multinational,default_multinational),
X saved(saved_autowrap,default_autowrap),
X saved(saved_application,default_application),
X default_sets,
X saved(saved_legend,default_legend),
X saved(saved_newline,default_newline));
X set_banks(0,saved(saved_multinational,default_multinational) ? 2 : -1);
X set_attr(0);
X set_region(-1,-1);
X goto_XY(1,down_line <= lines ? down_line : lines);
X if (down_line > lines) set_mode("%c",LF);
X
X flush_error_buffer();
X}
X
Xstatic int fast_start = 0;
X
Xstatic void pass_2(void);
Xvoid get_terminal_state(void) {
X set_attr(FL_BLINK);
X print_to_terminal(rCs("\rInitializing terminal: "));
X set_attr(0);
X fast_start = init_from_kehpager_term();
X xterm_latin1_magic = (set_xterm_latin1 && is_xterm()) ||
X 2 == set_xterm_latin1;
X
X SET_PASS(1);
X
X if (!fast_start) {
X set_mode("%c%c%c[0c",CAN,ST,ESC); /* Ask terminal status report */
X } else {
X pass_2();
X }
X}
X
Xstatic void pass_3(void);
Xstatic void pass_2(void) {
X int tmp = personality_8bit;
X SET_PASS(2);
X if (force_mode > 0) {
X /* force 7 or 8bit */
X switch(force_mode) {
X case 1: /* force National */
X have_8bit_clean = 0;
X if (!HAVE(ATR_cs_ncr)) SUPPOSE(ATR_cs_ncr);
X if (-1 == default_multinational) default_multinational = 0;
X break;
X case 2: /* force Multinational */
X have_8bit_clean = 1;
X if (!HAVE(ATR_cs_multinational)) SUPPOSE(ATR_cs_multinational);
X if (!HAVE(ATR_G2)) SUPPOSE(ATR_G2);
X if (-1 == default_multinational) default_multinational = 1;
X break;
X }
X pass_3();
X } else if (xterm_latin1_magic) {
X /* force 8bit */
X have_8bit_clean = 1;
X if (!HAVE(ATR_cs_latin1)) SUPPOSE(ATR_cs_latin1);
X if (!HAVE(ATR_G2)) SUPPOSE(ATR_G2);
X if (-1 == default_multinational) default_multinational = 1;
X pass_3();
X } else if (!fast_start) {
X personality_8bit = 1;
X
X set_mode("%c0c",CSI);
X
X personality_8bit = tmp;
X } else {
X pass_3();
X }
X}
X
Xstatic CHAR *Boolean(int v) {
X char *S = "??"; switch(v) {
X case -1: S = "Undefined"; break;
X case 0: S = "False"; break;
X case 1: S = "True"; break; }
X return rCs(S);
X}
X
Xstatic CHAR *Number(int v) {
X static int B=0;
X static CHAR buffer[5][10];
X if (-1 == v) return rCs("Undefined");
X B = (B+1)%5;
X sprintf(Cs(buffer[B]),"%d",v);
X return buffer[B];
X}
X
Xvoid give_debug_page(void (*printer)(CHAR *line, int header)) {
X CHAR buffer[80];
X#define PV(T,v) { if (-1 == v) sprintf(Cs(buffer),"%-30s: Undefined",T); \
X else sprintf(Cs(buffer),"%-30s: %d",T,v); printer(buffer,0); }
X#define PV1(T,v,v1) { sprintf(Cs(buffer),"%-30s: %-15s Default: %s",T,\
X Number(v),Number(v1)); printer(buffer,0); }
X
X#define PB(T,v) { sprintf(Cs(buffer),"%-30s: %s",T,Boolean(v)); printer(buffer,0); }
X#define PB1(T,v,v1) { sprintf(Cs(buffer),"%-30s: %-15s Default: %s",T,\
X Boolean(v),Boolean(v1)); printer(buffer,0); }
X#define PF(T,v) { char *S = "??"; switch(v) { \
X case -1: S = "Undefined"; break; \
X default: S = sets[v].name; } \
X sprintf(Cs(buffer),"%-30s: %-1s",T,S); printer(buffer,0); }
X#define PMP(T,v) { CHAR *S = rCs("??"); switch(v) { \
X case -1: S = rCs("Undefined"); break; \
X default: S = map_name(v,0); } \
X sprintf(Cs(buffer),"%-30s: %-1s",T,S); printer(buffer,0); }
X#define MES(T,s) { CHAR *S = NULL; sprintf(Cs(buffer),"%-30s: ",T); \
X S = concat_text(S,buffer); S = concat_text(S,s); \
X printer(S,-32); FREE(S); FREE(s); }
X printer(rCs("Terminal state"),1);
X MES("Terminal type",terminal_type());
X printer(rCs("Features"),0);
X MES(" - basic",ftr_string(PRIM_attr));
X MES(" - optional",ftr_string(OPT_attr));
X MES(" - supposed",ftr_string(SUP_attr));
X MES(" - disabled",ftr_string(DISAB_attr));
X MES("Terminal/driver hazards",terminal_hazards());
X
X PB("8 bit clean", have_8bit_clean);
X PB("Use national mode", use_national);
X PB1("8 bit personality", personality_8bit,default_personality);
X PB("XTerm mode", xterm_latin1_magic);
X PV1("Keyboard language", keyboard_language,default_language);
X PMP("Keyboard charset",keyboard_charset);
X PF("Bank G0 font", used_sets[0]);
X PF("Bank G1 font", used_sets[1]);
X PF("Bank G2 font", used_sets[2]);
X PF("Bank G3 font", used_sets[3]);
X PV1("Lines",lines,def_lines);
X PV1("Columns",columns,def_columns);
X printer(rCs("Saved (or exit) terminal state"),1);
X PB1("8 bit characters", saved_multinational,default_multinational);
X PB1("8 bit personality", saved_personality,default_personality);
X PB1("Autowrap", saved_autowrap,default_autowrap);
X PB1("App. cursor keys", saved_application,default_application);
X PB1("Data processing keys", saved_legend,default_legend);
X PB1("Newline mode", saved_newline,default_newline);
X PF("Bank G0 font", default_sets[0]);
X PF("Bank G1 font", default_sets[1]);
X PF("Bank G2 font", default_sets[2]);
X PF("Bank G3 font", default_sets[3]);
X
X#undef MES
X#undef PMP
X#undef PV
X#undef PB
X#undef PB1
X#undef PF
X}
X
Xstatic int ASCII_set = 0; /* ASCII or it's superset */
X
Xstatic int find_ASCII(void) {
X int i;
X for (i = 0; i < 4; i++)
X if (-1 != used_sets[i] && (sets[used_sets[i]].area & A_ASCII))
X return used_sets[i];
X
X PANIC("Software failure/ASCII compatible font not found from any bank!");
X return 0;
X}
X
Xint keyboard_charset = MAP_ASCII;
X
Xvoid set_terminal_state(void) {
X if (terminal_type_pass == READY_PASS) {
X int i;
X int LANG = saved(saved_language,default_language);
X use_national = -1;
X
X if (HAZ_MAY(HAZ_national)) {
X use_national = 1;
X have_8bit_clean = 0;
X default_multinational = 0;
X }
X
X /* DEFAULT */
X default_sets[0] = saved(saved_multinational,default_multinational)
X ? find_set_by_name(rCs("ASCII"),0)
X : find_set_by_language(LANG,
X saved(saved_personality,default_personality));
X if (-1 == default_sets[0])
X default_sets[0] = find_set_by_name(rCs("ASCII"),0);
SHAR_EOF
echo "End of part 9"
echo "File control.c is continued in part 10"
echo "10" > s2_seq_.tmp
exit 0