Exit when out of terminals or windows
[tilda-gobject.git] / tilda.c
1 #include <glib.h>
2 #include <stdlib.h>
3
4 #include "tilda.h"
5 #include "tilda-window.h"
6 #include "tilda-terminal.h"
7 #include "tomboykeybinder.h"
8
9 DBusGConnection *dbus_connection;
10 GPtrArray *windows;
11
12 static void
13 tilda_initialize_dbus ()
14 {
15         debug_enter  ();
16
17         static const gchar service_name[] = "net.sourceforge.Tilda";
18         GError *error = NULL;
19         DBusGProxy *driver_proxy;
20         guint request_ret;
21         gboolean ret;
22
23         // Initialize the DBus connection
24         dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
25         if (dbus_connection == NULL)
26         {
27                 g_warning (_("Unable to connect to DBus: %s\n"), error->message);
28                 g_error_free (error);
29                 return;
30         }
31
32         // Register the service name
33         driver_proxy = dbus_g_proxy_new_for_name (dbus_connection,
34                                                                                           DBUS_SERVICE_DBUS,
35                                                                                           DBUS_PATH_DBUS,
36                                                                                           DBUS_INTERFACE_DBUS);
37
38         ret = org_freedesktop_DBus_request_name (driver_proxy,
39                                                                                          service_name,
40                                                                                          DBUS_NAME_FLAG_DO_NOT_QUEUE,
41                                                                                          &request_ret,
42                                                                                          &error);
43
44         if (!ret)
45         {
46                 g_warning (_("Unable to communicate with DBus: %s\n"), error->message);
47                 g_error_free (error);
48         }
49
50         if (request_ret == DBUS_REQUEST_NAME_REPLY_EXISTS)
51         {
52                 g_critical (_("There is already an instance of Tilda running\n"));
53                 exit (EXIT_FAILURE);
54         }
55
56         g_object_unref (driver_proxy);
57 }
58
59 static gint
60 tilda_find_next_free_window_number ()
61 {
62         debug_enter  ();
63
64         gint i, j;
65         gboolean found;
66
67         for (i=0; i<INT_MAX; ++i)
68         {
69                 found = FALSE;
70
71                 for (j=0; j<windows->len; ++j)
72                 {
73                         TildaWindow *tw = g_ptr_array_index (windows, j);
74
75                         if (tw->number == i)
76                         {
77                                 found = TRUE;
78                                 break;
79                         }
80                 }
81
82                 if (!found)
83                         return i;
84         }
85
86         return 0;
87 }
88
89 static TildaWindow *
90 tilda_add_window ()
91 {
92         debug_enter ();
93
94         TildaWindow *ret;
95         gint number;
96
97         number = tilda_find_next_free_window_number ();
98         ret = g_object_new (TILDA_TYPE_WINDOW, "number", number, NULL);
99
100         g_ptr_array_add (windows, ret);
101
102         debug_printf ("Adding window: 0x%x (number %d of %d)\n", ret, ret->number, windows->len-1);
103         return ret;
104 }
105
106 void
107 tilda_del_window (gint number)
108 {
109         debug_enter ();
110
111         gint i;
112         TildaWindow *win;
113
114         for (i=0; i<windows->len; ++i)
115         {
116                 win = g_ptr_array_index (windows, i);
117
118                 if (win->number == number)
119                 {
120                         debug_printf ("Deleting window 0x%x (number %d of %d)\n", win, win->number, windows->len-1);
121                         g_ptr_array_remove_index (windows, i);
122                         g_object_unref (G_OBJECT(win));
123
124                         if (windows->len == 0)
125                         {
126                                 debug_printf ("No windows left, exiting...\n");
127                                 gtk_main_quit ();
128                         }
129
130                         break;
131                 }
132         }
133 }
134
135 static void
136 tilda_parse_command_line (gint argc, gchar *argv[])
137 {
138         debug_enter ();
139
140         gboolean version = FALSE;
141
142         /* All of the various command-line options */
143         const GOptionEntry cl_opts[] = {
144                 { "version",                    'V', 0, G_OPTION_ARG_NONE,              &version,                       N_("Show version information"), NULL },
145                 { NULL },
146         };
147
148         /* Set up the command-line parser */
149         GError *error = NULL;
150         GOptionContext *context = g_option_context_new (NULL);
151         g_option_context_add_main_entries (context, cl_opts, NULL);
152         g_option_context_add_group (context, gtk_get_option_group (TRUE));
153         g_option_context_parse (context, &argc, &argv, &error);
154         g_option_context_free (context);
155
156         /* Check for unknown options, and give a nice message if there are some */
157         if (error)
158         {
159                 g_printerr (_("Error parsing command-line options: %s\n"), error->message);
160                 g_printerr (_("The command \"tilda --help\" will show all possible options\n"));
161                 g_error_free (error);
162                 exit (EXIT_FAILURE);
163         }
164
165         /* If we need to show the version, show it then exit normally */
166         if (version)
167         {
168                 g_print ("%s\n\n", TILDA_VERSION);
169
170                 g_print ("Copyright (c) 2005-2008 Tristan Sloughter (sloutri@iit.edu)\n");
171                 g_print ("Copyright (c) 2005-2008 Ira W. Snyder (tilda@irasnyder.com)\n\n");
172
173                 g_print ("This program comes with ABSOLUTELY NO WARRANTY.\n");
174                 g_print ("This is free software, and you are welcome to redistribute it\n");
175                 g_print ("under certain conditions. See the file COPYING for details.\n");
176
177                 exit (EXIT_SUCCESS);
178         }
179 }
180
181 int main (int argc, char *argv[])
182 {
183         debug_enter ();
184
185         TildaWindow *tw;
186
187 #if ENABLE_NLS
188         /* Gettext Initialization */
189         setlocale (LC_ALL, "");
190         bindtextdomain (PACKAGE, LOCALEDIR);
191         textdomain (PACKAGE);
192 #endif
193
194         /* Parse the command-line options */
195         tilda_parse_command_line (argc, argv);
196
197         /* Initialize GTK+ (and the GObject system) */
198         gtk_init (&argc, &argv);
199
200         /* Initialize the keybinder */
201         tomboy_keybinder_init ();
202
203         /* Start our connection to DBus */
204         tilda_initialize_dbus ();
205
206         /* Initialize the array of windows */
207         windows = g_ptr_array_new ();
208
209         /* Create a TildaWindow, run it, and exit when it does, basically.
210          *
211          * This is nothing like what the real main() will be, but it's
212          * a good start for testing and integration of more of TildaWindow
213          * and TildaTerminal. */
214         tw = tilda_add_window ();
215
216         debug_printf ("Starting gtk_main()!\n");
217         gtk_main ();
218         debug_printf ("Out of gtk_main(), going down\n");
219
220         /* Free the pointer array we allocated earlier */
221         g_ptr_array_free (windows, TRUE);
222
223         return 0;
224 }
225
226 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */