Merged from silc_1_0_branch (second merge).
[silc.git] / apps / irssi / src / fe-text / silc.c
1 /*
2  irssi.c : irssi
3
4     Copyright (C) 1999-2000 Timo Sirainen
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "module.h"
22 #include "module-formats.h"
23 #include "modules-load.h"
24 #include "args.h"
25 #include "signals.h"
26 #include "levels.h"
27 #include "core.h"
28 #include "settings.h"
29 #include "session.h"
30
31 #include "printtext.h"
32 #include "fe-common-core.h"
33 #include "fe-common-silc.h"
34 #include "themes.h"
35
36 #include "term.h"
37 #include "gui-entry.h"
38 #include "mainwindows.h"
39 #include "gui-printtext.h"
40 #include "gui-readline.h"
41 #include "statusbar.h"
42 #include "gui-windows.h"
43 #include "textbuffer-reformat.h"
44
45 #include <signal.h>
46 #include <locale.h>
47
48 #ifdef HAVE_STATIC_PERL
49 void perl_core_init(void);
50 void perl_core_deinit(void);
51
52 void fe_perl_init(void);
53 void fe_perl_deinit(void);
54 #endif
55
56 void silc_init(void);
57 void silc_deinit(void);
58
59 void gui_expandos_init(void);
60 void gui_expandos_deinit(void);
61
62 void textbuffer_commands_init(void);
63 void textbuffer_commands_deinit(void);
64
65 void lastlog_init(void);
66 void lastlog_deinit(void);
67
68 void mainwindow_activity_init(void);
69 void mainwindow_activity_deinit(void);
70
71 void mainwindows_layout_init(void);
72 void mainwindows_layout_deinit(void);
73
74 void term_dummy_init(void);
75 void term_dummy_deinit(void);
76
77 static int dirty, full_redraw, dummy;
78
79 static GMainLoop *main_loop;
80 int quitting;
81
82 static const char *firsttimer_text =
83         "Looks like this is the first time you run irssi.\n"
84         "This is just a reminder that you really should go read\n"
85         "startup-HOWTO if you haven't already. Irssi's default\n"
86         "settings aren't probably what you've used to, and you\n"
87         "shouldn't judge the whole client as crap based on them.\n\n"
88         "You can find startup-HOWTO and more irssi beginner info at\n"
89         "http://irssi.org/beginner/";
90 static int display_firsttimer = FALSE;
91
92
93 static void sig_exit(void)
94 {
95         quitting = TRUE;
96 }
97
98 /* redraw irssi's screen.. */
99 void irssi_redraw(void)
100 {
101         dirty = TRUE;
102         full_redraw = TRUE;
103 }
104
105 void irssi_set_dirty(void)
106 {
107         dirty = TRUE;
108 }
109
110 static void dirty_check(void)
111 {
112         if (!dirty || dummy)
113                 return;
114
115         term_resize_dirty();
116
117         if (full_redraw) {
118                 full_redraw = FALSE;
119
120                 /* first clear the screen so curses will be
121                    forced to redraw the screen */
122                 term_clear();
123                 term_refresh(NULL);
124
125                 mainwindows_redraw();
126                 statusbar_redraw(NULL, TRUE);
127         }
128
129         mainwindows_redraw_dirty();
130         statusbar_redraw_dirty();
131         term_refresh(NULL);
132
133         dirty = FALSE;
134 }
135
136 static void textui_init(void)
137 {
138 #ifdef SIGTRAP
139         struct sigaction act;
140
141         sigemptyset(&act.sa_mask);
142         act.sa_flags = 0;
143         act.sa_handler = SIG_IGN;
144         sigaction(SIGTRAP, &act, NULL);
145 #endif
146
147         irssi_gui = IRSSI_GUI_TEXT;
148         core_init();
149         silc_init();
150         fe_common_core_init();
151         fe_silc_init();
152
153         theme_register(gui_text_formats);
154         signal_add_last("gui exit", (SIGNAL_FUNC) sig_exit);
155 }
156
157 static void textui_finish_init(void)
158 {
159         quitting = FALSE;
160
161         if (dummy)
162                 term_dummy_init();
163         else {
164                 term_refresh_freeze();
165                 textbuffer_init();
166                 textbuffer_view_init();
167                 textbuffer_commands_init();
168                 textbuffer_reformat_init();
169                 gui_expandos_init();
170                 gui_printtext_init();
171                 gui_readline_init();
172                 lastlog_init();
173                 mainwindows_init();
174                 mainwindow_activity_init();
175                 mainwindows_layout_init();
176                 gui_windows_init();
177                 statusbar_init();
178                 term_refresh_thaw();
179         }
180
181         settings_check();
182         module_register("core", "fe-text");
183
184 #ifdef HAVE_STATIC_PERL
185         perl_core_init();
186         fe_perl_init();
187 #endif
188
189         dirty_check();
190
191         fe_common_core_finish_init();
192         signal_emit("irssi init finished", 0);
193
194 #if 0
195         if (display_firsttimer) {
196                 printtext_window(active_win, MSGLEVEL_CLIENTNOTICE,
197                                  "%s", firsttimer_text);
198         }
199 #endif
200 }
201
202 static void textui_deinit(void)
203 {
204         signal(SIGINT, SIG_DFL);
205
206         term_refresh_freeze();
207         while (modules != NULL)
208                 module_unload(modules->data);
209
210 #ifdef HAVE_STATIC_PERL
211         perl_core_deinit();
212         fe_perl_deinit();
213 #endif
214
215         dirty_check(); /* one last time to print any quit messages */
216         signal_remove("gui exit", (SIGNAL_FUNC) sig_exit);
217
218         if (dummy)
219                 term_dummy_deinit();
220         else {
221                 lastlog_deinit();
222                 statusbar_deinit();
223                 gui_printtext_deinit();
224                 gui_readline_deinit();
225                 gui_windows_deinit();
226                 mainwindows_layout_deinit();
227                 mainwindow_activity_deinit();
228                 mainwindows_deinit();
229                 gui_expandos_deinit();
230                 textbuffer_reformat_deinit();
231                 textbuffer_commands_deinit();
232                 textbuffer_view_deinit();
233                 textbuffer_deinit();
234
235                 term_refresh_thaw();
236                 term_deinit();
237         }
238
239         theme_unregister();
240
241         fe_silc_deinit();
242         fe_common_core_deinit();
243         silc_deinit();
244         core_deinit();
245 }
246
247 static void check_oldcrap(void)
248 {
249         FILE *f;
250         char *path, str[256];
251         int found;
252
253         /* check that default.theme is up-to-date */
254         path = g_strdup_printf("%s/default.theme", get_irssi_dir());
255         f = fopen(path, "r+");
256         if (f == NULL) {
257                 g_free(path);
258                 return;
259         }
260         found = FALSE;
261         while (!found && fgets(str, sizeof(str), f) != NULL)
262                 found = strstr(str, "abstracts = ") != NULL;
263         fclose(f);
264
265         if (found) {
266                 g_free(path);
267                 return;
268         }
269
270         printf("\nYou seem to have old default.theme in "IRSSI_DIR_SHORT"/ directory.\n");
271         printf("Themeing system has changed a bit since last irssi release,\n");
272         printf("you should either delete your old default.theme or manually\n");
273         printf("merge it with the new default.theme.\n\n");
274         printf("Do you want to delete the old theme now? (Y/n)\n");
275
276         str[0] = '\0';
277         fgets(str, sizeof(str), stdin);
278         if (i_toupper(str[0]) == 'Y' || str[0] == '\n' || str[0] == '\0')
279                 remove(path);
280         g_free(path);
281 }
282
283 static void check_files(void)
284 {
285         struct stat statbuf;
286
287         if (stat(get_irssi_dir(), &statbuf) != 0) {
288                 /* ~/.irssi doesn't exist, first time running irssi */
289                 display_firsttimer = TRUE;
290         } else {
291                 check_oldcrap();
292         }
293 }
294
295 #ifdef WIN32
296 static void winsock_init(void)
297 {
298         WORD wVersionRequested;
299         WSADATA wsaData;
300
301         wVersionRequested = MAKEWORD(2, 2);
302
303         if (WSAStartup(wVersionRequested, &wsaData) != 0) {
304                 printf("Error initializing winsock\n");
305                 exit(1);
306         }
307 }
308 #endif
309
310 int main(int argc, char **argv)
311 {
312         static struct poptOption options[] = {
313 #if 0 /* --dummy is not available in SILC Client */
314                 { "dummy", 'd', POPT_ARG_NONE, &dummy, 0, "Use the dummy terminal mode", NULL },
315 #endif
316                 { NULL, '\0', 0, NULL }
317         };
318
319         dummy = FALSE;
320         quitting = FALSE;
321         core_init_paths(argc, argv);
322
323         check_files();
324
325 #ifdef WIN32
326         winsock_init();
327 #endif
328 #ifdef HAVE_SOCKS
329         SOCKSinit(argv[0]);
330 #endif
331 #ifdef ENABLE_NLS
332         /* initialize the i18n stuff */
333         bindtextdomain(PACKAGE, LOCALEDIR);
334         textdomain(PACKAGE);
335 #endif
336
337         /* setlocale() must be called at the beginning before any callsthat
338            affect it, especially regexps seem to break if they'regenerated
339            before t his call.
340
341            locales aren't actually used for anything else thanautodetection
342            of UTF-8 currently.. */
343         setlocale(LC_CTYPE, "");
344
345         textui_init();
346         args_register(options);
347         args_execute(argc, argv);
348
349         if (!dummy && !term_init()) {
350                 fprintf(stderr, "Can't initialize screen handling, quitting.\n");
351                 fprintf(stderr, "You can still use the dummy mode with -d parameter\n");
352                 return 1;
353         }
354
355         textui_finish_init();
356         main_loop = g_main_new(TRUE);
357
358         /* Does the same as g_main_run(main_loop), except we
359            can call our dirty-checker after each iteration */
360         while (!quitting) {
361                 g_main_iteration(TRUE);
362                 dirty_check();
363         }
364
365         g_main_destroy(main_loop);
366         textui_deinit();
367
368         session_upgrade(); /* if we /UPGRADEd, start the new process */
369         return 0;
370 }