Mercurial > ~mikael > mcabber > hg
comparison mcabber/src/screen.c @ 849:42c43a88d823
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).
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Mon, 08 May 2006 23:46:18 +0200 |
parents | a9161d2dc414 |
children | d0781ca2dd08 |
comparison
equal
deleted
inserted
replaced
848:a9161d2dc414 | 849:42c43a88d823 |
---|---|
68 static WINDOW *mainstatusWnd, *chatstatusWnd; | 68 static WINDOW *mainstatusWnd, *chatstatusWnd; |
69 static PANEL *rosterPanel, *chatPanel, *inputPanel; | 69 static PANEL *rosterPanel, *chatPanel, *inputPanel; |
70 static PANEL *mainstatusPanel, *chatstatusPanel; | 70 static PANEL *mainstatusPanel, *chatstatusPanel; |
71 static PANEL *logPanel; | 71 static PANEL *logPanel; |
72 static int maxY, maxX; | 72 static int maxY, maxX; |
73 static winbuf *statusWindow; | |
73 static winbuf *currentWindow; | 74 static winbuf *currentWindow; |
74 | 75 |
75 static int roster_hidden; | 76 static int roster_hidden; |
76 static int chatmode; | 77 static int chatmode; |
77 static int multimode; | 78 static int multimode; |
375 g_free(buffer2); | 376 g_free(buffer2); |
376 } | 377 } |
377 g_free(buffer); | 378 g_free(buffer); |
378 } | 379 } |
379 | 380 |
381 // scr_CreateBuddyPanel(title, dontshow) | |
382 // Note: title (aka winId) can be NULL for special buffers | |
380 static winbuf *scr_CreateBuddyPanel(const char *title, int dont_show) | 383 static winbuf *scr_CreateBuddyPanel(const char *title, int dont_show) |
381 { | 384 { |
382 int x; | 385 int x; |
383 int y; | 386 int y; |
384 int lines; | 387 int lines; |
411 else | 414 else |
412 top_panel(chatPanel); | 415 top_panel(chatPanel); |
413 } | 416 } |
414 update_panels(); | 417 update_panels(); |
415 | 418 |
416 // Load buddy history from file (if enabled) | 419 // If title is NULL, this is a special buffer |
417 hlog_read_history(title, &tmp->hbuf, maxX - Roster_Width - PREFIX_WIDTH); | 420 if (title) { |
418 | 421 // Load buddy history from file (if enabled) |
419 winbuflst = g_slist_append(winbuflst, tmp); | 422 hlog_read_history(title, &tmp->hbuf, maxX - Roster_Width - PREFIX_WIDTH); |
423 | |
424 winbuflst = g_slist_append(winbuflst, tmp); | |
425 } | |
420 return tmp; | 426 return tmp; |
421 } | 427 } |
422 | 428 |
423 static winbuf *scr_SearchWindow(const char *winId) | 429 static winbuf *scr_SearchWindow(const char *winId, int special) |
424 { | 430 { |
425 GSList *wblp; | 431 GSList *wblp; |
426 winbuf *wbp; | 432 winbuf *wbp; |
427 | 433 |
428 if (!winId) return NULL; | 434 if (special) |
435 return statusWindow; // Only one special window atm. | |
436 | |
437 if (!winId) | |
438 return NULL; | |
429 | 439 |
430 for (wblp = winbuflst; wblp; wblp = g_slist_next(wblp)) { | 440 for (wblp = winbuflst; wblp; wblp = g_slist_next(wblp)) { |
431 wbp = wblp->data; | 441 wbp = wblp->data; |
432 if (wbp->name) { | 442 if (wbp->name) { |
433 if (!strcasecmp(wbp->name, winId)) | 443 if (!strcasecmp(wbp->name, winId)) |
437 return NULL; | 447 return NULL; |
438 } | 448 } |
439 | 449 |
440 bool scr_BuddyBufferExists(const char *jid) | 450 bool scr_BuddyBufferExists(const char *jid) |
441 { | 451 { |
442 return (scr_SearchWindow(jid) != NULL); | 452 return (scr_SearchWindow(jid, FALSE) != NULL); |
443 } | 453 } |
444 | 454 |
445 // scr_UpdateWindow() | 455 // scr_UpdateWindow() |
446 // (Re-)Display the given chat window. | 456 // (Re-)Display the given chat window. |
447 static void scr_UpdateWindow(winbuf *win_entry) | 457 static void scr_UpdateWindow(winbuf *win_entry) |
532 g_free(lines); | 542 g_free(lines); |
533 } | 543 } |
534 | 544 |
535 // scr_ShowWindow() | 545 // scr_ShowWindow() |
536 // Display the chat window with the given identifier. | 546 // Display the chat window with the given identifier. |
537 static void scr_ShowWindow(const char *winId) | 547 // "special" must be true if this is a special buffer window. |
538 { | 548 static void scr_ShowWindow(const char *winId, int special) |
539 winbuf *win_entry = scr_SearchWindow(winId); | 549 { |
540 | 550 winbuf *win_entry; |
541 if (!win_entry) | 551 |
542 win_entry = scr_CreateBuddyPanel(winId, FALSE); | 552 win_entry = scr_SearchWindow(winId, special); |
553 | |
554 if (!win_entry) { | |
555 if (special) { | |
556 if (!statusWindow) { | |
557 statusWindow = scr_CreateBuddyPanel(NULL, FALSE); | |
558 // We could set statusWindow->name here... | |
559 } | |
560 win_entry = statusWindow; | |
561 } else { | |
562 win_entry = scr_CreateBuddyPanel(winId, FALSE); | |
563 } | |
564 } | |
543 | 565 |
544 top_panel(win_entry->panel); | 566 top_panel(win_entry->panel); |
545 currentWindow = win_entry; | 567 currentWindow = win_entry; |
546 chatmode = TRUE; | 568 chatmode = TRUE; |
547 roster_msg_setflag(winId, FALSE); | 569 if (!special) { |
548 roster_setflags(winId, ROSTER_FLAG_LOCK, TRUE); | 570 roster_msg_setflag(winId, FALSE); |
549 update_roster = TRUE; | 571 roster_setflags(winId, ROSTER_FLAG_LOCK, TRUE); |
572 update_roster = TRUE; | |
573 } | |
550 | 574 |
551 // Refresh the window | 575 // Refresh the window |
552 scr_UpdateWindow(win_entry); | 576 scr_UpdateWindow(win_entry); |
553 | 577 |
554 // Finished :) | 578 // Finished :) |
561 // Display the chat window buffer for the current buddy. | 585 // Display the chat window buffer for the current buddy. |
562 void scr_ShowBuddyWindow(void) | 586 void scr_ShowBuddyWindow(void) |
563 { | 587 { |
564 const gchar *jid; | 588 const gchar *jid; |
565 | 589 |
566 if (!current_buddy) | 590 if (!current_buddy) { |
567 jid = NULL; | 591 jid = NULL; |
568 else | 592 } else { |
569 jid = CURRENT_JID; | 593 jid = CURRENT_JID; |
594 if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL) { | |
595 scr_ShowWindow(buddy_getname(BUDDATA(current_buddy)), TRUE); | |
596 return; | |
597 } | |
598 } | |
570 | 599 |
571 if (!jid) { | 600 if (!jid) { |
572 top_panel(chatPanel); | 601 top_panel(chatPanel); |
573 top_panel(inputPanel); | 602 top_panel(inputPanel); |
574 currentWindow = NULL; | 603 currentWindow = NULL; |
575 return; | 604 return; |
576 } | 605 } |
577 | 606 |
578 scr_ShowWindow(jid); | 607 scr_ShowWindow(jid, FALSE); |
579 } | 608 } |
580 | 609 |
581 // scr_WriteInWindow() | 610 // scr_WriteInWindow() |
582 // Write some text in the winId window (this usually is a jid). | 611 // Write some text in the winId window (this usually is a jid). |
612 // Use winId == NULL for the special status buffer. | |
583 // Lines are splitted when they are too long to fit in the chat window. | 613 // Lines are splitted when they are too long to fit in the chat window. |
584 // If this window doesn't exist, it is created. | 614 // If this window doesn't exist, it is created. |
585 void scr_WriteInWindow(const char *winId, const char *text, time_t timestamp, | 615 void scr_WriteInWindow(const char *winId, const char *text, time_t timestamp, |
586 unsigned int prefix_flags, int force_show) | 616 unsigned int prefix_flags, int force_show) |
587 { | 617 { |
588 winbuf *win_entry; | 618 winbuf *win_entry; |
589 char *text_locale; | 619 char *text_locale; |
590 int dont_show = FALSE; | 620 int dont_show = FALSE; |
621 int special; | |
591 | 622 |
592 // Look for the window entry. | 623 // Look for the window entry. |
593 win_entry = scr_SearchWindow(winId); | 624 special = (winId == NULL); |
625 win_entry = scr_SearchWindow(winId, special); | |
594 | 626 |
595 // Do we have to really show the window? | 627 // Do we have to really show the window? |
596 if (!chatmode) | 628 if (!chatmode) |
597 dont_show = TRUE; | 629 dont_show = TRUE; |
598 else if ((!force_show) && ((!currentWindow || (currentWindow != win_entry)))) | 630 else if ((!force_show) && ((!currentWindow || (currentWindow != win_entry)))) |
599 dont_show = TRUE; | 631 dont_show = TRUE; |
600 | 632 |
601 // If the window entry doesn't exist yet, let's create it. | 633 // If the window entry doesn't exist yet, let's create it. |
602 if (win_entry == NULL) { | 634 if (!win_entry) { |
603 win_entry = scr_CreateBuddyPanel(winId, dont_show); | 635 if (special) { |
636 if (!statusWindow) { | |
637 statusWindow = scr_CreateBuddyPanel(NULL, dont_show); | |
638 // We could set statusWindow->name here... | |
639 } | |
640 win_entry = statusWindow; | |
641 } else { | |
642 win_entry = scr_CreateBuddyPanel(winId, dont_show); | |
643 } | |
604 } | 644 } |
605 | 645 |
606 // The message must be displayed -> update top pointer | 646 // The message must be displayed -> update top pointer |
607 if (win_entry->cleared) | 647 if (win_entry->cleared) |
608 win_entry->top = g_list_last(win_entry->hbuf); | 648 win_entry->top = g_list_last(win_entry->hbuf); |
633 top_panel(win_entry->panel); | 673 top_panel(win_entry->panel); |
634 scr_UpdateWindow(win_entry); | 674 scr_UpdateWindow(win_entry); |
635 top_panel(inputPanel); | 675 top_panel(inputPanel); |
636 update_panels(); | 676 update_panels(); |
637 doupdate(); | 677 doupdate(); |
638 } else if (!(prefix_flags & HBB_PREFIX_NOFLAG)) { | 678 } else if (!special && !(prefix_flags & HBB_PREFIX_NOFLAG)) { |
639 roster_msg_setflag(winId, TRUE); | 679 roster_msg_setflag(winId, TRUE); |
640 update_roster = TRUE; | 680 update_roster = TRUE; |
641 } | 681 } |
642 } | 682 } |
643 | 683 |
761 logPanel = new_panel(logWnd); | 801 logPanel = new_panel(logWnd); |
762 chatstatusPanel = new_panel(chatstatusWnd); | 802 chatstatusPanel = new_panel(chatstatusWnd); |
763 mainstatusPanel = new_panel(mainstatusWnd); | 803 mainstatusPanel = new_panel(mainstatusWnd); |
764 inputPanel = new_panel(inputWnd); | 804 inputPanel = new_panel(inputWnd); |
765 | 805 |
806 // Build the buddylist at least once, to make sure the special buffer | |
807 // is added | |
808 buddylist_build(); | |
809 | |
766 if (utf8_mode) | 810 if (utf8_mode) |
767 scr_LogPrint(LPRINT_NORMAL, "WARNING: UTF-8 not yet supported!"); | 811 scr_LogPrint(LPRINT_NORMAL, "WARNING: UTF-8 not yet supported!"); |
768 } else { | 812 } else { |
769 // Update panels | 813 // Update panels |
770 replace_panel(rosterPanel, rosterWnd); | 814 replace_panel(rosterPanel, rosterWnd); |
778 // We'll need to redraw the roster | 822 // We'll need to redraw the roster |
779 update_roster = TRUE; | 823 update_roster = TRUE; |
780 return; | 824 return; |
781 } | 825 } |
782 | 826 |
827 static inline void resize_win_buffer(winbuf *wbp, int x, int y, | |
828 int lines, int cols) | |
829 { | |
830 // Resize/move buddy window | |
831 wresize(wbp->win, lines, cols); | |
832 mvwin(wbp->win, 0, Roster_Width); | |
833 werase(wbp->win); | |
834 // If a panel exists, replace the old window with the new | |
835 if (wbp->panel) | |
836 replace_panel(wbp->panel, wbp->win); | |
837 // Redo line wrapping | |
838 wbp->top = hbuf_previous_persistent(wbp->top); | |
839 hbuf_rebuild(&wbp->hbuf, maxX - Roster_Width - PREFIX_WIDTH); | |
840 } | |
841 | |
783 // scr_Resize() | 842 // scr_Resize() |
784 // Function called when the window is resized. | 843 // Function called when the window is resized. |
785 // - Resize windows | 844 // - Resize windows |
786 // - Rewrap lines in each buddy buffer | 845 // - Rewrap lines in each buddy buffer |
787 void scr_Resize() | 846 void scr_Resize() |
807 cols = maxX - Roster_Width; | 866 cols = maxX - Roster_Width; |
808 if (cols < 1) cols = 1; | 867 if (cols < 1) cols = 1; |
809 | 868 |
810 for (wblp = winbuflst; wblp; wblp = g_slist_next(wblp)) { | 869 for (wblp = winbuflst; wblp; wblp = g_slist_next(wblp)) { |
811 wbp = wblp->data; | 870 wbp = wblp->data; |
812 if (wbp->win) { | 871 if (wbp->win) |
813 // Resize/move buddy window | 872 resize_win_buffer(wbp, x, y, lines, cols); |
814 wresize(wbp->win, lines, cols); | 873 } |
815 mvwin(wbp->win, 0, Roster_Width); | 874 |
816 werase(wbp->win); | 875 // Resize/move special status buffer |
817 // If a panel exists, replace the old window with the new | 876 if (statusWindow) |
818 if (wbp->panel) | 877 resize_win_buffer(statusWindow, x, y, lines, cols); |
819 replace_panel(wbp->panel, wbp->win); | |
820 // Redo line wrapping | |
821 wbp->top = hbuf_previous_persistent(wbp->top); | |
822 hbuf_rebuild(&wbp->hbuf, maxX - Roster_Width - PREFIX_WIDTH); | |
823 } | |
824 } | |
825 | 878 |
826 // Refresh current buddy window | 879 // Refresh current buddy window |
827 if (chatmode) | 880 if (chatmode) |
828 scr_ShowBuddyWindow(); | 881 scr_ShowBuddyWindow(); |
829 } | 882 } |
1145 } | 1198 } |
1146 | 1199 |
1147 void scr_WriteOutgoingMessage(const char *jidto, const char *text) | 1200 void scr_WriteOutgoingMessage(const char *jidto, const char *text) |
1148 { | 1201 { |
1149 scr_WriteMessage(jidto, text, 0, HBB_PREFIX_OUT|HBB_PREFIX_HLIGHT); | 1202 scr_WriteMessage(jidto, text, 0, HBB_PREFIX_OUT|HBB_PREFIX_HLIGHT); |
1150 scr_ShowWindow(jidto); | 1203 scr_ShowWindow(jidto, FALSE); |
1151 } | 1204 } |
1152 | 1205 |
1153 inline void set_autoaway(bool setaway) | 1206 inline void set_autoaway(bool setaway) |
1154 { | 1207 { |
1155 static enum imstatus oldstatus; | 1208 static enum imstatus oldstatus; |
1353 void scr_BufferScrollUpDown(int updown, unsigned int nblines) | 1406 void scr_BufferScrollUpDown(int updown, unsigned int nblines) |
1354 { | 1407 { |
1355 winbuf *win_entry; | 1408 winbuf *win_entry; |
1356 int n, nbl; | 1409 int n, nbl; |
1357 GList *hbuf_top; | 1410 GList *hbuf_top; |
1411 guint isspe; | |
1358 | 1412 |
1359 // Get win_entry | 1413 // Get win_entry |
1360 if (!current_buddy) return; | 1414 if (!current_buddy) return; |
1361 win_entry = scr_SearchWindow(CURRENT_JID); | 1415 |
1416 isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; | |
1417 win_entry = scr_SearchWindow(CURRENT_JID, isspe); | |
1362 if (!win_entry) return; | 1418 if (!win_entry) return; |
1363 | 1419 |
1364 if (!nblines) { | 1420 if (!nblines) { |
1365 // Scroll half a screen (or less) | 1421 // Scroll half a screen (or less) |
1366 nbl = CHAT_WIN_HEIGHT/2; | 1422 nbl = CHAT_WIN_HEIGHT/2; |
1404 // scr_BufferClear() | 1460 // scr_BufferClear() |
1405 // Clear the current buddy window (used for the /clear command) | 1461 // Clear the current buddy window (used for the /clear command) |
1406 void scr_BufferClear(void) | 1462 void scr_BufferClear(void) |
1407 { | 1463 { |
1408 winbuf *win_entry; | 1464 winbuf *win_entry; |
1465 guint isspe; | |
1409 | 1466 |
1410 // Get win_entry | 1467 // Get win_entry |
1411 if (!current_buddy) return; | 1468 if (!current_buddy) return; |
1412 win_entry = scr_SearchWindow(CURRENT_JID); | 1469 isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; |
1470 win_entry = scr_SearchWindow(CURRENT_JID, isspe); | |
1413 if (!win_entry) return; | 1471 if (!win_entry) return; |
1414 | 1472 |
1415 win_entry->cleared = TRUE; | 1473 win_entry->cleared = TRUE; |
1416 win_entry->top = NULL; | 1474 win_entry->top = NULL; |
1417 | 1475 |
1427 // Jump to the head/tail of the current buddy window | 1485 // Jump to the head/tail of the current buddy window |
1428 // (top if topbottom == -1, bottom topbottom == 1) | 1486 // (top if topbottom == -1, bottom topbottom == 1) |
1429 void scr_BufferTopBottom(int topbottom) | 1487 void scr_BufferTopBottom(int topbottom) |
1430 { | 1488 { |
1431 winbuf *win_entry; | 1489 winbuf *win_entry; |
1490 guint isspe; | |
1432 | 1491 |
1433 // Get win_entry | 1492 // Get win_entry |
1434 if (!current_buddy) return; | 1493 if (!current_buddy) return; |
1435 win_entry = scr_SearchWindow(CURRENT_JID); | 1494 isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; |
1495 win_entry = scr_SearchWindow(CURRENT_JID, isspe); | |
1436 if (!win_entry) return; | 1496 if (!win_entry) return; |
1437 | 1497 |
1438 win_entry->cleared = FALSE; | 1498 win_entry->cleared = FALSE; |
1439 if (topbottom == 1) | 1499 if (topbottom == 1) |
1440 win_entry->top = NULL; | 1500 win_entry->top = NULL; |
1454 // (backward search if direction == -1, forward if topbottom == 1) | 1514 // (backward search if direction == -1, forward if topbottom == 1) |
1455 void scr_BufferSearch(int direction, const char *text) | 1515 void scr_BufferSearch(int direction, const char *text) |
1456 { | 1516 { |
1457 winbuf *win_entry; | 1517 winbuf *win_entry; |
1458 GList *current_line, *search_res; | 1518 GList *current_line, *search_res; |
1519 guint isspe; | |
1459 | 1520 |
1460 // Get win_entry | 1521 // Get win_entry |
1461 if (!current_buddy) return; | 1522 if (!current_buddy) return; |
1462 win_entry = scr_SearchWindow(CURRENT_JID); | 1523 isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; |
1524 win_entry = scr_SearchWindow(CURRENT_JID, isspe); | |
1463 if (!win_entry) return; | 1525 if (!win_entry) return; |
1464 | 1526 |
1465 if (win_entry->top) | 1527 if (win_entry->top) |
1466 current_line = win_entry->top; | 1528 current_line = win_entry->top; |
1467 else | 1529 else |
1487 // Jump to the specified position in the buffer, in % | 1549 // Jump to the specified position in the buffer, in % |
1488 void scr_BufferPercent(int pc) | 1550 void scr_BufferPercent(int pc) |
1489 { | 1551 { |
1490 winbuf *win_entry; | 1552 winbuf *win_entry; |
1491 GList *search_res; | 1553 GList *search_res; |
1554 guint isspe; | |
1492 | 1555 |
1493 // Get win_entry | 1556 // Get win_entry |
1494 if (!current_buddy) return; | 1557 if (!current_buddy) return; |
1495 win_entry = scr_SearchWindow(CURRENT_JID); | 1558 isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; |
1559 win_entry = scr_SearchWindow(CURRENT_JID, isspe); | |
1496 if (!win_entry) return; | 1560 if (!win_entry) return; |
1497 | 1561 |
1498 if (pc < 0 || pc > 100) { | 1562 if (pc < 0 || pc > 100) { |
1499 scr_LogPrint(LPRINT_NORMAL, "Bad % value"); | 1563 scr_LogPrint(LPRINT_NORMAL, "Bad % value"); |
1500 return; | 1564 return; |
1518 // t is a date in seconds since `00:00:00 1970-01-01 UTC' | 1582 // t is a date in seconds since `00:00:00 1970-01-01 UTC' |
1519 void scr_BufferDate(time_t t) | 1583 void scr_BufferDate(time_t t) |
1520 { | 1584 { |
1521 winbuf *win_entry; | 1585 winbuf *win_entry; |
1522 GList *search_res; | 1586 GList *search_res; |
1587 guint isspe; | |
1523 | 1588 |
1524 // Get win_entry | 1589 // Get win_entry |
1525 if (!current_buddy) return; | 1590 if (!current_buddy) return; |
1526 win_entry = scr_SearchWindow(CURRENT_JID); | 1591 isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; |
1592 win_entry = scr_SearchWindow(CURRENT_JID, isspe); | |
1527 if (!win_entry) return; | 1593 if (!win_entry) return; |
1528 | 1594 |
1529 search_res = hbuf_jump_date(win_entry->hbuf, t); | 1595 search_res = hbuf_jump_date(win_entry->hbuf, t); |
1530 | 1596 |
1531 win_entry->cleared = FALSE; | 1597 win_entry->cleared = FALSE; |
1557 // scr_setmsgflag_if_needed(jid) | 1623 // scr_setmsgflag_if_needed(jid) |
1558 // Set the message flag unless we're already in the jid buffer window | 1624 // Set the message flag unless we're already in the jid buffer window |
1559 void scr_setmsgflag_if_needed(const char *jid) | 1625 void scr_setmsgflag_if_needed(const char *jid) |
1560 { | 1626 { |
1561 const char *current_jid; | 1627 const char *current_jid; |
1628 | |
1629 if (!jid) | |
1630 return; | |
1562 | 1631 |
1563 if (current_buddy) | 1632 if (current_buddy) |
1564 current_jid = buddy_getjid(BUDDATA(current_buddy)); | 1633 current_jid = buddy_getjid(BUDDATA(current_buddy)); |
1565 else | 1634 else |
1566 current_jid = NULL; | 1635 current_jid = NULL; |