⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gui_main.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 * 
 * The Original Code is MPEG4IP.
 * 
 * The Initial Developer of the Original Code is Cisco Systems Inc.
 * Portions created by Cisco Systems Inc. are
 * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
 * 
 * Contributor(s): 
 *              Bill May        wmay@cisco.com
 */
/*
 * gui_main.cpp - Contains the gtk based gui for this player.
 */
#include <stdlib.h>
#include <stdio.h>
#include "player_session.h"
#include "player_media.h"
#include <glib.h>
#include <gtk/gtk.h>
#include "gui_utils.h"
#include "media_utils.h"
#include "player_util.h"
#include "gui_xpm.h"
#include <syslog.h>
#include <rtsp/rtsp_client.h>
#include "our_config_file.h"
#include "playlist.h"
#include <libhttp/http.h>
#include <rtp/debug.h>
#include "codec_plugin_private.h"
/* ??? */
#ifndef LOG_PRI
#define LOG_PRI(p) ((p) & LOG_PRIMASK)
#endif

/* Local variables */
static GtkWidget *main_window;
static GtkWidget *main_vbox;
static GtkWidget *close_menuitem;
static GtkAccelGroup *accel_group = NULL;
static GtkTooltips         *tooltips = NULL;
static GList *playlist = NULL;
static GtkWidget *combo;

static volatile enum {
  PLAYING_NONE,
  PLAYING,
  STOPPED,
  PAUSED,
} play_state = PLAYING_NONE;
static CPlaylist *master_playlist;
static CPlayerSession *psptr = NULL;
static CMsgQueue master_queue;
static GtkWidget *play_button;
static GtkWidget *pause_button;
static GtkWidget *stop_button;
//static GtkWidget *rewind_button;
//static GtkWidget *ff_button;
static GtkWidget *speaker_button;
static GtkWidget *volume_slider;
static GtkWidget *time_slider;
static GtkWidget *time_disp;
static GtkWidget *session_desc[5];
static SDL_mutex *command_mutex;
static int master_looped;
static int master_volume;
static int master_muted;
static int master_fullscreen = 0;
static uint64_t master_time;
static int time_slider_pressed = 0;
static int master_screen_size = 100;
static const char *last_entry = NULL;
static const gchar *last_file = NULL;
static GtkTargetEntry drop_types[] = 
{
  { "text/plain", 0, 1 }
};

static void media_list_query (CPlayerSession *psptr,
			      int num_video, 
			      video_query_t *vq,
			      int num_audio,
			      audio_query_t *aq)
{
  if (num_video > 0) {
    if (config.get_config_value(CONFIG_PLAY_VIDEO) != 0) {
      vq[0].enabled = 1;
    } 
  }
  if (num_audio > 0) {
    if (config.get_config_value(CONFIG_PLAY_AUDIO) != 0) {
      aq[0].enabled = 1;
    } 
  }
}

static control_callback_vft_t cc_vft = {
  media_list_query,
};
/*
 * toggle_button_adjust - make sure a toggle button reflects the correct
 * state
 */
static void toggle_button_adjust (GtkWidget *button, int state)
{
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) == state)
    return;
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), state);
}

/*
 * close_session - delete the session, and set the various gui pieces
 */
static void close_session (void)
{
  if (psptr != NULL) {
    delete psptr;
    psptr = NULL;
    play_state = PLAYING_NONE;
    gtk_widget_set_sensitive(close_menuitem, 0);
    toggle_button_adjust(play_button, FALSE);
    toggle_button_adjust(pause_button, FALSE);
    toggle_button_adjust(stop_button, FALSE);
    gtk_widget_set_sensitive(stop_button, 0);
    gtk_widget_set_sensitive(play_button, 0);
    gtk_widget_set_sensitive(pause_button, 0);
    gtk_widget_set_sensitive(time_slider, 0);
  }
}

/*
 * When we hit play, adjust the gui
 */
static void adjust_gui_for_play (void)
{
  gtk_widget_set_sensitive(close_menuitem, 1);
  gtk_widget_set_sensitive(play_button, 1);
  gtk_widget_set_sensitive(pause_button, 1);
  gtk_widget_set_sensitive(stop_button, 1);
  if (psptr->session_is_seekable()) {
    gtk_widget_set_sensitive(time_slider, 1);
  }
  play_state = PLAYING;
  toggle_button_adjust(play_button, TRUE);
  toggle_button_adjust(stop_button, FALSE);
  toggle_button_adjust(pause_button, FALSE);
  gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), last_entry);
  gtk_editable_select_region(GTK_EDITABLE(GTK_COMBO(combo)->entry), 0, -1);
  gtk_editable_set_position(GTK_EDITABLE(GTK_COMBO(combo)->entry), -1);
  gtk_widget_grab_focus(combo);
}


