Memory leak fixes.
[silc.git] / apps / irssi / src / fe-text / silc.c
index 17a77967fda0ce6d0af67ab07633e4f4efa76377..c5f68a8d4dc65e94f1acb036bc59d062ac4be000 100644 (file)
@@ -1,7 +1,7 @@
 /*
  irssi.c : irssi
 
-    Copyright (C) 1999-2000 Timo Sirainen
+    Copyright (C) 1999-2000, 2007 Timo Sirainen
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -43,6 +43,7 @@
 #include "textbuffer-reformat.h"
 
 #include <signal.h>
+#include <locale.h>
 
 #ifdef HAVE_STATIC_PERL
 void perl_core_init(void);
@@ -77,21 +78,29 @@ static int dirty, full_redraw, dummy;
 
 static GMainLoop *main_loop;
 int quitting;
+int quit_signalled;
+int protocols_deinit;
 
-static const char *firsttimer_text =
-       "Looks like this is the first time you run irssi.\n"
-       "This is just a reminder that you really should go read\n"
-       "startup-HOWTO if you haven't already. Irssi's default\n"
-       "settings aren't probably what you've used to, and you\n"
-       "shouldn't judge the whole client as crap based on them.\n\n"
-       "You can find startup-HOWTO and more irssi beginner info at\n"
-       "http://irssi.org/beginner/";
 static int display_firsttimer = FALSE;
 
+/* Protocol exit signal to tell protocol has gone away.  Safe to quit. */
+
+static void sig_protocol_exit(void)
+{
+  protocols_deinit = TRUE;
+  if (!quitting && quit_signalled)
+    quitting = TRUE;
+}
 
 static void sig_exit(void)
 {
-        quitting = TRUE;
+  quit_signalled = TRUE;
+
+  /* If protocol hasn't finished yet, wait untill it sends "chat protocol
+     deinit" signal. */
+  if (!protocols_deinit)
+    return;
+  quitting = TRUE;
 }
 
 /* redraw irssi's screen.. */
@@ -147,15 +156,19 @@ static void textui_init(void)
        core_init();
        silc_init();
        fe_common_core_init();
-       fe_common_silc_init();
+       fe_silc_init();
 
        theme_register(gui_text_formats);
        signal_add_last("gui exit", (SIGNAL_FUNC) sig_exit);
+       signal_add_last("chat protocol deinit",
+                       (SIGNAL_FUNC) sig_protocol_exit);
 }
 
 static void textui_finish_init(void)
 {
        quitting = FALSE;
+       quit_signalled = FALSE;
+       protocols_deinit = FALSE;
 
        if (dummy)
                term_dummy_init();
@@ -175,9 +188,11 @@ static void textui_finish_init(void)
                gui_windows_init();
                statusbar_init();
                term_refresh_thaw();
+
+               /* don't check settings with dummy mode */
+               settings_check();
        }
 
-       settings_check();
        module_register("core", "fe-text");
 
 #ifdef HAVE_STATIC_PERL
@@ -189,13 +204,6 @@ static void textui_finish_init(void)
 
        fe_common_core_finish_init();
        signal_emit("irssi init finished", 0);
-
-#if 0
-       if (display_firsttimer) {
-               printtext_window(active_win, MSGLEVEL_CLIENTNOTICE,
-                                "%s", firsttimer_text);
-       }
-#endif
 }
 
 static void textui_deinit(void)
@@ -213,6 +221,7 @@ static void textui_deinit(void)
 
         dirty_check(); /* one last time to print any quit messages */
        signal_remove("gui exit", (SIGNAL_FUNC) sig_exit);
+       signal_remove("chat protocol deinit", (SIGNAL_FUNC) sig_protocol_exit);
 
        if (dummy)
                term_dummy_deinit();
@@ -237,7 +246,7 @@ static void textui_deinit(void)
 
        theme_unregister();
 
-       fe_common_silc_deinit();
+       fe_silc_deinit();
        fe_common_core_deinit();
        silc_deinit();
        core_deinit();
@@ -306,15 +315,41 @@ static void winsock_init(void)
 }
 #endif
 
+#ifdef USE_GC
+#ifdef HAVE_GC_H
+#  include <gc.h>
+#else
+#  include <gc/gc.h>
+#endif
+
+GMemVTable gc_mem_table = {
+       GC_malloc,
+       GC_realloc,
+       GC_free,
+
+       NULL, NULL, NULL
+};
+#endif
+
 int main(int argc, char **argv)
 {
        static struct poptOption options[] = {
+#if 0 /* --dummy is not available in SILC Client */
                { "dummy", 'd', POPT_ARG_NONE, &dummy, 0, "Use the dummy terminal mode", NULL },
+#endif
                { NULL, '\0', 0, NULL }
        };
 
+#ifdef USE_GC
+       g_mem_set_vtable(&gc_mem_table);
+#endif
+
+       srand(time(NULL));
+
        dummy = FALSE;
        quitting = FALSE;
+       quit_signalled = FALSE;
+       protocols_deinit = FALSE;
        core_init_paths(argc, argv);
 
        check_files();
@@ -331,6 +366,17 @@ int main(int argc, char **argv)
        textdomain(PACKAGE);
 #endif
 
+       /* setlocale() must be called at the beginning before any calls that
+          affect it, especially regexps seem to break if they're generated
+          before t his call.
+
+          locales aren't actually used for anything else than autodetection
+          of UTF-8 currently..
+
+          furthermore to get the users's charset with g_get_charset() properly
+          you have to call setlocale(LC_ALL, "") */
+       setlocale(LC_ALL, "");
+
        textui_init();
        args_register(options);
        args_execute(argc, argv);
@@ -347,7 +393,19 @@ int main(int argc, char **argv)
        /* Does the same as g_main_run(main_loop), except we
           can call our dirty-checker after each iteration */
        while (!quitting) {
+#ifdef USE_GC
+               GC_collect_a_little();
+#endif
+               if (!dummy) term_refresh_freeze();
                g_main_iteration(TRUE);
+               if (!dummy) term_refresh_thaw();
+
+               if (reload_config) {
+                       /* SIGHUP received, do /RELOAD */
+                       reload_config = FALSE;
+                       signal_emit("command reload", 1, "");
+               }
+
                 dirty_check();
        }