Release 3.6
[gmidimonitor.git] / main.c
bloba76c74eec2fb70cb3bf3526d493cf1ee77b0f2e0
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * gmidimonitor main code.
6 * This file is part of gmidimonitor
8 * Copyright (C) 2005,2006,2007,2008,2011 Nedko Arnaudov <nedko@arnaudov.name>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23 *****************************************************************************/
25 #include "config.h"
27 #include <stdlib.h>
28 #include <string.h>
29 #include <glib.h>
30 #include <glib/gprintf.h>
31 #include <gtk/gtk.h>
32 #include <signal.h>
33 #include <sys/types.h>
34 #include <unistd.h>
36 #ifdef HAVE_LASH_1_0
37 #include <lash/lash.h>
38 #endif
40 #include "common.h"
41 #include "path.h"
42 #include "gm.h"
43 #include "jack.h"
44 #include "alsa.h"
46 GtkBuilder * g_builder = NULL;
47 GtkWidget * g_main_window_ptr;
49 gboolean g_midi_ignore = FALSE;
51 int g_row_count;
53 #ifdef HAVE_LASH_1_0
54 lash_client_t * g_lashc;
55 #endif
57 const char * g_note_names[12] =
59 "C",
60 "C#",
61 "D",
62 "D#",
63 "E",
64 "F",
65 "F#",
66 "G",
67 "G#",
68 "A",
69 "A#",
70 "B",
73 void
74 create_mainwindow()
76 GtkWidget * child_ptr;
77 GtkListStore * list_store_ptr;
78 GtkTreeViewColumn * column_ptr;
79 GtkCellRenderer * text_renderer_ptr;
80 GError * error;
81 gchar * ui_filename;
83 ui_filename = path_get_data_filename("gmidimonitor.ui");
84 if (ui_filename == NULL)
86 g_warning("Cannot find UI description file.");
87 exit(1);
90 /* load the interface builder */
91 error = NULL;
92 g_builder = gtk_builder_new();
93 if (!gtk_builder_add_from_file (g_builder, ui_filename, &error))
95 g_warning ("Couldn't load builder file: %s", error->message);
96 g_error_free (error);
98 g_free(ui_filename);
100 /* Retrieve the main window and connect the signals in the interface */
101 g_main_window_ptr = GTK_WIDGET (gtk_builder_get_object (g_builder, "main_window"));
102 gtk_builder_connect_signals(g_builder, NULL);
104 child_ptr = GTK_WIDGET (gtk_builder_get_object (g_builder, "list"));
106 text_renderer_ptr = gtk_cell_renderer_text_new();
108 g_object_set(
109 G_OBJECT(text_renderer_ptr),
110 "family",
111 "Monospace",
112 NULL);
114 /* column_ptr = gtk_tree_view_column_new_with_attributes( */
115 /* "Time", */
116 /* text_renderer_ptr, */
117 /* "text", COL_TIME, */
118 /* NULL); */
120 /* gtk_tree_view_append_column( */
121 /* GTK_TREE_VIEW(child_ptr), */
122 /* column_ptr); */
124 column_ptr = gtk_tree_view_column_new_with_attributes(
125 "Channel",
126 text_renderer_ptr,
127 "text", COL_CHANNEL,
128 NULL);
130 gtk_tree_view_append_column(
131 GTK_TREE_VIEW(child_ptr),
132 column_ptr);
134 column_ptr = gtk_tree_view_column_new_with_attributes(
135 "Message",
136 text_renderer_ptr,
137 "text", COL_MESSAGE,
138 NULL);
140 gtk_tree_view_append_column(
141 GTK_TREE_VIEW(child_ptr),
142 column_ptr);
144 gtk_widget_show_all(g_main_window_ptr);
146 list_store_ptr = gtk_list_store_new(
147 NUM_COLS,
148 G_TYPE_STRING,
149 G_TYPE_STRING,
150 G_TYPE_STRING);
152 gtk_tree_view_set_model(GTK_TREE_VIEW(child_ptr), GTK_TREE_MODEL(list_store_ptr));
155 /* stop button toggle */
156 void on_button_stop_toggled(
157 GtkAction * action_ptr,
158 GtkWidget * widget_ptr)
160 GtkWidget * child_ptr;
162 child_ptr = GTK_WIDGET (gtk_builder_get_object (g_builder, "button_stop"));
164 if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(child_ptr)))
166 g_midi_ignore = TRUE;
168 else
170 g_midi_ignore = FALSE;
174 void on_clear_clicked
175 (GtkButton *button, gpointer user_data)
177 gtk_list_store_clear(
178 GTK_LIST_STORE(
179 gtk_tree_view_get_model(
180 GTK_TREE_VIEW(
181 gtk_builder_get_object(
182 g_builder,
183 "list")))));
184 g_row_count = 0;
187 #ifdef HAVE_LASH_1_0
189 void
190 process_lash_event(lash_event_t * event_ptr)
192 enum LASH_Event_Type type;
193 const char * str;
195 type = lash_event_get_type(event_ptr);
196 str = lash_event_get_string(event_ptr);
198 switch (type)
200 case LASH_Quit:
201 g_warning("LASH_Quit received.\n");
202 g_lashc = NULL;
203 gtk_main_quit();
204 break;
205 case LASH_Save_File:
206 case LASH_Restore_File:
207 case LASH_Save_Data_Set:
208 default:
209 g_warning("LASH Event. Type = %u, string = \"%s\"\n",
210 (unsigned int)type,
211 (str == NULL)?"":str);
215 void
216 process_lash_config(lash_config_t * config_ptr)
218 const char * key;
219 const void * data;
220 size_t data_size;
222 key = lash_config_get_key(config_ptr);
223 data = lash_config_get_value(config_ptr);
224 data_size = lash_config_get_value_size(config_ptr);
226 g_warning("LASH Config. Key = \"%s\"\n", key);
229 /* process lash events callback */
230 gboolean
231 process_lash_events(gpointer data)
233 lash_event_t * event_ptr;
234 lash_config_t * config_ptr;
236 /* Process events */
237 while ((event_ptr = lash_get_event(g_lashc)) != NULL)
239 process_lash_event(event_ptr);
240 lash_event_destroy(event_ptr);
243 /* Process configs */
244 while ((config_ptr = lash_get_config(g_lashc)) != NULL)
246 process_lash_config(config_ptr);
247 lash_config_destroy(config_ptr);
250 return TRUE;
253 #endif /* #ifdef HAVE_LASH_1_0 */
255 static
256 void
257 sigint_handler(
258 int i)
260 gtk_main_quit();
264 main(int argc, char *argv[])
266 #ifdef HAVE_LASH_1_0
267 lash_event_t * lash_event_ptr;
268 #endif
269 GString * client_name_str_ptr;
271 int i;
272 gboolean want_any = TRUE;
273 #ifdef HAVE_JACK
274 gboolean want_jack = FALSE;
275 gboolean jack_enabled = FALSE;
276 #endif
277 #ifdef HAVE_ALSA
278 gboolean want_alsa = FALSE;
279 gboolean alsa_enabled = FALSE;
280 #endif
281 gboolean io_enabled = FALSE;
282 int ret = 0;
284 for (i = 1; i < argc; i++)
286 #ifdef HAVE_JACK
287 if (strcmp(argv[i], "--jack") == 0)
289 want_jack = TRUE;
290 want_any = FALSE;
291 continue;
293 #endif
294 #ifdef HAVE_ALSA
295 if (strcmp(argv[i], "--alsa") == 0)
297 want_alsa = TRUE;
298 want_any = FALSE;
299 continue;
301 #endif
302 if (strcmp(argv[i], "--help") != 0)
304 fprintf(stderr, "Unrecognized parameter \"%s\"\n", argv[i]);
305 ret = 1;
308 fprintf(
309 ret == 0 ? stdout : stderr,
310 "Usage: %s"
311 #ifdef HAVE_JACK
312 " [--jack]"
313 #endif
314 #ifdef HAVE_ALSA
315 " [--alsa]"
316 #endif
317 "\n",
318 argv[0]);
320 exit(ret);
323 /* init threads */
324 g_thread_init(NULL);
325 gdk_threads_init();
326 gdk_threads_enter();
328 gtk_init(&argc, &argv);
330 path_init(argv[0]);
332 #ifdef HAVE_LASH_1_0
333 if (getenv("LADISH_APPNAME") != NULL)
335 g_lashc = lash_init(
336 lash_extract_args(&argc, &argv),
337 "gmidimonitor",
339 LASH_PROTOCOL_VERSION);
340 if (g_lashc == NULL)
342 g_warning("Failed to connect to LASH. Session management will not occur.\n");
344 else
346 lash_event_ptr = lash_event_new_with_type(LASH_Client_Name);
347 lash_event_set_string(lash_event_ptr, "GMIDImonitor");
348 lash_send_event(g_lashc, lash_event_ptr);
349 g_timeout_add(250, process_lash_events, NULL);
352 #endif
354 /* interface creation */
355 create_mainwindow();
357 client_name_str_ptr = g_string_new("");
358 g_string_sprintf(client_name_str_ptr, "MIDI monitor");
360 g_row_count = 0;
362 #ifdef HAVE_JACK
363 if (want_jack || want_any)
365 jack_enabled = jack_init(client_name_str_ptr->str);
366 if (jack_enabled)
368 g_printf("JACK MIDI enabled\n");
369 io_enabled = TRUE;
371 else if (want_jack)
373 goto failed_jack;
376 #endif
378 #ifdef HAVE_ALSA
379 if (want_alsa || (want_any && !io_enabled))
381 alsa_enabled = alsa_init(client_name_str_ptr->str);
382 if (alsa_enabled)
384 g_printf("ALSA MIDI enabled\n");
385 io_enabled = TRUE;
387 else if (want_alsa)
389 goto failed_alsa;
392 #endif
394 if (io_enabled)
396 signal(SIGINT, &sigint_handler);
397 signal(SIGTERM, &sigint_handler);
399 /* main loop */
400 gtk_main();
403 #ifdef HAVE_ALSA
404 if (alsa_enabled)
406 alsa_uninit();
408 failed_alsa:
409 #endif
411 #ifdef HAVE_JACK
412 if (jack_enabled)
414 jack_uninit();
416 failed_jack:
417 #endif
419 gdk_threads_leave();
421 path_init(argv[0]);
423 return ret;