static void create_session_from_name (const char *name)
{
  gint x, y, w, h;
  GdkWindow *window;
  window = GTK_WIDGET(main_window)->window;
  gdk_window_get_position(window, &x, &y);
  gdk_window_get_size(window, &w, &h);
  y += h + 40;

  if (config.get_config_value(CONFIG_PLAY_AUDIO) == 0 &&
      config.get_config_value(CONFIG_PLAY_VIDEO) == 0) {
    ShowMessage("Hey Dummy", "You have both audio and video disabled");
    return;
  }

  // If we're already running a session, close it.
  if (psptr != NULL) {
    close_session();
  }

  psptr = new CPlayerSession(&master_queue,
			     NULL,
			     name);
  if (psptr != NULL) {
    char errmsg[512];
    errmsg[0] = '\0';
    // See if we can create media for this session
    int ret = parse_name_for_session(psptr, name, errmsg, sizeof(errmsg),
				     &cc_vft);
    if (ret >= 0) {
      // Yup - valid session.  Set volume, set up sync thread, and
      // start the session
      if (ret > 0) {
	ShowMessage("Warning", errmsg);
      }
      if (master_muted == 0)
	psptr->set_audio_volume(master_volume);
      else
	psptr->set_audio_volume(0);
      psptr->set_up_sync_thread();
      psptr->set_screen_location(x, y);
      psptr->set_screen_size(master_screen_size / 50, master_fullscreen);
      psptr->play_all_media(TRUE);  // check response here...
    adjust_gui_for_play();
    } else {
      // Nope - display a message
      delete psptr;
      psptr = NULL;
      char buffer[1024];
      snprintf(buffer, sizeof(buffer), "%s cannot be opened\n%s", name,
	       errmsg);
      ShowMessage("Open error", buffer);
    }
  }
}
/*
 * start a session
 */
static void start_session_from_name (const char *name)
{
  GList *p;
  int in_list = 0;

  // Save the last file, so we can use it next time we do a file open
  if (last_entry != NULL) {
    free((void *)last_entry);
  }
  last_entry = strdup(name);
  if (strncmp("rtsp://", name, strlen("rtsp://")) != 0) {
    if (last_file != NULL) {
      free((void *)last_file);
      last_file = NULL;
    }
    last_file = g_strdup(name);
    config.set_config_string(CONFIG_PREV_DIRECTORY, strdup(last_file));
  }

  // See if entry is already in the list.
  p = g_list_first(playlist);
  while (p != NULL && in_list == 0) {
    if (g_strcasecmp(name, (const gchar *)p->data) == 0) {
      in_list = 1;
    }
    p = g_list_next(p);
  }
  
  SDL_mutexP(command_mutex);
  
  // If we're running a playlist, close it now.
  if (master_playlist != NULL) {
    delete master_playlist;
    master_playlist = NULL;
  }

  // Create a new player session
  const char *suffix = strrchr(name, '.');
  if ((suffix != NULL) && 
      ((strcasecmp(suffix, ".mp4plist") == 0) ||
       (strcasecmp(suffix, ".mxu") == 0) ||
       (strcasecmp(suffix, ".gmp4_playlist") == 0))) {
    const char *errmsg = NULL;
    master_playlist = new CPlaylist(name, &errmsg);
    if (errmsg != NULL) {
      ShowMessage("Playlist error", errmsg);
    } else {
      create_session_from_name(master_playlist->get_first());
    }
  } else {
    create_session_from_name(name);
  }

  // Add this file to the drop down list
  // If we're playing, adjust the gui
  if (psptr != NULL) {

    if (in_list == 0) {
      config.move_config_strings(CONFIG_PREV_FILE_3, CONFIG_PREV_FILE_2);
      config.move_config_strings(CONFIG_PREV_FILE_2, CONFIG_PREV_FILE_1);
      config.move_config_strings(CONFIG_PREV_FILE_1, CONFIG_PREV_FILE_0);
      config.set_config_string(CONFIG_PREV_FILE_0, strdup(name));
    }
  }
  if (in_list == 0) {
    gchar *newone = g_strdup(name);
    playlist = g_list_append(playlist, newone);
    gtk_combo_set_popdown_strings (GTK_COMBO(combo), playlist);
    gtk_widget_show(combo);
  }
  SDL_mutexV(command_mutex);
}

/*
 * delete_event - called when window closed
 */
void delete_event (GtkWidget *widget, gpointer *data)
{
  if (psptr != NULL) {
    delete psptr;
  }
  if (master_playlist != NULL) {
    delete master_playlist;
  }
  close_plugins();
  gtk_main_quit();
}

