/*
* 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 <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <curses.h>
#include <unistd.h>
#include <sys/ioctl.h>
#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_
syntax highlighted by Code2HTML, v. 0.9.1