# HG changeset patch # User mikael # Date 1113669451 0 # Node ID b392112ab995c1c0954f10f12c0f0d0aa49afa74 # Parent 1fc66b6c08eff2cae7b150ba466dd900046d6f97 [/trunk] Changeset 88 by mikael * Switch to using hbuf, the new history buffer implementation. * I've had to rewrite some parts of the interface, and I have removed the frames for the roster and the chat window. * The wrapping is not perfect, as the prefix is not yet treated separately... * Seems to be a display problem when receiving UTF-8, too. :-( diff -r 1fc66b6c08ef -r b392112ab995 mcabber/src/buddies.c --- a/mcabber/src/buddies.c Sat Apr 16 11:59:26 2005 +0000 +++ b/mcabber/src/buddies.c Sat Apr 16 16:37:31 2005 +0000 @@ -13,7 +13,7 @@ #define STR_EMPTY(s) ((s)[0] == '\0') /* global vars for BUDDIES.C */ -int buddySelected = 1; /* Hold the selected Buddy */ +int buddySelected = 0; /* Hold the selected Buddy */ int buddyOffset = 0; /* Hold the roster offset */ static LIST_HEAD(buddy_list); @@ -126,20 +126,21 @@ int n; int maxx, maxy; int fakeOffset = buddyOffset; - char name[ROSTER_WEIGHT]; + char name[ROSTER_WIDTH]; getmaxyx(win, maxy, maxx); - name[ROSTER_WEIGHT-8] = 0; + maxx --; // last char is for vertical border + name[ROSTER_WIDTH-8] = 0; /* cleanup of roster window */ wattrset(win, COLOR_PAIR(COLOR_GENERAL)); - for (i = 1; i < maxy - 1; i++) { - mvwprintw(win, i, 1, ""); - for (n = 2; n < maxx; n++) + for (i = 0; i < maxy; i++) { + mvwprintw(win, i, 0, ""); + for (n = 0; n < maxx; n++) waddch(win, ' '); } - i = 1; + i = 0; list_for_each_safe(pos, nn, &buddy_list) { char status = '?'; @@ -169,11 +170,11 @@ else wattrset(win, COLOR_PAIR(COLOR_BD_DES)); } - mvwprintw(win, i, 1, ""); + mvwprintw(win, i, 0, ""); for (n = 2; n < maxx; n++) waddch(win, ' '); - strncpy(name, tmp->name, ROSTER_WEIGHT-8); - mvwprintw(win, i, 1, " %c[%c] %s", pending, status, name); + strncpy(name, tmp->name, ROSTER_WIDTH-8); + mvwprintw(win, i, 0, " %c[%c] %s", pending, status, name); i++; if (i >= maxy - 1) break; @@ -195,9 +196,8 @@ { int x, y; getmaxyx(scr_GetRosterWindow(), y, x); - y -= 2; - if (buddySelected < bud_BuddyCount()) { + if (buddySelected+1 < bud_BuddyCount()) { buddySelected++; if (buddySelected > y) buddyOffset++; @@ -214,9 +214,9 @@ */ void bud_RosterUp(void) { - if (buddySelected > 1) { + if (buddySelected > 0) { buddySelected--; - if (buddySelected - buddyOffset < 1) + if (buddySelected < buddyOffset) buddyOffset--; bud_DrawRoster(scr_GetRosterWindow()); } @@ -238,7 +238,7 @@ list_for_each_safe(pos, n, &buddy_list) { tmp = buddy_entry(pos); - if (i == buddySelected - 1) { + if (i == buddySelected) { return tmp; } i++; diff -r 1fc66b6c08ef -r b392112ab995 mcabber/src/screen.c --- a/mcabber/src/screen.c Sat Apr 16 11:59:26 2005 +0000 +++ b/mcabber/src/screen.c Sat Apr 16 16:37:31 2005 +0000 @@ -15,6 +15,7 @@ #include "lang.h" #include "list.h" #include "utf8.h" +#include "hbuf.h" #define window_entry(n) list_entry(n, window_entry_t, list) @@ -24,8 +25,7 @@ WINDOW *win; PANEL *panel; char *name; - int nlines; - char **texto; + GList *hbuf; int hidden_msg; struct list_head list; } window_entry_t; @@ -49,13 +49,25 @@ /* Funciones */ -int scr_WindowHeight(WINDOW * win) +int scr_WindowWidth(WINDOW * win) { int x, y; getmaxyx(win, y, x); return x; } +void scr_clear_box(WINDOW *win, int y, int x, int height, int width, int Color) +{ + int i, j; + + wattrset(win, COLOR_PAIR(Color)); + for (i = 0; i < height; i++) { + wmove(win, y + i, x); + for (j = 0; j < width; j++) + wprintw(win, " "); + } +} + void scr_draw_box(WINDOW * win, int y, int x, int height, int width, int Color, chtype box, chtype border) { @@ -174,7 +186,8 @@ tmp->name = (char *) calloc(1, 1024); strncpy(tmp->name, title, 1024); - scr_draw_box(tmp->win, 0, 0, lines, cols, COLOR_GENERAL, 0, 0); + //scr_draw_box(tmp->win, 0, 0, lines, cols, COLOR_GENERAL, 0, 0); + scr_clear_box(tmp->win, 0, 0, lines, cols, COLOR_GENERAL); //mvwprintw(tmp->win, 0, (cols - (2 + strlen(title))) / 2, " %s ", title); if ((!dont_show)) { currentWindow = tmp; @@ -211,29 +224,61 @@ return NULL; } +void scr_UpdateWindow(window_entry_t *win_entry) +{ + int n; + int width; + char **lines; + GList *hbuf_head; + + // We will show the last CHAT_WIN_HEIGHT lines. + // Let's find out where it begins. + win_entry->hbuf = g_list_last(win_entry->hbuf); + hbuf_head = win_entry->hbuf; + for (n=0; hbuf_head && n<(CHAT_WIN_HEIGHT-1) && g_list_previous(hbuf_head); n++) + hbuf_head = g_list_previous(hbuf_head); + + // Get the last CHAT_WIN_HEIGHT lines. + lines = hbuf_get_lines(hbuf_head, CHAT_WIN_HEIGHT); + + // Display these lines + width = scr_WindowWidth(win_entry->win); + wmove(win_entry->win, 0, 0); + for (n = 0; n < CHAT_WIN_HEIGHT; n++) { + int r = width; + if (*(lines+n)) { + wprintw(win_entry->win, "%s", *(lines+n)); + r -= strlen(*(lines+n)); + }// else + // wmove(win_entry->win, n, 0); + for ( ; r>0 ; r--) { + wprintw(win_entry->win, " "); + } + //// wclrtoeol(win_entry->win); does not work :( + } + g_free(lines); +} + void scr_ShowWindow(const char *winId) { - int n, width, i; - window_entry_t *tmp = scr_SearchWindow(winId); - if (tmp != NULL) { - top_panel(tmp->panel); - currentWindow = tmp; + window_entry_t *win_entry = scr_SearchWindow(winId); + + if (win_entry != NULL) { + top_panel(win_entry->panel); + currentWindow = win_entry; chatmode = TRUE; - tmp->hidden_msg = FALSE; + win_entry->hidden_msg = FALSE; update_roster = TRUE; - width = scr_WindowHeight(tmp->win); - for (n = 0; n < tmp->nlines; n++) { - mvwprintw(tmp->win, n + 1, 1, ""); - for (i = 0; i < width - 2; i++) - waddch(tmp->win, ' '); - mvwprintw(tmp->win, n + 1, 1, "%s", tmp->texto[n]); - } - //move(CHAT_WIN_HEIGHT - 1, maxX - 1); + + // Refresh the window entry + scr_UpdateWindow(win_entry); + + // Finished :) update_panels(); doupdate(); } else { top_panel(chatPanel); - currentWindow = tmp; + currentWindow = win_entry; // == NULL (current window empty) } } @@ -246,79 +291,53 @@ } -void scr_WriteInWindow(const char *winId, char *texto, int TimeStamp, int force_show) +void scr_WriteInWindow(const char *winId, char *text, int TimeStamp, + int force_show) { - time_t ahora; - int n; - int i; - int width; - window_entry_t *tmp; + char *line; + window_entry_t *win_entry; int dont_show = FALSE; - tmp = scr_SearchWindow(winId); + line = calloc(1, strlen(text)+16); + // Prepare line (timestamp + text) + // FIXME: actually timestamp and text should not be merged, there is a prefix + // field in the hbuf_block structure just for that. + if (TimeStamp) { + time_t now = time(NULL); + strftime(line, 12, "[%H:%M] ", localtime(&now)); + } else { + strcpy(line, " "); + } + strcat(line, text); + + // Look for the window entry. + win_entry = scr_SearchWindow(winId); + + // Do we have to really show the window? if (!chatmode) dont_show = TRUE; - else if ((!force_show) && ((!currentWindow || (currentWindow != tmp)))) + else if ((!force_show) && ((!currentWindow || (currentWindow != win_entry)))) dont_show = TRUE; - if (tmp == NULL) { - tmp = scr_CreatePanel(winId, ROSTER_WEIGHT, 0, CHAT_WIN_HEIGHT, - maxX - ROSTER_WEIGHT, dont_show); - tmp->texto = (char **) calloc((CHAT_WIN_HEIGHT+1) * 3, sizeof(char *)); - for (n = 0; n < CHAT_WIN_HEIGHT * 3; n++) - tmp->texto[n] = (char *) calloc(1, 1024); - - if (TimeStamp) { - ahora = time(NULL); - strftime(tmp->texto[tmp->nlines], 1024, "[%H:%M] ", - localtime(&ahora)); - strcat(tmp->texto[tmp->nlines], texto); - } else { - sprintf(tmp->texto[tmp->nlines], " %s", texto); - } - tmp->nlines++; - } else { - if (tmp->nlines < CHAT_WIN_HEIGHT - 2) { - if (TimeStamp) { - ahora = time(NULL); - strftime(tmp->texto[tmp->nlines], 1024, - "[%H:%M] ", localtime(&ahora)); - strcat(tmp->texto[tmp->nlines], texto); - } else { - sprintf(tmp->texto[tmp->nlines], " %s", texto); - } - tmp->nlines++; - } else { - for (n = 0; n < tmp->nlines; n++) { - memset(tmp->texto[n], 0, 1024); - strncpy(tmp->texto[n], tmp->texto[n + 1], 1024); - } - if (TimeStamp) { - ahora = time(NULL); - strftime(tmp->texto[tmp->nlines - 1], 1024, - "[%H:%M] ", localtime(&ahora)); - strcat(tmp->texto[tmp->nlines - 1], texto); - } else { - sprintf(tmp->texto[tmp->nlines - 1], " %s", texto); - } - } + // If the window entry doesn't exist yet, let's create it. + if (win_entry == NULL) { + win_entry = scr_CreatePanel(winId, ROSTER_WIDTH, 0, CHAT_WIN_HEIGHT, + maxX - ROSTER_WIDTH, dont_show); } + hbuf_add_line(&win_entry->hbuf, line, + maxX - scr_WindowWidth(rosterWnd) - 14); + free(line); + if (!dont_show) { - top_panel(tmp->panel); - width = scr_WindowHeight(tmp->win); - for (n = 0; n < tmp->nlines; n++) { - mvwprintw(tmp->win, n + 1, 1, ""); - for (i = 0; i < width - 2; i++) - waddch(tmp->win, ' '); - mvwprintw(tmp->win, n + 1, 1, "%s", tmp->texto[n]); - } - + // Show and refresh the window + top_panel(win_entry->panel); + scr_UpdateWindow(win_entry); update_panels(); doupdate(); } else { - tmp->hidden_msg = TRUE; + win_entry->hidden_msg = TRUE; update_roster = TRUE; } } @@ -345,19 +364,22 @@ void scr_DrawMainWindow(void) { + int l; + /* Draw main panels */ - rosterWnd = newwin(CHAT_WIN_HEIGHT, ROSTER_WEIGHT, 0, 0); + rosterWnd = newwin(CHAT_WIN_HEIGHT, ROSTER_WIDTH, 0, 0); rosterPanel = new_panel(rosterWnd); - scr_draw_box(rosterWnd, 0, 0, CHAT_WIN_HEIGHT, ROSTER_WEIGHT, - COLOR_GENERAL, 0, 0); - mvwprintw(rosterWnd, 0, (ROSTER_WEIGHT - strlen(i18n("Roster"))) / 2, - i18n("Roster")); + scr_clear_box(rosterWnd, 0, 0, CHAT_WIN_HEIGHT, ROSTER_WIDTH, + COLOR_GENERAL); + for (l=0 ; l < CHAT_WIN_HEIGHT ; l++) + mvwaddch(rosterWnd, l, ROSTER_WIDTH-1, ACS_VLINE); - chatWnd = newwin(CHAT_WIN_HEIGHT, maxX - ROSTER_WEIGHT, 0, ROSTER_WEIGHT); + chatWnd = newwin(CHAT_WIN_HEIGHT, maxX - ROSTER_WIDTH, 0, ROSTER_WIDTH); chatPanel = new_panel(chatWnd); - scr_draw_box(chatWnd, 0, 0, CHAT_WIN_HEIGHT, maxX - ROSTER_WEIGHT, - COLOR_GENERAL, 0, 0); - mvwprintw(chatWnd, 1, 1, "This is the status window"); + scr_clear_box(chatWnd, 0, 0, CHAT_WIN_HEIGHT, maxX - ROSTER_WIDTH, + COLOR_GENERAL); + scrollok(chatWnd, TRUE); + mvwprintw(chatWnd, 0, 0, "This is the status window"); logWnd_border = newwin(LOG_WIN_HEIGHT, maxX, CHAT_WIN_HEIGHT, 0); logPanel_border = new_panel(logWnd_border); @@ -366,7 +388,7 @@ logPanel = new_panel(logWnd); wbkgd(logWnd, COLOR_PAIR(COLOR_GENERAL)); - scrollok(logWnd,TRUE); + scrollok(logWnd, TRUE); inputWnd = newwin(1, maxX, maxY-1, 0); inputPanel = new_panel(inputWnd); @@ -385,11 +407,11 @@ return; } +// XXX This function is almost useless now. Once we handle properly +// the prefix in scr_WriteInWindow(), we can remove it... void scr_WriteMessage(const char *jid, const char *text, char *prefix) { - char **submsgs; - int n, i; - char *buffer = (char *) malloc(strlen(text) + strlen(text)); + char *buffer = (char *) malloc(strlen(prefix) + strlen(text) + 1); if (prefix) strcpy(buffer, prefix); @@ -398,25 +420,15 @@ strcat(buffer, text); - submsgs = - ut_SplitMessage(buffer, &n, maxX - scr_WindowHeight(rosterWnd) - 14); + scr_WriteInWindow(jid, buffer, TRUE, FALSE); - for (i = 0; i < n; i++) { - if (i == 0) - scr_WriteInWindow(jid, submsgs[i], TRUE, FALSE); - else - scr_WriteInWindow(jid, submsgs[i], FALSE, FALSE); - } - - for (i = 0; i < n; i++) - free(submsgs[i]); - free(submsgs); free(buffer); } void scr_WriteIncomingMessage(const char *jidfrom, const char *text) { char *buffer = utf8_decode(text); + // FIXME expand tabs... scr_WriteMessage(jidfrom, buffer, "<== "); free(buffer); top_panel(inputPanel); diff -r 1fc66b6c08ef -r b392112ab995 mcabber/src/screen.h --- a/mcabber/src/screen.h Sat Apr 16 11:59:26 2005 +0000 +++ b/mcabber/src/screen.h Sat Apr 16 16:37:31 2005 +0000 @@ -11,7 +11,7 @@ #define COLOR_BD_DES 7 #define LOG_WIN_HEIGHT (5+2) -#define ROSTER_WEIGHT 24 +#define ROSTER_WIDTH 24 #define CHAT_WIN_HEIGHT (maxY-1-LOG_WIN_HEIGHT) #define INPUTLINE_LENGTH 1024