comparison mcabber/mcabber/screen.c @ 2222:ce1043326bbc

Fix a small leak when a window is closed Also, fix a segfault when buffer close is called with a non-lowercase JID...
author Mikael Berthe <mikael@lilotux.net>
date Fri, 06 Nov 2015 20:33:31 +0100
parents 902f271743b0
children dc3b3ac1ba76
comparison
equal deleted inserted replaced
2221:3f9988ec21e0 2222:ce1043326bbc
1707 chat_x_pos = Roster_Width; 1707 chat_x_pos = Roster_Width;
1708 } 1708 }
1709 1709
1710 if (fullinit) { 1710 if (fullinit) {
1711 if (!winbufhash) 1711 if (!winbufhash)
1712 winbufhash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); 1712 winbufhash = g_hash_table_new_full(g_str_hash, g_str_equal,
1713 g_free, g_free);
1713 /* Create windows */ 1714 /* Create windows */
1714 rosterWnd = newwin(CHAT_WIN_HEIGHT, Roster_Width, chat_y_pos, roster_x_pos); 1715 rosterWnd = newwin(CHAT_WIN_HEIGHT, Roster_Width, chat_y_pos, roster_x_pos);
1715 chatWnd = newwin(CHAT_WIN_HEIGHT, maxX - Roster_Width, chat_y_pos, 1716 chatWnd = newwin(CHAT_WIN_HEIGHT, maxX - Roster_Width, chat_y_pos,
1716 chat_x_pos); 1717 chat_x_pos);
1717 activechatWnd = newwin(CHAT_WIN_HEIGHT, maxX - Roster_Width, chat_y_pos, 1718 activechatWnd = newwin(CHAT_WIN_HEIGHT, maxX - Roster_Width, chat_y_pos,
2856 // buffer_purge() 2857 // buffer_purge()
2857 // key: winId/jid 2858 // key: winId/jid
2858 // value: winbuf structure 2859 // value: winbuf structure
2859 // data: int, set to 1 if the buffer should be closed. 2860 // data: int, set to 1 if the buffer should be closed.
2860 // NOTE: does not work for special buffers. 2861 // NOTE: does not work for special buffers.
2862 // Returns TRUE IFF the win_entry can be closed and freed.
2861 static gboolean buffer_purge(gpointer key, gpointer value, gpointer data) 2863 static gboolean buffer_purge(gpointer key, gpointer value, gpointer data)
2862 { 2864 {
2863 int *p_closebuf = data; 2865 int *p_closebuf = data;
2864 winbuf *win_entry = value; 2866 winbuf *win_entry = value;
2865 gboolean retval = FALSE; 2867 gboolean retval = FALSE;
2886 // If closebuf is 1, close the buffer. 2888 // If closebuf is 1, close the buffer.
2887 void scr_buffer_purge(int closebuf, const char *jid) 2889 void scr_buffer_purge(int closebuf, const char *jid)
2888 { 2890 {
2889 winbuf *win_entry; 2891 winbuf *win_entry;
2890 guint isspe; 2892 guint isspe;
2891 guint *p_closebuf;
2892 const char *cjid; 2893 const char *cjid;
2894 char *ljid = NULL;
2893 guint hold_chatmode = FALSE; 2895 guint hold_chatmode = FALSE;
2894 2896
2895 if (jid) { 2897 if (jid) {
2896 cjid = jid;
2897 isspe = FALSE; 2898 isspe = FALSE;
2899 ljid = g_strdup(jid);
2900 mc_strtolower(ljid);
2901 cjid = ljid;
2898 // If closebuf is TRUE, it's probably better not to leave chat mode 2902 // If closebuf is TRUE, it's probably better not to leave chat mode
2899 // if the change isn't related to the current buffer. 2903 // if the change isn't related to the current buffer.
2900 if (closebuf && current_buddy) { 2904 if (closebuf && current_buddy) {
2901 if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL || 2905 if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL ||
2902 strcasecmp(jid, CURRENT_JID)) 2906 strcasecmp(jid, CURRENT_JID))
2907 if (!current_buddy) return; 2911 if (!current_buddy) return;
2908 cjid = CURRENT_JID; 2912 cjid = CURRENT_JID;
2909 isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL; 2913 isspe = buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_SPECIAL;
2910 } 2914 }
2911 win_entry = scr_search_window(cjid, isspe); 2915 win_entry = scr_search_window(cjid, isspe);
2912 if (!win_entry) return; 2916 if (!win_entry) {
2917 g_free(ljid);
2918 return;
2919 }
2913 2920
2914 if (!isspe) { 2921 if (!isspe) {
2915 p_closebuf = g_new(guint, 1); 2922 if (buffer_purge((gpointer)cjid, win_entry, &closebuf))
2916 *p_closebuf = closebuf;
2917 if(buffer_purge((gpointer)cjid, win_entry, p_closebuf))
2918 g_hash_table_remove(winbufhash, cjid); 2923 g_hash_table_remove(winbufhash, cjid);
2919 roster_msg_setflag(cjid, FALSE, FALSE); 2924 roster_msg_setflag(cjid, FALSE, FALSE);
2920 g_free(p_closebuf);
2921 if (closebuf && !hold_chatmode) { 2925 if (closebuf && !hold_chatmode) {
2922 scr_set_chatmode(FALSE); 2926 scr_set_chatmode(FALSE);
2923 currentWindow = NULL; 2927 currentWindow = NULL;
2924 } 2928 }
2925 } else { 2929 } else {
2939 // Refresh the window 2943 // Refresh the window
2940 scr_update_buddy_window(); 2944 scr_update_buddy_window();
2941 2945
2942 // Finished :) 2946 // Finished :)
2943 update_panels(); 2947 update_panels();
2948
2949 g_free(ljid);
2944 } 2950 }
2945 2951
2946 // scr_buffer_purge_all(closebuf) 2952 // scr_buffer_purge_all(closebuf)
2947 // Purge all existing buffers. 2953 // Purge all existing buffers.
2948 // If closebuf is 1, the buffers are closed. 2954 // If closebuf is 1, the buffers are closed.
2949 void scr_buffer_purge_all(int closebuf) 2955 void scr_buffer_purge_all(int closebuf)
2950 { 2956 {
2951 guint *p_closebuf; 2957 g_hash_table_foreach_remove(winbufhash, buffer_purge, &closebuf);
2952 p_closebuf = g_new(guint, 1);
2953
2954 *p_closebuf = closebuf;
2955 g_hash_table_foreach_remove(winbufhash, buffer_purge, p_closebuf);
2956 g_free(p_closebuf);
2957 2958
2958 if (closebuf) { 2959 if (closebuf) {
2959 scr_set_chatmode(FALSE); 2960 scr_set_chatmode(FALSE);
2960 currentWindow = NULL; 2961 currentWindow = NULL;
2961 } 2962 }