diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2003-10-12 14:15:15 +0000 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2003-10-12 14:15:15 +0000 |
commit | c67cfeaa87ea30747c0dbfe1737b7ff43b12cf0e (patch) | |
tree | e25ca1cafe8277f2486fb2503714f81da3023430 /src/gui | |
parent | d92955a533a3d4cffaeed7fab95b53ff7d5261ca (diff) | |
download | weechat-c67cfeaa87ea30747c0dbfe1737b7ff43b12cf0e.zip |
Common functions for all GUI.
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/gui-common.c | 453 |
1 files changed, 453 insertions, 0 deletions
diff --git a/src/gui/gui-common.c b/src/gui/gui-common.c new file mode 100644 index 000000000..330f1f642 --- /dev/null +++ b/src/gui/gui-common.c @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2003 by FlashCode <flashcode@flashtux.org> + * Bounga <bounga@altern.org> + * Xahlexx <xahlexx@tuxisland.org> + * See README for License detail. + * + * 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 + */ + + +/* gui-common.c: display functions, used by any GUI */ + + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <signal.h> +#include <time.h> +#include <curses.h> + +#include "../weechat.h" +#include "gui.h" +#include "../irc/irc.h" + + +int gui_ready; /* = 1 if GUI is initialized */ + +t_gui_window *gui_windows = NULL; /* pointer to first window */ +t_gui_window *last_gui_window = NULL; /* pointer to last window */ +t_gui_window *gui_current_window = NULL; /* pointer to current window */ + + +/* + * gui_window_clear: clear window content + */ + +void +gui_window_clear (t_gui_window *window) +{ + t_gui_line *ptr_line; + t_gui_message *ptr_message; + + while (window->lines) + { + ptr_line = window->lines->next_line; + while (window->lines->messages) + { + ptr_message = window->lines->messages->next_message; + if (window->lines->messages->message) + free (window->lines->messages->message); + free (window->lines->messages); + window->lines->messages = ptr_message; + } + free (window->lines); + window->lines = ptr_line; + } + + window->lines = NULL; + window->last_line = NULL; + window->first_line_displayed = 1; + window->sub_lines = 0; + window->line_complete = 1; + window->unread_data = 0; + + if (window == gui_current_window) + gui_redraw_window_chat (window); +} + +/* + * gui_window_clear_all: clear all windows content + */ + +void +gui_window_clear_all () +{ + t_gui_window *ptr_win; + + for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window) + gui_window_clear (ptr_win); +} + +/* + * gui_window_new: create a new window + * (TODO: add coordinates and size, for splited windows) + */ + +t_gui_window * +gui_window_new (void *server, void *channel + /*int x, int y, int width, int height*/) +{ + t_gui_window *new_window; + + if (gui_windows) + { + /* use first window if no server was assigned to this window */ + if (!SERVER(gui_windows)) + { + if (server) + ((t_irc_server *)(server))->window = gui_windows; + if (channel) + ((t_irc_channel *)(channel))->window = gui_windows; + SERVER(gui_windows) = server; + CHANNEL(gui_windows) = channel; + return gui_windows; + } + } + + if ((new_window = (t_gui_window *)(malloc (sizeof (t_gui_window))))) + { + /* assign server and channel to window */ + SERVER(new_window) = server; + CHANNEL(new_window) = channel; + /* assign window to server and channel */ + if (server && !channel) + SERVER(new_window)->window = new_window; + if (channel) + CHANNEL(new_window)->window = new_window; + + gui_calculate_pos_size (new_window); + + /* init windows */ + new_window->win_title = NULL; + new_window->win_chat = NULL; + new_window->win_nick = NULL; + new_window->win_status = NULL; + new_window->win_input = NULL; + + /* init lines */ + new_window->lines = NULL; + new_window->last_line = NULL; + new_window->first_line_displayed = 1; + new_window->sub_lines = 0; + new_window->line_complete = 1; + new_window->unread_data = 0; + + /* init input buffer */ + new_window->input_buffer_alloc = INPUT_BUFFER_BLOCK_SIZE; + new_window->input_buffer = (char *) malloc (INPUT_BUFFER_BLOCK_SIZE); + new_window->input_buffer[0] = '\0'; + new_window->input_buffer_size = 0; + new_window->input_buffer_pos = 0; + new_window->input_buffer_1st_display = 0; + + /* init completion */ + completion_init (&(new_window->completion)); + + /* init history */ + new_window->history = NULL; + new_window->ptr_history = NULL; + + /* switch to new window */ + gui_switch_to_window (new_window); + + /* add window to windows queue */ + new_window->prev_window = last_gui_window; + if (gui_windows) + last_gui_window->next_window = new_window; + else + gui_windows = new_window; + last_gui_window = new_window; + new_window->next_window = NULL; + + /* redraw whole screen */ + gui_redraw_window (new_window); + } + else + return NULL; + + return new_window; +} + +/* + * gui_window_free: delete a window + */ + +void +gui_window_free (t_gui_window *window) +{ + t_gui_line *ptr_line; + t_gui_message *ptr_message; + int create_new; + + create_new = (window->server || window->channel); + + /* TODO: manage splitted windows! */ + if ((window == gui_current_window) && + ((window->next_window) || (window->prev_window))) + gui_switch_to_previous_window (); + + /* free lines and messages */ + while (window->lines) + { + ptr_line = window->lines->next_line; + while (window->lines->messages) + { + ptr_message = window->lines->messages->next_message; + if (window->lines->messages->message) + free (window->lines->messages->message); + free (window->lines->messages); + window->lines->messages = ptr_message; + } + free (window->lines); + window->lines = ptr_line; + } + if (window->input_buffer) + free (window->input_buffer); + + completion_free (&(window->completion)); + + /* remove window from windows list */ + if (window->prev_window) + window->prev_window->next_window = window->next_window; + if (window->next_window) + window->next_window->prev_window = window->prev_window; + if (gui_windows == window) + gui_windows = window->next_window; + if (last_gui_window == window) + last_gui_window = window->prev_window; + + free (window); + + /* always at least one window */ + if (!gui_windows && create_new) + gui_window_new (NULL, NULL); +} + +/* + * gui_new_line: create new line for a window + */ + +t_gui_line * +gui_new_line (t_gui_window *window) +{ + t_gui_line *new_line; + + if ((new_line = (t_gui_line *) malloc (sizeof (struct t_gui_line)))) + { + new_line->length = 0; + new_line->length_align = 0; + new_line->line_with_message = 0; + new_line->messages = NULL; + new_line->last_message = NULL; + if (!window->lines) + window->lines = new_line; + else + window->last_line->next_line = new_line; + new_line->prev_line = window->last_line; + new_line->next_line = NULL; + window->last_line = new_line; + } + else + { + log_printf (_("%s not enough memory for new line!\n")); + return NULL; + } + return new_line; +} + +/* + * gui_new_message: create a new message for last line of window + */ + +t_gui_message * +gui_new_message (t_gui_window *window) +{ + t_gui_message *new_message; + + if ((new_message = (t_gui_message *) malloc (sizeof (struct t_gui_message)))) + { + if (!window->last_line->messages) + window->last_line->messages = new_message; + else + window->last_line->last_message->next_message = new_message; + new_message->prev_message = window->last_line->last_message; + new_message->next_message = NULL; + window->last_line->last_message = new_message; + } + else + { + log_printf (_("not enough memory!\n")); + return NULL; + } + return new_message; +} + +/* + * gui_optimize_input_buffer_size: optimize input buffer size by adding + * or deleting data block (predefined size) + */ + +void +gui_optimize_input_buffer_size (t_gui_window *window) +{ + int optimal_size; + + optimal_size = ((window->input_buffer_size / INPUT_BUFFER_BLOCK_SIZE) * + INPUT_BUFFER_BLOCK_SIZE) + INPUT_BUFFER_BLOCK_SIZE; + if (window->input_buffer_alloc != optimal_size) + { + window->input_buffer_alloc = optimal_size; + window->input_buffer = realloc (window->input_buffer, optimal_size); + } +} + +/* + * gui_delete_previous_word: delete previous word + */ + +void +gui_delete_previous_word () +{ + int i, j, num_char_deleted, num_char_end; + + if (gui_current_window->input_buffer_pos > 0) + { + i = gui_current_window->input_buffer_pos - 1; + while ((i >= 0) && + (gui_current_window->input_buffer[i] == ' ')) + i--; + if (i >= 0) + { + while ((i >= 0) && + (gui_current_window->input_buffer[i] != ' ')) + i--; + if (i >= 0) + { + while ((i >= 0) && + (gui_current_window->input_buffer[i] == ' ')) + i--; + } + } + + if (i >= 0) + i++; + i++; + num_char_deleted = gui_current_window->input_buffer_pos - i; + num_char_end = gui_current_window->input_buffer_size - + gui_current_window->input_buffer_pos; + + for (j = 0; j < num_char_end; j++) + gui_current_window->input_buffer[i + j] = + gui_current_window->input_buffer[gui_current_window->input_buffer_pos + j]; + + gui_current_window->input_buffer_size -= num_char_deleted; + gui_current_window->input_buffer[gui_current_window->input_buffer_size] = '\0'; + gui_current_window->input_buffer_pos = i; + gui_draw_window_input (gui_current_window); + gui_optimize_input_buffer_size (gui_current_window); + gui_current_window->completion.position = -1; + } +} + +/* + * gui_move_previous_word: move to beginning of previous word + */ + +void +gui_move_previous_word () +{ + int i; + + if (gui_current_window->input_buffer_pos > 0) + { + i = gui_current_window->input_buffer_pos - 1; + while ((i >= 0) && + (gui_current_window->input_buffer[i] == ' ')) + i--; + if (i < 0) + gui_current_window->input_buffer_pos = 0; + else + { + while ((i >= 0) && + (gui_current_window->input_buffer[i] != ' ')) + i--; + gui_current_window->input_buffer_pos = i + 1; + } + gui_draw_window_input (gui_current_window); + } +} + +/* + * gui_move_next_word: move to the end of next + */ + +void +gui_move_next_word () +{ + int i; + + if (gui_current_window->input_buffer_pos < + gui_current_window->input_buffer_size + 1) + { + i = gui_current_window->input_buffer_pos; + while ((i <= gui_current_window->input_buffer_size) && + (gui_current_window->input_buffer[i] == ' ')) + i++; + if (i > gui_current_window->input_buffer_size) + gui_current_window->input_buffer_pos = i - 1; + else + { + while ((i <= gui_current_window->input_buffer_size) && + (gui_current_window->input_buffer[i] != ' ')) + i++; + if (i > gui_current_window->input_buffer_size) + gui_current_window->input_buffer_pos = + gui_current_window->input_buffer_size; + else + gui_current_window->input_buffer_pos = i; + + } + gui_draw_window_input (gui_current_window); + } +} + +/* + * gui_buffer_insert_string: insert a string into the input buffer + */ + +void +gui_buffer_insert_string (char *string, int pos) +{ + int i, start, end, length; + + length = strlen (string); + + /* increase buffer size */ + gui_current_window->input_buffer_size += length; + gui_optimize_input_buffer_size (gui_current_window); + gui_current_window->input_buffer[gui_current_window->input_buffer_size] = '\0'; + + /* move end of string to the right */ + start = pos + length; + end = gui_current_window->input_buffer_size - 1; + for (i = end; i >= start; i--) + gui_current_window->input_buffer[i] = + gui_current_window->input_buffer[i - length]; + + /* insert new string */ + strncpy (gui_current_window->input_buffer + pos, string, length); +} |