# HG changeset patch # User Mikael Berthe # Date 1147124778 -7200 # Node ID 42c43a88d8238dcaad51c802a47d76868665e1c3 # Parent a9161d2dc414fdf21e2794b1f8788308fd1b46c7 Status buffer management Create a status window and a status history buffer. This special history buffer is not part of the winbuflst linked list, because it will be used early (for startup logs for example). diff -r a9161d2dc414 -r 42c43a88d823 mcabber/src/screen.c --- a/mcabber/src/screen.c Mon May 08 23:45:58 2006 +0200 +++ b/mcabber/src/screen.c Mon May 08 23:46:18 2006 +0200 @@ -70,6 +70,7 @@ static PANEL *mainstatusPanel, *chatstatusPanel; static PANEL *logPanel; static int maxY, maxX; +static winbuf *statusWindow; static winbuf *currentWindow; static int roster_hidden; @@ -377,6 +378,8 @@ g_free(buffer); } +// scr_CreateBuddyPanel(title, dontshow) +// Note: title (aka winId) can be NULL for special buffers static winbuf *scr_CreateBuddyPanel(const char *title, int dont_show) { int x; @@ -413,19 +416,26 @@ } update_panels(); - // Load buddy history from file (if enabled) - hlog_read_history(title, &tmp->hbuf, maxX - Roster_Width - PREFIX_WIDTH); + // If title is NULL, this is a special buffer + if (title) { + // Load buddy history from file (if enabled) + hlog_read_history(title, &tmp->hbuf, maxX - Roster_Width - PREFIX_WIDTH); - winbuflst = g_slist_append(winbuflst, tmp); + winbuflst = g_slist_append(winbuflst, tmp); + } return tmp; } -static winbuf *scr_SearchWindow(const char *winId) +static winbuf *scr_SearchWindow(const char *winId, int special) { GSList *wblp; winbuf *wbp; - if (!winId) return NULL; + if (special) + return statusWindow; // Only one special window atm. + + if (!winId) + return NULL; for (wblp = winbuflst; wblp; wblp = g_slist_next(wblp)) { wbp = wblp->data; @@ -439,7 +449,7 @@ bool scr_BuddyBufferExists(const char *jid) { - return (scr_SearchWindow(jid) != NULL); + return (scr_SearchWindow(jid, FALSE) != NULL); } // scr_UpdateWindow() @@ -534,19 +544,33 @@ // scr_ShowWindow() // Display the chat window with the given identifier. -static void scr_ShowWindow(const char *winId) +// "special" must be true if this is a special buffer window. +static void scr_ShowWindow(const char *winId, int special) { - winbuf *win_entry = scr_SearchWindow(winId); + winbuf *win_entry; + + win_entry = scr_SearchWindow(winId, special); - if (!win_entry) - win_entry = scr_CreateBuddyPanel(winId, FALSE); + if (!win_entry) { + if (special) { + if (!statusWindow) { + statusWindow = scr_CreateBuddyPanel(NULL, FALSE); + // We could set statusWindow->name here... + } + win_entry = statusWindow; + } else { + win_entry = scr_CreateBuddyPanel(winId, FALSE); + } + } top_panel(win_entry->panel); currentWindow = win_entry; chatmode = TRUE; - roster_msg_setflag(winId, FALSE); - roster_setflags(winId, ROSTER_FLAG_LOCK, TRUE); - update_roster = TRUE; + if (!special) { + roster_msg_setflag(winId, FALSE); + roster_setflags(winId, ROSTER_FLAG_LOCK, TRUE); + update_roster = TRUE; + } // Refresh the window scr_UpdateWindow(win_entry); @@ -563,10 +587,15 @@ { const gchar *jid; - if (!current_buddy) + if (!current_buddy) { jid = NULL; - else + } else { jid = CURRENT_JID; + if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL) { + scr_ShowWindow(buddy_getname(BUDDATA(current_buddy)), TRUE); + return; + } + } if (!jid) { top_panel(chatPanel); @@ -575,11 +604,12 @@ return; } - scr_ShowWindow(jid); + scr_ShowWindow(jid, FALSE); } // scr_WriteInWindow() // Write some text in the winId window (this usually is a jid). +// Use winId == NULL for the special status buffer. // Lines are splitted when they are too long to fit in the chat window. // If this window doesn't exist, it is created. void scr_WriteInWindow(const char *winId, const char *text, time_t timestamp, @@ -588,9 +618,11 @@ winbuf *win_entry; char *text_locale; int dont_show = FALSE; + int special; // Look for the window entry. - win_entry = scr_SearchWindow(winId); + special = (winId == NULL); + win_entry = scr_SearchWindow(winId, special); // Do we have to really show the window? if (!chatmode) @@ -599,8 +631,16 @@ dont_show = TRUE; // If the window entry doesn't exist yet, let's create it. - if (win_entry == NULL) { - win_entry = scr_CreateBuddyPanel(winId, dont_show); + if (!win_entry) { + if (special) { + if (!statusWindow) { + statusWindow = scr_CreateBuddyPanel(NULL, dont_show); + // We could set statusWindow->name here... + } + win_entry = statusWindow; + } else { + win_entry = scr_CreateBuddyPanel(winId, dont_show); + } } // The message must be displayed -> update top pointer @@ -635,7 +675,7 @@ top_panel(inputPanel); update_panels(); doupdate(); - } else if (!(prefix_flags & HBB_PREFIX_NOFLAG)) { + } else if (!special && !(prefix_flags & HBB_PREFIX_NOFLAG)) { roster_msg_setflag(winId, TRUE); update_roster = TRUE; } @@ -763,6 +803,10 @@ mainstatusPanel = new_panel(mainstatusWnd); inputPanel = new_panel(inputWnd); + // Build the buddylist at least once, to make sure the special buffer + // is added + buddylist_build(); + if (utf8_mode) scr_LogPrint(LPRINT_NORMAL, "WARNING: UTF-8 not yet supported!"); } else { @@ -780,6 +824,21 @@ return; } +static inline void resize_win_buffer(winbuf *wbp, int x, int y, + int lines, int cols) +{ + // Resize/move buddy window + wresize(wbp->win, lines, cols); + mvwin(wbp->win, 0, Roster_Width); + werase(wbp->win); + // If a panel exists, replace the old window with the new + if (wbp->panel) + replace_panel(wbp->panel, wbp->win); + // Redo line wrapping + wbp->top = hbuf_previous_persistent(wbp->top); + hbuf_rebuild(&wbp->hbuf, maxX - Roster_Width - PREFIX_WIDTH); +} + // scr_Resize() // Function called when the window is resized. // - Resize windows @@ -809,20 +868,14 @@ for (wblp = winbuflst; wblp; wblp = g_slist_next(wblp)) { wbp = wblp->data; - if (wbp->win) { - // Resize/move buddy window - wresize(wbp->win, lines, cols); - mvwin(wbp->win, 0, Roster_Width); - werase(wbp->win); - // If a panel exists, replace the old window with the new - if (wbp->panel) - replace_panel(wbp->panel, wbp->win); - // Redo line wrapping - wbp->top = hbuf_previous_persistent(wbp->top); - hbuf_rebuild(&wbp->hbuf, maxX - Roster_Width - PREFIX_WIDTH); - } + if (wbp->win) + resize_win_buffer(wbp, x, y, lines, cols); } + // Resize/move special status buffer + if (statusWindow) + resize_win_buffer(statusWindow, x, y, lines, cols); + // Refresh current buddy window if (chatmode) scr_ShowBuddyWindow(); @@ -1147,7 +1200,7 @@ void scr_WriteOutgoingMessage(const char *jidto, const char *text) { scr_WriteMessage(jidto, text, 0, HBB_PREFIX_OUT|HBB_PREFIX_HLIGHT); - scr_ShowWindow(jidto); + scr_ShowWindow(jidto, FALSE); } inline void set_autoaway(bool setaway) @@ -1355,10 +1408,13 @@ winbuf *win_entry; int n, nbl; GList *hbuf_top; + guint isspe; // Get win_entry if (!current_buddy) return; - win_entry = scr_SearchWindow(CURRENT_JID); + + isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; + win_entry = scr_SearchWindow(CURRENT_JID, isspe); if (!win_entry) return; if (!nblines) { @@ -1406,10 +1462,12 @@ void scr_BufferClear(void) { winbuf *win_entry; + guint isspe; // Get win_entry if (!current_buddy) return; - win_entry = scr_SearchWindow(CURRENT_JID); + isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; + win_entry = scr_SearchWindow(CURRENT_JID, isspe); if (!win_entry) return; win_entry->cleared = TRUE; @@ -1429,10 +1487,12 @@ void scr_BufferTopBottom(int topbottom) { winbuf *win_entry; + guint isspe; // Get win_entry if (!current_buddy) return; - win_entry = scr_SearchWindow(CURRENT_JID); + isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; + win_entry = scr_SearchWindow(CURRENT_JID, isspe); if (!win_entry) return; win_entry->cleared = FALSE; @@ -1456,10 +1516,12 @@ { winbuf *win_entry; GList *current_line, *search_res; + guint isspe; // Get win_entry if (!current_buddy) return; - win_entry = scr_SearchWindow(CURRENT_JID); + isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; + win_entry = scr_SearchWindow(CURRENT_JID, isspe); if (!win_entry) return; if (win_entry->top) @@ -1489,10 +1551,12 @@ { winbuf *win_entry; GList *search_res; + guint isspe; // Get win_entry if (!current_buddy) return; - win_entry = scr_SearchWindow(CURRENT_JID); + isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; + win_entry = scr_SearchWindow(CURRENT_JID, isspe); if (!win_entry) return; if (pc < 0 || pc > 100) { @@ -1520,10 +1584,12 @@ { winbuf *win_entry; GList *search_res; + guint isspe; // Get win_entry if (!current_buddy) return; - win_entry = scr_SearchWindow(CURRENT_JID); + isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; + win_entry = scr_SearchWindow(CURRENT_JID, isspe); if (!win_entry) return; search_res = hbuf_jump_date(win_entry->hbuf, t); @@ -1560,6 +1626,9 @@ { const char *current_jid; + if (!jid) + return; + if (current_buddy) current_jid = buddy_getjid(BUDDATA(current_buddy)); else