Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / fe-text / silc.c
index 7c05703cdc58f5386facbedff1b1c11a65092f87..000d5f6884f8a4b893589573addd8e7e81af639e 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
 
 #include "module.h"
 #include "module-formats.h"
+#include "modules-load.h"
 #include "args.h"
 #include "signals.h"
 #include "levels.h"
 #include "core.h"
 #include "settings.h"
+#include "session.h"
 
 #include "printtext.h"
 #include "fe-common-core.h"
 #include "fe-common-silc.h"
 #include "themes.h"
 
-#include "screen.h"
+#include "term.h"
 #include "gui-entry.h"
 #include "mainwindows.h"
 #include "gui-printtext.h"
 #include "gui-readline.h"
 #include "statusbar.h"
 #include "gui-windows.h"
+#include "textbuffer-reformat.h"
 
 #include <signal.h>
+#include <locale.h>
 
 #ifdef HAVE_STATIC_PERL
 void perl_core_init(void);
@@ -64,134 +68,163 @@ void lastlog_deinit(void);
 void mainwindow_activity_init(void);
 void mainwindow_activity_deinit(void);
 
-void mainwindows_save_init(void);
-void mainwindows_save_deinit(void);
+void mainwindows_layout_init(void);
+void mainwindows_layout_deinit(void);
+
+void term_dummy_init(void);
+void term_dummy_deinit(void);
+
+static int dirty, full_redraw, dummy;
 
 static GMainLoop *main_loop;
 int quitting;
 
-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;
 
-
 static void sig_exit(void)
 {
-       g_main_quit(main_loop);
+  quitting = TRUE;
 }
 
 /* redraw irssi's screen.. */
 void irssi_redraw(void)
 {
-       clear();
-       refresh();
-
-       /* windows */
-        mainwindows_redraw();
-       /* statusbar */
-       statusbar_redraw(NULL);
-       /* entry line */
-       gui_entry_redraw();
+       dirty = TRUE;
+        full_redraw = TRUE;
+}
+
+void irssi_set_dirty(void)
+{
+        dirty = TRUE;
+}
+
+static void dirty_check(void)
+{
+       if (!dirty || dummy)
+               return;
+
+        term_resize_dirty();
+
+       if (full_redraw) {
+                full_redraw = FALSE;
+
+               /* first clear the screen so curses will be
+                  forced to redraw the screen */
+               term_clear();
+               term_refresh(NULL);
+
+               mainwindows_redraw();
+               statusbar_redraw(NULL, TRUE);
+       }
+
+       mainwindows_redraw_dirty();
+        statusbar_redraw_dirty();
+       term_refresh(NULL);
+
+        dirty = FALSE;
 }
 
 static void textui_init(void)
 {
-       static struct poptOption options[] = {
-               POPT_AUTOHELP
-               { NULL, '\0', 0, NULL }
-       };
+#ifdef SIGTRAP
+       struct sigaction act;
 
-       args_register(options);
+       sigemptyset(&act.sa_mask);
+       act.sa_flags = 0;
+       act.sa_handler = SIG_IGN;
+       sigaction(SIGTRAP, &act, NULL);
+#endif
 
        irssi_gui = IRSSI_GUI_TEXT;
        core_init();
        silc_init();
        fe_common_core_init();
-       fe_common_silc_init();
+       fe_silc_init();
 
        theme_register(gui_text_formats);
-       signal_add("gui exit", (SIGNAL_FUNC) sig_exit);
+       signal_add_last("gui exit", (SIGNAL_FUNC) sig_exit);
 }
 
 static void textui_finish_init(void)
 {
        quitting = FALSE;
 
-       screen_refresh_freeze();
-        textbuffer_init();
-        textbuffer_view_init();
-       textbuffer_commands_init();
-       gui_entry_init();
-       gui_expandos_init();
-       gui_printtext_init();
-       gui_readline_init();
-        lastlog_init();
-       mainwindows_init();
-       mainwindow_activity_init();
-       mainwindows_save_init();
-       gui_windows_init();
-       statusbar_init();
-
-       settings_check();
+       if (dummy)
+               term_dummy_init();
+       else {
+               term_refresh_freeze();
+               textbuffer_init();
+               textbuffer_view_init();
+               textbuffer_commands_init();
+               textbuffer_reformat_init();
+               gui_expandos_init();
+               gui_printtext_init();
+               gui_readline_init();
+               lastlog_init();
+               mainwindows_init();
+               mainwindow_activity_init();
+               mainwindows_layout_init();
+               gui_windows_init();
+               statusbar_init();
+               term_refresh_thaw();
+
+               /* don't check settings with dummy mode */
+               settings_check();
+       }
 
-       fe_common_core_finish_init();
+       module_register("core", "fe-text");
 
 #ifdef HAVE_STATIC_PERL
        perl_core_init();
-        fe_perl_init();
+       fe_perl_init();
 #endif
-       signal_emit("irssi init finished", 0);
 
-       if (display_firsttimer) {
-               printtext_window(active_win, MSGLEVEL_CLIENTNOTICE,
-                                "%s", firsttimer_text);
-       }
+       dirty_check();
 
-       screen_refresh_thaw();
+       fe_common_core_finish_init();
+       signal_emit("irssi init finished", 0);
 }
 
 static void textui_deinit(void)
 {
-       quitting = TRUE;
        signal(SIGINT, SIG_DFL);
 
-        screen_refresh_freeze();
+        term_refresh_freeze();
        while (modules != NULL)
                module_unload(modules->data);
 
-       signal_remove("gui exit", (SIGNAL_FUNC) sig_exit);
-
-        lastlog_deinit();
-       statusbar_deinit();
-       gui_printtext_deinit();
-       gui_readline_deinit();
-       gui_windows_deinit();
-       mainwindows_save_deinit();
-       mainwindow_activity_deinit();
-       mainwindows_deinit();
-       gui_expandos_deinit();
-       gui_entry_deinit();
-       textbuffer_commands_deinit();
-        textbuffer_view_deinit();
-        textbuffer_deinit();
-
-        screen_refresh_thaw();
-       deinit_screen();
-
 #ifdef HAVE_STATIC_PERL
-        fe_perl_deinit();
         perl_core_deinit();
+        fe_perl_deinit();
 #endif
 
+        dirty_check(); /* one last time to print any quit messages */
+       signal_remove("gui exit", (SIGNAL_FUNC) sig_exit);
+
+       if (dummy)
+               term_dummy_deinit();
+       else {
+               lastlog_deinit();
+               statusbar_deinit();
+               gui_printtext_deinit();
+               gui_readline_deinit();
+               gui_windows_deinit();
+               mainwindows_layout_deinit();
+               mainwindow_activity_deinit();
+               mainwindows_deinit();
+               gui_expandos_deinit();
+               textbuffer_reformat_deinit();
+               textbuffer_commands_deinit();
+               textbuffer_view_deinit();
+               textbuffer_deinit();
+
+               term_refresh_thaw();
+               term_deinit();
+       }
+
        theme_unregister();
 
-       fe_common_silc_deinit();
+       fe_silc_deinit();
        fe_common_core_deinit();
        silc_deinit();
        core_deinit();
@@ -204,7 +237,7 @@ static void check_oldcrap(void)
         int found;
 
         /* check that default.theme is up-to-date */
-       path = g_strdup_printf("%s/.silc/default.theme", g_get_home_dir());
+       path = g_strdup_printf("%s/default.theme", get_irssi_dir());
        f = fopen(path, "r+");
        if (f == NULL) {
                g_free(path);
@@ -220,7 +253,7 @@ static void check_oldcrap(void)
                return;
        }
 
-       printf("\nYou seem to have old default.theme in ~/.silc/ directory.\n");
+       printf("\nYou seem to have old default.theme in "IRSSI_DIR_SHORT"/ directory.\n");
         printf("Themeing system has changed a bit since last irssi release,\n");
         printf("you should either delete your old default.theme or manually\n");
         printf("merge it with the new default.theme.\n\n");
@@ -228,7 +261,7 @@ static void check_oldcrap(void)
 
        str[0] = '\0';
        fgets(str, sizeof(str), stdin);
-       if (toupper(str[0]) == 'Y' || str[0] == '\n' || str[0] == '\0')
+       if (i_toupper(str[0]) == 'Y' || str[0] == '\n' || str[0] == '\0')
                 remove(path);
        g_free(path);
 }
