tty-slang.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. /*
  2. Interface to the terminal controlling library.
  3. Slang wrapper.
  4. Copyright (C) 2005-2018
  5. Free Software Foundation, Inc.
  6. Written by:
  7. Andrew Borodin <aborodin@vmail.ru>, 2009
  8. Egmont Koblinger <egmont@gmail.com>, 2010
  9. This file is part of the Midnight Commander.
  10. The Midnight Commander is free software: you can redistribute it
  11. and/or modify it under the terms of the GNU General Public License as
  12. published by the Free Software Foundation, either version 3 of the License,
  13. or (at your option) any later version.
  14. The Midnight Commander is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. GNU General Public License for more details.
  18. You should have received a copy of the GNU General Public License
  19. along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /** \file
  22. * \brief Source: S-Lang-based tty layer of Midnight Commander
  23. */
  24. #include <config.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <sys/types.h> /* size_t */
  29. #include <unistd.h>
  30. #ifdef HAVE_SYS_IOCTL_H
  31. #include <sys/ioctl.h>
  32. #endif
  33. #include <termios.h>
  34. #include "lib/global.h"
  35. #include "lib/strutil.h" /* str_term_form */
  36. #include "lib/util.h" /* is_printable() */
  37. #include "tty-internal.h" /* mc_tty_normalize_from_utf8() */
  38. #include "tty.h"
  39. #include "color.h"
  40. #include "color-slang.h"
  41. #include "color-internal.h"
  42. #include "mouse.h" /* Gpm_Event is required in key.h */
  43. #include "key.h" /* define_sequence */
  44. #include "win.h"
  45. /*** global variables ****************************************************************************/
  46. /* If true program softkeys (HP terminals only) on startup and after every
  47. command ran in the subshell to the description found in the termcap/terminfo
  48. database */
  49. int reset_hp_softkeys = 0;
  50. /*** file scope macro definitions ****************************************************************/
  51. #ifndef SLTT_MAX_SCREEN_COLS
  52. #define SLTT_MAX_SCREEN_COLS 512
  53. #endif
  54. #ifndef SLTT_MAX_SCREEN_ROWS
  55. #define SLTT_MAX_SCREEN_ROWS 512
  56. #endif
  57. /*** file scope type declarations ****************************************************************/
  58. /*** file scope variables ************************************************************************/
  59. /* Various saved termios settings that we control here */
  60. static struct termios boot_mode;
  61. static struct termios new_mode;
  62. /* Controls whether we should wait for input in tty_lowlevel_getch */
  63. static gboolean no_slang_delay;
  64. static gboolean slsmg_active = FALSE;
  65. /* This table describes which capabilities we want and which values we
  66. * assign to them.
  67. */
  68. static const struct
  69. {
  70. int key_code;
  71. const char *key_name;
  72. } key_table[] =
  73. {
  74. /* *INDENT-OFF* */
  75. { KEY_F (0), "k0" },
  76. { KEY_F (1), "k1" },
  77. { KEY_F (2), "k2" },
  78. { KEY_F (3), "k3" },
  79. { KEY_F (4), "k4" },
  80. { KEY_F (5), "k5" },
  81. { KEY_F (6), "k6" },
  82. { KEY_F (7), "k7" },
  83. { KEY_F (8), "k8" },
  84. { KEY_F (9), "k9" },
  85. { KEY_F (10), "k;" },
  86. { KEY_F (11), "F1" },
  87. { KEY_F (12), "F2" },
  88. { KEY_F (13), "F3" },
  89. { KEY_F (14), "F4" },
  90. { KEY_F (15), "F5" },
  91. { KEY_F (16), "F6" },
  92. { KEY_F (17), "F7" },
  93. { KEY_F (18), "F8" },
  94. { KEY_F (19), "F9" },
  95. { KEY_F (20), "FA" },
  96. { KEY_IC, "kI" },
  97. { KEY_NPAGE, "kN" },
  98. { KEY_PPAGE, "kP" },
  99. { KEY_LEFT, "kl" },
  100. { KEY_RIGHT, "kr" },
  101. { KEY_UP, "ku" },
  102. { KEY_DOWN, "kd" },
  103. { KEY_DC, "kD" },
  104. { KEY_BACKSPACE, "kb" },
  105. { KEY_HOME, "kh" },
  106. { KEY_END, "@7" },
  107. { 0, NULL }
  108. /* *INDENT-ON* */
  109. };
  110. /* --------------------------------------------------------------------------------------------- */
  111. /*** file scope functions ************************************************************************/
  112. /* --------------------------------------------------------------------------------------------- */
  113. static void
  114. tty_setup_sigwinch (void (*handler) (int))
  115. {
  116. (void) SLsignal (SIGWINCH, handler);
  117. }
  118. /* --------------------------------------------------------------------------------------------- */
  119. static void
  120. sigwinch_handler (int dummy)
  121. {
  122. (void) dummy;
  123. mc_global.tty.winch_flag = 1;
  124. (void) SLsignal (SIGWINCH, sigwinch_handler);
  125. }
  126. /* --------------------------------------------------------------------------------------------- */
  127. /* HP Terminals have capabilities (pfkey, pfloc, pfx) to program function keys.
  128. elm 2.4pl15 invoked with the -K option utilizes these softkeys and the
  129. consequence is that function keys don't work in MC sometimes...
  130. Unfortunately I don't now the one and only escape sequence to turn off.
  131. softkeys (elm uses three different capabilities to turn on softkeys and two.
  132. capabilities to turn them off)..
  133. Among other things elm uses the pair we already use in slang_keypad. That's.
  134. the reason why I call slang_reset_softkeys from slang_keypad. In lack of
  135. something better the softkeys are programmed to their defaults from the
  136. termcap/terminfo database.
  137. The escape sequence to program the softkeys is taken from elm and it is.
  138. hardcoded because neither slang nor ncurses 4.1 know how to 'printf' this.
  139. sequence. -- Norbert
  140. */
  141. static void
  142. slang_reset_softkeys (void)
  143. {
  144. int key;
  145. static const char display[] = " ";
  146. char tmp[BUF_SMALL];
  147. for (key = 1; key < 9; key++)
  148. {
  149. char *send;
  150. g_snprintf (tmp, sizeof (tmp), "k%d", key);
  151. send = SLtt_tgetstr (tmp);
  152. if (send != NULL)
  153. {
  154. g_snprintf (tmp, sizeof (tmp), ESC_STR "&f%dk%dd%dL%s%s", key,
  155. (int) (sizeof (display) - 1), (int) strlen (send), display, send);
  156. SLtt_write_string (tmp);
  157. }
  158. }
  159. }
  160. /* --------------------------------------------------------------------------------------------- */
  161. static void
  162. do_define_key (int code, const char *strcap)
  163. {
  164. char *seq;
  165. seq = SLtt_tgetstr ((SLFUTURE_CONST char *) strcap);
  166. if (seq != NULL)
  167. define_sequence (code, seq, MCKEY_NOACTION);
  168. }
  169. /* --------------------------------------------------------------------------------------------- */
  170. static void
  171. load_terminfo_keys (void)
  172. {
  173. int i;
  174. for (i = 0; key_table[i].key_code; i++)
  175. do_define_key (key_table[i].key_code, key_table[i].key_name);
  176. }
  177. /* --------------------------------------------------------------------------------------------- */
  178. /*** public functions ****************************************************************************/
  179. /* --------------------------------------------------------------------------------------------- */
  180. int
  181. mc_tty_normalize_lines_char (const char *str)
  182. {
  183. char *str2;
  184. int res;
  185. struct mc_tty_lines_struct
  186. {
  187. const char *line;
  188. int line_code;
  189. } const lines_codes[] = {
  190. {"\342\224\214", SLSMG_ULCORN_CHAR},
  191. {"\342\224\220", SLSMG_URCORN_CHAR},
  192. {"\342\224\224", SLSMG_LLCORN_CHAR},
  193. {"\342\224\230", SLSMG_LRCORN_CHAR},
  194. {"\342\224\234", SLSMG_LTEE_CHAR},
  195. {"\342\224\244", SLSMG_RTEE_CHAR},
  196. {"\342\224\254", SLSMG_UTEE_CHAR},
  197. {"\342\224\264", SLSMG_DTEE_CHAR},
  198. {"\342\224\200", SLSMG_HLINE_CHAR},
  199. {"\342\224\202", SLSMG_VLINE_CHAR},
  200. {"\342\224\274", SLSMG_PLUS_CHAR},
  201. {NULL, 0}
  202. };
  203. if (!str)
  204. return (int) ' ';
  205. for (res = 0; lines_codes[res].line; res++)
  206. {
  207. if (strcmp (str, lines_codes[res].line) == 0)
  208. return lines_codes[res].line_code;
  209. }
  210. str2 = mc_tty_normalize_from_utf8 (str);
  211. res = g_utf8_get_char_validated (str2, -1);
  212. if (res < 0)
  213. res = (unsigned char) str2[0];
  214. g_free (str2);
  215. return res;
  216. }
  217. /* --------------------------------------------------------------------------------------------- */
  218. void
  219. tty_init (gboolean mouse_enable, gboolean is_xterm)
  220. {
  221. SLtt_Ignore_Beep = 1;
  222. SLutf8_enable (-1); /* has to be called first before any of the other functions. */
  223. SLtt_get_terminfo ();
  224. /*
  225. * If the terminal in not in terminfo but begins with a well-known
  226. * string such as "linux" or "xterm" S-Lang will go on, but the
  227. * terminal size and several other variables won't be initialized
  228. * (as of S-Lang 1.4.4). Detect it and abort. Also detect extremely
  229. * small, large and negative screen dimensions.
  230. */
  231. if ((COLS < 10) || (LINES < 5)
  232. || (COLS > SLTT_MAX_SCREEN_COLS) || (LINES > SLTT_MAX_SCREEN_ROWS))
  233. {
  234. fprintf (stderr,
  235. _("Screen size %dx%d is not supported.\n"
  236. "Check the TERM environment variable.\n"), COLS, LINES);
  237. exit (EXIT_FAILURE);
  238. }
  239. tcgetattr (fileno (stdin), &boot_mode);
  240. /* 255 = ignore abort char; XCTRL('g') for abort char = ^g */
  241. SLang_init_tty (XCTRL ('g'), 1, 0);
  242. if (mc_global.tty.ugly_line_drawing)
  243. SLtt_Has_Alt_Charset = 0;
  244. /* If SLang uses fileno(stderr) for terminal input MC will hang
  245. if we call SLang_getkey between calls to open_error_pipe and
  246. close_error_pipe, e.g. when we do a growing view of an gzipped
  247. file. */
  248. if (SLang_TT_Read_FD == fileno (stderr))
  249. SLang_TT_Read_FD = fileno (stdin);
  250. if (tcgetattr (SLang_TT_Read_FD, &new_mode) == 0)
  251. {
  252. #ifdef VDSUSP
  253. new_mode.c_cc[VDSUSP] = NULL_VALUE; /* to ignore ^Y */
  254. #endif
  255. #ifdef VLNEXT
  256. new_mode.c_cc[VLNEXT] = NULL_VALUE; /* to ignore ^V */
  257. #endif
  258. tcsetattr (SLang_TT_Read_FD, TCSADRAIN, &new_mode);
  259. }
  260. tty_reset_prog_mode ();
  261. load_terminfo_keys ();
  262. SLtt_Blink_Mode = (tty_use_256colors () || tty_use_truecolors (NULL)) ? 1 : 0;
  263. tty_start_interrupt_key ();
  264. /* It's the small part from the previous init_key() */
  265. init_key_input_fd ();
  266. /* For 8-bit locales, NCurses handles 154 (0x9A) symbol properly, while S-Lang
  267. * requires SLsmg_Display_Eight_Bit >= 154 (OR manual filtering if xterm display
  268. * detected - but checking TERM would fail under screen, OR running xterm
  269. * with allowC1Printable).
  270. */
  271. tty_display_8bit (FALSE);
  272. SLsmg_init_smg ();
  273. slsmg_active = TRUE;
  274. if (!mouse_enable)
  275. use_mouse_p = MOUSE_DISABLED;
  276. tty_init_xterm_support (is_xterm); /* do it before tty_enter_ca_mode() call */
  277. tty_enter_ca_mode ();
  278. tty_keypad (TRUE);
  279. tty_nodelay (FALSE);
  280. tty_setup_sigwinch (sigwinch_handler);
  281. }
  282. /* --------------------------------------------------------------------------------------------- */
  283. void
  284. tty_shutdown (void)
  285. {
  286. char *op_cap;
  287. tty_reset_shell_mode ();
  288. tty_noraw_mode ();
  289. tty_keypad (FALSE);
  290. tty_reset_screen ();
  291. tty_exit_ca_mode ();
  292. SLang_reset_tty ();
  293. slsmg_active = FALSE;
  294. /* Load the op capability to reset the colors to those that were
  295. * active when the program was started up
  296. */
  297. op_cap = SLtt_tgetstr ((SLFUTURE_CONST char *) "op");
  298. if (op_cap != NULL)
  299. {
  300. fputs (op_cap, stdout);
  301. fflush (stdout);
  302. }
  303. }
  304. /* --------------------------------------------------------------------------------------------- */
  305. void
  306. tty_enter_ca_mode (void)
  307. {
  308. /* S-Lang handles alternate screen switching and cursor position saving */
  309. }
  310. /* --------------------------------------------------------------------------------------------- */
  311. void
  312. tty_exit_ca_mode (void)
  313. {
  314. /* S-Lang handles alternate screen switching and cursor position restoring */
  315. }
  316. /* --------------------------------------------------------------------------------------------- */
  317. void
  318. tty_change_screen_size (void)
  319. {
  320. SLtt_get_screen_size ();
  321. if (slsmg_active)
  322. SLsmg_reinit_smg ();
  323. #ifdef ENABLE_SUBSHELL
  324. if (mc_global.tty.use_subshell)
  325. tty_resize (mc_global.tty.subshell_pty);
  326. #endif
  327. }
  328. /* --------------------------------------------------------------------------------------------- */
  329. /* Done each time we come back from done mode */
  330. void
  331. tty_reset_prog_mode (void)
  332. {
  333. tcsetattr (SLang_TT_Read_FD, TCSANOW, &new_mode);
  334. SLsmg_init_smg ();
  335. slsmg_active = TRUE;
  336. SLsmg_touch_lines (0, LINES);
  337. }
  338. /* --------------------------------------------------------------------------------------------- */
  339. /* Called each time we want to shutdown slang screen manager */
  340. void
  341. tty_reset_shell_mode (void)
  342. {
  343. tcsetattr (SLang_TT_Read_FD, TCSANOW, &boot_mode);
  344. }
  345. /* --------------------------------------------------------------------------------------------- */
  346. void
  347. tty_raw_mode (void)
  348. {
  349. tcsetattr (SLang_TT_Read_FD, TCSANOW, &new_mode);
  350. }
  351. /* --------------------------------------------------------------------------------------------- */
  352. void
  353. tty_noraw_mode (void)
  354. {
  355. }
  356. /* --------------------------------------------------------------------------------------------- */
  357. void
  358. tty_noecho (void)
  359. {
  360. }
  361. /* --------------------------------------------------------------------------------------------- */
  362. int
  363. tty_flush_input (void)
  364. {
  365. return 0; /* OK */
  366. }
  367. /* --------------------------------------------------------------------------------------------- */
  368. void
  369. tty_keypad (gboolean set)
  370. {
  371. char *keypad_string;
  372. keypad_string = SLtt_tgetstr ((SLFUTURE_CONST char *) (set ? "ks" : "ke"));
  373. if (keypad_string != NULL)
  374. SLtt_write_string (keypad_string);
  375. if (set && reset_hp_softkeys)
  376. slang_reset_softkeys ();
  377. }
  378. /* --------------------------------------------------------------------------------------------- */
  379. void
  380. tty_nodelay (gboolean set)
  381. {
  382. no_slang_delay = set;
  383. }
  384. /* --------------------------------------------------------------------------------------------- */
  385. int
  386. tty_baudrate (void)
  387. {
  388. return SLang_TT_Baud_Rate;
  389. }
  390. /* --------------------------------------------------------------------------------------------- */
  391. int
  392. tty_lowlevel_getch (void)
  393. {
  394. int c;
  395. if (no_slang_delay && (SLang_input_pending (0) == 0))
  396. return -1;
  397. c = SLang_getkey ();
  398. if (c == SLANG_GETKEY_ERROR)
  399. {
  400. fprintf (stderr,
  401. "SLang_getkey returned SLANG_GETKEY_ERROR\n"
  402. "Assuming EOF on stdin and exiting\n");
  403. exit (EXIT_FAILURE);
  404. }
  405. return c;
  406. }
  407. /* --------------------------------------------------------------------------------------------- */
  408. int
  409. tty_reset_screen (void)
  410. {
  411. SLsmg_reset_smg ();
  412. slsmg_active = FALSE;
  413. return 0; /* OK */
  414. }
  415. /* --------------------------------------------------------------------------------------------- */
  416. void
  417. tty_touch_screen (void)
  418. {
  419. SLsmg_touch_lines (0, LINES);
  420. }
  421. /* --------------------------------------------------------------------------------------------- */
  422. void
  423. tty_gotoyx (int y, int x)
  424. {
  425. SLsmg_gotorc (y, x);
  426. }
  427. /* --------------------------------------------------------------------------------------------- */
  428. void
  429. tty_getyx (int *py, int *px)
  430. {
  431. *py = SLsmg_get_row ();
  432. *px = SLsmg_get_column ();
  433. }
  434. /* --------------------------------------------------------------------------------------------- */
  435. void
  436. tty_draw_hline (int y, int x, int ch, int len)
  437. {
  438. int x1;
  439. if (y < 0 || y >= LINES || x >= COLS)
  440. return;
  441. x1 = x;
  442. if (x < 0)
  443. {
  444. len += x;
  445. if (len <= 0)
  446. return;
  447. x = 0;
  448. }
  449. if (ch == ACS_HLINE)
  450. ch = mc_tty_frm[MC_TTY_FRM_HORIZ];
  451. if (ch == 0)
  452. ch = ACS_HLINE;
  453. SLsmg_gotorc (y, x);
  454. if (ch == ACS_HLINE)
  455. SLsmg_draw_hline (len);
  456. else
  457. while (len-- != 0)
  458. tty_print_char (ch);
  459. SLsmg_gotorc (y, x1);
  460. }
  461. /* --------------------------------------------------------------------------------------------- */
  462. void
  463. tty_draw_vline (int y, int x, int ch, int len)
  464. {
  465. int y1;
  466. if (x < 0 || x >= COLS || y >= LINES)
  467. return;
  468. y1 = y;
  469. if (y < 0)
  470. {
  471. len += y;
  472. if (len <= 0)
  473. return;
  474. y = 0;
  475. }
  476. if (ch == ACS_VLINE)
  477. ch = mc_tty_frm[MC_TTY_FRM_VERT];
  478. if (ch == 0)
  479. ch = ACS_VLINE;
  480. SLsmg_gotorc (y, x);
  481. if (ch == ACS_VLINE)
  482. SLsmg_draw_vline (len);
  483. else
  484. {
  485. int pos = 0;
  486. while (len-- != 0)
  487. {
  488. SLsmg_gotorc (y + pos, x);
  489. tty_print_char (ch);
  490. pos++;
  491. }
  492. }
  493. SLsmg_gotorc (y1, x);
  494. }
  495. /* --------------------------------------------------------------------------------------------- */
  496. void
  497. tty_fill_region (int y, int x, int rows, int cols, unsigned char ch)
  498. {
  499. SLsmg_fill_region (y, x, rows, cols, ch);
  500. }
  501. /* --------------------------------------------------------------------------------------------- */
  502. void
  503. tty_set_alt_charset (gboolean alt_charset)
  504. {
  505. SLsmg_set_char_set ((int) alt_charset);
  506. }
  507. /* --------------------------------------------------------------------------------------------- */
  508. void
  509. tty_display_8bit (gboolean what)
  510. {
  511. SLsmg_Display_Eight_Bit = what ? 128 : 160;
  512. }
  513. /* --------------------------------------------------------------------------------------------- */
  514. void
  515. tty_print_char (int c)
  516. {
  517. SLsmg_write_char ((SLwchar_Type) ((unsigned int) c));
  518. }
  519. /* --------------------------------------------------------------------------------------------- */
  520. void
  521. tty_print_alt_char (int c, gboolean single)
  522. {
  523. #define DRAW(x, y) (x == y) \
  524. ? SLsmg_draw_object (SLsmg_get_row(), SLsmg_get_column(), x) \
  525. : SLsmg_write_char ((unsigned int) y)
  526. switch (c)
  527. {
  528. case ACS_VLINE:
  529. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT]);
  530. break;
  531. case ACS_HLINE:
  532. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ]);
  533. break;
  534. case ACS_LTEE:
  535. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_LEFTMIDDLE : MC_TTY_FRM_DLEFTMIDDLE]);
  536. break;
  537. case ACS_RTEE:
  538. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_RIGHTMIDDLE : MC_TTY_FRM_DRIGHTMIDDLE]);
  539. break;
  540. case ACS_TTEE:
  541. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_TOPMIDDLE : MC_TTY_FRM_DTOPMIDDLE]);
  542. break;
  543. case ACS_BTEE:
  544. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_BOTTOMMIDDLE : MC_TTY_FRM_DBOTTOMMIDDLE]);
  545. break;
  546. case ACS_ULCORNER:
  547. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_LEFTTOP : MC_TTY_FRM_DLEFTTOP]);
  548. break;
  549. case ACS_LLCORNER:
  550. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_LEFTBOTTOM : MC_TTY_FRM_DLEFTBOTTOM]);
  551. break;
  552. case ACS_URCORNER:
  553. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_RIGHTTOP : MC_TTY_FRM_DRIGHTTOP]);
  554. break;
  555. case ACS_LRCORNER:
  556. DRAW (c, mc_tty_frm[single ? MC_TTY_FRM_RIGHTBOTTOM : MC_TTY_FRM_DRIGHTBOTTOM]);
  557. break;
  558. case ACS_PLUS:
  559. DRAW (c, mc_tty_frm[MC_TTY_FRM_CROSS]);
  560. break;
  561. default:
  562. SLsmg_write_char ((unsigned int) c);
  563. }
  564. #undef DRAW
  565. }
  566. /* --------------------------------------------------------------------------------------------- */
  567. void
  568. tty_print_anychar (int c)
  569. {
  570. if (c > 255)
  571. {
  572. char str[UTF8_CHAR_LEN + 1];
  573. int res;
  574. res = g_unichar_to_utf8 (c, str);
  575. if (res == 0)
  576. {
  577. str[0] = '.';
  578. str[1] = '\0';
  579. }
  580. else
  581. {
  582. str[res] = '\0';
  583. }
  584. SLsmg_write_string ((char *) str_term_form (str));
  585. }
  586. else
  587. {
  588. if (!is_printable (c))
  589. c = '.';
  590. SLsmg_write_char ((SLwchar_Type) ((unsigned int) c));
  591. }
  592. }
  593. /* --------------------------------------------------------------------------------------------- */
  594. void
  595. tty_print_string (const char *s)
  596. {
  597. SLsmg_write_string ((char *) str_term_form (s));
  598. }
  599. /* --------------------------------------------------------------------------------------------- */
  600. void
  601. tty_printf (const char *fmt, ...)
  602. {
  603. va_list args;
  604. va_start (args, fmt);
  605. SLsmg_vprintf ((char *) fmt, args);
  606. va_end (args);
  607. }
  608. /* --------------------------------------------------------------------------------------------- */
  609. char *
  610. tty_tgetstr (const char *cap)
  611. {
  612. return SLtt_tgetstr ((SLFUTURE_CONST char *) cap);
  613. }
  614. /* --------------------------------------------------------------------------------------------- */
  615. void
  616. tty_refresh (void)
  617. {
  618. SLsmg_refresh ();
  619. }
  620. /* --------------------------------------------------------------------------------------------- */
  621. void
  622. tty_beep (void)
  623. {
  624. SLtt_beep ();
  625. }
  626. /* --------------------------------------------------------------------------------------------- */