root/lib/tty/tty-slang.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. tty_setup_sigwinch
  2. sigwinch_handler
  3. slang_reset_softkeys
  4. do_define_key
  5. load_terminfo_keys
  6. mc_tty_normalize_lines_char
  7. tty_init
  8. tty_shutdown
  9. tty_enter_ca_mode
  10. tty_exit_ca_mode
  11. tty_change_screen_size
  12. tty_reset_prog_mode
  13. tty_reset_shell_mode
  14. tty_raw_mode
  15. tty_noraw_mode
  16. tty_noecho
  17. tty_flush_input
  18. tty_keypad
  19. tty_nodelay
  20. tty_baudrate
  21. tty_lowlevel_getch
  22. tty_reset_screen
  23. tty_touch_screen
  24. tty_gotoyx
  25. tty_getyx
  26. tty_draw_hline
  27. tty_draw_vline
  28. tty_fill_region
  29. tty_colorize_area
  30. tty_set_alt_charset
  31. tty_display_8bit
  32. tty_print_char
  33. tty_print_alt_char
  34. tty_print_anychar
  35. tty_print_string
  36. tty_printf
  37. tty_tgetstr
  38. tty_refresh
  39. tty_beep

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

/* [previous][next][first][last][top][bottom][index][help]  */