terminal.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /******************************************************************************
  2. * This file is part of TinTin++ *
  3. * *
  4. * Copyright 2004-2020 Igor van den Hoven *
  5. * *
  6. * TinTin++ is free software; you can redistribute it and/or modify *
  7. * it under the terms of the GNU General Public License as published by *
  8. * the Free Software Foundation; either version 3 of the License, or *
  9. * (at your option) any later version. *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with TinTin++. If not, see https://www.gnu.org/licenses. *
  18. ******************************************************************************/
  19. /******************************************************************************
  20. * T I N T I N + + *
  21. * *
  22. * coded by Igor van den Hoven 2006 *
  23. ******************************************************************************/
  24. #include "tintin.h"
  25. #ifdef HAVE_SYS_IOCTL_H
  26. #include <sys/ioctl.h>
  27. #endif
  28. #include <termios.h>
  29. void init_terminal(struct session *ses)
  30. {
  31. struct termios io;
  32. if (tcgetattr(0, &gtd->old_terminal))
  33. {
  34. syserr_fatal(-1, "init_terminal: tcgetattr 1");
  35. }
  36. io = gtd->old_terminal;
  37. /*
  38. Canonical mode off
  39. */
  40. DEL_BIT(io.c_lflag, ICANON);
  41. io.c_cc[VMIN] = 1;
  42. io.c_cc[VTIME] = 0;
  43. io.c_cc[VSTART] = 255;
  44. io.c_cc[VSTOP] = 255;
  45. io.c_cc[VINTR] = 4; // ctrl-d
  46. /*
  47. Make the terminalal as raw as possible
  48. */
  49. /*
  50. DEL_BIT(io.c_iflag, IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
  51. DEL_BIT(io.c_oflag, OPOST);
  52. DEL_BIT(io.c_cflag, CSIZE|PARENB);
  53. */
  54. DEL_BIT(io.c_lflag, ECHO|ECHONL|IEXTEN|ISIG);
  55. // DEL_BIT(io.c_lflag, ECHO|ECHONL|IEXTEN|ISIG);
  56. SET_BIT(io.c_cflag, CS8);
  57. if (tcsetattr(0, TCSANOW, &io))
  58. {
  59. syserr_printf(ses, "init_terminal: tcsetattr");
  60. }
  61. if (tcgetattr(0, &gts->cur_terminal))
  62. {
  63. syserr_fatal(-1, "init_terminal: tcgetattr 2");
  64. }
  65. print_stdout("\e=");
  66. print_stdout("\e[>4;1m");
  67. }
  68. void reset_terminal(struct session *ses)
  69. {
  70. if (gtd->detach_port == 0)
  71. {
  72. if (tcsetattr(0, TCSANOW, &gtd->old_terminal))
  73. {
  74. syserr_printf(ses, "reset_terminal: tcsetattr");
  75. }
  76. }
  77. if (HAS_BIT(gtd->flags, TINTIN_FLAG_MOUSETRACKING))
  78. {
  79. print_stdout("\e[?1000l\e[?1002l\e[?1004l\e[?1006l");
  80. }
  81. print_stdout("\e[?25h");
  82. print_stdout("\e[23t");
  83. print_stdout("\e[>4n");
  84. }
  85. void save_session_terminal(struct session *ses)
  86. {
  87. tcgetattr(0, &ses->cur_terminal);
  88. }
  89. void refresh_session_terminal(struct session *ses)
  90. {
  91. // tcsetattr(0, TCSANOW, &ses->cur_terminal);
  92. }
  93. void echo_off(struct session *ses)
  94. {
  95. struct termios io;
  96. tcgetattr(STDIN_FILENO, &io);
  97. DEL_BIT(io.c_lflag, ECHO|ECHONL);
  98. tcsetattr(STDIN_FILENO, TCSADRAIN, &io);
  99. }
  100. void echo_on(struct session *ses)
  101. {
  102. struct termios io;
  103. tcgetattr(STDIN_FILENO, &io);
  104. SET_BIT(io.c_lflag, ECHO|ECHONL);
  105. tcsetattr(STDIN_FILENO, TCSADRAIN, &io);
  106. }
  107. void init_terminal_size(struct session *ses)
  108. {
  109. struct winsize screen;
  110. static int old_rows, old_cols;
  111. push_call("init_terminal_size(%p)",ses);
  112. if (ses == gts)
  113. {
  114. old_rows = gtd->screen->rows;
  115. old_cols = gtd->screen->cols;
  116. if (ioctl(1, TIOCGWINSZ, &screen) >= 0)
  117. {
  118. init_screen(screen.ws_row, screen.ws_col, screen.ws_ypixel, screen.ws_xpixel);
  119. if (gtd->attach_sock)
  120. {
  121. char buf[100];
  122. sprintf(buf, "\e[8;%d;%dt\e[4;%d;%dt\e[7t", screen.ws_row, screen.ws_col, screen.ws_ypixel, screen.ws_xpixel);
  123. write(gtd->attach_sock, buf, strlen(buf));
  124. }
  125. }
  126. }
  127. if (ses->scroll)
  128. {
  129. SET_BIT(ses->scroll->flags, SCROLL_FLAG_RESIZE);
  130. }
  131. if (ses->map)
  132. {
  133. SET_BIT(ses->map->flags, MAP_FLAG_RESIZE);
  134. }
  135. init_split(ses, ses->split->sav_top_row, ses->split->sav_top_col, ses->split->sav_bot_row, ses->split->sav_bot_col);
  136. check_all_events(ses, SUB_ARG, 0, 4, "SCREEN RESIZE", ntos(gtd->screen->rows), ntos(gtd->screen->cols), ntos(gtd->screen->height), ntos(gtd->screen->width));
  137. if (old_rows <= old_cols / 2 && gtd->screen->rows > gtd->screen->cols / 2)
  138. {
  139. check_all_events(ses, SUB_ARG, 0, 4, "SCREEN ROTATE PORTRAIT", ntos(gtd->screen->rows), ntos(gtd->screen->cols), ntos(gtd->screen->height), ntos(gtd->screen->width));
  140. }
  141. else if (old_rows >= old_cols / 2 && gtd->screen->rows < gtd->screen->cols / 2)
  142. {
  143. check_all_events(ses, SUB_ARG, 0, 4, "SCREEN ROTATE LANDSCAPE", ntos(gtd->screen->rows), ntos(gtd->screen->cols), ntos(gtd->screen->height), ntos(gtd->screen->width));
  144. }
  145. msdp_update_all("SCREEN_ROWS", "%d", gtd->screen->rows);
  146. msdp_update_all("SCREEN_COLS", "%d", gtd->screen->cols);
  147. msdp_update_all("SCREEN_HEIGHT", "%d", gtd->screen->height);
  148. msdp_update_all("SCREEN_WIDTH", "%d", gtd->screen->width);
  149. pop_call();
  150. return;
  151. }
  152. int get_scroll_rows(struct session *ses)
  153. {
  154. return (ses->split->bot_row - ses->split->top_row);
  155. }
  156. int get_scroll_cols(struct session *ses)
  157. {
  158. return ses->wrap;
  159. }
  160. char *get_charset(struct session *ses)
  161. {
  162. switch (HAS_BIT(ses->charset, CHARSET_FLAG_ALL))
  163. {
  164. case CHARSET_FLAG_BIG5:
  165. return "BIG-5";
  166. case CHARSET_FLAG_GBK1:
  167. return "GBK-1";
  168. case CHARSET_FLAG_UTF8:
  169. return "UTF-8";
  170. case CHARSET_FLAG_UTF8|CHARSET_FLAG_BIG5TOUTF8:
  171. return "BIG5TOUTF8";
  172. case CHARSET_FLAG_UTF8|CHARSET_FLAG_FANSITOUTF8:
  173. return "FANSI";
  174. case CHARSET_FLAG_UTF8|CHARSET_FLAG_GBK1TOUTF8:
  175. return "GBK1TOUTF8";
  176. case CHARSET_FLAG_UTF8|CHARSET_FLAG_KOI8TOUTF8:
  177. return "KOI8TOUTF8";
  178. case CHARSET_FLAG_UTF8|CHARSET_FLAG_ISO1TOUTF8:
  179. return "ISO1TOUTF8";
  180. case CHARSET_FLAG_UTF8|CHARSET_FLAG_ISO2TOUTF8:
  181. return "ISO2TOUTF8";
  182. default:
  183. return "ASCII";
  184. }
  185. }