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

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