05400b3574e2def9c5ae9a06fc98cf94502bef05
[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 GtkTargetEntry drag_targets[] = { { (char*) "application/playlist_item_t", 0, 0 } };
43
44 gboolean instance_button_click(instance_t* app, control_buttons_t button)
45 {
46 #if 0
47 switch(button)
48 {
49 case BUTTON_PLAYLIST_ITEM_ADD:
50 omnplay_playlist_item_add(app, 0);
51 break;
52 case BUTTON_PLAYLIST_ITEM_DEL:
53 omnplay_playlist_item_del(app);
54 break;
55 case BUTTON_PLAYLIST_ITEM_EDIT:
56 omnplay_playlist_item_edit(app);
57 break;
58 case BUTTON_PLAYLIST_LOAD:
59 omnplay_playlist_load(app);
60 break;
61 case BUTTON_PLAYLIST_SAVE:
62 omnplay_playlist_save(app);
63 break;
64 case BUTTON_PLAYLIST_BLOCK_SINGLE:
65 case BUTTON_PLAYLIST_BLOCK_LOOP:
66 omnplay_playlist_block(app, button);
67 break;
68 case BUTTON_PLAYLIST_ITEM_UP:
69 omnplay_playlist_item_swap(app, -1);
70 break;
71 case BUTTON_PLAYLIST_ITEM_DOWN:
72 omnplay_playlist_item_swap(app, +1);
73 break;
74 case BUTTON_PLAYER_CUE:
75 case BUTTON_PLAYER_PLAY:
76 case BUTTON_PLAYER_PAUSE:
77 case BUTTON_PLAYER_STOP:
78 omnplay_ctl(app, button);
79 break;
80 case BUTTON_LIBRARY_ADD:
81 omnplay_library_add(app, 0);
82 break;
83 case BUTTON_LIBRARY_REFRESH:
84 omnplay_library_refresh(app);
85 break;
86 case BUTTON_LIBRARY_FIND:
87 omnplay_library_search(app, 0);
88 break;
89 case BUTTON_LIBRARY_FIND_NEXT:
90 omnplay_library_search(app, 1);
91 break;
92 case BUTTON_PLAYLIST_RELINK:
93 omnplay_playlist_relink(app);
94 break;
95 };
96 #endif
97 return TRUE;
98 };
99
100 static gboolean on_button_click(GtkWidget *button, gpointer user_data)
101 {
102 int i;
103 instance_t* app = (instance_t*)user_data;
104
105 for(i = 1; i < BUTTON_LAST; i++)
106 if(app->buttons[i] == button)
107 return instance_button_click(app, (control_buttons_t)i);
108
109 return FALSE;
110 };
111
112 static gboolean on_main_window_delete_event( GtkWidget *widget, GdkEvent *event, gpointer user_data )
113 {
114 g_print ("delete event occurred [start]\n");
115 gdk_threads_leave();
116 instance_release((instance_t*)user_data);
117 gdk_threads_enter();
118 g_print ("delete event occurred [finish]\n");
119
120 return FALSE;
121 }
122
123 static void on_main_window_destroy( GtkWidget *widget, gpointer user_data )
124 {
125 g_print ("destroy occurred\n");
126 gtk_main_quit();
127 }
128
129 instance_t* instance_create(int argc, char** argv)
130 {
131 int i, c;
132 instance_t* app;
133
134 /* prepare application instance */
135 app = (instance_t*)malloc(sizeof(instance_t));
136 memset(app, 0, sizeof(instance_t));
137
138 /* load parameters from command line */
139 if(!instance_opt(argc, argv, app) && app->players.count)
140 app->window = ui_create(app);
141 else
142 instance_usage();
143
144 return app;
145 };
146
147 void instance_destroy(instance_t* app)
148 {
149 free(app);
150 };
151
152 void instance_init(instance_t* app)
153 {
154 int i;
155 pthread_mutexattr_t attr;
156
157 pthread_mutexattr_init(&attr);
158 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
159
160 gtk_signal_connect( GTK_OBJECT( app->window ), "delete-event",
161 GTK_SIGNAL_FUNC(on_main_window_delete_event), app);
162
163 gtk_signal_connect( GTK_OBJECT( app->window ), "destroy",
164 GTK_SIGNAL_FUNC(on_main_window_destroy), app);
165
166 #if 0
167 gtk_widget_add_events(app->playlist_grid, GDK_BUTTON_PRESS_MASK);
168 gtk_widget_add_events(app->playlist_grid, GDK_KEY_PRESS_MASK);
169 gtk_signal_connect(GTK_OBJECT(app->playlist_grid), "key-press-event",
170 GTK_SIGNAL_FUNC(on_playlist_grid_key), app);
171
172 gtk_widget_add_events(app->library_grid, GDK_BUTTON_PRESS_MASK);
173 gtk_widget_add_events(app->library_grid, GDK_KEY_PRESS_MASK);
174 gtk_signal_connect(GTK_OBJECT(app->library_grid), "key-press-event",
175 GTK_SIGNAL_FUNC(on_library_grid_key), app);
176
177 gtk_signal_connect(GTK_OBJECT(app->playlist_grid), "button-press-event",
178 GTK_SIGNAL_FUNC(on_playlist_grid_button), app);
179
180 gtk_signal_connect(GTK_OBJECT(app->library_grid), "button-press-event",
181 GTK_SIGNAL_FUNC(on_library_grid_button), app);
182 #endif
183
184 /* create lock */
185 pthread_mutex_init(&app->players.lock, &attr);
186 pthread_mutex_init(&app->playlist.lock, &attr);
187 pthread_mutex_init(&app->library.lock, &attr);
188 pthread_mutexattr_destroy(&attr);
189
190 /* run unit monitoring threads */
191 for(i = 0; i < app->players.count; i++)
192 player_run(app, i);
193
194 /* attach buttons click */
195 for(i = 1; i < BUTTON_LAST; i++)
196 gtk_signal_connect(GTK_OBJECT(app->buttons[i]), "clicked",
197 GTK_SIGNAL_FUNC( on_button_click), app );
198
199 /* load library */
200 library_init(app);
201
202 #if 0
203 /* setup drag n drop source/target */
204 static GtkTargetEntry drag_targets[] = { { (char*) "application/playlist_item_t", 0, 0 } };
205
206 gtk_drag_source_set(app->library_grid, GDK_BUTTON1_MASK,
207 drag_targets, 1, (GdkDragAction)(GDK_ACTION_COPY));
208
209 gtk_drag_source_set(app->playlist_grid, GDK_BUTTON1_MASK,
210 drag_targets, 1, (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE));
211
212 gtk_drag_dest_set(app->playlist_grid, (GtkDestDefaults)(GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP),
213 drag_targets, 1, (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE));
214
215 g_signal_connect (app->library_grid, "drag_data_get", G_CALLBACK(library_grid_drag_data_get_cb), app);
216 g_signal_connect (app->playlist_grid, "drag_data_get", G_CALLBACK(playlist_grid_drag_data_get_cb), app);
217 g_signal_connect (app->library_grid, "drag_begin", G_CALLBACK(library_grid_drag_begin_cb), app);
218 g_signal_connect (app->playlist_grid, "drag_begin", G_CALLBACK(playlist_grid_drag_begin_cb), app);
219 g_signal_connect (app->playlist_grid, "drag_data_received", G_CALLBACK (playlist_grid_drag_data_received), app);
220 g_signal_connect (app->playlist_grid, "drag_data_delete", G_CALLBACK (playlist_grid_drag_data_delete), app);
221 g_signal_connect (app->playlist_grid, "drag_motion", G_CALLBACK (playlist_grid_drag_motion), app);
222 #endif
223 };
224
225 void instance_release(instance_t* app)
226 {
227 int i;
228
229 app->f_exit = 1;
230
231 library_release(app);
232
233 /* stop unit monitoring threads */
234 for(i = 0; i < app->players.count; i++)
235 player_stop(app, i);
236
237 /* destroy lock */
238 pthread_mutex_destroy(&app->players.lock);
239
240 /* destroy lock */
241 pthread_mutex_destroy(&app->playlist.lock);
242
243 #if 0
244 /* load library */
245 omnplay_library_save(app);
246 #endif
247
248 /* destroy library lock */
249 pthread_mutex_destroy(&app->library.lock);
250 };