@@ -236,16 +269,13 @@ static void check_oldcrap(void)
 static void check_files(void)
 {
        struct stat statbuf;
-        char *path;
 
-        path = g_strdup_printf("%s/.silc", g_get_home_dir());
-       if (stat(path, &statbuf) != 0) {
+       if (stat(get_irssi_dir(), &statbuf) != 0) {
                /* ~/.irssi doesn't exist, first time running irssi */
                display_firsttimer = TRUE;
        } else {
                 check_oldcrap();
        }
-        g_free(path);
 }
 
 #ifdef WIN32
@@ -263,9 +293,43 @@ 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;
+       core_init_paths(argc, argv);
+
        check_files();
+
 #ifdef WIN32
         winsock_init();
 #endif
@@ -278,22 +342,52 @@ 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);
-       silc_init_finish();
 
-       if (!init_screen())
-               g_error("Can't initialize screen handling, quitting.\n");
+       if (!dummy && !term_init()) {
+               fprintf(stderr, "Can't initialize screen handling, quitting.\n");
+               fprintf(stderr, "You can still use the dummy mode with -d parameter\n");
+               return 1;
+       }
 
        textui_finish_init();
        main_loop = g_main_new(TRUE);
-       g_main_run(main_loop);
-       g_main_destroy(main_loop);
-       textui_deinit();
 
-#ifdef MEM_DEBUG
-       ig_mem_profile();
+       /* 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();
+       }
+
+       g_main_destroy(main_loop);
+       textui_deinit();
 
+        session_upgrade(); /* if we /UPGRADEd, start the new process */
        return 0;
 }