input.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  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. void process_input(void)
  26. {
  27. char input[STRING_SIZE];
  28. int len, out;
  29. push_call("process_input(void)");
  30. gtd->time_input = gtd->time;
  31. if (gtd->detach_port)
  32. {
  33. if (gtd->detach_sock > 0)
  34. {
  35. len = read(gtd->detach_sock, input, 1);
  36. if (len <= 0)
  37. {
  38. if (len == -1)
  39. {
  40. syserr_printf(gtd->ses, "process_input: read", gtd->detach_sock);
  41. }
  42. else
  43. {
  44. show_message(gtd->ses, LIST_COMMAND, "#DAEMON UPDATE: DETACHING FROM PID {%d} DUE TO READ FAILURE.", gtd->detach_pid);
  45. }
  46. gtd->detach_sock = close(gtd->detach_sock);
  47. pop_call();
  48. return;
  49. }
  50. }
  51. else
  52. {
  53. printf("process_input: error?\n");
  54. }
  55. }
  56. else
  57. {
  58. len = read(0, input, 1);
  59. }
  60. input[len] = 0;
  61. if (gtd->attach_sock)
  62. {
  63. out = write(gtd->attach_sock, input, 1);
  64. if (out >= 0)
  65. {
  66. pop_call();
  67. return;
  68. }
  69. gtd->attach_sock = close(gtd->attach_sock);
  70. show_message(gtd->ses, LIST_COMMAND, "#DAEMON ATTACH: WRITE ERROR: UNATTACHING.");
  71. }
  72. if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_SGA) && !HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO))
  73. {
  74. read_key(input, len);
  75. }
  76. else
  77. {
  78. read_line(input, len);
  79. }
  80. if (!HAS_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT))
  81. {
  82. pop_call();
  83. return;
  84. }
  85. DEL_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT);
  86. if (gtd->chat && gtd->chat->paste_time)
  87. {
  88. chat_paste(gtd->input_buf, NULL);
  89. pop_call();
  90. return;
  91. }
  92. if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO))
  93. {
  94. add_line_history(gtd->ses, gtd->input_buf);
  95. }
  96. if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO))
  97. {
  98. echo_command(gtd->ses, gtd->input_buf);
  99. }
  100. else
  101. {
  102. echo_command(gtd->ses, "");
  103. }
  104. if (gtd->ses->scroll->line != -1)
  105. {
  106. buffer_end(gtd->ses, "");
  107. }
  108. check_all_events(gtd->ses, SUB_ARG|SUB_SEC, 0, 1, "RECEIVED INPUT", gtd->input_buf);
  109. if (check_all_events(gtd->ses, SUB_ARG|SUB_SEC, 0, 1, "CATCH RECEIVED INPUT", gtd->input_buf) == 1)
  110. {
  111. pop_call();
  112. return;
  113. }
  114. if (HAS_BIT(gtd->flags, TINTIN_FLAG_CHILDLOCK))
  115. {
  116. write_mud(gtd->ses, gtd->input_buf, SUB_EOL);
  117. }
  118. else
  119. {
  120. gtd->ses = script_driver(gtd->ses, LIST_COMMAND, gtd->input_buf);
  121. }
  122. if (IS_SPLIT(gtd->ses))
  123. {
  124. erase_toeol();
  125. }
  126. gtd->input_buf[0] = 0;
  127. fflush(NULL);
  128. pop_call();
  129. return;
  130. }
  131. void read_line(char *input, int len)
  132. {
  133. int size, width, index;
  134. // gtd->input_buf[gtd->input_len] = 0;
  135. if (HAS_BIT(gtd->ses->flags, SES_FLAG_CONVERTMETA))
  136. {
  137. convert_meta(input, &gtd->macro_buf[strlen(gtd->macro_buf)], FALSE);
  138. }
  139. else if (HAS_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR))
  140. {
  141. convert_meta(input, &gtd->macro_buf[strlen(gtd->macro_buf)], TRUE);
  142. }
  143. else
  144. {
  145. strcat(gtd->macro_buf, input);
  146. }
  147. if (check_key(input, len))
  148. {
  149. return;
  150. }
  151. if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(gtd->macro_buf))
  152. {
  153. if (get_utf8_size(gtd->macro_buf) == 1)
  154. {
  155. return;
  156. }
  157. }
  158. if (gtd->macro_buf[0] == ASCII_ESC)
  159. {
  160. strcpy(input, gtd->macro_buf);
  161. convert_meta(input, gtd->macro_buf, FALSE);
  162. }
  163. get_utf8_index(gtd->macro_buf, &index);
  164. check_all_events(gtd->ses, SUB_ARG, 0, 2, "RECEIVED KEYPRESS", gtd->macro_buf, ntos(index));
  165. if (check_all_events(gtd->ses, SUB_ARG, 0, 2, "CATCH RECEIVED KEYPRESS", gtd->macro_buf, ntos(index)) == 1)
  166. {
  167. gtd->macro_buf[0] = 0;
  168. return;
  169. }
  170. while (gtd->macro_buf[0])
  171. {
  172. switch (gtd->macro_buf[0])
  173. {
  174. case ASCII_CR:
  175. case ASCII_LF:
  176. cursor_enter(gtd->ses, "");
  177. memmove(gtd->macro_buf, &gtd->macro_buf[1], 1 + strlen(&gtd->macro_buf[1]));
  178. break;
  179. default:
  180. if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) && gtd->macro_buf[0] & 128 && gtd->macro_buf[1])
  181. {
  182. size = get_utf8_width(gtd->macro_buf, &width);
  183. if (HAS_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT) && gtd->input_len != gtd->input_cur)
  184. {
  185. if (width)
  186. {
  187. cursor_delete(gtd->ses, "");
  188. }
  189. }
  190. ins_sprintf(&gtd->input_buf[gtd->input_cur], "%.*s", size, gtd->macro_buf);
  191. gtd->input_pos += width;
  192. gtd->input_cur += size;
  193. gtd->input_len += size;
  194. if (width && gtd->input_len != gtd->input_cur)
  195. {
  196. input_printf("\e[%d@%.*s", width, size, gtd->macro_buf);
  197. }
  198. else
  199. {
  200. input_printf("%.*s", size, gtd->macro_buf);
  201. }
  202. memmove(gtd->macro_buf, &gtd->macro_buf[size], 1 + strlen(&gtd->macro_buf[size]));
  203. }
  204. else
  205. {
  206. if (HAS_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT) && gtd->input_len != gtd->input_cur)
  207. {
  208. cursor_delete(gtd->ses, "");
  209. }
  210. ins_sprintf(&gtd->input_buf[gtd->input_cur], "%c", gtd->macro_buf[0]);
  211. gtd->input_len++;
  212. gtd->input_cur++;
  213. gtd->input_pos++;
  214. if (gtd->input_len != gtd->input_cur)
  215. {
  216. input_printf("\e[1@%c", gtd->macro_buf[0]);
  217. }
  218. else
  219. {
  220. input_printf("%c", gtd->macro_buf[0]);
  221. }
  222. memmove(gtd->macro_buf, &gtd->macro_buf[1], 1 + strlen(&gtd->macro_buf[1]));
  223. }
  224. // gtd->macro_buf[0] = 0;
  225. gtd->input_tmp[0] = 0;
  226. gtd->input_buf[gtd->input_len] = 0;
  227. cursor_check_line_modified(gtd->ses, "");
  228. DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE);
  229. kill_list(gtd->ses->list[LIST_COMMAND]);
  230. if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH))
  231. {
  232. cursor_history_find(gtd->ses, "");
  233. }
  234. break;
  235. }
  236. }
  237. }
  238. void read_key(char *input, int len)
  239. {
  240. int cnt;
  241. if (gtd->input_buf[0] == gtd->tintin_char)
  242. {
  243. read_line(input, len);
  244. return;
  245. }
  246. if (HAS_BIT(gtd->ses->flags, SES_FLAG_CONVERTMETA))
  247. {
  248. convert_meta(input, &gtd->macro_buf[strlen(gtd->macro_buf)], FALSE);
  249. }
  250. else if (HAS_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR))
  251. {
  252. convert_meta(input, &gtd->macro_buf[strlen(gtd->macro_buf)], TRUE);
  253. }
  254. else
  255. {
  256. strcat(gtd->macro_buf, input);
  257. }
  258. if (check_key(input, len))
  259. {
  260. return;
  261. }
  262. for (cnt = 0 ; gtd->macro_buf[cnt] ; cnt++)
  263. {
  264. switch (gtd->macro_buf[cnt])
  265. {
  266. case ASCII_CR:
  267. case ASCII_LF:
  268. gtd->input_buf[0] = 0;
  269. gtd->macro_buf[0] = 0;
  270. gtd->input_len = 0;
  271. if (HAS_BIT(gtd->ses->flags, SES_FLAG_RUN))
  272. {
  273. socket_printf(gtd->ses, 1, "%c", '\r');
  274. }
  275. else
  276. {
  277. socket_printf(gtd->ses, 2, "%c%c", '\r', '\n');
  278. }
  279. break;
  280. default:
  281. if (gtd->macro_buf[cnt] == gtd->tintin_char && gtd->input_buf[0] == 0)
  282. {
  283. if (gtd->input_len != gtd->input_cur)
  284. {
  285. print_stdout("\e[1@%c", gtd->macro_buf[cnt]);
  286. }
  287. else
  288. {
  289. print_stdout("%c", gtd->macro_buf[cnt]);
  290. }
  291. gtd->input_buf[0] = gtd->tintin_char;
  292. gtd->input_buf[1] = 0;
  293. gtd->macro_buf[0] = 0;
  294. gtd->input_len = 1;
  295. gtd->input_cur = 1;
  296. gtd->input_pos = 1;
  297. }
  298. else
  299. {
  300. socket_printf(gtd->ses, 1, "%c", gtd->macro_buf[cnt]);
  301. gtd->input_buf[0] = 127;
  302. gtd->macro_buf[0] = 0;
  303. gtd->input_len = 0;
  304. }
  305. break;
  306. }
  307. }
  308. }
  309. int check_key(char *input, int len)
  310. {
  311. char buf[BUFFER_SIZE];
  312. struct listroot *root;
  313. struct listnode *node;
  314. int cnt, val[5];
  315. push_call("check_key(%p,%d)",input,len);
  316. // tintin_printf2(gtd->ses, "check_key(%d,%s)",*gtd->macro_buf, gtd->macro_buf);
  317. if (!HAS_BIT(gtd->ses->flags, SES_FLAG_CONVERTMETA))
  318. {
  319. root = gtd->ses->list[LIST_MACRO];
  320. if (!HAS_BIT(root->flags, LIST_FLAG_IGNORE))
  321. {
  322. for (root->update = 0 ; root->update < root->used ; root->update++)
  323. {
  324. node = root->list[root->update];
  325. if (*node->arg1 == '^' && gtd->input_len)
  326. {
  327. continue;
  328. }
  329. else if (!strcmp(gtd->macro_buf, node->arg3))
  330. {
  331. strcpy(buf, node->arg2);
  332. if (HAS_BIT(node->flags, NODE_FLAG_ONESHOT))
  333. {
  334. delete_node_list(gtd->ses, LIST_MACRO, node);
  335. }
  336. script_driver(gtd->ses, LIST_MACRO, buf);
  337. gtd->macro_buf[0] = 0;
  338. pop_call();
  339. return TRUE;
  340. }
  341. else if (!strncmp(gtd->macro_buf, node->arg3, strlen(gtd->macro_buf)))
  342. {
  343. pop_call();
  344. return TRUE;
  345. }
  346. }
  347. }
  348. if (!HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_SGA) || HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO) || gtd->input_buf[0] == gtd->tintin_char)
  349. {
  350. for (cnt = 0 ; *cursor_table[cnt].fun != NULL ; cnt++)
  351. {
  352. if (*cursor_table[cnt].code)
  353. {
  354. if (!strcmp(gtd->macro_buf, cursor_table[cnt].code))
  355. {
  356. cursor_table[cnt].fun(gtd->ses, "");
  357. gtd->macro_buf[0] = 0;
  358. pop_call();
  359. return TRUE;
  360. }
  361. else if (!strncmp(gtd->macro_buf, cursor_table[cnt].code, strlen(gtd->macro_buf)))
  362. {
  363. pop_call();
  364. return TRUE;
  365. }
  366. }
  367. }
  368. }
  369. if (gtd->macro_buf[0] == ASCII_ESC)
  370. {
  371. if (gtd->macro_buf[1] == '[')
  372. {
  373. if (gtd->macro_buf[2] == '<' && !HAS_BIT(gtd->ses->list[LIST_BUTTON]->flags, LIST_FLAG_IGNORE))
  374. {
  375. val[0] = val[1] = val[2] = cnt = input[0] = 0;
  376. for (len = 3 ; gtd->macro_buf[len] ; len++)
  377. {
  378. if (isdigit(gtd->macro_buf[len]))
  379. {
  380. cat_sprintf(input, "%c", gtd->macro_buf[len]);
  381. }
  382. else
  383. {
  384. switch (gtd->macro_buf[len])
  385. {
  386. case ';':
  387. val[cnt++] = get_number(gtd->ses, input);
  388. input[0] = 0;
  389. break;
  390. case 'm':
  391. case 'M':
  392. val[cnt++] = get_number(gtd->ses, input);
  393. mouse_handler(gtd->ses, val[0], val[2], val[1], gtd->macro_buf[len]); // swap x y to row col
  394. gtd->macro_buf[0] = 0;
  395. pop_call();
  396. return TRUE;
  397. default:
  398. print_stdout("unknownmouse input error (%s)\n", gtd->macro_buf);
  399. gtd->macro_buf[0] = 0;
  400. pop_call();
  401. return TRUE;
  402. }
  403. }
  404. }
  405. pop_call();
  406. return TRUE;
  407. }
  408. else if (gtd->macro_buf[2] >= '0' && gtd->macro_buf[2] <= '9')
  409. {
  410. cnt = input[0] = 0;
  411. memset(val, 0, sizeof(val));
  412. // tintin_printf2(gtd->ses, "debug: %d %d %d %d %d", val[0], val[1], val[2], val[3], val[4], val[5]);
  413. for (len = 2 ; gtd->macro_buf[len] ; len++)
  414. {
  415. if (cnt > 5)
  416. {
  417. pop_call();
  418. return FALSE;
  419. }
  420. if (isdigit(gtd->macro_buf[len]))
  421. {
  422. cat_sprintf(input, "%c", gtd->macro_buf[len]);
  423. }
  424. else
  425. {
  426. switch (gtd->macro_buf[len])
  427. {
  428. case '-':
  429. if (input[0] == 0)
  430. {
  431. strcat(input, "-");
  432. }
  433. else
  434. {
  435. tintin_printf2(NULL, "\e[1;31merror: bad csi input (%s)\n", &gtd->macro_buf[1]);
  436. gtd->macro_buf[0] = 0;
  437. continue;
  438. }
  439. break;
  440. case ';':
  441. val[cnt++] = get_number(gtd->ses, input);
  442. input[0] = 0;
  443. break;
  444. case 't':
  445. val[cnt++] = get_number(gtd->ses, input);
  446. csit_handler(val[0], val[1], val[2]);
  447. gtd->macro_buf[0] = 0;
  448. pop_call();
  449. return TRUE;
  450. case '&':
  451. val[cnt++] = get_number(gtd->ses, input);
  452. input[0] = 0;
  453. break;
  454. case 'w':
  455. rqlp_handler(val[0], val[1], val[2], val[3]);
  456. gtd->macro_buf[0] = 0;
  457. pop_call();
  458. return TRUE;
  459. default:
  460. pop_call();
  461. return FALSE;
  462. }
  463. }
  464. }
  465. pop_call();
  466. return TRUE;
  467. }
  468. else if (gtd->macro_buf[2] == 0)
  469. {
  470. pop_call();
  471. return TRUE;
  472. }
  473. }
  474. else if (gtd->macro_buf[1] == ']')
  475. {
  476. switch (gtd->macro_buf[2])
  477. {
  478. case 'L':
  479. case 'l':
  480. for (len = 3 ; gtd->macro_buf[len] ; len++)
  481. {
  482. if (gtd->macro_buf[len] < 32)
  483. {
  484. input[len - 3] = 0;
  485. osc_handler(gtd->macro_buf[2], input);
  486. gtd->macro_buf[0] = 0;
  487. pop_call();
  488. return TRUE;
  489. }
  490. else
  491. {
  492. input[len - 3 ] = gtd->macro_buf[len];
  493. }
  494. }
  495. break;
  496. default:
  497. print_stdout("\e[1;31merror: unknown osc input (%s)\n", gtd->macro_buf);
  498. gtd->macro_buf[0] = 0;
  499. pop_call();
  500. return TRUE;
  501. }
  502. }
  503. else if (gtd->macro_buf[1] == 0)
  504. {
  505. pop_call();
  506. return TRUE;
  507. }
  508. }
  509. }
  510. pop_call();
  511. return FALSE;
  512. }
  513. void convert_meta(char *input, char *output, int eol)
  514. {
  515. char *pti, *pto;
  516. push_call("convert_meta(%p,%p,%d)",input,output,eol);
  517. pti = input;
  518. pto = output;
  519. while (*pti && pti - input < BUFFER_SIZE / 2)
  520. {
  521. switch (*pti)
  522. {
  523. case ASCII_ESC:
  524. *pto++ = '\\';
  525. *pto++ = 'e';
  526. pti++;
  527. break;
  528. case ASCII_DEL:
  529. *pto++ = '\\';
  530. *pto++ = 'x';
  531. *pto++ = '7';
  532. *pto++ = 'F';
  533. pti++;
  534. break;
  535. case ASCII_BEL:
  536. *pto++ = '\\';
  537. *pto++ = 'a';
  538. pti++;
  539. break;
  540. case ASCII_BS:
  541. *pto++ = '\\';
  542. *pto++ = 'b';
  543. pti++;
  544. break;
  545. case ASCII_FF:
  546. *pto++ = '\\';
  547. *pto++ = 'f';
  548. pti++;
  549. break;
  550. case ASCII_HTAB:
  551. *pto++ = '\\';
  552. *pto++ = 't';
  553. pti++;
  554. break;
  555. case ASCII_CR:
  556. if (HAS_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR))
  557. {
  558. *pto++ = '\\';
  559. *pto++ = 'r';
  560. *pto = 0;
  561. DEL_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR);
  562. pop_call();
  563. return;
  564. }
  565. if (eol)
  566. {
  567. *pto++ = '\\';
  568. *pto++ = 'r';
  569. }
  570. *pto++ = *pti++;
  571. break;
  572. case ASCII_VTAB:
  573. *pto++ = '\\';
  574. *pto++ = 'v';
  575. pti++;
  576. break;
  577. case ASCII_LF:
  578. if (HAS_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR))
  579. {
  580. *pto++ = '\\';
  581. *pto++ = 'n';
  582. *pto = 0;
  583. DEL_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR);
  584. pop_call();
  585. return;
  586. }
  587. if (eol)
  588. {
  589. *pto++ = '\\';
  590. *pto++ = 'n';
  591. }
  592. *pto++ = *pti++;
  593. break;
  594. default:
  595. if (*pti > 0 && *pti < 32)
  596. {
  597. *pto++ = '\\';
  598. *pto++ = 'c';
  599. if (*pti <= 26)
  600. {
  601. *pto++ = 'a' + *pti - 1;
  602. }
  603. else
  604. {
  605. *pto++ = 'A' + *pti - 1;
  606. }
  607. pti++;
  608. break;
  609. }
  610. else
  611. {
  612. *pto++ = *pti++;
  613. }
  614. break;
  615. }
  616. }
  617. *pto = 0;
  618. DEL_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR);
  619. pop_call();
  620. return;
  621. }
  622. char *str_convert_meta(char *input, int eol)
  623. {
  624. static char buf[BUFFER_SIZE];
  625. convert_meta(input, buf, eol);
  626. return buf;
  627. }
  628. /*
  629. Currenly only used in split mode.
  630. */
  631. void echo_command(struct session *ses, char *line)
  632. {
  633. char buffer[BUFFER_SIZE], output[BUFFER_SIZE];
  634. DEL_BIT(ses->telopts, TELOPT_FLAG_PROMPT);
  635. if (ses->check_output)
  636. {
  637. strcpy(output, ses->more_output);
  638. process_mud_output(ses, buffer, FALSE);
  639. }
  640. else
  641. {
  642. strcpy(output, "");
  643. }
  644. if (!HAS_BIT(ses->flags, SES_FLAG_SPLIT))
  645. {
  646. add_line_buffer(ses, line, -1);
  647. return;
  648. }
  649. if (HAS_BIT(ses->flags, SES_FLAG_ECHOCOMMAND))
  650. {
  651. sprintf(buffer, "%s%s\e[0m", ses->cmd_color, line);
  652. }
  653. else
  654. {
  655. if (strip_vt102_strlen(ses, output) == 0)
  656. {
  657. return;
  658. }
  659. sprintf(buffer, "\e[0m");
  660. }
  661. if (ses->wrap == gtd->screen->cols)
  662. {
  663. gtd->level->scroll++;
  664. tintin_printf2(ses, "%s%s", ses->scroll->input, buffer);
  665. gtd->level->scroll--;
  666. }
  667. add_line_buffer(ses, buffer, -1);
  668. }
  669. void input_printf(char *format, ...)
  670. {
  671. char buf[STRING_SIZE];
  672. va_list args;
  673. if (!HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH))
  674. {
  675. if (!HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO) && gtd->input_buf[0] != gtd->tintin_char)
  676. {
  677. return;
  678. }
  679. }
  680. va_start(args, format);
  681. vsprintf(buf, format, args);
  682. va_end(args);
  683. print_stdout("%s", buf);
  684. }
  685. void modified_input(void)
  686. {
  687. kill_list(gtd->ses->list[LIST_COMMAND]);
  688. if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH))
  689. {
  690. cursor_history_find(gtd->ses, "");
  691. }
  692. if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE))
  693. {
  694. DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE);
  695. }
  696. }