/****************************************************************************** * TinTin++ * * Copyright (C) 2006 (See CREDITS file) * * * * This program is protected under the GNU GPL (See COPYING) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ******************************************************************************/ /****************************************************************************** * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t * * * * coded by Igor van den Hoven 2006 * ******************************************************************************/ #include "tintin.h" void process_input(void) { if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_SGA) && !HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO)) { read_key(); } else { read_line(); } if (!HAS_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT)) { return; } DEL_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT); if (gtd->chat && gtd->chat->paste_time) { chat_paste(gtd->input_buf, NULL); return; } if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO)) { add_line_history(gtd->ses, gtd->input_buf); } if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO)) { echo_command(gtd->ses, gtd->input_buf); } else { echo_command(gtd->ses, ""); } if (gtd->ses->scroll_line != -1) { buffer_end(gtd->ses, ""); } gtd->ses = script_driver(gtd->ses, -1, gtd->input_buf); check_all_events(gtd->ses, 0, 1, "RECEIVED INPUT", gtd->input_buf); if (IS_SPLIT(gtd->ses)) { erase_toeol(); } gtd->input_buf[0] = 0; } void read_line() { char buffer[STRING_SIZE]; struct listnode *node; struct listroot *root; int len, cnt, match; gtd->input_buf[gtd->input_len] = 0; len = read(0, buffer, 1); buffer[len] = 0; if (HAS_BIT(gtd->ses->flags, SES_FLAG_CONVERTMETA) || HAS_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR)) { convert_meta(buffer, >d->macro_buf[strlen(gtd->macro_buf)]); } else { strcat(gtd->macro_buf, buffer); } if (!HAS_BIT(gtd->ses->flags, SES_FLAG_CONVERTMETA)) { match = 0; root = gtd->ses->list[LIST_MACRO]; for (root->update = 0 ; root->update < root->used ; root->update++) { node = root->list[root->update]; if (!strcmp(gtd->macro_buf, node->pr)) { script_driver(gtd->ses, LIST_MACRO, node->right); gtd->macro_buf[0] = 0; return; } else if (!strncmp(gtd->macro_buf, node->pr, strlen(gtd->macro_buf))) { match = 1; } } for (cnt = 0 ; *cursor_table[cnt].fun != NULL ; cnt++) { if (!strcmp(gtd->macro_buf, cursor_table[cnt].code)) { cursor_table[cnt].fun(""); gtd->macro_buf[0] = 0; return; } else if (!strncmp(gtd->macro_buf, cursor_table[cnt].code, strlen(gtd->macro_buf))) { match = 1; } } if (match) { return; } } if (gtd->macro_buf[0] == ESCAPE) { strcpy(buffer, gtd->macro_buf); convert_meta(buffer, gtd->macro_buf); } for (cnt = 0 ; gtd->macro_buf[cnt] ; cnt++) { switch (gtd->macro_buf[cnt]) { case 10: cursor_enter(""); break; default: if (HAS_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT) && gtd->input_len != gtd->input_cur) { gtd->input_buf[gtd->input_cur] = gtd->macro_buf[cnt]; gtd->input_cur++; gtd->input_pos++; input_printf("%c", gtd->macro_buf[cnt]); } else { ins_sprintf(>d->input_buf[gtd->input_cur], "%c", gtd->macro_buf[cnt]); gtd->input_len++; gtd->input_cur++; gtd->input_pos++; if (gtd->input_len != gtd->input_cur) { input_printf("\033[1@%c", gtd->macro_buf[cnt]); } else { input_printf("%c", gtd->macro_buf[cnt]); } } gtd->macro_buf[0] = 0; gtd->input_tmp[0] = 0; gtd->input_buf[gtd->input_len] = 0; cursor_check_line(""); DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE); kill_list(gtd->ses->list[LIST_TABCYCLE]); if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH)) { cursor_history_find(""); } break; } } } void read_key(void) { char buffer[BUFFER_SIZE]; struct listnode *node; struct listroot *root; int len, cnt, match; if (gtd->input_buf[0] == gtd->tintin_char) { read_line(); return; } len = read(0, buffer, 1); buffer[len] = 0; if (HAS_BIT(gtd->ses->flags, SES_FLAG_CONVERTMETA) || HAS_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR)) { convert_meta(buffer, >d->macro_buf[strlen(gtd->macro_buf)]); } else { strcat(gtd->macro_buf, buffer); } if (!HAS_BIT(gtd->ses->flags, SES_FLAG_CONVERTMETA)) { match = 0; root = gtd->ses->list[LIST_MACRO]; for (root->update = 0 ; root->update < root->used ; root->update++) { node = root->list[root->update]; if (!strcmp(gtd->macro_buf, node->pr)) { script_driver(gtd->ses, LIST_MACRO, node->right); gtd->macro_buf[0] = 0; return; } else if (!strncmp(gtd->macro_buf, node->pr, strlen(gtd->macro_buf))) { match = 1; } } if (match) { return; } } for (cnt = 0 ; gtd->macro_buf[cnt] ; cnt++) { switch (gtd->macro_buf[cnt]) { case '\r': printf("\n\[1;31mfound \\r!\n"); break; case '\n': gtd->input_buf[0] = 0; gtd->macro_buf[0] = 0; gtd->input_len = 0; if (HAS_BIT(gtd->ses->flags, SES_FLAG_RUN)) { socket_printf(gtd->ses, 1, "%c", '\r'); } else { socket_printf(gtd->ses, 2, "%c%c", '\r', '\n'); } break; default: if (gtd->macro_buf[cnt] == gtd->tintin_char && gtd->input_buf[0] == 0) { if (gtd->input_len != gtd->input_cur) { printf("\033[1@%c", gtd->macro_buf[cnt]); } else { printf("%c", gtd->macro_buf[cnt]); } gtd->input_buf[0] = gtd->tintin_char; gtd->input_buf[1] = 0; gtd->macro_buf[0] = 0; gtd->input_len = 1; gtd->input_cur = 1; gtd->input_pos = 1; } else { socket_printf(gtd->ses, 1, "%c", gtd->macro_buf[cnt]); gtd->input_buf[0] = 127; gtd->macro_buf[0] = 0; gtd->input_len = 0; } break; } } } void convert_meta(char *input, char *output) { char *pti, *pto; DEL_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR); pti = input; pto = output; while (*pti) { switch (*pti) { case ESCAPE: *pto++ = '\\'; *pto++ = 'e'; pti++; break; case 127: *pto++ = '\\'; *pto++ = 'b'; pti++; break; case '\a': *pto++ = '\\'; *pto++ = 'a'; pti++; break; case '\b': *pto++ = '\\'; *pto++ = 'b'; pti++; break; case '\t': *pto++ = '\\'; *pto++ = 't'; pti++; break; case '\r': *pto++ = '\\'; *pto++ = 'r'; pti++; break; case '\n': *pto++ = *pti++; break; default: if (*pti > 0 && *pti < 32) { *pto++ = '\\'; *pto++ = 'c'; if (*pti <= 26) { *pto++ = 'a' + *pti - 1; } else { *pto++ = 'A' + *pti - 1; } pti++; break; } else { *pto++ = *pti++; } break; } } *pto = 0; } void unconvert_meta(char *input, char *output) { char *pti, *pto; pti = input; pto = output; while (*pti) { switch (pti[0]) { case '\\': switch (pti[1]) { case 'C': if (pti[2] == '-' && pti[3]) { *pto++ = pti[3] - 'a' + 1; pti += 4; } else { *pto++ = *pti++; } break; case 'c': *pto++ = pti[2] % 32; pti += 3; break; case 'a': *pto++ = '\a'; pti += 2; break; case 'b': *pto++ = 127; pti += 2; break; case 'e': *pto++ = ESCAPE; pti += 2; break; case 't': *pto++ = '\t'; pti += 2; break; case 'x': if (pti[2] && pti[3]) { *pto++ = hex_number(&pti[2]); pti += 4; } else { *pto++ = *pti++; } break; default: *pto++ = *pti++; break; } break; default: *pto++ = *pti++; break; } } *pto = 0; } /* Currenly only used in split mode. */ void echo_command(struct session *ses, char *line) { char buffer[STRING_SIZE], result[STRING_SIZE]; if (HAS_BIT(ses->flags, SES_FLAG_SPLIT)) { sprintf(buffer, "%s%s\033[0m", ses->cmd_color, line); } else { sprintf(buffer, "%s", line); } /* Deal with pending output */ if (ses->more_output[0]) { if (ses->check_output) { strcpy(result, ses->more_output); ses->more_output[0] = 0; process_mud_output(ses, result, FALSE); } } DEL_BIT(ses->telopts, TELOPT_FLAG_PROMPT); if (HAS_BIT(ses->flags, SES_FLAG_SPLIT)) { if (!HAS_BIT(ses->flags, SES_FLAG_ECHOCOMMAND)) { sprintf(result, "\033[0;37m"); } else { sprintf(result, "%s%s", ses->more_output, buffer); } add_line_buffer(ses, buffer, -1); SET_BIT(ses->flags, SES_FLAG_SCROLLSTOP); tintin_printf2(ses, "%s", result); DEL_BIT(ses->flags, SES_FLAG_SCROLLSTOP); } else { add_line_buffer(ses, buffer, -1); } } void input_printf(char *format, ...) { char buf[STRING_SIZE]; va_list args; if (!HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH)) { if (!HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO) && gtd->input_buf[0] != gtd->tintin_char) { return; } } va_start(args, format); vsprintf(buf, format, args); va_end(args); printf("%s", buf); } void modified_input(void) { kill_list(gtd->ses->list[LIST_TABCYCLE]); if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH)) { cursor_history_find(""); } if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE)) { DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE); } }