/* * Code from: Philipp Meinen * Copyright (C): 2003-2004 Philipp Meinen * * Email: lancelot@lancelot2k.dyndns.org * Homepage: http://lancelot2k.dyndns.org * License: GPL * */ #define _SCREEN_CC_ #include #include #include #include #include #include #include #include "screen.h" Screen::Screen(void) { MainScreen = NULL; TextScreen = NULL; InfoBottom = NULL; InfoTop = NULL; InputScreen = NULL; redraw_screen_from_scratch = 0; //noecho(); InputBuffer = new char[INPUT_LEN_MAX+1]; InputBuffer[0] = '\0'; num_textscreen_redraws = 0; /* Server-screen */ active_channel = 0; first_print_msg = 0; /* initialize the structure screeninfo */ for(int i = 0; i < CHANNELS_MAX; i++) { screen_info[i].used = screen_info[i].type = 0; screen_info[i].channel_name[0] = '\0'; screen_info[i].channel_topic[0] = '\0'; screen_info[i].directchat_nickname[0] = '\0'; } screen_info[0].used = 1; screen_info[0].type = 0; bold_started = 0; underline_started = 0; strncpy(screen_info[0].channel_name, "Server messages", CHANNELS_NAME_LEN-1); MakeAllWindow(0); return; } Screen::~Screen(void) { EndNcurses(); if(InputBuffer) delete[] InputBuffer; return; } void Screen::DrawTopScreen(void) { CheckScreenForRedraw(); werase(InfoTop); int textsize = COLSnow - 9; char buffer[textsize]; if(screen_info[active_channel].used) { if(screen_info[active_channel].type) { /* direct chat */ snprintf(buffer, textsize, "screen %i - Direct-Chat with User: %s", active_channel, screen_info[active_channel].directchat_nickname); } else { /* normal channel */ if(active_channel == 0) { snprintf(buffer, textsize, "%s", screen_info[active_channel].channel_name); } else { snprintf(buffer, textsize, "screen %i - #%s Topic: %s", active_channel, screen_info[active_channel].channel_name, screen_info[active_channel].channel_topic); } } } else { /* not used screen */ snprintf(buffer, textsize, SCREEN_NOT_USED); } InfoTop->_cury = InfoTop->_curx = 0; whline(InfoTop, 0, 5); InfoTop->_curx = 5; wprintw(InfoTop, "%s", buffer); InfoTop->_curx = 5 + strlen(buffer); whline(InfoTop, 0, COLSnow-(InfoTop->_curx)); wrefresh(InfoTop); SetCursorToInputScreen(); return; } void Screen::DrawBottomScreen(void) { CheckScreenForRedraw(); werase(InfoBottom); int textsize = COLSnow - 24; InfoBottom->_cury = InfoBottom->_curx = 0; whline(InfoBottom, 0, 15); InfoBottom->_curx = 15; char * channel_str_ptr = MakeScreenString(0); char * dchat_str_ptr = MakeScreenString(1); int num_users = 0; if(channel_str_ptr) num_users = Classes.IrcUserDB->Get_Num_Users_in_Channel(GetChannelName(active_channel)); char * nickname = Classes.IrcUser->GetNickname(); if(textsize >= HELP_BUF_LEN) textsize = HELP_BUF_LEN - 1; if(channel_str_ptr && ! dchat_str_ptr) { /* only channel */ snprintf(help_buffer, HELP_BUF_LEN, " %s - %i Users - Screens: (%s|)", nickname, num_users, channel_str_ptr); } else if(!channel_str_ptr && dchat_str_ptr) { /* only direct chat */ snprintf(help_buffer, HELP_BUF_LEN, " %s - Screens: (|%s)", nickname, dchat_str_ptr); } else if(channel_str_ptr && dchat_str_ptr) { /* both, direct chat and channels */ snprintf(help_buffer, HELP_BUF_LEN, " %s - %i Users - Screens: (%s|%s)", nickname, num_users, channel_str_ptr, dchat_str_ptr); } else { /* no channel or direct chat */ snprintf(help_buffer, HELP_BUF_LEN, "%s - no Screens!", nickname); } int num = print_format_text(InfoBottom, help_buffer, textsize); InfoBottom->_curx = 15 + num; whline(InfoBottom, 0, COLSnow - (InfoBottom->_curx)); wrefresh(InfoBottom); if(channel_str_ptr) delete[] channel_str_ptr; if(dchat_str_ptr) delete[] dchat_str_ptr; SetCursorToInputScreen(); return; } void Screen::DrawTextScreen(void) { CheckScreenForRedraw(); if(!Classes.MsgDB->GetChange(active_channel)) return; /* screen not altered */ Classes.MsgDB->SetChange(active_channel, 0); num_textscreen_redraws++; /* count how many messages we can print on the screen */ int messages_to_print = MessagesToPrint(); werase(TextScreen); TextScreen->_curx = TextScreen->_cury = 0; for(int i = messages_to_print+first_print_msg-1; i >= first_print_msg; i--) { /* print 1 line */ char * text = Classes.MsgDB->GetMessage(active_channel, i); if(text != NULL) { if(!Classes.MsgDB->GetFormatOptions(active_channel, i)) { /* we dont have anything to formate, veeery nice :) */ wprintw(TextScreen, "%s\n", text); } else { /* we do have something to format * so I print the Message Titel and then allways only 1 char and check the next one if he is a format char */ print_format_text(TextScreen, text, LINEBUF_LEN); } } /* enf of "if(text != NULL)"*/ } /* end of "for(int i = messages_to_print+first_print_msg-1; i >= first_print_msg; i--)" */ wrefresh(TextScreen); SetCursorToInputScreen(); return; } void Screen::DrawInputScreen(void) { CheckScreenForRedraw(); werase(InputScreen); if(strlen(InputBuffer) <= (unsigned)COLSnow) { /* Just print the buffer when enough space is available */ wprintw(InputScreen, "%s", InputBuffer); } else { /* Make a new text for printing */ int input_len = strlen(InputBuffer)-1; char TextToPrintOut[COLSnow]; for(int i = COLSnow-1; i >= 0; i--) { TextToPrintOut[i] = InputBuffer[input_len]; input_len--; } wprintw(InputScreen, "%s", TextToPrintOut); } wrefresh(InputScreen); return; } void Screen::GetInput(void) { CheckScreenForRedraw(); char buf[INPUT_LEN_MAX]; int num_read = read(0, buf, INPUT_LEN_MAX); /* Read from stdin */ if(num_read < 1) return; buf[num_read] = '\0'; int ret = Test_Input_for_special_Chars(buf); if(ret == 1) { if(InputBuffer == '\0') return; /* return when enter is pressed but no input given */ /* Input Data is ready, parse it */ if(InputBuffer[0] == '/') { ParseCommandToServer(NULL); InputBuffer[0] = '\0'; werase(InputScreen); wrefresh(InputScreen); } else if(active_channel) { /* this is a message for a channel or a direct chat */ if(screen_info[active_channel].used) { /* screen is used */ if(!screen_info[active_channel].type) { /* message for a channel */ snprintf(help_buffer, HELP_BUF_LEN, "PRIVMSG #%s :%s", screen_info[active_channel].channel_name, InputBuffer); } else { /* direct message */ snprintf(help_buffer, HELP_BUF_LEN, "PRIVMSG %s :%s", screen_info[active_channel].directchat_nickname, InputBuffer); } Classes.Connection->WriteMessageToServer(help_buffer); Classes.MsgDB->SetIrcChatMessage(active_channel, Classes.IrcUser->GetNickname(), InputBuffer); InputBuffer[0] = '\0'; werase(InputScreen); wrefresh(InputScreen); DrawTextScreen(); } else { /* screen is not used */ Classes.MsgDB->SetIrcChatMessage(active_channel, DISPLAY_ERROR, "this screen is not used for a channel or a direct-chat"); DrawTextScreen(); } } else { /* this is on the server screen */ Classes.MsgDB->SetIrcChatMessage(active_channel, DISPLAY_ERROR, "this is the server screen, you can only enter commands on this screen"); DrawTextScreen(); } } else { /* Input Data is not ready, user wants to write more chars */ DrawInputScreen(); } return; } void Screen::MakeAllWindow(int sigwinch) { redraw_screen_from_scratch = 0; /* get the terminal size and store it in the ncurses variables "COLS" and "LINES" */ struct winsize terminal; terminal.ws_row = terminal.ws_col = 0; ioctl(0, TIOCGWINSZ, &terminal); clearok(stdscr, TRUE); COLS = COLSnow = terminal.ws_col; LINES = LINESnow = terminal.ws_row; if(sigwinch) { endwin(); refresh(); doupdate(); delwin(InfoTop); delwin(InputScreen); delwin(InfoBottom); delwin(TextScreen); } else { MainScreen = initscr(); } InfoTop = newwin(1, COLSnow, 0, 0); InputScreen = newwin(1, COLSnow, LINESnow-1, 0); InfoBottom = newwin(1, COLSnow, LINESnow-2, 0); TextScreen = newwin(LINESnow-3, COLSnow, 1, 0); whline(InfoTop, 0, COLSnow); whline(InfoBottom, 0, COLSnow); /* now redraw this screens */ DrawTopScreen(); DrawBottomScreen(); DrawInputScreen(); DrawTextScreen(); return; } int Screen::Test_Input_for_special_Chars(char * buf) { /* Some ansi codes * F1: 27-91-49-49-126 * F2: 27-91-49-50-126 * F3: 27-91-49-51-126 * F4: 27-91-49-52-126 * F5: 27-91-49-53-126 * F6: 27-91-49-55-126 * F7: 27-91-49-56-126 * F8: 27-91-49-57-126 * F9: 27-91-50-48-126 * F10: 27-91-50-49-126 * F11: 27-91-50-51-126 * F12: 27-91-50-52-126 * F1: 27-79-80 in the programm 'screen' * F2: 27-79-81 in the programm 'screen' * F3: 27-79-82 in the programm 'screen' * F4: 27-79-83 in the programm 'screen' * Page-up: 27-91-53-126 * Page-down: 27-91-54-126 * Keyboard-up: 27-91-65 * Keyboard-left: 27-91-68 * Keyboard-right: 27-91-67 * Keyboard-down: 27-91-66 * Backspace: 127 * Delete: 27-91-51-126 * Tabulator: 9 * Enter: 13 * Control-l: 12 * Escape: 27 * * This Function will set a '\0' for every char which I dont allow * On the end of this Function the text will be shrink together * example: * in this exampl the 4 chars '27'; '91'; '53'; '126' is a page-up * input: * +-----+-----+-----+-----+-----+-----+-----+ * | a | 27 | 91 | 53 | 126 | b | \0 | * +-----+-----+-----+-----+-----+-----+-----+ * after while: | a | \0 | \0 | \0 | \0 | b | \0 | * +-----+-----+-----+-----+-----+-----+-----+ * after shrink:| a | b | \0 | * +-----+-----+-----+ * */ int len = strlen(buf); int cycle = -1; int return_value = 0; char *tmp = buf; int rest_len; do { cycle++; rest_len = len - cycle; if(rest_len >= 5) { if((tmp[0] == 27) && (tmp[1] == 91) && (tmp[4] == 126)) { /* Possibly key between F1 and F12 */ if((tmp[2] == 49) && (tmp[3] == 49)) { /* f1 */ SetActiveChannel(1); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 49) && (tmp[3] == 50)) { /* f2 */ SetActiveChannel(2); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 49) && (tmp[3] == 51)) { /* f3 */ SetActiveChannel(3); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 49) && (tmp[3] == 52)) { /* f4 */ SetActiveChannel(4); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 49) && (tmp[3] == 53)) { /* f5 */ SetActiveChannel(5); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 49) && (tmp[3] == 55)) { /* f6 */ SetActiveChannel(6); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 49) && (tmp[3] == 56)) { /* f7 */ SetActiveChannel(7); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 49) && (tmp[3] == 57)) { /* f8 */ SetActiveChannel(8); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 50) && (tmp[3] == 48)) { /* f9 */ SetActiveChannel(9); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 50) && (tmp[3] == 49)) { /* f10 */ SetActiveChannel(10); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 50) && (tmp[3] == 51)) { /* f11 */ SetActiveChannel(11); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } else if((tmp[2] == 50) && (tmp[3] == 52)) { /* f12 */ SetActiveChannel(12); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = '\0'; } } } if(rest_len >= 4) { if((tmp[0] == 27) && (tmp[1] == 91) && (tmp[2] == 53) && (tmp[3] == 126)) { /* Page Up */ /* get a bit up */ first_print_msg += 5; if(first_print_msg > NUM_LINES) first_print_msg = NUM_LINES; tmp[0] = tmp[1] = tmp[2] = tmp[3] = '\0'; Classes.MsgDB->SetChange(active_channel, 1); DrawTextScreen(); } else if((tmp[0] == 27) && (tmp[1] == 91) && (tmp[2] == 54) && (tmp[3] == 126)) { /* Page Down */ /* get a bit down when the screen isnt allready at the bottom */ first_print_msg -= 5; if(first_print_msg <0) first_print_msg = 0; tmp[0] = tmp[1] = tmp[2] = tmp[3] = '\0'; Classes.MsgDB->SetChange(active_channel, 1); DrawTextScreen(); } else if((tmp[0] == 27) && (tmp[1] == 91) && (tmp[2] == 51) && (tmp[3] == 126)) { /* delete */ tmp[0] = tmp[1] = tmp[2] = tmp[3] = '\0'; } } if(rest_len >= 3) { if((tmp[0] == 27) && (tmp[1] == 91) && (tmp[2] == 65)) { /* keyboard-up */ tmp[0] = tmp[1] = tmp[2] = '\0'; } else if((tmp[0] == 27) && (tmp[1] == 91) && (tmp[2] == 68)) { /* keyboard-left */ tmp[0] = tmp[1] = tmp[2] = '\0'; } else if((tmp[0] == 27) && (tmp[1] == 91) && (tmp[2] == 67)) { /* keyboard-right */ tmp[0] = tmp[1] = tmp[2] = '\0'; } else if((tmp[0] == 27) && (tmp[1] == 91) && (tmp[2] == 66)) { /* keyboard-down */ tmp[0] = tmp[1] = tmp[2] = '\0'; } else if((tmp[0] == 27) && (tmp[1] == 79) && (tmp[2] == 80)) { /* f1 in programm 'screen' */ SetActiveChannel(1); tmp[0] = tmp[1] = tmp[2] = '\0'; } else if((tmp[0] == 27) && (tmp[1] == 79) && (tmp[2] == 81)) { /* f2 in programm 'screen' */ SetActiveChannel(2); tmp[0] = tmp[1] = tmp[2] = '\0'; } else if((tmp[0] == 27) && (tmp[1] == 79) && (tmp[2] == 82)) { /* f3 in programm 'screen' */ SetActiveChannel(3); tmp[0] = tmp[1] = tmp[2] = '\0'; } else if((tmp[0] == 27) && (tmp[1] == 79) && (tmp[2] == 83)) { /* f4 in programm 'screen' */ SetActiveChannel(4); tmp[0] = tmp[1] = tmp[2] = '\0'; } } if(rest_len >= 2) { } if(rest_len >= 1) { if(tmp[0] == 13) { /* 13 = '\n' => enter */ /* User pressed enter, so parse his input */ return_value = 1; } else if(tmp[0] == 127 || tmp[0] == 8) { /* Backspace -> ^? and ^H */ if((tmp > buf) || (cycle > 0)) { /* this is not the first char in this stream so delete the one before */ tmp[-1] = tmp[0] = '\0'; } else { int len_now = strlen(InputBuffer); if(len_now > 0) InputBuffer[len_now-1] = '\0'; tmp[0] = '\0'; } } else if(tmp[0] == 12) { /* clean the current screen */ tmp[0] = '\0'; Classes.MsgDB->EmptyMessages(active_channel); DrawTextScreen(); /* and redraw the screen */ } else if(tmp[0] == 27) { /* Escape -> go to screen 0 (Server messages) */ tmp[0] = '\0'; SetActiveChannel(0); } } tmp++; /* increase the pointer for the next cycle */ } while((len - cycle) >= 5); for(int i = 0; i < len; i++) { if((unsigned int)buf[i] < 32 && (unsigned int)buf[i] > 0) buf[i] = '\0'; /* dont print this char */ } /* shrink the '\0''s away */ int position = 0; for(int i = 0; i < len; i++) { if(buf[i] != '\0') { buf[position] = buf[i]; position++; } } buf[position] = '\0'; /* now add this string to the input buffer */ AddToInputBuffer(buf); return return_value; } void Screen::AddToInputBuffer(char * buf) { int buf_len = strlen(buf); int pos = 0; int i; char * buffer = NULL; /* I want 4 spaces instead of 1 tab */ int tab_num = 0; for(i = 0; i < buf_len; i++) if(buf[i] == 9) tab_num++; /* 9 = ansicode of tabulator */ if(tab_num) { buffer = new char [((buf_len - tab_num) + (4 * tab_num) + 1)]; for(i = 0; i < buf_len; i++) { if(buf[i] != 9) { buffer[pos] = buf[i]; pos++; } else { buffer[pos] = buffer[pos+1] = buffer[pos+2] = buffer[pos+3] = ' '; pos += 4; } } buffer[pos] = '\0'; buf_len = strlen(buffer); } else buffer = buf; /* I dont want '\r' or '\n' in the InputBuffer */ pos = 0; char tmp_buf[buf_len+1]; for(i = 0; i < buf_len; i++) { if(!(buffer[i] == '\r') && !(buffer[i] == '\n')) { tmp_buf[pos] = buffer[i]; pos++; } } tmp_buf[pos] = '\0'; int len_now = strlen(InputBuffer); int len_new = len_now + strlen(tmp_buf); int diff = 0; if(len_new > INPUT_LEN_MAX) len_new = INPUT_LEN_MAX; diff = len_new - len_now; strncat(InputBuffer, tmp_buf, diff); InputBuffer[len_new] = '\0'; if(tab_num && buffer) delete[] buffer; return; } int Screen::MessagesToPrint(void) { CheckScreenForRedraw(); /* count how many messages we can print on the screen */ if(!Classes.MsgDB->GetLinesNum(active_channel)) return 0; int num_lines_left = LINESnow-3;/* maximum count of possible messages */ int control = 1; int message = first_print_msg; int messages_to_print = 0; /* how many messages we have to print out */ do { char * text = Classes.MsgDB->GetMessage(active_channel, message); if(text != NULL) { /* we have a text, now test how many lines we need to print this text */ int len = num_lines(strlen(text), COLSnow); if(num_lines_left > len) { /* we have enough space left to print out this text */ num_lines_left -= len; messages_to_print++; } else if(num_lines_left == len) { /* we have exactly enough space to print the text */ messages_to_print++; return messages_to_print; } else { /* there is not enough space to print this text, so we do not */ return messages_to_print; } message++; } else return messages_to_print; } while(control); return messages_to_print; } void Screen::SetActiveChannel(int new_active_channel) { CheckScreenForRedraw(); if((new_active_channel < 0) || (new_active_channel >= CHANNELS_MAX)) return; Classes.MsgDB->SetChange(new_active_channel, 1); /* force a screen redraw, even if the content didnt change */ active_channel = new_active_channel; DrawTopScreen(); DrawBottomScreen(); DrawTextScreen(); return; } int Screen::GetActiveChannel(void) { return active_channel; } int Screen::GetScreenNr(char * name, int type) { CheckScreenForRedraw(); if((type > 1) || (type < 0)) return 0; if(name[0] == '\0') return 0; for(int i = 1; i < CHANNELS_MAX; i++) { if(screen_info[i].used) { /* i is a used screen */ if(screen_info[i].type == type) { /* we have the same type as requested */ if(type == 0) { /* channel */ if(strcmp(screen_info[i].channel_name, name) == 0) return i; } else { /* direct chat */ if(strcmp(screen_info[i].directchat_nickname, name) == 0) return i; } } } } return 0; } int Screen::GetNotUsedScreen(int type) { CheckScreenForRedraw(); for(int i = 1; i < CHANNELS_MAX; i++) { if(!screen_info[i].used) { /* this screen is not used */ if((type == 0) || (type == 1)) { screen_info[i].used = 1; screen_info[i].type = type; return i; } } } return 0; /* 0 when we have no screen left */ } void Screen::EmptyScreen(int screen_nr) { CheckScreenForRedraw(); if((screen_nr < 1) || (screen_nr >= CHANNELS_MAX)) return; screen_info[screen_nr].used = 0; screen_info[screen_nr].type = 0; screen_info[screen_nr].channel_name[0] = '\0'; screen_info[screen_nr].channel_topic[0] = '\0'; screen_info[screen_nr].directchat_nickname[0] = '\0'; DrawTopScreen(); DrawBottomScreen(); return; } void Screen::EmptyAllScreens(void) { CheckScreenForRedraw(); for(int i = 1; i < CHANNELS_MAX; i++) { EmptyScreen(i); } return; } void Screen::ParseCommandToServer(char * message) { /* commands that will be parsed * Command: What will be sent * MSG PRIVMSG, argument = nickname, message * M same as MSG * PART PART or just leave the direct message screen, possible arguments = leavemsg * P same as PART * QUIT exit the irc-client, possible argument = leavemsg * Q same as QUIT * JOIN Joines a channel, argument = channel * J same as JOIN * SCREEN Go to a Screen (for the programm 'screen') * S same as SCREEN * TOPIC change the topic of the current channel * T same as TOPIC * NICK changes the nickname * ME action * WHO list the people who are in a channel * W same as WHO * NAMES same as WHO * CTCP get informations about a user * RECONNECT reconnect to the irc-network * CONNECT connect to the specified server * RECONNECT same as CONNECT * HELP print help to a command * DISCONNECT disconnect from the irc network */ CheckScreenForRedraw(); char tmp_command[COMMAND_LEN]; int len; if(message == NULL) len = strlen(InputBuffer); else len = strlen(message); if(len < 2) return; /* only "/" */ /* is this a single word or a fully command? */ int spacepos; if(message == NULL) spacepos = position_of_num_char(InputBuffer, ' ', 1); else spacepos = position_of_num_char(message, ' ', 1); if(spacepos == 1) return; /* message is of type "/ message" */ int command_len = 0; if(spacepos == -1) { /* only 1 word after "/" */ command_len = len - 1; } else { /* more than one words */ command_len = spacepos - 1; } if(command_len >= COMMAND_LEN - 1) command_len = COMMAND_LEN - 1; if(message == NULL) memcpy(tmp_command, InputBuffer+1, command_len); else memcpy(tmp_command, message+1, command_len); tmp_command[command_len] = '\0'; /* make the command to uppercase */ string_toupper(tmp_command); /* now check this command */ int command_used = 0; char * user_input = NULL; /* pointer to the position of 'InputBuffer' where the options are*/ if(message == NULL) { if(len > command_len+2) user_input = InputBuffer + command_len + 2; /* bsp: "/msg a" => "a"*/ } else { if(len > command_len+2) user_input = message + command_len + 2; } if((command_len+2) >= len) user_input = NULL; /* no parameters */ if(command_len == 1) { if(strcmp(tmp_command, "M") == 0) { command_used = 1; Classes.Connection->DirectMSG(user_input); } else if(strcmp(tmp_command, "P") == 0) { command_used = 1; Classes.Connection->PARTChannelorChat(user_input); } else if(strcmp(tmp_command, "Q") == 0) { command_used = 1; Classes.Connection->QUITIrc(user_input); } else if(strcmp(tmp_command, "J") == 0) { command_used = 1; Classes.Connection->JOINChannel(user_input); } else if(strcmp(tmp_command, "S") == 0) { command_used = 1; user_input_SCREEN(user_input); } else if(strcmp(tmp_command, "T") == 0) { command_used = 1; Classes.Connection->TOPIC_Change(user_input); } else if(strcmp(tmp_command, "W") == 0) { command_used = 1; Classes.IrcUserDB->ListUsersToScreen(user_input); } } else if(command_len == 2) { if(strcmp(tmp_command, "ME") == 0) { command_used = 1; Classes.Connection->MECommand(user_input); } } else if(command_len == 3) { if(strcmp(tmp_command, "MSG") == 0) { command_used = 1; Classes.Connection->DirectMSG(user_input); } else if(strcmp(tmp_command, "WHO") == 0) { command_used = 1; Classes.IrcUserDB->ListUsersToScreen(user_input); } } else if(command_len == 4) { if(strcmp(tmp_command, "PART") == 0) { command_used = 1; Classes.Connection->PARTChannelorChat(user_input); } else if(strcmp(tmp_command, "QUIT") == 0) { command_used = 1; Classes.Connection->QUITIrc(user_input); } else if(strcmp(tmp_command, "JOIN") == 0) { command_used = 1; Classes.Connection->JOINChannel(user_input); } else if(strcmp(tmp_command, "NICK") == 0) { command_used = 1; Classes.Connection->NICK_Change(user_input); } else if(strncmp(tmp_command, "CTCP", 4) == 0) { command_used = 1; Classes.Connection->CTCP_User(user_input); } else if(strncmp(tmp_command, "HELP", 4) == 0) { command_used = 1; help_me(user_input); } } else if(command_len == 5) { if(strcmp(tmp_command, "TOPIC") == 0) { command_used = 1; Classes.Connection->TOPIC_Change(user_input); } else if(strcmp(tmp_command, "NAMES") == 0) { command_used = 1; Classes.IrcUserDB->ListUsersToScreen(user_input); } } else if(command_len == 6) { if(strcmp(tmp_command, "SCREEN") == 0) { command_used = 1; user_input_SCREEN(user_input); } } else if(command_len == 7) { if(strcmp(tmp_command, "CONNECT") == 0) { command_used = 1; Classes.Connection->Connect_to_Server(user_input); } } else if(command_len == 9) { if(strcmp(tmp_command, "RECONNECT") == 0) { command_used = 1; Classes.Connection->Connect_to_Server(user_input); } } else if(command_len == 10) { if(strcmp(tmp_command, "DISCONNECT") == 0) { command_used = 1; Classes.Connection->Disconnect(); Classes.Connection->UnsetMaybeReconnect(); } } if(message == NULL) if(!command_used) Classes.Connection->WriteMessageToServer(InputBuffer+1); else if(!command_used) Classes.Connection->WriteMessageToServer(message+1); DrawTextScreen(); return; } void Screen::MarktoRedrawScreen(void) { redraw_screen_from_scratch = 1; return; } void Screen::CheckScreenForRedraw(void) { if(redraw_screen_from_scratch) MakeAllWindow(1); return; } void Screen::EndNcurses(void) { delwin(TextScreen); delwin(InfoBottom); delwin(InfoTop); delwin(InputScreen); endwin(); return; } void Screen::user_input_SCREEN(char * user_input) { if(user_input) { int channel_nr = atoi(user_input); SetActiveChannel(channel_nr); } else { help_me("screen"); } return; } int Screen::GetScreenUse(int screen_nr) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return 0; return screen_info[screen_nr].used; } void Screen::SetScreenUse(int screen_nr, int new_use) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return; screen_info[screen_nr].used = new_use; return; } int Screen::GetScreenType(int screen_nr) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return 0; return screen_info[screen_nr].type; } void Screen::SetScreenType(int screen_nr, int new_type) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return; screen_info[screen_nr].type = new_type; return; } char * Screen::GetChannelName(int screen_nr) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return NULL; return screen_info[screen_nr].channel_name; } int Screen::GetScreenNumForChannel(char * tmp_channel) { if(tmp_channel[0] == '\0') return 0; for(int i = 0; i < CHANNELS_MAX; i++) if(strcmp(tmp_channel, screen_info[i].channel_name) == 0) return i; return 0; } int Screen::GetScreenNumForDirectChat(char * tmp_nickname) { if(tmp_nickname[0] == '\0') return 0; for(int i = 0; i < CHANNELS_MAX; i++) if(strcmp(tmp_nickname, screen_info[i].directchat_nickname) == 0) return i; return 0; } void Screen::SetChannelName(int screen_nr, char * new_channelname) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return; snprintf(screen_info[screen_nr].channel_name, CHANNELS_NAME_LEN, "%s", new_channelname); return; } char * Screen::Screen::GetTopic(int screen_nr) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return NULL; return screen_info[screen_nr].channel_topic; } void Screen::SetTopic(int screen_nr, char * new_topic) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return; snprintf(screen_info[screen_nr].channel_topic, TOPIC_LEN_MAX, "%s", new_topic); return; } char * Screen::GetDirectChatNick(int screen_nr) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return NULL; return screen_info[screen_nr].directchat_nickname; } int Screen::GetScreenCols(void) { return COLSnow; } void Screen::SetDirectChatNick(int screen_nr, char * new_directchatnick) { if((screen_nr < 0) || (screen_nr >= CHANNELS_MAX)) return; snprintf(screen_info[screen_nr].directchat_nickname, NICKNAME_LEN, "%s", new_directchatnick); return; } char * Screen::MakeScreenString(int type) { /* * If the screens 1,3,5,7 and 10 are used and number 3 and 7 are direct chats * this function will return a string like: * "1,5,10" * if the type is 0. * If the type is 1 the returned string will be like this: * "3,7" * */ if(type < 0 || type > 1) return NULL; char * tmp_buf = NULL; int num_screens = 0; for(int i = 1; i < CHANNELS_MAX; i++) if((GetScreenUse(i)) && (GetScreenType(i) == type)) num_screens++; if(num_screens == 0) return NULL; /* we dont have screens of the requested type */ int string_len = (num_screens * (CHANNELS_MAX_STRLEN + 3)) + 1; /* +3 because we have to be able to store a ',' and 2 format chars */ tmp_buf = new char[string_len]; tmp_buf[0] = '\0'; int num_handled = 0; char * num = new char[CHANNELS_MAX_STRLEN + 4]; /* +4 because we have to be able to store a ',' and 2 format chars */ int have_change; int screen = Classes.IrcScreen->GetActiveChannel(); for(int i = 1; i < CHANNELS_MAX; i++) { if((GetScreenUse(i)) && (GetScreenType(i) == type)) { num_handled++; have_change = Classes.MsgDB->GetChange(i); if(num_handled == num_screens) { /* this is the last screen */ if(have_change && screen != i) snprintf(num, CHANNELS_MAX_STRLEN + 3, "\2%i\2", i); else snprintf(num, CHANNELS_MAX_STRLEN + 1, "%i", i); } else { if(have_change && screen != i) snprintf(num, CHANNELS_MAX_STRLEN + 4, "\2%i\2,", i); else snprintf(num, CHANNELS_MAX_STRLEN + 2, "%i,", i); } strcat(tmp_buf, num); } } delete[] num; return tmp_buf; } void Screen::SetCursorToInputScreen(void) { int xpos_inputscreen = strlen(InputBuffer); if(xpos_inputscreen >= COLSnow) xpos_inputscreen = COLSnow - 1; move(LINESnow-1, xpos_inputscreen); wrefresh(InputScreen); return; } void Screen::ResetFormat(WINDOW * screen) { underline_started = 0; bold_started = 0; wattrset(screen, WA_NORMAL); return; } void Screen::SetBold(WINDOW * screen) { if(bold_started) { wattroff(screen, WA_BOLD); bold_started = 0; } else { wattron(screen, WA_BOLD); bold_started = 1; } return; } void Screen::SetUnderline(WINDOW * screen) { if(underline_started) { wattroff(screen, WA_UNDERLINE); underline_started = 0; } else { wattron(screen, WA_UNDERLINE); underline_started = 1; } return; } int Screen::SetColor(char * string) { int colorchars = 0; if(!string) return 0; if(string[0] != FORMAT_COLOR_NUM || string[1] == '\0') { return colorchars; } int num = string[1]; if(num >= 48 && num <= 57) {/* 48 = 0; 49 = 1; .... ; 57 = 9 */ num -= 48; colorchars++; } else { return colorchars; } /* check if the number is higher then 9 */ if(string[2] != '\0') { int num2 = string[2]; if(num2 >= 48 && num2 <= 57) { num2 -= 48; colorchars++; num = (num * 10) + num2; } } return colorchars; } int Screen::print_format_text(WINDOW * screen, char * string, int max_chars) { int count = 0; int num = 0; while(*(string+count) && (num < max_chars)) { switch((unsigned int)*(string+count)) { case FORMAT_BOLD_NUM: SetBold(screen); break; case FORMAT_UNDERLINE_NUM: SetUnderline(screen); break; case FORMAT_COLOR_NUM: count += SetColor(string+count); break; case FORMAT_RESET_NUM: ResetFormat(screen); break; default: num++; wprintw(screen, "%c", *(string+count)); break; } count++; } /* print a newline on the end and reset the formats */ ResetFormat(screen); wprintw(screen, "\n"); return num; } #undef _SCREEN_CC_