1ae08c316afc23fb26202cecb757edf12da1bf69
[melted_gui] / src / instance.c
1 /*
2 * instance.c -- GTK+ 2 melted gui
3 * Copyright (C) 2012 Maksym Veremeyenko <verem@m1stereo.tv>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #ifndef _GNU_SOURCE
21 #define _GNU_SOURCE
22 #endif
23
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <gtk/gtk.h>
32 #include <gdk/gdkkeysyms.h>
33 #include <pthread.h>
34
35 #include "instance.h"
36 #include "ui.h"
37 #include "opts.h"
38 #include "timecode.h"
39 #include "player.h"
40 #include "library.h"
41
42 gboolean instance_button_click(instance_t* app, control_buttons_t button)
43 {
44 #if 0
45 switch(button)
46 {
47 case BUTTON_PLAYLIST_ITEM_ADD:
48 omnplay_playlist_item_add(app, 0);
49 break;
50 case BUTTON_PLAYLIST_ITEM_DEL:
51 omnplay_playlist_item_del(app);
52 break;
53 case BUTTON_PLAYLIST_ITEM_EDIT:
54 omnplay_playlist_item_edit(app);
55 break;
56 case BUTTON_PLAYLIST_LOAD:
57 omnplay_playlist_load(app);
58 break;
59 case BUTTON_PLAYLIST_SAVE:
60 omnplay_playlist_save(app);
61 break;
62 case BUTTON_PLAYLIST_BLOCK_SINGLE:
63 case BUTTON_PLAYLIST_BLOCK_LOOP:
64 omnplay_playlist_block(app, button);
65 break;
66 case BUTTON_PLAYLIST_ITEM_UP:
67 omnplay_playlist_item_swap(app, -1);
68 break;
69 case BUTTON_PLAYLIST_ITEM_DOWN:
70 omnplay_playlist_item_swap(app, +1);
71 break;
72 case BUTTON_PLAYER_CUE:
73 case BUTTON_PLAYER_PLAY:
74 case BUTTON_PLAYER_PAUSE:
75 case BUTTON_PLAYER_STOP:
76 omnplay_ctl(app, button);
77 break;
78 case BUTTON_LIBRARY_ADD:
79 omnplay_library_add(app, 0);
80 break;
81 case BUTTON_LIBRARY_REFRESH:
82 omnplay_library_refresh(app);
83 break;
84 case BUTTON_LIBRARY_FIND:
85 omnplay_library_search(app, 0);
86 break;
87 case BUTTON_LIBRARY_FIND_NEXT:
88 omnplay_library_search(app, 1);
89 break;
90 case BUTTON_PLAYLIST_RELINK:
91 omnplay_playlist_relink(app);
92 break;
93 };
94 #endif
95 return TRUE;
96 };
97
98 static gboolean on_button_click(GtkWidget *button, gpointer user_data)
99 {
100 int i;
101 instance_t* app = (instance_t*)user_data;
102
103 for(i = 1; i < BUTTON_LAST; i++)
104 if(app->buttons[i] == button)
105 return instance_button_click(app, (control_buttons_t)i);
106
107 return FALSE;
108 };
109
110 static gboolean on_main_window_delete_event( GtkWidget *widget, GdkEvent *event, gpointer user_data )
111 {
112 g_print ("delete event occurred [start]\n");
113 gdk_threads_leave();
114 instance_release((instance_t*)user_data);
115 gdk_threads_enter();
116 g_print ("delete event occurred [finish]\n");
117
118 return FALSE;
119 }
120
121 static void on_main_window_destroy( GtkWidget *widget, gpointer user_data )
122 {
123 g_print ("destroy occurred\n");
124 gtk_main_quit();
125 }
126
127 instance_t* instance_create(int argc, char** argv)
128 {
129 int i, c;
130 instance_t* app;
131
132 /* prepare application instance */
133 app = (instance_t*)malloc(sizeof(instance_t));
134 memset(app, 0, sizeof(instance_t));
135
136 /* load parameters from command line */
137 if(!instance_opt(argc, argv, app) && app->players.count)
138 app->window = ui_create(app);
139 else
140 instance_usage();
141
142 return app;
143 };
144
145 void instance_destroy(instance_t* app)
146 {
147 free(app);
148 };
149
150 void instance_init(instance_t* app)
151 {
152 int i;
153 pthread_mutexattr_t attr;
154
155 pthread_mutexattr_init(&attr);
156 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
157
158 gtk_signal_connect( GTK_OBJECT( app->window ), "delete-event",
159 GTK_SIGNAL_FUNC(on_main_window_delete_event), app);
160
161 gtk_signal_connect( GTK_OBJECT( app->window ), "destroy",
162 GTK_SIGNAL_FUNC(on_main_window_destroy), app);
163
164 #if 0
165 gtk_widget_add_events(app->playlist_grid, GDK_BUTTON_PRESS_MASK);
166 gtk_widget_add_events(app->playlist_grid, GDK_KEY_PRESS_MASK);
167 gtk_signal_connect(GTK_OBJECT(app->playlist_grid), "key-press-event",
168 GTK_SIGNAL_FUNC(on_playlist_grid_key), app);
169
170 gtk_widget_add_events(app->library_grid, GDK_BUTTON_PRESS_MASK);
171 gtk_widget_add_events(app->library_grid, GDK_KEY_PRESS_MASK);
172 gtk_signal_connect(GTK_OBJECT(app->library_grid), "key-press-event",
173 GTK_SIGNAL_FUNC(on_library_grid_key), app);
174
175 gtk_signal_connect(GTK_OBJECT(app->playlist_grid), "button-press-event",
176 GTK_SIGNAL_FUNC(on_playlist_grid_button), app);
177
178 gtk_signal_connect(GTK_OBJECT(app->library_grid), "button-press-event",
179 GTK_SIGNAL_FUNC(on_library_grid_button), app);
180 #endif
181
182 /* create lock */
183 pthread_mutex_init(&app->players.lock, &attr);
184 pthread_mutex_init(&app->playlist.lock, &attr);
185 pthread_mutex_init(&app->library.lock, &attr);
186 pthread_mutexattr_destroy(&attr);
187
188 /* run unit monitoring threads */
189 for(i = 0; i < app->players.count; i++)
190 player_run(app, i);
191
192 /* attach buttons click */
193 for(i = 1; i < BUTTON_LAST; i++)
194 gtk_signal_connect(GTK_OBJECT(app->buttons[i]), "clicked",
195 GTK_SIGNAL_FUNC( on_button_click), app );
196
197 /* load library */
198 library_init(app);
199
200 #if 0
201 /* setup drag n drop source/target */
202 static GtkTargetEntry drag_targets[] = { { (char*) "application/playlist_item_t", 0, 0 } };
203
204 gtk_drag_source_set(app->library_grid, GDK_BUTTON1_MASK,
205 drag_targets, 1, (GdkDragAction)(GDK_ACTION_COPY));
206
207 gtk_drag_source_set(app->playlist_grid, GDK_BUTTON1_MASK,
208 drag_targets, 1, (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE));
209
210 gtk_drag_dest_set(app->playlist_grid, (GtkDestDefaults)(GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP),
211 drag_targets, 1, (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE));
212
213 g_signal_connect (app->library_grid, "drag_data_get", G_CALLBACK(library_grid_drag_data_get_cb), app);
214 g_signal_connect (app->playlist_grid, "drag_data_get", G_CALLBACK(playlist_grid_drag_data_get_cb), app);
215 g_signal_connect (app->library_grid, "drag_begin", G_CALLBACK(library_grid_drag_begin_cb), app);
216 g_signal_connect (app->playlist_grid, "drag_begin", G_CALLBACK(playlist_grid_drag_begin_cb), app);
217 g_signal_connect (app->playlist_grid, "drag_data_received", G_CALLBACK (playlist_grid_drag_data_received), app);
218 g_signal_connect (app->playlist_grid, "drag_data_delete", G_CALLBACK (playlist_grid_drag_data_delete), app);
219 g_signal_connect (app->playlist_grid, "drag_motion", G_CALLBACK (playlist_grid_drag_motion), app);
220 #endif
221 };
222
223 void instance_release(instance_t* app)
224 {
225 int i;
226
227 app->f_exit = 1;
228
229 library_release(app);
230
231 /* stop unit monitoring threads */
232 for(i = 0; i < app->players.count; i++)
233 player_stop(app, i);
234
235 /* destroy lock */
236 pthread_mutex_destroy(&app->players.lock);
237
238 /* destroy lock */
239 pthread_mutex_destroy(&app->playlist.lock);
240
241 #if 0
242 /* load library */
243 omnplay_library_save(app);
244 #endif
245
246 /* destroy library lock */
247 pthread_mutex_destroy(&app->library.lock);
248 };