Mercurial > ~mikael > mcabber > hg
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; |