1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * main.c
4 * Copyright (C) Kevin DeKorte 2006 <kdekorte@gmail.com>
5 *
6 * main.c is free software.
7 *
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * main.c is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with main.c. If not, write to:
20 * The Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA.
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <mntent_compat.h>
32 #include <unistd.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <libintl.h>
36 #include <signal.h>
37
38 //#include <bonobo.h>
39 // #include <gnome.h>
40 #include <glib/gstdio.h>
41 #include <glib/gi18n.h>
42
43 #include "common.h"
44 #include "support.h"
45 #include "dbus-interface.h"
46 #include "mpris-interface.h"
47 #include "gmtk.h"
48 #include "database.h"
49
50 static gint reallyverbose;
51 static gint last_x, last_y;
52 static gint stored_window_width, stored_window_height;
53 static gchar *rpname;
54 static gboolean use_volume_option;
55 //static gboolean restore_playlist;
56 //static gboolean restore_details;
57 //static gboolean restore_info;
58 static gboolean new_instance;
59 static gboolean use_pausing_keep_force;
60 static gboolean load_tracks_from_gpod;
61 // tv stuff
62 static gchar *tv_device;
63 static gchar *tv_driver;
64 static gchar *tv_input;
65 static gint tv_width;
66 static gint tv_height;
67 static gint tv_fps;
68
69 typedef struct _PlayData {
70 gchar uri[4096];
71 gboolean playlist;
72 } PlayData;
73
74 static GOptionEntry entries[] = {
75 {"window", 0, 0, G_OPTION_ARG_INT, &embed_window, N_("Window to embed in"), "WID"},
76 {"width", 'w', 0, G_OPTION_ARG_INT, &window_x, N_("Width of window to embed in"), "X"},
77 {"height", 'h', 0, G_OPTION_ARG_INT, &window_y, N_("Height of window to embed in"), "Y"},
78 {"controlid", 0, 0, G_OPTION_ARG_INT, &control_id, N_("Unique DBUS controller id"), "CID"},
79 {"playlist", 0, 0, G_OPTION_ARG_NONE, &playlist, N_("File Argument is a playlist"), NULL},
80 {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, N_("Show more output on the console"), NULL},
81 {"reallyverbose", '\0', 0, G_OPTION_ARG_NONE, &reallyverbose,
82 N_("Show even more output on the console"), NULL},
83 {"fullscreen", 0, 0, G_OPTION_ARG_NONE, &init_fullscreen, N_("Start in fullscreen mode"), NULL},
84 {"softvol", 0, 0, G_OPTION_ARG_NONE, &softvol, N_("Use mplayer software volume control"), NULL},
85 {"remember_softvol", 0, 0, G_OPTION_ARG_NONE, &remember_softvol,
86 N_("When set to TRUE the last volume level is set as the default"), NULL},
87 {"volume_softvol", 0, 0, G_OPTION_ARG_INT, &volume_softvol,
88 N_("Last software volume percentage- only applied when remember_softvol is set to TRUE"),
89 NULL},
90 {"mixer", 0, 0, G_OPTION_ARG_STRING, &(audio_device.alsa_mixer), N_("Mixer to use"), NULL},
91 {"volume", 0, 0, G_OPTION_ARG_INT, &(pref_volume), N_("Set initial volume percentage"), NULL},
92 // note that sizeof(gint)==sizeof(gboolean), so we can give &showcontrols here
93 {"showcontrols", 0, 0, G_OPTION_ARG_INT, &showcontrols, N_("Show the controls in window"),
94 "[0|1]"},
95 {"showsubtitles", 0, 0, G_OPTION_ARG_INT, &showsubtitles, N_("Show the subtitles if available"),
96 "[0|1]"},
97 {"autostart", 0, 0, G_OPTION_ARG_INT, &autostart,
98 N_("Autostart the media default to 1, set to 0 to load but don't play"), "[0|1]"},
99 {"disablecontextmenu", 0, 0, G_OPTION_ARG_NONE, &disable_context_menu,
100 N_("Disable popup menu on right click"), NULL},
101 {"disablefullscreen", 0, 0, G_OPTION_ARG_NONE, &disable_fullscreen,
102 N_("Disable fullscreen options in browser mode"), NULL},
103 {"loop", 0, 0, G_OPTION_ARG_NONE, &loop, N_("Play all files on the playlist forever"), NULL},
104 {"quit_on_complete", 'q', 0, G_OPTION_ARG_NONE, &quit_on_complete,
105 N_("Quit application when last file on playlist is played"), NULL},
106 {"random", 0, 0, G_OPTION_ARG_NONE, &random_order, N_("Play items on playlist in random order"),
107 NULL},
108 {"cache", 0, 0, G_OPTION_ARG_INT, &cache_size, N_("Set cache size"),
109 NULL},
110 {"ss", 0, 0, G_OPTION_ARG_INT, &start_second, N_("Start Second (default to 0)"),
111 NULL},
112 {"endpos", 0, 0, G_OPTION_ARG_INT, &play_length,
113 N_("Length of media to play from start second"),
114 NULL},
115 {"forcecache", 0, 0, G_OPTION_ARG_NONE, &forcecache, N_("Force cache usage on streaming sites"),
116 NULL},
117 {"disabledeinterlace", 0, 0, G_OPTION_ARG_NONE, &disable_deinterlace,
118 N_("Disable the deinterlace filter"),
119 NULL},
120 {"disableframedrop", 0, 0, G_OPTION_ARG_NONE, &disable_framedrop,
121 N_("Don't skip drawing frames to better keep sync"),
122 NULL},
123 {"disableass", 0, 0, G_OPTION_ARG_NONE, &disable_ass,
124 N_("Use the old subtitle rendering system"),
125 NULL},
126 {"disableembeddedfonts", 0, 0, G_OPTION_ARG_NONE, &disable_embeddedfonts,
127 N_("Don't use fonts embedded on matroska files"),
128 NULL},
129 {"vertical", 0, 0, G_OPTION_ARG_NONE, &vertical_layout, N_("Use Vertical Layout"),
130 NULL},
131 {"showplaylist", 0, 0, G_OPTION_ARG_NONE, &playlist_visible, N_("Start with playlist open"),
132 NULL},
133 {"showdetails", 0, 0, G_OPTION_ARG_NONE, &details_visible, N_("Start with details visible"),
134 NULL},
135 {"rpname", 0, 0, G_OPTION_ARG_STRING, &rpname, N_("Real Player Name"), "NAME"},
136 {"rpconsole", 0, 0, G_OPTION_ARG_STRING, &rpconsole, N_("Real Player Console ID"), "CONSOLE"},
137 {"rpcontrols", 0, 0, G_OPTION_ARG_STRING, &rpcontrols, N_("Real Player Console Controls"),
138 "Control Name,..."},
139 {"subtitle", 0, 0, G_OPTION_ARG_STRING, &subtitle, N_("Subtitle file for first media file"),
140 "FILENAME"},
141 {"tvdevice", 0, 0, G_OPTION_ARG_STRING, &tv_device, N_("TV device name"), "DEVICE"},
142 {"tvdriver", 0, 0, G_OPTION_ARG_STRING, &tv_driver, N_("TV driver name (v4l|v4l2)"), "DRIVER"},
143 {"tvinput", 0, 0, G_OPTION_ARG_STRING, &tv_input, N_("TV input name"), "INPUT"},
144 {"tvwidth", 0, 0, G_OPTION_ARG_INT, &tv_width, N_("Width of TV input"), "WIDTH"},
145 {"tvheight", 0, 0, G_OPTION_ARG_INT, &tv_height, N_("Height of TV input"), "HEIGHT"},
146 {"tvfps", 0, 0, G_OPTION_ARG_INT, &tv_fps, N_("Frames per second from TV input"), "FPS"},
147 {"single_instance", 0, 0, G_OPTION_ARG_NONE, &single_instance, N_("Only allow one instance"),
148 NULL},
149 {"replace_and_play", 0, 0, G_OPTION_ARG_NONE, &replace_and_play,
150 N_("Put single instance mode into replace and play mode"),
151 NULL},
152 {"large_buttons", 0, 0, G_OPTION_ARG_NONE, &large_buttons,
153 N_("Use large control buttons"),
154 NULL},
155 {"always_hide_after_timeout", 0, 0, G_OPTION_ARG_NONE, &always_hide_after_timeout,
156 N_("Hide control panel when mouse is not moving"),
157 NULL},
158 {"new_instance", 0, 0, G_OPTION_ARG_NONE, &new_instance,
159 N_("Ignore single instance preference for this instance"),
160 NULL},
161 {"keep_on_top", 0, 0, G_OPTION_ARG_NONE, &keep_on_top,
162 N_("Keep window on top"),
163 NULL},
164 #ifdef HAVE_GPOD
165 {"load_tracks_from_gpod", 0, 0, G_OPTION_ARG_NONE, &load_tracks_from_gpod,
166 N_("Load all tracks from media player using gpod"),
167 NULL},
168 #endif
169 {"disable_cover_art_fetch", 0, 0, G_OPTION_ARG_NONE, &disable_cover_art_fetch,
170 N_("Don't fetch new cover art images"),
171 NULL},
172 {"dvd_device", 0, 0, G_OPTION_ARG_STRING, &option_dvd_device, N_("DVD Device Name"), "Path to device or folder"},
173 {"vo", 0, 0, G_OPTION_ARG_STRING, &option_vo, N_("Video Output Device Name"), "mplayer vo name"},
174 {"mplayer", 0, 0, G_OPTION_ARG_STRING, &mplayer_bin, N_("Use specified mplayer"), "Path to mplayer binary"},
175 {NULL}
176 };
177
async_play_iter(void * data)178 gboolean async_play_iter(void *data)
179 {
180 next_iter = (GtkTreeIter *) (data);
181 gm_log(verbose, G_LOG_LEVEL_DEBUG, "media state = %s",
182 gmtk_media_state_to_string(gmtk_media_player_get_media_state(GMTK_MEDIA_PLAYER(media))));
183 if (gmtk_media_player_get_media_state(GMTK_MEDIA_PLAYER(media)) == MEDIA_STATE_UNKNOWN) {
184 play_iter(next_iter, 0);
185 next_iter = NULL;
186 }
187
188 return FALSE;
189 }
190
play(void * data)191 gboolean play(void *data)
192 {
193 PlayData *p = (PlayData *) data;
194
195 if (ok_to_play && p != NULL) {
196 if (!gtk_list_store_iter_is_valid(playliststore, &iter)) {
197 gm_log(verbose, G_LOG_LEVEL_DEBUG, "iter is not valid, getting first one");
198 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
199 }
200 gtk_list_store_set(playliststore, &iter, PLAYLIST_COLUMN, p->playlist, ITEM_COLUMN, p->uri, -1);
201 play_iter(&iter, 0);
202 }
203 g_free(p);
204
205 return FALSE;
206 }
207
208
play_next()209 void play_next()
210 {
211 gchar *filename;
212 gint count;
213 PlayData *p = NULL;
214
215 if (next_item_in_playlist(&iter)) {
216 if (gtk_list_store_iter_is_valid(playliststore, &iter)) {
217 gtk_tree_model_get(GTK_TREE_MODEL(playliststore), &iter, ITEM_COLUMN, &filename,
218 COUNT_COLUMN, &count, PLAYLIST_COLUMN, &playlist, -1);
219 g_strlcpy(idledata->info, filename, sizeof(idledata->info));
220 g_idle_add(set_title_bar, idledata);
221 p = (PlayData *) g_malloc(sizeof(PlayData));
222 g_strlcpy(p->uri, filename, sizeof(p->uri));
223 p->playlist = playlist;
224 g_idle_add(play, p);
225 g_free(filename);
226 }
227 } else {
228 gm_log(verbose, G_LOG_LEVEL_DEBUG, "end of thread playlist is empty");
229 if (loop) {
230 if (is_first_item_in_playlist(&iter)) {
231 gtk_tree_model_get(GTK_TREE_MODEL(playliststore), &iter, ITEM_COLUMN,
232 &filename, COUNT_COLUMN, &count, PLAYLIST_COLUMN, &playlist, -1);
233 g_strlcpy(idledata->info, filename, sizeof(idledata->info));
234 g_idle_add(set_title_bar, idledata);
235 p = (PlayData *) g_malloc(sizeof(PlayData));
236 g_strlcpy(p->uri, filename, sizeof(p->uri));
237 p->playlist = playlist;
238 g_idle_add(play, p);
239 g_free(filename);
240 }
241 } else {
242 idledata->fullscreen = 0;
243 g_idle_add(set_fullscreen, idledata);
244 g_idle_add(set_stop, idledata);
245 }
246
247 if (quit_on_complete) {
248 g_idle_add(set_quit, idledata);
249 }
250 }
251 }
252
253
play_iter(GtkTreeIter * playiter,gint restart_second)254 gint play_iter(GtkTreeIter * playiter, gint restart_second)
255 {
256
257 gchar *subtitle = NULL;
258 gchar *audiofile = NULL;
259 GtkTreePath *path;
260 gchar *uri = NULL;
261 gint count;
262 gboolean playlist;
263 gchar *title = NULL;
264 gchar *artist = NULL;
265 gchar *album = NULL;
266 gchar *audio_codec;
267 gchar *video_codec = NULL;
268 GtkAllocation alloc;
269 gchar *demuxer = NULL;
270 gboolean playable = TRUE;
271 gint width;
272 gint height;
273 gfloat length_value;
274 gint i;
275 gchar *cover_art_file = NULL;
276 gchar *buffer = NULL;
277 gchar *message = NULL;
278 MetaData *metadata;
279 #ifdef GTK2_12_ENABLED
280 GtkRecentData *recent_data;
281 #ifdef GIO_ENABLED
282 GFile *file;
283 GFileInfo *file_info;
284 #endif
285 #endif
286 #ifdef LIBGDA_ENABLED
287 gchar *position_text;
288 #endif
289
290 /*
291 if (!(gmtk_media_player_get_media_state(GMTK_MEDIA_PLAYER(media)) == MEDIA_STATE_UNKNOWN ||
292 gmtk_media_player_get_media_state(GMTK_MEDIA_PLAYER(media)) == MEDIA_STATE_QUIT)) {
293 while (gmtk_media_player_get_media_state(GMTK_MEDIA_PLAYER(media)) != MEDIA_STATE_UNKNOWN) {
294 gtk_main_iteration();
295 }
296 }
297 */
298
299 if (gtk_list_store_iter_is_valid(playliststore, playiter)) {
300 gtk_tree_model_get(GTK_TREE_MODEL(playliststore), playiter, ITEM_COLUMN, &uri,
301 DESCRIPTION_COLUMN, &title, LENGTH_VALUE_COLUMN, &length_value,
302 ARTIST_COLUMN, &artist,
303 ALBUM_COLUMN, &album,
304 AUDIO_CODEC_COLUMN, &audio_codec,
305 VIDEO_CODEC_COLUMN, &video_codec,
306 VIDEO_WIDTH_COLUMN, &width,
307 VIDEO_HEIGHT_COLUMN, &height,
308 DEMUXER_COLUMN, &demuxer,
309 COVERART_COLUMN, &cover_art_file,
310 SUBTITLE_COLUMN, &subtitle,
311 AUDIOFILE_COLUMN, &audiofile,
312 COUNT_COLUMN, &count, PLAYLIST_COLUMN, &playlist, PLAYABLE_COLUMN, &playable, -1);
313 if (GTK_IS_TREE_SELECTION(selection)) {
314 path = gtk_tree_model_get_path(GTK_TREE_MODEL(playliststore), playiter);
315 if (path) {
316 gtk_tree_selection_select_path(selection, path);
317 if (GTK_IS_WIDGET(list))
318 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(list), path, NULL, FALSE, 0, 0);
319 buffer = gtk_tree_path_to_string(path);
320 g_free(buffer);
321 gtk_tree_path_free(path);
322 }
323 }
324 gtk_list_store_set(playliststore, playiter, COUNT_COLUMN, count + 1, -1);
325 } else {
326 gm_log(verbose, G_LOG_LEVEL_DEBUG, "iter is invalid, nothing to play");
327 return 0;
328 }
329
330 gm_log(verbose, G_LOG_LEVEL_INFO, "playing - %s", uri);
331 gm_log(verbose, G_LOG_LEVEL_INFO, "is playlist %s", gm_bool_to_string(playlist));
332
333 gmtk_get_allocation(GTK_WIDGET(media), &alloc);
334 if (width == 0 || height == 0) {
335 alloc.width = 16;
336 alloc.height = 16;
337 } else {
338 alloc.width = width;
339 alloc.height = height;
340 }
341 gm_log(verbose, G_LOG_LEVEL_DEBUG, "setting window size to %i x %i", alloc.width, alloc.height);
342 gtk_widget_size_allocate(GTK_WIDGET(media), &alloc);
343 gm_log(verbose, G_LOG_LEVEL_DEBUG, "waiting for all events to drain");
344 while (gtk_events_pending())
345 gtk_main_iteration();
346
347 /*
348 // wait for metadata to be available on this item
349 if (!streaming_media(uri) && !device_name(uri)) {
350 i = 0;
351 if (playable) {
352 while (demuxer == NULL && i < 50) {
353 g_free(title);
354 g_free(artist);
355 g_free(album);
356 g_free(audio_codec);
357 g_free(video_codec);
358 g_free(demuxer);
359 g_free(subtitle);
360 g_free(audiofile);
361 if (gtk_list_store_iter_is_valid(playliststore, playiter)) {
362 gtk_tree_model_get(GTK_TREE_MODEL(playliststore), playiter, LENGTH_VALUE_COLUMN,
363 &length_value, DESCRIPTION_COLUMN, &title, ARTIST_COLUMN,
364 &artist, ALBUM_COLUMN, &album, AUDIO_CODEC_COLUMN,
365 &audio_codec, VIDEO_CODEC_COLUMN, &video_codec,
366 VIDEO_WIDTH_COLUMN, &width, VIDEO_HEIGHT_COLUMN, &height,
367 DEMUXER_COLUMN, &demuxer, COVERART_COLUMN, &pixbuf,
368 SUBTITLE_COLUMN, &subtitle, AUDIOFILE_COLUMN, &audiofile,
369 COUNT_COLUMN, &count, PLAYLIST_COLUMN, &playlist,
370 PLAYABLE_COLUMN, &playable, -1);
371 if (!playable) {
372 if (verbose)
373 printf("%s is not marked as playable (%i)\n", uri, i);
374 play_next();
375 return 0;
376 }
377 } else {
378 if (verbose)
379 printf("Current iter is not valid\n");
380 return 1; // error condition
381 }
382 gtk_main_iteration();
383 i++;
384 if (demuxer == NULL)
385 g_usleep(10000);
386 }
387 } else {
388 if (verbose)
389 printf("%s is not marked as playable\n", uri);
390 play_next();
391 return 0;
392 }
393
394 }
395 */
396 // reset audio meter
397 for (i = 0; i < METER_BARS; i++) {
398 buckets[i] = 0;
399 max_buckets[i] = 0;
400 }
401
402 gmtk_media_tracker_set_text(tracker, _("Playing"));
403 gmtk_media_tracker_set_position(tracker, (gfloat) restart_second);
404 gmtk_media_tracker_set_length(tracker, length_value);
405
406 message = g_strdup_printf("<small>\n");
407 if (title == NULL) {
408 title = g_filename_display_basename(uri);
409 }
410 buffer = g_markup_printf_escaped("\t<big><b>%s</b></big>\n", title);
411 message = g_strconcat(message, buffer, NULL);
412 g_free(buffer);
413
414 if (artist != NULL) {
415 buffer = g_markup_printf_escaped("\t<i>%s</i>\n", artist);
416 message = g_strconcat(message, buffer, NULL);
417 g_free(buffer);
418 }
419 if (album != NULL) {
420 buffer = g_markup_printf_escaped("\t%s\n", album);
421 message = g_strconcat(message, buffer, NULL);
422 g_free(buffer);
423 }
424 //buffer = g_markup_printf_escaped("\n\t%s\n", uri);
425 //message = g_strconcat(message, buffer, NULL);
426 //g_free(buffer);
427
428 message = g_strconcat(message, "</small>", NULL);
429
430 // probably not much cover art for random video files
431 if (cover_art_file == NULL && video_codec == NULL && !streaming_media(uri) && control_id == 0 && !playlist) {
432 metadata = (MetaData *) g_new0(MetaData, 1);
433 metadata->uri = g_strdup(uri);
434 if (title != NULL)
435 metadata->title = g_strstrip(g_strdup(title));
436 if (artist != NULL)
437 metadata->artist = g_strstrip(g_strdup(artist));
438 if (album != NULL)
439 metadata->album = g_strstrip(g_strdup(album));
440 gm_log(verbose, G_LOG_LEVEL_DEBUG, "starting get_cover_art(%s) thread", metadata->uri);
441 g_thread_create(get_cover_art, metadata, FALSE, NULL);
442 } else {
443 gtk_image_clear(GTK_IMAGE(cover_art));
444 }
445
446 g_strlcpy(idledata->media_info, message, sizeof(idledata->media_info));
447 g_strlcpy(idledata->display_name, title, sizeof(idledata->display_name));
448 g_free(message);
449
450 message = gm_tempname(NULL, "mplayer-af_exportXXXXXX");
451 g_strlcpy(idledata->af_export, message, sizeof(idledata->af_export));
452 g_free(message);
453
454 message = g_strdup("");
455 if (title == NULL) {
456 title = g_filename_display_basename(uri);
457 }
458 //buffer = g_markup_printf_escaped("\t<b>%s</b>\n", title);
459 //message = g_strconcat(message, buffer, NULL);
460 //g_free(buffer);
461
462 if (artist != NULL) {
463 buffer = g_markup_printf_escaped("\t<i>%s</i>\n", artist);
464 message = g_strconcat(message, buffer, NULL);
465 g_free(buffer);
466 }
467 if (album != NULL) {
468 buffer = g_markup_printf_escaped("\t%s\n", album);
469 message = g_strconcat(message, buffer, NULL);
470 g_free(buffer);
471 }
472 g_strlcpy(idledata->media_notification, message, sizeof(idledata->media_notification));
473 g_free(message);
474
475 if (control_id == 0) {
476 set_media_label(idledata);
477 } else {
478 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_view_info), FALSE);
479 }
480
481 if (subtitles)
482 gtk_container_forall(GTK_CONTAINER(subtitles), remove_langs, NULL);
483 gtk_widget_set_sensitive(GTK_WIDGET(menuitem_edit_select_sub_lang), FALSE);
484 if (tracks)
485 gtk_container_forall(GTK_CONTAINER(tracks), remove_langs, NULL);
486 gtk_widget_set_sensitive(GTK_WIDGET(menuitem_edit_select_audio_lang), FALSE);
487 lang_group = NULL;
488 audio_group = NULL;
489
490
491 if (subtitle != NULL) {
492 gmtk_media_player_set_attribute_string(GMTK_MEDIA_PLAYER(media), ATTRIBUTE_SUBTITLE_FILE, subtitle);
493 g_free(subtitle);
494 subtitle = NULL;
495 }
496 if (audiofile != NULL) {
497 gmtk_media_player_set_attribute_string(GMTK_MEDIA_PLAYER(media), ATTRIBUTE_AUDIO_TRACK_FILE, audiofile);
498 g_free(audiofile);
499 audiofile = NULL;
500 }
501
502 /*
503 if (g_ascii_strcasecmp(thread_data->filename, "") != 0) {
504 if (!device_name(thread_data->filename) && !streaming_media(thread_data->filename)) {
505 if (!g_file_test(thread_data->filename, G_FILE_TEST_EXISTS)) {
506 error_msg = g_strdup_printf("%s not found\n", thread_data->filename);
507 dialog =
508 gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
509 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", error_msg);
510 gtk_window_set_title(GTK_WINDOW(dialog), "GNOME MPlayer Error");
511 gtk_dialog_run(GTK_DIALOG(dialog));
512 gtk_widget_destroy(dialog);
513 return 1;
514 }
515 }
516 }
517 */
518 #ifdef GTK2_12_ENABLED
519 #ifdef GIO_ENABLED
520 // don't put it on the recent list, if it is running in plugin mode
521 if (control_id == 0 && !streaming_media(uri)) {
522 recent_data = (GtkRecentData *) g_new0(GtkRecentData, 1);
523 if (artist != NULL && strlen(artist) > 0) {
524 recent_data->display_name = g_strdup_printf("%s - %s", artist, title);
525 } else {
526 recent_data->display_name = g_strdup(title);
527 }
528 g_strlcpy(idledata->display_name, recent_data->display_name, sizeof(idledata->display_name));
529
530
531 file = g_file_new_for_uri(uri);
532 file_info = g_file_query_info(file,
533 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
534 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, G_FILE_QUERY_INFO_NONE, NULL, NULL);
535
536
537 if (file_info) {
538 recent_data->mime_type = g_strdup(g_file_info_get_content_type(file_info));
539 g_object_unref(file_info);
540 }
541 g_object_unref(file);
542 recent_data->app_name = g_strdup("gnome-mplayer");
543 recent_data->app_exec = g_strdup("gnome-mplayer %u");
544 if (recent_data->mime_type != NULL) {
545 gtk_recent_manager_add_full(recent_manager, uri, recent_data);
546 g_free(recent_data->mime_type);
547 }
548 g_free(recent_data->app_name);
549 g_free(recent_data->app_exec);
550 g_free(recent_data);
551
552 }
553 #endif
554 #endif
555 g_free(title);
556 g_free(artist);
557 g_free(album);
558 if (demuxer != NULL) {
559 g_strlcpy(idledata->demuxer, demuxer, sizeof(idledata->demuxer));
560 g_free(demuxer);
561 } else {
562 g_strlcpy(idledata->demuxer, "", sizeof(idledata->demuxer));
563 }
564
565 last_x = 0;
566 last_y = 0;
567 idledata->width = width;
568 idledata->height = height;
569
570 idledata->retry_on_full_cache = FALSE;
571 idledata->cachepercent = -1.0;
572 g_strlcpy(idledata->info, uri, sizeof(idledata->info));
573 set_title_bar(idledata);
574
575 streaming = 0;
576
577 gm_store = gm_pref_store_new("gnome-mplayer");
578 forcecache = gm_pref_store_get_boolean(gm_store, FORCECACHE);
579 gm_pref_store_free(gm_store);
580
581
582 if (g_ascii_strcasecmp(uri, "dvdnav://") == 0) {
583 gtk_widget_show(menu_event_box);
584 } else {
585 gtk_widget_hide(menu_event_box);
586 }
587
588 if (autostart) {
589 g_idle_add(hide_buttons, idledata);
590 js_state = STATE_PLAYING;
591
592 if (g_str_has_prefix(uri, "mmshttp") || g_str_has_prefix(uri, "http") || g_str_has_prefix(uri, "mms")) {
593 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_NETWORK);
594 } else if (g_str_has_prefix(uri, "dvd") || g_str_has_prefix(uri, "dvdnav")) {
595 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_DVD);
596 } else if (g_str_has_prefix(uri, "cdda")) {
597 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_CD);
598 } else if (g_str_has_prefix(uri, "cddb")) {
599 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_CD);
600 } else if (g_str_has_prefix(uri, "vcd")) {
601 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_VCD);
602 } else if (g_str_has_prefix(uri, "tv")) {
603 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_TV);
604 } else if (g_str_has_prefix(uri, "dvb")) {
605 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_DVB);
606 } else if (g_str_has_prefix(uri, "file")) {
607 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_FILE);
608 } else {
609 // if all else fails it must be a network type
610 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_NETWORK);
611 }
612
613 gmtk_media_player_set_attribute_boolean(GMTK_MEDIA_PLAYER(media), ATTRIBUTE_PLAYLIST, playlist);
614 gmtk_media_player_set_uri(GMTK_MEDIA_PLAYER(media), uri);
615 #ifdef LIBGDA_ENABLED
616 metadata = get_db_metadata(db_connection, uri);
617
618 if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(playliststore), NULL) == 1 && metadata->resumable
619 && (int) (metadata->position) > 0) {
620 position_text = seconds_to_string(metadata->position);
621 if (resume_mode == RESUME_ALWAYS_ASK) {
622 GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(window),
623 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
624 GTK_MESSAGE_QUESTION,
625 GTK_BUTTONS_YES_NO,
626 _("Resume Playback of %s at %s"),
627 metadata->title, position_text);
628 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) {
629 gmtk_media_tracker_set_length(tracker, metadata->length_value);
630 gmtk_media_tracker_set_position(tracker, metadata->position);
631 gmtk_media_player_set_attribute_double(GMTK_MEDIA_PLAYER(media), ATTRIBUTE_START_TIME,
632 metadata->position);
633 }
634 gtk_widget_destroy(dialog);
635 g_free(position_text);
636 }
637 if (resume_mode == RESUME_BUT_NEVER_ASK) {
638 gmtk_media_tracker_set_length(tracker, metadata->length_value);
639 gmtk_media_tracker_set_position(tracker, metadata->position);
640 gmtk_media_player_set_attribute_double(GMTK_MEDIA_PLAYER(media), ATTRIBUTE_START_TIME,
641 metadata->position);
642 }
643 }
644 free_metadata(metadata);
645 #endif
646 gmtk_media_player_set_state(GMTK_MEDIA_PLAYER(media), MEDIA_STATE_PLAY);
647
648 }
649
650 return 0;
651 }
652
653 #ifndef OS_WIN32
hup_handler(int signum)654 static void hup_handler(int signum)
655 {
656 gm_log(verbose, G_LOG_LEVEL_DEBUG, "handling signal %i", signum);
657 delete_callback(NULL, NULL, NULL);
658 g_idle_add(set_destroy, NULL);
659 }
660 #endif
661
assign_default_keys()662 void assign_default_keys()
663 {
664 if (!accel_keys[FILE_OPEN_LOCATION]) {
665 accel_keys[FILE_OPEN_LOCATION] = g_strdup("4+l");
666 }
667 if (!accel_keys[EDIT_SCREENSHOT]) {
668 accel_keys[EDIT_SCREENSHOT] = g_strdup("4+t");
669 }
670 if (!accel_keys[EDIT_PREFERENCES]) {
671 accel_keys[EDIT_PREFERENCES] = g_strdup("4+p");
672 }
673 if (!accel_keys[VIEW_PLAYLIST]) {
674 accel_keys[VIEW_PLAYLIST] = g_strdup("F9");
675 }
676 if (!accel_keys[VIEW_INFO]) {
677 accel_keys[VIEW_INFO] = g_strdup("i");
678 }
679 if (!accel_keys[VIEW_DETAILS]) {
680 accel_keys[VIEW_DETAILS] = g_strdup("4+d");
681 }
682 if (!accel_keys[VIEW_METER]) {
683 accel_keys[VIEW_METER] = g_strdup("4+m");
684 }
685 if (!accel_keys[VIEW_FULLSCREEN]) {
686 accel_keys[VIEW_FULLSCREEN] = g_strdup("4+f");
687 }
688 if (!accel_keys[VIEW_ASPECT]) {
689 accel_keys[VIEW_ASPECT] = g_strdup("a");
690 }
691 if (!accel_keys[VIEW_SUBTITLES]) {
692 accel_keys[VIEW_SUBTITLES] = g_strdup("v");
693 }
694 if (!accel_keys[VIEW_DECREASE_SIZE]) {
695 accel_keys[VIEW_DECREASE_SIZE] = g_strdup("1+R");
696 }
697 if (!accel_keys[VIEW_INCREASE_SIZE]) {
698 accel_keys[VIEW_INCREASE_SIZE] = g_strdup("1+T");
699 }
700 if (!accel_keys[VIEW_ANGLE]) {
701 accel_keys[VIEW_ANGLE] = g_strdup("4+a");
702 }
703 if (!accel_keys[VIEW_CONTROLS]) {
704 accel_keys[VIEW_CONTROLS] = g_strdup("c");
705 }
706 }
707
main(int argc,char * argv[])708 int main(int argc, char *argv[])
709 {
710 struct stat buf = { 0 };
711 struct mntent *mnt = NULL;
712 FILE *fp = NULL;
713 gchar *uri;
714 gint fileindex = 1;
715 GError *error = NULL;
716 GOptionContext *context;
717 gint i;
718 gdouble volume = 100.0;
719 gchar *accelerator_keys;
720 gchar **parse;
721 #ifdef GTK3_ENABLED
722 GtkSettings *gtk_settings;
723 #endif
724 int stat_result;
725
726 #ifndef OS_WIN32
727 struct sigaction sa;
728 #endif
729 gboolean playiter = FALSE;
730
731 #ifdef GIO_ENABLED
732 GFile *file;
733 #endif
734
735 #ifdef ENABLE_NLS
736 bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
737 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
738 textdomain(GETTEXT_PACKAGE);
739 #endif
740
741 playlist = FALSE;
742 embed_window = 0;
743 control_id = 0;
744 window_x = 0;
745 window_y = 0;
746 last_window_width = 0;
747 last_window_height = 0;
748 showcontrols = TRUE;
749 showsubtitles = TRUE;
750 autostart = 1;
751 videopresent = FALSE;
752 disable_context_menu = FALSE;
753 dontplaynext = FALSE;
754 idledata = (IdleData *) g_new0(IdleData, 1);
755 idledata->videopresent = FALSE;
756 idledata->length = 0.0;
757 idledata->device = NULL;
758 idledata->cachepercent = -1.0;
759 selection = NULL;
760 path = NULL;
761 js_state = STATE_UNDEFINED;
762 control_instance = TRUE;
763 playlistname = NULL;
764 rpconsole = NULL;
765 subtitle = NULL;
766 tv_device = NULL;
767 tv_driver = NULL;
768 tv_width = 0;
769 tv_height = 0;
770 tv_fps = 0;
771 ok_to_play = TRUE;
772 alang = NULL;
773 slang = NULL;
774 metadata_codepage = NULL;
775 playlistname = NULL;
776 window_width = -1;
777 window_height = -1;
778 stored_window_width = -1;
779 stored_window_height = -1;
780 cache_size = 0;
781 forcecache = FALSE;
782 use_volume_option = FALSE;
783 vertical_layout = FALSE;
784 playlist_visible = FALSE;
785 disable_fullscreen = FALSE;
786 disable_framedrop = FALSE;
787 softvol = FALSE;
788 remember_softvol = FALSE;
789 volume_softvol = -1;
790 volume_gain = 0;
791 subtitlefont = NULL;
792 subtitle_codepage = NULL;
793 subtitle_color = NULL;
794 subtitle_outline = FALSE;
795 subtitle_shadow = FALSE;
796 subtitle_fuzziness = 0;
797 disable_embeddedfonts = FALSE;
798 quit_on_complete = FALSE;
799 verbose = 0;
800 reallyverbose = 0;
801 embedding_disabled = FALSE;
802 disable_pause_on_click = FALSE;
803 disable_animation = FALSE;
804 disable_cover_art_fetch = FALSE;
805 auto_hide_timeout = 3;
806 mouse_over_controls = FALSE;
807 use_mediakeys = TRUE;
808 use_defaultpl = FALSE;
809 mplayer_bin = NULL;
810 mplayer_dvd_device = NULL;
811 single_instance = FALSE;
812 disable_deinterlace = TRUE;
813 details_visible = FALSE;
814 replace_and_play = FALSE;
815 bring_to_front = FALSE;
816 keep_on_top = FALSE;
817 resize_on_new_media = FALSE;
818 use_pausing_keep_force = FALSE;
819 show_notification = TRUE;
820 show_status_icon = TRUE;
821 lang_group = NULL;
822 audio_group = NULL;
823 gpod_mount_point = NULL;
824 load_tracks_from_gpod = FALSE;
825 disable_cover_art_fetch = FALSE;
826 fullscreen = 0;
827 vo = NULL;
828 data = NULL;
829 max_data = NULL;
830 details_table = NULL;
831 large_buttons = FALSE;
832 button_size = GTK_ICON_SIZE_BUTTON;
833 lastguistate = -1;
834 non_fs_height = 0;
835 non_fs_width = 0;
836 use_hw_audio = FALSE;
837 start_second = 0;
838 play_length = 0;
839 save_loc = TRUE;
840 screensaver_disabled = FALSE;
841 update_control_flag = FALSE;
842 skip_fixed_allocation_on_show = FALSE;
843 skip_fixed_allocation_on_hide = FALSE;
844 pref_volume = -1;
845 use_mplayer2 = FALSE;
846 enable_global_menu = FALSE;
847 cover_art_uri = NULL;
848 resume_mode = RESUME_ALWAYS_ASK;
849
850
851 // All Gtk docs say we need to call g_thread_init() and gdk_threads_init() before gtk_init()
852 //
853 // Why do we not call this? Why does the program seem to deadlock if we enable this call?
854 // I assume once we have truly fixed locking/threading this will work....
855 // gdk_threads_init();
856 if (!g_thread_supported())
857 g_thread_init(NULL);
858
859 g_type_init();
860 gtk_init(&argc, &argv);
861 g_setenv("PULSE_PROP_media.role", "video", TRUE);
862
863 #ifndef OS_WIN32
864 sa.sa_handler = hup_handler;
865 sigemptyset(&sa.sa_mask);
866 #ifdef SA_RESTART
867 sa.sa_flags = SA_RESTART; /* Restart functions if
868 interrupted by handler */
869 #endif
870
871 gm_log_name_this_thread("root");
872
873 #ifdef SIGINT
874 if (sigaction(SIGINT, &sa, NULL) == -1)
875 gm_log(verbose, G_LOG_LEVEL_MESSAGE, "SIGINT signal handler not installed");
876 #endif
877 #ifdef SIGHUP
878 if (sigaction(SIGHUP, &sa, NULL) == -1)
879 gm_log(verbose, G_LOG_LEVEL_MESSAGE, "SIGHUP signal handler not installed");
880 #endif
881 #ifdef SIGTERM
882 if (sigaction(SIGTERM, &sa, NULL) == -1)
883 gm_log(verbose, G_LOG_LEVEL_MESSAGE, "SIGTERM signal handler not installed");
884 #endif
885 #endif
886
887 uri = g_strdup_printf("%s/gnome-mplayer/cover_art", g_get_user_config_dir());
888 if (!g_file_test(uri, G_FILE_TEST_IS_DIR)) {
889 g_mkdir_with_parents(uri, 0775);
890 }
891 g_free(uri);
892
893 uri = g_strdup_printf("%s/gnome-mplayer/plugin", g_get_user_config_dir());
894 if (!g_file_test(uri, G_FILE_TEST_IS_DIR)) {
895 g_mkdir_with_parents(uri, 0775);
896 }
897 g_free(uri);
898 uri = NULL;
899
900 default_playlist = g_strdup_printf("file://%s/gnome-mplayer/default.pls", g_get_user_config_dir());
901 safe_to_save_default_playlist = TRUE;
902
903 gm_store = gm_pref_store_new("gnome-mplayer");
904 gmp_store = gm_pref_store_new("gecko-mediaplayer");
905 vo = gm_pref_store_get_string(gm_store, VO);
906 audio_device.alsa_mixer = gm_pref_store_get_string(gm_store, ALSA_MIXER);
907 use_hardware_codecs = gm_pref_store_get_boolean(gm_store, USE_HARDWARE_CODECS);
908 use_crystalhd_codecs = gm_pref_store_get_boolean(gm_store, USE_CRYSTALHD_CODECS);
909 osdlevel = gm_pref_store_get_int(gm_store, OSDLEVEL);
910 pplevel = gm_pref_store_get_int(gm_store, PPLEVEL);
911 #ifndef HAVE_ASOUNDLIB
912 volume = gm_pref_store_get_int(gm_store, VOLUME);
913 if (pref_volume == -1) {
914 pref_volume = volume;
915 }
916 #endif
917 audio_channels = gm_pref_store_get_int(gm_store, AUDIO_CHANNELS);
918 use_hw_audio = gm_pref_store_get_boolean(gm_store, USE_HW_AUDIO);
919 fullscreen = gm_pref_store_get_boolean(gm_store, FULLSCREEN);
920 softvol = gm_pref_store_get_boolean(gm_store, SOFTVOL);
921 remember_softvol = gm_pref_store_get_boolean(gm_store, REMEMBER_SOFTVOL);
922 volume_softvol = gm_pref_store_get_float(gm_store, VOLUME_SOFTVOL);
923 volume_gain = gm_pref_store_get_int(gm_store, VOLUME_GAIN);
924 forcecache = gm_pref_store_get_boolean(gm_store, FORCECACHE);
925 vertical_layout = gm_pref_store_get_boolean(gm_store, VERTICAL);
926 playlist_visible = gm_pref_store_get_boolean(gm_store, SHOWPLAYLIST);
927 details_visible = gm_pref_store_get_boolean(gm_store, SHOWDETAILS);
928 show_notification = gm_pref_store_get_boolean(gm_store, SHOW_NOTIFICATION);
929 show_status_icon = gm_pref_store_get_boolean(gm_store, SHOW_STATUS_ICON);
930 showcontrols = gm_pref_store_get_boolean_with_default(gm_store, SHOW_CONTROLS, showcontrols);
931 restore_controls = showcontrols;
932 disable_deinterlace = gm_pref_store_get_boolean(gm_store, DISABLEDEINTERLACE);
933 disable_framedrop = gm_pref_store_get_boolean(gm_store, DISABLEFRAMEDROP);
934 disable_fullscreen = gm_pref_store_get_boolean(gm_store, DISABLEFULLSCREEN);
935 disable_context_menu = gm_pref_store_get_boolean(gm_store, DISABLECONTEXTMENU);
936 disable_ass = gm_pref_store_get_boolean(gm_store, DISABLEASS);
937 disable_embeddedfonts = gm_pref_store_get_boolean(gm_store, DISABLEEMBEDDEDFONTS);
938 disable_pause_on_click = gm_pref_store_get_boolean(gm_store, DISABLEPAUSEONCLICK);
939 disable_animation = gm_pref_store_get_boolean(gm_store, DISABLEANIMATION);
940 disable_cover_art_fetch =
941 gm_pref_store_get_boolean_with_default(gm_store, DISABLE_COVER_ART_FETCH, disable_cover_art_fetch);
942 auto_hide_timeout = gm_pref_store_get_int_with_default(gm_store, AUTOHIDETIMEOUT, auto_hide_timeout);
943 disable_cover_art_fetch = gm_pref_store_get_boolean(gm_store, DISABLE_COVER_ART_FETCH);
944 use_mediakeys = gm_pref_store_get_boolean_with_default(gm_store, USE_MEDIAKEYS, use_mediakeys);
945 use_defaultpl = gm_pref_store_get_boolean_with_default(gm_store, USE_DEFAULTPL, use_defaultpl);
946 metadata_codepage = gm_pref_store_get_string(gm_store, METADATACODEPAGE);
947
948 alang = gm_pref_store_get_string(gm_store, AUDIO_LANG);
949 slang = gm_pref_store_get_string(gm_store, SUBTITLE_LANG);
950
951 subtitlefont = gm_pref_store_get_string(gm_store, SUBTITLEFONT);
952 subtitle_scale = gm_pref_store_get_float(gm_store, SUBTITLESCALE);
953 if (subtitle_scale < 0.25) {
954 subtitle_scale = 1.0;
955 }
956 subtitle_codepage = gm_pref_store_get_string(gm_store, SUBTITLECODEPAGE);
957 subtitle_color = gm_pref_store_get_string(gm_store, SUBTITLECOLOR);
958 subtitle_outline = gm_pref_store_get_boolean(gm_store, SUBTITLEOUTLINE);
959 subtitle_shadow = gm_pref_store_get_boolean(gm_store, SUBTITLESHADOW);
960 subtitle_margin = gm_pref_store_get_int(gm_store, SUBTITLE_MARGIN);
961 subtitle_fuzziness = gm_pref_store_get_int(gm_store, SUBTITLE_FUZZINESS);
962 showsubtitles = gm_pref_store_get_boolean_with_default(gm_store, SHOW_SUBTITLES, TRUE);
963
964 resume_mode = gm_pref_store_get_int(gm_store, RESUME_MODE);
965
966 qt_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_QT);
967 real_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_REAL);
968 wmp_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_WMP);
969 dvx_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_DVX);
970 midi_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_MIDI);
971 embedding_disabled = gm_pref_store_get_boolean(gmp_store, DISABLE_EMBEDDING);
972 disable_embedded_scaling = gm_pref_store_get_boolean(gmp_store, DISABLE_EMBEDDED_SCALING);
973 if (embed_window == 0) {
974 single_instance = gm_pref_store_get_boolean(gm_store, SINGLE_INSTANCE);
975 if (single_instance) {
976 replace_and_play = gm_pref_store_get_boolean(gm_store, REPLACE_AND_PLAY);
977 bring_to_front = gm_pref_store_get_boolean(gm_store, BRING_TO_FRONT);
978 }
979 }
980 enable_global_menu = gm_pref_store_get_boolean(gm_store, ENABLE_GLOBAL_MENU);
981 gm_log(verbose, G_LOG_LEVEL_DEBUG, "Enable global menu preference value is %s",
982 gm_bool_to_string(enable_global_menu));
983 if (!enable_global_menu) {
984 if (g_getenv("UBUNTU_MENUPROXY") != NULL) {
985 if (g_ascii_strcasecmp(g_getenv("UBUNTU_MENUPROXY"), "0") == 0)
986 enable_global_menu = FALSE;
987 if (g_ascii_strcasecmp(g_getenv("UBUNTU_MENUPROXY"), "1") == 0)
988 enable_global_menu = TRUE;
989 }
990 gm_log(verbose, G_LOG_LEVEL_DEBUG,
991 "Enable global menu preference value is %s after reading UBUNTU_MENUPROXY",
992 gm_bool_to_string(enable_global_menu));
993 }
994
995 enable_nautilus_plugin = gm_pref_store_get_boolean_with_default(gm_store, ENABLE_NAUTILUS_PLUGIN, TRUE);
996 if (mplayer_bin == NULL)
997 mplayer_bin = gm_pref_store_get_string(gm_store, MPLAYER_BIN);
998 if (mplayer_bin != NULL && !g_file_test(mplayer_bin, G_FILE_TEST_EXISTS)) {
999 g_free(mplayer_bin);
1000 mplayer_bin = NULL;
1001 }
1002 mplayer_dvd_device = gm_pref_store_get_string(gm_store, MPLAYER_DVD_DEVICE);
1003 extraopts = gm_pref_store_get_string(gm_store, EXTRAOPTS);
1004 accelerator_keys = gm_pref_store_get_string(gm_store, ACCELERATOR_KEYS);
1005 accel_keys = g_strv_new(KEY_COUNT);
1006 accel_keys_description = g_strv_new(KEY_COUNT);
1007 if (accelerator_keys != NULL) {
1008 parse = g_strsplit(accelerator_keys, " ", KEY_COUNT);
1009 for (i = 0; i < g_strv_length(parse); i++) {
1010 accel_keys[i] = g_strdup(parse[i]);
1011 }
1012 g_free(accelerator_keys);
1013 g_strfreev(parse);
1014 }
1015 assign_default_keys();
1016 accel_keys_description[FILE_OPEN_LOCATION] = g_strdup(_("Open Location"));
1017 accel_keys_description[EDIT_SCREENSHOT] = g_strdup(_("Take Screenshot"));
1018 accel_keys_description[EDIT_PREFERENCES] = g_strdup(_("Preferences"));
1019 accel_keys_description[VIEW_PLAYLIST] = g_strdup(_("Playlist"));
1020 accel_keys_description[VIEW_INFO] = g_strdup(_("Media Info"));
1021 accel_keys_description[VIEW_DETAILS] = g_strdup(_("Details"));
1022 accel_keys_description[VIEW_METER] = g_strdup(_("Audio Meter"));
1023 accel_keys_description[VIEW_FULLSCREEN] = g_strdup(_("Full Screen"));
1024 accel_keys_description[VIEW_ASPECT] = g_strdup(_("Aspect"));
1025 accel_keys_description[VIEW_SUBTITLES] = g_strdup(_("Subtitles"));
1026 accel_keys_description[VIEW_DECREASE_SIZE] = g_strdup(_("Decrease Subtitle Size"));
1027 accel_keys_description[VIEW_INCREASE_SIZE] = g_strdup(_("Increase Subtitle Size"));
1028 accel_keys_description[VIEW_ANGLE] = g_strdup(_("Switch Angle"));
1029 accel_keys_description[VIEW_CONTROLS] = g_strdup(_("Controls"));
1030 remember_loc = gm_pref_store_get_boolean(gm_store, REMEMBER_LOC);
1031 loc_window_x = gm_pref_store_get_int(gm_store, WINDOW_X);
1032 loc_window_y = gm_pref_store_get_int(gm_store, WINDOW_Y);
1033 loc_window_height = gm_pref_store_get_int(gm_store, WINDOW_HEIGHT);
1034 loc_window_width = gm_pref_store_get_int(gm_store, WINDOW_WIDTH);
1035 loc_panel_position = gm_pref_store_get_int(gm_store, PANEL_POSITION);
1036 keep_on_top = gm_pref_store_get_boolean(gm_store, KEEP_ON_TOP);
1037 resize_on_new_media = gm_pref_store_get_boolean(gm_store, RESIZE_ON_NEW_MEDIA);
1038 mouse_wheel_changes_volume = gm_pref_store_get_boolean_with_default(gm_store, MOUSE_WHEEL_CHANGES_VOLUME, FALSE);
1039 audio_device_name = gm_pref_store_get_string(gm_store, AUDIO_DEVICE_NAME);
1040 audio_device.description = g_strdup(audio_device_name);
1041 context = g_option_context_new(_("[FILES...] - GNOME Media player based on MPlayer"));
1042 #ifdef GTK2_12_ENABLED
1043 g_option_context_set_translation_domain(context, "UTF-8");
1044 g_option_context_set_translate_func(context, (GTranslateFunc) gettext, NULL, NULL);
1045 #endif
1046 g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE);
1047 g_option_context_add_group(context, gtk_get_option_group(TRUE));
1048 g_option_context_parse(context, &argc, &argv, &error);
1049 g_option_context_free(context);
1050 if (new_instance)
1051 single_instance = FALSE;
1052 if (verbose == 0)
1053 verbose = gm_pref_store_get_int(gm_store, VERBOSE);
1054 if (reallyverbose)
1055 verbose = 2;
1056 if (verbose) {
1057 printf(_("GNOME MPlayer v%s\n"), VERSION);
1058 printf(_("gmtk v%s\n"), gmtk_version());
1059 printf("GTK %i.%i.%i\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
1060 printf("GLIB %i.%i.%i\n", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
1061 printf("GDA Enabled\n");
1062 }
1063
1064 if (cache_size == 0)
1065 cache_size = gm_pref_store_get_int(gm_store, CACHE_SIZE);
1066 if (cache_size == 0)
1067 cache_size = 2000;
1068 plugin_audio_cache_size = gm_pref_store_get_int(gm_store, PLUGIN_AUDIO_CACHE_SIZE);
1069 if (plugin_audio_cache_size == 0)
1070 plugin_audio_cache_size = 2000;
1071 plugin_video_cache_size = gm_pref_store_get_int(gm_store, PLUGIN_VIDEO_CACHE_SIZE);
1072 if (plugin_video_cache_size == 0)
1073 plugin_video_cache_size = 2000;
1074 if (control_id != 0)
1075 cache_size = plugin_video_cache_size;
1076 gm_pref_store_free(gm_store);
1077 gm_pref_store_free(gmp_store);
1078 if (embed_window) {
1079 gm_log(verbose, G_LOG_LEVEL_INFO, "embedded in window id 0x%x", embed_window);
1080 }
1081
1082 if (single_instance) {
1083 gm_log(verbose, G_LOG_LEVEL_INFO, "Running in single instance mode");
1084 }
1085 #ifdef GIO_ENABLED
1086 gm_log(verbose, G_LOG_LEVEL_INFO, "Running with GIO support");
1087 #endif
1088 #ifdef ENABLE_PANSCAN
1089 gm_log(verbose, G_LOG_LEVEL_INFO, "Running with panscan enabled (mplayer svn r29565 or higher required)");
1090 #endif
1091 gm_log(verbose, G_LOG_LEVEL_INFO, "Using audio device: %s", audio_device_name);
1092 #ifdef HAVE_MUSICBRAINZ
1093 if (curl_global_init(CURL_GLOBAL_ALL) != 0) {
1094 gm_log(verbose, G_LOG_LEVEL_MESSAGE, "CURL initialization failed");
1095 }
1096 #endif
1097
1098 if (softvol) {
1099 gm_log(verbose, G_LOG_LEVEL_INFO, "Using MPlayer Software Volume control");
1100 if (remember_softvol && volume_softvol != -1) {
1101 gm_log(verbose, G_LOG_LEVEL_INFO, "Using last volume of %f%%", volume_softvol * 100.0);
1102 volume = (gdouble) volume_softvol *100.0;
1103 audio_device.volume = volume / 100.0;
1104 } else {
1105 volume = 100.0;
1106 }
1107 }
1108
1109 if (large_buttons)
1110 button_size = GTK_ICON_SIZE_DIALOG;
1111 if (playlist_visible && control_id != 0)
1112 playlist_visible = FALSE;
1113 if (error != NULL) {
1114 printf("%s\n", error->message);
1115 printf(_("Run 'gnome-mplayer --help' to see a full list of available command line options.\n"));
1116 return 1;
1117 }
1118 gm_log(verbose, G_LOG_LEVEL_DEBUG, "Threading support enabled = %s", gm_bool_to_string(g_thread_supported()));
1119 if (rpconsole == NULL)
1120 rpconsole = g_strdup("NONE");
1121 // setup playliststore
1122 playliststore =
1123 gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN,
1124 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_FLOAT, G_TYPE_STRING,
1125 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
1126 G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
1127 G_TYPE_FLOAT, G_TYPE_FLOAT, G_TYPE_BOOLEAN);
1128 #ifdef LIBGDA_ENABLED
1129 db_connection = open_db_connection();
1130 #endif
1131 // only use dark theme if not embedded, otherwise use the default theme
1132 #ifdef GTK3_ENABLED
1133 if (embed_window <= 0) {
1134 gtk_settings = gtk_settings_get_default();
1135 g_object_set(G_OBJECT(gtk_settings), "gtk-application-prefer-dark-theme", TRUE, NULL);
1136 }
1137 #endif
1138
1139 create_window(embed_window);
1140 autopause = FALSE;
1141 #ifdef GIO_ENABLED
1142 idledata->caching = g_mutex_new();
1143 idledata->caching_complete = g_cond_new();
1144 #endif
1145 retrieve_metadata_pool = g_thread_pool_new(retrieve_metadata, NULL, 10, TRUE, NULL);
1146 retrieve_mutex = g_mutex_new();
1147 set_mutex = g_mutex_new();
1148 if (argv[fileindex] != NULL) {
1149 #ifdef GIO_ENABLED
1150 file = g_file_new_for_commandline_arg(argv[fileindex]);
1151 stat_result = -1;
1152 if (file != NULL) {
1153 GError *error = NULL;
1154 GFileInfo *file_info = g_file_query_info(file, G_FILE_ATTRIBUTE_UNIX_MODE, 0, NULL, &error);
1155 if (file_info != NULL) {
1156 buf.st_mode = g_file_info_get_attribute_uint32(file_info, G_FILE_ATTRIBUTE_UNIX_MODE);
1157 stat_result = 0;
1158 g_object_unref(file_info);
1159 }
1160 if (error != NULL) {
1161 gm_log(verbose, G_LOG_LEVEL_INFO, "failed to get mode: %s", error->message);
1162 g_error_free(error);
1163 }
1164 g_object_unref(file);
1165 }
1166 #else
1167 stat_result = g_stat(argv[fileindex], &buf);
1168 #endif
1169 gm_log(verbose, G_LOG_LEVEL_INFO, "opening %s", argv[fileindex]);
1170 gm_log(verbose, G_LOG_LEVEL_INFO, "stat_result = %i", stat_result);
1171 gm_log(verbose, G_LOG_LEVEL_INFO, "is block %s", gm_bool_to_string(S_ISBLK(buf.st_mode)));
1172 gm_log(verbose, G_LOG_LEVEL_INFO, "is character %s", gm_bool_to_string(S_ISCHR(buf.st_mode)));
1173 gm_log(verbose, G_LOG_LEVEL_INFO, "is reg %s", gm_bool_to_string(S_ISREG(buf.st_mode)));
1174 gm_log(verbose, G_LOG_LEVEL_INFO, "is dir %s", gm_bool_to_string(S_ISDIR(buf.st_mode)));
1175 gm_log(verbose, G_LOG_LEVEL_INFO, "playlist %s", gm_bool_to_string(playlist));
1176 gm_log(verbose, G_LOG_LEVEL_INFO, "embedded in window id 0x%x", embed_window);
1177 if (stat_result == 0 && S_ISBLK(buf.st_mode)) {
1178 // might have a block device, so could be a DVD
1179
1180 #ifdef HAVE_SYS_MOUNT_H
1181 fp = setmntent("/etc/mtab", "r");
1182 do {
1183 mnt = getmntent(fp);
1184 if (mnt)
1185 gm_log(verbose, G_LOG_LEVEL_MESSAGE, "%s is at %s", mnt->mnt_fsname, mnt->mnt_dir);
1186 if (argv[fileindex] != NULL && mnt && mnt->mnt_fsname != NULL) {
1187 if (strcmp(argv[fileindex], mnt->mnt_fsname) == 0)
1188 break;
1189 }
1190 }
1191 while (mnt);
1192 endmntent(fp);
1193 #endif
1194 if (mnt && mnt->mnt_dir) {
1195 gm_log(verbose, G_LOG_LEVEL_MESSAGE, "%s is mounted on %s", argv[fileindex], mnt->mnt_dir);
1196 uri = g_strdup_printf("%s/VIDEO_TS", mnt->mnt_dir);
1197 stat(uri, &buf);
1198 g_free(uri);
1199 if (S_ISDIR(buf.st_mode)) {
1200 add_item_to_playlist("dvdnav://", FALSE);
1201 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
1202 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_DVD);
1203 //play_iter(&iter, 0);
1204 playiter = TRUE;
1205 } else {
1206 uri = g_strdup_printf("file://%s", mnt->mnt_dir);
1207 create_folder_progress_window();
1208 add_folder_to_playlist_callback(uri, NULL);
1209 g_free(uri);
1210 destroy_folder_progress_window();
1211 if (random_order) {
1212 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
1213 randomize_playlist(playliststore);
1214 }
1215 if (first_item_in_playlist(playliststore, &iter)) {
1216 // play_iter(&iter, 0);
1217 playiter = TRUE;
1218 }
1219 }
1220 } else {
1221 parse_cdda("cdda://");
1222 if (random_order) {
1223 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
1224 randomize_playlist(playliststore);
1225 }
1226 //play_file("cdda://", playlist);
1227 if (first_item_in_playlist(playliststore, &iter)) {
1228 // play_iter(&iter, 0);
1229 playiter = TRUE;
1230 }
1231 }
1232 } else if (stat_result == 0 && S_ISDIR(buf.st_mode)) {
1233 uri = g_strdup_printf("%s/VIDEO_TS", argv[fileindex]);
1234 stat_result = g_stat(uri, &buf);
1235 g_free(uri);
1236 if (stat_result == 0 && S_ISDIR(buf.st_mode)) {
1237 add_item_to_playlist("dvdnav://", FALSE);
1238 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
1239 gmtk_media_player_set_media_type(GMTK_MEDIA_PLAYER(media), TYPE_DVD);
1240 //play_iter(&iter, 0);
1241 playiter = TRUE;
1242 } else {
1243 create_folder_progress_window();
1244 uri = NULL;
1245 #ifdef GIO_ENABLED
1246 file = g_file_new_for_commandline_arg(argv[fileindex]);
1247 if (file != NULL) {
1248 uri = g_file_get_uri(file);
1249 g_object_unref(file);
1250 }
1251 #else
1252 uri = g_filename_to_uri(argv[fileindex], NULL, NULL);
1253 #endif
1254 add_folder_to_playlist_callback(uri, NULL);
1255 g_free(uri);
1256 destroy_folder_progress_window();
1257 if (random_order) {
1258 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
1259 randomize_playlist(playliststore);
1260 }
1261 if (first_item_in_playlist(playliststore, &iter)) {
1262 //play_iter(&iter, 0);
1263 playiter = TRUE;
1264 }
1265 }
1266 } else {
1267 // local file
1268 // detect if playlist here, so even if not specified it can be picked up
1269 i = fileindex;
1270 while (argv[i] != NULL) {
1271 gm_log(verbose, G_LOG_LEVEL_DEBUG, "Argument %i is %s", i, argv[i]);
1272 #ifdef GIO_ENABLED
1273 if (!device_name(argv[i])) {
1274 file = g_file_new_for_commandline_arg(argv[i]);
1275 if (file != NULL) {
1276 uri = g_file_get_uri(file);
1277 g_object_unref(file);
1278 } else {
1279 uri = g_strdup(argv[i]);
1280 }
1281 } else {
1282 uri = g_strdup(argv[i]);
1283 }
1284 #else
1285 uri = g_filename_to_uri(argv[i], NULL, NULL);
1286 #endif
1287 if (uri != NULL) {
1288 if (playlist == FALSE)
1289 playlist = detect_playlist(uri);
1290 if (!playlist) {
1291 add_item_to_playlist(uri, playlist);
1292 } else {
1293 if (!parse_playlist(uri)) {
1294 add_item_to_playlist(uri, playlist);
1295 }
1296 }
1297 g_free(uri);
1298 }
1299 i++;
1300 }
1301
1302 if (random_order) {
1303 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(playliststore), &iter);
1304 randomize_playlist(playliststore);
1305 }
1306 if (first_item_in_playlist(playliststore, &iter)) {
1307 playiter = TRUE;
1308 }
1309 }
1310
1311 }
1312 #ifdef HAVE_GPOD
1313 if (load_tracks_from_gpod) {
1314 gpod_mount_point = find_gpod_mount_point();
1315 gm_log(verbose, G_LOG_LEVEL_MESSAGE, "mount point is %s", gpod_mount_point);
1316 if (gpod_mount_point != NULL) {
1317 gpod_load_tracks(gpod_mount_point);
1318 } else {
1319 gm_log(verbose, G_LOG_LEVEL_MESSAGE, "Unable to find gpod mount point");
1320 }
1321 }
1322 #endif
1323
1324 gm_audio_update_device(&audio_device);
1325 // disabling this line seems to help with hangs on startup when using pulseaudio
1326 //gm_audio_get_volume(&audio_device);
1327 set_media_player_attributes(media);
1328 if (softvol) {
1329 if (pref_volume != -1) {
1330 audio_device.volume = (gdouble) pref_volume / 100.0;
1331 gm_log(verbose, G_LOG_LEVEL_INFO, "The volume on '%s' is %f", audio_device.description,
1332 audio_device.volume);
1333 volume = audio_device.volume * 100;
1334 } else {
1335 audio_device.volume = volume / 100.0;
1336 }
1337 }
1338 gm_log(verbose, G_LOG_LEVEL_DEBUG, "Volume is %lf Audio Device Volume = %f", volume, audio_device.volume);
1339
1340 #ifdef GTK2_12_ENABLED
1341 gtk_scale_button_set_value(GTK_SCALE_BUTTON(vol_slider), audio_device.volume);
1342 #else
1343 gtk_range_set_value(GTK_RANGE(vol_slider), audio_device.volume);
1344 #endif
1345 use_volume_option = detect_volume_option();
1346 dbus_hookup(embed_window, control_id);
1347 // don't hook up MPRIS when running in embedded mode
1348 if (embed_window == 0) {
1349 mpris_hookup(control_id);
1350 }
1351 show_window(embed_window);
1352 if (playiter)
1353 play_iter(&iter, 0);
1354 if (argv[fileindex] == NULL && embed_window == 0) {
1355 // When running as apple.com external player, don't load the default playlist
1356 if (control_id == 0) {
1357 use_remember_loc = remember_loc;
1358 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_view_playlist), playlist_visible);
1359 } else {
1360 remember_loc = FALSE;
1361 use_remember_loc = FALSE;
1362 // prevents saving of a playlist with one item on it
1363 use_defaultpl = FALSE;
1364 // don't save the loc when launched with a single file
1365 save_loc = FALSE;
1366 }
1367 } else {
1368 // prevents saving of a playlist with one item on it
1369 use_defaultpl = FALSE;
1370 // don't save the loc when launched with a single file
1371 save_loc = FALSE;
1372 }
1373
1374 if (single_instance && embed_window == 0) {
1375 if (control_id == 0) {
1376 use_remember_loc = remember_loc;
1377 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_view_playlist), playlist_visible);
1378 }
1379 }
1380
1381 if (embed_window == 0) {
1382 if (remember_loc) {
1383 gtk_window_move(GTK_WINDOW(window), loc_window_x, loc_window_y);
1384 g_idle_add(set_pane_position, NULL);
1385 }
1386 }
1387
1388 safe_to_save_default_playlist = FALSE;
1389 if (use_defaultpl) {
1390 create_folder_progress_window();
1391 parse_playlist(default_playlist);
1392 destroy_folder_progress_window();
1393 }
1394 safe_to_save_default_playlist = TRUE;
1395 // put the request to update the volume into the list of tasks to complete
1396 g_idle_add(hookup_volume, NULL);
1397 g_idle_add(set_volume, NULL);
1398 if (fullscreen && embed_window == 0)
1399 g_idle_add(set_fullscreen, NULL);
1400 gtk_main();
1401 return 0;
1402 }
1403