comparison mcabber/mcabber/screen.c @ 2225:dc3b3ac1ba76

Free the buffdata structures when buffers are closed Free the buffdata strcutures when buffers are closed and there are no more users (these structures can be shared if the "symlink" shared history is used).
author Mikael Berthe <mikael@lilotux.net>
date Sat, 07 Nov 2015 12:21:12 +0100
parents ce1043326bbc
children c1eb68306520
comparison
equal deleted inserted replaced
2224:736f9323d701 2225:dc3b3ac1ba76
98 #endif 98 #endif
99 99
100 static GHashTable *winbufhash; 100 static GHashTable *winbufhash;
101 101
102 typedef struct { 102 typedef struct {
103 GList *hbuf; 103 GList *hbuf;
104 GList *top; // If top is NULL, we'll display the last lines 104 GList *top; // If top is NULL, we'll display the last lines
105 char cleared; // For ex, user has issued a /clear command... 105 char cleared; // For ex, user has issued a /clear command...
106 char lock; 106 char lock;
107 char refcount; // refcount > 0 if there are other users of this struct
108 // e.g. with symlinked history
107 } buffdata; 109 } buffdata;
108 110
109 typedef struct { 111 typedef struct {
110 WINDOW *win; 112 WINDOW *win;
111 PANEL *panel; 113 PANEL *panel;
1036 // scr_new_buddy(title, dontshow) 1038 // scr_new_buddy(title, dontshow)
1037 // Note: title (aka winId/jid) can be NULL for special buffers 1039 // Note: title (aka winId/jid) can be NULL for special buffers
1038 static winbuf *scr_new_buddy(const char *title, int dont_show) 1040 static winbuf *scr_new_buddy(const char *title, int dont_show)
1039 { 1041 {
1040 winbuf *tmp; 1042 winbuf *tmp;
1043 char *id;
1041 1044
1042 tmp = g_new0(winbuf, 1); 1045 tmp = g_new0(winbuf, 1);
1043 1046
1044 tmp->win = activechatWnd; 1047 tmp->win = activechatWnd;
1045 tmp->panel = activechatPanel; 1048 tmp->panel = activechatPanel;
1053 top_panel(chatPanel); 1056 top_panel(chatPanel);
1054 } 1057 }
1055 update_panels(); 1058 update_panels();
1056 1059
1057 // If title is NULL, this is a special buffer 1060 // If title is NULL, this is a special buffer
1058 if (title) { 1061 if (!title) {
1059 char *id;
1060 id = hlog_get_log_jid(title);
1061 if (id) {
1062 winbuf *wb = scr_search_window(id, FALSE);
1063 if (!wb)
1064 wb = scr_new_buddy(id, TRUE);
1065 tmp->bd=wb->bd;
1066 g_free(id);
1067 } else { // Load buddy history from file (if enabled)
1068 tmp->bd = g_new0(buffdata, 1);
1069 hlog_read_history(title, &tmp->bd->hbuf,
1070 maxX - Roster_Width - scr_getprefixwidth());
1071
1072 // Set a readmark to separate new content
1073 hbuf_set_readmark(tmp->bd->hbuf, TRUE);
1074 }
1075
1076 id = g_strdup(title);
1077 mc_strtolower(id);
1078 g_hash_table_insert(winbufhash, id, tmp);
1079 } else {
1080 tmp->bd = g_new0(buffdata, 1); 1062 tmp->bd = g_new0(buffdata, 1);
1081 } 1063 return tmp;
1064 }
1065
1066 id = hlog_get_log_jid(title);
1067 if (id) {
1068 // This is a symlinked history log file.
1069 // Let's check if the target JID buffer has already been created.
1070 winbuf *wb = scr_search_window(id, FALSE);
1071 if (!wb)
1072 wb = scr_new_buddy(id, TRUE);
1073 tmp->bd = wb->bd;
1074 tmp->bd->refcount++;
1075 g_free(id);
1076 } else { // Load buddy history from file (if enabled)
1077 tmp->bd = g_new0(buffdata, 1);
1078 hlog_read_history(title, &tmp->bd->hbuf,
1079 maxX - Roster_Width - scr_getprefixwidth());
1080
1081 // Set a readmark to separate new content
1082 hbuf_set_readmark(tmp->bd->hbuf, TRUE);
1083 }
1084
1085 id = g_strdup(title);
1086 mc_strtolower(id);
1087 g_hash_table_insert(winbufhash, id, tmp);
1088
1082 return tmp; 1089 return tmp;
1083 } 1090 }
1084 1091
1085 // scr_line_prefix(line, pref, preflen) 1092 // scr_line_prefix(line, pref, preflen)
1086 // Use data from the hbb_line structure and write the prefix 1093 // Use data from the hbb_line structure and write the prefix
2865 int *p_closebuf = data; 2872 int *p_closebuf = data;
2866 winbuf *win_entry = value; 2873 winbuf *win_entry = value;
2867 gboolean retval = FALSE; 2874 gboolean retval = FALSE;
2868 2875
2869 // Delete the current hbuf 2876 // Delete the current hbuf
2870 hbuf_free(&win_entry->bd->hbuf); 2877 // unless we close the buffer *and* this is a shared bd structure
2878 if (!(*p_closebuf && win_entry->bd->refcount))
2879 hbuf_free(&win_entry->bd->hbuf);
2871 2880
2872 if (*p_closebuf) { 2881 if (*p_closebuf) {
2873 GSList *roster_elt; 2882 GSList *roster_elt;
2874 retval = TRUE; 2883 retval = TRUE;
2875 roster_elt = roster_find(key, jidsearch, 2884 roster_elt = roster_find(key, jidsearch,
2876 ROSTER_TYPE_USER|ROSTER_TYPE_AGENT); 2885 ROSTER_TYPE_USER|ROSTER_TYPE_AGENT);
2877 if (roster_elt) 2886 if (roster_elt)
2878 buddy_setactiveresource(roster_elt->data, NULL); 2887 buddy_setactiveresource(roster_elt->data, NULL);
2888 if (win_entry->bd->refcount) {
2889 win_entry->bd->refcount--;
2890 } else {
2891 g_free(win_entry->bd);
2892 win_entry->bd = NULL;
2893 }
2879 } else { 2894 } else {
2880 win_entry->bd->cleared = FALSE; 2895 win_entry->bd->cleared = FALSE;
2881 win_entry->bd->top = NULL; 2896 win_entry->bd->top = NULL;
2882 } 2897 }
2883 return retval; 2898 return retval;