static void on_main_menu_close (GtkWidget *window, gpointer data)
{
  SDL_mutexP(command_mutex);
  close_session();
  master_fullscreen = 0;
  SDL_mutexV(command_mutex);
}

static void on_main_menu_help (GtkWidget *window, gpointer data)
{
}

static void on_main_menu_about (GtkWidget *window, gpointer data)
{
  char buffer[1024];
  sprintf(buffer,
	  "gmp4player Version %s.\n"
	  "An open source file/streaming MPEG4 player\n"
	  "Developed by cisco Systems using the\n"
	  "following open source packages:\n"
	  "\n"
	  "SDL, SMPEG audio (MP3) from lokigames\n"
	  "RTP from UCL\n"
	  "ISO reference decoder for MPEG4\n"
	  "FAAC decoder\n"
	  "Xvid decoder\n"
	  "Developed by Bill May, 10/00 to present", VERSION);

  ShowMessage("About gmp4player",buffer);
}

/*
 * on_drag_data_received - copied from gtv, who copied from someone else
 */
static void on_drag_data_received (GtkWidget *widget,
				   GdkDragContext *context,
				   gint x,
				   gint y,
				   GtkSelectionData *selection_data,
				   guint info,
				   guint time)
{
    gchar *temp, *string;

    string = (gchar *)selection_data->data;

    /* remove newline at end of line, and the file:// url header
       at the begining, copied this code from the xmms source */
    temp = strchr(string, '\n');
    if (temp)
    {
        if (*(temp - 1) == '\r')
            *(temp - 1) = '\0';
        *temp = '\0';
    }
    if (!strncasecmp(string, "file:", 5))
        string = string + 5;
    start_session_from_name(string);
}

static GtkWidget *filesel;

static void on_filename_selected (GtkFileSelection *selector, 
				  gpointer user_data) 
{
  const gchar *name;

  name = gtk_file_selection_get_filename(GTK_FILE_SELECTION(filesel));
  start_session_from_name(name);
}

/*
 * This is right out of the book...
 */
static void on_browse_button_clicked (GtkWidget *window, gpointer data)
{
  filesel = gtk_file_selection_new("Open Media file");
  if (last_file != NULL) {
    gtk_file_selection_set_filename(GTK_FILE_SELECTION(filesel), last_file);
  }
  gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(filesel));
  gtk_signal_connect (GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button),
		      "clicked", 
		      GTK_SIGNAL_FUNC(on_filename_selected), 
		      filesel);
                             
  /* Ensure that the dialog box is destroyed when the user clicks a button. */
     
  gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button),
			    "clicked", 
			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
			    GTK_OBJECT(filesel));

  gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button),
			    "clicked", 
			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
			    GTK_OBJECT(filesel));
  
  /* Display that dialog */
     
  gtk_widget_show (filesel);
  
}

static void on_playlist_child_selected (GtkWidget *window, gpointer data)
{
  gchar *entry = 
    gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry));
  if (strcmp(entry, "") == 0) 
    return;
  if (last_entry && strcmp(entry, last_entry) == 0) 
    return;
  start_session_from_name(entry);
}

static void on_play_list_selected (GtkWidget *window, gpointer data)
{
  gchar *entry = gtk_entry_get_text(GTK_ENTRY(window));
  start_session_from_name(entry);
}

static void on_play_clicked (GtkWidget *window, gpointer data)
{
  int ret;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(play_button)) == FALSE) {
    if (play_state == PLAYING) {
      toggle_button_adjust(play_button, TRUE);
    }
    return;
  }

  if (psptr == NULL)
    return;
  ret = 0;
  SDL_mutexP(command_mutex);
  switch (play_state) {
  case PAUSED:
    ret = psptr->play_all_media(FALSE);
    break;
  case STOPPED:
    ret = psptr->play_all_media(TRUE, 0.0);
    break;
  default:
    break;
  }
  if (ret == 0)
    adjust_gui_for_play();
  SDL_mutexV(command_mutex);
  if (ret != 0) {
    close_session();
    ShowMessage("Play error", "Error re-starting session");
  }
}

static void do_pause (void)
{
  SDL_mutexP(command_mutex);
  if (psptr != NULL && play_state == PLAYING) {
    play_state = PAUSED;
    toggle_button_adjust(play_button, FALSE);
    toggle_button_adjust(pause_button, TRUE);
    psptr->pause_all_media();
  } else {
    toggle_button_adjust(pause_button, play_state == PAUSED);
  }
  SDL_mutexV(command_mutex);
}
static void on_pause_clicked (GtkWidget *window, gpointer data)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -