home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso / altsrc / articles / 10825 < prev    next >
Internet Message Format  |  1994-07-11  |  63KB

  1. 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
  2. From: Kari.Hurtta@Helsinki.FI (Kari E. Hurtta)
  3. Newsgroups: alt.sources
  4. Subject: kehpager V1.2 (part 09/14)
  5. Followup-To: alt.sources.d
  6. Date: 9 Jul 1994 14:22:16 +0300
  7. Organization: University of Helsinki
  8. Lines: 2149
  9. Sender: hurtta@cc.Helsinki.FI
  10. Message-ID: <2vm198$hlp@plootu.Helsinki.FI>
  11. Reply-To: "Kari E. Hurtta" <Kari.Hurtta@Helsinki.FI>
  12. NNTP-Posting-Host: plootu.helsinki.fi
  13. Mime-Version: 1.0
  14. Content-Type: text/plain; charset=ISO-8859-1
  15. Content-Transfer-Encoding: 8bit
  16.  
  17. Title: kehpager V1.2 - Charset aware pager for VTxxx terminals
  18. Archive-Name: kehpager0120/part09
  19. Author: Kari E. Hurtta <Kari.Hurtta@Helsinki.FI>
  20. Part: 09/14
  21. Environment: Ansi C, SunOS 4.1.2 (OS/MP 4.1B), 4.1.3, 5.2, 5.3, 
  22.     HP-UX A.09.01, IRIX 4.0.5 (?), FreeBSD (?), NetBSD(?),
  23.     386BSD(?), VTxxx
  24.  
  25. #!/bin/sh
  26. # this is part 9 of a multipart archive
  27. # do not concatenate these parts, unpack them in order with /bin/sh
  28. # file content.c continued
  29. #
  30. CurArch=9
  31. if test ! -r s2_seq_.tmp
  32. then echo "Please unpack part 1 first!"
  33.      exit 1; fi
  34. ( read Scheck
  35.   if test "$Scheck" != $CurArch
  36.   then echo "Please unpack part $Scheck next!"
  37.        exit 1;
  38.   else exit 0; fi
  39. ) < s2_seq_.tmp || exit 1
  40. echo "x - Continuing file content.c"
  41. sed 's/^X//' << 'SHAR_EOF' >> content.c
  42. X  }
  43. X}
  44. X
  45. Xstatic void  ER_center_enter (content *CT, struct er_STACK *current) {
  46. X  if (CT->c.enriched.stack_top->nofill) return;
  47. X
  48. X  force_line_break(CT);
  49. X  current->justify = JUST_center;
  50. X}
  51. X
  52. Xstatic void  ER_center_exit (content *CT, struct er_STACK *current) {
  53. X  if (CT->c.enriched.stack_top->nofill) return;
  54. X
  55. X  force_line_break(CT);
  56. X}
  57. X
  58. Xstatic void  ER_flushleft_enter (content *CT, struct er_STACK *current) {
  59. X  if (CT->c.enriched.stack_top->nofill) return;
  60. X
  61. X  force_line_break(CT);
  62. X  current->justify = JUST_left;
  63. X}
  64. X
  65. Xstatic void  ER_flushleft_exit (content *CT, struct er_STACK *current) {
  66. X  if (CT->c.enriched.stack_top->nofill) return;
  67. X
  68. X  force_line_break(CT);
  69. X}
  70. X
  71. Xstatic void  ER_flushright_enter (content *CT, struct er_STACK *current) {
  72. X  if (CT->c.enriched.stack_top->nofill) return;
  73. X
  74. X  force_line_break(CT);
  75. X  current->justify = JUST_right;
  76. X}
  77. X
  78. Xstatic void  ER_flushright_exit (content *CT, struct er_STACK *current) {
  79. X  if (CT->c.enriched.stack_top->nofill) return;
  80. X
  81. X  force_line_break(CT);
  82. X}
  83. X
  84. Xstatic void  ER_flushboth_enter (content *CT, struct er_STACK *current) {
  85. X  if (CT->c.enriched.stack_top->nofill) return;
  86. X
  87. X  force_line_break(CT);
  88. X  current->justify = JUST_both;
  89. X}
  90. X
  91. Xstatic void  ER_flushboth_exit (content *CT, struct er_STACK *current) {
  92. X  if (CT->c.enriched.stack_top->nofill) return;
  93. X
  94. X  force_line_break(CT);
  95. X}
  96. X
  97. Xstatic void  ER_excerpt_enter (content *CT, struct er_STACK *current) {
  98. X  force_line_break(CT);
  99. X
  100. X  current->excerpt_count++;
  101. X  current->excerpt_flag = current->attrib_flag;;
  102. X}
  103. X
  104. Xstatic void  ER_excerpt_exit (content *CT, struct er_STACK *current) {
  105. X
  106. X  force_line_break(CT);
  107. X}
  108. X
  109. Xstatic void  RT_signature_enter (content *CT, struct er_STACK *current) {
  110. X  CHAR_IDX mapped[2];
  111. X  force_line_break(CT);
  112. X  do_line_break(CT);
  113. X
  114. X  current -> attrib_flag = FL_DIM;
  115. X  current->nofill = 1;
  116. X  current->justify = JUST_left;
  117. X  current->force_wrap = 0;
  118. X
  119. X  map_input(MAP_ASCII,2,rCs("--"),mapped);
  120. X
  121. X  print_to_window(CT->win,
  122. X          CT->last_line_X+1,
  123. X          CT->last_line_Y,
  124. X          CT->c.enriched.stack_top->attrib_flag,
  125. X          2,mapped);
  126. X  CT->last_line_X += 2;
  127. X
  128. X  CT->c.enriched.spc_count = 0;
  129. X
  130. X  do_line_break(CT);    
  131. X
  132. X}
  133. X
  134. Xstatic void  RT_signature_exit (content *CT, struct er_STACK *current) {
  135. X  force_line_break(CT);
  136. X  do_line_break(CT);
  137. X
  138. X}
  139. X
  140. X
  141. Xstatic void  RT_paragraph_enter (content *CT, struct er_STACK *current) {
  142. X  force_line_break(CT);
  143. X
  144. X  current -> pindent = 3;
  145. X
  146. X}
  147. X
  148. Xstatic void  RT_paragraph_exit (content *CT, struct er_STACK *current) {
  149. X  current -> pindent = 0;
  150. X  force_line_break(CT);
  151. X  do_line_break(CT);
  152. X  CT->c.enriched.no_nl = 1;  
  153. X}
  154. X
  155. X
  156. Xstatic void attrib_update(content *CT) {
  157. X  int A,I,S,J,E1,E2,W;
  158. X
  159. X  get_line_status(CT->win,CT->last_line_Y,&A,&I,&S,&J,&E1,&E2,&W);
  160. X  if (A != CT->c.enriched.stack_top->pindent ||
  161. X      I != CT->c.enriched.stack_top->indent ||
  162. X      S != CT->c.enriched.stack_top->submargin ||
  163. X      E1 != CT->c.enriched.stack_top->excerpt_count ||
  164. X      E2 != CT->c.enriched.stack_top->excerpt_flag ||
  165. X      W != CT->c.enriched.stack_top->force_wrap) {
  166. X    A = CT->c.enriched.stack_top->pindent;
  167. X    I = CT->c.enriched.stack_top->indent;
  168. X    S = CT->c.enriched.stack_top->submargin;
  169. X    E1 = CT->c.enriched.stack_top->excerpt_count;
  170. X    E2 = CT->c.enriched.stack_top->excerpt_flag;
  171. X    W = CT->c.enriched.stack_top->force_wrap;
  172. X    set_line_status(CT->win,CT->last_line_Y,A,I,S,J,E1,E2,W);
  173. X  }
  174. X}
  175. X
  176. Xstatic void  RT_superscript_enter (content *CT, struct er_STACK *current) {
  177. X
  178. X  if (0 == CT->last_line_X)
  179. X    attrib_update(CT);
  180. X  print_to_window(CT->win,
  181. X          CT->last_line_X+1,
  182. X          CT->last_line_Y,
  183. X          CT->c.enriched.stack_top->attrib_flag,
  184. X          1,&CH_SUP_M);
  185. X  CT->last_line_X++;
  186. X  CT->c.enriched.spc_count = 0;
  187. X}
  188. X
  189. Xstatic void  RT_superscript_exit (content *CT, struct er_STACK *current) {
  190. X
  191. X  if (0 == CT->last_line_X)
  192. X    attrib_update(CT);
  193. X  print_to_window(CT->win,
  194. X          CT->last_line_X+1,
  195. X          CT->last_line_Y,
  196. X          CT->c.enriched.stack_top->attrib_flag,
  197. X          1,&CH_END_M);
  198. X  CT->last_line_X++;
  199. X  CT->c.enriched.spc_count = 0;
  200. X}
  201. X
  202. X
  203. Xstatic void  RT_subscript_enter (content *CT, struct er_STACK *current) {
  204. X
  205. X  if (0 == CT->last_line_X)
  206. X    attrib_update(CT);
  207. X  print_to_window(CT->win,
  208. X          CT->last_line_X+1,
  209. X          CT->last_line_Y,
  210. X          CT->c.enriched.stack_top->attrib_flag,
  211. X          1,&CH_SUB_M);
  212. X  CT->last_line_X++;
  213. X  CT->c.enriched.spc_count = 0;
  214. X}
  215. X
  216. Xstatic void  RT_subscript_exit (content *CT, struct er_STACK *current) {
  217. X
  218. X  if (0 == CT->last_line_X)
  219. X    attrib_update(CT);
  220. X  print_to_window(CT->win,
  221. X          CT->last_line_X+1,
  222. X          CT->last_line_Y,
  223. X          CT->c.enriched.stack_top->attrib_flag,
  224. X          1,&CH_END_M);
  225. X  CT->last_line_X++;
  226. X  CT->c.enriched.spc_count = 0;
  227. X}
  228. X
  229. X#define ER_main_f 0
  230. X#define ER_unknown_f 1
  231. X#define ER_verbatim_f 2
  232. X#define RT_comment_f 3
  233. X
  234. X#define M_er 1
  235. X#define M_rt 2
  236. X
  237. Xstatic struct ER_functions {
  238. X  int mode;
  239. X  char *name;
  240. X  ER_function *enter_region;
  241. X  ER_function *exit_region;
  242. X} ER_functions[] = {
  243. X  { M_er|M_rt,  NULL,       ER_main_enter,      ER_main_exit },
  244. X  { M_er|M_rt,  NULL,       ER_unknown_enter,   ER_unknown_exit },
  245. X  { M_er,       "Verbatim", ER_verbatim_enter,  ER_verbatim_exit },
  246. X  { M_rt,       "Comment",  RT_comment_enter,   RT_comment_exit },
  247. X
  248. X  { M_er|M_rt,  "Bold",     ER_bold_enter,      ER_bold_exit },
  249. X  { M_er|M_rt,  "Italic",   ER_underline_enter, ER_underline_exit },
  250. X  { M_er|M_rt,  "Underline",ER_underline_enter, ER_underline_exit },
  251. X  { M_er|M_rt,  "Indent",   ER_indent_enter,    ER_indent_exit },
  252. X  { M_er|M_rt,  "IndentRight",ER_indentright_enter,ER_indentright_exit },
  253. X  { M_er,       "Param",    ER_param_enter,     ER_param_exit },
  254. X  { M_er,       "NoFill",   ER_nofill_enter,    ER_nofill_exit },
  255. X  { M_er|M_rt,  "Center",   ER_center_enter,    ER_center_exit },
  256. X  { M_er|M_rt,  "FlushLeft",ER_flushleft_enter, ER_flushleft_exit },
  257. X  { M_er|M_rt,  "FlushRight",ER_flushright_enter,ER_flushright_exit },
  258. X  { M_er,       "FlushBoth",ER_flushboth_enter, ER_flushboth_exit },
  259. X  { M_er|M_rt,  "Excerpt",  ER_excerpt_enter,   ER_excerpt_exit },
  260. X  { M_rt,       "Paragraph",RT_paragraph_enter, RT_paragraph_exit },
  261. X  { M_rt,       "Signature",RT_signature_enter, RT_signature_exit },
  262. X  { M_rt,       "Heading",  RT_reject_enter,    RT_reject_exit },
  263. X  { M_rt,       "Footing",  RT_reject_enter,    RT_reject_exit },
  264. X  { M_rt,       "Subscript", RT_subscript_enter, RT_subscript_exit },
  265. X  { M_rt,       "Superscript",RT_superscript_enter,RT_superscript_exit },
  266. X
  267. X};
  268. X
  269. Xstatic void push_er_stack(content *CT, int fnc,CHAR *main) {
  270. X  struct er_STACK *prev = CT->c.enriched.stack_top;
  271. X  struct er_STACK *new = (struct er_STACK *) MALLOC(sizeof (struct er_STACK));
  272. X  CHAR *ptr = main ? concat_text(NULL,main) : NULL;
  273. X
  274. X  if (DEBUG_ENRICHED) {
  275. X    print_debug("ENRICHED/RICHTEXT: -> %d: %s",fnc,Cs(main) ? Cs(main) : "");
  276. X  }
  277. X
  278. X  new-> previous = prev;
  279. X  new-> er_function = fnc;
  280. X  new-> name = ptr;
  281. X  new-> cs = NULL_chtable;
  282. X  if (prev) {    
  283. X    copy_table(&(new -> cs),&(prev -> cs));
  284. X    new -> indent = prev -> indent;
  285. X    new -> pindent = prev -> pindent;
  286. X    new -> submargin = prev -> submargin;
  287. X    new -> param = prev -> param;
  288. X    new -> justify = prev -> justify;
  289. X    new -> nofill = prev -> nofill;
  290. X    new -> excerpt_count = prev -> excerpt_count;
  291. X    new -> excerpt_flag = prev -> excerpt_flag;
  292. X    new -> force_wrap = prev -> force_wrap;
  293. X    new -> attrib_flag = prev -> attrib_flag;
  294. X  } else {
  295. X    copy_table(&(new -> cs),&(CT -> cs));
  296. X    new -> indent = 0;
  297. X    new -> pindent = 0;
  298. X    new -> submargin = 0;
  299. X    new -> param = 0;
  300. X    new -> justify = enable_fulljust ? JUST_both : JUST_left;
  301. X    new -> nofill = 0;
  302. X    new -> excerpt_count = 0;
  303. X    new -> excerpt_flag = 0;
  304. X    new -> force_wrap = 1;
  305. X    new -> attrib_flag = 0;
  306. X  }
  307. X  CT->c.enriched.stack_top = new;
  308. X  if (2 == CT->c.enriched.stack_top->param && fnc != RT_comment_f) {
  309. X    if (DEBUG_ENRICHED) 
  310. X      print_debug("ENRICHED/RICHTEXT -> richtext comment: enter not executed");
  311. X
  312. X  } else {
  313. X    ER_functions[fnc].enter_region(CT,new);
  314. X  }
  315. X}
  316. X
  317. Xstatic void pop_er_stack(content *CT) {
  318. X  struct er_STACK *current = CT->c.enriched.stack_top;
  319. X  struct er_STACK *prev = current->previous;
  320. X
  321. X  if (DEBUG_ENRICHED) {
  322. X    print_debug("ENRICHED/RICHTEXT <- %d: %s",
  323. X        current->er_function,Cs(current->name) ? 
  324. X        Cs(current->name) : "");
  325. X  }
  326. X
  327. X
  328. X  if (2 == CT->c.enriched.stack_top->param && 
  329. X      current->er_function != RT_comment_f) {
  330. X    if (DEBUG_ENRICHED) 
  331. X      print_debug("ENRICHED/RICHTEXT <- richtext comment: exit not executed");
  332. X
  333. X  } else {
  334. X    ER_functions[current->er_function].exit_region(CT,current);
  335. X  }
  336. X  close_table(&(current->cs));
  337. X  if (current->name) FREE(current->name);
  338. X  FREE((void *)current);
  339. X  CT->c.enriched.stack_top = prev;
  340. X}
  341. X
  342. Xstatic void unroll_er_stack(content *CT, int fnc) {
  343. X  while(CT->c.enriched.stack_top->er_function != fnc &&
  344. X    CT->c.enriched.stack_top->previous != NULL)
  345. X    pop_er_stack(CT);
  346. X}
  347. X
  348. Xstatic void unroll_er_stack_n(content *CT, CHAR *fnc) {
  349. X  while((!CT->c.enriched.stack_top->name ||
  350. X     0 != strcasecmp(Cs(CT->c.enriched.stack_top->name),Cs(fnc))) &&
  351. X    CT->c.enriched.stack_top->previous != NULL)
  352. X    pop_er_stack(CT);
  353. X}
  354. X
  355. Xstatic int ER_basic_handle(content *CT,int len, CHAR *buffer,int flush) {
  356. X  CT->c.enriched.no_nl = 0;
  357. X  if (1 < CT->c.enriched.stack_top->param) {
  358. X    /* richtext comment or heading/footing - ignore */
  359. X
  360. X    return len;
  361. X  } else if (CT->c.enriched.stack_top->param) {
  362. X    /* param not currently stored */
  363. X
  364. X    /* mast also add handling for multibyte text to here !!! */
  365. X
  366. X    return len;
  367. X  } else {
  368. X    int ret,mlen;
  369. X    CHAR_IDX *mapped = (CHAR_IDX *)MALLOC(len * sizeof(CHAR_IDX));
  370. X    
  371. X    if (CT->last_line_X == 0) {
  372. X      attrib_update(CT);
  373. X    }
  374. X    
  375. X    /* in richtext (but not in enriched) changin of charset is possible */
  376. X    ret=map2_input(&(CT->c.enriched.stack_top->cs),len,buffer,
  377. X           &mlen,mapped,CT->multi,flush); 
  378. X    if (0 == ret) {
  379. X      CT->multi = !CT->multi;
  380. X      FREE(mapped);
  381. X      return 0;
  382. X    }
  383. X    else if (ret <0) { 
  384. X      StrSet2(&(CT->multi_buffer),len,buffer);
  385. X      FREE(mapped);
  386. X      return -1;
  387. X    } 
  388. X    
  389. X    print_to_window(CT->win,
  390. X            CT->last_line_X+1,
  391. X            CT->last_line_Y,
  392. X            CT->c.enriched.stack_top->attrib_flag,
  393. X            mlen,mapped);
  394. X    CT->last_line_X += mlen;
  395. X    CT->c.enriched.spc_count = 0;
  396. X    
  397. X    FREE(mapped);
  398. X    return ret;
  399. X  }
  400. X}
  401. X
  402. Xstatic int ER_handle_multi(content *CT,int len, CHAR *buffer,int flush) {
  403. X  int ret = ER_basic_handle(CT,len,buffer,flush);
  404. X  if (ret < 0) return len;
  405. X  return ret;
  406. X}
  407. X
  408. X
  409. Xstatic int handle_common(content *CT,int len, CHAR *buffer,
  410. X             CHAR **ch1, CHAR **ch2, 
  411. X             int (*handle_it)(content *CT,CHAR ch),
  412. X             int (*handle_sp)(content *CT,CHAR ch)) {
  413. X  CHAR *ch3;
  414. X  
  415. X  for ((*ch2) = (*ch1); 
  416. X       (*ch2) < buffer + len && handle_it(CT,*(*ch2)); 
  417. X       (*ch2)++);
  418. X  
  419. X  ch3 = (*ch2);
  420. X  for (; (*ch2) < buffer + len && !handle_sp(CT,*(*ch2)); (*ch2)++);
  421. X  
  422. X  if ((*ch2) != ch3) {
  423. X    int ret = ER_basic_handle(CT,(*ch2)-ch3,ch3,0);
  424. X    if (ret < 0) { CrashMe ("multibyte store with no multi data"); }
  425. X    if (0 == ret) return 0;
  426. X    (*ch2) = ch3 + ret;
  427. X  }    
  428. X  return 1;
  429. X}
  430. X
  431. Xstatic void add_space(content *CT) {
  432. X  if (CT->last_line_X == 0) {
  433. X    attrib_update(CT);
  434. X  }
  435. X  CT->c.enriched.spc_count++;
  436. X  if (CT->c.enriched.spc_count == 1 || CT->c.enriched.verbatim ||
  437. X      CT->c.enriched.stack_top->nofill)
  438. X    print_to_window(CT->win,CT->last_line_X+1,
  439. X            CT->last_line_Y,
  440. X            CT->c.enriched.stack_top->attrib_flag,
  441. X            1,&CH_SPC);
  442. X  else 
  443. X    print_to_window(CT->win,CT->last_line_X+1,
  444. X            CT->last_line_Y,
  445. X            CT->c.enriched.stack_top->attrib_flag,
  446. X            1,&CH_SPC_C);
  447. X  CT->last_line_X++;
  448. X  CT->c.enriched.no_nl = 0;
  449. X}
  450. X
  451. X/* Enriched content-type --------------------------------------------------- */
  452. X
  453. Xstatic int er_special_char(content *CT,CHAR ch) {
  454. X  if (' ' == ch) return 1;
  455. X  if (StrLEN(CT->c.enriched.cmd_buffer) > 1) return 0;
  456. X  if ('<' == ch) return 1;
  457. X  return 0;
  458. X}
  459. X
  460. Xstatic int cmd_handle(content *CT,CHAR ch) {
  461. X  if (0 == StrLEN(CT->c.enriched.cmd_buffer)) return 0;
  462. X  if (1 == StrLEN(CT->c.enriched.cmd_buffer) && '<' == ch) return 0;
  463. X  if (1 == StrLEN(CT->c.enriched.cmd_buffer) && '/' == ch) {      
  464. X    StrAdd(&(CT->c.enriched.cmd_buffer),ch);
  465. X    return 1;
  466. X  }
  467. X  if (isdigit(ch) || ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')
  468. X      || '-' == ch) {
  469. X    StrAdd(&(CT->c.enriched.cmd_buffer),ch);
  470. X    return 1;
  471. X  }
  472. X
  473. X
  474. X  if (CT->c.enriched.verbatim &&  '>' == ch &&
  475. X      0 == strncasecmp("</verbatim",
  476. X               Cs(StrPTR(CT->c.enriched.cmd_buffer)),10)) {
  477. X
  478. X    if (DEBUG_ENRICHED) {
  479. X      print_debug("ENRICHED token: </verbatim>");
  480. X    }
  481. X
  482. X
  483. X      unroll_er_stack(CT,ER_verbatim_f);
  484. X      if (CT->c.enriched.stack_top->previous != NULL)
  485. X    pop_er_stack(CT);
  486. X
  487. X    StrFree(&(CT->c.enriched.cmd_buffer));
  488. X    return 1;
  489. X  }
  490. X  
  491. X  if (!CT->c.enriched.verbatim && '>' == ch) {
  492. X    CHAR *ptr;
  493. X    int neg = 0;
  494. X
  495. X    ptr = StrPTR(CT->c.enriched.cmd_buffer);
  496. X
  497. X    if (DEBUG_ENRICHED) {
  498. X      print_debug("ENRICHED token: %s>",ptr);
  499. X    }
  500. X    
  501. X    ptr++;
  502. X
  503. X    if ('/' == *ptr) {
  504. X      neg = 1;
  505. X      ptr++;
  506. X    }
  507. X
  508. X    if (neg) {
  509. X      unroll_er_stack_n(CT,ptr);
  510. X      if (CT->c.enriched.stack_top->previous != NULL)
  511. X    pop_er_stack(CT);
  512. X    } else {
  513. X      int fnc = ER_unknown_f,i;
  514. X      
  515. X      for (i = 0; i < sizeof(ER_functions) / sizeof(struct ER_functions); i++)
  516. X    if ((ER_functions[i].mode & M_er) == M_er && 
  517. X        ER_functions[i].name &&
  518. X        0 == strcasecmp(Cs(ptr),ER_functions[i].name)) 
  519. X      fnc = i;
  520. X      
  521. X      push_er_stack(CT,fnc,ptr);
  522. X    }
  523. X    
  524. X    StrFree(&(CT->c.enriched.cmd_buffer));
  525. X    return 1;
  526. X  }
  527. X
  528. X  flush_cmd_buffer(CT);
  529. X  return 0;
  530. X}
  531. X
  532. Xstatic int ER_handle(content *CT,int len, CHAR *buffer) {
  533. X  CHAR *ch1,*ch2;
  534. X
  535. X  set_win_prompt(-1,-1,-1);
  536. X
  537. X  if (1 == CT->c.enriched.nl_count) {
  538. X    add_space(CT); 
  539. X  }
  540. X  CT->c.enriched.nl_count = 0;
  541. X
  542. X  for (ch1 = buffer; ch1 < buffer + len; ch1 = ch2) {
  543. X
  544. X    if (!handle_common(CT,len,buffer,&ch1,&ch2,cmd_handle,er_special_char))
  545. X      break;
  546. X       
  547. X    for (;ch2 < buffer + len && er_special_char(CT,*ch2); ch2++) {
  548. X      if (' ' == *ch2) add_space(CT);
  549. X      else if (StrLEN(CT->c.enriched.cmd_buffer)) {
  550. X    if (CT->c.enriched.stack_top->param) {
  551. X      /* param not currently stored */
  552. X
  553. X      StrFree(&(CT->c.enriched.cmd_buffer));
  554. X    } else {
  555. X      if (CT->c.enriched.verbatim) 
  556. X        StrAdd(&(CT->c.enriched.cmd_buffer),'<');
  557. X      flush_cmd_buffer(CT);
  558. X    }
  559. X      } else StrAdd(&(CT->c.enriched.cmd_buffer),'<');
  560. X    }
  561. X    scroll_it(CT->win); /* for autowrap */
  562. X  }
  563. X  return ch1-buffer;
  564. X}
  565. X
  566. Xstatic void ER_handle_eoln(content *CT) {
  567. X  CT->c.enriched.no_nl = 0;
  568. X
  569. X  if (CT->c.enriched.verbatim || CT->c.enriched.stack_top->nofill) {
  570. X    do_line_break(CT);
  571. X    return;
  572. X  }
  573. X
  574. X  if (CT->c.enriched.stack_top->param) {
  575. X    /* Storing of param not implemented */
  576. X    return;
  577. X  }
  578. X
  579. X  CT->c.enriched.nl_count++;
  580. X  if (CT->c.enriched.nl_count > 1) {
  581. X    do_line_break(CT);
  582. X  }
  583. X}
  584. X
  585. Xstatic void ER_init (content *CT) {
  586. X  CT->c.enriched.magic = CT_enriched;
  587. X  StrInit(&(CT->c.enriched.cmd_buffer),60);
  588. X  CT->c.enriched.nl_count = 0;
  589. X  CT->c.enriched.spc_count = 1;   /* eats spaces also in beginning of line */
  590. X  CT->c.enriched.no_nl = 0;
  591. X  CT->c.enriched.verbatim = 0;
  592. X  CT->c.enriched.stack_top = NULL;
  593. X  push_er_stack(CT,ER_main_f,NULL);
  594. X}
  595. X
  596. Xstatic void ER_exit(content *CT) {
  597. X
  598. X  if(StrLEN(CT->c.enriched.cmd_buffer))
  599. X    flush_cmd_buffer(CT);
  600. X  StrFree(&(CT->c.enriched.cmd_buffer));
  601. X
  602. X  justification_update(CT);
  603. X
  604. X  unroll_er_stack(CT,ER_main_f);
  605. X  pop_er_stack(CT);
  606. X  if (NULL != CT->c.enriched.stack_top) {
  607. X    CrashMe("ER_exit: stack not empty - FATAL error ");
  608. X  }
  609. X  CT->c.enriched.magic = -1;
  610. X}
  611. X
  612. Xstatic void ER_update(content *CT) {
  613. X  justification_update(CT);
  614. X}
  615. X
  616. X/* Richtext content-type --------------------------------------------- */
  617. X
  618. Xstatic int rt_special_char(content *CT,CHAR ch) {
  619. X  if (' ' == ch) return 1;
  620. X  if (StrLEN(CT->c.enriched.cmd_buffer) > 0) return 0;
  621. X  if ('<' == ch) return 1;
  622. X  return 0;
  623. X}
  624. X
  625. Xstatic int rt_cmd_handle(content *CT,CHAR ch) {
  626. X  if (0 == StrLEN(CT->c.enriched.cmd_buffer)) return 0;
  627. X
  628. X  if (1 == StrLEN(CT->c.enriched.cmd_buffer) && '/' == ch) {      
  629. X    StrAdd(&(CT->c.enriched.cmd_buffer),ch);
  630. X    return 1;
  631. X  }
  632. X  if (isdigit(ch) || ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')
  633. X      || '-' == ch) {
  634. X    StrAdd(&(CT->c.enriched.cmd_buffer),ch);
  635. X    return 1;
  636. X  }
  637. X
  638. X  if ('>' == ch) {
  639. X    CHAR *ptr;
  640. X    int neg = 0;
  641. X
  642. X    ptr = StrPTR(CT->c.enriched.cmd_buffer);
  643. X
  644. X
  645. X    if (DEBUG_ENRICHED) {
  646. X      print_debug("RICHTEXT token: %s>",ptr);
  647. X    }
  648. X    
  649. X    ptr++;
  650. X
  651. X    if (0 == strcasecmp(Cs(ptr),"lt")) {
  652. X      if (CT->last_line_X == 0) 
  653. X    attrib_update(CT);
  654. X
  655. X      print_to_window(CT->win,CT->last_line_X+1,
  656. X              CT->last_line_Y,
  657. X              CT->c.enriched.stack_top->attrib_flag,
  658. X              1,&CH_LT);
  659. X      CT->last_line_X++;
  660. X      CT->c.enriched.spc_count = 0;
  661. X      
  662. X      StrFree(&(CT->c.enriched.cmd_buffer));
  663. X      return 1;
  664. X      
  665. X    } else if (0 == strcasecmp(Cs(ptr),"nl") || 
  666. X           0 == strcasecmp(Cs(ptr),"np")) {
  667. X      do_line_break(CT);
  668. X      CT->c.enriched.no_nl = 1;      
  669. X
  670. X      if (0 == strcasecmp(Cs(ptr),"np")) {
  671. X    print_to_window(CT->win,
  672. X            CT->last_line_X+1,
  673. X            CT->last_line_Y,
  674. X            CT->c.enriched.stack_top->attrib_flag,
  675. X            1,&CH_NP);
  676. X    CT->last_line_X += 1;
  677. X      }
  678. X
  679. X      StrFree(&(CT->c.enriched.cmd_buffer));
  680. X      return 1;
  681. X    }
  682. X    CT->c.enriched.no_nl = 0;      
  683. X
  684. X    if ('/' == *ptr) {
  685. X      neg = 1;
  686. X      ptr++;
  687. X    }
  688. X
  689. X    if (neg) {
  690. X      unroll_er_stack_n(CT,ptr);
  691. X      if (CT->c.enriched.stack_top->previous != NULL)
  692. X    pop_er_stack(CT);
  693. X    } else {
  694. X      int fnc = ER_unknown_f,i;
  695. X      
  696. X      for (i = 0; i < sizeof(ER_functions) / sizeof(struct ER_functions); i++)
  697. X    if ((ER_functions[i].mode & M_rt) == M_rt && 
  698. X        ER_functions[i].name &&
  699. X        0 == strcasecmp(Cs(ptr),ER_functions[i].name)) 
  700. X      fnc = i;
  701. X
  702. X      push_er_stack(CT,fnc,ptr);
  703. X
  704. X      if (fnc == ER_unknown_f) {
  705. X    int map = find_mime_map(ptr);
  706. X    if (-1 != map) {
  707. X      if (!open_table(&(CT->c.enriched.stack_top->cs),map,NULL))
  708. X        copy_table(&(CT->c.enriched.stack_top->cs), &(CT->cs));
  709. X    }
  710. X      }
  711. X    }
  712. X    
  713. X    StrFree(&(CT->c.enriched.cmd_buffer));
  714. X    return 1;
  715. X  }
  716. X  
  717. X  flush_cmd_buffer(CT);
  718. X  return 0;
  719. X
  720. X}
  721. X
  722. Xstatic void RT_init (content *CT) {
  723. X  CT->c.enriched.magic = CT_richtext;
  724. X  StrInit(&(CT->c.enriched.cmd_buffer),40);
  725. X  CT->c.enriched.nl_count = 0;
  726. X  CT->c.enriched.spc_count = 1;  /* eat spacesc also in beginning of line */
  727. X  CT->c.enriched.no_nl = 0;
  728. X  CT->c.enriched.verbatim = 0;
  729. X  CT->c.enriched.stack_top = NULL;
  730. X  push_er_stack(CT,ER_main_f,NULL);
  731. X}
  732. X
  733. Xstatic void RT_handle_eoln(content *CT) {
  734. X  if (CT->c.enriched.stack_top->param) return;
  735. X  if (!CT->c.enriched.no_nl) add_space(CT); 
  736. X  CT->c.enriched.no_nl = 0;
  737. X}
  738. X
  739. Xstatic int RT_handle(content *CT,int len, CHAR *buffer) {
  740. X  CHAR *ch1,*ch2;
  741. X
  742. X  set_win_prompt(-1,-1,-1);
  743. X
  744. X  for (ch1 = buffer; ch1 < buffer + len; ch1 = ch2) {
  745. X
  746. X    if (!handle_common(CT,len,buffer,&ch1,&ch2,rt_cmd_handle,rt_special_char))
  747. X      break;
  748. X       
  749. X    for (;ch2 < buffer + len && rt_special_char(CT,*ch2); ch2++) {
  750. X      if (' ' == *ch2) add_space(CT);
  751. X      else StrAdd(&(CT->c.enriched.cmd_buffer),'<');
  752. X    }
  753. X    scroll_it(CT->win); /* for autowrap */
  754. X  }
  755. X  return ch1-buffer;
  756. X}
  757. X
  758. X
  759. X/* NULL content-type ------------------------------------------------- */
  760. X
  761. Xstatic void NL_init (content *CT) {
  762. X  CrashMe("NL_init");
  763. X}
  764. X
  765. Xstatic void NL_handle_eoln(content *CT) {
  766. X  CrashMe("NL_handle_eoln");
  767. X}
  768. X
  769. X
  770. Xstatic void NL_exit(content *CT) {
  771. X  CrashMe("NL_exit");
  772. X}
  773. X
  774. Xstatic void NL_update(content *CT) {
  775. X  CrashMe("NL_update");
  776. X}
  777. X
  778. Xstatic int NL_handle(content *CT,int len, CHAR *buffer) {
  779. X  CrashMe("NL_handle");
  780. X}
  781. X
  782. Xstatic int NL_handle_multi(content *CT,int len, CHAR *buffer, int flush) {
  783. X  CrashMe("NL_handle_multi");
  784. X}
  785. X
  786. X/* ------------------------------------------------------------------- */
  787. X
  788. Xstatic content content_models[] = {
  789. X  /* CT_plain */
  790. X  { CT_plain, NULL, -1, -1, 0,
  791. X      PL_init, PL_handle, PL_handle_multi,
  792. X      PL_handle_eoln, PL_exit, PL_update, 1, 0 },
  793. X  /* CT_terminal */
  794. X  { CT_terminal, NULL, -1, -1, 0,
  795. X      TR_init, TR_handle, TR_handle_multi,
  796. X      TR_handle_eoln, TR_exit, TR_update, 1, 0 },
  797. X  /* CT_enriched */
  798. X  { CT_enriched, NULL, -1, -1, 0,
  799. X      ER_init, ER_handle, ER_handle_multi,
  800. X      ER_handle_eoln, ER_exit, ER_update, 1, 0 },
  801. X  /* CT_richtext */
  802. X  { CT_richtext, NULL, -1, -1, 0,
  803. X      RT_init, RT_handle, ER_handle_multi,
  804. X      RT_handle_eoln, ER_exit, ER_update, 1, 0 },
  805. X};
  806. X
  807. Xconst content NULL_content = 
  808. X{ -1, NULL, -1, 0, 0,
  809. X    NL_init, NL_handle, NL_handle_multi,
  810. X    NL_handle_eoln, NL_exit, NL_update, 1, 0 };
  811. X
  812. Xstatic struct CN {
  813. X  int mime;
  814. X  char *name;
  815. X  int content;
  816. X} ct_names[] = {
  817. X  { 0,  "Terminal",     CT_terminal },
  818. X  { 0,  "Plain",        CT_plain },
  819. X  { 1,  "Text/Plain",   CT_plain },
  820. X  { 0,  "Enriched",     CT_enriched },
  821. X  { 1,  "Text/Enriched",CT_enriched },
  822. X  { 0,  "Richtext",     CT_richtext },
  823. X  { 1,  "Text/Richtext",CT_richtext },
  824. X
  825. X  { -1, NULL, -1 }
  826. X};
  827. X
  828. Xint search_content(CHAR *name,int mime) {
  829. X  int i;
  830. X  for (i=0; NULL != ct_names[i].name; i++)
  831. X    if ((!mime || ct_names[i].mime) &&
  832. X    0 == strcasecmp(Cs(name),ct_names[i].name))
  833. X      return ct_names[i].content;
  834. X  return -1;
  835. X}
  836. X
  837. XCHAR *content_name(int content, int mime) {
  838. X  int i;
  839. X  for (i=0; NULL != ct_names[i].name; i++)
  840. X    if (mime == ct_names[i].mime &&
  841. X    content == ct_names[i].content)
  842. X      return rCs(ct_names[i].name);
  843. X  return rCs("Unknown");
  844. X}
  845. X
  846. XINLINE static void turn_flag(content *CT) {
  847. X  if (!CT->cs_flag) {
  848. X    StrInit(&(CT->multi_buffer),10);
  849. X    CT->cs=NULL_chtable;
  850. X    CT->cs_flag=1;
  851. X  }
  852. X}
  853. X
  854. Xvoid init_content(int content_type,int *fp,int win, 
  855. X          int cs, CHAR *cs_param,
  856. X          content *CT) {
  857. X  *CT = content_models[content_type];
  858. X  turn_flag(CT);
  859. X  CT->fp = fp;
  860. X  CT->win=win;
  861. X  if (!open_table(&(CT->cs),cs,cs_param)) {
  862. X    int ok = 0;
  863. X    if (cs_param) {
  864. X      if (open_table(&(CT->cs),cs,NULL)) {
  865. X    print_notify("(%s) Unsupported charset: %s; %s\n"
  866. X             "     Using charset: %s",
  867. X             prog,map_name(cs,0),cs_param,
  868. X             map_name(cs,0));
  869. X    ok = 1;    
  870. X      } else {
  871. X    print_notify("(%s) Unsupported charset: %s; %s\n"
  872. X             "\tUsing charset: %s",
  873. X             prog,map_name(cs,0),cs_param,
  874. X             map_name(MAP_ASCII,0));
  875. X      }
  876. X    }
  877. X    else
  878. X      print_notify("(%s) Unsupported charset: %s\n",
  879. X           "\tUsing charset: %s",
  880. X           prog,map_name(cs,0),
  881. X           map_name(MAP_ASCII,0));
  882. X    if (!ok && !open_table(&(CT->cs),MAP_ASCII,NULL))
  883. X      CrashMe("Opening of Ascii failed !");
  884. X  }
  885. X  CT->multi = 0;
  886. X  CT->last_line_Y = 1;
  887. X  CT->last_line_X = 0;
  888. X  clear_window(CT->win);    
  889. X  CT->init(CT);
  890. X}
  891. X
  892. X
  893. Xvoid handle_content(content *CT, int len, CHAR *buffer) {
  894. X  int ret=0;
  895. X  int rlen=len;
  896. X  CHAR *rbuffer = buffer,*ptr;
  897. X  turn_flag(CT);
  898. X  if (StrLEN(CT->multi_buffer) > 0) {
  899. X    rbuffer = MALLOC(len+StrLEN(CT->multi_buffer));
  900. X    memcpy((void *)rbuffer,(void *)buffer,len);
  901. X    memcpy((void *)(rbuffer+len),(void *)StrPTR(CT->multi_buffer),
  902. X       StrLEN(CT->multi_buffer));
  903. X    rlen = len + StrLEN(CT->multi_buffer);
  904. X    StrFree(&(CT->multi_buffer));
  905. X  }
  906. X  
  907. X  for (ptr=rbuffer;ptr < rbuffer+rlen; ptr += ret) {
  908. X    if (CT->multi) 
  909. X      ret=CT->handle_multi(CT,rlen-(ptr-rbuffer),ptr,0);
  910. X    else
  911. X      ret=CT->handle(CT,rlen-(ptr-rbuffer),ptr);
  912. X  }
  913. X
  914. X  if (rbuffer != buffer) FREE(rbuffer);
  915. X}
  916. X
  917. Xstatic void flush_pending_multi(content *CT) {
  918. X  if (StrLEN(CT->multi_buffer) > 0) {
  919. X    int ret=0;
  920. X    CHAR *ptr;
  921. X    for (ptr=StrPTR(CT->multi_buffer);
  922. X     ptr < StrPTR(CT->multi_buffer)+StrLEN(CT->multi_buffer); ptr += ret) {
  923. X      if (!CT->multi) { CrashMe("Pending data with no multi mode!!"); }
  924. X      ret=CT->handle_multi(CT,
  925. X               StrLEN(CT->multi_buffer)
  926. X               -(ptr-StrPTR(CT->multi_buffer)),ptr,1);
  927. X    }
  928. X    StrFree(&(CT->multi_buffer));              
  929. X  }
  930. X}
  931. X
  932. Xvoid eoln_content(content *CT) {
  933. X  turn_flag(CT);
  934. X  flush_pending_multi(CT);
  935. X  CT->handle_eoln(CT);
  936. X}
  937. X
  938. Xvoid exit_content(content *CT) {
  939. X  turn_flag(CT);
  940. X  flush_pending_multi(CT);
  941. X  turn_flag(CT);
  942. X}
  943. X
  944. Xvoid update_content(content *CT) {   /* shoft eof - eof detected, but
  945. X                        here can be more data incoming 
  946. X                    when reread */
  947. X  turn_flag(CT);
  948. X  /* can here to be flush_pending_multi(CT) ? */
  949. X  CT->update(CT);
  950. X}
  951. SHAR_EOF
  952. echo "File content.c is complete"
  953. chmod 0644 content.c || echo "restore of content.c fails"
  954. echo "x - extracting content.h (Text)"
  955. sed 's/^X//' << 'SHAR_EOF' > content.h &&
  956. X/*  file: content.h
  957. X *
  958. X *  kehpager, Charset aware pager, Kari E. Hurtta
  959. X *
  960. X *  Copyright (c) 1993, 1994 Kari E. Hurtta
  961. X *
  962. X *  Redistribution and use in source and binary forms are permitted
  963. X *  provided that the above copyright notice and this paragraph are
  964. X *  duplicated in all such forms. This software is provided 'as is'
  965. X *  and without any warranty. 
  966. X */
  967. X
  968. X#define CT_plain    0
  969. X#define CT_terminal 1
  970. X#define CT_enriched 2
  971. X#define CT_richtext 3
  972. X
  973. Xtypedef struct CT content;
  974. Xstruct CT {
  975. X  int ct;
  976. X  int *fp;
  977. X  int win;
  978. X  int cs_flag;
  979. X  int multi;
  980. X  void (* init)(content *CT);
  981. X  int (* handle)(content *CT,int len, CHAR *buffer);
  982. X  int (* handle_multi)(content *CT,int len, CHAR *buffer,int flush);
  983. X  void (* handle_eoln)(content *CT);
  984. X  void (* exit)(content *CT);
  985. X  void (* update)(content *CT);
  986. X  int last_line_Y;
  987. X  int last_line_X;
  988. X  union {
  989. X    struct {
  990. X       int magic;
  991. X       int attrib_char_flag;
  992. X       int owerwrite;
  993. X       String attrib_buffer; 
  994. X
  995. X    } terminal;
  996. X    int plain;
  997. X    struct {      /* both Enriched and Richtext uses this same structure */
  998. X      int magic;
  999. X      String cmd_buffer; 
  1000. X      int nl_count;
  1001. X      int spc_count;
  1002. X      int verbatim;
  1003. X      int no_nl; /* used by richtext */
  1004. X      struct er_STACK {
  1005. X    struct er_STACK *previous;
  1006. X    int indent;
  1007. X    int pindent;   /* used by richtext */
  1008. X    chtable cs;        /* used by richtext */
  1009. X    int submargin;
  1010. X    int param; /* 2 = richtext comment */
  1011. X    int nofill;
  1012. X    int justify;
  1013. X    int excerpt_count;
  1014. X    int excerpt_flag;
  1015. X    int attrib_flag;
  1016. X    int force_wrap;
  1017. X    int er_function;
  1018. X    CHAR *name;
  1019. X      } *stack_top;
  1020. X    } enriched;
  1021. X  } c;
  1022. X  chtable cs;
  1023. X  String multi_buffer;
  1024. X};
  1025. X
  1026. Xextern const content NULL_content;
  1027. X
  1028. Xextern void init_content(int content_type,int *fp,int win, 
  1029. X             int cs, CHAR *cs_param,
  1030. X             content *CT);
  1031. Xextern void handle_content(content *CT, int len, unsigned char *buffer);
  1032. Xextern void eoln_content(content *CT);
  1033. Xextern void exit_content(content *CT);
  1034. Xextern void update_content(content *CT);
  1035. Xextern int search_content(CHAR *name,int mime);
  1036. Xextern CHAR *content_name(int content, int mime);
  1037. X            
  1038. Xextern void scroll_it(int win);
  1039. X
  1040. Xextern int enable_fulljust;
  1041. X
  1042. SHAR_EOF
  1043. chmod 0444 content.h || echo "restore of content.h fails"
  1044. echo "x - extracting control.c (Text)"
  1045. sed 's/^X//' << 'SHAR_EOF' > control.c &&
  1046. X/*  file: control.c
  1047. X *
  1048. X *  kehpager, Charset aware pager, Kari E. Hurtta
  1049. X *
  1050. X *  Copyright (c) 1993, 1994 Kari E. Hurtta
  1051. X *
  1052. X *  Redistribution and use in source and binary forms are permitted
  1053. X *  provided that the above copyright notice and this paragraph are
  1054. X *  duplicated in all such forms. This software is provided 'as is'
  1055. X *  and without any warranty. 
  1056. X */
  1057. X
  1058. X#include <string.h>
  1059. X#include <stdio.h>
  1060. X#include <stdarg.h>
  1061. X
  1062. X
  1063. X#include "kehpager.h"
  1064. X#include "memory.h"
  1065. X#include "charset.h"
  1066. X
  1067. X#include "control.h"
  1068. X#include "terminal.h"
  1069. X#include "esc.h"
  1070. X#include "rc.h"
  1071. X#include "env.h"
  1072. X
  1073. Xvolatile int need_redraw = 0;
  1074. Xvolatile int pager_state = 0;
  1075. Xvolatile int down_line = 1; /* !! */
  1076. Xstatic int vt_type = -1;
  1077. Xstatic terminal_type_pass = 0;
  1078. X/* 1 = asking terminal type
  1079. X   2 = trying multinational
  1080. X   3 = ask attributes
  1081. X */
  1082. X
  1083. X#define READY_PASS (4)
  1084. X
  1085. X#define SET_PASS(a) { terminal_type_pass = (a); \
  1086. X     if (DEBUG_TERM) print_debug("Terminal pass: %d",terminal_type_pass); }
  1087. X
  1088. Xstatic int in_panic = 0;
  1089. X#define PANIC(text) if (!in_panic) { \
  1090. X     in_panic = 1; reset_terminal_state(); \
  1091. X     print_notify("(%s) " #text,prog);  \
  1092. X     close_files(); close_terminal(); exit(1); }
  1093. X
  1094. Xstatic int wait_count = 0;
  1095. X
  1096. X#define ASKED { wait_count++; \
  1097. X     if (DEBUG_TERM) print_debug("wait_count: %d",wait_count); }
  1098. X#define GOT   { if (DEBUG_TERM) print_debug("wait_count: %d",wait_count); \
  1099. X     if (wait_count && !--wait_count) pass_4(); }
  1100. X
  1101. Xstatic int saved_personality = -1;
  1102. Xstatic int saved_multinational = -1;
  1103. Xstatic int saved_autowrap = -1;
  1104. Xstatic int saved_application = -1;
  1105. Xstatic int saved_language = -1;
  1106. Xstatic int saved_legend = -1;    /* 1 = data processing keys */
  1107. Xstatic int saved_newline = -1;
  1108. X
  1109. Xstatic int default_personality = 0;
  1110. Xstatic int default_multinational = -1;
  1111. Xstatic int default_autowrap = 1;
  1112. Xstatic int default_application = 0;
  1113. Xint default_language = -1;
  1114. Xstatic int default_legend = 0;    /* 1 = data processing keys */
  1115. Xstatic int default_newline = 0;
  1116. X
  1117. Xstatic int default_latin1 = 0;
  1118. X
  1119. Xstatic int set_vt100_is_G2 = 0;
  1120. Xstatic int set_vt100_is_ncr = 0;
  1121. X
  1122. Xint set_xterm_latin1 = 1;
  1123. Xint query_terminal_size = 1;
  1124. Xint limit_query = 0;
  1125. Xint force_mode = 0;          /* 1 = National
  1126. X                  * 2 = Multinational 
  1127. X                  */
  1128. X
  1129. Xint timer_per_char = 1;
  1130. Xstatic int timer_id_1 = 50;
  1131. Xstatic int timer_id_2 = 50;
  1132. Xstatic int timer_states_1 = 30;
  1133. Xstatic int timer_states_2 = 10;
  1134. Xstatic int use_technical = 1;
  1135. X
  1136. Xstatic int n_SUP = 0;
  1137. Xstatic int n_DISAB = 1;
  1138. X
  1139. Xinit_item control_items[] = {
  1140. X  { &n_SUP,                 "force.feature.enabled", V_ATTR },
  1141. X  { &n_DISAB,               "force.feature.disabled", V_ATTR },
  1142. X  { &default_personality,   "exit.personality_8bit", V_BOOL },
  1143. X  { &default_multinational, "exit.multinational",    V_BOOL },
  1144. X  { &default_autowrap,      "exit.autowrap",         V_BOOL },
  1145. X  { &default_application,   "exit.application_cursor_keys", V_BOOL },
  1146. X  { &default_legend,        "exit.data_processing_keys", V_BOOL },
  1147. X  { &default_latin1,        "exit.vt300.8bit_latin1",V_BOOL },
  1148. X  { &default_newline,       "exit.newline",          V_BOOL },
  1149. X  { &default_language,      "use.keyboard_language", V_NUM },
  1150. X  { &set_vt100_is_G2,       "use.vt100.G2_available", V_BOOL },
  1151. X  { &set_vt100_is_ncr,      "use.vt100.national_available", V_BOOL },
  1152. X  { &use_technical,         "use.technical",         V_BOOL },
  1153. X  { &limit_query,           "use.limited.queries",   V_BOOL },
  1154. X  { &query_terminal_size,   "use.query_size",        V_BOOL },
  1155. X  { &set_xterm_latin1,      "force.xterm.latin1",    V_BOOL },
  1156. X  { &force_mode,            "force.mode",            V_MODE },
  1157. X  { &timer_per_char,        "timer.per_char",        V_TIMER },
  1158. X  { &timer_id_1,            "timer.identification",  V_TIMER },
  1159. X  { &timer_id_2,            "timer.test_8bit",       V_TIMER },
  1160. X  { &timer_states_1,        "timer.states_first",    V_TIMER },
  1161. X  { &timer_states_2,        "timer.states_interval", V_TIMER },
  1162. X  { NULL, NULL, V_LAST }
  1163. X};
  1164. X
  1165. Xstatic int starting_line = -1;
  1166. Xstatic int starting_col = -1;
  1167. Xstatic int pos_count = 0;  
  1168. X
  1169. X/*
  1170. Xstatic int saved_undef(int value,int def) {
  1171. X if (-1 == value) value = def;
  1172. X return value;
  1173. X}
  1174. X*/
  1175. X
  1176. Xstatic int saved(int value,int def) {
  1177. X  if (-1 == value) value = def;
  1178. X  if (-1 == value) value = 0;
  1179. X  return value;
  1180. X}
  1181. X
  1182. Xstatic int neg_undef(int value) {
  1183. X  if (-1 == value) return -1;
  1184. X  return !value;
  1185. X}
  1186. X
  1187. Xstatic int have_8bit_clean = 0; 
  1188. Xstatic int use_national = -1; 
  1189. Xstatic int keyboard_language = -1;
  1190. X              /* 1 North American
  1191. X           * 6 Finnish
  1192. X           */
  1193. X
  1194. Xstatic int xterm_latin1_magic = -1;
  1195. X
  1196. Xstatic int GL_set = -1;
  1197. Xstatic int GR_set = -1;
  1198. Xstatic int FLAGS_set = -1;
  1199. X
  1200. Xstatic long PRIM_attr = 0;
  1201. Xstatic long OPT_attr = 0;
  1202. Xstatic long SUP_attr = 0;
  1203. Xstatic long DISAB_attr = 0;
  1204. X
  1205. Xstatic long *attrs[] = { &SUP_attr, &DISAB_attr };
  1206. X
  1207. X
  1208. X#define HAVE(x) ((x) == ((x) & (SUP_attr | PRIM_attr | OPT_attr) \
  1209. X             & ~DISAB_attr))
  1210. X#define SUPPOSE(x)  (SUP_attr |= (x))
  1211. X
  1212. X#define ATR_insdel       (1L<<0)  /* Insert/delete characters/lines */
  1213. X/* #define ATR_xxx       (1L<<1)  */
  1214. X#define ATR_cs_latin1    (1L<<2)  /* (14) Have Latin/1 and possible some other
  1215. X                  *      Latin charset 
  1216. X                  */
  1217. X#define ATR_cs_technical  (1L<<3)  /* (15) Have technical character set */
  1218. X#define ATR_cs_ncr       (1L<<4)  /* (9) Have national charsets */
  1219. X#define ATR_soft_char    (1L<<5)  /* (7) Have shoft characters */
  1220. X#define ATR_132          (1L<<6)  /* (1) Have 132 columns */
  1221. X#define ATR_sel_erase    (1L<<7)  /* (6) Have selective erase */
  1222. X#define ATR_def_key      (1L<<8)  /* (8) Have user defined keys */
  1223. X/* #define ATR_windows   (1L<<9)   (18) Have user windows */
  1224. X/* #define ATR_2_sess    (1L<<10)  (19) Have two sessions */
  1225. X#define ATR_hor_scroll   (1L<<11) /* (21) Have horizontal scrolling */
  1226. X#define ATR_ReGIS        (1L<<12) /* (3) Have ReGIS graphics */
  1227. X#define ATR_SIXEL        (1L<<13) /* (4) Have SIXEL graphics */
  1228. X/* #define ATR_status_d  (1L<<14)  (11) Status display */
  1229. X#define ATR_printer      (1L<<15) /* (2) Printer port */
  1230. X#define ATR_cs_multinational (1L<<16) /* Have multinational */
  1231. X#define ATR_G2           (1L<<17) /*  Have G2 & G3 available */
  1232. X#define ATR_vt100_magic  (1L<<18) /* Unnamed negative feature */
  1233. X#define ATR_C1_controls  (1L<<19) /* Have C1 controls */
  1234. X#define ATR_terminal_rq  (1L<<20) /* Terminal interrogation commands
  1235. X                   * DECRQM, DECRQSS, ...
  1236. X                   */
  1237. X
  1238. Xstatic struct features {
  1239. X  long flag;
  1240. X  char *name;
  1241. X} ftrtable[] = {
  1242. X  { ATR_vt100_magic, "(vt100 magic)" },
  1243. X  { ATR_insdel,      "Ins/Del characters/lines" },
  1244. X  { ATR_G2,          "Banks G2 & G3 (changeable)" },
  1245. X  { ATR_cs_latin1,   "Latin/1 charset" },
  1246. X  { ATR_cs_multinational, "Multinational charset" },
  1247. X  { ATR_cs_technical, "Technical charset" },
  1248. X  { ATR_C1_controls, "C1 control characters" },
  1249. X  { ATR_cs_ncr,      "National charset" },
  1250. X  { ATR_soft_char,   "Shoft characters" },
  1251. X  { ATR_132,         "132 columns" },
  1252. X  { ATR_sel_erase,   "Selective erase" },
  1253. X  { ATR_def_key,     "User defined keys" },
  1254. X  { ATR_hor_scroll,  "Horizontal scrolling" },
  1255. X  { ATR_ReGIS,       "ReGIS graphic" },
  1256. X  { ATR_SIXEL,       "SIXEL graphic" },
  1257. X  { ATR_printer,     "Printer port" },
  1258. X  { ATR_terminal_rq, "Terminal interrogation commands" },
  1259. X  { -1, NULL }
  1260. X};
  1261. X
  1262. Xstatic long flag_name (CHAR *s) {
  1263. X  int i;
  1264. X  for (i = 0; -1 != ftrtable[i].flag; i++)
  1265. X    if (0 == strcasecmp(ftrtable[i].name,Cs(s))) return ftrtable[i].flag;
  1266. X  return -1;
  1267. X}
  1268. X
  1269. Xint map_attribute(CHAR *value,int *ptr)  {
  1270. X  long flag;
  1271. X  long *fp = attrs[*ptr];
  1272. X  if (0 == strcasecmp("None",Cs(value)))
  1273. X    (*fp) = 0L;
  1274. X  else {
  1275. X    flag  = flag_name(value);
  1276. X    if (-1 == flag) return -1;
  1277. X    (*fp) |= flag;
  1278. X  }
  1279. X  return *ptr;
  1280. X}
  1281. X
  1282. Xstatic void do_magic() {
  1283. X  if (HAVE(ATR_vt100_magic)) {
  1284. X    if (set_vt100_is_G2) SUPPOSE(ATR_G2);
  1285. X    if (set_vt100_is_ncr) SUPPOSE(ATR_cs_ncr);
  1286. X  }
  1287. X}
  1288. X
  1289. Xstatic CHAR * ftr_string(long features) {
  1290. X  CHAR *ptr = NULL;
  1291. X  int i;
  1292. X  for (i = 0; -1 != ftrtable[i].flag; i++) 
  1293. X    if (ftrtable[i].flag & features) {
  1294. X      if (ptr) ptr = concat_text(ptr,rCs(", "));
  1295. X      ptr = concat_text(ptr,rCs(ftrtable[i].name));
  1296. X    }
  1297. X  if (!ptr) 
  1298. X    ptr = concat_text(ptr,rCs("None"));
  1299. X  return ptr; 
  1300. X}
  1301. X
  1302. Xtypedef struct ftr {
  1303. X  int basic;
  1304. X  int pos;
  1305. X  int value;
  1306. X  long flags;
  1307. X} ftrs;
  1308. X
  1309. Xstatic ftrs DA_table[] = {
  1310. X  { -1, -1,  1,  ATR_132 },
  1311. X  { -1, -1,  2,  ATR_printer },
  1312. X  { -1, -1,  3,  ATR_ReGIS },
  1313. X  { -1, -1,  4,  ATR_SIXEL },
  1314. X  { -1, -1,  5,  0          /* AVO option (132 char wide) NOT  installed */ },
  1315. X  { -1, -1,  6,  ATR_sel_erase },
  1316. X  { -1, -1,  7,  ATR_soft_char },
  1317. X  { -1, -1,  8,  ATR_def_key },
  1318. X  { -1, -1,  9,  ATR_cs_ncr },
  1319. X  { -1, -1, 10,  0              /* Text ruling  vector */ },
  1320. X  { -1, -1, 11,  0              /* 25th Status line */ },
  1321. X  { -1, -1, 12,  0              /* Terminal is a VT125 */ },
  1322. X  { -1, -1, 13,  0              /* Local editing mode */ },
  1323. X  { 63, -1, 14,  ATR_cs_latin1  /* 8-bit characters */ }, 
  1324. X  { 62, -1, -1,  ATR_cs_multinational }, 
  1325. X  { -1, -1, 15,  ATR_cs_technical /* Technical character set */ },
  1326. X  { -1, -1, 16,  0              /* Locator device port (ReGIS) [=mouse?] */ },
  1327. X  { -1, -1, 17,  0              /* Terminal state reports */ },
  1328. X  { -1, -1, 18,  0              /* Windowing capability */ },
  1329. X  { -1, -1, 19,  0              /* Dual sessions */ },
  1330. X  { -1, -1, 21,  ATR_hor_scroll /* Horizontal scrolling */ },
  1331. X  { -1, -1, 29,  0              /* ANSI text locator [=mouse?] */ },
  1332. X
  1333. X  { 61, -1, -1,  ATR_insdel },
  1334. X  { 61, -1, -1,  ATR_G2 },
  1335. X  { 62, -1, -1,  ATR_C1_controls },
  1336. X  { 63, -1, -1,  ATR_terminal_rq },
  1337. X  { -1, -1, -1, -1 }
  1338. X};
  1339. X
  1340. Xstatic ftrs vt100_table[] = {
  1341. X  { 0, -1,  ATR_vt100_magic },
  1342. X  { -1, 1, 0,  0                     /* NO options */ },
  1343. X  { -1, 1, 1,  0                     /* Processor Option (STP)  */ },
  1344. X  { -1, 1, 2,  ATR_132 | ATR_insdel  /* Advanced Video Option (AVO) */ },
  1345. X  { -1, 1, 3,  ATR_132 | ATR_insdel  /* AVO and STP */ },
  1346. X  { -1, 1, 4,  0                     /* Graphics Option (GPO) */ },
  1347. X  { -1, 1, 5,  0                     /* GPO and STP */ },
  1348. X  { -1, 1, 6,  ATR_132 | ATR_insdel  /* GPO and AVO */ },
  1349. X  { -1, 1, 7,  ATR_132 | ATR_insdel  /* GPO, AVO, and STP */ },
  1350. X  /* I don't know if these are correct - don't seem to formed from bits: */
  1351. X  { -1, 1, 9,  ATR_printer | ATR_132 | ATR_insdel  /* PP and AVO */ },
  1352. X  { -1, 1, 11, ATR_printer | ATR_132 | ATR_insdel  /* PP, GPO and AVO */ },
  1353. X  /* VT125 uses: */
  1354. X  { -1, 2, 0,  0                     /* No printer present */ },
  1355. X  { -1, 2, 1,  ATR_printer           /* printer present */ },
  1356. X  { -1, -1, -1, -1 }                     
  1357. X};
  1358. X
  1359. Xstatic ftrs LPC02_table[] = {
  1360. X  { -1, -1, 1,  ATR_ReGIS      /* ReGIS graphics software loaded */ },
  1361. X  { -1, -1, 2,  ATR_SIXEL      /* Color Sixel graphics software loaded */ },
  1362. X  { -1, -1, 3,  0              /* NAPLPS ???? */ },
  1363. X  { -1, -1, 4,  0              /* GIDIS */ },
  1364. X
  1365. X  { -1, -1, -1, -1 }                     
  1366. X};
  1367. X
  1368. Xstatic ftrs basic_table[] = {
  1369. X  { 0, -1, -1,   ATR_vt100_magic },
  1370. X  { 0, -1, -1,   ATR_insdel },
  1371. X  { -1, -1,  4,  ATR_SIXEL },
  1372. X  { -1, -1,  3,  ATR_ReGIS },
  1373. X  { -1, -1,  2,  ATR_printer },
  1374. X  { -1, -1,  1,  ATR_132 },
  1375. X  { -1, -1, -1, -1 }                     
  1376. X};
  1377. X
  1378. Xstatic struct lvl {
  1379. X  int type;
  1380. X  ftrs *table;
  1381. X  char *name;
  1382. X} levels[] = {
  1383. X  {  1,  vt100_table, "VT100" },
  1384. X  {  2,  vt100_table, "VT102" },
  1385. X  {  3,  vt100_table,  "DECwrite IV" },
  1386. X  {  4,  vt100_table, "VT132" },
  1387. X  {  5,  vt100_table, "VK100" },
  1388. X  {  6,  basic_table, "VT102" },
  1389. X  {  7,  basic_table, "VT131" },
  1390. X  {  12, vt100_table, "VT125" },
  1391. X  {  28, LPC02_table, "LPC01 (Unsupported)" },
  1392. X  {  37, LPC02_table, "LG02  (Unsupported)" },
  1393. X  {  61, DA_table,    "Level 1 (VT100 series)" },
  1394. X  {  62, DA_table,    "Level 2 (VT200 series)" },
  1395. X  {  63, DA_table,    "Level 3 (VT300 series)" },
  1396. X  {  64, DA_table,    "Level 4 (VT400 series)" },
  1397. X  /* These are unsupported, because basic features for 
  1398. X   * these levels is not know 
  1399. X   */
  1400. X  {  65, DA_table,    "Level 5 (Unsupported)" },
  1401. X  {  66, DA_table,    "Level 6 (Unsupported)" },
  1402. X  {  67, DA_table,    "Level 7 (Unsupported)" },
  1403. X  {  68, DA_table,    "Level 8 (Unsupported)" },
  1404. X  {  69, DA_table,    "Level 9 (Unsupported)" },
  1405. X  {  -1, NULL, NULL }
  1406. X  };
  1407. X
  1408. Xstatic void parse_DEC_DA (CHAR * S) {
  1409. X  char *level,*ptr;
  1410. X  int L,i,pos;
  1411. X  static ftrs *table;
  1412. X  
  1413. X  PRIM_attr = 0;
  1414. X  OPT_attr = 0;
  1415. X  if (NULL == (level = strtok(Cs(S),";")) || 
  1416. X      0 == (vt_type = atoi(level))) {
  1417. X    print_notify("Warning: Unsupported DA response");
  1418. X    vt_type = -1;
  1419. X    return;
  1420. X  }
  1421. X  L=-1;
  1422. X  for (i = 0; -1 != levels[i].type; i++) 
  1423. X    if (vt_type == levels[i].type) {
  1424. X      L = i; 
  1425. X      break;
  1426. X    }
  1427. X  if (-1 == L) {
  1428. X    print_notify("Warning: Unknown terminal model (type/level field=%d)",
  1429. X         vt_type);
  1430. X    return;
  1431. X  }
  1432. X  table = levels[L].table;
  1433. X  /* Calculate primary features */
  1434. X  for (i = 0; -1 != table[i].flags; i++)
  1435. X    if (-1 != table[i].basic &&
  1436. X    vt_type >= table[i].basic)
  1437. X      PRIM_attr |= table[i].flags;
  1438. X  if (DEBUG_TERM) {
  1439. X    CHAR *P = ftr_string(PRIM_attr);
  1440. X    if (strlen(Cs(P)) < ERROR_LEN -20)
  1441. X      print_debug("Primary features: %s",P);
  1442. X    else
  1443. X      print_debug("Primary features list too long to print...");
  1444. X    free(P);
  1445. X  }
  1446. X  /* Calculate optional features */
  1447. X  pos=0;
  1448. X  for (ptr = strtok(NULL,";"); NULL != ptr; ptr = strtok(NULL,";")) {
  1449. X    int val = atoi(ptr);
  1450. X    pos++;
  1451. X    for (i = 0; -1 != table[i].flags; i++)
  1452. X      if (-1 != table[i].value &&
  1453. X      val == table[i].value &&
  1454. X      (-1 == table[i].pos || pos == table[i].pos))
  1455. X    OPT_attr |= table[i].flags;
  1456. X  }  
  1457. X  if (DEBUG_TERM) {
  1458. X    CHAR *P = ftr_string(OPT_attr);
  1459. X    if (strlen(Cs(P)) < ERROR_LEN -20)
  1460. X      print_debug("Optional features: %s",P);
  1461. X    else
  1462. X      print_debug("Optional features list too long to print...");
  1463. X    free(P);
  1464. X  }
  1465. X}
  1466. X
  1467. Xstatic CHAR * terminal_type(void) {
  1468. X  CHAR *ptr=NULL;
  1469. X  int i;
  1470. X  if (-1 == vt_type) {
  1471. X    ptr = concat_text(ptr,rCs("Undefined"));
  1472. X  } else {
  1473. X    CHAR T[10];
  1474. X    sprintf(Cs(T),"(%d) ",vt_type);
  1475. X    ptr = concat_text(ptr,T);
  1476. X    for (i = 0; -1 != levels[i].type; i++) 
  1477. X      if (vt_type == levels[i].type) 
  1478. X    ptr = concat_text(ptr,rCs(levels[i].name));
  1479. X  }
  1480. X  return ptr;
  1481. X}
  1482. X
  1483. Xlong hazards = 0L;
  1484. X
  1485. Xstatic struct Hazard {
  1486. X  long value;
  1487. X  char *text;
  1488. X} hazard_table[] = {
  1489. X  { HAZ_wrap,     "Terminal may wrap in right" },
  1490. X  { HAZ_national, "Terminal is always in national mode" },
  1491. X  { HAZ_ONLCR,    "Tty driver may wrap LF -> CR LF on output" },
  1492. X  { HAZ_TAB,      "Tty driver may expand TAB -> SPCs on output" },
  1493. X  { HAZ_newline,  "Terminal is always in newline mode (LF produces new line, "
  1494. X      " RETURN produces CR LF)" },
  1495. X  { HAZ_application, "Cursor keys are always in application mode" },
  1496. X
  1497. X  { -1, NULL }
  1498. X};
  1499. X
  1500. Xstatic CHAR * terminal_hazards(void) {
  1501. X  CHAR *ptr=NULL;
  1502. X  int i;
  1503. X  for (i = 0; -1 != hazard_table[i].value; i++) 
  1504. X    if (HAZ_MAY(hazard_table[i].value)) {
  1505. X      if (ptr) ptr = concat_text(ptr,rCs(", "));
  1506. X      ptr = concat_text(ptr,rCs(hazard_table[i].text));
  1507. X    }
  1508. X  if (!ptr) ptr = concat_text(ptr,rCs("None"));
  1509. X  return ptr;
  1510. X}
  1511. X
  1512. Xstruct termitem kehpager_term[] = {
  1513. X  { "type",                 &vt_type },
  1514. X  { "s.personality",        &saved_personality },
  1515. X  { "s.multinational",      &saved_multinational },
  1516. X  { "d.multinational",      &default_multinational },
  1517. X  { "s.application",        &saved_application },
  1518. X  { "s.language",           &saved_language },
  1519. X  { "s.legend",             &saved_legend },
  1520. X  { "s.autowrap",           &saved_autowrap },
  1521. X  { "u.8bit_clean",         &have_8bit_clean },
  1522. X  { NULL, NULL }
  1523. X};
  1524. X
  1525. Xstruct termitem2 kehpager_term2[] = {
  1526. X  { "attr.prim",            &PRIM_attr },
  1527. X  { "attr.supp",            &SUP_attr }, 
  1528. X  { "attr.opt",             &OPT_attr },
  1529. X  { "attr.hazards",         &hazards },
  1530. X  { NULL, NULL }
  1531. X};
  1532. X
  1533. X#define A_ASCII 1
  1534. X#define A_8bit  2
  1535. X#define A_8bit_n (A_ASCII | A_8bit)
  1536. X#define A_96set 4
  1537. X
  1538. Xstruct one_set {
  1539. X  int language;
  1540. X  char *set;
  1541. X  char *name;
  1542. X  long flags;
  1543. X  int use_latin;
  1544. X  int area;
  1545. X  int charset;
  1546. X} sets[] = {
  1547. X
  1548. X  /* National character sets */
  1549. X  { 1, "B", "ASCII",           0  , -1 ,        A_ASCII,  MAP_ASCII }, /* 0 */
  1550. X  { 2, "A", "UK-ASCII",        0  , -1 ,        0,  MAP_UK },
  1551. X  { 4, "9", "French Canadian", ATR_cs_ncr, -1 , 0,  MAP_CAN },
  1552. X  { 6, "5", "Finnish",         ATR_cs_ncr, -1 , 0,  MAP_FINNISH },
  1553. X  { 7, "K", "German",          ATR_cs_ncr, -1 , 0,  MAP_GER },
  1554. X  { 9, "Y", "Italian",         ATR_cs_ncr, -1 , 0,  MAP_ITAL },
  1555. X  { 5, "E", "Danish",          ATR_cs_ncr, -1 , 0,  MAP_NOR },
  1556. X  { 13,"E", "Norwegian",       ATR_cs_ncr, -1 , 0,  MAP_NOR },
  1557. X  { 12,"7", "Swedish",         ATR_cs_ncr, -1 , 0,  MAP_SWE },
  1558. X  { 3, "R", "Flemish",         ATR_cs_ncr, -1 , 0,  MAP_BEL },
  1559. X  { 14,"R", "French/Belgian",  ATR_cs_ncr, -1 , 0,  MAP_BEL },
  1560. X  { 15,"Z", "Spanish",         ATR_cs_ncr, -1 , 0,  MAP_SPA },
  1561. X
  1562. X  { -1, ">", "Technical",      ATR_cs_technical, -1, 0, MAP_TECHNICAL },
  1563. X  { -1, "<", "Multinational" , ATR_cs_multinational  
  1564. X                                          , 0 , A_8bit_n, MAP_MULTINATIONAL },
  1565. X  { -1, "%5", "Multinational", ATR_cs_multinational | ATR_cs_latin1
  1566. X                                          , -1, A_8bit_n, MAP_MULTINATIONAL },
  1567. X
  1568. X  { -1, "<", "Latin/1",        ATR_cs_latin1 , 1 , A_8bit_n,   MAP_LATIN1 }, /* Must be last -1 */
  1569. X  { -1, "0", "Special",        0  , -1 , 0,  MAP_SPECIAL }   /* Must be last */
  1570. X
  1571. X};
  1572. X
  1573. X#define SET_NUM (sizeof (sets) / sizeof (struct one_set))
  1574. X
  1575. Xint find_set_by_name (CHAR *name, int is_8bit) {
  1576. X  int i,result=-1;
  1577. X  for (i = 0; i < SET_NUM; i++) {
  1578. X    if (-1 != result && 0 == strcmp(sets[i].name,sets[result].name) &&
  1579. X    HAVE(sets[i].flags)) result = -1;
  1580. X    if (0 == strcasecmp(sets[i].name,Cs(name)) &&
  1581. X    HAVE(sets[i].flags) &&
  1582. X    (0 == (sets[i].area & A_8bit) || is_8bit)) result = i;
  1583. X  }
  1584. X  return result;
  1585. X}
  1586. X
  1587. Xint find_set_by_language (int language, int is_8bit) {
  1588. X  int i,result=-1;
  1589. X  for (i = 0; i < SET_NUM; i++) {
  1590. X    if (-1 != result && 0 == strcmp(sets[i].name,sets[result].name) &&
  1591. X    HAVE(sets[i].flags)) result = -1;
  1592. X    if (sets[i].language == language &&
  1593. X    HAVE(sets[i].flags) &&
  1594. X    (0 == (sets[i].area & A_8bit) || is_8bit)) result = i;
  1595. X  }
  1596. X  return result;
  1597. X}
  1598. X
  1599. Xtypedef pattern[4];
  1600. X
  1601. X/* G0 -> national  |  national | ascii         | ascii
  1602. X * G1 -> special   |  ascii    | special       | special
  1603. X * G2 -> ascii     |           | multinational | latin/1
  1604. X * G3 -> uk-ascii  |           | latin/1       |
  1605. X */
  1606. X
  1607. Xstatic pattern default_sets = { -1, (SET_NUM -1), -1, 0 };
  1608. Xstatic pattern used_sets = { -1, (SET_NUM -1), -1, -1 };
  1609. X
  1610. Xstatic void set_mode(char *frm, ...) {
  1611. X  va_list args;
  1612. X  CHAR buffer[MAX_OUTPUT+1],*ptr,*ptr2=NULL;
  1613. X  CHAR sbuffer[MAX_OUTPUT+1];
  1614. X
  1615. X  va_start(args,frm);
  1616. X  vsprintf(Cs(buffer),frm,args);
  1617. X  va_end(args);
  1618. X
  1619. X  ptr = map_buffer(buffer,!personality_8bit,sbuffer,MAX_OUTPUT);
  1620. X  print_to_terminal(ptr);
  1621. X
  1622. X  if (DEBUG_TERM) {
  1623. X    String S;
  1624. X    S.buffer = ptr;
  1625. X    S.len = strlen(Cs(ptr));
  1626. X    S.alloced=0;
  1627. X    char2names(&S,&ptr2);
  1628. X    print_debug("To terminal: %s",ptr2);
  1629. X    FREE(ptr2);
  1630. X  }
  1631. X
  1632. X  if (ptr != sbuffer) FREE(ptr);
  1633. X
  1634. X}
  1635. X
  1636. Xstatic void clear_attr_conflict(int *flag) {
  1637. X
  1638. X   if (((*flag) & (FL_BOLD | FL_DIM)) == (FL_BOLD | FL_DIM))
  1639. X     (*flag) &= ~(FL_BOLD | FL_DIM);
  1640. X
  1641. X}
  1642. X
  1643. Xint sum_fl_attr(int flags, int new) {
  1644. X  flags |= new;
  1645. X  clear_attr_conflict(&flags);
  1646. X  flags |= new;
  1647. X  return flags;
  1648. X}
  1649. X
  1650. Xstatic void set_attr(int flags) {
  1651. X   CHAR buffer[32];
  1652. X   char tmp[4];
  1653. X
  1654. X   buffer[0] = '\0';
  1655. X
  1656. X#define ADD_VAL(p) { sprintf(tmp,"%d",p); \
  1657. X                     if ('\0' != buffer[0]) strcat(Cs(buffer),";"); \
  1658. X             strcat(Cs(buffer),tmp); }
  1659. X
  1660. X  clear_attr_conflict(&flags);
  1661. X
  1662. X   if (0 == flags && 0 != FLAGS_set) {
  1663. X     set_mode("%cm",CSI);
  1664. X     FLAGS_set = 0;
  1665. X     return;
  1666. X   }
  1667. X
  1668. X   if (-1 == FLAGS_set) { ADD_VAL(0); FLAGS_set = 0; }
  1669. X   if (FLAGS_set & ~flags) {ADD_VAL(0); FLAGS_set = 0; }
  1670. X
  1671. X   if (FL_BOLD & flags & ~FLAGS_set) { ADD_VAL(1); FLAGS_set |= FL_BOLD; }
  1672. X   if (FL_DIM & flags & ~FLAGS_set) { ADD_VAL(2); FLAGS_set |= FL_DIM; }
  1673. X   if (FL_UNDER & flags & ~FLAGS_set) { ADD_VAL(4); FLAGS_set |= FL_UNDER; }
  1674. X   if (FL_REVERSE & flags & ~FLAGS_set) { ADD_VAL(7); FLAGS_set |= FL_REVERSE; }
  1675. X   if (FL_BLINK & flags & ~FLAGS_set) { ADD_VAL(5); FLAGS_set |= FL_BLINK; }
  1676. X
  1677. X   if ('\0' == buffer[0]) return;
  1678. X
  1679. X   set_mode("%c%sm",CSI,buffer);
  1680. X
  1681. X#undef ADD_VAL
  1682. X}
  1683. X
  1684. X
  1685. Xstatic int set_banks(int GL, int GR) {
  1686. X  int flag = 1;
  1687. X  if (-1 != GL && GL != GL_set) switch(GL) {
  1688. X  case 0: set_mode("%c",SI); GL_set = 0; break;
  1689. X  case 1: set_mode("%c",SO); GL_set = 1; break;
  1690. X  case 2: 
  1691. X    if (HAVE(ATR_cs_latin1) || HAVE(ATR_cs_multinational)) {
  1692. X      set_mode("%cn",ESC); GL_set = 2; }
  1693. X    else { set_mode("%cN",ESC); flag = 0; } break;
  1694. X  case 3: 
  1695. X    if (HAVE(ATR_cs_latin1) || HAVE(ATR_cs_multinational)) {
  1696. X      set_mode("%co",ESC); GL_set = 3; }
  1697. X    else { set_mode("%cO",ESC); flag = 0; } break;
  1698. X  }
  1699. X
  1700. X  if (-1 != GR && GR != GR_set) switch(GR) {
  1701. X  case 0:
  1702. X    PANIC("Software failure: trying map GR to G0");
  1703. X    break;
  1704. X  case 1: set_mode("%c~",ESC); GR_set = 1; break;
  1705. X  case 2: set_mode("%c}",ESC); GR_set = 2; break;
  1706. X  case 3: set_mode("%c|",ESC); GR_set = 3; break;
  1707. X  }
  1708. X  return flag;
  1709. X}
  1710. X
  1711. Xstatic int X_set = -1, Y_set = -1;
  1712. Xstatic int X_hard = -1, Y_hard = -1;
  1713. X
  1714. Xstatic void print_viaset(int set, CHAR *buffer) {
  1715. X  int i, bank = -1, left,len = strlen(Cs(buffer));
  1716. X  int lo = 0, hi = 0, GL,GR,repeat,maxx=columns;
  1717. X  CHAR *c;
  1718. X
  1719. X  if (HAZ_MAY(HAZ_wrap) && Y_set == lines) maxx = columns-1;
  1720. X
  1721. X  if (X_set > maxx) X_set = -1;
  1722. X  if (-1 == X_set) return;
  1723. X  left = maxx - X_set +1;
  1724. X
  1725. X  for (i = 0; i < 4; i++) if (used_sets[i]==set) { bank = i; break; }
  1726. X  if (-1 == bank) {
  1727. X    PANIC("Charset not in any bank!");
  1728. X    bank = 0;
  1729. X  }
  1730. X  for (c= buffer; *c; c++)
  1731. X    if (*c & 128) hi = 1;
  1732. X    else lo = 1;
  1733. X  GL = lo ? bank : -1;
  1734. X  GR = hi ? bank : -1;
  1735. X  repeat = !set_banks(GL,GR);
  1736. X  if (repeat) for (c=buffer;*c && left ;c++,set_banks(GL,GR)) {
  1737. X    CHAR tbuffer[2];
  1738. X    tbuffer[0] = *c; tbuffer[1] = 0;
  1739. X    print_to_terminal(tbuffer);
  1740. X    if (DEBUG_TERM) {
  1741. X      print_debug("Text to terminal: %s",tbuffer);
  1742. X    }
  1743. X    X_set++; left--;
  1744. X  } else if (left < len) {
  1745. X    CHAR sbuffer[MAX_OUTPUT+1];
  1746. X    CHAR *tbuffer = left < MAX_OUTPUT ? sbuffer : MALLOC(left+1);
  1747. X
  1748. X    memcpy((void *)tbuffer,(void *)buffer,left);
  1749. X    tbuffer[left] = '\0';
  1750. X    print_to_terminal(tbuffer);
  1751. X    
  1752. X    if (tbuffer != sbuffer) FREE(tbuffer);
  1753. X
  1754. X    if (DEBUG_TERM) {
  1755. X      print_debug("Text to terminal: %s",tbuffer);
  1756. X    }
  1757. X    X_set += left;
  1758. X  } else {
  1759. X    print_to_terminal(buffer);
  1760. X    if (DEBUG_TERM) {
  1761. X      print_debug("Text to terminal: %s",buffer);
  1762. X    }
  1763. X    X_set += len;
  1764. X  }
  1765. X  if (HAZ_MAY(HAZ_wrap) && X_set == columns) {
  1766. X    X_set = -1;
  1767. X    Y_set = -1;
  1768. X  } else if (X_set > columns) X_set = -1;
  1769. X}
  1770. X
  1771. Xstatic void change_banks(pattern char_sets) {
  1772. X  int i;
  1773. X  /* Set char sets */
  1774. X
  1775. X  for (i = 0; i < 4; i++) if (-1 != char_sets[i]) {
  1776. X    if (sets[char_sets[i]].area & A_96set) {
  1777. X      if (i == 0) 
  1778. X    PANIC("Can't assign 96 char sets to bank 0 !");
  1779. X      set_mode("%c%c%s",ESC,"\0-./"[i],sets[char_sets[i]].set);
  1780. X    } else
  1781. X      set_mode("%c%c%s",ESC,"()*+"[i],sets[char_sets[i]].set);
  1782. X  }
  1783. X}
  1784. X
  1785. Xstatic void change_state(int setup,
  1786. X            int personality,
  1787. X            int multinational,
  1788. X            int autowrap,
  1789. X            int application,
  1790. X            pattern char_sets,
  1791. X            int legend,
  1792. X            int new_line) {
  1793. X  int use_latin1 = -1, i;
  1794. X  static int latin1_prev = -1;
  1795. X
  1796. X  for (i = 0; i < 4; i++) if (-1 != char_sets[i])
  1797. X    if (-1 != sets[char_sets[i]].use_latin)
  1798. X      use_latin1 = sets[char_sets[i]].use_latin;
  1799. X
  1800. X  set_mode("%c%c%c!p",CAN,ST,CSI); /* shoft reset */
  1801. X
  1802. X  if (HAVE(ATR_C1_controls)) {
  1803. X    set_mode("%c[%d;%d\"p",ESC,vt_type,personality ? 2 : 1);
  1804. X
  1805. X    if (-1 != multinational) {
  1806. X      set_mode ("%c?42%c",CSI,multinational ? 'l' : 'h');
  1807. X      personality_8bit = personality && multinational;      
  1808. X    } else
  1809. X      personality_8bit = 0;
  1810. X
  1811. X  } else {
  1812. X    if (-1 != multinational)
  1813. X      set_mode ("%c?42%c",CSI,multinational ? 'l' : 'h');
  1814. X    personality_8bit = 0;
  1815. X  }
  1816. X
  1817. X  if (-1 != autowrap)
  1818. X    set_mode ("%c?7%c",CSI,autowrap ? 'h' : 'l');
  1819. X  if (-1 != application)
  1820. X    set_mode ("%c?1%c",CSI,application ? 'h' : 'l' );
  1821. X  set_mode ("%c?68%c",CSI,legend ? 'h' : 'l' );
  1822. X
  1823. X  /* Insert mode off, New line mode off,
  1824. X     Control excution on
  1825. X   */
  1826. X  set_mode ("%c4;13l",CSI);
  1827. X  /* Local echo off */
  1828. X  set_mode ("%c12h",CSI);
  1829. X
  1830. X  if (-1 != new_line)
  1831. X    set_mode("%c20%c",CSI,new_line ? 'h' : 'l');
  1832. X
  1833. X  /* Set Latin/1 mode */
  1834. X  if (-1 != use_latin1 && (latin1_prev != use_latin1 || setup)) {
  1835. X    set_mode("%c%s%c",DCS,use_latin1 ? "1!uA" : "0!u%5" , ST);
  1836. X    latin1_prev = use_latin1; /* for avoid garbage when suspending */
  1837. X  } else if (-1 == use_latin1 && -1 != default_latin1 &&
  1838. X         -1 != latin1_prev && latin1_prev != default_latin1) {
  1839. X    set_mode("%c%s%c",DCS,default_latin1 ? "1!uA" : "0!u%5" , ST);
  1840. X    latin1_prev = default_latin1;
  1841. X  }
  1842. X
  1843. X  change_banks(char_sets);
  1844. X}
  1845. X
  1846. Xstatic int Y1_set = -1;
  1847. Xstatic int Y2_set = -1;
  1848. Xstatic int Y1_region = -1;
  1849. Xstatic int Y2_region = -1;
  1850. X
  1851. Xstatic void set_region(int Y1, int Y2) {
  1852. X  if (-1 == Y1 || -1 == Y2) {
  1853. X    Y1 = 1; Y2 = lines;
  1854. X  }
  1855. X  if (DEBUG_CURSOR) {
  1856. X    print_debug("Region to (Y1,Y2) = (%d,%d) from (%d,%d)",
  1857. X        Y1,Y2,Y1_set,Y2_set);
  1858. X  }
  1859. X  if (Y1 != Y1_set || Y2 != Y2_set) {
  1860. X    set_mode("%c%d;%dr",CSI,Y1,Y2);
  1861. X    Y1_set = Y1; Y2_set = Y2;
  1862. X    Y_set = -1;
  1863. X  }
  1864. X}
  1865. X
  1866. Xstatic void update_region(void) {
  1867. X  int Y1 = Y1_region, Y2=Y2_region;
  1868. X
  1869. X  if (Y1 > lines) PANIC("Software failure/Region out of screen");
  1870. X  if (Y2 > lines) Y2 = lines;
  1871. X
  1872. X  if (-1 == Y1) {
  1873. X    Y1 = -1; Y2  = -1;
  1874. X  }
  1875. X  set_region(Y1,Y2);
  1876. X}
  1877. X
  1878. Xstatic void check_region(void) {
  1879. X  if (-1 != Y1_region || -1 != Y2_region)
  1880. X    PANIC("Software error/Regions not supported here!");
  1881. X}
  1882. X
  1883. Xstatic int is_region(int line) {
  1884. X  if (-1 == Y1_region || -1 == Y2_region) return 0;
  1885. X  if (line < Y1_region || line > Y2_region)
  1886. X    PANIC("Software error/Line out of region");
  1887. X  return 1;
  1888. X}
  1889. X
  1890. Xvoid set_margins(int Y1, int Y2) {
  1891. X  if (Y1 > Y2) PANIC("Software failure/set_margins: Y1 > Y2");
  1892. X
  1893. X  Y1_region = Y1; Y2_region = Y2;
  1894. X}
  1895. X
  1896. Xstatic void set_down_line(int line) {
  1897. X  if (DEBUG_CURSOR) {
  1898. X    print_debug("Down line to %d from %d",line,down_line);
  1899. X  }
  1900. X  down_line = line;
  1901. X}
  1902. X  
  1903. Xstatic void goto_XY(int X, int Y) {
  1904. X
  1905. X  if (-1 == X_set  && -1 == Y_set) {
  1906. X    /* Origin mode off */
  1907. X    set_mode ("%c?6l",CSI);
  1908. X  }
  1909. X
  1910. X  if (-1 == Y1_set || -1 == Y2_set) 
  1911. X    set_region(-1,-1);
  1912. X
  1913. X  if (Y < Y1_set || Y > Y2_set)
  1914. X    PANIC("Software error/Going out of region");
  1915. X
  1916. X  if (DEBUG_CURSOR) {
  1917. X    print_debug("Cursor to (X,Y) = (%d,%d) from (%d,%d)",X,Y,X_set,Y_set);
  1918. X  }
  1919. X
  1920. X  if (X == X_set && Y == Y_set) return;
  1921. X  if (Y >= down_line) set_down_line(Y+1);
  1922. X
  1923. X  if (Y == Y_set && X == X_set-1) {
  1924. X    set_mode("%c",BS);
  1925. X    X_set--;
  1926. X    return;
  1927. X  }
  1928. X
  1929. X  if (1 == Y && 1 == X) {
  1930. X    set_mode("%cH",CSI);
  1931. X    X_set = 1;
  1932. X    Y_set = 1;
  1933. X    return;
  1934. X  }
  1935. X
  1936. X  if (Y == Y_set+1 && X == X_set) {
  1937. X    /* IND is two characters in 7-bit output !! */
  1938. X    if (personality_8bit || HAZ_MAY(HAZ_ONLCR) ||
  1939. X    HAZ_MAY(HAZ_newline)) set_mode("%c",IND);
  1940. X    else set_mode("%c",LF);
  1941. X    Y_set++;
  1942. X    return;
  1943. X  }
  1944. X
  1945. X  if (Y == Y_set+1 && X == 1 && -1 != X_set) {
  1946. X    set_mode("%c",NEL);
  1947. X    Y_set++;
  1948. X    X_set = 1;
  1949. X    return;
  1950. X  }
  1951. X
  1952. X  if (Y == Y_set && -1 != X_set) {
  1953. X    if (1 == X) set_mode("%c",CR);
  1954. X    else if (X < X_set) set_mode("%c%dD",CSI,X_set-X);
  1955. X    else set_mode("%c%dC",CSI,X-X_set);
  1956. X    X_set = X; return;
  1957. X  }
  1958. X  if (X == X_set && -1 != Y_set && Y_set >= Y1_set && Y_set <= Y2_set) {
  1959. X    if (Y < Y_set) set_mode("%c%dA",CSI,Y_set-Y);
  1960. X    else set_mode("%c%dB",CSI,Y-Y_set);
  1961. X    Y_set = Y; return;
  1962. X  }
  1963. X  set_mode("%c%d;%dH",CSI,Y,X); X_set = X; Y_set = Y;
  1964. X}
  1965. X
  1966. Xstatic void update_hard(void) {
  1967. X  set_region(-1,-1);
  1968. X  if (-1 != X_hard && -1 != Y_hard &&
  1969. X      X_hard <= columns && Y_hard <= lines) goto_XY(X_hard,Y_hard);
  1970. X}
  1971. X
  1972. Xvoid reset_terminal_state(void) {
  1973. X  pager_state = 0;
  1974. X  change_state(0,
  1975. X           saved(saved_personality,default_personality),
  1976. X           saved(saved_multinational,default_multinational),
  1977. X           saved(saved_autowrap,default_autowrap),
  1978. X           saved(saved_application,default_application),
  1979. X           default_sets,
  1980. X           saved(saved_legend,default_legend),
  1981. X           saved(saved_newline,default_newline));
  1982. X  set_banks(0,saved(saved_multinational,default_multinational) ? 2 : -1);
  1983. X  set_attr(0);
  1984. X  set_region(-1,-1);
  1985. X  goto_XY(1,down_line <= lines ? down_line : lines);
  1986. X  if (down_line > lines) set_mode("%c",LF);
  1987. X
  1988. X  flush_error_buffer(); 
  1989. X}
  1990. X
  1991. Xstatic int fast_start = 0;
  1992. X
  1993. Xstatic void pass_2(void);
  1994. Xvoid get_terminal_state(void) {
  1995. X  set_attr(FL_BLINK);
  1996. X  print_to_terminal(rCs("\rInitializing terminal: "));
  1997. X  set_attr(0);
  1998. X  fast_start = init_from_kehpager_term();
  1999. X  xterm_latin1_magic = (set_xterm_latin1 && is_xterm()) || 
  2000. X    2 == set_xterm_latin1;
  2001. X
  2002. X  SET_PASS(1);
  2003. X
  2004. X  if (!fast_start) {
  2005. X    set_mode("%c%c%c[0c",CAN,ST,ESC); /* Ask terminal status report */
  2006. X  } else {
  2007. X    pass_2();
  2008. X  }
  2009. X}
  2010. X
  2011. Xstatic void pass_3(void);
  2012. Xstatic void pass_2(void) {
  2013. X  int tmp = personality_8bit;
  2014. X  SET_PASS(2);
  2015. X  if (force_mode > 0) {
  2016. X    /* force 7 or 8bit */
  2017. X    switch(force_mode) {
  2018. X    case 1: /* force National */
  2019. X      have_8bit_clean = 0;
  2020. X      if (!HAVE(ATR_cs_ncr)) SUPPOSE(ATR_cs_ncr);
  2021. X      if (-1 == default_multinational) default_multinational = 0;
  2022. X      break;
  2023. X    case 2: /* force Multinational */
  2024. X      have_8bit_clean = 1;
  2025. X      if (!HAVE(ATR_cs_multinational)) SUPPOSE(ATR_cs_multinational);
  2026. X      if (!HAVE(ATR_G2)) SUPPOSE(ATR_G2);
  2027. X      if (-1 == default_multinational) default_multinational = 1;
  2028. X      break;
  2029. X    }
  2030. X    pass_3();
  2031. X  } else if (xterm_latin1_magic) {
  2032. X    /* force 8bit */
  2033. X    have_8bit_clean = 1;
  2034. X    if (!HAVE(ATR_cs_latin1)) SUPPOSE(ATR_cs_latin1);
  2035. X    if (!HAVE(ATR_G2)) SUPPOSE(ATR_G2);
  2036. X    if (-1 == default_multinational) default_multinational = 1;
  2037. X    pass_3();
  2038. X  } else if (!fast_start) {
  2039. X    personality_8bit = 1;
  2040. X
  2041. X    set_mode("%c0c",CSI);
  2042. X
  2043. X    personality_8bit = tmp;
  2044. X  } else {
  2045. X    pass_3();
  2046. X  }
  2047. X}
  2048. X
  2049. Xstatic CHAR *Boolean(int v) {
  2050. X  char *S = "??"; switch(v) { 
  2051. X  case -1: S = "Undefined"; break; 
  2052. X  case 0:  S = "False"; break; 
  2053. X  case 1:  S = "True"; break; } 
  2054. X  return rCs(S);
  2055. X}
  2056. X
  2057. Xstatic CHAR *Number(int v) {
  2058. X  static int B=0;
  2059. X  static CHAR buffer[5][10];
  2060. X  if (-1 == v) return rCs("Undefined");
  2061. X  B = (B+1)%5;
  2062. X  sprintf(Cs(buffer[B]),"%d",v);
  2063. X  return buffer[B];
  2064. X}
  2065. X
  2066. Xvoid give_debug_page(void (*printer)(CHAR *line, int header)) {
  2067. X  CHAR buffer[80];
  2068. X#define PV(T,v) { if (-1 == v) sprintf(Cs(buffer),"%-30s: Undefined",T); \
  2069. X          else sprintf(Cs(buffer),"%-30s: %d",T,v); printer(buffer,0); }
  2070. X#define PV1(T,v,v1) { sprintf(Cs(buffer),"%-30s: %-15s Default: %s",T,\
  2071. X                  Number(v),Number(v1)); printer(buffer,0); }
  2072. X
  2073. X#define PB(T,v) { sprintf(Cs(buffer),"%-30s: %s",T,Boolean(v)); printer(buffer,0); }
  2074. X#define PB1(T,v,v1) { sprintf(Cs(buffer),"%-30s: %-15s Default: %s",T,\
  2075. X                  Boolean(v),Boolean(v1)); printer(buffer,0); }
  2076. X#define PF(T,v) { char *S = "??"; switch(v) { \
  2077. X                        case -1: S = "Undefined"; break; \
  2078. X                        default: S = sets[v].name; } \
  2079. X          sprintf(Cs(buffer),"%-30s: %-1s",T,S); printer(buffer,0); }
  2080. X#define PMP(T,v) { CHAR *S = rCs("??"); switch(v) { \
  2081. X                        case -1: S = rCs("Undefined"); break; \
  2082. X                        default: S = map_name(v,0); } \
  2083. X          sprintf(Cs(buffer),"%-30s: %-1s",T,S); printer(buffer,0); }
  2084. X#define MES(T,s) { CHAR *S = NULL; sprintf(Cs(buffer),"%-30s: ",T); \
  2085. X           S = concat_text(S,buffer); S = concat_text(S,s); \
  2086. X                   printer(S,-32); FREE(S); FREE(s); }
  2087. X  printer(rCs("Terminal state"),1); 
  2088. X  MES("Terminal type",terminal_type());
  2089. X  printer(rCs("Features"),0);
  2090. X  MES("   - basic",ftr_string(PRIM_attr));
  2091. X  MES("   - optional",ftr_string(OPT_attr));
  2092. X  MES("   - supposed",ftr_string(SUP_attr));
  2093. X  MES("   - disabled",ftr_string(DISAB_attr));
  2094. X  MES("Terminal/driver hazards",terminal_hazards());
  2095. X
  2096. X  PB("8 bit clean", have_8bit_clean);
  2097. X  PB("Use national mode", use_national);
  2098. X  PB1("8 bit personality", personality_8bit,default_personality);
  2099. X  PB("XTerm mode", xterm_latin1_magic);
  2100. X  PV1("Keyboard language", keyboard_language,default_language);
  2101. X  PMP("Keyboard charset",keyboard_charset);
  2102. X  PF("Bank G0 font", used_sets[0]);
  2103. X  PF("Bank G1 font", used_sets[1]);
  2104. X  PF("Bank G2 font", used_sets[2]);
  2105. X  PF("Bank G3 font", used_sets[3]);
  2106. X  PV1("Lines",lines,def_lines);
  2107. X  PV1("Columns",columns,def_columns);
  2108. X  printer(rCs("Saved (or exit) terminal state"),1);
  2109. X  PB1("8 bit characters",     saved_multinational,default_multinational);  
  2110. X  PB1("8 bit personality",    saved_personality,default_personality);
  2111. X  PB1("Autowrap",             saved_autowrap,default_autowrap);
  2112. X  PB1("App. cursor keys",     saved_application,default_application);
  2113. X  PB1("Data processing keys", saved_legend,default_legend);
  2114. X  PB1("Newline mode",         saved_newline,default_newline);
  2115. X  PF("Bank G0 font", default_sets[0]);
  2116. X  PF("Bank G1 font", default_sets[1]);
  2117. X  PF("Bank G2 font", default_sets[2]);
  2118. X  PF("Bank G3 font", default_sets[3]);
  2119. X
  2120. X#undef MES
  2121. X#undef PMP
  2122. X#undef PV
  2123. X#undef PB
  2124. X#undef PB1
  2125. X#undef PF
  2126. X}
  2127. X
  2128. Xstatic int ASCII_set = 0; /* ASCII or it's superset */
  2129. X
  2130. Xstatic int find_ASCII(void) {
  2131. X  int i;
  2132. X  for (i = 0; i < 4; i++)
  2133. X    if (-1 != used_sets[i] && (sets[used_sets[i]].area & A_ASCII))
  2134. X      return used_sets[i];
  2135. X  
  2136. X  PANIC("Software failure/ASCII compatible font not found from any bank!");
  2137. X  return 0;
  2138. X}
  2139. X
  2140. Xint keyboard_charset = MAP_ASCII;
  2141. X
  2142. Xvoid set_terminal_state(void) {
  2143. X  if (terminal_type_pass == READY_PASS) {
  2144. X    int i;
  2145. X    int LANG = saved(saved_language,default_language);
  2146. X    use_national = -1;
  2147. X
  2148. X    if (HAZ_MAY(HAZ_national)) {
  2149. X      use_national = 1;
  2150. X      have_8bit_clean = 0;
  2151. X      default_multinational = 0;
  2152. X    }
  2153. X      
  2154. X    /* DEFAULT */
  2155. X    default_sets[0] = saved(saved_multinational,default_multinational)
  2156. X      ? find_set_by_name(rCs("ASCII"),0)
  2157. X    : find_set_by_language(LANG,
  2158. X                   saved(saved_personality,default_personality));
  2159. X    if (-1 == default_sets[0])
  2160. X      default_sets[0] = find_set_by_name(rCs("ASCII"),0);
  2161. SHAR_EOF
  2162. echo "End of part 9"
  2163. echo "File control.c is continued in part 10"
  2164. echo "10" > s2_seq_.tmp
  2165. exit 0
  2166.