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

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