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