1.1 --- a/gmyth/Makefile.am Wed Sep 27 00:08:03 2006 +0100
1.2 +++ b/gmyth/Makefile.am Thu Sep 28 15:41:06 2006 +0100
1.3 @@ -1,4 +1,4 @@
1.4 -SUBDIRS= src pixmaps
1.5 +SUBDIRS= src
1.6
1.7 ### all of the standard pc files we need to generate
1.8 pcfiles = gmyth-@GMYTH_MAJORMINOR@.pc
2.1 --- a/gmyth/configure.ac Wed Sep 27 00:08:03 2006 +0100
2.2 +++ b/gmyth/configure.ac Thu Sep 28 15:41:06 2006 +0100
2.3 @@ -111,45 +111,10 @@
2.4 AC_SUBST(GOBJECT_CFLAGS)
2.5 AC_SUBST(GOBJECT_LIBS)
2.6
2.7 -# Check for GTK+-2.0
2.8 -PKG_CHECK_MODULES(GTK, gtk+-2.0, HAVE_GTK=yes,HAVE_GTK=no)
2.9 -
2.10 -# Give error and exit if we don't have gtk
2.11 -if test "x$HAVE_GTK" = "xyes"; then
2.12 - AC_DEFINE(WITH_GTK, 1, [build with GTK+ related stuff])
2.13 - dnl AC_MSG_ERROR(you need gtk+-2.0 installed)
2.14 -else
2.15 - AC_MSG_RESULT(no)
2.16 -fi
2.17 -
2.18 -AM_CONDITIONAL(WITH_GTK, test "x$HAVE_GTK" = "xyes" )
2.19 -
2.20 -# make GTK_CFLAGS and GTK_LIBS available
2.21 -AC_SUBST(GTK_CFLAGS)
2.22 -AC_SUBST(GTK_LIBS)
2.23 -
2.24 -dnl ========== Check for Hildon Libraries
2.25 -PKG_CHECK_MODULES(HILDON,
2.26 - hildon-lgpl libosso hildon-status-bar-lib libhildonmenu hildon-base-lib hildon-control-panel hildon-libs,
2.27 - HAVE_HILDON=yes, HAVE_HILDON=no)
2.28 -
2.29 -if test "x$HAVE_HILDON" = "xyes"; then
2.30 - AC_DEFINE(MAEMO_PLATFORM, 1, [build with hildon libs])
2.31 - HILDON_CFLAGS="$HILDON_CFLAGS -DMAEMO_PLATFORM=1"
2.32 -else
2.33 - AC_MSG_RESULT(no)
2.34 -fi
2.35 -
2.36 -AM_CONDITIONAL(MAEMO_PLATFORM, test "x$HAVE_HILDON" = "xyes")
2.37 -
2.38 -dnl make HILDON_CFLAGS and HILDON_LIBS available
2.39 -AC_SUBST(HILDON_CFLAGS)
2.40 -AC_SUBST(HILDON_LIBS)
2.41 -
2.42 # Check for libxml-2.0
2.43 PKG_CHECK_MODULES(LIBXML, libxml-2.0, HAVE_LIBXML=yes,HAVE_LIBXML=no)
2.44
2.45 -# Give error and exit if we don't have gtk
2.46 +# Give error and exit if we don't have libxml
2.47 if test "x$HAVE_LIBXML" = "xno"; then
2.48 AC_MSG_ERROR(you need libxml-2.0 installed)
2.49 fi
2.50 @@ -216,9 +181,6 @@
2.51
2.52
2.53 AC_CONFIG_FILES([Makefile
2.54 - pixmaps/Makefile
2.55 src/Makefile
2.56 - src/libgmyth/Makefile
2.57 - src/gui/Makefile
2.58 - gmyth.pc])
2.59 + gmyth.pc])
2.60 AC_OUTPUT
3.1 --- a/gmyth/m4/Makefile.am Wed Sep 27 00:08:03 2006 +0100
3.2 +++ b/gmyth/m4/Makefile.am Thu Sep 28 15:41:06 2006 +0100
3.3 @@ -1,7 +1,10 @@
3.4 -EXTRA_DIST = \
3.5 - ac_doxygen.m4 \
3.6 - as-compiler-flag.m4 \
3.7 - as-expand.m4 \
3.8 - as-version.m4 \
3.9 - as-gtk-doc.m4
3.10 +SUBDIRS= src pixmaps
3.11
3.12 +include aminclude.am
3.13 +
3.14 +EXTRA_DIST = \
3.15 + autogen.sh \
3.16 + AUTHORS \
3.17 + COPYING \
3.18 + README
3.19 +
4.1 --- a/gmyth/pixmaps/Makefile.am Wed Sep 27 00:08:03 2006 +0100
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,11 +0,0 @@
4.4 -# Adding the application icon
4.5 -#icondir = $(datadir)/mmyth/pixmaps
4.6 -#icon_DATA = \
4.7 -# mmyth.png
4.8 -
4.9 -
4.10 -# Adding the application resources
4.11 -pixmapdir = $(pkgdatadir)/pixmaps
4.12 -pixmap_DATA = mmyth_logo.png
4.13 -
4.14 -EXTRA_DIST = $(pixmap_DATA)
5.1 Binary file gmyth/pixmaps/mmyth_logo.png has changed
6.1 --- a/gmyth/src/Makefile.am Wed Sep 27 00:08:03 2006 +0100
6.2 +++ b/gmyth/src/Makefile.am Thu Sep 28 15:41:06 2006 +0100
6.3 @@ -1,29 +1,56 @@
6.4 -SUBDIRS = libgmyth gui .
6.5 +SUBDIRS = .
6.6
6.7 -bin_PROGRAMS = mmyth
6.8 +lib_LTLIBRARIES = libgmyth.la
6.9
6.10 -mmyth_SOURCES = mmyth_main.c
6.11 +libgmyth_la_SOURCES = \
6.12 + gmyth_common.c \
6.13 + gmyth_context.c \
6.14 + gmyth_epg.c \
6.15 + gmyth_remote_encoder.c \
6.16 + gmyth_remote_util.c \
6.17 + gmyth_settings.c \
6.18 + gmyth_tvchain.c \
6.19 + gmyth_scheduler.c \
6.20 + gmyth_util.c \
6.21 + gmyth_query.c \
6.22 + gmyth_socket.c \
6.23 + gmyth_stringlist.c
6.24
6.25 -mmyth_CFLAGS = \
6.26 - $(GTK_CFLAGS) \
6.27 - $(GLIB_CFLAGS) \
6.28 - $(GST_CFLAGS) \
6.29 - $(MYSQL_CFLAGS) \
6.30 - -g3 -O0 \
6.31 - -I$(top_srcdir)/src/libgmyth \
6.32 - -I$(top_srcdir)/src/gui \
6.33 - -DDATA_DIR=\""$(pkgdatadir)"\" \
6.34 - -DPIX_DIR=\""$(pkgdatadir)/pixmaps/"\" \
6.35 - -DESG_DIR=\""$(pkgdatadir)/pixmaps/"\" \
6.36 - -DICON_DIR=\""$(pkgdatadir)/pixmaps/"\"
6.37 +libgmyth_la_CFLAGS = \
6.38 + -DDATADIR=\"$(pkgdatadir)\" \
6.39 + $(GLIB_CFLAGS) \
6.40 + $(GOBJECT_CFLAGS) \
6.41 + $(GST_CFLAGS) \
6.42 + $(GSTBASE_CFLAGS) \
6.43 + $(MYSQL_CFLAGS) \
6.44 + -g3 -O0
6.45
6.46 -mmyth_LDFLAGS =
6.47 +#libgmyth_la_LIBADD = \
6.48 +# $(MYSQL_LIBS)
6.49
6.50 -mmyth_LDADD = \
6.51 - $(GTK_LIBS) \
6.52 - $(GLIB_LIBS) \
6.53 - $(GST_LIBS) \
6.54 - $(GSTBASE_LIBS) \
6.55 - $(HILDON_LIBS) \
6.56 - $(top_srcdir)/src/libgmyth/libgmyth.la \
6.57 - $(top_srcdir)/src/gui/libmmythgui.la
6.58 +libgmyth_la_LDFLAGS = \
6.59 + -export-dynamic \
6.60 + -lgstinterfaces-0.10 \
6.61 + $(MYSQL_LIBS) \
6.62 + $(GST_LIBS) \
6.63 + $(GSTBASE_LIBS)
6.64 +
6.65 +libgmyth_includedir = \
6.66 + $(pkgincludedir)
6.67 +
6.68 +libgmyth_include_HEADERS = \
6.69 + gmyth_common.h \
6.70 + gmyth_context.h \
6.71 + gmyth_epg.h \
6.72 + gmyth_remote_encoder.h \
6.73 + gmyth_scheduler.h \
6.74 + gmyth_settings.h \
6.75 + gmyth_tvchain.h \
6.76 + gmyth_util.h \
6.77 + gmyth_query.h \
6.78 + gmyth_socket.h \
6.79 + gmyth_remote_util.h \
6.80 + gmyth_stringlist.h
6.81 +
6.82 +CLEANFILES = $(BUILT_SOURCES)
6.83 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/gmyth/src/gmyth_common.c Thu Sep 28 15:41:06 2006 +0100
7.3 @@ -0,0 +1,85 @@
7.4 +/**
7.5 + * GMyth Library
7.6 + *
7.7 + * @file gmyth/gmyth_common.c
7.8 + *
7.9 + * @brief <p> This file contains basic common functions for the gmyth library.
7.10 + *
7.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
7.12 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
7.13 + *
7.14 + *//*
7.15 + *
7.16 + * This program is free software; you can redistribute it and/or modify
7.17 + * it under the terms of the GNU Lesser General Public License as published by
7.18 + * the Free Software Foundation; either version 2 of the License, or
7.19 + * (at your option) any later version.
7.20 + *
7.21 + * This program is distributed in the hope that it will be useful,
7.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.24 + * GNU General Public License for more details.
7.25 + *
7.26 + * You should have received a copy of the GNU Lesser General Public License
7.27 + * along with this program; if not, write to the Free Software
7.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7.29 + */
7.30 +
7.31 +#include "gmyth_common.h"
7.32 +
7.33 +static void free_channel_data(gpointer data, gpointer user_data);
7.34 +static void free_program_data(gpointer data, gpointer user_data);
7.35 +
7.36 +/** Frees the memory allocated to the GMythChannelInfo objects inside list.
7.37 + * The list memory is also released by g_list_free(). If LIST is NULL it
7.38 + * simply returns.
7.39 + *
7.40 + * @param list the GList containing a list of GMythChannelInfo to free.
7.41 + */
7.42 +void
7.43 +gmyth_free_channel_list(GList *list)
7.44 +{
7.45 + if (list == NULL) {
7.46 + g_warning ("%s received null GList as parameter", __FUNCTION__);
7.47 + return;
7.48 + }
7.49 +
7.50 + g_list_foreach (list, free_channel_data, NULL);
7.51 +
7.52 + g_list_free (list);
7.53 +}
7.54 +
7.55 +/** Frees the memory allocated to the GMythProgramInfo objects inside list.
7.56 + * The list memory is also released by g_list_free(). If list is NULL it
7.57 + * simply returns.
7.58 + *
7.59 + * @param list the GList containing a list of GMythProgramInfo to free.
7.60 + */
7.61 +void
7.62 +gmyth_free_program_list(GList *list)
7.63 +{
7.64 + if (list == NULL) {
7.65 + g_warning ("%s received null GList as parameter", __FUNCTION__);
7.66 + return;
7.67 + }
7.68 +
7.69 + g_list_foreach (list, free_program_data, NULL);
7.70 +
7.71 + g_list_free (list);
7.72 +}
7.73 +
7.74 +
7.75 +static void
7.76 +free_channel_data(gpointer data, gpointer user_data)
7.77 +{
7.78 + if(data)
7.79 + g_free((GMythChannelInfo*) data);
7.80 +}
7.81 +
7.82 +static void
7.83 +free_program_data(gpointer data, gpointer user_data)
7.84 +{
7.85 + if(data)
7.86 + g_free((GMythProgramInfo*) data);
7.87 +}
7.88 +
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/gmyth/src/gmyth_common.h Thu Sep 28 15:41:06 2006 +0100
8.3 @@ -0,0 +1,159 @@
8.4 +/**
8.5 + * GMyth Library
8.6 + *
8.7 + * @file gmyth/gmyth_common.h
8.8 + *
8.9 + * @brief <p> This file contains basic common functions for the gmyth library.
8.10 + *
8.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
8.12 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
8.13 + *
8.14 + *//*
8.15 + *
8.16 + * This program is free software; you can redistribute it and/or modify
8.17 + * it under the terms of the GNU Lesser General Public License as published by
8.18 + * the Free Software Foundation; either version 2 of the License, or
8.19 + * (at your option) any later version.
8.20 + *
8.21 + * This program is distributed in the hope that it will be useful,
8.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.24 + * GNU General Public License for more details.
8.25 + *
8.26 + * You should have received a copy of the GNU Lesser General Public License
8.27 + * along with this program; if not, write to the Free Software
8.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
8.29 + */
8.30 +
8.31 +#ifndef GMYTH_COMMON_H_
8.32 +#define GMYTH_COMMON_H_
8.33 +
8.34 +#include <glib.h>
8.35 +#include <time.h>
8.36 +
8.37 +G_BEGIN_DECLS
8.38 +
8.39 +/**
8.40 + * The GMythChannelInfo structure represents the channel information
8.41 + * stored in the backend database.
8.42 + */
8.43 +typedef struct {
8.44 + /** The channel ID in backend database */
8.45 + int channel_ID;
8.46 +
8.47 + /** The channel name in backend database */
8.48 + GString *channel_name;
8.49 +
8.50 +} GMythChannelInfo;
8.51 +
8.52 +
8.53 +/**
8.54 + * The GMythProgramInfo structure represents a program information
8.55 + * stored in the database. It could be a program from the EPG data,
8.56 + * a program scheduled to be recorded, or a program already recorded.
8.57 + */
8.58 +typedef struct {
8.59 +
8.60 + /** The channel unique ID. */
8.61 + GString *chanid;
8.62 +
8.63 + /** The program start time. */
8.64 + time_t startts;
8.65 + /** The program end time. */
8.66 + time_t endts;
8.67 + /** The recording schedule start time. */
8.68 + time_t recstartts;
8.69 + /** The recording schedule end time */
8.70 + time_t recendts;
8.71 +
8.72 + /** The program title. */
8.73 + GString *title;
8.74 + /** The program subtitle. */
8.75 + GString *subtitle;
8.76 + /** The program description. */
8.77 + GString *description;
8.78 + /** The program category. */
8.79 + GString *category;
8.80 +
8.81 + GString *chanstr;
8.82 + GString *chansign;
8.83 + /** The associated channel name. */
8.84 + GString *channame;
8.85 + int chancommfree;
8.86 + GString *chanOutputFilters;
8.87 +
8.88 + GString *seriesid;
8.89 + /** The program unique id. */
8.90 + GString *programid;
8.91 + GString * catType;
8.92 +
8.93 + GString * sortTitle;
8.94 +
8.95 + /** A flag informing if the program has video or not. */
8.96 + gboolean isVideo;
8.97 + int lenMins;
8.98 +
8.99 + GString *year;
8.100 + double stars;
8.101 + int repeat;
8.102 +
8.103 + time_t originalAirDate;
8.104 + time_t lastmodified;
8.105 + time_t lastInUseTime;
8.106 +
8.107 + gboolean hasAirDate;
8.108 +
8.109 + int spread;
8.110 + int startCol;
8.111 +
8.112 +// enum RecStatusType recstatus;
8.113 +// enum RecStatusType oldrecstatus;
8.114 +// enum RecStatusType savedrecstatus;
8.115 + int recpriority2;
8.116 + int reactivate;
8.117 +
8.118 + int recordid;
8.119 + int parentid;
8.120 + //enum RecordingType rectype;
8.121 + //enum RecordingDupInType dupin;
8.122 + //enum RecordingDupMethodType dupmethod;
8.123 +
8.124 + /** The backend video source id associated to this program.*/
8.125 + int sourceid;
8.126 + /** the backend input id associated to this program.*/
8.127 + int inputid;
8.128 + /** The backend card id associated to this program.*/
8.129 + int cardid;
8.130 + gboolean shareable;
8.131 + gboolean duplicate;
8.132 +
8.133 + GString * schedulerid;
8.134 + int findid;
8.135 +
8.136 + int programflags;
8.137 + int transcoder;
8.138 +
8.139 + //proginfo->spread = -1;
8.140 + //proginfo->programflags = proginfo->getProgramFlags();
8.141 +
8.142 + GString *recgroup;
8.143 + GString *playgroup;
8.144 + int recpriority;
8.145 +
8.146 + /** The file size of the recorded program.*/
8.147 + long long filesize;
8.148 + /** The file name of the recorded program.*/
8.149 + GString *pathname;
8.150 + GString *hostname;
8.151 +
8.152 + /* AvailableStatusType availableStatus;*/
8.153 +
8.154 +} GMythProgramInfo;
8.155 +
8.156 +
8.157 +void gmyth_free_channel_list(GList *list);
8.158 +void gmyth_free_program_list(GList *list);
8.159 +
8.160 +G_END_DECLS
8.161 +
8.162 +#endif /* GMYTH_COMMON_H_ */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/gmyth/src/gmyth_context.c Thu Sep 28 15:41:06 2006 +0100
9.3 @@ -0,0 +1,312 @@
9.4 +/**
9.5 + * GMyth Library
9.6 + *
9.7 + * @file gmyth/gmyth_context.c
9.8 + *
9.9 + * @brief <p> GMythContext class contains general attributes and functions
9.10 + * that express the connection state of each mythtvfrontend.
9.11 + *
9.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
9.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
9.14 + *
9.15 + *//*
9.16 + *
9.17 + * This program is free software; you can redistribute it and/or modify
9.18 + * it under the terms of the GNU Lesser General Public License as published by
9.19 + * the Free Software Foundation; either version 2 of the License, or
9.20 + * (at your option) any later version.
9.21 + *
9.22 + * This program is distributed in the hope that it will be useful,
9.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.25 + * GNU General Public License for more details.
9.26 + *
9.27 + * You should have received a copy of the GNU Lesser General Public License
9.28 + * along with this program; if not, write to the Free Software
9.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
9.30 + */
9.31 +
9.32 +#include "gmyth_context.h"
9.33 +
9.34 +#include <arpa/inet.h>
9.35 +#include <sys/types.h>
9.36 +#include <sys/socket.h>
9.37 +#include <netdb.h>
9.38 +#include <errno.h>
9.39 +#include <stdlib.h>
9.40 +
9.41 +#include "gmyth_query.h"
9.42 +#include "gmyth_socket.h"
9.43 +
9.44 +static void gmyth_context_class_init (GMythContextClass *klass);
9.45 +static void gmyth_context_init (GMythContext *object);
9.46 +
9.47 +static void gmyth_context_dispose (GObject *object);
9.48 +static void gmyth_context_finalize (GObject *object);
9.49 +
9.50 +
9.51 +G_DEFINE_TYPE(GMythContext, gmyth_context, G_TYPE_OBJECT)
9.52 +
9.53 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
9.54 +
9.55 +static GMythContext *gcontext = NULL;
9.56 +
9.57 +static void
9.58 +gmyth_context_class_init (GMythContextClass *klass)
9.59 +{
9.60 + GObjectClass *gobject_class;
9.61 +
9.62 + gobject_class = (GObjectClass *) klass;
9.63 +
9.64 + gobject_class->dispose = gmyth_context_dispose;
9.65 + gobject_class->finalize = gmyth_context_finalize;
9.66 +}
9.67 +
9.68 +static void
9.69 +gmyth_context_init (GMythContext *gmyth_context)
9.70 +{
9.71 +
9.72 +}
9.73 +
9.74 +static void
9.75 +gmyth_context_dispose (GObject *object)
9.76 +{
9.77 + GMythContext *gmyth_context = GMYTH_CONTEXT(object);
9.78 +
9.79 + if ( gmyth_context->gmyth_settings != NULL ) {
9.80 + g_object_unref (gmyth_context->gmyth_settings);
9.81 + gmyth_context->gmyth_settings = NULL;
9.82 + }
9.83 +
9.84 + if ( gmyth_context->localhostname != NULL ) {
9.85 + g_string_free ( gmyth_context->localhostname, TRUE );
9.86 + gmyth_context->localhostname = NULL;
9.87 + }
9.88 +
9.89 + if (gmyth_context->server_socket != NULL) {
9.90 + g_object_unref (gmyth_context->server_socket);
9.91 + gmyth_context->server_socket = NULL;
9.92 + }
9.93 +
9.94 + G_OBJECT_CLASS (gmyth_context_parent_class)->dispose (object);
9.95 +}
9.96 +
9.97 +static void
9.98 +gmyth_context_finalize (GObject *object)
9.99 +{
9.100 + g_signal_handlers_destroy (object);
9.101 +
9.102 + G_OBJECT_CLASS (gmyth_context_parent_class)->finalize (object);
9.103 +}
9.104 +
9.105 +/** Gets the some important address translation info,
9.106 + * from the client socket that will open a connection.
9.107 + *
9.108 + * @return gint error number
9.109 + */
9.110 +static gint
9.111 +myth_context_toaddrinfo( gchar *addr, gint port, struct addrinfo **addrInfo )
9.112 +{
9.113 + struct addrinfo hints;
9.114 + gchar *portStr = g_strnfill( 32, ' ' );
9.115 + gint errorn = EADDRNOTAVAIL;
9.116 +
9.117 + memset( &hints, 0, sizeof(hints) );
9.118 + hints.ai_family = AF_INET;
9.119 + hints.ai_socktype = SOCK_STREAM;
9.120 +
9.121 + /* hints.ai_flags = AI_NUMERICHOST; */
9.122 + if ( port != -1 )
9.123 + sprintf(portStr, "%d", port);
9.124 + else
9.125 + portStr = NULL;
9.126 +
9.127 + g_debug( "[%s] Address: %s, port: %s\n", __FUNCTION__, addr, portStr );
9.128 + if ( ( errorn = getaddrinfo(addr, portStr, &hints, addrInfo) ) != 0 ) {
9.129 + g_printerr( "[%s] Socket ERROR: %s\n", __FUNCTION__, gai_strerror(errorn) );
9.130 + }
9.131 +
9.132 + return errorn;
9.133 +
9.134 +}
9.135 +
9.136 +/** Initializes the GMythContext object. It reads local system information
9.137 + * load gmyth user settings and start connection to the database.
9.138 + *
9.139 + * @return TRUE if initialization was successfull,
9.140 + * FALSE if any error happens.
9.141 + */
9.142 +gboolean
9.143 +gmyth_context_initialize ()
9.144 +{
9.145 + GString *localhost = NULL;
9.146 +
9.147 + if (gcontext == NULL) {
9.148 + gcontext = GMYTH_CONTEXT ( g_object_new (GMYTH_CONTEXT_TYPE, FALSE));
9.149 + }
9.150 +
9.151 + localhost = gmyth_socket_get_local_hostname( );
9.152 +
9.153 + if (localhost==NULL || localhost->len <=0 ) {
9.154 + g_warning ("[%s] Could not determine local hostname. Setting to 127.0.0.1", __FUNCTION__);
9.155 + gcontext->localhostname = g_string_new ("127.0.0.1");
9.156 + } else {
9.157 + gcontext->localhostname = localhost;
9.158 + }
9.159 +
9.160 + if (gcontext->gmyth_settings) {
9.161 + g_object_unref (gcontext->gmyth_settings);
9.162 + gcontext->gmyth_settings = NULL;
9.163 + }
9.164 +
9.165 + gcontext->gmyth_settings = gmyth_settings_new ();
9.166 + if (!gmyth_settings_load (gcontext->gmyth_settings)) {
9.167 + g_warning ("GMythContext: Settings file not opened!\n");
9.168 + } else {
9.169 + g_debug ("GMythContext: Settings file loaded");
9.170 + }
9.171 +
9.172 + if (gcontext->server_socket != NULL) {
9.173 + g_object_unref (gcontext->server_socket);
9.174 + gcontext->server_socket = NULL;
9.175 + }
9.176 +
9.177 + GString *server_hostname =
9.178 + gmyth_settings_get_backend_hostname(gcontext->gmyth_settings);
9.179 + int server_port = gmyth_settings_get_backend_port(gcontext->gmyth_settings);
9.180 +
9.181 + gcontext->server_socket = gmyth_socket_new ();
9.182 + if (!gmyth_socket_connect_to_backend (gcontext->server_socket,
9.183 + server_hostname->str, server_port, FALSE)) {
9.184 + g_warning ("[%s] Socket connection to backend error!", __FUNCTION__);
9.185 + g_object_unref (gcontext->server_socket);
9.186 + gcontext->server_socket = NULL;
9.187 + return FALSE;
9.188 + }
9.189 +
9.190 + return TRUE;
9.191 +}
9.192 +
9.193 +/** Formats a Mythtv protocol command based on strlist and sends it to
9.194 + * the connected backend. The backend response is overwritten into strlist.
9.195 + *
9.196 + * @param strlist the string list to be sent,
9.197 + * and on which the answer will be written.
9.198 + * @return TRUE if command was sent and an answer was received, FALSE if any
9.199 + * error happens.
9.200 + */
9.201 +gboolean
9.202 +gmyth_context_send_receive_stringlist (GMythStringList *strlist)
9.203 +{
9.204 + gint ok = -1;
9.205 +
9.206 + if (!gcontext || !(gcontext->server_socket)) {
9.207 + g_warning ("[%s] GMythContext not initialized", __FUNCTION__);
9.208 + return FALSE;
9.209 + }
9.210 +
9.211 + //g_static_mutex_lock( &mutex );
9.212 +
9.213 + ok = gmyth_socket_sendreceive_stringlist (gcontext->server_socket, strlist);
9.214 +
9.215 + //g_static_mutex_unlock( &mutex );
9.216 +
9.217 + if (!ok) {
9.218 + g_warning ("Connection to backend server lost");
9.219 + }
9.220 +
9.221 + return (ok ? TRUE : FALSE);
9.222 +}
9.223 +
9.224 +/** Gets the GMythSettings object associated to this context.
9.225 + *
9.226 + * @return The GMythSettings object currently valid or NULL if the settings
9.227 + * were not opened.
9.228 + */
9.229 +GMythSettings*
9.230 +gmyth_context_get_settings ()
9.231 +{
9.232 + if (!gcontext) {
9.233 + g_warning ("[%s] GMythContext not initialized\n", __FUNCTION__);
9.234 + return NULL;
9.235 + }
9.236 +
9.237 + return gcontext->gmyth_settings;
9.238 +}
9.239 +
9.240 +/** Gets the machine local hostname.
9.241 + *
9.242 + * @param hostname a valid GString object to be overwritten with the local
9.243 + * hostname.
9.244 + * @return true if the hostname was read, false if any error happened.
9.245 + */
9.246 +gboolean
9.247 +gmyth_context_get_local_hostname (GString *hostname)
9.248 +{
9.249 + if (!hostname) {
9.250 + g_warning ("[%s] Received null argument", __FUNCTION__);
9.251 + return FALSE;
9.252 + }
9.253 +
9.254 + g_string_assign (hostname, gcontext->localhostname->str);
9.255 +
9.256 + return TRUE;
9.257 +}
9.258 +
9.259 +/** Gets a setting information from the backend mysql database.
9.260 + *
9.261 + * @param key The setting key to be retrieved.
9.262 + * @param host the hostname associated to the desired setting.
9.263 + * @param default_value the default setting value if could not query from
9.264 + * backend database.
9.265 + * @return The setting value loaded from database, or the given default value
9.266 + * if the query fails.
9.267 + */
9.268 +GString*
9.269 +gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value)
9.270 +{
9.271 + GString *query_str;
9.272 +
9.273 + // TODO: Reuse msql query in gmyth_context
9.274 + GMythQuery *gmyth_query = gmyth_query_new ();
9.275 +
9.276 + if (gmyth_query_connect (gmyth_query)) {
9.277 + MYSQL_RES *msql_res;
9.278 + MYSQL_ROW msql_row;
9.279 +
9.280 + query_str = g_string_new ("");
9.281 + g_string_printf (query_str, "SELECT data FROM settings WHERE value = \"%s\" "
9.282 + "AND hostname = \"%s\" ;", key->str, host->str);
9.283 +
9.284 + msql_res = gmyth_query_process_statement (gmyth_query, query_str->str);
9.285 + if (msql_res) {
9.286 + msql_row = mysql_fetch_row (msql_res);
9.287 + if (msql_row != NULL) {
9.288 + return g_string_new (msql_row[0]);
9.289 + }
9.290 + }
9.291 +
9.292 + g_object_unref (gmyth_query);
9.293 + } else {
9.294 + g_warning ("Database not open while trying to load setting: %s", key->str);
9.295 + }
9.296 +
9.297 +
9.298 + return default_value;
9.299 +}
9.300 +
9.301 +/** Verify if the context is currently connected to a backend.
9.302 + *
9.303 + * @return true if connection was opened, false if not.
9.304 + */
9.305 +gboolean
9.306 +gmyth_context_check_connection ()
9.307 +{
9.308 + // FIXME: Check this based on socket states
9.309 + if (!gcontext) {
9.310 + g_warning ("[%s] GMythContext not initialized", __FUNCTION__);
9.311 + return FALSE;
9.312 + }
9.313 +
9.314 + return (gcontext->server_socket != NULL);
9.315 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/gmyth/src/gmyth_context.h Thu Sep 28 15:41:06 2006 +0100
10.3 @@ -0,0 +1,88 @@
10.4 +/**
10.5 + * GMyth Library
10.6 + *
10.7 + * @file gmyth/gmyth_context.h
10.8 + *
10.9 + * @brief <p> GMythContext class contains general attributes and functions
10.10 + * that express the connection state of each mythtvfrontend.
10.11 + *
10.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
10.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
10.14 + *
10.15 + *//*
10.16 + *
10.17 + * This program is free software; you can redistribute it and/or modify
10.18 + * it under the terms of the GNU Lesser General Public License as published by
10.19 + * the Free Software Foundation; either version 2 of the License, or
10.20 + * (at your option) any later version.
10.21 + *
10.22 + * This program is distributed in the hope that it will be useful,
10.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.25 + * GNU General Public License for more details.
10.26 + *
10.27 + * You should have received a copy of the GNU Lesser General Public License
10.28 + * along with this program; if not, write to the Free Software
10.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10.30 + */
10.31 +
10.32 +#ifndef __GMYTH_CONTEXT_H__
10.33 +#define __GMYTH_CONTEXT_H__
10.34 +
10.35 +#include <glib-object.h>
10.36 +
10.37 +#include "gmyth_settings.h"
10.38 +#include "gmyth_socket.h"
10.39 +#include "gmyth_stringlist.h"
10.40 +
10.41 +G_BEGIN_DECLS
10.42 +
10.43 +#define GMYTH_CONTEXT_TYPE (gmyth_context_get_type ())
10.44 +#define GMYTH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_CONTEXT_TYPE, GMythContext))
10.45 +#define GMYTH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_CONTEXT_TYPE, GMythContextClass))
10.46 +#define IS_GMYTH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_CONTEXT_TYPE))
10.47 +#define IS_GMYTH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_CONTEXT_TYPE))
10.48 +#define GMYTH_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_CONTEXT_TYPE, GMythContextClass))
10.49 +
10.50 +#define MYTHTV_VERSION_DEFAULT 30
10.51 +
10.52 +typedef struct _GMythContext GMythContext;
10.53 +typedef struct _GMythContextClass GMythContextClass;
10.54 +
10.55 +struct _GMythContextClass
10.56 +{
10.57 + GObjectClass parent_class;
10.58 +
10.59 + /* callbacks */
10.60 + /* no one for now */
10.61 +};
10.62 +
10.63 +struct _GMythContext
10.64 +{
10.65 + GObject parent;
10.66 +
10.67 + GMythSettings *gmyth_settings;
10.68 + GMythSocket *server_socket;
10.69 +
10.70 + GString *localhostname;
10.71 +};
10.72 +
10.73 +
10.74 +GType gmyth_context_get_type (void);
10.75 +void gmyth_context_create();
10.76 +
10.77 +gboolean gmyth_context_initialize ();
10.78 +gboolean gmyth_context_check_connection ();
10.79 +GMythSettings* gmyth_context_get_settings ();
10.80 +
10.81 +gboolean gmyth_context_send_receive_stringlist (GMythStringList *strlist);
10.82 +
10.83 +GString* gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value);
10.84 +gboolean gmyth_context_get_local_hostname (GString *hostname);
10.85 +
10.86 +GString* gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value);
10.87 +
10.88 +
10.89 +G_END_DECLS
10.90 +
10.91 +#endif /* __GMYTH_CONTEXT_H__ */
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/gmyth/src/gmyth_epg.c Thu Sep 28 15:41:06 2006 +0100
11.3 @@ -0,0 +1,278 @@
11.4 +/**
11.5 + * GMyth Library
11.6 + *
11.7 + * @file gmyth/gmyth_epg.c
11.8 + *
11.9 + * @brief <p> GMythEPG class provides access to the program and channel data
11.10 + * from the Electronic Program Guide (EPG) of the Mythtv backend.
11.11 + *
11.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
11.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
11.14 + *
11.15 + *//*
11.16 + *
11.17 + * This program is free software; you can redistribute it and/or modify
11.18 + * it under the terms of the GNU Lesser General Public License as published by
11.19 + * the Free Software Foundation; either version 2 of the License, or
11.20 + * (at your option) any later version.
11.21 + *
11.22 + * This program is distributed in the hope that it will be useful,
11.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.25 + * GNU General Public License for more details.
11.26 + *
11.27 + * You should have received a copy of the GNU Lesser General Public License
11.28 + * along with this program; if not, write to the Free Software
11.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
11.30 + */
11.31 +
11.32 +#include <mysql.h>
11.33 +#include <stdlib.h>
11.34 +#include <string.h>
11.35 +#include <assert.h>
11.36 +
11.37 +#include "gmyth_epg.h"
11.38 +#include "gmyth_util.h"
11.39 +
11.40 +static void gmyth_epg_class_init (GMythEPGClass *klass);
11.41 +static void gmyth_epg_init (GMythEPG *object);
11.42 +
11.43 +static void gmyth_epg_dispose (GObject *object);
11.44 +static void gmyth_epg_finalize (GObject *object);
11.45 +
11.46 +G_DEFINE_TYPE(GMythEPG, gmyth_epg, G_TYPE_OBJECT)
11.47 +
11.48 +static void
11.49 +gmyth_epg_class_init (GMythEPGClass *klass)
11.50 +{
11.51 + GObjectClass *gobject_class;
11.52 +
11.53 + gobject_class = (GObjectClass *) klass;
11.54 +
11.55 + gobject_class->dispose = gmyth_epg_dispose;
11.56 + gobject_class->finalize = gmyth_epg_finalize;
11.57 +}
11.58 +
11.59 +static void
11.60 +gmyth_epg_init (GMythEPG *gmyth_epg)
11.61 +{
11.62 + gmyth_epg->sqlquery = gmyth_query_new ();
11.63 +}
11.64 +
11.65 +static void
11.66 +gmyth_epg_dispose (GObject *object)
11.67 +{
11.68 + //GMythEPG *gmyth_epg = GMYTH_EPG(object);
11.69 +
11.70 + G_OBJECT_CLASS (gmyth_epg_parent_class)->dispose (object);
11.71 +}
11.72 +
11.73 +static void
11.74 +gmyth_epg_finalize (GObject *object)
11.75 +{
11.76 + g_signal_handlers_destroy (object);
11.77 +
11.78 + G_OBJECT_CLASS (gmyth_epg_parent_class)->finalize (object);
11.79 +}
11.80 +
11.81 +/**
11.82 + * Creates a new instance of GMythEPG.
11.83 + *
11.84 + * @return a new instance of GMythEPG.
11.85 + */
11.86 +GMythEPG*
11.87 +gmyth_epg_new (void)
11.88 +{
11.89 + GMythEPG *epg = GMYTH_EPG (g_object_new(GMYTH_EPG_TYPE, NULL));
11.90 +
11.91 + return epg;
11.92 +}
11.93 +
11.94 +/** Connects to the Mysql database in the backend. The backend address
11.95 + * is loaded from the GMythSettings instance.
11.96 + *
11.97 + * @param gmyth_epg the GMythEPG instance to be connected.
11.98 + * @return true if connection was success, false if failed.
11.99 + */
11.100 +gboolean
11.101 +gmyth_epg_connect (GMythEPG *gmyth_epg)
11.102 +{
11.103 + assert(gmyth_epg);
11.104 +
11.105 + if (gmyth_epg->sqlquery == NULL) {
11.106 + g_warning ("[%s] GMythEPG not initialized", __FUNCTION__);
11.107 + return FALSE;
11.108 + }
11.109 +
11.110 + if (!gmyth_query_connect(gmyth_epg->sqlquery)) {
11.111 + g_warning ("[%s] Error while connecting to db", __FUNCTION__);
11.112 + return FALSE;
11.113 + }
11.114 +
11.115 + return TRUE;
11.116 +}
11.117 +
11.118 +/** Disconnects from the Mysql database in the backend.
11.119 + *
11.120 + * @param gmyth_epg the GMythEPG instance to be disconnected
11.121 + * @return true if disconnection was success, false if failed.
11.122 + */
11.123 +gboolean
11.124 +gmyth_epg_disconnect (GMythEPG *gmyth_epg)
11.125 +{
11.126 + assert(gmyth_epg);
11.127 +
11.128 + if (gmyth_epg->sqlquery != NULL) {
11.129 + g_object_unref (gmyth_epg->sqlquery);
11.130 + }
11.131 +
11.132 + return TRUE;
11.133 +}
11.134 +
11.135 +/** Retrieves the available list of channels from the backend Mysql database.
11.136 + *
11.137 + * @param gmyth_epg the GMythEPG instance.
11.138 + * @param glist_ptr the GList pointer to be filled with the loaded list address.
11.139 + * @return The amount of channels retrieved from database, or -1 if error.
11.140 + */
11.141 +gint
11.142 +gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr)
11.143 +{
11.144 + MYSQL_RES *msql_res;
11.145 +
11.146 + assert(gmyth_epg);
11.147 +
11.148 + msql_res = gmyth_query_process_statement (gmyth_epg->sqlquery,
11.149 + "SELECT chanid,name FROM channel;");
11.150 +
11.151 + (*glist_ptr) = NULL;
11.152 +
11.153 + if (msql_res == NULL) {
11.154 + g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
11.155 + return -1;
11.156 + } else {
11.157 + MYSQL_ROW row;
11.158 + GMythChannelInfo *channel_info;
11.159 +
11.160 + while ((row = mysql_fetch_row (msql_res)) != NULL){
11.161 +
11.162 + channel_info = g_new0(GMythChannelInfo, 1);
11.163 + channel_info->channel_ID = atoi (row[0]);
11.164 + channel_info->channel_name = g_string_new (row[1]);
11.165 +
11.166 + (*glist_ptr) = g_list_append ((*glist_ptr), channel_info);
11.167 + }
11.168 + }
11.169 + mysql_free_result (msql_res);
11.170 + return (!(*glist_ptr)) ? 0 : g_list_length (*glist_ptr);
11.171 +}
11.172 +
11.173 +/**
11.174 + * Retrieves the available list of channels from the backend Mysql database.
11.175 + *
11.176 + * @param gmyth_epg the GMythEPG instance.
11.177 + * @param proglist the GList pointer to be filled with the loaded list.
11.178 + * @param chan_num the channel num on which to search for program.
11.179 + * @param starttime the start time to search for programs.
11.180 + * @param endtime the end time to search for programs.
11.181 + * @return The amount of channels retrieved from database, or -1 if error.
11.182 + */
11.183 +gint
11.184 +gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
11.185 + const gint chan_num, time_t starttime, time_t endtime)
11.186 +{
11.187 + GString *startts = gmyth_util_time_to_string(starttime);
11.188 + GString *endts = gmyth_util_time_to_string(endtime);
11.189 + MYSQL_ROW row;
11.190 + GString *querystr;
11.191 +
11.192 + assert(gmyth_epg);
11.193 +
11.194 + querystr = g_string_new(
11.195 + "SELECT DISTINCT program.chanid, program.starttime, program.endtime, "
11.196 + " program.title, program.subtitle, program.description, "
11.197 + " program.category, channel.channum, channel.callsign, "
11.198 + " channel.name, program.previouslyshown, channel.commfree, "
11.199 + " channel.outputfilters, program.seriesid, program.programid, "
11.200 + " program.airdate, program.stars, program.originalairdate, "
11.201 + " program.category_type, oldrecstatus.recordid, "
11.202 + " oldrecstatus.rectype, oldrecstatus.recstatus, "
11.203 + " oldrecstatus.findid "
11.204 + "FROM program "
11.205 + "LEFT JOIN channel ON program.chanid = channel.chanid "
11.206 + "LEFT JOIN oldrecorded AS oldrecstatus ON "
11.207 + " program.title = oldrecstatus.title AND "
11.208 + " channel.callsign = oldrecstatus.station AND "
11.209 + " program.starttime = oldrecstatus.starttime "
11.210 + );
11.211 +
11.212 + g_string_append_printf (querystr,
11.213 + "WHERE program.chanid = %d "
11.214 + " AND program.endtime >= '%s' "
11.215 + " AND program.starttime <= '%s' "
11.216 + " AND program.manualid = 0 ",
11.217 + chan_num, startts->str, endts->str);
11.218 +
11.219 + if (!g_strrstr(querystr->str, " GROUP BY "))
11.220 + querystr = g_string_append(querystr,
11.221 + " GROUP BY program.starttime, channel.channum, "
11.222 + " channel.callsign, program.title ");
11.223 +
11.224 + if (!g_strrstr(querystr->str, " LIMIT "))
11.225 + querystr = g_string_append(querystr, " LIMIT 1000 ");
11.226 +
11.227 + MYSQL_RES *res_set =
11.228 + gmyth_query_process_statement(gmyth_epg->sqlquery, querystr->str);
11.229 +
11.230 + if (res_set == NULL) {
11.231 + g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
11.232 + return -1;
11.233 + }
11.234 +
11.235 + (*proglist) = NULL;
11.236 + while ((row = mysql_fetch_row (res_set)) != NULL) {
11.237 +
11.238 + GMythProgramInfo *p = g_new0 (GMythProgramInfo, 1);
11.239 + p->chanid = g_string_new (row[0]);
11.240 +
11.241 + p->startts = gmyth_util_string_to_time (g_string_new (row[1]));
11.242 + p->endts = gmyth_util_string_to_time (g_string_new (row[2]));
11.243 +
11.244 + p->recstartts = p->startts;
11.245 + p->recendts = p->endts;
11.246 + p->lastmodified = p->startts;
11.247 +
11.248 + p->title = g_string_new (row[3]);
11.249 + p->subtitle = g_string_new (row[4]);
11.250 + p->description = g_string_new (row[5]);
11.251 + p->category = g_string_new (row[6]);
11.252 + p->chanstr = g_string_new (row[7]);
11.253 + p->chansign = g_string_new (row[8]);
11.254 + p->channame = g_string_new (row[9]);
11.255 + p->repeat = atoi(row[10]);
11.256 + p->chancommfree = atoi(row[11]);
11.257 + p->chanOutputFilters = g_string_new (row[12]);
11.258 + p->seriesid = g_string_new (row[13]);
11.259 + p->programid = g_string_new (row[14]);
11.260 + p->year = g_string_new (row[15]);
11.261 + p->stars = atof(row[16]);
11.262 +
11.263 + if (!row[17] || !strcmp(row[17], "")) {
11.264 + p->originalAirDate = 0;
11.265 + p->hasAirDate = FALSE;
11.266 + } else {
11.267 + p->originalAirDate = gmyth_util_string_to_time (g_string_new (row[17]));
11.268 + p->hasAirDate = TRUE;
11.269 + }
11.270 +
11.271 + p->catType = g_string_new (row[18]);
11.272 +
11.273 + *proglist = g_list_append((*proglist), p);
11.274 + }
11.275 +
11.276 + /* deallocate */
11.277 + mysql_free_result (res_set);
11.278 + g_string_free(querystr, TRUE);
11.279 +
11.280 + return TRUE;
11.281 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/gmyth/src/gmyth_epg.h Thu Sep 28 15:41:06 2006 +0100
12.3 @@ -0,0 +1,75 @@
12.4 +/**
12.5 + * GMyth Library
12.6 + *
12.7 + * @file gmyth/gmyth_epg.h
12.8 + *
12.9 + * @brief <p> GMythEPG class provides access to the program and channel data
12.10 + * from the Electronic Program Guide (EPG) of the Mythtv backend.
12.11 + *
12.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
12.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
12.14 + *
12.15 + *//*
12.16 + *
12.17 + * This program is free software; you can redistribute it and/or modify
12.18 + * it under the terms of the GNU Lesser General Public License as published by
12.19 + * the Free Software Foundation; either version 2 of the License, or
12.20 + * (at your option) any later version.
12.21 + *
12.22 + * This program is distributed in the hope that it will be useful,
12.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.25 + * GNU General Public License for more details.
12.26 + *
12.27 + * You should have received a copy of the GNU Lesser General Public License
12.28 + * along with this program; if not, write to the Free Software
12.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
12.30 + */
12.31 +
12.32 +#ifndef GMYTH_EPG_H_
12.33 +#define GMYTH_EPG_H_
12.34 +
12.35 +#include <glib-object.h>
12.36 +
12.37 +#include "gmyth_query.h"
12.38 +#include "gmyth_common.h"
12.39 +
12.40 +G_BEGIN_DECLS
12.41 +
12.42 +#define GMYTH_EPG_TYPE (gmyth_epg_get_type ())
12.43 +#define GMYTH_EPG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE, GMythEPG))
12.44 +#define GMYTH_EPG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE, GMythEPGClass))
12.45 +#define IS_GMYTH_EPG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE))
12.46 +#define IS_GMYTH_EPG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE))
12.47 +#define GMYTH_EPG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_EPG_TYPE, GMythEPGClass))
12.48 +
12.49 +typedef struct _GMythEPG GMythEPG;
12.50 +typedef struct _GMythEPGClass GMythEPGClass;
12.51 +
12.52 +struct _GMythEPGClass
12.53 +{
12.54 + GObjectClass parent_class;
12.55 +
12.56 + /* callbacks */
12.57 + /* no one for now */
12.58 +};
12.59 +
12.60 +struct _GMythEPG
12.61 +{
12.62 + GObject parent;
12.63 +
12.64 + GMythQuery *sqlquery;
12.65 +};
12.66 +
12.67 +GType gmyth_epg_get_type (void);
12.68 +
12.69 +GMythEPG* gmyth_epg_new (void);
12.70 +
12.71 +gboolean gmyth_epg_connect (GMythEPG *gmyth_epg);
12.72 +gboolean gmyth_epg_disconnect (GMythEPG *gmyth_epg);
12.73 +
12.74 +gint gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr);
12.75 +gint gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
12.76 + const gint chanNum, time_t starttime, time_t endtime);
12.77 +
12.78 +#endif /*GMYTH_EPG_H_*/
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/gmyth/src/gmyth_query.c Thu Sep 28 15:41:06 2006 +0100
13.3 @@ -0,0 +1,221 @@
13.4 +/**
13.5 + * GMyth Library
13.6 + *
13.7 + * @file gmyth/gmyth_query.c
13.8 + *
13.9 + * @brief <p> GMythQuery class provides a wrapper for accessing
13.10 + * the libmysqlclient funtions.
13.11 + *
13.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
13.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
13.14 + *
13.15 + *//*
13.16 + *
13.17 + * This program is free software; you can redistribute it and/or modify
13.18 + * it under the terms of the GNU Lesser General Public License as published by
13.19 + * the Free Software Foundation; either version 2 of the License, or
13.20 + * (at your option) any later version.
13.21 + *
13.22 + * This program is distributed in the hope that it will be useful,
13.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13.25 + * GNU General Public License for more details.
13.26 + *
13.27 + * You should have received a copy of the GNU Lesser General Public License
13.28 + * along with this program; if not, write to the Free Software
13.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13.30 + */
13.31 +
13.32 +#include <stdlib.h>
13.33 +#include <stdio.h>
13.34 +#include <assert.h>
13.35 +
13.36 +#include "gmyth_query.h"
13.37 +#include "gmyth_settings.h"
13.38 +#include "gmyth_context.h"
13.39 +
13.40 +static void gmyth_query_class_init (GMythQueryClass *klass);
13.41 +static void gmyth_query_init (GMythQuery *object);
13.42 +
13.43 +static void gmyth_query_dispose (GObject *object);
13.44 +static void gmyth_query_finalize (GObject *object);
13.45 +
13.46 +static void gmyth_query_print_error (MYSQL *conn, char *message);
13.47 +
13.48 +G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT)
13.49 +
13.50 +static void
13.51 +gmyth_query_class_init (GMythQueryClass *klass)
13.52 +{
13.53 + GObjectClass *gobject_class;
13.54 +
13.55 + gobject_class = (GObjectClass *) klass;
13.56 +
13.57 + gobject_class->dispose = gmyth_query_dispose;
13.58 + gobject_class->finalize = gmyth_query_finalize;
13.59 +}
13.60 +
13.61 +static void
13.62 +gmyth_query_init (GMythQuery *gmyth_query)
13.63 +{
13.64 + GMythSettings *gmyth_settings = gmyth_context_get_settings ();
13.65 +
13.66 + gmyth_query->opt_host_name = gmyth_settings_get_backend_hostname(gmyth_settings);
13.67 + gmyth_query->opt_user_name = gmyth_settings_get_username(gmyth_settings);
13.68 + gmyth_query->opt_password = gmyth_settings_get_password(gmyth_settings);
13.69 + gmyth_query->opt_db_name = gmyth_settings_get_dbname(gmyth_settings);
13.70 +
13.71 + /* initialize connection handler */
13.72 + gmyth_query->conn = mysql_init (NULL);
13.73 +
13.74 + if (!(gmyth_query->conn))
13.75 + g_warning ("[%s] MSQL structure not initialized", __FUNCTION__);
13.76 +
13.77 +}
13.78 +
13.79 +static void
13.80 +gmyth_query_dispose (GObject *object)
13.81 +{
13.82 + GMythQuery *gmyth_query = GMYTH_QUERY (object);
13.83 +
13.84 + /* disconnect from server */
13.85 + gmyth_query_disconnect (gmyth_query);
13.86 +
13.87 + G_OBJECT_CLASS (gmyth_query_parent_class)->dispose (object);
13.88 +}
13.89 +
13.90 +static void
13.91 +gmyth_query_finalize (GObject *object)
13.92 +{
13.93 + g_signal_handlers_destroy (object);
13.94 +
13.95 + G_OBJECT_CLASS (gmyth_query_parent_class)->finalize (object);
13.96 +}
13.97 +
13.98 +/** Creates a new instance of GMythQuery.
13.99 + *
13.100 + * @return a new instance of GMythQuery.
13.101 + */
13.102 +GMythQuery*
13.103 +gmyth_query_new ()
13.104 +{
13.105 + GMythQuery *sql_query = GMYTH_QUERY (g_object_new(GMYTH_QUERY_TYPE, NULL));
13.106 +
13.107 + return sql_query;
13.108 +}
13.109 +
13.110 +/** Connects to the Mysql database in the backend. The backend address
13.111 + * is loaded from the GMythSettings instance.
13.112 + *
13.113 + * @param gmyth_query the GMythEPG instance to be connected.
13.114 + * @return true if connection was success, false if failed.
13.115 + */
13.116 +gboolean
13.117 +gmyth_query_connect (GMythQuery *gmyth_query)
13.118 +{
13.119 + char *opt_host_name;
13.120 + char *opt_user_name;
13.121 + char *opt_password;
13.122 + char *opt_db_name;
13.123 +
13.124 + assert(gmyth_query);
13.125 +
13.126 + opt_host_name = (gmyth_query->opt_host_name ? gmyth_query->opt_host_name->str : NULL);
13.127 + opt_db_name = (gmyth_query->opt_db_name ? gmyth_query->opt_db_name->str : NULL);
13.128 + opt_user_name = (gmyth_query->opt_user_name ? gmyth_query->opt_user_name->str : NULL);
13.129 + opt_password = (gmyth_query->opt_password ? gmyth_query->opt_password->str : NULL);
13.130 +
13.131 +
13.132 + if (gmyth_query->conn == NULL) {
13.133 + gmyth_query_print_error (NULL, "mysql_init() failed (probably out of memory)");
13.134 + return FALSE;
13.135 + }
13.136 +
13.137 + /* connect to server */
13.138 + if (mysql_real_connect (gmyth_query->conn, opt_host_name,
13.139 + opt_user_name, opt_password, opt_db_name,
13.140 + 0, NULL, 0) == NULL) {
13.141 +
13.142 + gmyth_query_print_error (gmyth_query->conn, "mysql_real_connect() failed");
13.143 + return FALSE;
13.144 + }
13.145 +
13.146 + g_debug ("[%s] Connection to Mysql server succeeded!", __FUNCTION__);
13.147 +
13.148 + return TRUE;
13.149 +}
13.150 +
13.151 +/** Disconnects from the Mysql database in the backend.
13.152 + *
13.153 + * @param gmyth_query the GMythQuery instance to be disconnected
13.154 + * @return true if disconnection was success, false if failed.
13.155 + */
13.156 +gboolean
13.157 +gmyth_query_disconnect (GMythQuery *gmyth_query)
13.158 +{
13.159 + assert(gmyth_query);
13.160 +
13.161 + /* TODO: Check how to return error */
13.162 + g_debug ("[%s] Closing gmyth_query->conn", __FUNCTION__);
13.163 + mysql_close (gmyth_query->conn);
13.164 +
13.165 + return TRUE;
13.166 +}
13.167 +
13.168 +static void
13.169 +gmyth_query_print_error (MYSQL *conn, char *message)
13.170 +{
13.171 + fprintf (stderr, "%s\n", message);
13.172 +
13.173 + if (conn != NULL) {
13.174 +#if MYSQL_VERSION_ID >= 40101
13.175 + fprintf (stderr, "Error %u (%s): %s\n",
13.176 + mysql_errno (conn), mysql_sqlstate(conn), mysql_error (conn));
13.177 +#else
13.178 + fprintf (stderr, "Error %u: %s\n",
13.179 + mysql_errno (conn), mysql_error (conn));
13.180 +#endif
13.181 + }
13.182 +}
13.183 +
13.184 +/** Sends the given query to the backend returning the query result as
13.185 + * MYSQL_RES pointer.
13.186 + *
13.187 + * FIXME: this function is returning NULL whether any error happens
13.188 + * or no rows are returned (e.g. UPDATE or REPLACE).
13.189 + *
13.190 + * @param gmyth_query the GMythQuery instance.
13.191 + * @param stmt_str the query text.
13.192 + * @return the MYSQL_RES result pointer or NULL if any error happens.
13.193 + */
13.194 +MYSQL_RES*
13.195 +gmyth_query_process_statement (GMythQuery *gmyth_query, char *stmt_str)
13.196 +{
13.197 + MYSQL_RES *res_set;
13.198 +
13.199 + assert(gmyth_query);
13.200 +
13.201 + g_debug ("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
13.202 +
13.203 + if (gmyth_query == NULL)
13.204 + return NULL;
13.205 +
13.206 + /* the statement failed */
13.207 + if (mysql_query (gmyth_query->conn, stmt_str) != 0) {
13.208 + gmyth_query_print_error (gmyth_query->conn, "Could not execute statement");
13.209 + return NULL;
13.210 + }
13.211 +
13.212 + /* the statement succeeded; determine whether it returned data */
13.213 + res_set = mysql_store_result (gmyth_query->conn);
13.214 + if (res_set) {
13.215 + return res_set;
13.216 + } else if (mysql_field_count (gmyth_query->conn) == 0) {
13.217 + g_debug ("%lu rows affected\n",
13.218 + (unsigned long) mysql_affected_rows (gmyth_query->conn));
13.219 + } else {
13.220 + gmyth_query_print_error (gmyth_query->conn, "Could not retrieve result set");
13.221 + }
13.222 +
13.223 + return NULL;
13.224 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/gmyth/src/gmyth_query.h Thu Sep 28 15:41:06 2006 +0100
14.3 @@ -0,0 +1,84 @@
14.4 +/**
14.5 + * GMyth Library
14.6 + *
14.7 + * @file gmyth/gmyth_query.h
14.8 + *
14.9 + * @brief <p> GMythQuery class provides a wrapper for accessing
14.10 + * the libmysqlclient funtions.
14.11 + *
14.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
14.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
14.14 + *
14.15 + *//*
14.16 + *
14.17 + * This program is free software; you can redistribute it and/or modify
14.18 + * it under the terms of the GNU Lesser General Public License as published by
14.19 + * the Free Software Foundation; either version 2 of the License, or
14.20 + * (at your option) any later version.
14.21 + *
14.22 + * This program is distributed in the hope that it will be useful,
14.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.25 + * GNU General Public License for more details.
14.26 + *
14.27 + * You should have received a copy of the GNU Lesser General Public License
14.28 + * along with this program; if not, write to the Free Software
14.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14.30 + */
14.31 +
14.32 +#ifndef __GMYTH_QUERY_H__
14.33 +#define __GMYTH_QUERY_H__
14.34 +
14.35 +#include <glib-object.h>
14.36 +
14.37 +/* MYSQL includes */
14.38 +#include <mysql.h>
14.39 +
14.40 +G_BEGIN_DECLS
14.41 +
14.42 +#define GMYTH_QUERY_TYPE (gmyth_query_get_type ())
14.43 +#define GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE, GMythQuery))
14.44 +#define GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE, GMythQueryClass))
14.45 +#define IS_GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE))
14.46 +#define IS_GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE))
14.47 +#define GMYTH_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_QUERY_TYPE, GMythQueryClass))
14.48 +
14.49 +
14.50 +typedef struct _GMythQuery GMythQuery;
14.51 +typedef struct _GMythQueryClass GMythQueryClass;
14.52 +
14.53 +struct _GMythQueryClass
14.54 +{
14.55 + GObjectClass parent_class;
14.56 +
14.57 + /* callbacks */
14.58 + /* no one for now */
14.59 +};
14.60 +
14.61 +struct _GMythQuery
14.62 +{
14.63 + GObject parent;
14.64 +
14.65 + GString *opt_host_name; /* server host (default=localhost) */
14.66 + GString *opt_user_name; /* username (default=login name) */
14.67 + GString *opt_password; /* password (default=none) */
14.68 + unsigned int opt_port_num; /* port number (use built-in value) */
14.69 + GString *opt_socket_name; /* socket name (use built-in value) */
14.70 + GString *opt_db_name; /* database name (default=none) */
14.71 + unsigned int opt_flags; /* connection flags (none) */
14.72 + MYSQL *conn; /* pointer to connection handler */
14.73 +};
14.74 +
14.75 +
14.76 +GType gmyth_query_get_type (void);
14.77 +
14.78 +GMythQuery* gmyth_query_new ();
14.79 +MYSQL_RES * gmyth_query_process_statement
14.80 + (GMythQuery *gmyth_query, char *stmt_str);
14.81 +
14.82 +gboolean gmyth_query_connect (GMythQuery *gmyth_query);
14.83 +gboolean gmyth_query_disconnect (GMythQuery *gmyth_query);
14.84 +
14.85 +G_END_DECLS
14.86 +
14.87 +#endif /* __GMYTH_QUERY_H__ */
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/gmyth/src/gmyth_remote_encoder.c Thu Sep 28 15:41:06 2006 +0100
15.3 @@ -0,0 +1,207 @@
15.4 +/**
15.5 + * GMyth Library
15.6 + *
15.7 + * @file gmyth/gmyth_remote_encoder.c
15.8 + *
15.9 + * @brief <p> GMythRemoteEncoder class defines functions for playing live tv.
15.10 + *
15.11 + * The remote encoder is used by gmyth_tvplayer to setup livetv.
15.12 + *
15.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
15.14 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
15.15 + *
15.16 + *//*
15.17 + *
15.18 + * This program is free software; you can redistribute it and/or modify
15.19 + * it under the terms of the GNU Lesser General Public License as published by
15.20 + * the Free Software Foundation; either version 2 of the License, or
15.21 + * (at your option) any later version.
15.22 + *
15.23 + * This program is distributed in the hope that it will be useful,
15.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15.26 + * GNU General Public License for more details.
15.27 + *
15.28 + * You should have received a copy of the GNU Lesser General Public License
15.29 + * along with this program; if not, write to the Free Software
15.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15.31 + */
15.32 +
15.33 +#include "gmyth_remote_encoder.h"
15.34 +
15.35 +#include <assert.h>
15.36 +
15.37 +#include "gmyth_stringlist.h"
15.38 +
15.39 +static void gmyth_remote_encoder_class_init (GMythRemoteEncoderClass *klass);
15.40 +static void gmyth_remote_encoder_init (GMythRemoteEncoder *object);
15.41 +
15.42 +static void gmyth_remote_encoder_dispose (GObject *object);
15.43 +static void gmyth_remote_encoder_finalize (GObject *object);
15.44 +
15.45 +G_DEFINE_TYPE(GMythRemoteEncoder, gmyth_remote_encoder, G_TYPE_OBJECT)
15.46 +
15.47 +static void
15.48 +gmyth_remote_encoder_class_init (GMythRemoteEncoderClass *klass)
15.49 +{
15.50 + GObjectClass *gobject_class;
15.51 +
15.52 + gobject_class = (GObjectClass *) klass;
15.53 +
15.54 + gobject_class->dispose = gmyth_remote_encoder_dispose;
15.55 + gobject_class->finalize = gmyth_remote_encoder_finalize;
15.56 +}
15.57 +
15.58 +static void
15.59 +gmyth_remote_encoder_init (GMythRemoteEncoder *gmyth_remote_encoder)
15.60 +{
15.61 +}
15.62 +
15.63 +static void
15.64 +gmyth_remote_encoder_dispose (GObject *object)
15.65 +{
15.66 + // GMythRemoteEncoder *gmyth_remote_encoder = GMYTH_REMOTE_ENCODER(object);
15.67 +
15.68 + G_OBJECT_CLASS (gmyth_remote_encoder_parent_class)->dispose (object);
15.69 +}
15.70 +
15.71 +
15.72 +static void
15.73 +gmyth_remote_encoder_finalize (GObject *object)
15.74 +{
15.75 + g_signal_handlers_destroy (object);
15.76 +
15.77 + GMythRemoteEncoder *remote_encoder = GMYTH_REMOTE_ENCODER(object);
15.78 +
15.79 + g_debug ("[%s] Closing control socket", __FUNCTION__);
15.80 + gmyth_socket_close_connection(remote_encoder->myth_socket);
15.81 + g_object_unref (remote_encoder->myth_socket);
15.82 +
15.83 + G_OBJECT_CLASS (gmyth_remote_encoder_parent_class)->finalize (object);
15.84 +}
15.85 +
15.86 +/** Creates a new instance of GMythRemoteEncoder.
15.87 + *
15.88 + * @return a new instance of GMythRemoteEncoder.
15.89 + */
15.90 +GMythRemoteEncoder*
15.91 +gmyth_remote_encoder_new (int num, GString *hostname, gshort port)
15.92 +{
15.93 + GMythRemoteEncoder *encoder = GMYTH_REMOTE_ENCODER ( g_object_new (
15.94 + GMYTH_REMOTE_ENCODER_TYPE, FALSE ));
15.95 +
15.96 + encoder->recorder_num = num;
15.97 + encoder->hostname = g_string_new (hostname->str);
15.98 + encoder->port = port;
15.99 +
15.100 + return encoder;
15.101 +}
15.102 +
15.103 +/** Configures the remote encoder instance connecting it to Mythtv backend.
15.104 + *
15.105 + * @param remote_encoder the GMythRemoteEncoder instance.
15.106 + * @return TRUE if successfull, FALSE if any error happens.
15.107 + */
15.108 +gboolean
15.109 +gmyth_remote_encoder_setup (GMythRemoteEncoder *remote_encoder)
15.110 +{
15.111 + assert (remote_encoder);
15.112 + g_debug ("[%s] Creating socket and connecting to backend", __FUNCTION__);
15.113 +
15.114 + if (remote_encoder->myth_socket == NULL) {
15.115 +
15.116 + remote_encoder->myth_socket = gmyth_socket_new ();
15.117 +
15.118 + if (!gmyth_socket_connect_to_backend (remote_encoder->myth_socket, remote_encoder->hostname->str,
15.119 + remote_encoder->port, TRUE) ) {
15.120 + g_warning ("GMythRemoteEncoder: Connection to backend failed");
15.121 + return FALSE;
15.122 + }
15.123 +
15.124 + } else {
15.125 + g_warning("Remote encoder socket already created\n");
15.126 + }
15.127 +
15.128 + return TRUE;
15.129 +}
15.130 +
15.131 +/** Sends the SPAWN_LIVETV command through Mythtv protocol. This command
15.132 + * requests the backend to start capturing TV content.
15.133 + *
15.134 + * @param remote_encoder The GMythRemoteEncoder instance.
15.135 + * @param tvchain_id The tvchain unique id.
15.136 + * @return true if success, false if any error happens.
15.137 + */
15.138 +gboolean
15.139 +gmyth_remote_encoder_spawntv (GMythRemoteEncoder *remote_encoder, GString *tvchain_id)
15.140 +{
15.141 + GMythStringList *str_list;
15.142 + GString *tmp_str;
15.143 +
15.144 + g_debug ("[%s] Spawntv with tvchain_id = %s", __FUNCTION__, tvchain_id->str);
15.145 +
15.146 + str_list = gmyth_string_list_new ();
15.147 +
15.148 + tmp_str = g_string_new ("QUERY_RECORDER ");
15.149 + g_string_append_printf (tmp_str, "%d", remote_encoder->recorder_num);
15.150 +
15.151 + gmyth_string_list_append_string (str_list, tmp_str);
15.152 + gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
15.153 + gmyth_string_list_append_string (str_list, tvchain_id);
15.154 + gmyth_string_list_append_int (str_list, 0); // PIP = FALSE (0)
15.155 +
15.156 + gmyth_socket_sendreceive_stringlist (remote_encoder->myth_socket, str_list);
15.157 +
15.158 + g_string_free (tmp_str, TRUE);
15.159 +
15.160 + tmp_str = gmyth_string_list_get_string (str_list, 0);
15.161 + if (tmp_str == NULL) {
15.162 + g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
15.163 + return FALSE;
15.164 + }
15.165 +
15.166 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
15.167 + g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
15.168 + g_object_unref (str_list);
15.169 + return FALSE;
15.170 + }
15.171 +
15.172 + g_object_unref (str_list);
15.173 + return TRUE;
15.174 +
15.175 +}
15.176 +
15.177 +/** Sends the command STOP_LIVETV to Mythtv backend.
15.178 + *
15.179 + * @param remote_encoder the GMythRemoteEncoder instance.
15.180 + * @return true if success, false if any error happens.
15.181 + */
15.182 +gboolean
15.183 +gmyth_remote_encoder_stop_livetv (GMythRemoteEncoder *remote_encoder)
15.184 +{
15.185 + GMythStringList *str_list;
15.186 + GString *tmp_str;
15.187 +
15.188 + g_debug ("[%s]", __FUNCTION__);
15.189 +
15.190 + str_list = gmyth_string_list_new ();
15.191 +
15.192 + tmp_str = g_string_new ("QUERY_RECORDER ");
15.193 + g_string_append_printf (tmp_str, "%d", remote_encoder->recorder_num);
15.194 + gmyth_string_list_append_string (str_list, g_string_new ("STOP_LIVETV"));
15.195 +
15.196 + gmyth_socket_sendreceive_stringlist (remote_encoder->myth_socket, str_list);
15.197 +
15.198 + g_string_free (tmp_str, TRUE);
15.199 +
15.200 + tmp_str = gmyth_string_list_get_string (str_list, 0);
15.201 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
15.202 + g_warning ("[%s] Stop livetv request returned %s", __FUNCTION__, tmp_str->str);
15.203 + g_object_unref (str_list);
15.204 + return FALSE;
15.205 + }
15.206 +
15.207 + g_object_unref (str_list);
15.208 + return TRUE;
15.209 +
15.210 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/gmyth/src/gmyth_remote_encoder.h Thu Sep 28 15:41:06 2006 +0100
16.3 @@ -0,0 +1,89 @@
16.4 +/**
16.5 + * GMyth Library
16.6 + *
16.7 + * @file gmyth/gmyth_remote_encoder.h
16.8 + *
16.9 + * @brief <p> GMythRemoteEncoder class defines functions for playing live tv.
16.10 + *
16.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
16.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
16.13 + *
16.14 + *//*
16.15 + *
16.16 + * This program is free software; you can redistribute it and/or modify
16.17 + * it under the terms of the GNU Lesser General Public License as published by
16.18 + * the Free Software Foundation; either version 2 of the License, or
16.19 + * (at your option) any later version.
16.20 + *
16.21 + * This program is distributed in the hope that it will be useful,
16.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16.24 + * GNU General Public License for more details.
16.25 + *
16.26 + * You should have received a copy of the GNU Lesser General Public License
16.27 + * along with this program; if not, write to the Free Software
16.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16.29 + */
16.30 +
16.31 +#ifndef __GMYTH_REMOTE_ENCODER_H__
16.32 +#define __GMYTH_REMOTE_ENCODER_H__
16.33 +
16.34 +#include <glib-object.h>
16.35 +
16.36 +#include "gmyth_socket.h"
16.37 +
16.38 +#include <stdio.h>
16.39 +#include <stdlib.h>
16.40 +#include <string.h>
16.41 +#include <netdb.h>
16.42 +#include <sys/socket.h>
16.43 +#include <unistd.h>
16.44 +
16.45 +G_BEGIN_DECLS
16.46 +
16.47 +#define GMYTH_REMOTE_ENCODER_TYPE (gmyth_remote_encoder_get_type ())
16.48 +#define GMYTH_REMOTE_ENCODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoder))
16.49 +#define GMYTH_REMOTE_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoderClass))
16.50 +#define IS_GMYTH_REMOTE_ENCODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_REMOTE_ENCODER_TYPE))
16.51 +#define IS_GMYTH_REMOTE_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_REMOTE_ENCODER_TYPE))
16.52 +#define GMYTH_REMOTE_ENCODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoderClass))
16.53 +
16.54 +
16.55 +typedef struct _GMythRemoteEncoder GMythRemoteEncoder;
16.56 +typedef struct _GMythRemoteEncoderClass GMythRemoteEncoderClass;
16.57 +
16.58 +struct _GMythRemoteEncoderClass
16.59 +{
16.60 + GObjectClass parent_class;
16.61 +
16.62 + /* callbacks */
16.63 + /* no one for now */
16.64 +};
16.65 +
16.66 +struct _GMythRemoteEncoder
16.67 +{
16.68 + GObject parent;
16.69 +
16.70 + /* socket descriptor */
16.71 + GMythSocket *myth_socket;
16.72 +
16.73 + int recorder_num;
16.74 + GString *hostname;
16.75 + int port;
16.76 +};
16.77 +
16.78 +
16.79 +GType gmyth_remote_encoder_get_type (void);
16.80 +
16.81 +GMythRemoteEncoder* gmyth_remote_encoder_new (int num,
16.82 + GString *hostname,
16.83 + gshort port);
16.84 +
16.85 +gboolean gmyth_remote_encoder_setup (GMythRemoteEncoder *encoder);
16.86 +gboolean gmyth_remote_encoder_spawntv (GMythRemoteEncoder *remote_encoder,
16.87 + GString *tvchain_id);
16.88 +gboolean gmyth_remote_encoder_stop_livetv (GMythRemoteEncoder *remote_encoder);
16.89 +
16.90 +G_END_DECLS
16.91 +
16.92 +#endif /* __GMYTH_REMOTE_ENCODER_H__ */
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/gmyth/src/gmyth_remote_util.c Thu Sep 28 15:41:06 2006 +0100
17.3 @@ -0,0 +1,70 @@
17.4 +/**
17.5 + * GMyth Library
17.6 + *
17.7 + * @file gmyth/gmyth_remote_util.c
17.8 + *
17.9 + * @brief <p> This component provides utility functions for accessing remote data.
17.10 + *
17.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
17.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
17.13 + *
17.14 + *//*
17.15 + *
17.16 + * This program is free software; you can redistribute it and/or modify
17.17 + * it under the terms of the GNU Lesser General Public License as published by
17.18 + * the Free Software Foundation; either version 2 of the License, or
17.19 + * (at your option) any later version.
17.20 + *
17.21 + * This program is distributed in the hope that it will be useful,
17.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17.24 + * GNU General Public License for more details.
17.25 + *
17.26 + * You should have received a copy of the GNU Lesser General Public License
17.27 + * along with this program; if not, write to the Free Software
17.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17.29 + */
17.30 +
17.31 +#include "gmyth_remote_util.h"
17.32 +
17.33 +#include "gmyth_context.h"
17.34 +#include "gmyth_remote_encoder.h"
17.35 +#include "gmyth_stringlist.h"
17.36 +
17.37 +/** Requests the Mythtv backend for a free remote recorder.
17.38 + *
17.39 + * @param curr The recorder index, or -1 to consider the first one.
17.40 + * @return the remote encoder instance available, or NULL if any error happens.
17.41 + */
17.42 +GMythRemoteEncoder*
17.43 +remote_request_next_free_recorder (int curr)
17.44 +{
17.45 + GMythRemoteEncoder *encoder;
17.46 + GString *hostname;
17.47 + int num, port;
17.48 +
17.49 + GMythStringList *strlist = gmyth_string_list_new();
17.50 +
17.51 + g_debug ("[%s] Request next free recorder in the backend", __FUNCTION__);
17.52 +
17.53 + gmyth_string_list_append_char_array (strlist, "GET_NEXT_FREE_RECORDER");
17.54 + gmyth_string_list_append_int (strlist, curr);
17.55 +
17.56 + if (!gmyth_context_send_receive_stringlist(strlist)) {
17.57 + g_warning ("GET_NEXT_FREE_RECORDER request error!\n");
17.58 + return NULL;
17.59 + }
17.60 +
17.61 + num = gmyth_string_list_get_int (strlist, 0);
17.62 + hostname = gmyth_string_list_get_string (strlist, 1);
17.63 + port = gmyth_string_list_get_int (strlist, 2);
17.64 +
17.65 + g_debug ("[%s] Free recorder info received: num: %d, hostname: %s, port: %d",
17.66 + __FUNCTION__, num, hostname->str, port);
17.67 +
17.68 + encoder = gmyth_remote_encoder_new (num, hostname, port);
17.69 +
17.70 + g_object_unref (strlist);
17.71 +
17.72 + return encoder;
17.73 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/gmyth/src/gmyth_remote_util.h Thu Sep 28 15:41:06 2006 +0100
18.3 @@ -0,0 +1,40 @@
18.4 +/**
18.5 + * GMyth Library
18.6 + *
18.7 + * @file gmyth/gmyth_remote_util.h
18.8 + *
18.9 + * @brief <p> This component provides utility functions for accessing remote data.
18.10 + *
18.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
18.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
18.13 + *
18.14 + *//*
18.15 + *
18.16 + * This program is free software; you can redistribute it and/or modify
18.17 + * it under the terms of the GNU Lesser General Public License as published by
18.18 + * the Free Software Foundation; either version 2 of the License, or
18.19 + * (at your option) any later version.
18.20 + *
18.21 + * This program is distributed in the hope that it will be useful,
18.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
18.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18.24 + * GNU General Public License for more details.
18.25 + *
18.26 + * You should have received a copy of the GNU Lesser General Public License
18.27 + * along with this program; if not, write to the Free Software
18.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18.29 + */
18.30 +
18.31 +#ifndef __REMOTE_UTIL_H__
18.32 +#define __REMOTE_UTIL_H__
18.33 +
18.34 +#include <glib.h>
18.35 +#include "gmyth_remote_encoder.h"
18.36 +
18.37 +G_BEGIN_DECLS
18.38 +
18.39 +GMythRemoteEncoder* remote_request_next_free_recorder (int curr);
18.40 +
18.41 +G_END_DECLS
18.42 +
18.43 +#endif
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/gmyth/src/gmyth_scheduler.c Thu Sep 28 15:41:06 2006 +0100
19.3 @@ -0,0 +1,610 @@
19.4 +/**
19.5 + * GMyth Library
19.6 + *
19.7 + * @file gmyth/gmyth_scheduler.c
19.8 + *
19.9 + * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
19.10 + * and modifying the recorded content.
19.11 + *
19.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
19.13 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
19.14 + *
19.15 + *//*
19.16 + *
19.17 + * This program is free software; you can redistribute it and/or modify
19.18 + * it under the terms of the GNU Lesser General Public License as published by
19.19 + * the Free Software Foundation; either version 2 of the License, or
19.20 + * (at your option) any later version.
19.21 + *
19.22 + * This program is distributed in the hope that it will be useful,
19.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19.25 + * GNU General Public License for more details.
19.26 + *
19.27 + * You should have received a copy of the GNU Lesser General Public License
19.28 + * along with this program; if not, write to the Free Software
19.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19.30 + */
19.31 +
19.32 +#include <assert.h>
19.33 +
19.34 +#include "gmyth_scheduler.h"
19.35 +
19.36 +#include "gmyth_context.h"
19.37 +#include "gmyth_util.h"
19.38 +#include "gmyth_query.h"
19.39 +
19.40 +static void gmyth_scheduler_class_init (GMythSchedulerClass *klass);
19.41 +static void gmyth_scheduler_init (GMythScheduler *object);
19.42 +
19.43 +static void gmyth_scheduler_dispose (GObject *object);
19.44 +static void gmyth_scheduler_finalize (GObject *object);
19.45 +
19.46 +static gint get_record_id_from_database (GMythScheduler *scheduler);
19.47 +static void update_backend (gint record_id);
19.48 +
19.49 +G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
19.50 +
19.51 +static void
19.52 +gmyth_scheduler_class_init (GMythSchedulerClass *klass)
19.53 +{
19.54 + GObjectClass *gobject_class;
19.55 +
19.56 + gobject_class = (GObjectClass *) klass;
19.57 +
19.58 + gobject_class->dispose = gmyth_scheduler_dispose;
19.59 + gobject_class->finalize = gmyth_scheduler_finalize;
19.60 +}
19.61 +
19.62 +static void
19.63 +gmyth_scheduler_init (GMythScheduler *sched)
19.64 +{
19.65 + sched->recordid =0;
19.66 + sched->type = 0;
19.67 + sched->search = 0;
19.68 + sched->profile = g_string_new("");
19.69 +
19.70 + sched->dupin = 0;
19.71 + sched->dupmethod = 0;
19.72 + sched->autoexpire = 0;
19.73 + sched->autotranscode = 0;
19.74 + sched->transcoder = 0;
19.75 +
19.76 + sched->autocommflag = 0;
19.77 + sched->autouserjob1 = 0;
19.78 + sched->autouserjob2 = 0;
19.79 + sched->autouserjob3 = 0;
19.80 + sched->autouserjob4 = 0;
19.81 +
19.82 + sched->startoffset = 0;
19.83 + sched->endoffset = 0;
19.84 + sched->maxepisodes = 0;
19.85 + sched->maxnewest = 0;
19.86 +
19.87 + sched->recpriority = 0;
19.88 + sched->recgroup = 0;
19.89 + sched->playgroup = 0;
19.90 +
19.91 + sched->prefinput = 0;
19.92 + sched->inactive = 0;
19.93 +
19.94 + sched->searchType = g_string_new("");
19.95 + sched->searchForWhat = g_string_new("");
19.96 +
19.97 + sched->msqlquery = gmyth_query_new ();
19.98 +}
19.99 +
19.100 +static void
19.101 +gmyth_scheduler_dispose (GObject *object)
19.102 +{
19.103 + G_OBJECT_CLASS (gmyth_scheduler_parent_class)->dispose (object);
19.104 +}
19.105 +
19.106 +static void
19.107 +gmyth_scheduler_finalize (GObject *object)
19.108 +{
19.109 + g_signal_handlers_destroy (object);
19.110 +
19.111 + G_OBJECT_CLASS (gmyth_scheduler_parent_class)->finalize (object);
19.112 +}
19.113 +
19.114 +/** Creates a new instance of GMythScheduler.
19.115 + *
19.116 + * @return a new instance of GMythScheduler.
19.117 + */
19.118 +GMythScheduler*
19.119 +gmyth_scheduler_new ()
19.120 +{
19.121 + GMythScheduler *scheduler =
19.122 + GMYTH_SCHEDULER (g_object_new(GMYTH_SCHEDULER_TYPE, NULL));
19.123 +
19.124 + return scheduler;
19.125 +}
19.126 +
19.127 +/** Connects to the Mysql database in the backend. The backend address
19.128 + * is loaded from the GMythSettings instance.
19.129 + *
19.130 + * @param scheduler the GMythScheduler instance to be connected.
19.131 + * @return true if connection was success, false if failed.
19.132 + */
19.133 +gboolean
19.134 +gmyth_scheduler_connect (GMythScheduler *scheduler)
19.135 +{
19.136 + assert(scheduler);
19.137 +
19.138 + if (scheduler->msqlquery == NULL) {
19.139 + g_warning ("[%s] MMythScheduler not initialized", __FUNCTION__);
19.140 + return FALSE;
19.141 + }
19.142 +
19.143 + if (!gmyth_query_connect(scheduler->msqlquery)) {
19.144 + g_warning ("[%s] Error while connecting to db", __FUNCTION__);
19.145 + return FALSE;
19.146 + }
19.147 +
19.148 + return TRUE;
19.149 +}
19.150 +
19.151 +/** Disconnects from the Mysql database in the backend.
19.152 + *
19.153 + * @param scheduler the GMythScheduler instance to be disconnected
19.154 + * @return true if disconnection was success, false if failed.
19.155 + */
19.156 +gboolean
19.157 +gmyth_scheduler_disconnect (GMythScheduler *scheduler)
19.158 +{
19.159 + assert(scheduler);
19.160 +
19.161 + if (scheduler->msqlquery != NULL) {
19.162 + g_object_unref (scheduler->msqlquery);
19.163 + }
19.164 +
19.165 + return TRUE;
19.166 +}
19.167 +
19.168 +/** Retrieves from the backend Mysql database the list of recording schedules.
19.169 + *
19.170 + * @param scheduler The GMythScheduler instance.
19.171 + * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
19.172 + * @return The amount of schedules retrieved from database, or -1 if error.
19.173 + */
19.174 +gint
19.175 +gmyth_scheduler_get_schedule_list ( GMythScheduler *scheduler, GList **schedule_list)
19.176 +{
19.177 + ScheduleInfo *schedule;
19.178 + MYSQL_RES *msql_res;
19.179 + GString *query_str = g_string_new ("");
19.180 + GString *date_time = g_string_new ("");
19.181 +
19.182 + assert(scheduler);
19.183 +
19.184 + g_string_printf (query_str,
19.185 + "SELECT recordid,programid,chanid,starttime,startdate,"
19.186 + "endtime,enddate,title,subtitle,description,category FROM record;");
19.187 +
19.188 + if (scheduler->msqlquery == NULL) {
19.189 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
19.190 + return -1;
19.191 + }
19.192 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
19.193 +
19.194 + if (msql_res == NULL) {
19.195 + g_warning ("DB retrieval of schedule list failed");
19.196 + return -1;
19.197 + } else {
19.198 + MYSQL_ROW row;
19.199 + *schedule_list = NULL;
19.200 +
19.201 + while((row = mysql_fetch_row (msql_res)) != NULL) {
19.202 + schedule = g_new0(ScheduleInfo, 1);
19.203 +
19.204 + schedule->record_id = atoi (row[0]);
19.205 + schedule->program_id = atoi (row[1]);
19.206 + schedule->channel_id = atoi (row[2]);
19.207 +
19.208 + /* generate a time_t from a time and a date db field */
19.209 + g_string_printf (date_time, "%s %s", row[4], row[3]);
19.210 +
19.211 + schedule->start_time = gmyth_util_string_to_time (date_time);
19.212 +
19.213 + /* generate a time_t from a time and a date db field */
19.214 + g_string_printf (date_time, "%s %s", row[6], row[5]);
19.215 +
19.216 + schedule->end_time = gmyth_util_string_to_time (date_time);
19.217 +
19.218 + schedule->title = g_string_new (row[7]);
19.219 + schedule->subtitle = g_string_new (row[8]);
19.220 + schedule->description = g_string_new (row[9]);
19.221 + schedule->category = g_string_new (row[10]);
19.222 +
19.223 + (*schedule_list) = g_list_append (*(schedule_list), schedule);
19.224 + }
19.225 + }
19.226 +
19.227 + mysql_free_result (msql_res);
19.228 + g_string_free(query_str, TRUE);
19.229 + g_string_free(date_time, TRUE);
19.230 +
19.231 + return (*schedule_list == NULL) ? 0 : g_list_length (*schedule_list);
19.232 +}
19.233 +
19.234 +/** Retrieves from the backend Mysql database the list of recorded programs.
19.235 + *
19.236 + * @param scheduler The GMythScheduler instance.
19.237 + * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
19.238 + * @return The amount of recorded retrieved from database, or -1 if error.
19.239 + */
19.240 +gint
19.241 +gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler, GList **recorded_list)
19.242 +{
19.243 + RecordedInfo *record;
19.244 + MYSQL_RES *msql_res;
19.245 + GString *query_str = g_string_new ("");
19.246 + GString *date_time = g_string_new ("");
19.247 +
19.248 + assert(scheduler);
19.249 +
19.250 + g_string_printf (query_str,
19.251 + "SELECT recordid,programid,chanid,starttime,progstart,"
19.252 + "endtime,progend,title,subtitle,description,category,basename FROM recorded;");
19.253 +
19.254 + if (scheduler->msqlquery == NULL) {
19.255 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
19.256 + return -1;
19.257 + }
19.258 +
19.259 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
19.260 +
19.261 + if (msql_res == NULL) {
19.262 + g_warning ("DB retrieval of recording list failed");
19.263 + return -1;
19.264 + } else {
19.265 + MYSQL_ROW row;
19.266 + *recorded_list = NULL;
19.267 +
19.268 + while((row = mysql_fetch_row (msql_res))!=NULL){
19.269 + record = g_new0(RecordedInfo, 1);
19.270 +
19.271 + record->record_id = atoi (row[0]);
19.272 + record->program_id = atoi (row[1]);
19.273 + record->channel_id = atoi (row[2]);
19.274 +
19.275 + /* the db field time already contains the date. therefore
19.276 + * we are not using the date field */
19.277 + /* generate a time_t from a time and a date db field */
19.278 + /* g_string_printf (date_time, "%s %s", row[4], row[3]); */
19.279 + g_string_printf (date_time, "%s", row[3]);
19.280 +
19.281 + record->start_time = gmyth_util_string_to_time (date_time);
19.282 +
19.283 + /* the db field time already contains the date. therefore
19.284 + * we are not using the date field */
19.285 + /* generate a time_t from a time and a date db field */
19.286 + /* g_string_printf (date_time, "%s %s", row[6], row[5]); */
19.287 + g_string_printf (date_time, "%s", row[5]);
19.288 +
19.289 + record->end_time = gmyth_util_string_to_time (date_time);
19.290 +
19.291 + record->title = g_string_new (row[7]);
19.292 + record->subtitle = g_string_new (row[8]);
19.293 + record->description = g_string_new (row[9]);
19.294 + record->category = g_string_new (row[10]);
19.295 + record->basename = g_string_new (row[11]);
19.296 +
19.297 + *recorded_list = g_list_append (*recorded_list, record);
19.298 + }
19.299 + }
19.300 +
19.301 + mysql_free_result (msql_res);
19.302 + g_string_free(query_str, TRUE);
19.303 + g_string_free(date_time, TRUE);
19.304 +
19.305 + return (*recorded_list == NULL) ? 0 : g_list_length (*recorded_list);
19.306 +}
19.307 +
19.308 +/** Requests the Mysql database in the backend to add a new schedule.
19.309 + *
19.310 + * @param scheduler the GMythScheduler instance.
19.311 + * @param schedule_info the ScheduleInfo with recording schedule information
19.312 + * to be added. record_id = -1 to add a new schedule, otherwise this
19.313 + * function will update the schedule in the db
19.314 + * @return gboolean returns FALSE if some error occurs, TRUE otherwise
19.315 + */
19.316 +gboolean
19.317 +gmyth_scheduler_add_schedule (GMythScheduler *scheduler,
19.318 + ScheduleInfo *schedule_info)
19.319 +{
19.320 + struct tm start_tm;
19.321 + struct tm end_tm;
19.322 +
19.323 + MYSQL_RES *msql_res;
19.324 + GString *query_str = g_string_new ("");
19.325 +
19.326 + assert(scheduler);
19.327 +
19.328 + if (scheduler->msqlquery == NULL) {
19.329 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
19.330 + return 0;
19.331 + }
19.332 +
19.333 + /* manipulating time */
19.334 + if(localtime_r(&schedule_info->start_time, &start_tm) == NULL) {
19.335 + g_warning ("localtime_r error in libgmyth scheduler!\n");
19.336 + return FALSE;
19.337 + }
19.338 +
19.339 + if(localtime_r(&schedule_info->end_time, &end_tm) == NULL) {
19.340 + g_warning ("localtime_r error in libgmyth scheduler!\n");
19.341 + return FALSE;
19.342 + }
19.343 +
19.344 + //TODO: verify if this funtion realy does what it should do!
19.345 + g_string_printf (query_str, "REPLACE INTO record "
19.346 + "(recordid, type, chanid, starttime, "
19.347 + "startdate, endtime, enddate, title,"
19.348 + "profile, recpriority, maxnewest, inactive, "
19.349 + "maxepisodes, autoexpire, startoffset, endoffset, "
19.350 + "recgroup, dupmethod, dupin, station, "
19.351 + "autocommflag, findday, findtime, findid, "
19.352 + "search, autotranscode, transcoder, tsdefault, "
19.353 + "autouserjob1, autouserjob2, autouserjob3, autouserjob4) "
19.354 + " values ( %d, 1, %d, \"%02d:%02d:00\"," //recordid, type, chanid, starttime
19.355 + " \"%d-%02d-%02d\", \"%02d:%02d:00\", \"%04d-%02d-%02d\", \"%s\","
19.356 + //startdate, endtime, enddate, title
19.357 + "DEFAULT, 0, 0, 0, " //profile, recpriority, maxnewest, inactive
19.358 + "0, 1, 0, 0, " //maxepisodes, autoexpire, startoffset, endoffset
19.359 + "DEFAULT, 6, 15, %d, " //recgroup, dupmethod, dupin, station
19.360 + "1, %d, \"%02d:%02d:00\", %d, " //autocommflag, findday, findtime, findid
19.361 + "5, 0, 29, 1, " //search, autotranscode, transcoder, tsdefault
19.362 + "0, 0, 0, 0 );", //autouserjob1, autouserjob2, autouserjob3, autouserjob4
19.363 + schedule_info->record_id, schedule_info->channel_id,
19.364 + start_tm.tm_hour, start_tm.tm_min,
19.365 + start_tm.tm_year+1900, start_tm.tm_mon+1,
19.366 + start_tm.tm_mday,
19.367 + end_tm.tm_hour, end_tm.tm_min,
19.368 + end_tm.tm_year+1900, end_tm.tm_mon+1,
19.369 + end_tm.tm_mday, schedule_info->title->str, //title
19.370 + schedule_info->channel_id,//station
19.371 + start_tm.tm_wday+1, //findday
19.372 + start_tm.tm_hour, start_tm.tm_min, //findtime
19.373 + (gint)(schedule_info->start_time/60/60/24 + 719528)//findid
19.374 + );
19.375 +
19.376 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
19.377 +
19.378 + /* FIXME: currently no way to detect db error in UPDATE, REPLACES!
19.379 + if (msql_res == NULL) {
19.380 + g_warning ("DB retrieval of recording list failed");
19.381 + return -1;
19.382 + }*/
19.383 +
19.384 + /* TODO: verify record_id = -1 semantics */
19.385 + if (schedule_info->record_id <= 0)
19.386 + schedule_info->record_id = get_record_id_from_database(scheduler);
19.387 +
19.388 + /* Notify the backend of changes */
19.389 + update_backend(schedule_info->record_id);
19.390 +
19.391 + /* free allocated memory */
19.392 + mysql_free_result (msql_res);
19.393 + g_string_free(query_str, TRUE);
19.394 +
19.395 + return 1;
19.396 +}
19.397 +
19.398 +/** Requests the Mysql database in the backend to remove an existing schedule.
19.399 + *
19.400 + * @param scheduler the GMythScheduler instance.
19.401 + * @param record_id The schedule's record id to be removed
19.402 + * @return gboolean TRUE if success, FALSE if error
19.403 + */
19.404 +gboolean
19.405 +gmyth_scheduler_delete_schedule (GMythScheduler *scheduler, gint record_id)
19.406 +{
19.407 +
19.408 + MYSQL_RES *msql_res;
19.409 + GString *query_str = g_string_new ("");
19.410 +
19.411 + assert(scheduler);
19.412 +
19.413 + if (scheduler->msqlquery == NULL) {
19.414 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
19.415 + return FALSE;
19.416 + }
19.417 +
19.418 + //========================================
19.419 + g_string_printf (query_str,
19.420 + "DELETE FROM record WHERE recordid=%d", record_id);
19.421 +
19.422 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
19.423 +
19.424 + if (msql_res == NULL) {
19.425 + g_warning ("[%s] Error while trying to delete a schedule in the database", __FUNCTION__);
19.426 + return FALSE;
19.427 + }
19.428 +
19.429 + update_backend(record_id);// Notify the backend of the changes
19.430 +
19.431 + mysql_free_result (msql_res);
19.432 + g_string_free(query_str, TRUE);
19.433 +
19.434 + return TRUE;
19.435 +}
19.436 +
19.437 +/** Requests the Mysql database in the backend to remove an existing recorded item.
19.438 + *
19.439 + * @param scheduler the GMythScheduler instance.
19.440 + * @param record_id The recorded item id to be removed
19.441 + * @return gboolean TRUE if success, FALSE if error
19.442 + */
19.443 +gboolean
19.444 +gmyth_scheduler_delete_recorded (GMythScheduler *scheduler, gint record_id)
19.445 +{
19.446 +
19.447 + MYSQL_RES *msql_res;
19.448 + GString *query_str = g_string_new ("");
19.449 +
19.450 + assert(scheduler);
19.451 +
19.452 + if (scheduler->msqlquery == NULL) {
19.453 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
19.454 + return FALSE;
19.455 + }
19.456 +
19.457 + //========================================
19.458 + g_string_printf (query_str,
19.459 + "DELETE FROM recorded WHERE recordid=%d", record_id);
19.460 +
19.461 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
19.462 +
19.463 + update_backend(record_id);// Notify the backend of the changes
19.464 +
19.465 + mysql_free_result (msql_res);
19.466 + g_string_free(query_str, TRUE);
19.467 +
19.468 + return TRUE;
19.469 +}
19.470 +
19.471 +/** Retrieves an existing recorded item information from database. The information
19.472 + * is used to fill the returned GMythProgramInfo.
19.473 + *
19.474 + * @param scheduler The GMythScheduler instance.
19.475 + * @param channel The channel associated to the record
19.476 + * @param starttime The record start time
19.477 + * @return A GMythProgramInfo struct with the requested record item
19.478 + * information, or NULL if error.
19.479 + */
19.480 +GMythProgramInfo*
19.481 +gmyth_scheduler_get_recorded (GMythScheduler *scheduler,
19.482 + GString *channel, time_t starttime)
19.483 +{
19.484 + MYSQL_RES *msql_res;
19.485 + GMythProgramInfo *proginfo = NULL;
19.486 + GString *query_str = g_string_new("");
19.487 + GString *time_str = gmyth_util_time_to_string (starttime);
19.488 +
19.489 + assert(scheduler);
19.490 +
19.491 + if (scheduler->msqlquery == NULL) {
19.492 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
19.493 + return NULL;
19.494 + }
19.495 +
19.496 + g_string_printf (query_str, "SELECT recorded.chanid,starttime,endtime,title, "
19.497 + "subtitle,description,channel.channum, "
19.498 + "channel.callsign,channel.name,channel.commfree, "
19.499 + "channel.outputfilters,seriesid,programid,filesize, "
19.500 + "lastmodified,stars,previouslyshown,originalairdate, "
19.501 + "hostname,recordid,transcoder,playgroup, "
19.502 + "recorded.recpriority,progstart,progend,basename,recgroup "
19.503 + "FROM recorded "
19.504 + "LEFT JOIN channel "
19.505 + "ON recorded.chanid = channel.chanid "
19.506 + "WHERE recorded.chanid = \"%s\" "
19.507 + "AND starttime = \"%s\" ;",
19.508 + channel->str, time_str->str);
19.509 +
19.510 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
19.511 +
19.512 + if (msql_res /*&& query.size() > 0*/) {
19.513 +
19.514 + MYSQL_ROW msql_row = mysql_fetch_row (msql_res);
19.515 + if (msql_row) {
19.516 +
19.517 + proginfo = g_new0 (GMythProgramInfo, 1);
19.518 +
19.519 + proginfo->chanid = g_string_new (msql_row[0]);
19.520 + proginfo->startts = gmyth_util_string_to_time (g_string_new (msql_row[23]));
19.521 + proginfo->endts = gmyth_util_string_to_time (g_string_new (msql_row[24]));
19.522 + proginfo->recstartts = gmyth_util_string_to_time (g_string_new (msql_row[1]));
19.523 + proginfo->recendts = gmyth_util_string_to_time (g_string_new (msql_row[2]));
19.524 + proginfo->title = g_string_new (msql_row[3]);
19.525 + proginfo->subtitle = g_string_new (msql_row[4]);
19.526 + proginfo->description = g_string_new (msql_row[5]);
19.527 +
19.528 + proginfo->chanstr = g_string_new (msql_row[6]);
19.529 + proginfo->chansign = g_string_new (msql_row[7]);
19.530 + proginfo->channame = g_string_new (msql_row[0]);
19.531 + proginfo->chancommfree = atoi (msql_row[9]);
19.532 + proginfo->chanOutputFilters = g_string_new (msql_row[10]);
19.533 + proginfo->seriesid = g_string_new (msql_row[11]);
19.534 + proginfo->programid = g_string_new (msql_row[12]);
19.535 + proginfo->filesize = atoll (msql_row[13]);
19.536 +
19.537 + proginfo->lastmodified = gmyth_util_string_to_time (g_string_new (msql_row[14]));
19.538 +
19.539 + proginfo->stars = atof (msql_row[15]);
19.540 + proginfo->repeat = atoi (msql_row[16]);
19.541 +
19.542 + if (msql_row[17] == NULL) {
19.543 + proginfo->originalAirDate = 0;
19.544 + proginfo->hasAirDate = FALSE;
19.545 + } else {
19.546 + proginfo->originalAirDate = gmyth_util_string_to_time (g_string_new (msql_row[17]));
19.547 + proginfo->hasAirDate = TRUE;
19.548 + }
19.549 +
19.550 + proginfo->hostname = g_string_new (msql_row[18]);
19.551 + proginfo->recordid = atoi (msql_row[19]);
19.552 + proginfo->transcoder = atoi (msql_row[20]);
19.553 +
19.554 + //proginfo->spread = -1;
19.555 + //proginfo->programflags = proginfo->getProgramFlags();
19.556 +
19.557 + proginfo->recgroup = g_string_new (msql_row[26]);
19.558 + proginfo->playgroup = g_string_new (msql_row[21]);
19.559 + proginfo->recpriority = atoi (msql_row[22]);
19.560 +
19.561 + proginfo->pathname = g_string_new (msql_row[25]);
19.562 +
19.563 + g_debug ("One program info loaded from mysql database\n");
19.564 + }
19.565 + }
19.566 +
19.567 + mysql_free_result (msql_res);
19.568 + g_string_free(query_str, TRUE);
19.569 + g_string_free(time_str, TRUE);
19.570 +
19.571 + return proginfo;
19.572 +}
19.573 +
19.574 +/** Retrieves the next record id.
19.575 + *
19.576 + * @param scheduler The GMythScheduler instance.
19.577 + * @return gint record_id if success, -1 otherwise
19.578 + */
19.579 +static gint
19.580 +get_record_id_from_database (GMythScheduler *scheduler)
19.581 +{
19.582 + gint record_id;
19.583 +
19.584 + assert(scheduler);
19.585 +
19.586 + if (scheduler->msqlquery == NULL) {
19.587 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
19.588 + return 0;
19.589 + }
19.590 +
19.591 + record_id = mysql_insert_id (scheduler->msqlquery->conn);
19.592 +
19.593 + return record_id;
19.594 +}
19.595 +
19.596 +/** Notifies the backend of an update in the db.
19.597 + *
19.598 + * @param record_id the id of the modified recording.
19.599 + */
19.600 +static void
19.601 +update_backend(gint record_id)//fixme: put void and discovery record_id inside
19.602 +{
19.603 + GMythStringList *strlist = gmyth_string_list_new ();
19.604 + GString *datastr = g_string_new ("RESCHEDULE_RECORDINGS ");
19.605 +
19.606 + g_string_append_printf (datastr, "%d", record_id);
19.607 + gmyth_string_list_append_string (strlist, datastr);
19.608 +
19.609 + gmyth_context_send_receive_stringlist (strlist);
19.610 +
19.611 + g_string_free(datastr, TRUE);
19.612 + g_object_unref(strlist);
19.613 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/gmyth/src/gmyth_scheduler.h Thu Sep 28 15:41:06 2006 +0100
20.3 @@ -0,0 +1,156 @@
20.4 +/**
20.5 + * GMyth Library
20.6 + *
20.7 + * @file gmyth/gmyth_scheduler.h
20.8 + *
20.9 + * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
20.10 + * and modifying the recorded content.
20.11 + *
20.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
20.13 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
20.14 + *
20.15 + *//*
20.16 + *
20.17 + * This program is free software; you can redistribute it and/or modify
20.18 + * it under the terms of the GNU Lesser General Public License as published by
20.19 + * the Free Software Foundation; either version 2 of the License, or
20.20 + * (at your option) any later version.
20.21 + *
20.22 + * This program is distributed in the hope that it will be useful,
20.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
20.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20.25 + * GNU General Public License for more details.
20.26 + *
20.27 + * You should have received a copy of the GNU Lesser General Public License
20.28 + * along with this program; if not, write to the Free Software
20.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20.30 + */
20.31 +
20.32 +#ifndef __GMYTH_SCHEDULER_H__
20.33 +#define __GMYTH_SCHEDULER_H__
20.34 +
20.35 +#include <glib-object.h>
20.36 +#include <time.h>
20.37 +
20.38 +#include "gmyth_common.h"
20.39 +#include "gmyth_query.h"
20.40 +
20.41 +G_BEGIN_DECLS
20.42 +
20.43 +#define GMYTH_SCHEDULER_TYPE (gmyth_scheduler_get_type ())
20.44 +#define GMYTH_SCHEDULER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE, GMythScheduler))
20.45 +#define GMYTH_SCHEDULER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
20.46 +#define IS_GMYTH_SCHEDULER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE))
20.47 +#define IS_GMYTH_SCHEDULER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE))
20.48 +#define GMYTH_SCHEDULER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
20.49 +
20.50 +
20.51 +typedef struct _GMythScheduler GMythScheduler;
20.52 +typedef struct _GMythSchedulerClass GMythSchedulerClass;
20.53 +
20.54 +struct _GMythSchedulerClass
20.55 +{
20.56 + GObjectClass parent_class;
20.57 +
20.58 + /* callbacks */
20.59 + /* no one for now */
20.60 +};
20.61 +
20.62 +struct _GMythScheduler
20.63 +{
20.64 + GObject parent;
20.65 +
20.66 + unsigned long recordid;
20.67 + unsigned long type;
20.68 + unsigned long search;
20.69 + GString *profile;
20.70 +
20.71 + long dupin;
20.72 + long dupmethod;
20.73 + long autoexpire;
20.74 + short int autotranscode;
20.75 + long transcoder;
20.76 +
20.77 + short int autocommflag;
20.78 + short int autouserjob1;
20.79 + short int autouserjob2;
20.80 + short int autouserjob3;
20.81 + short int autouserjob4;
20.82 +
20.83 + long startoffset;
20.84 + long endoffset;
20.85 + long maxepisodes;
20.86 + long maxnewest;
20.87 +
20.88 + long recpriority;
20.89 + GString *recgroup;
20.90 + GString *playgroup;
20.91 +
20.92 + long prefinput;
20.93 + short int inactive;
20.94 +
20.95 + GString *searchType;
20.96 + GString *searchForWhat;
20.97 +
20.98 + GMythQuery *msqlquery;
20.99 +};
20.100 +
20.101 +typedef struct {
20.102 + gint record_id;
20.103 + gint program_id;
20.104 + gint channel_id;
20.105 +
20.106 + time_t start_time;
20.107 + time_t end_time;
20.108 +
20.109 + GString *title;
20.110 + GString *subtitle;
20.111 + GString *description;
20.112 + GString *category;
20.113 +
20.114 +} ScheduleInfo;
20.115 +
20.116 +typedef struct {
20.117 + gint record_id;
20.118 + gint program_id;
20.119 + gint channel_id;
20.120 +
20.121 + time_t start_time;
20.122 + time_t end_time;
20.123 +
20.124 + GString *title;
20.125 + GString *subtitle;
20.126 + GString *description;
20.127 + GString *category;
20.128 +
20.129 + GString *basename;
20.130 +
20.131 +} RecordedInfo;
20.132 +
20.133 +
20.134 +GType gmyth_scheduler_get_type (void);
20.135 +
20.136 +GMythScheduler* gmyth_scheduler_new ();
20.137 +gboolean gmyth_scheduler_connect (GMythScheduler *scheduler);
20.138 +gboolean gmyth_scheduler_disconnect (GMythScheduler *scheduler);
20.139 +
20.140 +gint gmyth_scheduler_get_schedule_list (GMythScheduler *scheduler,
20.141 + GList **sched_list);
20.142 +gint gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler,
20.143 + GList **rec_list);
20.144 +
20.145 +GMythProgramInfo* gmyth_scheduler_get_recorded (GMythScheduler *scheduler,
20.146 + GString *channel, time_t starttime);
20.147 +
20.148 +gint gmyth_scheduler_add_schedule(GMythScheduler *scheduler,
20.149 + ScheduleInfo *schedule_info);
20.150 +
20.151 +gint gmyth_scheduler_delete_schedule (GMythScheduler *scheduler,
20.152 + gint record_id);
20.153 +gint gmyth_scheduler_delete_recorded (GMythScheduler *scheduler,
20.154 + gint record_id);
20.155 +
20.156 +G_END_DECLS
20.157 +
20.158 +#endif /* __GMYTH_SCHEDULER_H__ */
20.159 +
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/gmyth/src/gmyth_settings.c Thu Sep 28 15:41:06 2006 +0100
21.3 @@ -0,0 +1,417 @@
21.4 +/**
21.5 + * GMyth Library
21.6 + *
21.7 + * @file gmyth/gmyth_settings.c
21.8 + *
21.9 + * @brief <p> This component contains functions acessing and modifying
21.10 + * user and program settings.
21.11 + *
21.12 + * The standard settings file is created in the user home folder, in the
21.13 + * file ~/.mmyth/settings.dat.
21.14 + *
21.15 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
21.16 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
21.17 + *
21.18 + *//*
21.19 + *
21.20 + * This program is free software; you can redistribute it and/or modify
21.21 + * it under the terms of the GNU Lesser General Public License as published by
21.22 + * the Free Software Foundation; either version 2 of the License, or
21.23 + * (at your option) any later version.
21.24 + *
21.25 + * This program is distributed in the hope that it will be useful,
21.26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21.27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21.28 + * GNU General Public License for more details.
21.29 + *
21.30 + * You should have received a copy of the GNU Lesser General Public License
21.31 + * along with this program; if not, write to the Free Software
21.32 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21.33 + */
21.34 +
21.35 +#include "gmyth_settings.h"
21.36 +
21.37 +#include <string.h>
21.38 +#include <stdlib.h>
21.39 +#include <unistd.h>
21.40 +#include <fcntl.h>
21.41 +
21.42 +#include <glib.h>
21.43 +#include <glib/gprintf.h>
21.44 +#include <glib/gstdio.h>
21.45 +
21.46 +#define GMYTH_SETTINGS_FILE_NAME "settings.dat"
21.47 +#define GMYTH_SETTINGS_DIR ".mmyth"
21.48 +
21.49 +static void gmyth_settings_class_init (GMythSettingsClass *klass);
21.50 +static void gmyth_settings_init (GMythSettings *object);
21.51 +
21.52 +static void gmyth_settings_dispose (GObject *object);
21.53 +static void gmyth_settings_finalize (GObject *object);
21.54 +
21.55 +static void fill_settings_data(GMythSettings *gmyth_settings, char* line);
21.56 +
21.57 +G_DEFINE_TYPE(GMythSettings, gmyth_settings, G_TYPE_OBJECT)
21.58 +
21.59 +static void
21.60 +gmyth_settings_class_init (GMythSettingsClass *klass)
21.61 +{
21.62 + GObjectClass *gobject_class;
21.63 +
21.64 + gobject_class = (GObjectClass *) klass;
21.65 +
21.66 + gobject_class->dispose = gmyth_settings_dispose;
21.67 + gobject_class->finalize = gmyth_settings_finalize;
21.68 +}
21.69 +
21.70 +static void
21.71 +gmyth_settings_init (GMythSettings *gmyth_settings)
21.72 +{
21.73 +
21.74 + gmyth_settings->settings_file = NULL;
21.75 +
21.76 + gmyth_settings->backend_hostname = g_string_new("127.0.0.1");
21.77 + gmyth_settings->backend_port = 6543;
21.78 + gmyth_settings->mysql_dbname = g_string_new("mythconverg");
21.79 + gmyth_settings->mysql_username = g_string_new("mythtv");
21.80 + gmyth_settings->mysql_password = g_string_new("mythtv");
21.81 + gmyth_settings->database_type = g_string_new("mysql");
21.82 +
21.83 +}
21.84 +
21.85 +
21.86 +static void
21.87 +gmyth_settings_dispose (GObject *object)
21.88 +{
21.89 + GMythSettings *gmyth_settings = GMYTH_SETTINGS(object);
21.90 +
21.91 + if ( gmyth_settings->backend_hostname != NULL )
21.92 + g_string_free( gmyth_settings->backend_hostname, TRUE );
21.93 + if ( gmyth_settings->mysql_dbname != NULL )
21.94 + g_string_free( gmyth_settings->mysql_dbname, TRUE );
21.95 + if ( gmyth_settings->mysql_username != NULL )
21.96 + g_string_free( gmyth_settings->mysql_username, TRUE );
21.97 + if ( gmyth_settings->mysql_password != NULL )
21.98 + g_string_free( gmyth_settings->mysql_password, TRUE );
21.99 + if ( gmyth_settings->database_type != NULL )
21.100 + g_string_free( gmyth_settings->database_type, TRUE );
21.101 +
21.102 + G_OBJECT_CLASS (gmyth_settings_parent_class)->dispose (object);
21.103 +}
21.104 +
21.105 +static void
21.106 +gmyth_settings_finalize (GObject *object)
21.107 +{
21.108 + g_signal_handlers_destroy (object);
21.109 +
21.110 + G_OBJECT_CLASS (gmyth_settings_parent_class)->finalize (object);
21.111 +}
21.112 +
21.113 +/** Creates a new instance of GMythSettings.
21.114 + *
21.115 + * @return a new instance of GMythSettings.
21.116 + */
21.117 +GMythSettings*
21.118 +gmyth_settings_new (void)
21.119 +{
21.120 + GMythSettings *gmyth_settings = GMYTH_SETTINGS (g_object_new(GMYTH_SETTINGS_TYPE, NULL));
21.121 +
21.122 + return gmyth_settings;
21.123 +}
21.124 +
21.125 +static gboolean
21.126 +gmyth_settings_ensure_dir_exists (const gchar *dir)
21.127 +{
21.128 +
21.129 + g_debug ("[%s] \tdir = %s\n", __FUNCTION__, dir);
21.130 +
21.131 + if (g_file_test (dir, G_FILE_TEST_IS_DIR) == FALSE) {
21.132 + if (g_file_test (dir, G_FILE_TEST_EXISTS) == TRUE) {
21.133 + g_warning ("%s exists, please move it out of the way.", dir);
21.134 + return FALSE;
21.135 + }
21.136 +
21.137 + if (mkdir (dir, 488) != 0) {
21.138 + g_warning ("Failed to create directory %s.", dir);
21.139 + return FALSE;
21.140 + }
21.141 + }
21.142 +
21.143 + return TRUE;
21.144 +}
21.145 +
21.146 +static gboolean
21.147 +gmyth_settings_ensure_file_exists (const gchar *file_name) {
21.148 +
21.149 + int file = 0;
21.150 +
21.151 + if ( g_file_test( file_name, G_FILE_TEST_EXISTS ) == FALSE ) {
21.152 + g_debug ( "\n\tCreating %s file...\n", file_name );
21.153 + file = creat( file_name, S_IRWXU | S_IRWXO | S_IRWXG );
21.154 +
21.155 + if ( close( file ) == -1 )
21.156 + return FALSE;
21.157 + }
21.158 +
21.159 + return TRUE;
21.160 +}
21.161 +
21.162 +/** Loads the GMyth settings from the given file.
21.163 + *
21.164 + * @param gmyth_settings the GMythSettings instance.
21.165 + * @param filename The desired file to be opened.
21.166 + * @return TRUE if success, FALSE if error.
21.167 + */
21.168 +gboolean
21.169 +gmyth_settings_load_from_file (GMythSettings *gmyth_settings, GString *filename)
21.170 +{
21.171 + FILE *file_desc;
21.172 + char line[100];
21.173 +
21.174 + g_debug ("[%s] Loading GMyth settings file: %s", __FUNCTION__, filename->str);
21.175 +
21.176 + file_desc = fopen(filename->str, "r");
21.177 + if( file_desc == NULL) {
21.178 + g_warning ("[%s] Settings file %s could not be opened", __FUNCTION__, filename->str);
21.179 + return FALSE;
21.180 + }
21.181 +
21.182 + gmyth_settings->settings_file = g_string_new (filename->str);
21.183 +
21.184 + while(fgets(line, 100, file_desc)) {
21.185 + int i;
21.186 +
21.187 + /* Removes the new line characters from the end of line */
21.188 + for ( i = strlen(line)-1; i >= 0; i--) {
21.189 + if ( !g_ascii_iscntrl (line[i]) ) {
21.190 + line[i+1] = '\0';
21.191 + break;
21.192 + }
21.193 + }
21.194 +
21.195 + fill_settings_data(gmyth_settings, line);
21.196 + }
21.197 +
21.198 + fclose (file_desc);
21.199 +
21.200 + return TRUE;
21.201 +}
21.202 +
21.203 +/** Loads the GMyth settings from the standard settings file
21.204 + * (~/.mmyth/settings.dat).
21.205 + *
21.206 + * @param gmyth_settings the GMythSettings instance.
21.207 + * @return TRUE if success, FALSE if error.
21.208 + */
21.209 +gboolean
21.210 +gmyth_settings_load (GMythSettings *gmyth_settings)
21.211 +{
21.212 + GString* file_full_path = g_string_new( g_build_filename( g_get_home_dir(),
21.213 + GMYTH_SETTINGS_DIR, GMYTH_SETTINGS_FILE_NAME, NULL ) );
21.214 +
21.215 + gmyth_settings->settings_file = file_full_path;
21.216 +
21.217 + gmyth_settings_ensure_dir_exists( g_build_filename( g_get_home_dir(), GMYTH_SETTINGS_DIR, NULL ) );
21.218 +
21.219 + // Verifies if the file already exist
21.220 + if ( g_file_test( file_full_path->str, G_FILE_TEST_EXISTS ) == FALSE ) {
21.221 + g_debug ("[%s] Settings file does not exist. A new one will be created.\n", __FUNCTION__);
21.222 +
21.223 + if ( gmyth_settings_ensure_file_exists( file_full_path->str ) == FALSE )
21.224 + return FALSE;
21.225 +
21.226 + // Creates the file with default values (see _init function)
21.227 + return gmyth_settings_save (gmyth_settings);
21.228 +
21.229 + } else {
21.230 + g_debug ("[%s] Opening settings from file %s", __FUNCTION__, file_full_path->str);
21.231 +
21.232 + return gmyth_settings_load_from_file (gmyth_settings, file_full_path);
21.233 + }
21.234 +}
21.235 +
21.236 +/** Saves the current gmyth_settings to the settings file related to the
21.237 + * given instance.
21.238 + *
21.239 + * @param gmyth_settings the GMythSettings instance.
21.240 + * @return TRUE if success, FALSE if error.
21.241 + */
21.242 +gboolean
21.243 +gmyth_settings_save (GMythSettings *gmyth_settings)
21.244 +{
21.245 + FILE *file_desc;
21.246 +
21.247 + if (gmyth_settings->settings_file == NULL) {
21.248 + g_warning ("[%s] Settings were not loaded from file, could not save!", __FUNCTION__);
21.249 + }
21.250 +
21.251 + file_desc = fopen(gmyth_settings->settings_file->str, "w");
21.252 + if( file_desc == NULL) {
21.253 + g_warning ("GMYTH_SETTINGS: settings file %s not found", gmyth_settings->settings_file->str);
21.254 + return FALSE;
21.255 + }
21.256 +
21.257 + g_fprintf(file_desc, "#Maemo-Myth Settings\n");
21.258 +
21.259 + g_fprintf(file_desc, "#General settings related with mythtv database\n");
21.260 + g_fprintf(file_desc, "dbname=%s\n", gmyth_settings->mysql_dbname->str);
21.261 + g_fprintf(file_desc, "username=%s\n", gmyth_settings->mysql_username->str);
21.262 + g_fprintf(file_desc, "password=%s\n", gmyth_settings->mysql_password->str);
21.263 +
21.264 + g_fprintf(file_desc, "\n#General settings related with mythtv backend\n");
21.265 + g_fprintf(file_desc, "hostname=%s\n", gmyth_settings->backend_hostname->str);
21.266 + g_fprintf(file_desc, "backend_port=%d\n", gmyth_settings->backend_port);
21.267 +
21.268 + fclose (file_desc);
21.269 +
21.270 + g_debug ("[%s] Settings file saved", __FUNCTION__);
21.271 + return TRUE;
21.272 +}
21.273 +
21.274 +/** Gets the backend hostname from the settings.
21.275 + *
21.276 + * @param gmyth_settings the GMythSettings instance.
21.277 + * @return The loaded backend hostname, or the default value "127.0.0.1" if settings
21.278 + * file was not opened.
21.279 + */
21.280 +GString*
21.281 +gmyth_settings_get_backend_hostname (GMythSettings *gmyth_settings)
21.282 +{
21.283 + return g_string_new (gmyth_settings->backend_hostname->str);
21.284 +}
21.285 +
21.286 +/** Sets the backend hostname to the settings.
21.287 + *
21.288 + * @param gmyth_settings the GMythSettings instance.
21.289 + * @param new_hostname The new hostname.
21.290 + */
21.291 +void
21.292 +gmyth_settings_set_backend_hostname (GMythSettings *gmyth_settings, GString *new_hostname)
21.293 +{
21.294 + g_string_assign (gmyth_settings->backend_hostname, new_hostname->str);
21.295 +}
21.296 +
21.297 +/** Gets the user name to connect to backend database.
21.298 + *
21.299 + * @param gmyth_settings the GMythSettings instance.
21.300 + * @return The loaded user name, or the default value "mythtv" if settings
21.301 + * file was not opened.
21.302 + */
21.303 +GString*
21.304 +gmyth_settings_get_username (GMythSettings *gmyth_settings)
21.305 +{
21.306 + return g_string_new (gmyth_settings->mysql_username->str);
21.307 +}
21.308 +
21.309 +/** Sets the username to connect to backend database.
21.310 + *
21.311 + * @param gmyth_settings the GMythSettings instance.
21.312 + * @param new_username The new username.
21.313 + */
21.314 +void
21.315 +gmyth_settings_set_username (GMythSettings *gmyth_settings, GString *new_username)
21.316 +{
21.317 + g_string_assign (gmyth_settings->mysql_username, new_username->str);
21.318 +}
21.319 +
21.320 +/** Gets the database password from the settings file.
21.321 + *
21.322 + * @param gmyth_settings the GMythSettings instance.
21.323 + * @return The loaded password, or the default value "mythtv" if settings
21.324 + * file was not opened.
21.325 + */
21.326 +GString*
21.327 +gmyth_settings_get_password (GMythSettings *gmyth_settings)
21.328 +{
21.329 + return g_string_new (gmyth_settings->mysql_password->str);
21.330 +}
21.331 +
21.332 +/** Sets the database password.
21.333 + *
21.334 + * @param gmyth_settings the GMythSettings instance.
21.335 + * @param new_password The new password.
21.336 + */
21.337 +
21.338 +void
21.339 +gmyth_settings_set_password (GMythSettings *gmyth_settings, GString *new_password)
21.340 +{
21.341 + g_string_assign (gmyth_settings->mysql_password, new_password->str);
21.342 +}
21.343 +
21.344 +/** Gets the backend database name from the settings file.
21.345 + *
21.346 + * @param gmyth_settings the GMythSettings instance.
21.347 + * @return The loaded database name, or the default value "mythconverg" if settings
21.348 + * file was not opened.
21.349 + */
21.350 +GString*
21.351 +gmyth_settings_get_dbname (GMythSettings *gmyth_settings)
21.352 +{
21.353 + return g_string_new (gmyth_settings->mysql_dbname->str);
21.354 +}
21.355 +
21.356 +/** Sets the Mythtv database name to the settings.
21.357 + *
21.358 + * @param gmyth_settings the GMythSettings instance.
21.359 + * @param new_dbname The new database name.
21.360 + */
21.361 +
21.362 +void
21.363 +gmyth_settings_set_dbname (GMythSettings *gmyth_settings, GString *new_dbname)
21.364 +{
21.365 + g_string_assign (gmyth_settings->mysql_dbname, new_dbname->str);
21.366 +}
21.367 +
21.368 +/** Gets the backend port from the settings.
21.369 + *
21.370 + * @param gmyth_settings the GMythSettings instance.
21.371 + * @return The loaded backend port, or the default value "6543" if settings
21.372 + * file was not opened.
21.373 + */
21.374 +int
21.375 +gmyth_settings_get_backend_port (GMythSettings *gmyth_settings)
21.376 +{
21.377 + return gmyth_settings->backend_port;
21.378 +}
21.379 +
21.380 +/** Sets the backend port.
21.381 + *
21.382 + * @param gmyth_settings the GMythSettings instance.
21.383 + * @param new_port The new port.
21.384 + */
21.385 +void
21.386 +gmyth_settings_set_backend_port (GMythSettings *gmyth_settings, gint new_port)
21.387 +{
21.388 + gmyth_settings->backend_port = new_port;
21.389 +}
21.390 +
21.391 +
21.392 +static void
21.393 +fill_settings_data(GMythSettings *gmyth_settings, char* line)
21.394 +{
21.395 + gchar** str_splited;
21.396 +
21.397 + GString *gstr_splited;
21.398 + gstr_splited = g_string_new("");
21.399 + str_splited = g_strsplit (line, "=", -1);
21.400 +
21.401 + if(!(strcmp(str_splited[0], "hostname"))){
21.402 + g_string_assign(gstr_splited, str_splited[1]);
21.403 + gmyth_settings_set_backend_hostname(gmyth_settings, gstr_splited);
21.404 + }
21.405 + else if (!(strcmp(str_splited[0], "dbname"))){
21.406 + g_string_assign(gstr_splited, str_splited[1]);
21.407 + gmyth_settings_set_dbname(gmyth_settings, gstr_splited);
21.408 + }
21.409 + else if (!(strcmp(str_splited[0], "username"))){
21.410 + g_string_assign(gstr_splited, str_splited[1]);
21.411 + gmyth_settings_set_username(gmyth_settings, gstr_splited);
21.412 + }
21.413 + else if (!(strcmp(str_splited[0], "password"))){
21.414 + g_string_assign(gstr_splited, str_splited[1]);
21.415 + gmyth_settings_set_password(gmyth_settings, gstr_splited);
21.416 + }
21.417 + else if (!(strcmp(str_splited[0], "backend_port"))){
21.418 + gmyth_settings_set_backend_port(gmyth_settings, atoi(str_splited[1]));
21.419 + }
21.420 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/gmyth/src/gmyth_settings.h Thu Sep 28 15:41:06 2006 +0100
22.3 @@ -0,0 +1,103 @@
22.4 +/**
22.5 + * GMyth Library
22.6 + *
22.7 + * @file gmyth/gmyth_settings.h
22.8 + *
22.9 + * @brief <p> This component contains functions acessing and modifying
22.10 + * user and program settings.
22.11 + *
22.12 + * The standard settings file is created in the user home folder, in the
22.13 + * file ~/.mmyth/settings.dat.
22.14 + *
22.15 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
22.16 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
22.17 + *
22.18 + *//*
22.19 + *
22.20 + * This program is free software; you can redistribute it and/or modify
22.21 + * it under the terms of the GNU Lesser General Public License as published by
22.22 + * the Free Software Foundation; either version 2 of the License, or
22.23 + * (at your option) any later version.
22.24 + *
22.25 + * This program is distributed in the hope that it will be useful,
22.26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22.27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22.28 + * GNU General Public License for more details.
22.29 + *
22.30 + * You should have received a copy of the GNU Lesser General Public License
22.31 + * along with this program; if not, write to the Free Software
22.32 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22.33 + */
22.34 +
22.35 +#ifndef __GMYTH_SETTINGS_H__
22.36 +#define __GMYTH_SETTINGS_H__
22.37 +
22.38 +#include <glib-object.h>
22.39 +
22.40 +//#include <stdio.h>
22.41 +//#include <stdlib.h>
22.42 +//#include <string.h>
22.43 +//#include <netdb.h>
22.44 +//#include <sys/socket.h>
22.45 +//#include <unistd.h>
22.46 +
22.47 +G_BEGIN_DECLS
22.48 +
22.49 +#define GMYTH_SETTINGS_TYPE (gmyth_settings_get_type ())
22.50 +#define GMYTH_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SETTINGS_TYPE, GMythSettings))
22.51 +#define GMYTH_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SETTINGS_TYPE, GMythSettingsClass))
22.52 +#define IS_GMYTH_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SETTINGS_TYPE))
22.53 +#define IS_GMYTH_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SETTINGS_TYPE))
22.54 +#define GMYTH_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SETTINGS_TYPE, GMythSettingsClass))
22.55 +
22.56 +
22.57 +typedef struct _GMythSettings GMythSettings;
22.58 +typedef struct _GMythSettingsClass GMythSettingsClass;
22.59 +
22.60 +struct _GMythSettingsClass
22.61 +{
22.62 + GObjectClass parent_class;
22.63 +
22.64 + /* callbacks */
22.65 + /* no one for now */
22.66 +};
22.67 +
22.68 +struct _GMythSettings
22.69 +{
22.70 + GObject parent;
22.71 +
22.72 + GString *settings_file;
22.73 +
22.74 + GString *backend_hostname;
22.75 + int backend_port;
22.76 +
22.77 + GString *mysql_dbname;
22.78 + GString *mysql_username;
22.79 + GString *mysql_password;
22.80 + // FIXME: Why do we need database_type? Do we intend to support other dbs?
22.81 + GString *database_type;
22.82 +};
22.83 +
22.84 +
22.85 +GType gmyth_settings_get_type (void);
22.86 +
22.87 +GMythSettings* gmyth_settings_new (void);
22.88 +gboolean gmyth_settings_load_from_file (GMythSettings *gmyth_settings, GString *filename);
22.89 +gboolean gmyth_settings_load (GMythSettings *msettings);
22.90 +gboolean gmyth_settings_save (GMythSettings *gmyth_settings);
22.91 +
22.92 +GString* gmyth_settings_get_backend_hostname (GMythSettings *gmyth_settings);
22.93 +void gmyth_settings_set_backend_hostname (GMythSettings *gmyth_settings, GString *new_hostname);
22.94 +GString* gmyth_settings_get_username (GMythSettings *gmyth_settings);
22.95 +void gmyth_settings_set_username (GMythSettings *gmyth_settings, GString *new_username);
22.96 +GString* gmyth_settings_get_password (GMythSettings *gmyth_settings);
22.97 +void gmyth_settings_set_password (GMythSettings *gmyth_settings, GString *new_password);
22.98 +GString* gmyth_settings_get_dbname (GMythSettings *gmyth_settings);
22.99 +void gmyth_settings_set_dbname (GMythSettings *gmyth_settings, GString *new_dbname);
22.100 +int gmyth_settings_get_backend_port (GMythSettings *gmyth_settings);
22.101 +void gmyth_settings_set_backend_port (GMythSettings *gmyth_settings, gint new_port);
22.102 +
22.103 +
22.104 +G_END_DECLS
22.105 +
22.106 +#endif /* __GMYTH_SETTINGS_H__ */
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/gmyth/src/gmyth_socket.c Thu Sep 28 15:41:06 2006 +0100
23.3 @@ -0,0 +1,708 @@
23.4 +/**
23.5 + * GMyth Library
23.6 + *
23.7 + * @file gmyth/gmyth_socket.c
23.8 + *
23.9 + * @brief <p> MythTV socket implementation, according to the MythTV Project
23.10 + * (www.mythtv.org).
23.11 + *
23.12 + * This component provides basic socket functionalities to interact with
23.13 + * the Mythtv backend.
23.14 + * <p>
23.15 + *
23.16 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
23.17 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
23.18 + *
23.19 + *//*
23.20 + *
23.21 + * This program is free software; you can redistribute it and/or modify
23.22 + * it under the terms of the GNU Lesser General Public License as published by
23.23 + * the Free Software Foundation; either version 2 of the License, or
23.24 + * (at your option) any later version.
23.25 + *
23.26 + * This program is distributed in the hope that it will be useful,
23.27 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23.28 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23.29 + * GNU General Public License for more details.
23.30 + *
23.31 + * You should have received a copy of the GNU Lesser General Public License
23.32 + * along with this program; if not, write to the Free Software
23.33 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23.34 + */
23.35 +
23.36 +#include <glib.h>
23.37 +#include <glib/gprintf.h>
23.38 +
23.39 +#include <arpa/inet.h>
23.40 +#include <sys/types.h>
23.41 +#include <sys/socket.h>
23.42 +#include <netdb.h>
23.43 +#include <errno.h>
23.44 +#include <stdlib.h>
23.45 +
23.46 +#include "gmyth_socket.h"
23.47 +#include "gmyth_stringlist.h"
23.48 +#include "gmyth_context.h"
23.49 +
23.50 +#define BUFLEN 512
23.51 +#define MYTH_SEPARATOR "[]:[]"
23.52 +#define MYTH_PROTOCOL_FIELD_SIZE 8
23.53 +
23.54 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
23.55 +
23.56 +static void gmyth_socket_class_init (GMythSocketClass *klass);
23.57 +static void gmyth_socket_init (GMythSocket *object);
23.58 +
23.59 +static void gmyth_socket_dispose (GObject *object);
23.60 +static void gmyth_socket_finalize (GObject *object);
23.61 +
23.62 +G_DEFINE_TYPE(GMythSocket, gmyth_socket, G_TYPE_OBJECT)
23.63 +
23.64 +static void
23.65 +gmyth_socket_class_init (GMythSocketClass *klass)
23.66 +{
23.67 + GObjectClass *gobject_class;
23.68 +
23.69 + gobject_class = (GObjectClass *) klass;
23.70 +
23.71 + gobject_class->dispose = gmyth_socket_dispose;
23.72 + gobject_class->finalize = gmyth_socket_finalize;
23.73 +}
23.74 +
23.75 +static void
23.76 +gmyth_socket_init (GMythSocket *gmyth_socket)
23.77 +{
23.78 +}
23.79 +
23.80 +/** Gets the some important address translation info, from the client socket
23.81 + * that will open a connection.
23.82 + *
23.83 + * @return gint that represents the error number from getaddrinfo().
23.84 + */
23.85 +static gint
23.86 +gmyth_socket_toaddrinfo( gchar *addr, gint port, struct addrinfo **addrInfo )
23.87 +{
23.88 + struct addrinfo hints;
23.89 + gchar *portStr = g_strnfill( 32, ' ' );
23.90 + gint errorn = EADDRNOTAVAIL;
23.91 +
23.92 + memset( &hints, 0, sizeof(hints) );
23.93 + hints.ai_family = AF_INET;
23.94 + hints.ai_socktype = SOCK_STREAM;
23.95 + /* hints.ai_flags = AI_NUMERICHOST; */
23.96 + if ( port != -1 )
23.97 + sprintf(portStr, "%d", port);
23.98 + else
23.99 + portStr = NULL;
23.100 +
23.101 + g_debug( "[%s] Address: %s, port: %s\n", __FUNCTION__, addr, portStr );
23.102 + if ( ( errorn = getaddrinfo(addr, portStr, &hints, addrInfo) ) != 0 ) {
23.103 + g_printerr( "[%s] Socket ERROR: %s\n", __FUNCTION__, gai_strerror(errorn) );
23.104 + }
23.105 +
23.106 + return errorn;
23.107 +}
23.108 +
23.109 +/** This function retrieves the local hostname of the
23.110 + * client machine.
23.111 + *
23.112 + * @return GString* get local hostname.
23.113 + */
23.114 +GString *
23.115 +gmyth_socket_get_local_hostname( )
23.116 +{
23.117 + GString *str = g_string_new("");
23.118 +
23.119 + gchar *localhostname = g_strnfill( 1024, ' ' );
23.120 + gchar *localaddr = g_strdup( "127.0.0.1" );
23.121 +
23.122 + gboolean found_addr = FALSE;
23.123 +
23.124 + struct addrinfo* addr_info_data = NULL, *addr_info0 = NULL;
23.125 +
23.126 + struct sockaddr_in* sa = NULL;
23.127 +
23.128 + g_static_mutex_lock( &mutex );
23.129 +
23.130 + gethostname(localhostname, 1024);
23.131 +
23.132 + gint err = gmyth_socket_toaddrinfo( localhostname, -1, &addr_info_data );
23.133 +
23.134 + addr_info0 = addr_info_data;
23.135 +
23.136 + while( addr_info0 != NULL && addr_info0->ai_addr != NULL &&
23.137 + ( sa = (struct sockaddr_in*)addr_info0->ai_addr ) != NULL && !found_addr ) {
23.138 + localaddr = inet_ntoa( sa->sin_addr );
23.139 + if ( localaddr != NULL )
23.140 + g_print( "[%s] localaddr = %s\n", __FUNCTION__, localaddr );
23.141 +
23.142 + if ( localaddr != NULL && ( g_strrstr( localaddr, "127" ) == NULL ) ) {
23.143 + g_print( "[%s] Trying the address %s (err = %d).\n",
23.144 + __FUNCTION__, localaddr, err );
23.145 + g_print( "[%s] Found local address %s!\n", __FUNCTION__, localaddr );
23.146 + str = g_string_assign( str, g_strdup( localaddr ) );
23.147 + found_addr = TRUE;
23.148 + break;
23.149 + }
23.150 + addr_info0 = addr_info0->ai_next;
23.151 + };
23.152 +
23.153 + if ( found_addr == FALSE ) {
23.154 + g_warning("[%s] Could not determine the local hostname address. Setting to %s\n",
23.155 + __FUNCTION__, localaddr );
23.156 + if ( localaddr != NULL )
23.157 + str = g_string_assign( str, localaddr );
23.158 + else
23.159 + str = g_string_assign( str, "127.0.0.1" );
23.160 + }
23.161 +
23.162 + g_static_mutex_unlock( &mutex );
23.163 +
23.164 + if (localhostname!=NULL)
23.165 + g_free( localhostname );
23.166 +
23.167 + return str;
23.168 +}
23.169 +
23.170 +static void
23.171 +gmyth_socket_dispose (GObject *object)
23.172 +{
23.173 + GMythSocket *gmyth_socket = GMYTH_SOCKET(object);
23.174 +
23.175 + gmyth_socket_close_connection (gmyth_socket);
23.176 + /* disconnect socket */
23.177 + G_OBJECT_CLASS (gmyth_socket_parent_class)->dispose (object);
23.178 +}
23.179 +
23.180 +static void
23.181 +gmyth_socket_finalize (GObject *object)
23.182 +{
23.183 + g_signal_handlers_destroy (object);
23.184 +
23.185 + G_OBJECT_CLASS (gmyth_socket_parent_class)->finalize (object);
23.186 +}
23.187 +
23.188 +/** Creates a new instance of GMythSocket.
23.189 + *
23.190 + * @return a new instance of GMythSocket.
23.191 + */
23.192 +GMythSocket*
23.193 +gmyth_socket_new ()
23.194 +{
23.195 + GMythSocket *gmyth_socket = GMYTH_SOCKET (g_object_new(GMYTH_SOCKET_TYPE, NULL));
23.196 +
23.197 + gmyth_socket->sd_io_ch = NULL;
23.198 +
23.199 + gmyth_socket->hostname = g_strdup("");
23.200 +
23.201 + gmyth_socket->port = 6543;
23.202 +
23.203 + return gmyth_socket;
23.204 +}
23.205 +
23.206 +/** Connects to the backend.
23.207 + *
23.208 + * @param gmyth_socket The GMythSocket instance.
23.209 + * @param hostname The backend hostname or IP address.
23.210 + * @param port The backend port.
23.211 + * @return TRUE if success, FALSE if error.
23.212 + */
23.213 +gboolean
23.214 +gmyth_socket_connect (GMythSocket **gmyth_socket,
23.215 + gchar *hostname, gint port)
23.216 +{
23.217 + struct addrinfo *addr_info_data = NULL, *addr_info0 = NULL;
23.218 + gint ret_code = -1;
23.219 + gint errno;
23.220 + gboolean ret = TRUE;
23.221 +
23.222 + if ( hostname == NULL )
23.223 + g_printerr ( "[%s] Invalid hostname parameter!\n", __FUNCTION__ );
23.224 +
23.225 + errno = gmyth_socket_toaddrinfo( hostname, port, &addr_info_data );
23.226 +
23.227 + g_return_val_if_fail( addr_info_data != NULL, FALSE );
23.228 +
23.229 + /* store hostname and port number */
23.230 + (*gmyth_socket)->hostname = g_strdup( hostname );
23.231 + (*gmyth_socket)->port = port;
23.232 +
23.233 + for ( addr_info0 = addr_info_data; addr_info0; addr_info0 = addr_info_data->ai_next ) {
23.234 +
23.235 + struct sockaddr_in *sa = (struct sockaddr_in*)addr_info0->ai_addr;
23.236 + /* init socket descriptor */
23.237 + (*gmyth_socket)->sd = socket( addr_info0->ai_family, addr_info0->ai_socktype,
23.238 + addr_info0->ai_protocol );
23.239 +
23.240 + if ( (*gmyth_socket)->sd < 0 )
23.241 + continue;
23.242 +
23.243 + g_debug( "[%s] hostname = %s, sock_fd = %d, addr = %s, addr_len = %d, \
23.244 + ai_family = %d, ai_protocol = %d\n",
23.245 + __FUNCTION__, hostname, (*gmyth_socket)->sd, inet_ntoa( sa->sin_addr ),
23.246 + addr_info0->ai_addrlen, addr_info0->ai_family, addr_info0->ai_protocol );
23.247 +
23.248 + if ( ( ret_code = connect( (*gmyth_socket)->sd, (struct sockaddr *)addr_info0->ai_addr,
23.249 + addr_info0->ai_addrlen ) ) < 0 )
23.250 + {
23.251 + g_printerr( "[%s] Error connecting to backend!\n", __FUNCTION__ );
23.252 + if ( ret_code == ETIMEDOUT )
23.253 + g_printerr( "[%s]\tBackend host unreachable!\n", __FUNCTION__ );
23.254 +
23.255 + g_printerr( "ERROR: %s\n", gai_strerror(ret_code) );
23.256 + continue;
23.257 + }
23.258 +
23.259 + /* only will be reached if none of the error above occurred */
23.260 + break;
23.261 +
23.262 + }
23.263 +
23.264 + (*gmyth_socket)->sd_io_ch = g_io_channel_unix_new( (*gmyth_socket)->sd );
23.265 +
23.266 + //if (addr_info_data != NULL )
23.267 + //freeaddrinfo( addr_info_data );
23.268 +
23.269 + ret = ( ret_code == 0 ) ? TRUE : FALSE ;
23.270 +
23.271 + return ret;
23.272 +
23.273 +}
23.274 +
23.275 +/** Gets the GIOChannel associated to the given GMythSocket.
23.276 + *
23.277 + * @param gmyth_socket The GMythSocket instance.
23.278 + */
23.279 +GIOChannel *
23.280 +gmyth_socket_get_io_channel( GMythSocket *gmyth_socket )
23.281 +{
23.282 + g_return_val_if_fail( gmyth_socket != NULL, NULL );
23.283 +
23.284 + return gmyth_socket->sd_io_ch;
23.285 +}
23.286 +
23.287 +/** Verifies if the socket is able to read.
23.288 + *
23.289 + * @param gmyth_socket The GMythSocket instance.
23.290 + * @return TRUE if the socket is able to read, FALSE if not.
23.291 + */
23.292 +gboolean
23.293 +gmyth_socket_is_able_to_read( GMythSocket *gmyth_socket )
23.294 +{
23.295 + gboolean ret = TRUE;
23.296 +
23.297 + /* verify if the input (read) buffer is ready to receive data */
23.298 + GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
23.299 +
23.300 + if ( ( io_cond & G_IO_IN ) == 0 ) {
23.301 + g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
23.302 + ret = FALSE;
23.303 + }
23.304 +
23.305 + return ret;
23.306 +
23.307 +}
23.308 +
23.309 +/** Verifies if the socket is able to write.
23.310 + *
23.311 + * @param gmyth_socket The GMythSocket instance.
23.312 + * @return TRUE if the socket is able to write, FALSE if not.
23.313 + */
23.314 +gboolean
23.315 +gmyth_socket_is_able_to_write( GMythSocket *gmyth_socket )
23.316 +{
23.317 + gboolean ret = TRUE;
23.318 +
23.319 + /* verify if the input (read) buffer is ready to receive data */
23.320 + GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
23.321 +
23.322 + if ( ( ( io_cond & G_IO_OUT ) == 0 ) || ( ( io_cond & G_IO_HUP ) == 0 ) ) {
23.323 + g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
23.324 + ret = FALSE;
23.325 + }
23.326 +
23.327 + return ret;
23.328 +
23.329 +}
23.330 +
23.331 +/** Sends a command to the backend.
23.332 + *
23.333 + * @param gmyth_socket the GMythSocket instance.
23.334 + * @param command The string command to be sent.
23.335 + */
23.336 +gboolean
23.337 +gmyth_socket_send_command(GMythSocket *gmyth_socket, GString *command)
23.338 +{
23.339 + gboolean ret = TRUE;
23.340 +
23.341 + GIOStatus io_status = G_IO_STATUS_NORMAL;
23.342 + //GIOCondition io_cond;
23.343 + GError* error = NULL;
23.344 + gchar *buffer = NULL;
23.345 +
23.346 + gsize bytes_written = 0;
23.347 +
23.348 + if( command == NULL || ( command->len <= 0 ) ) {
23.349 + g_warning ("[%s] Invalid NULL command parameter!\n", __FUNCTION__);
23.350 + ret = FALSE;
23.351 + goto done;
23.352 + }
23.353 +
23.354 + g_static_mutex_lock( &mutex );
23.355 + g_debug ("[%s] Sending command to backend: %s\n", __FUNCTION__, command->str);
23.356 +
23.357 + /*
23.358 + io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
23.359 +
23.360 + if ( ( io_cond & G_IO_IN ) == 0 ) {
23.361 + g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
23.362 + ret = FALSE;
23.363 + goto done;
23.364 + }
23.365 + */
23.366 +
23.367 + buffer = g_strnfill( BUFLEN, ' ' );
23.368 + snprintf( buffer, MYTH_PROTOCOL_FIELD_SIZE+1, "%-8d", command->len);
23.369 + g_print( "[%s] buffer = [%s]\n", __FUNCTION__, buffer );
23.370 +
23.371 + command = g_string_prepend(command, buffer);
23.372 +
23.373 + g_print( "[%s] command = [%s]\n", __FUNCTION__, command->str );
23.374 +
23.375 + /* write bytes to socket */
23.376 + io_status = g_io_channel_write_chars( gmyth_socket->sd_io_ch, command->str,
23.377 + command->len, &bytes_written, &error );
23.378 +
23.379 +
23.380 + if( (io_status == G_IO_STATUS_ERROR) || ( bytes_written <= 0 ) ) {
23.381 + g_warning ("[%s] Error while writing to socket", __FUNCTION__);
23.382 + ret = FALSE;
23.383 + } else if ( bytes_written < command->len ) {
23.384 + g_warning ("[%s] Not all data was written socket", __FUNCTION__);
23.385 + ret = FALSE;
23.386 + }
23.387 +
23.388 + io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
23.389 +
23.390 + if ( ( bytes_written != command->len ) || ( io_status == G_IO_STATUS_ERROR ) )
23.391 + {
23.392 + g_warning ("[%s] Some problem occurred when sending data to the socket\n", __FUNCTION__);
23.393 +
23.394 + ret = TRUE;
23.395 + }
23.396 +
23.397 + g_static_mutex_unlock( &mutex );
23.398 +done:
23.399 + if ( error != NULL ) {
23.400 + g_printerr( "[%s] Error found reading data from IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
23.401 + ret = FALSE;
23.402 + g_error_free( error );
23.403 + }
23.404 +
23.405 + if ( buffer!= NULL )
23.406 + g_free( buffer );
23.407 +
23.408 + return ret;
23.409 +}
23.410 +
23.411 +/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
23.412 + * supported by the backend and send the "ANN" command.
23.413 + *
23.414 + * @param gmyth_socket the GMythSocket instance.
23.415 + * @param hostname_backend The backend hostname or IP address.
23.416 + * @param port The backend port to connect.
23.417 + * @param blocking_client A flag to choose between blocking and non-blocking
23.418 + * backend connection.
23.419 + */
23.420 +gboolean
23.421 +gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket,
23.422 + gchar *hostname_backend, int port, gboolean blocking_client)
23.423 +{
23.424 + if (!gmyth_socket_connect (&gmyth_socket, hostname_backend, port)) {
23.425 + g_warning ("[%s] Could not open socket to backend machine", __FUNCTION__);
23.426 + return FALSE;
23.427 + }
23.428 +
23.429 + if (gmyth_socket_check_protocol_version (gmyth_socket)) {
23.430 +
23.431 + GString *result;
23.432 + GString *base_str = g_string_new("");
23.433 + GString *hostname = NULL;
23.434 +
23.435 + hostname = gmyth_socket_get_local_hostname();
23.436 +
23.437 + g_string_printf(base_str, "ANN %s %s 0",
23.438 + (blocking_client ? "Playback" : "Monitor"),
23.439 + hostname->str);
23.440 +
23.441 + g_debug ("[%s] Connection command sent to backend: %s", __FUNCTION__, base_str->str);
23.442 +
23.443 + gmyth_socket_send_command (gmyth_socket, base_str);
23.444 + result = gmyth_socket_receive_response(gmyth_socket);
23.445 +
23.446 + if (result != NULL) {
23.447 + g_debug ("[%s] Response received from backend: %s", __FUNCTION__, result->str);
23.448 + g_string_free (result, TRUE);
23.449 + }
23.450 +
23.451 + g_string_free (hostname, TRUE);
23.452 + g_string_free (base_str, TRUE);
23.453 +
23.454 + return TRUE;
23.455 + } else {
23.456 + g_warning ("[%s] GMythSocket could not connect to the backend", __FUNCTION__);
23.457 + return FALSE;
23.458 + }
23.459 +
23.460 +}
23.461 +
23.462 +/** Closes the socket connection to the backend.
23.463 + *
23.464 + * @param gmyth_socket The GMythSocket instance.
23.465 + */
23.466 +void
23.467 +gmyth_socket_close_connection (GMythSocket *gmyth_socket)
23.468 +{
23.469 + close (gmyth_socket->sd);
23.470 +}
23.471 +
23.472 +
23.473 +/** Try the MythTV version numbers, and get the version returned by
23.474 + * the possible REJECT message, in order to contruct a new
23.475 + * MythTV version request.
23.476 + *
23.477 + * @param gmyth_socket The GMythSocket instance.
23.478 + * @param mythtv_version The Mythtv protocol version to be tested
23.479 + */
23.480 +gboolean
23.481 +gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket, gint mythtv_version)
23.482 +{
23.483 + GString *response;
23.484 + GString *payload;
23.485 + gchar *new_version = g_strdup("");
23.486 + gboolean res = TRUE;
23.487 +
23.488 +try_new_version:
23.489 + payload = g_string_new ("MYTH_PROTO_VERSION");
23.490 + g_string_append_printf( payload, " %d", mythtv_version );
23.491 +
23.492 + gmyth_socket_send_command(gmyth_socket, payload);
23.493 + response = gmyth_socket_receive_response(gmyth_socket);
23.494 +
23.495 + if (response == NULL) {
23.496 + g_warning ("[%s] Check protocol version error! Not answered!", __FUNCTION__);
23.497 + res = FALSE;
23.498 + goto done;
23.499 + }
23.500 +
23.501 + res = g_str_has_prefix (response->str, "ACCEPT");
23.502 + if (!res) {
23.503 + g_warning ("[%s] Protocol version request error: %s", __FUNCTION__, response->str);
23.504 + /* get the version number returned by the REJECT message */
23.505 + if ( ( res = g_str_has_prefix (response->str, "REJECT") ) == TRUE ) {
23.506 + new_version = g_strrstr( response->str, "]" );
23.507 + if (new_version!=NULL) {
23.508 + ++new_version; /* skip ']' character */
23.509 + if ( new_version != NULL ) {
23.510 + g_print( "[%s] got MythTV version = %s\n", __FUNCTION__, new_version );
23.511 + mythtv_version = g_ascii_strtoull( g_strdup( new_version ), NULL, 10 );
23.512 + /* do reconnection to the socket (socket is closed if the MythTV version was wrong) */
23.513 + gmyth_socket_connect( &gmyth_socket, gmyth_socket->hostname, gmyth_socket->port );
23.514 + /* g_free( new_version ); */
23.515 + goto try_new_version;
23.516 + }
23.517 + }
23.518 + }
23.519 + }
23.520 +
23.521 +done:
23.522 + if ( payload != NULL )
23.523 + g_string_free (payload, TRUE);
23.524 + if ( response != NULL )
23.525 + g_string_free (response, TRUE);
23.526 +// if (new_version!=NULL)
23.527 +// g_free( new_version );
23.528 +
23.529 + return res;
23.530 +}
23.531 +
23.532 +/** Verifies if the Mythtv backend supported the GMyth supported version.
23.533 + *
23.534 + * @param gmyth_socket The GMythSocket instance.
23.535 + * @return TRUE if supports, FALSE if not.
23.536 + */
23.537 +gboolean
23.538 +gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket)
23.539 +{
23.540 + return gmyth_socket_check_protocol_version_number( gmyth_socket, MYTHTV_VERSION_DEFAULT );
23.541 +}
23.542 +
23.543 +/** Receives a backend answer after a gmyth_socket_send_command_call ().
23.544 + *
23.545 + * @param gmyth_socket The GMythSocket instance.
23.546 + * @return The response received, or NULL if error or nothing was received.
23.547 + */
23.548 +GString*
23.549 +gmyth_socket_receive_response(GMythSocket *gmyth_socket)
23.550 +{
23.551 + GIOStatus io_status = G_IO_STATUS_NORMAL;
23.552 + GError* error = NULL;
23.553 + gchar *buffer = NULL;
23.554 +
23.555 + GString *str = NULL;
23.556 +
23.557 + gsize bytes_read = 0;
23.558 + gint len = 0;
23.559 + GIOCondition io_cond;
23.560 +
23.561 + g_return_val_if_fail( gmyth_socket != NULL, NULL );
23.562 +
23.563 + /* verify if the input (read) buffer is ready to receive data */
23.564 +
23.565 + buffer = g_strnfill( BUFLEN, ' ' );
23.566 +
23.567 + g_static_mutex_lock( &mutex );
23.568 +
23.569 + io_status = g_io_channel_read_chars( gmyth_socket->sd_io_ch, buffer, MYTH_PROTOCOL_FIELD_SIZE, &bytes_read, &error );
23.570 +
23.571 +
23.572 + /* verify if the input (read) buffer is ready to receive data */
23.573 + io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
23.574 +
23.575 + g_print ( "[%s] Bytes read = %d\n", __FUNCTION__, bytes_read );
23.576 +
23.577 + if( (io_status == G_IO_STATUS_ERROR) || (bytes_read <= 0) ) {
23.578 + g_warning ("[%s] Error in mythprotocol response from backend\n", __FUNCTION__);
23.579 + str = NULL;
23.580 + //return NULL;
23.581 + } else {
23.582 +
23.583 + io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
23.584 + /* verify if the input (read) buffer is ready to receive data */
23.585 + io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
23.586 +
23.587 + if ( ( io_cond & G_IO_IN ) != 0 ) {
23.588 +
23.589 + snprintf( buffer, MYTH_PROTOCOL_FIELD_SIZE+1, "%-8s", g_strdup(buffer));
23.590 + g_print( "[%s] buffer = [%s]\n", __FUNCTION__, buffer );
23.591 +
23.592 + /* removes trailing whitespace */
23.593 + buffer = g_strstrip( buffer );
23.594 +
23.595 + len = (gint)strtoull ( buffer, NULL, 10 );
23.596 +
23.597 + bytes_read = 0;
23.598 + io_status = g_io_channel_read_chars( gmyth_socket->sd_io_ch, buffer, len, &bytes_read, &error );
23.599 + buffer[bytes_read] = '\0';
23.600 + }
23.601 + }
23.602 +
23.603 + g_static_mutex_unlock( &mutex );
23.604 +
23.605 + g_debug ("[%s] Response received from backend: {%s}\n", __FUNCTION__, buffer);
23.606 +
23.607 + if ( ( bytes_read != len ) || ( io_status == G_IO_STATUS_ERROR ) )
23.608 + str = NULL;
23.609 + else
23.610 + str = g_string_new( buffer );
23.611 +
23.612 + if ( buffer != NULL )
23.613 + g_free( buffer );
23.614 +
23.615 + if ( error != NULL ) {
23.616 + g_printerr( "[%s] Error found receiving response from the IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
23.617 + str = NULL;
23.618 + g_error_free( error );
23.619 + }
23.620 +
23.621 + return str;
23.622 +}
23.623 +
23.624 +/** Format a Mythtv command from the str_list entries and send it to backend.
23.625 + *
23.626 + * @param gmyth_socket The GMythSocket instance.
23.627 + * @param str_list The string list to form the command
23.628 + * @return TRUE if command was sent, FALSE if any error happens.
23.629 + */
23.630 +gboolean
23.631 +gmyth_socket_write_stringlist(GMythSocket *gmyth_socket, GMythStringList* str_list)
23.632 +{
23.633 +
23.634 + GList *tmp_list;
23.635 + GPtrArray *ptr_array;
23.636 + gchar *str_array;
23.637 +
23.638 + g_static_mutex_lock( &mutex );
23.639 +
23.640 + ptr_array = g_ptr_array_sized_new(g_list_length(str_list->glist));
23.641 +
23.642 + g_print( "[%s] Number of parameters = %d\n", __FUNCTION__, g_list_length(str_list->glist) );
23.643 +
23.644 + // FIXME: change this implementation!
23.645 + tmp_list = str_list->glist;
23.646 + for(; tmp_list; tmp_list = tmp_list->next) {
23.647 + if ( tmp_list->data != NULL )
23.648 + g_ptr_array_add(ptr_array, ((GString*)tmp_list->data)->str);
23.649 + }
23.650 + g_ptr_array_add(ptr_array, NULL); // g_str_joinv() needs a NULL terminated string
23.651 +
23.652 + str_array = g_strjoinv (MYTH_SEPARATOR, (gchar **) (ptr_array->pdata));
23.653 +
23.654 + g_static_mutex_unlock( &mutex );
23.655 +
23.656 + // Sends message to backend
23.657 + // TODO: implement looping to send remaining data, and add timeout testing!
23.658 + gmyth_socket_send_command(gmyth_socket, g_string_new(str_array));
23.659 +
23.660 + g_free (str_array);
23.661 + g_ptr_array_free (ptr_array, TRUE);
23.662 +
23.663 + return TRUE;
23.664 +}
23.665 +
23.666 +/* Receives a backend command response and split it into the given string list.
23.667 + *
23.668 + * @param gmyth_socket The GMythSocket instance.
23.669 + * @param str_list the string list to be filled.
23.670 + * @return The number of received strings.
23.671 + */
23.672 +gint
23.673 +gmyth_socket_read_stringlist (GMythSocket *gmyth_socket, GMythStringList* str_list)
23.674 +{
23.675 + GString *response;
23.676 + gchar **str_array;
23.677 + gint i;
23.678 +
23.679 + response = gmyth_socket_receive_response(gmyth_socket);
23.680 + g_static_mutex_lock( &mutex );
23.681 +
23.682 + gmyth_string_list_clear_all (str_list);
23.683 + str_array = g_strsplit (response->str, MYTH_SEPARATOR, -1);
23.684 +
23.685 + for (i=0; i< g_strv_length (str_array); i++) {
23.686 + gmyth_string_list_append_string (str_list, g_string_new (str_array[i]));
23.687 + }
23.688 + g_static_mutex_unlock( &mutex );
23.689 +
23.690 + g_string_free (response, TRUE);
23.691 + g_strfreev (str_array);
23.692 +
23.693 + return gmyth_string_list_length (str_list);
23.694 +}
23.695 +
23.696 +/** Formats a Mythtv protocol command based on str_list and sends it to
23.697 + * the connected backend. The backend response is overwritten into str_list.
23.698 + *
23.699 + * @param gmyth_socket The GMythSocket instance.
23.700 + * @param str_list The string list to be sent, and on which the answer
23.701 + * will be written.
23.702 + * @return TRUE if command was sent and an answer was received, FALSE if any
23.703 + * error happens.
23.704 + */
23.705 +gint
23.706 +gmyth_socket_sendreceive_stringlist (GMythSocket *gmyth_socket, GMythStringList *str_list)
23.707 +{
23.708 + gmyth_socket_write_stringlist (gmyth_socket, str_list);
23.709 +
23.710 + return gmyth_socket_read_stringlist (gmyth_socket, str_list);
23.711 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/gmyth/src/gmyth_socket.h Thu Sep 28 15:41:06 2006 +0100
24.3 @@ -0,0 +1,116 @@
24.4 +/**
24.5 + * GMyth Library
24.6 + *
24.7 + * @file gmyth/gmyth_socket.h
24.8 + *
24.9 + * @brief <p> MythTV socket implementation, according to the MythTV Project
24.10 + * (www.mythtv.org).
24.11 + *
24.12 + * This component provides basic socket functionalities to interact with
24.13 + * the Mythtv backend.
24.14 + * <p>
24.15 + *
24.16 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
24.17 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
24.18 + *
24.19 + *//*
24.20 + *
24.21 + * This program is free software; you can redistribute it and/or modify
24.22 + * it under the terms of the GNU Lesser General Public License as published by
24.23 + * the Free Software Foundation; either version 2 of the License, or
24.24 + * (at your option) any later version.
24.25 + *
24.26 + * This program is distributed in the hope that it will be useful,
24.27 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24.28 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24.29 + * GNU General Public License for more details.
24.30 + *
24.31 + * You should have received a copy of the GNU Lesser General Public License
24.32 + * along with this program; if not, write to the Free Software
24.33 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24.34 + */
24.35 +
24.36 +#ifndef __GMYTH_SOCKET_H__
24.37 +#define __GMYTH_SOCKET_H__
24.38 +
24.39 +#include <glib-object.h>
24.40 +
24.41 +#include <string.h>
24.42 +#include <netdb.h>
24.43 +#include <sys/socket.h>
24.44 +#include <unistd.h>
24.45 +#include <glib.h>
24.46 +
24.47 +#include "gmyth_stringlist.h"
24.48 +
24.49 +G_BEGIN_DECLS
24.50 +
24.51 +#define GMYTH_SOCKET_TYPE (gmyth_socket_get_type ())
24.52 +#define GMYTH_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE, GMythSocket))
24.53 +#define GMYTH_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE, GMythSocketClass))
24.54 +#define IS_GMYTH_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE))
24.55 +#define IS_GMYTH_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE))
24.56 +#define GMYTH_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SOCKET_TYPE, GMythSocketClass))
24.57 +
24.58 +
24.59 +typedef struct _GMythSocket GMythSocket;
24.60 +typedef struct _GMythSocketClass GMythSocketClass;
24.61 +
24.62 +struct _GMythSocketClass
24.63 +{
24.64 + GObjectClass parent_class;
24.65 +
24.66 + /* callbacks */
24.67 + /* no one for now */
24.68 +};
24.69 +
24.70 +struct _GMythSocket
24.71 +{
24.72 + GObject parent;
24.73 +
24.74 + /* socket descriptor */
24.75 + int sd;
24.76 + GIOChannel *sd_io_ch;
24.77 +
24.78 + gchar *hostname;
24.79 + gint port;
24.80 +};
24.81 +
24.82 +
24.83 +GType gmyth_socket_get_type (void);
24.84 +
24.85 +GMythSocket * gmyth_socket_new (void);
24.86 +
24.87 +GIOChannel * gmyth_socket_get_io_channel (GMythSocket *gmyth_socket );
24.88 +
24.89 +gboolean gmyth_socket_is_able_to_read (GMythSocket *gmyth_socket );
24.90 +gboolean gmyth_socket_is_able_to_write (GMythSocket *gmyth_socket );
24.91 +
24.92 +gboolean gmyth_socket_send_command (GMythSocket *gmyth_socket,
24.93 + GString *command);
24.94 +GString * gmyth_socket_receive_response (GMythSocket *gmyth_socket);
24.95 +int gmyth_socket_sendreceive_stringlist (GMythSocket * gmyth_socket,
24.96 + GMythStringList *str_list);
24.97 +
24.98 +gboolean gmyth_socket_connect (GMythSocket **gmyth_socket,
24.99 + gchar *hostname, gint port);
24.100 +gboolean gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket,
24.101 + gchar *hostname_backend, int port,
24.102 + gboolean blocking_client);
24.103 +
24.104 +GString * gmyth_socket_get_local_hostname (void);
24.105 +
24.106 +void gmyth_socket_close_connection (GMythSocket *gmyth_socket);
24.107 +
24.108 +gboolean gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket);
24.109 +gboolean gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket,
24.110 + gint mythtv_version);
24.111 +
24.112 +gboolean gmyth_socket_write_stringlist(GMythSocket *gmyth_socket,
24.113 + GMythStringList* str_list);
24.114 +int gmyth_socket_read_stringlist(GMythSocket *gmyth_socket,
24.115 + GMythStringList* str_list);
24.116 +
24.117 +G_END_DECLS
24.118 +
24.119 +#endif /* __GMYTH_SOCKET_H__ */
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/gmyth/src/gmyth_stringlist.c Thu Sep 28 15:41:06 2006 +0100
25.3 @@ -0,0 +1,272 @@
25.4 +/**
25.5 + * GMyth Library
25.6 + *
25.7 + * @file gmyth/gmyth_stringlist.c
25.8 + *
25.9 + * @brief <p> This component contains functions for dealing with the stringlist
25.10 + * format of the mythprotocol.
25.11 + *
25.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
25.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
25.14 + *
25.15 + *//*
25.16 + *
25.17 + * This program is free software; you can redistribute it and/or modify
25.18 + * it under the terms of the GNU Lesser General Public License as published by
25.19 + * the Free Software Foundation; either version 2 of the License, or
25.20 + * (at your option) any later version.
25.21 + *
25.22 + * This program is distributed in the hope that it will be useful,
25.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25.25 + * GNU General Public License for more details.
25.26 + *
25.27 + * You should have received a copy of the GNU Lesser General Public License
25.28 + * along with this program; if not, write to the Free Software
25.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25.30 + */
25.31 +
25.32 +#include "gmyth_stringlist.h"
25.33 +
25.34 +static void gmyth_string_list_class_init (GMythStringListClass *klass);
25.35 +static void gmyth_string_list_init (GMythStringList *object);
25.36 +
25.37 +static void gmyth_string_list_dispose (GObject *object);
25.38 +static void gmyth_string_list_finalize (GObject *object);
25.39 +
25.40 +G_DEFINE_TYPE(GMythStringList, gmyth_string_list, G_TYPE_OBJECT)
25.41 +
25.42 +static void
25.43 +gmyth_string_list_class_init (GMythStringListClass *klass)
25.44 +{
25.45 + GObjectClass *gobject_class;
25.46 +
25.47 + gobject_class = (GObjectClass *) klass;
25.48 +
25.49 + gobject_class->dispose = gmyth_string_list_dispose;
25.50 + gobject_class->finalize = gmyth_string_list_finalize;
25.51 +}
25.52 +
25.53 +static void
25.54 +gmyth_string_list_init (GMythStringList *gmyth_string_list)
25.55 +{
25.56 + gmyth_string_list->glist = NULL;
25.57 +}
25.58 +
25.59 +static void
25.60 +gmyth_string_list_dispose (GObject *object)
25.61 +{
25.62 + GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
25.63 +
25.64 + if (gmyth_string_list->glist)
25.65 + gmyth_string_list_clear_all(gmyth_string_list);
25.66 +
25.67 + G_OBJECT_CLASS (gmyth_string_list_parent_class)->dispose (object);
25.68 +}
25.69 +
25.70 +static void
25.71 +gmyth_string_list_finalize (GObject *object)
25.72 +{
25.73 + //GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
25.74 +
25.75 + g_signal_handlers_destroy (object);
25.76 +
25.77 + G_OBJECT_CLASS (gmyth_string_list_parent_class)->finalize (object);
25.78 +}
25.79 +
25.80 +/** Creates a new instance of GStringList.
25.81 + *
25.82 + * @return a new instance of GStringList.
25.83 + */
25.84 +GMythStringList *
25.85 +gmyth_string_list_new ()
25.86 +{
25.87 + GMythStringList *gmyth_string_list = GMYTH_STRING_LIST (g_object_new(GMYTH_STRING_LIST_TYPE, NULL));
25.88 +
25.89 + return gmyth_string_list;
25.90 +}
25.91 +
25.92 +/** Appends a guint64 to the string list.
25.93 + *
25.94 + * @param strlist The GMythStringList instance.
25.95 + * @param value The guint64 to be appended.
25.96 + *
25.97 + * @return The appended guint64 converted to a GString object.
25.98 + */
25.99 +GString*
25.100 +gmyth_string_list_append_int ( GMythStringList *strlist, const gint value )
25.101 +{
25.102 + GString *tmp_str = g_string_new ("");
25.103 +
25.104 + g_string_printf (tmp_str, "%d", value);
25.105 +
25.106 + gmyth_string_list_append_string (strlist, tmp_str);
25.107 +
25.108 + return tmp_str;
25.109 +}
25.110 +
25.111 +/** Appends a guint64 to the string list.
25.112 + *
25.113 + * @param strlist The GMythStringList instance.
25.114 + * @param value The guint64 to be appended.
25.115 + *
25.116 + * @return The appended guint64 converted to a GString object.
25.117 + */
25.118 +GString*
25.119 +gmyth_string_list_append_uint64 ( GMythStringList *strlist, const guint64 value)
25.120 +{
25.121 + GString *tmp_str = g_string_new ("");
25.122 +
25.123 + glong l2 = ( (guint64)(value) & 0xffffffffLL );
25.124 + glong l1 = ( ((guint64)(value) >> 32 ) & 0xffffffffLL );
25.125 +
25.126 + /* high order part of guint64 value */
25.127 + g_string_printf (tmp_str, "%ld", l1);
25.128 +
25.129 + g_debug( "[%s] uint64 (high) = %s\n", __FUNCTION__, tmp_str->str );
25.130 +
25.131 + gmyth_string_list_append_string (strlist, tmp_str);
25.132 +
25.133 + /* low order part of guint64 value */
25.134 + g_string_printf (tmp_str, "%ld", l2);
25.135 +
25.136 + g_debug( "[%s] uint64 (low) = %s\n", __FUNCTION__, tmp_str->str );
25.137 +
25.138 + gmyth_string_list_append_string (strlist, tmp_str);
25.139 +
25.140 + return tmp_str;
25.141 +}
25.142 +
25.143 +/** Appends a char array to the string list.
25.144 + *
25.145 + * @param strlist The GMythStringList instance.
25.146 + * @param value The char array to be appended.
25.147 + *
25.148 + * @return The appended char array converted to a GString object.
25.149 + */
25.150 +GString*
25.151 +gmyth_string_list_append_char_array ( GMythStringList *strlist, const gchar* value )
25.152 +{
25.153 + GString *tmp_str = NULL;
25.154 +
25.155 + g_return_val_if_fail( strlist != NULL, NULL );
25.156 +
25.157 + tmp_str = g_string_new (value);
25.158 +
25.159 + g_return_val_if_fail( tmp_str != NULL, NULL );
25.160 +
25.161 + gmyth_string_list_append_string (strlist, tmp_str);
25.162 +
25.163 + return tmp_str;
25.164 +}
25.165 +
25.166 +/** Appends a string to the string list.
25.167 + *
25.168 + * @param strlist The GMythStringList instance.
25.169 + * @param value The string to be appended.
25.170 + *
25.171 + * @return The appended string itself.
25.172 + */
25.173 +GString*
25.174 +gmyth_string_list_append_string ( GMythStringList *strlist, GString *value )
25.175 +{
25.176 + g_return_val_if_fail( strlist != NULL, NULL );
25.177 +
25.178 + strlist->glist = g_list_append (strlist->glist, value);
25.179 +
25.180 + return value;
25.181 +}
25.182 +
25.183 +/** Gets an integer value from the string list at the given position.
25.184 + *
25.185 + * @param strlist The GMythStringList instance.
25.186 + * @param index the integer position in the list, starting with zero.
25.187 + * @return The integer value.
25.188 + */
25.189 +gint
25.190 +gmyth_string_list_get_int ( GMythStringList *strlist, const gint index )
25.191 +{
25.192 + //TODO: Create static method check_index()
25.193 + GString *tmp_str = NULL;
25.194 +
25.195 + g_return_val_if_fail( strlist != NULL, 0 );
25.196 +
25.197 + tmp_str = (GString *) g_list_nth_data (strlist->glist, index);
25.198 +
25.199 + g_return_val_if_fail( tmp_str != NULL && tmp_str->str != NULL, 0 );
25.200 +
25.201 + return (gint) ( 0x00000000ffffffffL & g_ascii_strtoull ( tmp_str->str, NULL, 0 ) );
25.202 +}
25.203 +
25.204 +/** Gets a guint64 value from the string list at the given position.
25.205 + * According to the Mythtv protocol, the 64 bits value is formed by
25.206 + * two strings.
25.207 + *
25.208 + * @param strlist The GMythStringList instance.
25.209 + * @param index the index of the first string forming the 64 bits value.
25.210 + * Index starts with zero.
25.211 + * @return The guint64 value.
25.212 + */
25.213 +guint64
25.214 +gmyth_string_list_get_uint64 ( GMythStringList *strlist, const gint index )
25.215 +{
25.216 + //TODO: Create static method check_index()
25.217 + guint64 ret_value = 0;
25.218 +
25.219 + g_return_val_if_fail( strlist != NULL, 0 );
25.220 +
25.221 + const GString *tmp_str1 = (GString *) g_list_nth_data (strlist->glist, index);
25.222 + const GString *tmp_str2 = (GString *) g_list_nth_data (strlist->glist, index+1);
25.223 +
25.224 + glong l1 = (glong)g_ascii_strtoull (tmp_str1->str, NULL, 10);
25.225 + glong l2 = (glong)g_ascii_strtoull (tmp_str2->str, NULL, 10);
25.226 +
25.227 + ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
25.228 +
25.229 + g_debug( "[%s] returning uint64 value = %llu\n", __FUNCTION__, ret_value );
25.230 +
25.231 + return ret_value;
25.232 +}
25.233 +
25.234 +/** Gets a string from the string list at the given position.
25.235 + *
25.236 + * @param strlist The GMythStringList instance.
25.237 + * @param index the string position in the list, starting with zero.
25.238 + * @return A pointer to the string data.
25.239 + */
25.240 +GString*
25.241 +gmyth_string_list_get_string ( GMythStringList *strlist, const gint index )
25.242 +{
25.243 + if (!strlist || !(strlist->glist)) {
25.244 + g_warning ("%s received Null arguments", __FUNCTION__);
25.245 + return NULL;
25.246 + }
25.247 +
25.248 + return (GString *) g_list_nth_data (strlist->glist, index);
25.249 +}
25.250 +
25.251 +/** Removes all strings from the string list.
25.252 + *
25.253 + * @param strlist The GMythStringList instance.
25.254 + */
25.255 +void
25.256 +gmyth_string_list_clear_all ( GMythStringList *strlist )
25.257 +{
25.258 + if ( strlist != NULL && strlist->glist ) {
25.259 + g_list_free (strlist->glist);
25.260 + strlist->glist = NULL;
25.261 + }
25.262 +}
25.263 +
25.264 +/** Retrieves the number of elements in the string list.
25.265 + *
25.266 + * @param strlist The GMythStringList instance.
25.267 + * @return the string list length.
25.268 + */
25.269 +gint
25.270 +gmyth_string_list_length ( GMythStringList *strlist )
25.271 +{
25.272 + g_return_val_if_fail( strlist != NULL && strlist->glist != NULL, 0 );
25.273 +
25.274 + return g_list_length (strlist->glist);
25.275 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/gmyth/src/gmyth_stringlist.h Thu Sep 28 15:41:06 2006 +0100
26.3 @@ -0,0 +1,97 @@
26.4 +/**
26.5 + * GMyth Library
26.6 + *
26.7 + * @file gmyth/gmyth_stringlist.h
26.8 + *
26.9 + * @brief <p> This component contains functions for dealing with the stringlist
26.10 + * format of the mythprotocol.
26.11 + *
26.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
26.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
26.14 + *
26.15 + *//*
26.16 + *
26.17 + * This program is free software; you can redistribute it and/or modify
26.18 + * it under the terms of the GNU Lesser General Public License as published by
26.19 + * the Free Software Foundation; either version 2 of the License, or
26.20 + * (at your option) any later version.
26.21 + *
26.22 + * This program is distributed in the hope that it will be useful,
26.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
26.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26.25 + * GNU General Public License for more details.
26.26 + *
26.27 + * You should have received a copy of the GNU Lesser General Public License
26.28 + * along with this program; if not, write to the Free Software
26.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26.30 + */
26.31 +
26.32 +#ifndef GMYTH_STRING_LIST_H_
26.33 +#define GMYTH_STRING_LIST_H_
26.34 +
26.35 +#include <glib-object.h>
26.36 +
26.37 +#include <stdio.h>
26.38 +#include <stdlib.h>
26.39 +#include <string.h>
26.40 +#include <netdb.h>
26.41 +#include <sys/socket.h>
26.42 +#include <unistd.h>
26.43 +
26.44 +G_BEGIN_DECLS
26.45 +
26.46 +#define GMYTH_STRING_LIST_TYPE (gmyth_string_list_get_type ())
26.47 +#define GMYTH_STRING_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE, GMythStringList))
26.48 +#define GMYTH_STRING_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
26.49 +#define IS_GMYTH_STRING_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE))
26.50 +#define IS_GMYTH_STRING_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE))
26.51 +#define GMYTH_STRING_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
26.52 +
26.53 +
26.54 +typedef struct _GMythStringList GMythStringList;
26.55 +typedef struct _GMythStringListClass GMythStringListClass;
26.56 +
26.57 +struct _GMythStringListClass
26.58 +{
26.59 + GObjectClass parent_class;
26.60 +
26.61 + /* callbacks */
26.62 + /* no one for now */
26.63 +};
26.64 +
26.65 +struct _GMythStringList
26.66 +{
26.67 + GObject parent;
26.68 +
26.69 + /* string list */
26.70 + GList *glist;
26.71 +};
26.72 +
26.73 +
26.74 +GType gmyth_string_list_get_type (void);
26.75 +
26.76 +GMythStringList * gmyth_string_list_new ();
26.77 +
26.78 +void gmyth_string_list_clear_all (GMythStringList *strlist);
26.79 +int gmyth_string_list_length (GMythStringList *strlist);
26.80 +
26.81 +GString * gmyth_string_list_append_int (GMythStringList *strlist,
26.82 + const gint value);
26.83 +GString * gmyth_string_list_append_uint64 (GMythStringList *strlist,
26.84 + const guint64 value);
26.85 +
26.86 +GString * gmyth_string_list_append_char_array (GMythStringList *strlist,
26.87 + const char* value);
26.88 +GString * gmyth_string_list_append_string (GMythStringList *strlist,
26.89 + GString *value);
26.90 +
26.91 +int gmyth_string_list_get_int (GMythStringList *strlist, const gint index);
26.92 +guint64 gmyth_string_list_get_uint64 (GMythStringList *strlist, const gint index);
26.93 +GString * gmyth_string_list_get_string (GMythStringList *strlist, const gint index);
26.94 +
26.95 +#define gmyth_string_list_get_char_array(strlist, index) \
26.96 + (gmyth_string_list_get_string(strlist, index))->str
26.97 +
26.98 +G_END_DECLS
26.99 +
26.100 +#endif /*GMYTH_STRING_LIST_H_*/
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/gmyth/src/gmyth_tvchain.c Thu Sep 28 15:41:06 2006 +0100
27.3 @@ -0,0 +1,355 @@
27.4 +/**
27.5 + * GMyth Library
27.6 + *
27.7 + * @file gmyth/gmyth_tvchain.c
27.8 + *
27.9 + * @brief <p> This component contains functions for creating and accessing
27.10 + * the tvchain functions for live tv playback.
27.11 + *
27.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
27.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
27.14 + *
27.15 + *//*
27.16 + *
27.17 + * This program is free software; you can redistribute it and/or modify
27.18 + * it under the terms of the GNU Lesser General Public License as published by
27.19 + * the Free Software Foundation; either version 2 of the License, or
27.20 + * (at your option) any later version.
27.21 + *
27.22 + * This program is distributed in the hope that it will be useful,
27.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27.25 + * GNU General Public License for more details.
27.26 + *
27.27 + * You should have received a copy of the GNU Lesser General Public License
27.28 + * along with this program; if not, write to the Free Software
27.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27.30 + */
27.31 +
27.32 +#include <glib.h>
27.33 +#include <time.h>
27.34 +#include <stdio.h>
27.35 +#include <stdlib.h>
27.36 +
27.37 +#include "gmyth_epg.h"
27.38 +#include "gmyth_tvchain.h"
27.39 +#include "gmyth_util.h"
27.40 +#include "gmyth_query.h"
27.41 +#include "gmyth_scheduler.h"
27.42 +
27.43 +static void gmyth_tvchain_class_init (GMythTVChainClass *klass);
27.44 +static void gmyth_tvchain_init (GMythTVChain *object);
27.45 +
27.46 +static void gmyth_tvchain_dispose (GObject *object);
27.47 +static void gmyth_tvchain_finalize (GObject *object);
27.48 +
27.49 +G_DEFINE_TYPE(GMythTVChain, gmyth_tvchain, G_TYPE_OBJECT)
27.50 +
27.51 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
27.52 +
27.53 +static void
27.54 +gmyth_tvchain_class_init (GMythTVChainClass *klass)
27.55 +{
27.56 + GObjectClass *gobject_class;
27.57 +
27.58 + gobject_class = (GObjectClass *) klass;
27.59 +
27.60 + gobject_class->dispose = gmyth_tvchain_dispose;
27.61 + gobject_class->finalize = gmyth_tvchain_finalize;
27.62 +}
27.63 +
27.64 +static void
27.65 +gmyth_tvchain_init (GMythTVChain *tvchain)
27.66 +{
27.67 + tvchain->tvchain_id = NULL;
27.68 +
27.69 + tvchain->cur_chanid = g_string_new ("");
27.70 + tvchain->cur_startts = 0;
27.71 +}
27.72 +
27.73 +static void
27.74 +gmyth_tvchain_dispose (GObject *object)
27.75 +{
27.76 + GMythTVChain *tvchain = GMYTH_TVCHAIN(object);
27.77 +
27.78 + if ( tvchain->tvchain_id != NULL ) {
27.79 + g_string_free( tvchain->tvchain_id, TRUE );
27.80 + tvchain->tvchain_id = NULL;
27.81 + }
27.82 +
27.83 + if ( tvchain->tvchain_list != NULL ) {
27.84 + g_list_free( tvchain->tvchain_list );
27.85 + tvchain->tvchain_list = NULL;
27.86 + }
27.87 +
27.88 + if ( tvchain->cur_chanid != NULL ) {
27.89 + g_string_free( tvchain->cur_chanid, TRUE );
27.90 + tvchain->cur_chanid = NULL;
27.91 + }
27.92 +
27.93 + G_OBJECT_CLASS (gmyth_tvchain_parent_class)->dispose (object);
27.94 +}
27.95 +
27.96 +static void
27.97 +gmyth_tvchain_finalize (GObject *object)
27.98 +{
27.99 + g_signal_handlers_destroy (object);
27.100 +
27.101 + G_OBJECT_CLASS (gmyth_tvchain_parent_class)->finalize (object);
27.102 +}
27.103 +
27.104 +/** Initializes the tvchain and generates the tvchain id.
27.105 + *
27.106 + * @param tvchain The GMythTVChain instance.
27.107 + * @param hostname The local hostname used to generate the tvchain id.
27.108 + */
27.109 +void
27.110 +gmyth_tvchain_initialize (GMythTVChain *tvchain, GString *hostname)
27.111 +{
27.112 + if (tvchain->tvchain_id == NULL) {
27.113 + GString *isodate;
27.114 + time_t cur_time;
27.115 +
27.116 + time(&cur_time);
27.117 + isodate = gmyth_util_time_to_isoformat (cur_time);
27.118 +
27.119 + tvchain->tvchain_id = g_string_sized_new(7 + hostname->len + isodate->len);
27.120 + g_string_printf(tvchain->tvchain_id,
27.121 + "live-%s-%s", hostname->str, isodate->str);
27.122 +
27.123 + g_print("tv_chain_id: %s\n", tvchain->tvchain_id->str);
27.124 +
27.125 + g_string_free(isodate, TRUE);
27.126 +
27.127 + } else {
27.128 + g_warning ("[%s] TVchain already initialized", __FUNCTION__);
27.129 + }
27.130 +}
27.131 +
27.132 +/** Gets the tvchain id.
27.133 + *
27.134 + * @param tvchain The GMythTVChain instance.
27.135 + * @return The tvchain id.
27.136 + */
27.137 +GString*
27.138 +gmyth_tvchain_get_id (GMythTVChain *tvchain)
27.139 +{
27.140 + g_return_val_if_fail( tvchain != NULL && tvchain->tvchain_id != NULL, NULL );
27.141 +
27.142 + return g_string_new (tvchain->tvchain_id->str);
27.143 +}
27.144 +
27.145 +/** Reloads all tvchain entries in the database.
27.146 + *
27.147 + * @param tvchain The GMythTVChain instance.
27.148 + * @return TRUE if success, or FALSE if error.
27.149 + */
27.150 +gboolean
27.151 +gmyth_tvchain_reload_all (GMythTVChain *tvchain)
27.152 +{
27.153 + MYSQL_ROW msql_row;
27.154 + MYSQL_RES *msql_res;
27.155 + GMythQuery *gmyth_query;
27.156 + gboolean ret = TRUE;
27.157 +
27.158 + GString *stmt_str;
27.159 +
27.160 + g_static_mutex_lock( &mutex );
27.161 +
27.162 + guint prev_size = g_list_length (tvchain->tvchain_list);
27.163 +
27.164 + g_debug ("[%s] chainid: %s", __FUNCTION__, tvchain->tvchain_id->str);
27.165 +
27.166 + if ( tvchain != NULL && tvchain->tvchain_list != NULL ) {
27.167 + g_list_free (tvchain->tvchain_list);
27.168 + tvchain->tvchain_list = NULL;
27.169 + }
27.170 +
27.171 + // TODO: Reuse gmyth_query already connected from context
27.172 + gmyth_query = gmyth_query_new ();
27.173 + if (!gmyth_query_connect (gmyth_query)) {
27.174 + g_warning ("[%s] Could not connect to db", __FUNCTION__);
27.175 + g_static_mutex_unlock( &mutex );
27.176 +
27.177 + ret = FALSE;
27.178 +
27.179 + goto done;
27.180 + }
27.181 +
27.182 + stmt_str = g_string_new ("");
27.183 + g_string_printf (stmt_str,
27.184 + "SELECT chanid, starttime, endtime, discontinuity, "
27.185 + "chainpos, hostprefix, cardtype, channame, input "
27.186 + "FROM tvchain "
27.187 + "WHERE chainid = \"%s\" ORDER BY chainpos;",
27.188 + tvchain->tvchain_id->str);
27.189 +
27.190 + msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
27.191 + if (msql_res != NULL) {
27.192 +
27.193 + while ((msql_row = mysql_fetch_row (msql_res)) != NULL) {
27.194 + struct LiveTVChainEntry *entry = g_new0 (struct LiveTVChainEntry, 1);
27.195 + entry->chanid = g_string_new (msql_row[0]);
27.196 + entry->starttime = gmyth_util_string_to_time (g_string_new ((gchar*)msql_row[1]));
27.197 + entry->endtime = gmyth_util_string_to_time (g_string_new (msql_row[2]));
27.198 + entry->discontinuity = atoi (msql_row[3]) != 0;
27.199 + entry->hostprefix = g_string_new (msql_row[5]);
27.200 + entry->cardtype = g_string_new (msql_row[6]);
27.201 + entry->channum = g_string_new (msql_row[7]);
27.202 + entry->inputname = g_string_new (msql_row[8]);
27.203 +
27.204 + //m_maxpos = query.value(4).toInt() + 1;
27.205 +
27.206 + tvchain->tvchain_list = g_list_append (tvchain->tvchain_list, entry);
27.207 + }
27.208 + } else {
27.209 + g_warning ("gmyth_tvchain_reload_all query error!\n");
27.210 + g_static_mutex_unlock( &mutex );
27.211 +
27.212 + ret = FALSE;
27.213 + goto done;
27.214 + }
27.215 +
27.216 + g_static_mutex_unlock( &mutex );
27.217 +
27.218 + tvchain->cur_pos = gmyth_tvchain_program_is_at (tvchain, tvchain->cur_chanid, tvchain->cur_startts);
27.219 +
27.220 + if (tvchain->cur_pos < 0)
27.221 + tvchain->cur_pos = 0;
27.222 +
27.223 + // if (m_switchid >= 0)
27.224 + // m_switchid = ProgramIsAt(m_switchentry.chanid,m_switchentry.starttime);
27.225 +
27.226 + if (prev_size != g_list_length (tvchain->tvchain_list)) {
27.227 + g_debug ("[%s] Added new recording", __FUNCTION__);
27.228 + }
27.229 +
27.230 +done:
27.231 + if ( stmt_str != NULL )
27.232 + g_string_free (stmt_str, TRUE);
27.233 +
27.234 + if ( msql_res != NULL )
27.235 + mysql_free_result (msql_res);
27.236 +
27.237 + if ( gmyth_query != NULL )
27.238 + g_object_unref (gmyth_query);
27.239 +
27.240 + return ret;
27.241 +}
27.242 +
27.243 +/** Returns the internal index for the TV chain related to the given
27.244 + * channel and start time.
27.245 + *
27.246 + * @param tvchain The GMythTVChain instance.
27.247 + * @param chanid The channel id.
27.248 + * @param startts The program start time.
27.249 + */
27.250 +int
27.251 +gmyth_tvchain_program_is_at (GMythTVChain *tvchain, GString *chanid, time_t startts)
27.252 +{
27.253 + int count = 0;
27.254 + struct LiveTVChainEntry *entry;
27.255 + GList *tmp_list = tvchain->tvchain_list;
27.256 +
27.257 + g_static_mutex_lock( &mutex );
27.258 +
27.259 + for (; tmp_list; tmp_list = tvchain->tvchain_list->next, ++count)
27.260 + {
27.261 + entry = (struct LiveTVChainEntry*) tmp_list->data;
27.262 + if (!g_strncasecmp (entry->chanid->str, chanid->str, chanid->len)
27.263 + && entry->starttime == startts)
27.264 + {
27.265 + g_static_mutex_unlock( &mutex );
27.266 + return count;
27.267 + }
27.268 + }
27.269 + g_static_mutex_unlock( &mutex );
27.270 +
27.271 + return -1;
27.272 +}
27.273 +
27.274 +/** Get the program info associated to the tvchain.
27.275 + *
27.276 + * @param tvchain The GMythTVChain instance.
27.277 + * @param index The tvchain index.
27.278 + * @return The program info structure.
27.279 + */
27.280 +GMythProgramInfo*
27.281 +gmyth_tvchain_get_program_at (GMythTVChain *tvchain, int index)
27.282 +{
27.283 + struct LiveTVChainEntry *entry;
27.284 +
27.285 + entry = gmyth_tvchain_get_entry_at (tvchain, index);
27.286 +
27.287 + if (entry)
27.288 + return gmyth_tvchain_entry_to_program (tvchain, entry);
27.289 +
27.290 + return NULL;
27.291 +}
27.292 +
27.293 +/** Gets a LiveTVChainEntry associated to the tvchain by its index.
27.294 + *
27.295 + * @param tvchain The GMythTVChain instance.
27.296 + * @param index The tvchain entry index
27.297 + * @return The LiveTVchainEntry structure.
27.298 + */
27.299 +struct LiveTVChainEntry*
27.300 +gmyth_tvchain_get_entry_at (GMythTVChain *tvchain, int index)
27.301 +{
27.302 + struct LiveTVChainEntry* chain_entry = NULL;
27.303 +
27.304 + g_return_val_if_fail( tvchain != NULL && tvchain->tvchain_list != NULL, NULL );
27.305 +
27.306 + g_static_mutex_lock( &mutex );
27.307 +
27.308 + int size = g_list_length (tvchain->tvchain_list);
27.309 + int new_index = (index < 0 || index >= size) ? size - 1 : index;
27.310 +
27.311 + if (new_index >= 0)
27.312 + chain_entry = (struct LiveTVChainEntry*) g_list_nth_data (tvchain->tvchain_list, new_index);
27.313 +
27.314 + g_static_mutex_unlock( &mutex );
27.315 +
27.316 + if ( chain_entry != NULL ) {
27.317 + g_debug ("[%s] Got TV Chain entry at %d.\n", __FUNCTION__, new_index );
27.318 +
27.319 + } else {
27.320 + g_warning ("[%s] failed to get entry at index %d", __FUNCTION__, index);
27.321 + }
27.322 +
27.323 + return chain_entry;
27.324 +}
27.325 +
27.326 +/** Gets the program info from backend database associated to the tv chain entry.
27.327 + *
27.328 + * @param tvchain The GMythTVChain instance.
27.329 + * @param entry the LiveTVChainEntry to be converted.
27.330 + * @return The progrma info.
27.331 + */
27.332 +GMythProgramInfo*
27.333 +gmyth_tvchain_entry_to_program (GMythTVChain *tvchain, struct LiveTVChainEntry *entry)
27.334 +{
27.335 + GMythProgramInfo *proginfo = NULL;
27.336 +
27.337 + g_return_val_if_fail( tvchain != NULL, NULL );
27.338 +
27.339 + if (!entry || !tvchain) {
27.340 + g_warning ("gmyth_tvchain_entry_to_program() received NULL argument");
27.341 + return NULL;
27.342 + }
27.343 +
27.344 + GMythScheduler *scheduler = gmyth_scheduler_new ();
27.345 +
27.346 + gmyth_scheduler_connect( scheduler );
27.347 + proginfo = gmyth_scheduler_get_recorded (scheduler,
27.348 + entry->chanid, entry->starttime);
27.349 + gmyth_scheduler_disconnect( scheduler );
27.350 +
27.351 + if (proginfo) {
27.352 + proginfo->pathname = g_string_prepend (proginfo->pathname, entry->hostprefix->str);
27.353 + } else {
27.354 + g_warning ("tvchain_entry_to_program(%s, %ld) failed!", entry->chanid->str, entry->starttime);
27.355 + }
27.356 +
27.357 + return proginfo;
27.358 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/gmyth/src/gmyth_tvchain.h Thu Sep 28 15:41:06 2006 +0100
28.3 @@ -0,0 +1,105 @@
28.4 +/**
28.5 + * GMyth Library
28.6 + *
28.7 + * @file gmyth/gmyth_tvchain.h
28.8 + *
28.9 + * @brief <p> This component contains functions for creating and accessing
28.10 + * the tvchain functions for live tv playback.
28.11 + *
28.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
28.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
28.14 + *
28.15 + *//*
28.16 + *
28.17 + * This program is free software; you can redistribute it and/or modify
28.18 + * it under the terms of the GNU Lesser General Public License as published by
28.19 + * the Free Software Foundation; either version 2 of the License, or
28.20 + * (at your option) any later version.
28.21 + *
28.22 + * This program is distributed in the hope that it will be useful,
28.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28.25 + * GNU General Public License for more details.
28.26 + *
28.27 + * You should have received a copy of the GNU Lesser General Public License
28.28 + * along with this program; if not, write to the Free Software
28.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28.30 + */
28.31 +
28.32 +#ifndef LIVETVCHAIN_H_
28.33 +#define LIVETVCHAIN_H_
28.34 +
28.35 +#include <glib-object.h>
28.36 +#include <time.h>
28.37 +
28.38 +#include "gmyth_common.h"
28.39 +
28.40 +G_BEGIN_DECLS
28.41 +
28.42 +#define GMYTH_TVCHAIN_TYPE (gmyth_tvchain_get_type ())
28.43 +#define GMYTH_TVCHAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChain))
28.44 +#define GMYTH_TVCHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
28.45 +#define IS_GMYTH_TVCHAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE))
28.46 +#define IS_GMYTH_TVCHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE))
28.47 +#define GMYTH_TVCHAIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
28.48 +
28.49 +
28.50 +typedef struct _GMythTVChain GMythTVChain;
28.51 +typedef struct _GMythTVChainClass GMythTVChainClass;
28.52 +
28.53 +
28.54 +struct LiveTVChainEntry
28.55 +{
28.56 + GString *chanid;
28.57 +
28.58 + time_t starttime;
28.59 + time_t endtime;
28.60 +
28.61 + gboolean discontinuity; // if true, can't play smooth from last entry
28.62 + GString *hostprefix;
28.63 + GString *cardtype;
28.64 + GString *channum;
28.65 + GString *inputname;
28.66 +};
28.67 +
28.68 +
28.69 +struct _GMythTVChainClass
28.70 +{
28.71 + GObjectClass parent_class;
28.72 +
28.73 + /* callbacks */
28.74 + /* no one for now */
28.75 +};
28.76 +
28.77 +struct _GMythTVChain
28.78 +{
28.79 + GObject parent;
28.80 +
28.81 + GString *tvchain_id;
28.82 + GList *tvchain_list;
28.83 +
28.84 + time_t cur_startts;
28.85 + GString *cur_chanid;
28.86 + int cur_pos;
28.87 +};
28.88 +
28.89 +
28.90 +GType gmyth_tvchain_get_type (void);
28.91 +
28.92 +void gmyth_tvchain_initialize (GMythTVChain *tvchain,
28.93 + GString *hostname);
28.94 +gboolean gmyth_tvchain_reload_all (GMythTVChain *tvchain);
28.95 +GString* gmyth_tvchain_get_id (GMythTVChain *tvchain);
28.96 +int gmyth_tvchain_program_is_at (GMythTVChain *tvchain,
28.97 + GString *chanid, time_t startts);
28.98 +
28.99 +struct LiveTVChainEntry* gmyth_tvchain_get_entry_at (GMythTVChain *tvchain,
28.100 + gint index);
28.101 +
28.102 +GMythProgramInfo* gmyth_tvchain_entry_to_program (GMythTVChain *tvchain,
28.103 + struct LiveTVChainEntry *entry);
28.104 +GMythProgramInfo* gmyth_tvchain_get_program_at (GMythTVChain *tvchain, gint index);
28.105 +
28.106 +G_END_DECLS
28.107 +
28.108 +#endif /*LIVETVCHAIN_H_*/
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/gmyth/src/gmyth_tvplayer.c Thu Sep 28 15:41:06 2006 +0100
29.3 @@ -0,0 +1,684 @@
29.4 +/**
29.5 + * GMyth Library
29.6 + *
29.7 + * @file gmyth/gmyth_tvplayer.c
29.8 + *
29.9 + * @brief <p> This component provides playback of the remote A/V using
29.10 + * GStreamer.
29.11 + *
29.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
29.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
29.14 + *
29.15 + *//*
29.16 + *
29.17 + * This program is free software; you can redistribute it and/or modify
29.18 + * it under the terms of the GNU Lesser General Public License as published by
29.19 + * the Free Software Foundation; either version 2 of the License, or
29.20 + * (at your option) any later version.
29.21 + *
29.22 + * This program is distributed in the hope that it will be useful,
29.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29.25 + * GNU General Public License for more details.
29.26 + *
29.27 + * You should have received a copy of the GNU Lesser General Public License
29.28 + * along with this program; if not, write to the Free Software
29.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29.30 + */
29.31 +
29.32 +#include "gmyth_tvplayer.h"
29.33 +
29.34 +#include <gdk/gdkx.h>
29.35 +
29.36 +#include "gmyth_context.h"
29.37 +#include "gmyth_remote_util.h"
29.38 +
29.39 +typedef struct _GstPlayerWindowStateChange
29.40 +{
29.41 + GstElement *play;
29.42 + GstState old_state, new_state;
29.43 + GMythTVPlayer *tvplayer;
29.44 +} GstPlayerWindowStateChange;
29.45 +
29.46 +typedef struct _GstPlayerWindowTagFound
29.47 +{
29.48 + GstElement *play;
29.49 + GstTagList *taglist;
29.50 + GMythTVPlayer *tvplayer;
29.51 +} GstPlayerWindowTagFound;
29.52 +
29.53 +/*
29.54 +static gboolean idle_state (gpointer data);
29.55 +*/
29.56 +static gboolean bus_call (GstBus * bus, GstMessage * msg, gpointer data);
29.57 +
29.58 +static void gmyth_tvplayer_class_init (GMythTVPlayerClass *klass);
29.59 +static void gmyth_tvplayer_init (GMythTVPlayer *object);
29.60 +
29.61 +static void gmyth_tvplayer_dispose (GObject *object);
29.62 +static void gmyth_tvplayer_finalize (GObject *object);
29.63 +
29.64 +G_DEFINE_TYPE(GMythTVPlayer, gmyth_tvplayer, G_TYPE_OBJECT)
29.65 +
29.66 +static gboolean gmyth_tvplayer_create_pipeline (GMythTVPlayer* tvplayer);
29.67 +static void new_pad_cb (GstElement *element,
29.68 + GstPad *pad, gpointer data);
29.69 +
29.70 +static gboolean expose_cb (GtkWidget * widget,
29.71 + GdkEventExpose * event,
29.72 + gpointer user_data);
29.73 +
29.74 +static void
29.75 +gmyth_tvplayer_class_init (GMythTVPlayerClass *klass)
29.76 +{
29.77 + GObjectClass *gobject_class;
29.78 +
29.79 + gobject_class = (GObjectClass *) klass;
29.80 +
29.81 + gobject_class->dispose = gmyth_tvplayer_dispose;
29.82 + gobject_class->finalize = gmyth_tvplayer_finalize;
29.83 +}
29.84 +
29.85 +static void
29.86 +new_pad_cb (GstElement *element, GstPad *pad, gpointer data)
29.87 +{
29.88 + GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (data);
29.89 + GstPadLinkReturn ret;
29.90 + char *s;
29.91 +
29.92 + s = gst_caps_to_string (pad->caps);
29.93 +
29.94 + if ( s[0] == 'a') {
29.95 + ret = gst_pad_link (pad, gst_element_get_pad (tvplayer->audioqueue, "sink"));
29.96 + } else {
29.97 + ret = gst_pad_link (pad, gst_element_get_pad (tvplayer->videoqueue, "sink"));
29.98 + }
29.99 +
29.100 + g_free(s);
29.101 +}
29.102 +
29.103 +static gboolean
29.104 +expose_cb (GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
29.105 +{
29.106 + GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (user_data);
29.107 +
29.108 + if (tvplayer && tvplayer->videow) {
29.109 + gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (tvplayer->gst_videosink),
29.110 + GDK_WINDOW_XWINDOW (widget->window));
29.111 + return TRUE;
29.112 + }
29.113 +
29.114 + g_warning ("GMythTVPlayer expose called before setting video window\n");
29.115 +
29.116 + return FALSE;
29.117 +}
29.118 +
29.119 +static void
29.120 +gmyth_tvplayer_init (GMythTVPlayer *tvplayer)
29.121 +{
29.122 + tvplayer->gst_pipeline = NULL;
29.123 + tvplayer->gst_source = NULL;
29.124 + tvplayer->gst_videodec = NULL;
29.125 + tvplayer->gst_videosink = NULL;
29.126 + tvplayer->videoqueue = NULL;
29.127 + tvplayer->audioqueue = NULL;
29.128 +
29.129 + /* GTKWidget for rendering the video */
29.130 + tvplayer->videow = NULL;
29.131 + tvplayer->expose_handler = 0;
29.132 +
29.133 + tvplayer->backend_hostname = NULL;
29.134 + tvplayer->backend_port = 0;
29.135 + tvplayer->local_hostname = NULL;
29.136 +
29.137 + tvplayer->remote_encoder = NULL;
29.138 + tvplayer->tvchain = NULL;
29.139 + tvplayer->proginfo = NULL;
29.140 +}
29.141 +
29.142 +static void
29.143 +gmyth_tvplayer_dispose (GObject *object)
29.144 +{
29.145 +
29.146 + G_OBJECT_CLASS (gmyth_tvplayer_parent_class)->dispose (object);
29.147 +}
29.148 +
29.149 +static void
29.150 +gmyth_tvplayer_finalize (GObject *object)
29.151 +{
29.152 + g_signal_handlers_destroy (object);
29.153 +
29.154 + GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (object);
29.155 +
29.156 + g_debug ("[%s] Finalizing tvplayer", __FUNCTION__);
29.157 +
29.158 + if (tvplayer->videow != NULL) {
29.159 + if (g_signal_handler_is_connected (tvplayer->videow,
29.160 + tvplayer->expose_handler)) {
29.161 + g_signal_handler_disconnect (tvplayer->videow,
29.162 + tvplayer->expose_handler);
29.163 + }
29.164 + g_object_unref (tvplayer->videow);
29.165 + }
29.166 +
29.167 + if ( tvplayer->remote_encoder != NULL )
29.168 + g_object_unref (tvplayer->remote_encoder);
29.169 + if ( tvplayer->tvchain != NULL )
29.170 + g_object_unref (tvplayer->tvchain);
29.171 + if ( tvplayer->proginfo != NULL )
29.172 + g_object_unref (tvplayer->proginfo);
29.173 +
29.174 + // Release Gstreamer elements
29.175 + if ( tvplayer->gst_pipeline != NULL )
29.176 + g_object_unref (tvplayer->gst_pipeline);
29.177 + if ( tvplayer->gst_source != NULL )
29.178 + g_object_unref (tvplayer->gst_source);
29.179 + if ( tvplayer->gst_videodec != NULL )
29.180 + g_object_unref (tvplayer->gst_videodec);
29.181 + if ( tvplayer->gst_videosink != NULL )
29.182 + g_object_unref (tvplayer->gst_videosink);
29.183 + if ( tvplayer->videoqueue != NULL )
29.184 + g_object_unref (tvplayer->videoqueue);
29.185 + if ( tvplayer->audioqueue != NULL )
29.186 + g_object_unref (tvplayer->audioqueue);
29.187 +
29.188 + G_OBJECT_CLASS (gmyth_tvplayer_parent_class)->finalize (object);
29.189 +}
29.190 +
29.191 +/** Creates a new instance of GMythTVPlayer.
29.192 + *
29.193 + * @return a new instance of GMythTVPlayer.
29.194 + */
29.195 +GMythTVPlayer *
29.196 +gmyth_tvplayer_new ()
29.197 +{
29.198 + GMythTVPlayer *tvplayer =
29.199 + GMYTH_TVPLAYER (g_object_new(GMYTH_TVPLAYER_TYPE, NULL));
29.200 +
29.201 + return tvplayer;
29.202 +}
29.203 +
29.204 +/** Initializes the tv player.
29.205 + *
29.206 + * @param tvplayer the object instance.
29.207 + * @return gboolean TRUE if the pipeline was created
29.208 + * successfully, FALSE otherwise.
29.209 + */
29.210 +gboolean
29.211 +gmyth_tvplayer_initialize (GMythTVPlayer *tvplayer)
29.212 +{
29.213 +
29.214 + if (!gmyth_tvplayer_create_pipeline (tvplayer)) {
29.215 + g_warning ("[%s] Error while creating pipeline. TV Player not initialized", __FUNCTION__);
29.216 + return FALSE;
29.217 + } else {
29.218 + g_debug ("[%s] GStreamer pipeline created", __FUNCTION__);
29.219 + }
29.220 +
29.221 + return TRUE;
29.222 +}
29.223 +
29.224 +/** Creates the GStreamer pipeline used by the player.
29.225 + *
29.226 + * @param tvplayer the object instance.
29.227 + * @return gboolean TRUE if the pipeline was created
29.228 + * successfully, FALSE otherwise.
29.229 + */
29.230 +static gboolean
29.231 +gmyth_tvplayer_create_pipeline (GMythTVPlayer* tvplayer)
29.232 +{
29.233 + GstElement *pipeline;
29.234 + GstElement *source, *parser;
29.235 + GstElement *videodec, *videosink;
29.236 +#ifndef MAEMO_PLATFORM
29.237 + GstElement *audiodec, *audioconv;
29.238 +#endif
29.239 + GstElement *audiosink;
29.240 + GstElement *videoqueue, *audioqueue;
29.241 +
29.242 + g_debug ("GMythTVPlayer: Setting the Gstreamer pipeline\n");
29.243 +
29.244 + pipeline = gst_pipeline_new ("video-player");
29.245 + source = gst_element_factory_make ("mythtvsrc", "myth-source");
29.246 + parser = gst_element_factory_make ("ffdemux_nuv", "nuv-demux");
29.247 +
29.248 + /* Gstreamer Video elements */
29.249 + videoqueue = gst_element_factory_make ("queue", "video-queue");
29.250 + videodec = gst_element_factory_make ("ffdec_mpeg4", "video-decoder");
29.251 +#ifdef MAEMO_PLATFORM
29.252 + videosink = gst_element_factory_make ("sdlvideosink", "image-output");
29.253 +#else
29.254 + videosink = gst_element_factory_make ("xvimagesink", "image-output");
29.255 +#endif
29.256 +
29.257 + /* Gstreamer Audio elements */
29.258 + audioqueue = gst_element_factory_make ("queue", "audio-queue");
29.259 +#ifdef MAEMO_PLATFORM
29.260 + audiosink = gst_element_factory_make ("dspmp3sink", "audio-output");
29.261 +#else
29.262 + audiodec = gst_element_factory_make ("ffdec_mp3", "audio-decoder");
29.263 + audioconv = gst_element_factory_make ("audioconvert", "audio-converter");
29.264 + audiosink = gst_element_factory_make ("alsasink", "audio-output");
29.265 +#endif
29.266 +
29.267 + if (!(pipeline && source && parser && videodec && videosink) ||
29.268 + !(videoqueue && audioqueue && audiosink)) {
29.269 + /* FIXME: hanlde the error correctly */
29.270 + /* video_alignment is not being created (below)
29.271 + and is causing problems to the ui */
29.272 +
29.273 + tvplayer->gst_pipeline = NULL;
29.274 + tvplayer->gst_videodec = NULL;
29.275 + tvplayer->gst_videosink = NULL;
29.276 +
29.277 + g_warning ("GstElement creation error!\n");
29.278 + return FALSE;
29.279 + }
29.280 +
29.281 +#ifndef MAEMO_PLATFORM
29.282 + if (!(audiodec && audioconv)) {
29.283 + g_warning ("GstElement for audio stream creation error!");
29.284 + return FALSE;
29.285 + }
29.286 +#endif
29.287 +
29.288 +
29.289 + tvplayer->gst_pipeline = pipeline;
29.290 + tvplayer->gst_source = source;
29.291 + tvplayer->gst_videodec = videodec;
29.292 + tvplayer->gst_videosink = videosink;
29.293 + g_object_ref (tvplayer->gst_pipeline);
29.294 + g_object_ref (tvplayer->gst_source);
29.295 + g_object_ref (tvplayer->gst_videodec);
29.296 + g_object_ref (tvplayer->gst_videosink);
29.297 +
29.298 + tvplayer->videoqueue = videoqueue;
29.299 + tvplayer->audioqueue = audioqueue;
29.300 + g_object_ref (tvplayer->videoqueue);
29.301 + g_object_ref (tvplayer->audioqueue);
29.302 +
29.303 + g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
29.304 + g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
29.305 +
29.306 + gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (tvplayer->gst_pipeline)),
29.307 + bus_call, tvplayer);
29.308 +
29.309 + gst_bin_add_many (GST_BIN (pipeline), source, parser, videoqueue,
29.310 + videodec, videosink, audioqueue, audiodec, audioconv, audiosink, NULL);
29.311 +
29.312 + {
29.313 +// GstCaps *rtpcaps = gst_caps_new_simple ("application/x-rtp", NULL);
29.314 +// gst_element_link_filtered(source, parser, rtpcaps);
29.315 + }
29.316 +
29.317 + gst_element_link (source, parser);
29.318 + gst_element_link_many (videoqueue, videodec, videosink, NULL);
29.319 + gst_element_link_many (audioqueue, audiodec, audioconv, audiosink, NULL);
29.320 +
29.321 + g_signal_connect (parser, "pad-added", G_CALLBACK (new_pad_cb), tvplayer);
29.322 +
29.323 + return TRUE;
29.324 +}
29.325 +
29.326 +/** Configures the backend and the tv player
29.327 + * for playing the recorded content A/V.
29.328 + *
29.329 + * FIXME: Change filename to program info or other structure about the recorded
29.330 + *
29.331 + * @param tvplayer the object instance.
29.332 + * @param filename the file uri of the recorded content to be played.
29.333 + * @return TRUE if successfull, FALSE if any error happens.
29.334 + */
29.335 +gboolean
29.336 +gmyth_tvplayer_record_setup (GMythTVPlayer *tvplayer, gchar *filename)
29.337 +{
29.338 + GMythSettings *msettings = gmyth_context_get_settings();
29.339 +
29.340 + // FIXME: we should receive the uri instead of filename
29.341 + GString *hostname = gmyth_settings_get_backend_hostname (msettings);
29.342 + int port = gmyth_settings_get_backend_port(msettings);
29.343 +
29.344 + GString *fullpath = g_string_new ("myth://");
29.345 + g_string_append_printf (fullpath, "%s:%d/%s", hostname->str, port, filename);
29.346 +
29.347 + tvplayer->is_livetv = FALSE;
29.348 +
29.349 + g_debug ("[%s] Setting record uri to gstreamer pipeline to %s", __FUNCTION__, fullpath->str);
29.350 +
29.351 + g_object_set (G_OBJECT (tvplayer->gst_source), "location",
29.352 + fullpath->str, NULL);
29.353 +
29.354 + return TRUE;
29.355 +}
29.356 +
29.357 +/** Configures the backend and the tv player
29.358 + * for playing the live tv.
29.359 + *
29.360 + * @param tvplayer the object instance.
29.361 + * @return TRUE if successfull, FALSE if any error happens.
29.362 + */
29.363 +gboolean
29.364 +gmyth_tvplayer_livetv_setup (GMythTVPlayer *tvplayer)
29.365 +{
29.366 + GMythSettings *msettings = gmyth_context_get_settings ();
29.367 + gboolean res = TRUE;
29.368 +
29.369 + res = gmyth_context_check_connection();
29.370 + if (!res) {
29.371 + g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);
29.372 + res = FALSE;
29.373 + goto error;
29.374 + }
29.375 +
29.376 + tvplayer->backend_hostname = gmyth_settings_get_backend_hostname(msettings);
29.377 + tvplayer->backend_port = gmyth_settings_get_backend_port (msettings);
29.378 +
29.379 + tvplayer->local_hostname = g_string_new("");
29.380 + gmyth_context_get_local_hostname (tvplayer->local_hostname);
29.381 +
29.382 + if ( tvplayer->local_hostname == NULL ) {
29.383 + res = FALSE;
29.384 + goto error;
29.385 + }
29.386 +
29.387 + // Gets the remote encoder num
29.388 + tvplayer->remote_encoder = remote_request_next_free_recorder (-1);
29.389 +
29.390 + if ( tvplayer->remote_encoder == NULL ) {
29.391 + g_warning ("[%s] None remote encoder available", __FUNCTION__);
29.392 + res = FALSE;
29.393 + goto error;
29.394 + }
29.395 +
29.396 + // Creates livetv chain handler
29.397 + tvplayer->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
29.398 + gmyth_tvchain_initialize ( tvplayer->tvchain, tvplayer->local_hostname );
29.399 +
29.400 + if ( tvplayer->tvchain == NULL || tvplayer->tvchain->tvchain_id == NULL ) {
29.401 + res = FALSE;
29.402 + goto error;
29.403 + }
29.404 +
29.405 + // Init remote encoder. Opens its control socket.
29.406 + res = gmyth_remote_encoder_setup(tvplayer->remote_encoder);
29.407 + if ( !res ) {
29.408 + g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
29.409 + res = FALSE;
29.410 + goto error;
29.411 + }
29.412 + // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
29.413 + res = gmyth_remote_encoder_spawntv ( tvplayer->remote_encoder,
29.414 + gmyth_tvchain_get_id(tvplayer->tvchain) );
29.415 + if (!res) {
29.416 + g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
29.417 + res = FALSE;
29.418 + goto error;
29.419 + }
29.420 +
29.421 + // Reload all TV chain from Mysql database.
29.422 + gmyth_tvchain_reload_all (tvplayer->tvchain);
29.423 +
29.424 + if ( tvplayer->tvchain == NULL ) {
29.425 + res = FALSE;
29.426 + goto error;
29.427 + }
29.428 +
29.429 + // Get program info from database using chanid and starttime
29.430 + tvplayer->proginfo = gmyth_tvchain_get_program_at (tvplayer->tvchain, -1);
29.431 + if ( tvplayer->proginfo == NULL ) {
29.432 + g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
29.433 + res = FALSE;
29.434 + goto error;
29.435 + } else {
29.436 + g_debug ("[%s] MythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ );
29.437 + }
29.438 +
29.439 + return res;
29.440 +
29.441 +error:
29.442 + if ( tvplayer->backend_hostname != NULL ) {
29.443 + g_string_free( tvplayer->backend_hostname, TRUE );
29.444 + res = FALSE;
29.445 + }
29.446 +
29.447 + if ( tvplayer->local_hostname != NULL ) {
29.448 + g_string_free( tvplayer->local_hostname, TRUE );
29.449 + res = FALSE;
29.450 + }
29.451 +
29.452 + if ( tvplayer->remote_encoder != NULL ) {
29.453 + g_object_unref (tvplayer->remote_encoder);
29.454 + tvplayer->remote_encoder = NULL;
29.455 + }
29.456 +
29.457 + if ( tvplayer->tvchain != NULL ) {
29.458 + g_object_unref (tvplayer->tvchain);
29.459 + tvplayer->tvchain = NULL;
29.460 + }
29.461 +
29.462 + if ( tvplayer->proginfo != NULL ) {
29.463 + g_object_unref (tvplayer->proginfo);
29.464 + tvplayer->proginfo = NULL;
29.465 + }
29.466 +
29.467 + return res;
29.468 +
29.469 +}
29.470 +
29.471 +/** Sets the GTK video widget for the tv player.
29.472 + *
29.473 + * @param tvplayer the object instance.
29.474 + * @param videow the GTK video window.
29.475 + * @return TRUE if successfull, FALSE if any error happens.
29.476 + */
29.477 +gboolean
29.478 +gmyth_tvplayer_set_widget (GMythTVPlayer *tvplayer, GtkWidget *videow)
29.479 +{
29.480 + tvplayer->videow = videow;
29.481 + g_object_ref (videow);
29.482 +
29.483 + g_debug ("[%s] Setting widget for tv player render", __FUNCTION__);
29.484 +
29.485 + tvplayer->expose_handler = g_signal_connect (tvplayer->videow, "expose-event",
29.486 + G_CALLBACK (expose_cb), tvplayer);
29.487 +
29.488 + //g_signal_connect(miptv_ui->videow, "size_request", G_CALLBACK(cb_preferred_video_size), miptv_ui);
29.489 +
29.490 + return TRUE;
29.491 +}
29.492 +
29.493 +static gboolean
29.494 +bus_call (GstBus * bus, GstMessage * msg, gpointer data)
29.495 +{
29.496 + //GMythTVPlayer *tvplayer = GMYTH_TVPLAYER ( data );
29.497 + //GMainLoop *loop = tvplayer->loop;
29.498 +
29.499 + switch (GST_MESSAGE_TYPE (msg)) {
29.500 + case GST_MESSAGE_EOS:
29.501 + printf ("End of stream\n");
29.502 + //g_idle_add ((GSourceFunc) idle_eos, data);
29.503 + gst_element_set_state ( GST_ELEMENT (GST_MESSAGE_SRC (msg)), GST_STATE_NULL );
29.504 + gst_element_set_locked_state ( GST_ELEMENT (GST_MESSAGE_SRC (msg)), FALSE );
29.505 + break;
29.506 + case GST_MESSAGE_ERROR:
29.507 + {
29.508 + gchar *debug;
29.509 + GError *err;
29.510 +
29.511 + gst_message_parse_error (msg, &err, &debug);
29.512 + g_free (debug);
29.513 +
29.514 + printf ("Error: %s\n", err->message);
29.515 + g_error_free (err);
29.516 +
29.517 + //g_main_loop_quit (loop);
29.518 + }
29.519 + break;
29.520 + default:
29.521 + printf (gst_message_type_get_name (GST_MESSAGE_TYPE (msg)));
29.522 + printf ("\n");
29.523 + break;
29.524 + }
29.525 +
29.526 + return TRUE;
29.527 +}
29.528 +
29.529 +
29.530 +#if 0
29.531 +static gboolean
29.532 +idle_state (gpointer data)
29.533 +{
29.534 + GstPlayerWindowStateChange *st = data;
29.535 +
29.536 + if (st->old_state == GST_STATE_PLAYING) {
29.537 + if (st->miptv_ui->idle_id != 0) {
29.538 + g_source_remove (st->miptv_ui->idle_id);
29.539 + st->miptv_ui->idle_id = 0;
29.540 + }
29.541 + }
29.542 + else if (st->new_state == GST_STATE_PLAYING) {
29.543 + if (st->miptv_ui->idle_id != 0)
29.544 + g_source_remove (st->miptv_ui->idle_id);
29.545 +
29.546 + st->miptv_ui->idle_id = g_idle_add (cb_iterate, st->miptv_ui);
29.547 + }
29.548 +
29.549 + /* new movie loaded? */
29.550 + if (st->old_state == GST_STATE_READY && st->new_state > GST_STATE_READY) {
29.551 +
29.552 + /* gboolean have_video = FALSE; */
29.553 +
29.554 + gtk_widget_show (st->miptv_ui->videow);
29.555 +
29.556 + gtk_window_resize (GTK_WINDOW (st->miptv_ui->main_window), 1, 1);
29.557 +
29.558 + }
29.559 +
29.560 + /* discarded movie? */
29.561 + if (st->old_state > GST_STATE_READY && st->new_state == GST_STATE_READY) {
29.562 +
29.563 + if (st->miptv_ui->tagcache) {
29.564 + gst_tag_list_free (st->miptv_ui->tagcache);
29.565 + st->miptv_ui->tagcache = NULL;
29.566 + }
29.567 + }
29.568 +
29.569 + gst_object_unref (GST_OBJECT (st->play));
29.570 + //g_object_unref (G_OBJECT (st->win));
29.571 + g_free (st);
29.572 +
29.573 + /* once */
29.574 + return FALSE;
29.575 +}
29.576 +
29.577 +#endif
29.578 +
29.579 +/** Stops playing the current A/V.
29.580 + *
29.581 + * FIXME: How to proceed differently between livetv
29.582 + * and recorded content?
29.583 + *
29.584 + * @param tvplayer the object instance.
29.585 + * @return void
29.586 + */
29.587 +void
29.588 +gmyth_tvplayer_stop_playing (GMythTVPlayer *tvplayer)
29.589 +{
29.590 + g_debug ("[%s] Setting gstreamer pipeline state to NULL", __FUNCTION__);
29.591 +
29.592 + gst_element_set_state (tvplayer->gst_pipeline, GST_STATE_NULL);
29.593 +
29.594 + if (tvplayer->is_livetv) {
29.595 + if (!gmyth_remote_encoder_stop_livetv (tvplayer->remote_encoder)) {
29.596 + g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);
29.597 + }
29.598 + }
29.599 +}
29.600 +
29.601 +/** Queries if the tvplayer is active playing A/V content.
29.602 + *
29.603 + * @param tvplayer the object instance.
29.604 + * @return TRUE if the tvplayer is active, FALSE otherwise.
29.605 + */
29.606 +gboolean
29.607 +gmyth_tvplayer_is_playing (GMythTVPlayer *tvplayer)
29.608 +{
29.609 + return (GST_STATE (tvplayer->gst_pipeline) == GST_STATE_PLAYING);
29.610 +}
29.611 +
29.612 +/** Static function that sets the tvplayer state to PLAYING.
29.613 + *
29.614 + * @param tvplayer the object instance.
29.615 + * @return TRUE if the tvplayer is active, FALSE otherwise.
29.616 + */
29.617 +static gboolean
29.618 +idle_play (gpointer data)
29.619 +{
29.620 + GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (data);
29.621 +
29.622 + g_debug ("GMythTVPlayer: Setting pipeline state to PLAYING\n");
29.623 +
29.624 + gst_element_set_state (tvplayer->gst_pipeline, GST_STATE_PLAYING);
29.625 +
29.626 + return FALSE;
29.627 +}
29.628 +
29.629 +/** Start playing A/V with the tvplayer attributes.
29.630 + *
29.631 + * @param tvplayer the object instance.
29.632 + */
29.633 +void
29.634 +gmyth_tvplayer_start_playing (GMythTVPlayer *tvplayer)
29.635 +{
29.636 +
29.637 + // FIXME: Move this to livetv_setup??
29.638 + if (tvplayer->is_livetv) {
29.639 +
29.640 + #if 0
29.641 + if (!tvplayer || !(tvplayer->proginfo) || !(tvplayer->local_hostname)
29.642 + || !(tvplayer->gst_source)) {
29.643 + g_warning ("GMythtvPlayer not ready to start playing\n");
29.644 + }
29.645 +
29.646 + if (!(tvplayer->proginfo->pathname)) {
29.647 + g_warning ("[%s] Playback url is null, could not play the myth content", __FUNCTION__);
29.648 + return;
29.649 + }
29.650 +
29.651 + g_debug ("GMythTVPlayer: Start playing %s", tvplayer->proginfo->pathname->str);
29.652 +#endif
29.653 + g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live",
29.654 + TRUE, NULL);
29.655 +#if 0
29.656 + if ( tvplayer->tvchain != NULL ) {
29.657 + GString *str_chainid = gmyth_tvchain_get_id(tvplayer->tvchain);
29.658 + g_print( "[%s]\tCHAIN ID: %s\n", __FUNCTION__, str_chainid->str );
29.659 +
29.660 + g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live-chainid",
29.661 + g_strdup( str_chainid->str ), NULL);
29.662 + if ( str_chainid!=NULL)
29.663 + g_string_free( str_chainid, FALSE );
29.664 + }
29.665 +
29.666 + if ( tvplayer->remote_encoder != NULL )
29.667 + g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live-id",
29.668 + tvplayer->remote_encoder->recorder_num, NULL );
29.669 + g_debug ("[%s] Setting location to %s", __FUNCTION__,
29.670 + tvplayer->proginfo->pathname->str);
29.671 +
29.672 + /* Sets the gstreamer properties acording to the service access address */
29.673 + g_object_set (G_OBJECT (tvplayer->gst_source), "location",
29.674 + tvplayer->proginfo->pathname->str, NULL);
29.675 +#endif
29.676 + }
29.677 +
29.678 + g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-version",
29.679 + MYTHTV_VERSION_DEFAULT, NULL);
29.680 +
29.681 + g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-debug",
29.682 + TRUE, NULL);
29.683 +
29.684 + g_idle_add (idle_play, tvplayer);
29.685 +
29.686 +}
29.687 +
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/gmyth/src/gmyth_tvplayer.h Thu Sep 28 15:41:06 2006 +0100
30.3 @@ -0,0 +1,112 @@
30.4 +/**
30.5 + * GMyth Library
30.6 + *
30.7 + * @file gmyth/gmyth_tvplayer.h
30.8 + *
30.9 + * @brief <p> This component provides playback of the remote A/V using
30.10 + * GStreamer.
30.11 + *
30.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
30.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
30.14 + *
30.15 + *//*
30.16 + *
30.17 + * This program is free software; you can redistribute it and/or modify
30.18 + * it under the terms of the GNU Lesser General Public License as published by
30.19 + * the Free Software Foundation; either version 2 of the License, or
30.20 + * (at your option) any later version.
30.21 + *
30.22 + * This program is distributed in the hope that it will be useful,
30.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
30.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30.25 + * GNU General Public License for more details.
30.26 + *
30.27 + * You should have received a copy of the GNU Lesser General Public License
30.28 + * along with this program; if not, write to the Free Software
30.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30.30 + */
30.31 +
30.32 +#ifndef GMYTH_TVPLAYER_H_
30.33 +#define GMYTH_TVPLAYER_H_
30.34 +
30.35 +#include <glib-object.h>
30.36 +#include <gtk/gtk.h>
30.37 +
30.38 +/* GStreamer includes */
30.39 +#include <gst/gst.h>
30.40 +#include <gst/interfaces/xoverlay.h>
30.41 +
30.42 +#include "gmyth_remote_encoder.h"
30.43 +#include "gmyth_tvchain.h"
30.44 +#include "gmyth_common.h"
30.45 +
30.46 +G_BEGIN_DECLS
30.47 +
30.48 +#define GMYTH_TVPLAYER_TYPE (gmyth_tvplayer_get_type ())
30.49 +#define GMYTH_TVPLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVPLAYER_TYPE, GMythTVPlayer))
30.50 +#define GMYTH_TVPLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVPLAYER_TYPE, GMythTVPlayerClass))
30.51 +#define IS_GMYTH_TVPLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVPLAYER_TYPE))
30.52 +#define IS_GMYTH_TVPLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVPLAYER_TYPE))
30.53 +#define GMYTH_TVPLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVPLAYER_TYPE, GMythTVPlayerClass))
30.54 +
30.55 +
30.56 +typedef struct _GMythTVPlayer GMythTVPlayer;
30.57 +typedef struct _GMythTVPlayerClass GMythTVPlayerClass;
30.58 +
30.59 +struct _GMythTVPlayerClass
30.60 +{
30.61 + GObjectClass parent_class;
30.62 +
30.63 + /* callbacks */
30.64 + /* no one for now */
30.65 +};
30.66 +
30.67 +struct _GMythTVPlayer
30.68 +{
30.69 + GObject parent;
30.70 +
30.71 + GstElement *gst_pipeline;
30.72 + GstElement *gst_source;
30.73 + GstElement *gst_videodec;
30.74 + GstElement *gst_videosink;
30.75 + GstElement *videoqueue;
30.76 + GstElement *audioqueue;
30.77 +
30.78 + gulong expose_handler;
30.79 +// GMainLoop *loop;
30.80 +
30.81 + GtkWidget *videow;
30.82 +
30.83 + /* Backend connection related variables */
30.84 + GString *backend_hostname;
30.85 + gint backend_port;
30.86 + GString *local_hostname;
30.87 +
30.88 + GMythRemoteEncoder *remote_encoder;
30.89 + GMythTVChain *tvchain;
30.90 + GMythProgramInfo *proginfo;
30.91 +
30.92 + gboolean is_livetv;
30.93 +};
30.94 +
30.95 +
30.96 +GType gmyth_tvplayer_get_type (void);
30.97 +
30.98 +GMythTVPlayer* gmyth_tvplayer_new ();
30.99 +gboolean gmyth_tvplayer_initialize (GMythTVPlayer *tvplayer);
30.100 +
30.101 +void gmyth_tvplayer_start_playing (GMythTVPlayer *tvplayer);
30.102 +void gmyth_tvplayer_stop_playing (GMythTVPlayer *tvplayer);
30.103 +
30.104 +gboolean gmyth_tvplayer_set_widget (GMythTVPlayer *tvplayer,
30.105 + GtkWidget *videow);
30.106 +
30.107 +gboolean gmyth_tvplayer_is_playing (GMythTVPlayer *tvplayer);
30.108 +
30.109 +gboolean gmyth_tvplayer_record_setup (GMythTVPlayer *tvplayer,
30.110 + gchar *filename);
30.111 +gboolean gmyth_tvplayer_livetv_setup (GMythTVPlayer *tvplayer);
30.112 +
30.113 +G_END_DECLS
30.114 +
30.115 +#endif /*GMYTH_TVPLAYER_H_*/
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/gmyth/src/gmyth_util.c Thu Sep 28 15:41:06 2006 +0100
31.3 @@ -0,0 +1,138 @@
31.4 +/**
31.5 +* GMyth Library
31.6 +*
31.7 +* @file gmyth/gmyth_util.c
31.8 +*
31.9 +* @brief <p> This component provides utility functions.
31.10 +*
31.11 +* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
31.12 +* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
31.13 +*
31.14 +*//*
31.15 +*
31.16 +* This program is free software; you can redistribute it and/or modify
31.17 +* it under the terms of the GNU Lesser General Public License as published by
31.18 +* the Free Software Foundation; either version 2 of the License, or
31.19 +* (at your option) any later version.
31.20 +*
31.21 +* This program is distributed in the hope that it will be useful,
31.22 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
31.23 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31.24 +* GNU General Public License for more details.
31.25 +*
31.26 +* You should have received a copy of the GNU Lesser General Public License
31.27 +* along with this program; if not, write to the Free Software
31.28 +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31.29 +*/
31.30 +
31.31 +#include "gmyth_util.h"
31.32 +
31.33 +#include <glib.h>
31.34 +#include <glib/gprintf.h>
31.35 +
31.36 +/** Converts a time_t struct in a GString at ISO standard format
31.37 + * (e.g. 2006-07-20T09:56:41).
31.38 + *
31.39 + * The returned GString memory should be deallocated from
31.40 + * the calling function.
31.41 + *
31.42 + * @param time_value the time value to be converted
31.43 + * @return GString* the converted isoformat string
31.44 + */
31.45 +GString*
31.46 +gmyth_util_time_to_isoformat (time_t time_value)
31.47 +{
31.48 + struct tm tm_time;
31.49 + GString *result;
31.50 +
31.51 + if (localtime_r(&time_value, &tm_time) == NULL) {
31.52 + g_warning ("gmyth_util_time_to_isoformat convertion error!\n");
31.53 + return NULL;
31.54 + }
31.55 +
31.56 + result = g_string_sized_new(20);
31.57 + g_string_printf(result, "%04d-%02d-%02dT%02d:%02d:%02d",
31.58 + tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
31.59 + tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);
31.60 +
31.61 + return result;
31.62 +}
31.63 +
31.64 +/** Converts a time_t struct in a GString to the following
31.65 + * format (e.g. 2006-07-20 09:56:41).
31.66 + *
31.67 + * The returned GString memory should be deallocated from
31.68 + * the calling function.
31.69 + *
31.70 + * @param time_value the time value to be converted
31.71 + * @return GString* the converted string
31.72 + */
31.73 +GString*
31.74 +gmyth_util_time_to_string (time_t time_value)
31.75 +{
31.76 + GString *result = gmyth_util_time_to_isoformat (time_value);
31.77 + result->str[10] = ' ';
31.78 +
31.79 + return result;
31.80 +}
31.81 +
31.82 +/** Converts a GString in the following format
31.83 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
31.84 + *
31.85 + * @param time_str the string to be converted
31.86 + * @return time_t the time converted value
31.87 + */
31.88 +time_t
31.89 +gmyth_util_string_to_time (GString* time_str)
31.90 +{
31.91 + int year, month, day, hour, min, sec;
31.92 +
31.93 + g_debug( "[%s] time_str = %s.\n", __FUNCTION__, time_str != NULL ? time_str->str : "[time string is NULL!]" );
31.94 +
31.95 + if (sscanf (time_str->str, "%04d-%02d-%02d %02d:%02d:%02d",
31.96 + &year, &month, &day, &hour, &min, &sec) < 3) { /* At least date */
31.97 + g_warning ("GMythUtil: isoformat_to_time converter error!\n");
31.98 + return 0;
31.99 + } else {
31.100 + struct tm tm_time;
31.101 + tm_time.tm_year = year - 1900;
31.102 + tm_time.tm_mon = month - 1;
31.103 + tm_time.tm_mday = day;
31.104 + tm_time.tm_hour = hour;
31.105 + tm_time.tm_min = min;
31.106 + tm_time.tm_sec = sec;
31.107 +
31.108 + return mktime (&tm_time);
31.109 + }
31.110 +}
31.111 +
31.112 +/** Decodes a long long variable from the string list
31.113 + * format of the myhtprotocol.
31.114 + *
31.115 + * @param strlist the string list of mythprotocol values
31.116 + * @param offset the list node offset of the long long variable
31.117 + * @return guint64 the long long converted value
31.118 + */
31.119 +guint64
31.120 +gmyth_util_decode_long_long(GMythStringList *strlist, guint offset)
31.121 +{
31.122 +
31.123 + guint64 ret_value = 0LL;
31.124 +
31.125 + g_return_val_if_fail( strlist != NULL, ret_value );
31.126 +
31.127 + if ( offset < gmyth_string_list_length( strlist ))
31.128 + g_printerr( "[%s] Offset is lower than the Stringlist (offset = %d)!\n",
31.129 + __FUNCTION__, offset );
31.130 +
31.131 + g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value );
31.132 +
31.133 + gint l1 = gmyth_string_list_get_int( strlist, offset );
31.134 + gint l2 = gmyth_string_list_get_int( strlist, offset + 1 );
31.135 +
31.136 + ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
31.137 +
31.138 + return ret_value;
31.139 +
31.140 +}
31.141 +
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/gmyth/src/gmyth_util.h Thu Sep 28 15:41:06 2006 +0100
32.3 @@ -0,0 +1,45 @@
32.4 +/**
32.5 +* GMyth Library
32.6 +*
32.7 +* @file gmyth/gmyth_util.h
32.8 +*
32.9 +* @brief <p> This component provides utility functions.
32.10 +*
32.11 +* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
32.12 +* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
32.13 +*
32.14 +*//*
32.15 +*
32.16 +* This program is free software; you can redistribute it and/or modify
32.17 +* it under the terms of the GNU Lesser General Public License as published by
32.18 +* the Free Software Foundation; either version 2 of the License, or
32.19 +* (at your option) any later version.
32.20 +*
32.21 +* This program is distributed in the hope that it will be useful,
32.22 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
32.23 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32.24 +* GNU General Public License for more details.
32.25 +*
32.26 +* You should have received a copy of the GNU Lesser General Public License
32.27 +* along with this program; if not, write to the Free Software
32.28 +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32.29 +*/
32.30 +
32.31 +#ifndef GMYTH_UTIL_H_
32.32 +#define GMYTH_UTIL_H_
32.33 +
32.34 +#include <time.h>
32.35 +#include <glib.h>
32.36 +
32.37 +#include "gmyth_stringlist.h"
32.38 +
32.39 +G_BEGIN_DECLS
32.40 +
32.41 +GString * gmyth_util_time_to_isoformat(time_t time_value);
32.42 +GString * gmyth_util_time_to_string (time_t time_value);
32.43 +time_t gmyth_util_string_to_time (GString* time_str);
32.44 +guint64 gmyth_util_decode_long_long (GMythStringList *strlist,
32.45 + guint offset);
32.46 +G_END_DECLS
32.47 +
32.48 +#endif /*GMYTH_UTIL_H_*/
33.1 --- a/gmyth/src/gui/Makefile.am Wed Sep 27 00:08:03 2006 +0100
33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
33.3 @@ -1,29 +0,0 @@
33.4 -noinst_LTLIBRARIES = libmmythgui.la
33.5 -
33.6 -libmmythgui_la_SOURCES = \
33.7 - mmyth_ui.c \
33.8 - mmyth_uicommon.c \
33.9 - mmyth_epg_grid_view.c \
33.10 - mmyth_epg_grid_widget.c \
33.11 - mmyth_recordui.c \
33.12 - mmyth_uisettings.c \
33.13 - mmyth_schedulerui.c
33.14 -
33.15 -libmmythgui_la_CFLAGS = \
33.16 - $(GTK_CFLAGS) \
33.17 - $(GLIB_CFLAGS) \
33.18 - $(GST_CFLAGS) \
33.19 - $(MYSQL_CFLAGS) \
33.20 - -I$(top_srcdir)/src/libgmyth \
33.21 - -I$(top_srcdir)/src \
33.22 - -DDATA_DIR=\""$(pkgdatadir)"\" \
33.23 - -DPIX_DIR=\""$(pkgdatadir)/pixmaps/"\" \
33.24 - -DICON_DIR=\""$(datadir)/pixmaps/"\" \
33.25 - -g3 -O0
33.26 -
33.27 -libmmythgui_la_LIBADD = \
33.28 - $(top_srcdir)/src/libgmyth/libgmyth.la
33.29 -
33.30 -libmmythgui_la_LDFLAGS = -export-dynamic
33.31 -
33.32 -
34.1 --- a/gmyth/src/gui/mmyth_epg_grid_view.c Wed Sep 27 00:08:03 2006 +0100
34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
34.3 @@ -1,213 +0,0 @@
34.4 -#include <string.h>
34.5 -#include <stdlib.h>
34.6 -#include <gtk/gtk.h>
34.7 -#include <gdk/gdkkeysyms.h>
34.8 -#include <time.h>
34.9 -
34.10 -#include "mmyth_epg_grid_view.h"
34.11 -#include "mmyth_epg_grid_widget.h"
34.12 -
34.13 -/* Service genre */
34.14 -#define GENRE_MIN 0
34.15 -#define GENRE_MAX 10
34.16 -#define GENRE_UNDEFINED 0
34.17 -#define GENRE_MOVIE 1
34.18 -#define GENRE_NEWS 2
34.19 -#define GENRE_SHOW 3
34.20 -#define GENRE_SPORTS 4
34.21 -#define GENRE_CHILDREN 5
34.22 -#define GENRE_MUSIC 6
34.23 -#define GENRE_CULTURE 7
34.24 -#define GENRE_SOCIAL 8
34.25 -#define GENRE_EDUCATION 9
34.26 -#define GENRE_LEISURE 10
34.27 -
34.28 -#define NRO_HOURS 3
34.29 -
34.30 -/* Function prototypes*/
34.31 -static void update_service_details(MMythEpgGridWidget *object,
34.32 - gpointer arg1, gpointer user_data);
34.33 -static gboolean key_press_epg_grid_view(GtkWidget * widget,
34.34 - GdkEventKey * event,
34.35 - gpointer user_data);
34.36 -
34.37 -static GtkWidget *mmyth_epg_grid_widget = NULL;
34.38 -
34.39 -/* is a GtkEventBox */
34.40 -static GtkWidget *program_details_area = NULL;
34.41 -static GtkWidget *details_main_hbox = NULL;
34.42 -static GtkWidget *details_vbox = NULL;
34.43 -static GtkWidget *details_logo_vbox = NULL;
34.44 -
34.45 -/* update signal callback from MMythEpgGridWidget */
34.46 -static void
34.47 -update_service_details(MMythEpgGridWidget *object, gpointer arg1, gpointer user_data)
34.48 -{
34.49 - g_return_if_fail(arg1 != NULL);
34.50 -
34.51 - EpgGridItem *epg_grid_item = (EpgGridItem *) arg1;
34.52 -
34.53 - gchar sel_prog_desc[100] = "<big><b>";
34.54 - gchar time_buffer[50];
34.55 -
34.56 - /* FIXME: get first content from content_list*/
34.57 - GMythProgramInfo *proginfo = (GMythProgramInfo *) epg_grid_item->proginfo;
34.58 -
34.59 - if(proginfo) {
34.60 - GString *prog_name = proginfo->title;
34.61 - GString *service_name = proginfo->chanid;
34.62 -
34.63 - if(details_vbox != NULL)
34.64 - gtk_container_remove (GTK_CONTAINER (details_main_hbox), details_vbox);
34.65 -
34.66 - /* update service description */
34.67 - strcat(sel_prog_desc, service_name->str);
34.68 - strcat(sel_prog_desc, "</b></big>");
34.69 -
34.70 - GtkWidget *fst_line_lbl = gtk_label_new(NULL);
34.71 - gtk_misc_set_alignment (GTK_MISC(fst_line_lbl), 0.0, 0.0);
34.72 - gtk_label_set_markup(GTK_LABEL(fst_line_lbl), sel_prog_desc);
34.73 -
34.74 - /* freeing char[] */
34.75 - sel_prog_desc[0] = 0;
34.76 - strcat(sel_prog_desc, "\t");
34.77 - strcat(sel_prog_desc, prog_name->str);
34.78 -
34.79 - struct tm loctime_start, loctime_end;
34.80 -
34.81 - // Convert it to local time representation.
34.82 - /* FIXME: conversion from time to localtime is different
34.83 - in different machines */
34.84 - long int schedule_start_time = proginfo->startts;
34.85 - long int schedule_end_time = proginfo->endts;
34.86 -
34.87 - if (localtime_r(&schedule_start_time, &loctime_start) == NULL) {
34.88 - g_warning ("localtime_r error in mmyth_epg_grid_view!\n");
34.89 - }
34.90 -
34.91 - #if 0
34.92 - fprintf (stderr, asctime (loctime_start));
34.93 - #endif
34.94 -
34.95 - strftime (time_buffer, 100, " %H:%M - ", &loctime_start);
34.96 - strcat(sel_prog_desc, time_buffer );
34.97 -
34.98 - if (localtime_r(&schedule_end_time, &loctime_end) == NULL) {
34.99 - g_warning ("localtime_r error in mmyth_epg_grid_view!\n");
34.100 - }
34.101 -
34.102 - #if 0
34.103 - fprintf (stderr, asctime (loctime_end));
34.104 - #endif
34.105 -
34.106 - strftime (time_buffer, 100, "%H:%M\n", &loctime_end);
34.107 - strcat(sel_prog_desc, time_buffer );
34.108 -
34.109 - GtkWidget *snd_line_lbl = gtk_label_new(NULL);
34.110 - gtk_misc_set_alignment (GTK_MISC(snd_line_lbl), 0.0, 0.0);
34.111 - gtk_label_set_markup(GTK_LABEL(snd_line_lbl), sel_prog_desc);
34.112 -
34.113 - // add the current selected program description to the label
34.114 - details_vbox = gtk_vbox_new(FALSE, 0);
34.115 - GtkWidget *fst_line_hbox = gtk_hbox_new(FALSE, 0);
34.116 -
34.117 - gtk_box_pack_start (GTK_BOX (fst_line_hbox),
34.118 - fst_line_lbl, FALSE, FALSE, 6);
34.119 - gtk_box_pack_start (GTK_BOX (details_vbox),
34.120 - fst_line_hbox, FALSE, FALSE, 0);
34.121 - gtk_box_pack_start (GTK_BOX (details_vbox),
34.122 - snd_line_lbl, FALSE, FALSE, 0);
34.123 - gtk_box_pack_start (GTK_BOX (details_main_hbox),
34.124 - details_vbox, FALSE, FALSE, 0);
34.125 -
34.126 - gtk_widget_show_all(details_main_hbox);
34.127 - }
34.128 -}
34.129 -
34.130 -/* Callback for hardware keys */
34.131 -static gboolean
34.132 -key_press_epg_grid_view(GtkWidget * widget,
34.133 - GdkEventKey * event, gpointer user_data)
34.134 -{
34.135 - MMythEpgGridWidget *mmyth_epg_grid_widget = (MMythEpgGridWidget *) user_data;
34.136 -
34.137 - return mmyth_epg_grid_widget_key_press(mmyth_epg_grid_widget, widget, event);
34.138 -}
34.139 -
34.140 -GtkWidget *
34.141 -epg_grid_view_new (MMythUi* mmyth_ui)
34.142 -{
34.143 - GtkWidget *scrolled_window;
34.144 - scrolled_window = gtk_scrolled_window_new (NULL, NULL);
34.145 - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
34.146 - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
34.147 -
34.148 - gtk_widget_modify_bg(scrolled_window, GTK_STATE_NORMAL, &main_bg_color);
34.149 -
34.150 - GtkWidget *main_vbox = gtk_vbox_new (FALSE, 0);
34.151 - //gtk_container_set_border_width(main_vbox, 4);
34.152 -
34.153 - GtkWidget *details_event_box = gtk_event_box_new();
34.154 - gtk_widget_modify_bg(details_event_box, GTK_STATE_NORMAL, &main_bg_color);
34.155 -
34.156 - program_details_area = gtk_vbox_new (FALSE, 0);
34.157 - gtk_container_add (GTK_CONTAINER (details_event_box),
34.158 - program_details_area);
34.159 - gtk_container_set_border_width(GTK_CONTAINER (program_details_area), 4);
34.160 -
34.161 - details_main_hbox = gtk_hbox_new (FALSE, 10);
34.162 -
34.163 - gtk_box_pack_start (GTK_BOX (program_details_area),
34.164 - details_main_hbox, FALSE, FALSE, 0);
34.165 -
34.166 - details_logo_vbox = gtk_vbox_new (FALSE, 0);
34.167 -
34.168 - GtkWidget *details_desc_vbox = gtk_vbox_new (FALSE, 0);
34.169 -
34.170 - gtk_box_pack_start (GTK_BOX (details_main_hbox),
34.171 - details_desc_vbox, FALSE, FALSE, 0);
34.172 - gtk_box_pack_start (GTK_BOX (details_main_hbox),
34.173 - details_logo_vbox, FALSE, FALSE, 0);
34.174 -
34.175 - gtk_widget_set_size_request (program_details_area, -1, 120);
34.176 -
34.177 - mmyth_epg_grid_widget = mmyth_epg_grid_widget_new();
34.178 - g_signal_connect(mmyth_epg_grid_widget, "selection_updated",
34.179 - G_CALLBACK (update_service_details), NULL);
34.180 -
34.181 - /* select by default the first service */
34.182 - /* depends on mount services */
34.183 - if (MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget)->epg_view_model) {
34.184 - GList *fst_service = (GList *)
34.185 - MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget)->epg_view_model->data;
34.186 - mmyth_epg_grid_widget_update_service(MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget),
34.187 - fst_service);
34.188 - }
34.189 -
34.190 - gtk_box_pack_start (GTK_BOX (main_vbox),
34.191 - details_event_box, FALSE, FALSE, 0);
34.192 - gtk_box_pack_start (GTK_BOX (main_vbox),
34.193 - gtk_hseparator_new(), FALSE, FALSE, 0);
34.194 - gtk_box_pack_start (GTK_BOX (main_vbox),
34.195 - mmyth_epg_grid_widget, FALSE, FALSE, 0);
34.196 -
34.197 - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window),
34.198 - main_vbox);
34.199 -
34.200 - /* Add hardware button listener to application */
34.201 - g_signal_connect(mmyth_ui->main_window, "key_press_event",
34.202 - G_CALLBACK (key_press_epg_grid_view), mmyth_epg_grid_widget);
34.203 -
34.204 - gtk_widget_show_all (scrolled_window);
34.205 -
34.206 - return scrolled_window;
34.207 -}
34.208 -
34.209 -/*
34.210 -DVBHScheduleEvent *
34.211 -mmyth_epg_grid_view_get_selected_schedule()
34.212 -{
34.213 - return mmyth_epg_grid_get_selected_schedule
34.214 - (MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget));
34.215 -}
34.216 -*/
35.1 --- a/gmyth/src/gui/mmyth_epg_grid_view.h Wed Sep 27 00:08:03 2006 +0100
35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
35.3 @@ -1,8 +0,0 @@
35.4 -#ifndef MMYTH_ESG_GRID_VIEW_H_
35.5 -#define MMYTH_ESG_GRID_VIEW_H_
35.6 -
35.7 -#include "mmyth_ui.h"
35.8 -
35.9 -GtkWidget *epg_grid_view_new(MMythUi * mmyth_ui);
35.10 -
35.11 -#endif /* MMYTH_ESG_GRID_VIEW_H_ */
36.1 --- a/gmyth/src/gui/mmyth_epg_grid_widget.c Wed Sep 27 00:08:03 2006 +0100
36.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
36.3 @@ -1,622 +0,0 @@
36.4 -#include <gtk/gtksignal.h>
36.5 -#include <gdk/gdkevents.h>
36.6 -#include <gdk/gdkkeysyms.h>
36.7 -
36.8 -#include "mmyth_uicommon.h"
36.9 -#include "mmyth_epg_grid_widget.h"
36.10 -
36.11 -#include "gmyth_util.h"
36.12 -#include "gmyth_epg.h"
36.13 -
36.14 -#define PIXELS_HOUR 105
36.15 -#define PROGRAM_SEPARATION 2
36.16 -
36.17 -enum {
36.18 - SELECTION_UPDATED_SIGNAL,
36.19 - LAST_SIGNAL
36.20 -};
36.21 -
36.22 -struct _MMythEpgGridWidgetPrivate {
36.23 - /* private widget components */
36.24 - GtkWidget *epg_channels_vbox;
36.25 - GtkWidget *epg_programs_vbox;
36.26 -
36.27 - GHashTable *service_model_hash;
36.28 -
36.29 - /* guidegrid attributes */
36.30 - gboolean show_favorites;
36.31 - gint current_start_channel_id;
36.32 -
36.33 - time_t current_start_time;
36.34 - time_t current_end_time;
36.35 -
36.36 - guint selected_channel_index;
36.37 -
36.38 - /* GList of ProgramInfo for each Channel */
36.39 - GList * program_list[MAX_DISPLAY_CHANS];
36.40 - GList * channel_list;
36.41 -
36.42 - GMythEPG *mmyth_epg;
36.43 -
36.44 - gint DISPLAY_CHANS;
36.45 -};
36.46 -
36.47 -static void mmyth_epg_grid_widget_class_init (MMythEpgGridWidgetClass *klass);
36.48 -static void mmyth_epg_grid_widget_init (MMythEpgGridWidget *object);
36.49 -static void mmyth_epg_grid_widget_private_init (MMythEpgGridWidgetPrivate *private);
36.50 -static void mmyth_epg_grid_widget_mount_services (MMythEpgGridWidget *object,
36.51 - int start_time, int end_time);
36.52 -static void mmyth_epg_grid_widget_mount_header (MMythEpgGridWidget *object);
36.53 -static void mmyth_epg_grid_widget_clicked (GtkWidget* widget,
36.54 - GdkEventExpose *event,
36.55 - gpointer data);
36.56 -static GtkWidget *create_event_box_lbl (gchar *str, int width,
36.57 - const GdkColor *bg_color,
36.58 - const GdkColor *fg_color);
36.59 -
36.60 -static void mmyth_epg_grid_widget_fill_programinfos(MMythEpgGridWidgetPrivate *private);
36.61 -static void mmyth_epg_grid_widget_fill_program_row_infos(
36.62 - MMythEpgGridWidgetPrivate *private,
36.63 - unsigned int chanNum, unsigned int row);
36.64 -
36.65 -static gint mmyth_epg_grid_widget_signals[LAST_SIGNAL] = { 0 };
36.66 -
36.67 -G_DEFINE_TYPE(MMythEpgGridWidget, mmyth_epg_grid_widget, GTK_TYPE_EVENT_BOX)
36.68 -
36.69 -static void
36.70 -mmyth_epg_grid_widget_class_init (MMythEpgGridWidgetClass *klass)
36.71 -{
36.72 - g_type_class_add_private (klass, sizeof (MMythEpgGridWidgetPrivate));
36.73 -
36.74 - mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL] = g_signal_new (
36.75 - "selection_updated",
36.76 - G_TYPE_FROM_CLASS(klass),
36.77 - G_SIGNAL_RUN_FIRST,
36.78 - 0,
36.79 - NULL,
36.80 - NULL,
36.81 - g_cclosure_marshal_VOID__POINTER,
36.82 - G_TYPE_NONE,
36.83 - 1,
36.84 - G_TYPE_POINTER);
36.85 -}
36.86 -
36.87 -static void
36.88 -mmyth_epg_grid_widget_private_init (MMythEpgGridWidgetPrivate *private)
36.89 -{
36.90 - time_t cur_time;
36.91 -
36.92 - g_return_if_fail(private != NULL);
36.93 -
36.94 - private->epg_channels_vbox = NULL;
36.95 - private->epg_programs_vbox = NULL;
36.96 - private->service_model_hash = NULL;
36.97 -
36.98 - private->show_favorites = FALSE;
36.99 - private->current_start_channel_id = -1;
36.100 -
36.101 - /* Selected the first diplayable channel initially */
36.102 - private->selected_channel_index = 0;
36.103 -
36.104 - /* TODO fix the current start/end time */
36.105 - private->current_start_time = time(&cur_time);
36.106 - private->current_end_time = time(&cur_time) + 10800;
36.107 -
36.108 - private->DISPLAY_CHANS = MAX_DISPLAY_CHANS;
36.109 -
36.110 - // TODO: Close the epg and unref it in dispose call
36.111 - private->mmyth_epg = gmyth_epg_new ();
36.112 - if (!gmyth_epg_connect (private->mmyth_epg)) {
36.113 - g_warning ("[%s] Could not connect mysql handler to db", __FUNCTION__);
36.114 - g_object_unref (private->mmyth_epg);
36.115 - private->mmyth_epg = NULL;
36.116 - }
36.117 -}
36.118 -
36.119 -static void
36.120 -mmyth_epg_grid_widget_init (MMythEpgGridWidget *mmyth_epg_grid_widget)
36.121 -{
36.122 - MMythEpgGridWidgetPrivate *private =
36.123 - MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
36.124 -
36.125 - /* init private fields */
36.126 - mmyth_epg_grid_widget_private_init(private);
36.127 -
36.128 - mmyth_epg_grid_widget->epg_view_model = NULL;
36.129 - mmyth_epg_grid_widget->selected_grid_item = NULL;
36.130 -
36.131 - GtkWidget *epg_event_box = GTK_WIDGET(mmyth_epg_grid_widget);
36.132 - gtk_widget_modify_bg(epg_event_box, GTK_STATE_NORMAL, &main_bg_color);
36.133 - gtk_widget_set_size_request (epg_event_box, 0, 125);
36.134 -
36.135 - GtkWidget *epg_main_hbox = gtk_hbox_new (FALSE, 10);
36.136 - gtk_container_set_border_width(GTK_CONTAINER (epg_main_hbox), 10);
36.137 -
36.138 - gtk_container_add (GTK_CONTAINER (epg_event_box),
36.139 - epg_main_hbox);
36.140 -
36.141 - /* channels vbox */
36.142 - GtkWidget *epg_channels_vbox = gtk_vbox_new (FALSE, 3);
36.143 - private->epg_channels_vbox = epg_channels_vbox;
36.144 -
36.145 - /* programs vbox */
36.146 - GtkWidget *epg_programs_vbox = gtk_vbox_new (FALSE, 3);
36.147 - private->epg_programs_vbox = epg_programs_vbox;
36.148 -
36.149 - /* packing start */
36.150 - gtk_box_pack_start (GTK_BOX (epg_main_hbox),
36.151 - epg_channels_vbox, FALSE, FALSE, 0);
36.152 - gtk_box_pack_start (GTK_BOX (epg_main_hbox),
36.153 - epg_programs_vbox, FALSE, FALSE, 0);
36.154 -
36.155 - /* table header (first line) */
36.156 - mmyth_epg_grid_widget_mount_header(mmyth_epg_grid_widget);
36.157 -
36.158 - /* service programs */
36.159 - /* mount service programs with current time */
36.160 - mmyth_epg_grid_widget_mount_services(mmyth_epg_grid_widget,
36.161 - private->current_start_time,
36.162 - private->current_end_time);
36.163 -}
36.164 -
36.165 -GtkWidget*
36.166 -mmyth_epg_grid_widget_new ()
36.167 -{
36.168 - return GTK_WIDGET ( gtk_type_new (mmyth_epg_grid_widget_get_type ()));
36.169 -}
36.170 -
36.171 -static void
36.172 -mmyth_epg_grid_widget_mount_services(MMythEpgGridWidget *mmyth_epg_grid_widget,
36.173 - int start_time, int end_time)
36.174 -{
36.175 - GList *proglist;
36.176 - GList *channel_list = NULL;
36.177 - GMythChannelInfo *channel_info;
36.178 -
36.179 - int chanid;
36.180 - MMythEpgGridWidgetPrivate *private =
36.181 - MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
36.182 -
36.183 - // update view_model
36.184 - /* FIXME shallow free or recursive? */
36.185 - if(mmyth_epg_grid_widget->epg_view_model != NULL) {
36.186 - g_list_free(mmyth_epg_grid_widget->epg_view_model);
36.187 - mmyth_epg_grid_widget->epg_view_model = NULL;
36.188 - }
36.189 -
36.190 - if(private->service_model_hash != NULL) {
36.191 - g_hash_table_destroy(private->service_model_hash);
36.192 - }
36.193 -
36.194 - private->service_model_hash = g_hash_table_new(NULL, NULL);
36.195 -
36.196 - /* fill program infos from db */
36.197 - mmyth_epg_grid_widget_fill_programinfos(private);
36.198 -
36.199 - channel_list = private->channel_list;
36.200 -
36.201 - /* for each channel get_programs() */
36.202 - for (chanid=0; channel_list &&
36.203 - chanid < private->DISPLAY_CHANS; chanid++) {
36.204 - proglist = (GList *) private->program_list[chanid];
36.205 -
36.206 - channel_info = (GMythChannelInfo *) channel_list->data;
36.207 - channel_list = g_list_next(channel_list);
36.208 -
36.209 - /* Service Title*/
36.210 - GString *name = NULL;
36.211 - if (channel_info->channel_name)
36.212 - name = g_string_new (channel_info->channel_name->str);
36.213 -
36.214 - GdkColor title_bg_color;
36.215 - title_bg_color.red = 5000;
36.216 - title_bg_color.green = 9000;
36.217 - title_bg_color.blue = 40000;
36.218 -
36.219 - GdkColor title_fg_color;
36.220 - title_fg_color.red = 60000;
36.221 - title_fg_color.green = 60000;
36.222 - title_fg_color.blue = 60000;
36.223 -
36.224 - GtkWidget *event_box_channel = create_event_box_lbl(
36.225 - name->str, 90,
36.226 - &title_bg_color,
36.227 - &title_fg_color);
36.228 -
36.229 - gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
36.230 - event_box_channel, FALSE, FALSE, 0);
36.231 -
36.232 - GtkWidget *epg_line_hbox = gtk_hbox_new (FALSE, 0);
36.233 -
36.234 - GdkColor bg_color;
36.235 - bg_color.red = 5000;
36.236 - bg_color.green = 30000;
36.237 - bg_color.blue = 60000;
36.238 -
36.239 - GdkColor fg_color;
36.240 - fg_color.red = 60000;
36.241 - fg_color.green = 60000;
36.242 - fg_color.blue = 60000;
36.243 -
36.244 - /* Content parsing */
36.245 - GList *epg_grid_list = NULL;
36.246 -
36.247 - GMythProgramInfo *proginfo;
36.248 - int pixel_count = 0;
36.249 - for (; proglist; proglist = proglist->next) {
36.250 - proginfo = (GMythProgramInfo *) proglist->data;
36.251 -
36.252 - GString *content_name = proginfo->title;
36.253 -
36.254 - int initial_time, last_time, duration;
36.255 -
36.256 - int schedule_start_time = proginfo->startts;
36.257 - int schedule_end_time = proginfo->endts;
36.258 -
36.259 - initial_time =
36.260 - (schedule_start_time < start_time) ? start_time : schedule_start_time;
36.261 - last_time = (schedule_end_time > end_time) ? end_time : schedule_end_time;
36.262 - duration = last_time - initial_time;
36.263 -
36.264 - // Verify program time
36.265 - #if 0
36.266 - g_debug ("ServiceID: %d, ScheduleID: %d\n", service->id, schedule->id);
36.267 - fprintf (stderr, "program time\nfrom = %d, to = %d\n",
36.268 - schedule->validFrom, schedule->validTo);
36.269 -
36.270 - struct tm loctime;
36.271 -
36.272 - /* Convert it to local time representation. */
36.273 - if (localtime_r((time_t *)&schedule->validFrom, &loctime) == NULL) {
36.274 - g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
36.275 - return NULL;
36.276 - }
36.277 - fprintf (stderr, asctime (&loctime));
36.278 -
36.279 - if (localtime_r((time_t *)&schedule->validTo, &loctime) == NULL) {
36.280 - g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
36.281 - return NULL;
36.282 - }
36.283 - fprintf (stderr, asctime (&loctime));
36.284 - #endif
36.285 -
36.286 - /* fprintf(stderr, "duration = %d\n", duration); */
36.287 - double duration_hour = duration / (double) 3600.0;
36.288 - /* fprintf(stderr, "duration_hour = %lf\n", duration_hour); */
36.289 -
36.290 - int size = PIXELS_HOUR * duration_hour;
36.291 -
36.292 - /* complete hour */
36.293 - /* FIXME: UGLY WRONG HACK TO ALIGN PROGRAM TIME!!!*/
36.294 - if(last_time%3600 != 0) {
36.295 - size -= PROGRAM_SEPARATION;
36.296 - }
36.297 - if(initial_time%3600 != 0) {
36.298 - size -= PROGRAM_SEPARATION;
36.299 - }
36.300 -
36.301 - pixel_count += size + PROGRAM_SEPARATION;
36.302 - GtkWidget *event_box = create_event_box_lbl(content_name->str,
36.303 - size, &bg_color,
36.304 - &fg_color);
36.305 - gtk_widget_add_events(event_box,
36.306 - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
36.307 -
36.308 - /* create EpgGridItem */
36.309 - EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
36.310 - epg_grid_item->proginfo = proginfo;
36.311 - epg_grid_item->event_box = event_box;
36.312 - epg_grid_item->object = mmyth_epg_grid_widget;
36.313 -
36.314 - epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);
36.315 -
36.316 - gtk_box_pack_start (GTK_BOX (epg_line_hbox),
36.317 - event_box, FALSE, FALSE, PROGRAM_SEPARATION);
36.318 -
36.319 - g_signal_connect (G_OBJECT (event_box), "button-press-event",
36.320 - G_CALLBACK (mmyth_epg_grid_widget_clicked),
36.321 - (gpointer*) epg_grid_list);
36.322 - }
36.323 -#if 0
36.324 - printf("chaind = %d!!!!" chanid);fflush(stdout);
36.325 -#endif
36.326 -
36.327 - if(!epg_grid_list) {
36.328 - /* No programs for current channel */
36.329 - /* FIXME: size HARDCODED */
36.330 - GtkWidget *event_box = create_event_box_lbl("No program list available",
36.331 - PIXELS_HOUR * 3, &bg_color,
36.332 - &fg_color);
36.333 - gtk_widget_add_events(event_box,
36.334 - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
36.335 -
36.336 - /* create EpgGridItem */
36.337 - EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
36.338 - epg_grid_item->proginfo = NULL;
36.339 - epg_grid_item->event_box = event_box;
36.340 - epg_grid_item->object = mmyth_epg_grid_widget;
36.341 -
36.342 - epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);
36.343 -
36.344 - gtk_box_pack_start (GTK_BOX (epg_line_hbox),
36.345 - event_box, FALSE, FALSE, PROGRAM_SEPARATION);
36.346 -
36.347 - g_signal_connect (G_OBJECT (event_box), "button-press-event",
36.348 - G_CALLBACK (mmyth_epg_grid_widget_clicked),
36.349 - (gpointer*) epg_grid_list);
36.350 - }
36.351 -
36.352 - epg_grid_list = g_list_reverse(epg_grid_list);
36.353 - mmyth_epg_grid_widget->epg_view_model =
36.354 - g_list_append(mmyth_epg_grid_widget->epg_view_model, epg_grid_list);
36.355 -
36.356 - gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
36.357 - epg_line_hbox, FALSE, FALSE, 0);
36.358 - }
36.359 -}
36.360 -
36.361 -static void
36.362 -mmyth_epg_grid_widget_mount_header(MMythEpgGridWidget *mmyth_epg_grid_widget)
36.363 -{
36.364 - MMythEpgGridWidgetPrivate *private =
36.365 - MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
36.366 -
36.367 - struct tm hour_tm;
36.368 - const gchar name_title[] = "Today";
36.369 - GtkWidget * lbl_title = gtk_label_new(name_title);
36.370 -
36.371 - gtk_misc_set_alignment (GTK_MISC(lbl_title), 0.0, 0.5);
36.372 -
36.373 - gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
36.374 - lbl_title, FALSE, FALSE, 0);
36.375 -
36.376 - /* hours title line */
36.377 - GtkWidget *epg_programs_hours_hbox = gtk_hbox_new (TRUE, 0);
36.378 -
36.379 - if (localtime_r((time_t *)&private->current_start_time, &hour_tm) == NULL) {
36.380 - g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
36.381 - return NULL;
36.382 - }
36.383 -
36.384 - if (hour_tm.tm_min>30) {
36.385 - hour_tm.tm_min = 30;
36.386 - } else if (hour_tm.tm_min>0) {
36.387 - hour_tm.tm_min = 0;
36.388 - }
36.389 -
36.390 - gchar hour1_str[10];
36.391 - strftime(hour1_str, 8, "%H:%M", &hour_tm);
36.392 - GtkWidget * lbl_hour1 = gtk_label_new(hour1_str);
36.393 - gtk_misc_set_alignment (GTK_MISC(lbl_hour1), 0.0, 0.5);
36.394 -
36.395 - hour_tm.tm_hour++;
36.396 - gchar hour2_str[10];
36.397 - strftime(hour2_str, 8, "%H:%M", &hour_tm);
36.398 - GtkWidget * lbl_hour2 = gtk_label_new(hour2_str);
36.399 - gtk_misc_set_alignment (GTK_MISC(lbl_hour2), 0.0, 0.5);
36.400 -
36.401 - hour_tm.tm_hour++;
36.402 - gchar hour3_str[10];
36.403 - strftime(hour3_str, 8, "%H:%M", &hour_tm);
36.404 - GtkWidget * lbl_hour3 = gtk_label_new(hour3_str);
36.405 - gtk_misc_set_alignment (GTK_MISC(lbl_hour3), 0.0, 0.5);
36.406 -
36.407 - gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
36.408 - lbl_hour1, TRUE, TRUE, 0);
36.409 - gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
36.410 - lbl_hour2, TRUE, TRUE, 0);
36.411 - gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
36.412 - lbl_hour3, TRUE, TRUE, 0);
36.413 -
36.414 - gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
36.415 - epg_programs_hours_hbox, FALSE, FALSE, 0);
36.416 -}
36.417 -
36.418 -/******************************************************************************
36.419 - * INTERNAL CALLBACKS FOR STATE CHANGE *
36.420 - *****************************************************************************/
36.421 -static void
36.422 -mmyth_epg_grid_widget_deselect_service(MMythEpgGridWidget *mmyth_epg_grid_widget)
36.423 -{
36.424 - EpgGridItem *epg_grid_item;
36.425 -
36.426 - /* deselect*/
36.427 - if(mmyth_epg_grid_widget->selected_grid_item != NULL) {
36.428 - epg_grid_item =
36.429 - (EpgGridItem*) mmyth_epg_grid_widget->selected_grid_item->data;
36.430 - gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_NORMAL);
36.431 - }
36.432 -}
36.433 -
36.434 -static void
36.435 -mmyth_epg_grid_widget_clicked (GtkWidget* widget,
36.436 - GdkEventExpose *event, gpointer data)
36.437 -{
36.438 - g_return_if_fail(data != NULL);
36.439 -
36.440 - GList *epg_grid_item_list = (GList *) data;
36.441 - EpgGridItem *epg_grid_item = (EpgGridItem *) epg_grid_item_list->data;
36.442 -
36.443 - /* update the selected service */
36.444 - mmyth_epg_grid_widget_update_service( epg_grid_item->object, (GList*) data );
36.445 -}
36.446 -
36.447 -void
36.448 -mmyth_epg_grid_widget_update_service(MMythEpgGridWidget * object,
36.449 - GList *selected_grid_list)
36.450 -{
36.451 - g_return_if_fail(object != NULL);
36.452 - g_return_if_fail(selected_grid_list != NULL);
36.453 -
36.454 - EpgGridItem *epg_grid_item = (EpgGridItem *) selected_grid_list->data;
36.455 -
36.456 - mmyth_epg_grid_widget_deselect_service(epg_grid_item->object);
36.457 -
36.458 - /* updating current selected schedule_item and schedule_list*/
36.459 - object->selected_grid_item = selected_grid_list;
36.460 -
36.461 - /* set state of the event box */
36.462 - gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_SELECTED);
36.463 - /* emit update signal for listeners */
36.464 - g_signal_emit(object,
36.465 - mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL],
36.466 - 0,
36.467 - (gpointer) epg_grid_item);
36.468 -}
36.469 -
36.470 -static GtkWidget *
36.471 -create_event_box_lbl(gchar *str, int width, const GdkColor *bg_color,
36.472 - const GdkColor *fg_color)
36.473 -{
36.474 - GtkWidget *event_box = gtk_event_box_new();
36.475 - GtkWidget *lbl = gtk_label_new(str);
36.476 - gtk_label_set_ellipsize(GTK_LABEL(lbl), PANGO_ELLIPSIZE_END);
36.477 -
36.478 - gtk_widget_modify_bg(event_box, GTK_STATE_NORMAL, bg_color);
36.479 - gtk_widget_modify_fg(lbl, GTK_STATE_NORMAL, fg_color);
36.480 -
36.481 - /* selected colors are const*/
36.482 - GdkColor selected_bg_color;
36.483 - selected_bg_color.red = 100;
36.484 - selected_bg_color.green = 40000;
36.485 - selected_bg_color.blue = 100;
36.486 -
36.487 - GdkColor selected_fg_color;
36.488 - selected_fg_color.red = 100;
36.489 - selected_fg_color.green = 100;
36.490 - selected_fg_color.blue = 100;
36.491 -
36.492 - gtk_widget_modify_bg(event_box, GTK_STATE_SELECTED, &selected_bg_color);
36.493 - gtk_widget_modify_fg(lbl, GTK_STATE_SELECTED, &selected_fg_color);
36.494 -
36.495 - gtk_misc_set_alignment (GTK_MISC(lbl), 0.0, 0.5);
36.496 - gtk_container_add (GTK_CONTAINER (event_box),
36.497 - lbl);
36.498 - gtk_widget_set_size_request(event_box, width, -1);
36.499 -
36.500 - return event_box;
36.501 -}
36.502 -
36.503 -/******************************************************************************
36.504 - * METHODS *
36.505 - *****************************************************************************/
36.506 -
36.507 -/* Callback for hardware keys */
36.508 -gboolean
36.509 -mmyth_epg_grid_widget_key_press (MMythEpgGridWidget * object,
36.510 - GtkWidget * widget, GdkEventKey * event)
36.511 -{
36.512 - MMythEpgGridWidgetPrivate *private =
36.513 - MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(object);
36.514 -
36.515 - EpgGridItem *epg_grid_item;
36.516 - GList *tmp;
36.517 -
36.518 - /* List of selected_grid_item */
36.519 - GList *selected_view_model;
36.520 -
36.521 - gint channel_index;
36.522 -
36.523 - if(object->selected_grid_item == NULL) {
36.524 - g_warning ("No program selected");
36.525 - return FALSE;
36.526 - }
36.527 -
36.528 - epg_grid_item = (EpgGridItem*) object->selected_grid_item->data;
36.529 -
36.530 - channel_index = private->selected_channel_index;
36.531 -
36.532 - switch (event->keyval) {
36.533 - case GDK_Up:
36.534 - selected_view_model = g_list_nth( object->epg_view_model, channel_index - 1 );
36.535 - if(selected_view_model != NULL) {
36.536 - private->selected_channel_index = channel_index - 1;
36.537 - tmp = (GList *) selected_view_model->data;
36.538 - /* TODO: select a better centralized item
36.539 - currently is picking the 1st or last item */
36.540 - if(g_list_next(object->selected_grid_item) == NULL &&
36.541 - g_list_previous(object->selected_grid_item) != NULL) {
36.542 - /* in this case the new selected will be the last */
36.543 - tmp = g_list_last(tmp);
36.544 - }
36.545 -
36.546 - /* update the selected service */
36.547 - mmyth_epg_grid_widget_update_service( object, tmp );
36.548 - }
36.549 - return TRUE;
36.550 - case GDK_Down:
36.551 - selected_view_model = g_list_nth( object->epg_view_model, channel_index + 1 );
36.552 - if(selected_view_model != NULL) {
36.553 - private->selected_channel_index = channel_index + 1;
36.554 - tmp = (GList *) selected_view_model->data;
36.555 - /* TODO: select a better centralized item
36.556 - currently is picking the 1st or last item */
36.557 - if(g_list_next(object->selected_grid_item) == NULL &&
36.558 - g_list_previous(object->selected_grid_item) != NULL) {
36.559 - /* in this case the new selected will be the last */
36.560 - tmp = g_list_last(tmp);
36.561 - }
36.562 -
36.563 - /* update the selected service */
36.564 - mmyth_epg_grid_widget_update_service( object, tmp );
36.565 - }
36.566 - return TRUE;
36.567 - case GDK_Left:
36.568 - tmp = g_list_previous( object->selected_grid_item );
36.569 - if(tmp != NULL) {
36.570 - /* update the selected service */
36.571 - mmyth_epg_grid_widget_update_service( object, tmp );
36.572 - }
36.573 - return TRUE;
36.574 - case GDK_Right:
36.575 - tmp = g_list_next( object->selected_grid_item );
36.576 - if(tmp != NULL) {
36.577 - /* update the selected service */
36.578 - mmyth_epg_grid_widget_update_service( object, tmp );
36.579 - }
36.580 - return TRUE;
36.581 - default:
36.582 - return TRUE;
36.583 - }
36.584 -
36.585 - return FALSE;
36.586 -}
36.587 -
36.588 -static void
36.589 -mmyth_epg_grid_widget_fill_programinfos (MMythEpgGridWidgetPrivate *private)
36.590 -{
36.591 - GList *channels_list = NULL;
36.592 - int y;
36.593 -
36.594 - if ((private->mmyth_epg != NULL) &&
36.595 - (gmyth_epg_get_channel_list (private->mmyth_epg, &channels_list) < 0 )) {
36.596 - private->channel_list = NULL;
36.597 - return;
36.598 - }
36.599 -
36.600 - private->channel_list = channels_list;
36.601 -
36.602 - for (y = 0; y < private->DISPLAY_CHANS && channels_list; y++) {
36.603 - GMythChannelInfo *channel_info = (GMythChannelInfo *) channels_list->data;
36.604 -
36.605 - mmyth_epg_grid_widget_fill_program_row_infos(
36.606 - private, channel_info->channel_ID, y);
36.607 -
36.608 - channels_list = g_list_next (channels_list);
36.609 - }
36.610 -}
36.611 -
36.612 -static void
36.613 -mmyth_epg_grid_widget_fill_program_row_infos(MMythEpgGridWidgetPrivate *private,
36.614 - guint chanNum, guint row)
36.615 -{
36.616 - gint res = gmyth_epg_get_program_list (private->mmyth_epg,
36.617 - &(private->program_list[row]),
36.618 - chanNum, private->current_start_time,
36.619 - private->current_end_time);
36.620 -
36.621 - if (res < 0) {
36.622 - g_warning ("[%s] Error while retrieving epg programs", __FUNCTION__);
36.623 - }
36.624 -}
36.625 -
37.1 --- a/gmyth/src/gui/mmyth_epg_grid_widget.h Wed Sep 27 00:08:03 2006 +0100
37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
37.3 @@ -1,74 +0,0 @@
37.4 -#ifndef __MMYTH_EPG_GRID_WIDGET_H__
37.5 -#define __MMYTH_EPG_GRID_WIDGET_H__
37.6 -
37.7 -#include <glib-object.h>
37.8 -#include <gdk/gdk.h>
37.9 -#include <gtk/gtkvbox.h>
37.10 -#include <gtk/gtkeventbox.h>
37.11 -
37.12 -#include "gmyth_common.h"
37.13 -
37.14 -#define MAX_DISPLAY_CHANS 4
37.15 -
37.16 -G_BEGIN_DECLS
37.17 -
37.18 -#define MMYTH_EPG_GRID_WIDGET_TYPE (mmyth_epg_grid_widget_get_type ())
37.19 -#define MMYTH_EPG_GRID_WIDGET(obj) (GTK_CHECK_CAST ((obj), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidget))
37.20 -#define MMYTH_EPG_GRID_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidgetClass))
37.21 -#define IS_MMYTH_EPG_GRID_WIDGET(obj) (GTK_CHECK_TYPE ((obj), MMYTH_EPG_GRID_WIDGET_TYPE))
37.22 -#define IS_MMYTH_EPG_GRID_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), MMYTH_EPG_GRID_WIDGET_TYPE))
37.23 -#define MMYTH_EPG_GRID_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidgetClass))
37.24 -#define MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidgetPrivate))
37.25 -
37.26 -
37.27 -typedef struct _MMythEpgGridWidget MMythEpgGridWidget;
37.28 -typedef struct _MMythEpgGridWidgetClass MMythEpgGridWidgetClass;
37.29 -typedef struct _MMythEpgGridWidgetPrivate MMythEpgGridWidgetPrivate;
37.30 -
37.31 -struct _MMythEpgGridWidgetClass
37.32 -{
37.33 - GtkEventBoxClass parent_class;
37.34 -
37.35 - /* callbacks */
37.36 - /* no one for now */
37.37 -};
37.38 -
37.39 -struct _MMythEpgGridWidget
37.40 -{
37.41 - GtkEventBox event_box;
37.42 -
37.43 - /* Selected Widgets Logic*/
37.44 - /* List os Service Model in the current view
37.45 - * the data of this list are GList for the programs
37.46 - * of each service */
37.47 - GList *epg_view_model;
37.48 -
37.49 - /* Selected Schedule Item*/
37.50 - GList *selected_grid_item;
37.51 -};
37.52 -
37.53 -
37.54 -GType mmyth_epg_grid_widget_get_type (void);
37.55 -GtkWidget* mmyth_epg_grid_widget_new (void);
37.56 -/*DVBHScheduleEvent* mmyth_epg_grid_get_selected_schedule (MMythEpgGridWidget * object);*/
37.57 -void mmyth_epg_grid_widget_update_service (MMythEpgGridWidget * object,
37.58 - GList *epg_grid_item_node);
37.59 -gboolean mmyth_epg_grid_widget_key_press (MMythEpgGridWidget * object,
37.60 - GtkWidget * widget,
37.61 - GdkEventKey * event);
37.62 -
37.63 -typedef struct _EpgGridItem EpgGridItem;
37.64 -
37.65 -/* FIXME: auxiliary struct */
37.66 -struct _EpgGridItem {
37.67 -
37.68 - GMythProgramInfo *proginfo;
37.69 - GtkWidget *event_box;
37.70 -
37.71 - /* for callback purposes */
37.72 - MMythEpgGridWidget *object;
37.73 -};
37.74 -
37.75 -G_END_DECLS
37.76 -
37.77 -#endif /* __MMYTH_EPG_GRID_WIDGET_H__ */
38.1 --- a/gmyth/src/gui/mmyth_recordui.c Wed Sep 27 00:08:03 2006 +0100
38.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
38.3 @@ -1,332 +0,0 @@
38.4 -#include<gtk/gtk.h>
38.5 -#include<glib.h>
38.6 -#include <sys/types.h>
38.7 -#include <sys/stat.h>
38.8 -#include <unistd.h>
38.9 -#include <string.h>
38.10 -#include <stdio.h>
38.11 -#include <stdlib.h>
38.12 -
38.13 -#include "mmyth_ui.h"
38.14 -#include "mmyth_recordui.h"
38.15 -
38.16 -/* GMyth library includes */
38.17 -#include "gmyth_scheduler.h"
38.18 -#include "gmyth_util.h"
38.19 -
38.20 -enum {
38.21 - START_DATE_COLUMN = 0,
38.22 - TITLE_COLUMN,
38.23 - CHAN_ID_COLUMN,
38.24 - END_TIME_COLUMN,
38.25 - RECORD_ID_COLUMN,
38.26 - BASENAME_COLUMN,
38.27 - N_COLUMNS
38.28 -};
38.29 -
38.30 -gboolean
38.31 -mmyth_recordui_reload_all (MMythRecordUI *recordui)
38.32 -{
38.33 - gboolean res = FALSE;
38.34 -
38.35 - res = mmyth_recordui_reload_schedule (recordui);
38.36 -
38.37 - res = res & mmyth_recordui_reload_record (recordui);
38.38 -
38.39 -
38.40 - if (!res)
38.41 - g_warning ("[%s] Error while reloading schedule and recording content", __FUNCTION__);
38.42 -
38.43 - return res;
38.44 -}
38.45 -
38.46 -gboolean
38.47 -mmyth_recordui_reload_schedule (MMythRecordUI *recordui)
38.48 -{
38.49 - gint new_row = 0;
38.50 - ScheduleInfo *schedule_info;
38.51 - GList *schedule_list;
38.52 - GtkTreeIter iter;
38.53 - GString *start_date_time = NULL;
38.54 - GString *end_date_time = NULL;
38.55 - GString *str_aux = g_string_new("");
38.56 - gint res;
38.57 -
38.58 - gtk_tree_store_clear(recordui->sch_tree_store);
38.59 -
38.60 - res = gmyth_scheduler_get_schedule_list(recordui->scheduler, &(schedule_list));
38.61 - if (res < 0) {
38.62 - g_warning ("[%s] Retrieved NULL list of scheduled data from database",
38.63 - __FUNCTION__);
38.64 - return FALSE;
38.65 - }
38.66 -
38.67 - for ( ; schedule_list; schedule_list = schedule_list->next) {
38.68 - schedule_info = (ScheduleInfo*) schedule_list->data;
38.69 -
38.70 - gtk_tree_store_insert(recordui->sch_tree_store, &iter, NULL, new_row++);
38.71 -
38.72 - start_date_time = gmyth_util_time_to_string(schedule_info->start_time);
38.73 - end_date_time = gmyth_util_time_to_string(schedule_info->end_time);
38.74 -
38.75 - g_string_printf(str_aux, "%d", schedule_info->channel_id);
38.76 -
38.77 - gtk_tree_store_set(recordui->sch_tree_store, &iter,
38.78 - START_DATE_COLUMN, start_date_time->str,
38.79 - TITLE_COLUMN, schedule_info->title->str,
38.80 - CHAN_ID_COLUMN, str_aux->str,
38.81 - END_TIME_COLUMN, end_date_time->str, //It doesn't appear
38.82 - RECORD_ID_COLUMN, schedule_info->record_id,
38.83 - -1); //the last line is a hidden item to be used in searching tasks
38.84 - }
38.85 -
38.86 - g_debug ("[%s] %d lines added to schedule list UI", __FUNCTION__, new_row);
38.87 -
38.88 - /* free allocated memory */
38.89 - if(!start_date_time)
38.90 - g_string_free(start_date_time, FALSE);
38.91 - if(!end_date_time)
38.92 - g_string_free(end_date_time, FALSE);
38.93 - g_string_free(str_aux, FALSE);
38.94 -
38.95 - return TRUE;
38.96 -}
38.97 -
38.98 -gboolean
38.99 -mmyth_recordui_reload_record (MMythRecordUI *recordui)
38.100 -{
38.101 - gint new_row = 0;
38.102 - RecordedInfo *recorded_info;
38.103 - GList *record_list = NULL;
38.104 - GtkTreeIter iter;
38.105 - GString *start_date_time = NULL;
38.106 - GString *end_date_time = NULL;
38.107 - GString *str_aux = g_string_new("");
38.108 - gint res;
38.109 -
38.110 - gtk_tree_store_clear(recordui->rec_tree_store);
38.111 -
38.112 - res = gmyth_scheduler_get_recorded_list(recordui->scheduler, &record_list);
38.113 - if (res < 0) {
38.114 - g_warning ("[%s] Retrieved NULL list of recorded data from database", __FUNCTION__);
38.115 - return FALSE;
38.116 - }
38.117 -
38.118 - for (; record_list; record_list = record_list->next) {
38.119 - recorded_info = (RecordedInfo*) record_list->data;
38.120 -
38.121 - gtk_tree_store_insert(recordui->rec_tree_store, &iter, NULL, new_row++);
38.122 -
38.123 - start_date_time = gmyth_util_time_to_string(recorded_info->start_time);
38.124 - end_date_time = gmyth_util_time_to_string(recorded_info->end_time);
38.125 -
38.126 - g_string_printf(str_aux, "%d", recorded_info->channel_id);
38.127 -
38.128 - gtk_tree_store_set(recordui->rec_tree_store, &iter,
38.129 - START_DATE_COLUMN, start_date_time->str,
38.130 - TITLE_COLUMN, recorded_info->title->str,
38.131 - CHAN_ID_COLUMN, str_aux->str,
38.132 - END_TIME_COLUMN, end_date_time->str, //It doesn't appear
38.133 - RECORD_ID_COLUMN, recorded_info->record_id,
38.134 - BASENAME_COLUMN, recorded_info->basename->str, -1);
38.135 - //the last line is a hidden item to be used in searching tasks
38.136 - }
38.137 -
38.138 - g_debug ("[%s] %d lines added to record list UI", __FUNCTION__, new_row);
38.139 -
38.140 - return TRUE;
38.141 -}
38.142 -
38.143 -
38.144 -MMythRecordUI*
38.145 -mmyth_recordui_new(void)
38.146 -{
38.147 - MMythRecordUI *recordui = g_new0 (MMythRecordUI, 1);
38.148 -
38.149 - recordui->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
38.150 - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (recordui->scrolled_window),
38.151 - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
38.152 -
38.153 - recordui->viewport = gtk_viewport_new (NULL, NULL);
38.154 - gtk_container_add (GTK_CONTAINER (recordui->scrolled_window), recordui->viewport);
38.155 -
38.156 - recordui->notebook = gtk_notebook_new ();
38.157 - gtk_container_set_border_width (GTK_CONTAINER (recordui->notebook), 1);
38.158 - gtk_notebook_set_scrollable (GTK_NOTEBOOK (recordui->notebook), TRUE);
38.159 - gtk_notebook_popup_enable (GTK_NOTEBOOK (recordui->notebook));
38.160 - gtk_container_add (GTK_CONTAINER (recordui->viewport), recordui->notebook);
38.161 - gtk_notebook_popup_disable(GTK_NOTEBOOK (recordui->notebook));
38.162 -
38.163 - /* Schedule tab */
38.164 - recordui->sch_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
38.165 - gtk_container_add (GTK_CONTAINER (recordui->notebook), recordui->sch_scrolled_window);
38.166 - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (recordui->sch_scrolled_window),
38.167 - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
38.168 - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (recordui->sch_scrolled_window),
38.169 - GTK_SHADOW_IN);
38.170 -
38.171 - /* The basename column in the sched_tree_store is not being used*/
38.172 - recordui->sch_tree_store =
38.173 - gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
38.174 - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING );
38.175 -
38.176 - recordui->sch_treeview =
38.177 - gtk_tree_view_new_with_model(GTK_TREE_MODEL(recordui->sch_tree_store));
38.178 - gtk_container_add (GTK_CONTAINER (recordui->sch_scrolled_window),
38.179 - recordui->sch_treeview);
38.180 - recordui->sch_renderer = gtk_cell_renderer_text_new();
38.181 - //g_object_set(G_OBJECT(renderer1), "foreground", "green", "background", "black", NULL);
38.182 - recordui->sch_column1 =
38.183 - gtk_tree_view_column_new_with_attributes("Start time", recordui->sch_renderer,
38.184 - "text", START_DATE_COLUMN, NULL);
38.185 - gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview),
38.186 - recordui->sch_column1);
38.187 - recordui->sch_column2 =
38.188 - gtk_tree_view_column_new_with_attributes("Title", recordui->sch_renderer,
38.189 - "text", TITLE_COLUMN, NULL);
38.190 - gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview),
38.191 - recordui->sch_column2);
38.192 - recordui->sch_column3 =
38.193 - gtk_tree_view_column_new_with_attributes("Channel", recordui->sch_renderer,
38.194 - "text", CHAN_ID_COLUMN, NULL);
38.195 - gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview),
38.196 - recordui->sch_column3);
38.197 - gtk_tree_view_column_set_resizable(recordui->sch_column1, TRUE);
38.198 - gtk_tree_view_column_set_resizable(recordui->sch_column2, TRUE);
38.199 - gtk_tree_view_column_set_resizable(recordui->sch_column3, TRUE);
38.200 - gtk_tree_view_column_set_reorderable(recordui->sch_column1, TRUE);
38.201 - gtk_tree_view_column_set_reorderable(recordui->sch_column2, TRUE);
38.202 - gtk_tree_view_column_set_reorderable(recordui->sch_column3, TRUE);
38.203 -// recordui->sch_column4 =
38.204 -// gtk_tree_view_column_new_with_attributes("", recordui->sch_renderer, "text", END_TIME_COLUMN, NULL);
38.205 -// gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview),
38.206 -// recordui->sch_column4);
38.207 -
38.208 - recordui->sch_label = gtk_label_new (("Schedule"));
38.209 - gtk_notebook_set_tab_label (GTK_NOTEBOOK (recordui->notebook),
38.210 - gtk_notebook_get_nth_page (
38.211 - GTK_NOTEBOOK (recordui->notebook), 0),
38.212 - recordui->sch_label);
38.213 -
38.214 - // Record items tab
38.215 - // g_object_set(G_OBJECT(renderer2), "foreground", "blue", NULL);
38.216 - recordui->rec_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
38.217 - gtk_container_add (GTK_CONTAINER (recordui->notebook),
38.218 - recordui->rec_scrolled_window);
38.219 - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (recordui->rec_scrolled_window),
38.220 - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
38.221 - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (recordui->rec_scrolled_window),
38.222 - GTK_SHADOW_IN);
38.223 -
38.224 - recordui->rec_tree_store =
38.225 - gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
38.226 - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
38.227 - recordui->rec_treeview =
38.228 - gtk_tree_view_new_with_model(GTK_TREE_MODEL(recordui->rec_tree_store));
38.229 - gtk_container_add (GTK_CONTAINER (recordui->rec_scrolled_window),
38.230 - recordui->rec_treeview);
38.231 - recordui->rec_renderer = gtk_cell_renderer_text_new();
38.232 - //g_object_set(G_OBJECT(renderer1), "foreground", "green", "background", "black", NULL);
38.233 -
38.234 - recordui->rec_column1 =
38.235 - gtk_tree_view_column_new_with_attributes("Start time", recordui->rec_renderer,
38.236 - "text", START_DATE_COLUMN, NULL);
38.237 - gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview),
38.238 - recordui->rec_column1);
38.239 - recordui->rec_column2 =
38.240 - gtk_tree_view_column_new_with_attributes("Title", recordui->rec_renderer,
38.241 - "text", TITLE_COLUMN, NULL);
38.242 - gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview),
38.243 - recordui->rec_column2);
38.244 - recordui->rec_column3 =
38.245 - gtk_tree_view_column_new_with_attributes("Channel", recordui->rec_renderer,
38.246 - "text", CHAN_ID_COLUMN, NULL);
38.247 - gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview),
38.248 - recordui->rec_column3);
38.249 - gtk_tree_view_column_set_resizable(recordui->rec_column1, TRUE);
38.250 - gtk_tree_view_column_set_resizable(recordui->rec_column2, TRUE);
38.251 - gtk_tree_view_column_set_resizable(recordui->rec_column3, TRUE);
38.252 - gtk_tree_view_column_set_reorderable(recordui->rec_column1, TRUE);
38.253 - gtk_tree_view_column_set_reorderable(recordui->rec_column2, TRUE);
38.254 - gtk_tree_view_column_set_reorderable(recordui->rec_column3, TRUE);
38.255 -// recordui->rec_column4 = gtk_tree_view_column_new_with_attributes("", recordui->rec_renderer, "text", END_TIME_COLUMN, NULL);
38.256 -// gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview), recordui->rec_column4);
38.257 -
38.258 - recordui->rec_label = gtk_label_new (("Recorded"));
38.259 - gtk_notebook_set_tab_label (GTK_NOTEBOOK (recordui->notebook),
38.260 - gtk_notebook_get_nth_page (
38.261 - GTK_NOTEBOOK (recordui->notebook), 1),
38.262 - recordui->rec_label);
38.263 -
38.264 - // Gets the mmyth scheduler manager
38.265 - recordui->scheduler = gmyth_scheduler_new ();
38.266 -
38.267 - /* init connection to the backend */
38.268 - gmyth_scheduler_connect (recordui->scheduler);
38.269 -
38.270 - return recordui;
38.271 -}
38.272 -
38.273 -void
38.274 -mmyth_recordui_free (MMythRecordUI *recordui)
38.275 -{
38.276 - // FIXME: Release memory here!
38.277 - /* close connection to the backend */
38.278 - gmyth_scheduler_disconnect (recordui->scheduler);
38.279 -}
38.280 -
38.281 -void
38.282 -mmyth_recordui_delete_selected (GtkButton *button, MMythRecordUI *recordui)
38.283 -{
38.284 - GtkTreeSelection *selection;
38.285 - GtkTreeModel *list_store;
38.286 - GtkTreeIter iter;
38.287 - int index;
38.288 - int curr_page = 0;
38.289 -
38.290 - curr_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(recordui->notebook));
38.291 -
38.292 - if ( curr_page == 0) {
38.293 - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(recordui->sch_treeview));
38.294 - if (selection != NULL) {
38.295 - gtk_tree_selection_get_selected(selection, &list_store, &iter);
38.296 - gtk_tree_model_get(list_store, &iter, RECORD_ID_COLUMN, &index, -1);
38.297 - gmyth_scheduler_delete_schedule(recordui->scheduler, index);
38.298 - mmyth_recordui_reload_schedule (recordui);
38.299 - return;
38.300 - }
38.301 -
38.302 - } else if (curr_page == 1) {
38.303 - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(recordui->rec_treeview));
38.304 - if (selection != NULL) {
38.305 - gtk_tree_selection_get_selected(selection, &list_store, &iter);
38.306 - gtk_tree_model_get(list_store, &iter, RECORD_ID_COLUMN, &index, -1);
38.307 - gmyth_scheduler_delete_recorded(recordui->scheduler, index);
38.308 - mmyth_recordui_reload_record (recordui);
38.309 - return;
38.310 - }
38.311 - }
38.312 -
38.313 - g_warning ("[%s] None element was removed from the list", __FUNCTION__);
38.314 -}
38.315 -
38.316 -/* FIXME: change this function name, it is returning the
38.317 - * basename_column that represents the nuv filename of
38.318 - * the recorded content */
38.319 -gchar*
38.320 -mmyth_recordui_get_selected_recorded (MMythRecordUI *recordui)
38.321 -{
38.322 - GtkTreeSelection *selection = NULL;
38.323 - GtkTreeModel *list_store = NULL;
38.324 - GtkTreeIter iter;
38.325 - gchar *path = NULL;
38.326 -
38.327 - /* returning nuv filename, basename_column */
38.328 - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(recordui->rec_treeview));
38.329 - if (gtk_tree_selection_get_selected (selection, &list_store, &iter)) {
38.330 - gtk_tree_model_get(list_store, &iter, BASENAME_COLUMN, &path, -1);
38.331 - }
38.332 -
38.333 - // FIXME: MOVE THIS TO OTHER PLACE
38.334 - return path;
38.335 -}
39.1 --- a/gmyth/src/gui/mmyth_recordui.h Wed Sep 27 00:08:03 2006 +0100
39.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
39.3 @@ -1,48 +0,0 @@
39.4 -#ifndef MMYTH_RECORD_H_
39.5 -#define MMYTH_RECORD_H_
39.6 -
39.7 -#include "gmyth_scheduler.h"
39.8 -
39.9 -typedef struct _MMythRecordUI
39.10 -{
39.11 - GtkWidget *scrolled_window;
39.12 - GtkWidget *viewport;
39.13 - GtkWidget *notebook;
39.14 -
39.15 - GtkWidget *rec_scrolled_window;
39.16 - GtkWidget *sch_scrolled_window;
39.17 - GtkWidget *rec_treeview;
39.18 - GtkWidget *sch_treeview;
39.19 - GtkWidget *rec_label;
39.20 - GtkWidget *sch_label;
39.21 -
39.22 - GtkTreeViewColumn *rec_column1;
39.23 - GtkTreeViewColumn *rec_column2;
39.24 - GtkTreeViewColumn *rec_column3;
39.25 - GtkTreeViewColumn *rec_column4;
39.26 - GtkTreeViewColumn *sch_column1;
39.27 - GtkTreeViewColumn *sch_column2;
39.28 - GtkTreeViewColumn *sch_column3;
39.29 - GtkTreeViewColumn *sch_column4;
39.30 -
39.31 - GtkCellRenderer *rec_renderer;
39.32 - GtkCellRenderer *sch_renderer;
39.33 -
39.34 - GtkTreeStore *sch_tree_store;
39.35 - GtkTreeStore *rec_tree_store;
39.36 -
39.37 - GMythScheduler *scheduler;
39.38 -
39.39 -} MMythRecordUI;
39.40 -
39.41 -MMythRecordUI* mmyth_recordui_new(void);
39.42 -void mmyth_recordui_free (MMythRecordUI *recordui);
39.43 -
39.44 -void mmyth_recordui_delete_selected (GtkButton *button, MMythRecordUI *recordui);
39.45 -gboolean mmyth_recordui_reload_all (MMythRecordUI *recordui);
39.46 -gboolean mmyth_recordui_reload_schedule (MMythRecordUI *recordui);
39.47 -gboolean mmyth_recordui_reload_record (MMythRecordUI *recordui);
39.48 -
39.49 -gchar* mmyth_recordui_get_selected_recorded (MMythRecordUI *recordui);
39.50 -
39.51 -#endif /*MMYTH_RECORD_H_*/
40.1 --- a/gmyth/src/gui/mmyth_schedulerui.c Wed Sep 27 00:08:03 2006 +0100
40.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
40.3 @@ -1,368 +0,0 @@
40.4 -#include <gtk/gtk.h>
40.5 -#include <glib.h>
40.6 -#include <glib/gprintf.h>
40.7 -#include <sys/types.h>
40.8 -#include <sys/stat.h>
40.9 -#include <unistd.h>
40.10 -#include <string.h>
40.11 -#include <stdio.h>
40.12 -
40.13 -#include "mmyth_ui.h"
40.14 -#include "mmyth_uicommon.h"
40.15 -#include "mmyth_recordui.h"
40.16 -#include "mmyth_schedulerui.h"
40.17 -
40.18 -/* GMyth library includes */
40.19 -#include "gmyth_scheduler.h"
40.20 -#include "gmyth_common.h"
40.21 -#include "gmyth_epg.h"
40.22 -
40.23 -static void run_calendar_dialog (GtkButton *button, gpointer data);
40.24 -
40.25 -static void add_channel_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
40.26 -static void add_time_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
40.27 -static void add_date_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
40.28 -static void add_duration_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
40.29 -static void add_frequency_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
40.30 -static void add_title_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
40.31 -
40.32 -MMythSchedulerUI*
40.33 -mmyth_schedulerui_new (void)
40.34 -{
40.35 - GtkWidget *scrolledwindow;
40.36 - GtkWidget *viewport;
40.37 - GtkWidget *head_hbox;
40.38 - GtkWidget *fields_vbox;
40.39 - GtkWidget *hseparator;
40.40 - GtkWidget *label;
40.41 -
40.42 - MMythSchedulerUI *scheduler_ui = g_new0 (MMythSchedulerUI, 1);
40.43 -
40.44 - scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
40.45 - scheduler_ui->main_widget = scrolledwindow;
40.46 - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
40.47 - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
40.48 -
40.49 - //Is this needed?
40.50 - viewport = gtk_viewport_new (NULL, NULL);
40.51 - gtk_container_add (GTK_CONTAINER (scrolledwindow), viewport);
40.52 -
40.53 - //Is this needed?
40.54 - head_hbox = gtk_hbox_new (FALSE, 0);
40.55 - gtk_container_add (GTK_CONTAINER (viewport), head_hbox);
40.56 -
40.57 - fields_vbox = gtk_vbox_new (FALSE, 0);
40.58 - gtk_box_pack_start (GTK_BOX (head_hbox), fields_vbox, TRUE, TRUE, 0);
40.59 - gtk_container_set_border_width (GTK_CONTAINER (fields_vbox), 10);
40.60 -
40.61 - label = gtk_label_new_with_mnemonic (("Manual Schedule Recording"));
40.62 - gtk_box_pack_start (GTK_BOX (fields_vbox), label, FALSE, FALSE, 0);
40.63 - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
40.64 -
40.65 - hseparator = gtk_hseparator_new ();
40.66 - gtk_box_pack_start (GTK_BOX (fields_vbox), hseparator, FALSE, TRUE, 0);
40.67 -
40.68 - add_channel_field (scheduler_ui, fields_vbox);
40.69 - add_time_field (scheduler_ui, fields_vbox);
40.70 - add_date_field (scheduler_ui, fields_vbox);
40.71 - add_duration_field (scheduler_ui, fields_vbox);
40.72 - add_frequency_field (scheduler_ui, fields_vbox);
40.73 - add_title_field (scheduler_ui, fields_vbox);
40.74 -
40.75 - return scheduler_ui;
40.76 -}
40.77 -
40.78 -static void
40.79 -set_date_from_calendar (GtkCalendar *calendar, gpointer data)
40.80 -{
40.81 - char sched_date[24];
40.82 -
40.83 - MMythSchedulerUI *scheduler_ui = (MMythSchedulerUI*) data;
40.84 -
40.85 - // FIXME: Change this, save another value instead of month_temp, day_temp, ...
40.86 - gtk_calendar_get_date(GTK_CALENDAR(calendar),
40.87 - &(scheduler_ui->year_temp), &(scheduler_ui->month_temp), &(scheduler_ui->day_temp));
40.88 -
40.89 - sched_date[23]='\0';
40.90 - g_sprintf(sched_date, "%04d %02d %02d (yyyy mm dd)",
40.91 - scheduler_ui->year_temp, scheduler_ui->month_temp+1, scheduler_ui->day_temp);
40.92 -
40.93 - gtk_button_set_label(GTK_BUTTON(scheduler_ui->date_button), sched_date);
40.94 -
40.95 - gtk_widget_destroy(scheduler_ui->calendar_dialog);
40.96 - scheduler_ui->calendar_dialog = NULL;
40.97 - scheduler_ui->calendar = NULL;
40.98 -}
40.99 -
40.100 -//calendar
40.101 -static void
40.102 -run_calendar_dialog (GtkButton *button, gpointer data)
40.103 -{
40.104 -
40.105 - GtkWidget *dialog_vbox;
40.106 - MMythSchedulerUI *scheduler_ui = (MMythSchedulerUI*) data;
40.107 -
40.108 - // calendar_dialog and calendar are been released at set_date_from_calendar ()
40.109 - scheduler_ui->calendar_dialog = gtk_dialog_new ();
40.110 - gtk_container_set_border_width (GTK_CONTAINER (scheduler_ui->calendar_dialog), 1);
40.111 - gtk_window_set_title (GTK_WINDOW (scheduler_ui->calendar_dialog), "Select starting date");
40.112 - gtk_window_set_position (GTK_WINDOW (scheduler_ui->calendar_dialog), GTK_WIN_POS_CENTER);
40.113 - gtk_window_set_decorated (GTK_WINDOW (scheduler_ui->calendar_dialog), FALSE);
40.114 -
40.115 - dialog_vbox = GTK_DIALOG (scheduler_ui->calendar_dialog)->vbox;
40.116 -
40.117 - scheduler_ui->calendar = gtk_calendar_new ();
40.118 -
40.119 - gtk_box_pack_start (GTK_BOX (dialog_vbox), scheduler_ui->calendar, TRUE, TRUE, 0);
40.120 - gtk_calendar_display_options (GTK_CALENDAR (scheduler_ui->calendar),
40.121 - GTK_CALENDAR_SHOW_HEADING | GTK_CALENDAR_SHOW_DAY_NAMES);
40.122 -
40.123 - gtk_widget_show_all (scheduler_ui->calendar_dialog);
40.124 -
40.125 - g_signal_connect (G_OBJECT (scheduler_ui->calendar), "day-selected-double-click",
40.126 - G_CALLBACK (set_date_from_calendar), data);
40.127 -}
40.128 -
40.129 -
40.130 -gboolean
40.131 -mmyth_schedulerui_save (MMythSchedulerUI *scheduler_ui)
40.132 -{
40.133 - GMythScheduler *scheduler;
40.134 - ScheduleInfo *schedule_info;
40.135 - GMythChannelInfo *channel_info;
40.136 -
40.137 - GList *clist;
40.138 - gint index, duration;
40.139 - gint frequency;
40.140 - struct tm start_tm;
40.141 -
40.142 - schedule_info = g_new0(ScheduleInfo, 1);
40.143 - if(schedule_info == NULL) {
40.144 - g_warning ("Error allocating memory");
40.145 - return FALSE;
40.146 - }
40.147 -
40.148 - clist = scheduler_ui->channel_list;
40.149 -
40.150 - index = gtk_combo_box_get_active(GTK_COMBO_BOX(scheduler_ui->channel_combobox));
40.151 -
40.152 - if (clist != NULL)
40.153 - clist = g_list_nth(clist, index);
40.154 -
40.155 - if (clist) {
40.156 - g_debug ("[%s] New schedule: %d", __FUNCTION__, index);
40.157 - } else {
40.158 - g_warning ("[%s] Error when adding new schedule", __FUNCTION__);
40.159 - return FALSE;
40.160 - }
40.161 -
40.162 - channel_info = clist->data;
40.163 -
40.164 - /* initialize schedule_info */
40.165 - schedule_info->channel_id = channel_info->channel_ID;
40.166 -
40.167 - start_tm.tm_hour =
40.168 - (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(scheduler_ui->hour_spinbutton));
40.169 - start_tm.tm_min =
40.170 - (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(scheduler_ui->min_spinbutton));
40.171 - start_tm.tm_sec = 0;
40.172 -
40.173 - start_tm.tm_mday = (gint)scheduler_ui->day_temp;
40.174 - start_tm.tm_mon = (gint)scheduler_ui->month_temp;
40.175 - start_tm.tm_year = (gint)scheduler_ui->year_temp - 1900; //years since 1900
40.176 -
40.177 - schedule_info->start_time = timelocal(&start_tm);
40.178 - if (schedule_info->start_time == (time_t)(-1)) {
40.179 - g_warning ("timelocal error!\n");
40.180 - return FALSE;
40.181 - }
40.182 -
40.183 - duration = (gint) gtk_spin_button_get_value(
40.184 - GTK_SPIN_BUTTON(scheduler_ui->duration_spinbutton));
40.185 - schedule_info->end_time = schedule_info->start_time + (duration*60);
40.186 -
40.187 - /* TODO: frequency is not implemented yet */
40.188 - frequency = gtk_combo_box_get_active(GTK_COMBO_BOX(scheduler_ui->freq_combobox));
40.189 -
40.190 - schedule_info->title = g_string_new("");
40.191 - g_string_printf(schedule_info->title, "%s",
40.192 - gtk_entry_get_text(GTK_ENTRY(scheduler_ui->title_entry)));
40.193 -
40.194 - /* FIXME: Architecture change to reuse the scheduler created in the recordui! */
40.195 - scheduler = gmyth_scheduler_new ();
40.196 -
40.197 - gmyth_scheduler_connect(scheduler);
40.198 -
40.199 - /* FIXME: set record_id = -1 to add a new schedule */
40.200 - schedule_info->record_id = -1;
40.201 - gmyth_scheduler_add_schedule (scheduler, schedule_info);
40.202 -
40.203 - gmyth_scheduler_disconnect(scheduler);
40.204 -
40.205 - /* free allocated memory */
40.206 - g_object_unref (scheduler);
40.207 - g_free (schedule_info);
40.208 -
40.209 - return TRUE;
40.210 -}
40.211 -
40.212 -static GtkWidget*
40.213 -add_line (GtkWidget *vbox, const gchar *str)
40.214 -{
40.215 - GtkWidget *label;
40.216 - GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
40.217 -
40.218 - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
40.219 - gtk_container_set_border_width (GTK_CONTAINER (hbox), 3);
40.220 -
40.221 - label = gtk_label_new (str);
40.222 - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
40.223 - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
40.224 -
40.225 - return hbox;
40.226 -}
40.227 -
40.228 -static void
40.229 -add_channel_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
40.230 -{
40.231 - GtkWidget *combobox;
40.232 -
40.233 - GtkWidget *hbox = add_line (vbox, "Channel: ");
40.234 -
40.235 - combobox = gtk_combo_box_new_text ();
40.236 -
40.237 - scheduler_ui->channel_combobox = combobox;
40.238 - gtk_box_pack_start (GTK_BOX (hbox), combobox, FALSE, FALSE, 0);
40.239 -
40.240 - GMythEPG *mmyth_epg = gmyth_epg_new ();
40.241 - if (!gmyth_epg_connect (mmyth_epg)) {
40.242 - // FIXME: Without this list the scheduler UI should not be shown!
40.243 - g_warning ("[%s] Error when getting list of channels", __FUNCTION__);
40.244 - }
40.245 -
40.246 - if (gmyth_epg_get_channel_list (mmyth_epg, &(scheduler_ui->channel_list)) < 0) {
40.247 - g_debug ("[%s] Error while trying to retrieve channel list", __FUNCTION__);
40.248 - } else {
40.249 - GList *clist = scheduler_ui->channel_list;
40.250 - GMythChannelInfo *channel_info;
40.251 -
40.252 - while (clist != NULL) {
40.253 - channel_info = clist->data;
40.254 - clist = clist->next;
40.255 - gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->channel_combobox),
40.256 - (channel_info->channel_name->str));
40.257 - }
40.258 -
40.259 - gtk_combo_box_set_active(GTK_COMBO_BOX (scheduler_ui->channel_combobox), 0);
40.260 - }
40.261 -}
40.262 -
40.263 -static void
40.264 -add_time_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
40.265 -{
40.266 - GtkWidget *label;
40.267 - GtkObject *spinbutton_adj;
40.268 - GtkWidget *hbox = add_line (vbox, "Time: ");
40.269 -
40.270 - time_t real_time;
40.271 - struct tm sched_time;
40.272 -
40.273 - time(&real_time);
40.274 -
40.275 - if (localtime_r((time_t *)&real_time, &sched_time) == NULL) {
40.276 - g_warning ("localtime_r error in mmyth_epg_grid_view!\n");
40.277 - return NULL;
40.278 - }
40.279 -
40.280 - if (sched_time.tm_min>30){
40.281 - sched_time.tm_hour = sched_time.tm_hour+1;
40.282 - sched_time.tm_min = 0;
40.283 - } else if (sched_time.tm_min>0) {
40.284 - sched_time.tm_min = 30;
40.285 - }
40.286 -
40.287 - scheduler_ui->year_temp = (guint)sched_time.tm_year + 1900;
40.288 - scheduler_ui->month_temp = (guint)sched_time.tm_mon;
40.289 - scheduler_ui->day_temp = (guint)sched_time.tm_mday;
40.290 -
40.291 - //hour entry
40.292 - spinbutton_adj = gtk_adjustment_new (sched_time.tm_hour, 00, 23, 1, 10, 10);
40.293 - scheduler_ui->hour_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adj), 1, 0);
40.294 - gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->hour_spinbutton, FALSE, FALSE, 0);
40.295 -
40.296 - label = gtk_label_new ((" : "));
40.297 - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
40.298 - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
40.299 - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
40.300 -
40.301 - //minute entry
40.302 - spinbutton_adj = gtk_adjustment_new (sched_time.tm_min, 0, 59, 1, 10, 10);
40.303 - scheduler_ui->min_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adj), 1, 0);
40.304 - gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->min_spinbutton, FALSE, FALSE, 0);
40.305 -
40.306 - label = gtk_label_new ((" (hh:mm)"));
40.307 -
40.308 - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
40.309 -
40.310 -}
40.311 -
40.312 -static void
40.313 -add_date_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
40.314 -{
40.315 - char sched_date[24];
40.316 - GtkWidget *hbox = add_line (vbox, "Date: ");
40.317 -
40.318 - //sched_date = ctime(&real_time);
40.319 - g_sprintf (sched_date, "%04d %02d %02d (yyyy mm dd)", scheduler_ui->year_temp, scheduler_ui->month_temp+1, scheduler_ui->day_temp);
40.320 - sched_date[23]='\0';
40.321 -
40.322 - scheduler_ui->date_button = gtk_button_new_with_label (sched_date);
40.323 - gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->date_button, FALSE, FALSE, 0);
40.324 - gtk_button_set_relief (GTK_BUTTON (scheduler_ui->date_button), GTK_RELIEF_NONE);
40.325 -
40.326 - g_signal_connect (G_OBJECT (scheduler_ui->date_button), "clicked",
40.327 - G_CALLBACK (run_calendar_dialog), scheduler_ui);
40.328 -
40.329 -}
40.330 -
40.331 -static void
40.332 -add_duration_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
40.333 -{
40.334 - GtkWidget *hbox = add_line (vbox, "Duration: ");
40.335 - GtkWidget *label;
40.336 - GtkObject *spinbutton_adj;
40.337 -
40.338 - spinbutton_adj = gtk_adjustment_new (60, 5, 360, 5, 60, 60);
40.339 - scheduler_ui->duration_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adj), 1, 0);
40.340 - gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->duration_spinbutton, FALSE, TRUE, 0);
40.341 - gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (scheduler_ui->duration_spinbutton), TRUE);
40.342 -
40.343 - label = gtk_label_new ((" (minutes) "));
40.344 - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
40.345 -}
40.346 -
40.347 -static void
40.348 -add_frequency_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
40.349 -{
40.350 -
40.351 - GtkWidget *hbox = add_line (vbox, "Frequency: ");
40.352 -
40.353 - scheduler_ui->freq_combobox = gtk_combo_box_new_text ();
40.354 - gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->freq_combobox, FALSE, FALSE, 0);
40.355 - gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->freq_combobox), ("Only this day "));
40.356 - gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->freq_combobox), ("Daily "));
40.357 - gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->freq_combobox), ("Weekly "));
40.358 - gtk_combo_box_set_active(GTK_COMBO_BOX (scheduler_ui->freq_combobox), 0);
40.359 -
40.360 -}
40.361 -
40.362 -static void
40.363 -add_title_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
40.364 -{
40.365 - GtkWidget *hbox = add_line (vbox, "Title: ");
40.366 -
40.367 - scheduler_ui->title_entry = gtk_entry_new ();
40.368 - gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->title_entry, FALSE, FALSE, 0);
40.369 - gtk_entry_set_text (GTK_ENTRY (scheduler_ui->title_entry), "(Optional)");
40.370 -
40.371 -}
41.1 --- a/gmyth/src/gui/mmyth_schedulerui.h Wed Sep 27 00:08:03 2006 +0100
41.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
41.3 @@ -1,45 +0,0 @@
41.4 -#ifndef MMYTH_SCHEDULERECORDING_H_
41.5 -#define MMYTH_SCHEDULERECORDING_H_
41.6 -
41.7 -#include <glib.h>
41.8 -
41.9 -typedef struct _MMythSchedulerUI {
41.10 -
41.11 - GList *channel_list;
41.12 -
41.13 - GtkWidget *main_widget;
41.14 -
41.15 - GtkWidget *channel_combobox;
41.16 - GtkWidget *freq_combobox;
41.17 - GtkWidget *hour_spinbutton;
41.18 - GtkWidget *min_spinbutton;
41.19 - GtkWidget *duration_spinbutton;
41.20 - GtkWidget *title_entry;
41.21 - GtkWidget *date_button;
41.22 -
41.23 - GtkWidget *calendar_dialog;
41.24 - GtkWidget *calendar;
41.25 -
41.26 - guint year_temp, month_temp, day_temp;
41.27 -} MMythSchedulerUI;
41.28 -
41.29 -typedef struct {
41.30 - long int channel_id;
41.31 -
41.32 - struct tm start_tm;
41.33 -
41.34 - int duration;
41.35 - int frequency;
41.36 -
41.37 - GString *title;
41.38 -
41.39 -} ScheduleEntry;
41.40 -
41.41 -MMythSchedulerUI* mmyth_schedulerui_new (void);
41.42 -
41.43 -gboolean mmyth_schedulerui_save (MMythSchedulerUI *scheduler_ui);
41.44 -
41.45 -void mmyth_schedulerui_cb_schedule_button (GtkButton * button, gpointer user_data);
41.46 -
41.47 -
41.48 -#endif /*MMYTH_SCHEDULERECORDING_H_*/
42.1 --- a/gmyth/src/gui/mmyth_ui.c Wed Sep 27 00:08:03 2006 +0100
42.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
42.3 @@ -1,814 +0,0 @@
42.4 -
42.5 -#include <glib-object.h>
42.6 -#include <sys/types.h>
42.7 -#include <sys/stat.h>
42.8 -#include <unistd.h>
42.9 -#include <string.h>
42.10 -#include <stdio.h>
42.11 -#include <gtk/gtk.h>
42.12 -#include <gdk/gdkx.h>
42.13 -#include <gst/interfaces/xoverlay.h>
42.14 -#include <assert.h>
42.15 -
42.16 -#include "mmyth_ui.h"
42.17 -#include "mmyth_uicommon.h"
42.18 -#include "mmyth_schedulerui.h"
42.19 -#include "mmyth_recordui.h"
42.20 -#include "mmyth_uisettings.h"
42.21 -#include "mmyth_epg_grid_view.h"
42.22 -
42.23 -/* GMyth library includes */
42.24 -#include "gmyth_context.h"
42.25 -#include "gmyth_tvplayer.h"
42.26 -
42.27 -#ifndef MAEMO_PLATFORM
42.28 -static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
42.29 -#endif
42.30 -
42.31 -static MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
42.32 -static MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
42.33 -static MMythUiCommon *create_epg_grid_view (MMythUi * mmyth_ui);
42.34 -static MMythUiCommon *create_record_view (MMythUi * mmyth_ui);
42.35 -static MMythUiCommon *create_schedule_view (MMythUi * mmyth_ui);
42.36 -
42.37 -static void cb_video_close_button (GtkButton * button, gpointer user_data);
42.38 -static void cb_record_button (GtkButton * button, gpointer user_data);
42.39 -static void cb_menu_item_settings (GtkMenuItem *menuitem, gpointer user_data);
42.40 -
42.41 -/* main box from button box separator*/
42.42 -static GtkWidget *main_vseparator = NULL;
42.43 -
42.44 -GdkPixbuf *icon_sports, *icon_news,
42.45 - *icon_movies, *icon_shows, *icon_default;
42.46 -
42.47 -#ifndef MAEMO_PLATFORM
42.48 -/* FIXME: */
42.49 -static MMythUi *popup_mmyth_ui;
42.50 -#endif
42.51 -
42.52 -MMythUi *
42.53 -mmyth_ui_initialize (
42.54 -#ifdef MAEMO_PLATFORM
42.55 - HildonProgram *program,
42.56 -#endif
42.57 - GtkWidget * main_window)
42.58 -{
42.59 - MMythUi *mmyth_ui;
42.60 -
42.61 - mmyth_ui = g_new0 (MMythUi, 1);
42.62 -
42.63 - mmyth_ui->main_window = main_window;
42.64 - mmyth_ui->videow = NULL;
42.65 - mmyth_ui->mmyth_recordui = NULL;
42.66 - mmyth_ui->mmyth_schedulerui = NULL;
42.67 -
42.68 - /* Horizontal box that divides the view into control and video area */
42.69 - mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
42.70 - gtk_widget_show (mmyth_ui->main_hbox);
42.71 - g_object_ref (mmyth_ui->main_hbox);
42.72 -
42.73 - main_bg_color.red = 65000;
42.74 - main_bg_color.green = 65000;
42.75 - main_bg_color.blue = 65000;
42.76 -
42.77 -
42.78 -#ifndef MAEMO_PLATFORM
42.79 - /* Popup menu */
42.80 - popup_mmyth_ui = mmyth_ui;
42.81 - g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
42.82 - G_CALLBACK (button_press_handler),
42.83 - G_OBJECT (mmyth_ui->main_hbox));
42.84 -
42.85 -#else // #ifdef MAEMO
42.86 -
42.87 - mmyth_ui->main_menu = GTK_MENU(gtk_menu_new());
42.88 - hildon_program_set_common_menu(program, mmyth_ui->main_menu);
42.89 -
42.90 - mmyth_ui->menu_setup = gtk_menu_item_new_with_label("Setup");
42.91 - gtk_widget_set_size_request (GTK_WIDGET (mmyth_ui->menu_setup), 150, 40);
42.92 - gtk_menu_append(mmyth_ui->main_menu, mmyth_ui->menu_setup);
42.93 -
42.94 - g_signal_connect(G_OBJECT(mmyth_ui->menu_setup), "activate", G_CALLBACK(cb_menu_item_settings), mmyth_ui);
42.95 -
42.96 - gtk_widget_show_all (GTK_WIDGET (mmyth_ui->main_menu));
42.97 -#endif
42.98 -
42.99 - // Main widget is mmyth_ui->main_hbox
42.100 - mmyth_ui->main_uicommon = create_main_view (mmyth_ui);
42.101 -
42.102 - gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
42.103 - mmyth_ui->main_hbox);
42.104 -
42.105 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
42.106 -
42.107 - return mmyth_ui;
42.108 -}
42.109 -
42.110 -void
42.111 -mmyth_ui_finalize (MMythUi * mmyth_ui)
42.112 -{
42.113 - if (mmyth_ui != NULL) {
42.114 - if (mmyth_ui->main_uicommon)
42.115 - mmyth_uicommon_free (mmyth_ui->main_uicommon);
42.116 - if (mmyth_ui->video_uicommon)
42.117 - mmyth_uicommon_free (mmyth_ui->video_uicommon);
42.118 - if (mmyth_ui->epg_grid_uicommon)
42.119 - mmyth_uicommon_free (mmyth_ui->epg_grid_uicommon);
42.120 - if (mmyth_ui->record_uicommon)
42.121 - mmyth_uicommon_free (mmyth_ui->record_uicommon);
42.122 - if (mmyth_ui->schedule_uicommon)
42.123 - mmyth_uicommon_free (mmyth_ui->schedule_uicommon);
42.124 -
42.125 - g_free (mmyth_ui);
42.126 - }
42.127 -}
42.128 -
42.129 -void
42.130 -mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
42.131 -{
42.132 - if (new_uicommon == NULL) {
42.133 - g_warning ("MMythUI setting a NULL UI_Common as current display\n");
42.134 - return;
42.135 - }
42.136 -
42.137 - if (mmyth_ui->current_uicommon) {
42.138 - if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
42.139 - gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
42.140 - gtk_widget_hide (mmyth_ui->videow);
42.141 - }
42.142 - else {
42.143 - gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
42.144 - mmyth_ui->current_uicommon->main_widget);
42.145 - }
42.146 -
42.147 - gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
42.148 - mmyth_ui->current_uicommon->event_box);
42.149 - gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
42.150 - main_vseparator);
42.151 -
42.152 - }
42.153 -
42.154 - if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
42.155 - //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
42.156 - gtk_widget_show (mmyth_ui->video_alignment);
42.157 - gtk_widget_show (mmyth_ui->videow);
42.158 - }
42.159 - else {
42.160 - /* FIXME: Fst call is NULL when mmyth_player_init fails */
42.161 - if(mmyth_ui->video_alignment != NULL)
42.162 - gtk_widget_hide (mmyth_ui->video_alignment);
42.163 - /* FIXME: Fst call is NULL when mmyth_player_init fails */
42.164 - if(mmyth_ui->videow != NULL)
42.165 - gtk_widget_hide (mmyth_ui->videow);
42.166 -
42.167 - gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
42.168 - new_uicommon->main_widget, TRUE, TRUE, 0);
42.169 - }
42.170 -
42.171 - if(main_vseparator == NULL) {
42.172 - /* FIXME: should free this variable*/
42.173 - main_vseparator = gtk_vseparator_new();
42.174 - g_object_ref (main_vseparator);
42.175 - }
42.176 - gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
42.177 - main_vseparator, FALSE, FALSE, 0);
42.178 - gtk_widget_show (main_vseparator);
42.179 -
42.180 - gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
42.181 - FALSE, 0);
42.182 -
42.183 - mmyth_ui->current_uicommon = new_uicommon;
42.184 -
42.185 -}
42.186 -
42.187 -/* The close callback is the same for all windows*/
42.188 -static void
42.189 -cb_not_impl_button (GtkButton * button, gpointer user_data)
42.190 -{
42.191 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.192 -
42.193 - GtkWidget *msg_dialog = gtk_message_dialog_new (
42.194 - GTK_WINDOW(mmyth_ui->main_window),
42.195 - GTK_DIALOG_MODAL |
42.196 - GTK_DIALOG_DESTROY_WITH_PARENT,
42.197 - GTK_MESSAGE_INFO,
42.198 - GTK_BUTTONS_OK,
42.199 - "Feature not implemented");
42.200 - gtk_widget_set_size_request (msg_dialog, 350, 120);
42.201 -
42.202 - gtk_dialog_run (GTK_DIALOG (msg_dialog));
42.203 -
42.204 - gtk_widget_destroy(GTK_WIDGET(msg_dialog));
42.205 -}
42.206 -
42.207 -/******************************************************************************
42.208 - * POPUP MENU WIDGET METHODS *
42.209 - *****************************************************************************/
42.210 -
42.211 -static void
42.212 -cb_menu_item_settings (GtkMenuItem *menuitem,
42.213 - gpointer user_data)
42.214 -{
42.215 -
42.216 - MMythUi *mmyth_ui = (MMythUi*) user_data;
42.217 -
42.218 - if (mmyth_uisettings_run (GTK_WINDOW (mmyth_ui->main_window))) {
42.219 - // If user changes the settings, we restart the context
42.220 - g_debug ("[%s] Restarting mmyth_context to new settings", __FUNCTION__);
42.221 - gmyth_context_initialize();
42.222 - }
42.223 -}
42.224 -
42.225 -#ifndef MAEMO_PLATFORM
42.226 -
42.227 -static void
42.228 -detacher (GtkWidget *attach_widget,GtkMenu *menu)
42.229 -{
42.230 -
42.231 -}
42.232 -
42.233 -static void
42.234 -do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
42.235 -{
42.236 - GtkWidget *popup;
42.237 -
42.238 - int button, event_time;
42.239 -
42.240 - GtkWidget *item_general;
42.241 - GtkWidget *image;
42.242 -
42.243 - popup = gtk_menu_new ();
42.244 -
42.245 - item_general = gtk_image_menu_item_new_with_mnemonic ("Setup");
42.246 - gtk_widget_show (item_general);
42.247 - gtk_container_add (GTK_CONTAINER (popup), item_general);
42.248 -
42.249 - image = gtk_image_new_from_stock ("gtk-edit", GTK_ICON_SIZE_MENU);
42.250 - gtk_widget_show (image);
42.251 - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item_general), image);
42.252 -
42.253 - g_signal_connect (G_OBJECT(item_general), "activate", G_CALLBACK (cb_menu_item_settings), popup_mmyth_ui);
42.254 -
42.255 - if (event) {
42.256 - button = event->button;
42.257 - event_time = event->time;
42.258 - } else {
42.259 - button = 0;
42.260 - event_time = gtk_get_current_event_time ();
42.261 - }
42.262 -
42.263 - gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
42.264 - gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL,
42.265 - button, event_time);
42.266 - gtk_widget_show_all(popup);
42.267 -}
42.268 -
42.269 -/* Respond to a button-press by posting a menu passed in as widget.
42.270 - *
42.271 - * Note that the "widget" argument is the menu being posted, NOT
42.272 - * the button that was pressed.
42.273 - */
42.274 -static gint
42.275 -button_press_handler (GtkWidget *widget, GdkEvent *event)
42.276 -{
42.277 -
42.278 - if (event->type == GDK_BUTTON_PRESS) {
42.279 - GdkEventButton *bevent = (GdkEventButton *) event;
42.280 - /* Ignore double-clicks and triple-clicks */
42.281 - if (bevent->button == 3)
42.282 - {
42.283 - do_popup_menu (widget, bevent);
42.284 - return TRUE;
42.285 - }
42.286 - }
42.287 -
42.288 - /* Tell calling code that we have not handled this event; pass it on. */
42.289 - return FALSE;
42.290 -}
42.291 -#endif
42.292 -
42.293 -/******************************************************************************
42.294 - * MAIN APP VIEW METHODS *
42.295 - *****************************************************************************/
42.296 -
42.297 -static void
42.298 -cb_close_button (GtkButton * button, gpointer user_data)
42.299 -{
42.300 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.301 -
42.302 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
42.303 -}
42.304 -
42.305 -static void
42.306 -cb_watch_tv_button (GtkButton * button, gpointer user_data)
42.307 -{
42.308 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.309 - gboolean res = FALSE;
42.310 -
42.311 - if (!(mmyth_ui->video_uicommon))
42.312 - mmyth_ui->video_uicommon = create_video_view (mmyth_ui);
42.313 -
42.314 - // Creates the tv player that will retrieve the mythtv content, decode and show it
42.315 - mmyth_ui->tvplayer = gmyth_tvplayer_new ();
42.316 - /* choose here if this is a LiveTV session */
42.317 - mmyth_ui->tvplayer->is_livetv = TRUE;
42.318 -
42.319 - res = gmyth_tvplayer_initialize (mmyth_ui->tvplayer);
42.320 -
42.321 - if (!res) {
42.322 - g_warning ("[%s] Could not initialize tvplayer", __FUNCTION__);
42.323 -
42.324 - g_object_unref (mmyth_ui->tvplayer);
42.325 - mmyth_ui->tvplayer = NULL;
42.326 -
42.327 - GtkWidget *dialog = gtk_message_dialog_new (
42.328 - GTK_WINDOW(mmyth_ui->main_window),
42.329 - GTK_DIALOG_DESTROY_WITH_PARENT,
42.330 - GTK_MESSAGE_ERROR,
42.331 - GTK_BUTTONS_CLOSE,
42.332 - "MMyth found errors while starting TV Player, please check "
42.333 - "the GStreamer installation");
42.334 -
42.335 - gtk_dialog_run (GTK_DIALOG (dialog));
42.336 - gtk_widget_destroy (dialog);
42.337 -
42.338 - return;
42.339 - }
42.340 - //res = mmyth_tvplayer_livetv_setup (mmyth_ui->tvplayer);
42.341 - //
42.342 - if (mmyth_ui && mmyth_ui->tvplayer && res) {
42.343 - gmyth_tvplayer_set_widget (mmyth_ui->tvplayer, mmyth_ui->videow);
42.344 - gmyth_tvplayer_start_playing (mmyth_ui->tvplayer);
42.345 - } else {
42.346 - // TODO: Show Alert with error description!
42.347 - g_warning ("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
42.348 - g_object_unref (mmyth_ui->tvplayer);
42.349 - mmyth_ui->tvplayer = NULL;
42.350 - // FIXME: Show the exact error that happened
42.351 - GtkWidget *dialog = gtk_message_dialog_new (
42.352 - GTK_WINDOW(mmyth_ui->main_window),
42.353 - GTK_DIALOG_DESTROY_WITH_PARENT,
42.354 - GTK_MESSAGE_ERROR,
42.355 - GTK_BUTTONS_CLOSE,
42.356 - "Error while starting TV Player, please check if the backend"
42.357 - " is running properly and a tv card is available!");
42.358 - gtk_dialog_run (GTK_DIALOG (dialog));
42.359 - gtk_widget_destroy (dialog);
42.360 - return;
42.361 - }
42.362 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);
42.363 -
42.364 -}
42.365 -
42.366 -static void
42.367 -cb_epg_button (GtkButton * button, gpointer user_data)
42.368 -{
42.369 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.370 -
42.371 - if (!(mmyth_ui->epg_grid_uicommon))
42.372 - mmyth_ui->epg_grid_uicommon = create_epg_grid_view(mmyth_ui);
42.373 -
42.374 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->epg_grid_uicommon);
42.375 -}
42.376 -
42.377 -static MMythUiCommon *
42.378 -create_main_view (MMythUi * mmyth_ui)
42.379 -{
42.380 - MMythUiCommon *ui_common;
42.381 - GtkWidget *main_widget;
42.382 - GtkWidget *image;
42.383 -
42.384 - g_debug ("Creating Main UI Common");
42.385 -
42.386 - // FIXME: file path
42.387 -#ifdef MMYTH_DEV
42.388 - image = gtk_image_new_from_file ("../pixmaps/mmyth_logo.png");
42.389 -#else
42.390 - image = gtk_image_new_from_file ( PIX_DIR "mmyth_logo.png");
42.391 -#endif
42.392 -
42.393 - main_widget = gtk_event_box_new();
42.394 -
42.395 - gtk_container_add (GTK_CONTAINER (main_widget),
42.396 - image);
42.397 -
42.398 -
42.399 - gtk_widget_show_all (main_widget);
42.400 - g_object_ref (main_widget);
42.401 -
42.402 - ui_common = mmyth_uicommon_new (main_widget,
42.403 - "Watch TV", "EPG", "Recording");
42.404 -
42.405 - /* Button signals */
42.406 - // FIXME
42.407 - g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
42.408 - G_CALLBACK (cb_watch_tv_button), mmyth_ui);
42.409 - g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
42.410 - G_CALLBACK (cb_epg_button), mmyth_ui);
42.411 - g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
42.412 - G_CALLBACK (cb_record_button), mmyth_ui);
42.413 -
42.414 - return ui_common;
42.415 -
42.416 -}
42.417 -
42.418 -/******************************************************************************
42.419 - * epg GRID VIEW METHODS *
42.420 - *****************************************************************************/
42.421 -
42.422 -static MMythUiCommon *
42.423 -create_epg_grid_view (MMythUi * mmyth_ui)
42.424 -{
42.425 - MMythUiCommon *ui_common;
42.426 -
42.427 - g_debug ("Creating EPG Grid UI Common");
42.428 -
42.429 - GtkWidget *epg_grid_view = GTK_WIDGET (epg_grid_view_new (mmyth_ui));
42.430 -
42.431 - ui_common = mmyth_uicommon_new (epg_grid_view,
42.432 - "Play", "Record",
42.433 - "Close");
42.434 -
42.435 - /* Button signals */
42.436 - g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
42.437 - G_CALLBACK (cb_not_impl_button), mmyth_ui);
42.438 - g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
42.439 - G_CALLBACK (cb_record_button), mmyth_ui);
42.440 - g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
42.441 - G_CALLBACK (cb_close_button), mmyth_ui);
42.442 -
42.443 - return ui_common;
42.444 -}
42.445 -/******************************************************************************
42.446 - * SCHEDULE VIEW METHODS *
42.447 - ******************************************************************************/
42.448 -
42.449 -static void
42.450 -cb_save_new_schedule (GtkButton *button, gpointer user_data)
42.451 -{
42.452 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.453 -
42.454 - if (!(mmyth_ui->schedule_uicommon))
42.455 - mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
42.456 -
42.457 - mmyth_schedulerui_save (mmyth_ui->mmyth_schedulerui);
42.458 -
42.459 - mmyth_recordui_reload_schedule (mmyth_ui->mmyth_recordui);
42.460 -
42.461 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
42.462 -
42.463 -}
42.464 -
42.465 -static void
42.466 -cb_edit_scheduled (GtkTreeView * tree_view, GtkTreePath *path,
42.467 - GtkTreeViewColumn *column, gpointer user_data)
42.468 -{
42.469 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.470 - GtkTreeSelection *selection;
42.471 - GtkTreeModel *list_store;
42.472 - GtkTreeIter iter;
42.473 - int index;
42.474 - //gint new_row = 0, record_id = 0;
42.475 - ScheduleInfo *schedule_info;
42.476 - GList *schedule_list;
42.477 - //GtkTreeIter iter;
42.478 - gint res;
42.479 -
42.480 - //gtk_tree_store_clear(recordui->sch_tree_store);
42.481 -
42.482 - res = gmyth_scheduler_get_schedule_list(mmyth_ui->mmyth_recordui->scheduler, &(schedule_list));
42.483 - if (res < 0) {
42.484 - g_warning ("[%s] Retrieved NULL list of scheduled data from database", __FUNCTION__);
42.485 - //return FALSE;
42.486 - }
42.487 - printf("\nX %d", res); fflush(stdout);
42.488 -
42.489 - selection =
42.490 - gtk_tree_view_get_selection(GTK_TREE_VIEW(mmyth_ui->mmyth_recordui->sch_treeview));
42.491 -
42.492 - gtk_tree_selection_get_selected(selection, &list_store, &iter);
42.493 - gtk_tree_model_get(list_store, &iter, 4, &index, -1);
42.494 -
42.495 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
42.496 -
42.497 - if (!(mmyth_ui->schedule_uicommon))
42.498 - mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
42.499 -
42.500 - schedule_list = g_list_nth(schedule_list, atoi(gtk_tree_path_to_string(path)));
42.501 - schedule_info = (ScheduleInfo*) schedule_list->data;
42.502 -
42.503 - printf("\nstarttime: %ld", schedule_info->start_time); fflush(stdout);
42.504 -}
42.505 -
42.506 -static MMythUiCommon *
42.507 -create_schedule_view (MMythUi * mmyth_ui)
42.508 -{
42.509 - MMythUiCommon *ui_common;
42.510 - GtkWidget *schedule_widget;
42.511 -
42.512 - g_debug ("Creating Schedule UI Common");
42.513 -
42.514 - mmyth_ui->mmyth_schedulerui = mmyth_schedulerui_new ();
42.515 - if (mmyth_ui->mmyth_schedulerui == NULL) {
42.516 - g_warning ("[%s] Error while creating scheduler ui", __FUNCTION__);
42.517 - return NULL;
42.518 - }
42.519 -
42.520 - schedule_widget = mmyth_ui->mmyth_schedulerui->main_widget;
42.521 -
42.522 - gtk_widget_show_all (schedule_widget);
42.523 - g_object_ref (schedule_widget);
42.524 -
42.525 - ui_common = mmyth_uicommon_new (schedule_widget,
42.526 - "Save", "Clear",
42.527 - "Cancel");
42.528 -
42.529 - /* Button signals */
42.530 - g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
42.531 - G_CALLBACK (cb_save_new_schedule), mmyth_ui);
42.532 - g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
42.533 - G_CALLBACK (cb_not_impl_button), mmyth_ui);
42.534 - g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
42.535 - G_CALLBACK (cb_record_button), mmyth_ui);
42.536 -
42.537 - return ui_common;
42.538 -}
42.539 -/******************************************************************************
42.540 - * RECORD VIEW METHODS *
42.541 - ******************************************************************************/
42.542 -static void
42.543 -cb_record_button (GtkButton * button, gpointer user_data)
42.544 -{
42.545 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.546 -
42.547 - if (!(mmyth_ui->record_uicommon)) {
42.548 - mmyth_ui->record_uicommon = create_record_view (mmyth_ui);
42.549 - mmyth_ui->schedule_uicommon = create_schedule_view (mmyth_ui);
42.550 - }
42.551 -
42.552 - mmyth_recordui_reload_all (mmyth_ui->mmyth_recordui);
42.553 -
42.554 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
42.555 -
42.556 -}
42.557 -
42.558 -static void
42.559 -cb_record_close_button (GtkButton * button, gpointer user_data)
42.560 -{
42.561 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.562 -
42.563 - mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
42.564 -
42.565 - mmyth_recordui_free(mmyth_ui->mmyth_recordui);
42.566 -
42.567 - if (mmyth_ui->record_uicommon) {
42.568 - gtk_widget_destroy (mmyth_ui->record_uicommon->main_widget);
42.569 - mmyth_uicommon_free(mmyth_ui->record_uicommon);
42.570 - mmyth_ui->record_uicommon = NULL;
42.571 - }
42.572 -
42.573 - if (mmyth_ui->schedule_uicommon) {
42.574 - // mmyth_uicommon_free(mmyth_ui->schedule_uicommon);
42.575 - }
42.576 -}
42.577 -
42.578 -
42.579 -
42.580 -
42.581 -static void
42.582 -play_selected_recorded (gpointer user_data)
42.583 -{
42.584 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.585 - gboolean res = FALSE;
42.586 -
42.587 - gchar *path = mmyth_recordui_get_selected_recorded (mmyth_ui->mmyth_recordui);
42.588 -
42.589 - if (path == NULL) {
42.590 - // This should never happens. Play button is just activated when
42.591 - // a recording is selected.
42.592 - g_warning ("[%s] Play button pressed while none recorded is selected", __FUNCTION__);
42.593 - return;
42.594 - }
42.595 -
42.596 - if (!(mmyth_ui->video_uicommon))
42.597 - mmyth_ui->video_uicommon = create_video_view (mmyth_ui);
42.598 -
42.599 - // Creates the tv player that will retrieve the mythtv content, decode and show it
42.600 - mmyth_ui->tvplayer = gmyth_tvplayer_new ();
42.601 - g_debug ("[%s] New TV Player created: %d\n", __FUNCTION__, (int) (mmyth_ui->tvplayer));
42.602 - res = gmyth_tvplayer_initialize (mmyth_ui->tvplayer);
42.603 - if (!res) {
42.604 - g_warning ("[%s] Could not initialize tvplayer", __FUNCTION__);
42.605 -
42.606 - g_object_unref (mmyth_ui->tvplayer);
42.607 - mmyth_ui->tvplayer = NULL;
42.608 -
42.609 - GtkWidget *dialog = gtk_message_dialog_new (
42.610 - GTK_WINDOW(mmyth_ui->main_window),
42.611 - GTK_DIALOG_DESTROY_WITH_PARENT,
42.612 - GTK_MESSAGE_ERROR,
42.613 - GTK_BUTTONS_CLOSE,
42.614 - "MMyth found errors while starting TV Player, please check "
42.615 - "the GStreamer installation");
42.616 -
42.617 - gtk_dialog_run (GTK_DIALOG (dialog));
42.618 - gtk_widget_destroy (dialog);
42.619 -
42.620 - return;
42.621 - }
42.622 -
42.623 - res = gmyth_tvplayer_record_setup (mmyth_ui->tvplayer, path);
42.624 -
42.625 - if (mmyth_ui && mmyth_ui->tvplayer && res) {
42.626 - gmyth_tvplayer_set_widget (mmyth_ui->tvplayer, mmyth_ui->videow);
42.627 - gmyth_tvplayer_start_playing (mmyth_ui->tvplayer);
42.628 - } else {
42.629 - // TODO: Show Alert with error description!
42.630 - g_warning ("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
42.631 - g_object_unref (mmyth_ui->tvplayer);
42.632 - mmyth_ui->tvplayer = NULL;
42.633 - // FIXME: Show the exact error that happened
42.634 - GtkWidget *dialog = gtk_message_dialog_new (
42.635 - GTK_WINDOW(mmyth_ui->main_window),
42.636 - GTK_DIALOG_DESTROY_WITH_PARENT,
42.637 - GTK_MESSAGE_ERROR,
42.638 - GTK_BUTTONS_CLOSE,
42.639 - "Error while starting TV Player, please check if the backend"
42.640 - " is running properly and a tv card is available!");
42.641 - gtk_dialog_run (GTK_DIALOG (dialog));
42.642 - gtk_widget_destroy (dialog);
42.643 - return;
42.644 - }
42.645 -
42.646 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);
42.647 -}
42.648 -
42.649 -static void
42.650 -cb_play_clicked_recorded (GtkTreeView * tree_view, GtkTreePath *path,
42.651 - GtkTreeViewColumn *column, gpointer user_data)
42.652 -{
42.653 - play_selected_recorded (user_data);
42.654 -}
42.655 -
42.656 -static void
42.657 -cb_play_selected (GtkButton * button, gpointer user_data)
42.658 -{
42.659 - play_selected_recorded (user_data);
42.660 -}
42.661 -
42.662 -static void
42.663 -cb_schedule_button (GtkButton * button, gpointer user_data)
42.664 -{
42.665 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.666 -
42.667 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
42.668 -}
42.669 -
42.670 -void
42.671 -cb_switch_page (GtkNotebook *notebook, GtkNotebookPage *page,
42.672 - guint page_num, gpointer user_data)
42.673 -{
42.674 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.675 - MMythUiCommon *ui_common;
42.676 -
42.677 - assert (mmyth_ui);
42.678 - assert (mmyth_ui->record_uicommon);
42.679 -
42.680 - ui_common = mmyth_ui->record_uicommon;
42.681 -
42.682 - if (page_num == 0) { // Switched to Schedule list
42.683 - gtk_button_set_label (GTK_BUTTON (ui_common->button1), "New");
42.684 - g_signal_handlers_disconnect_by_func (
42.685 - G_OBJECT (ui_common->button1), G_CALLBACK (cb_play_selected), mmyth_ui);
42.686 - g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
42.687 - G_CALLBACK (cb_schedule_button), mmyth_ui);
42.688 - } else if (page_num == 1) {
42.689 - gtk_button_set_label (GTK_BUTTON (ui_common->button1), "Play");
42.690 - g_signal_handlers_disconnect_by_func (
42.691 - G_OBJECT (ui_common->button1), G_CALLBACK (cb_schedule_button), mmyth_ui);
42.692 - g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
42.693 - G_CALLBACK (cb_play_selected), mmyth_ui);
42.694 - }
42.695 -}
42.696 -
42.697 -
42.698 -static MMythUiCommon *
42.699 -create_record_view (MMythUi * mmyth_ui)
42.700 -{
42.701 - MMythUiCommon *ui_common;
42.702 -
42.703 - g_debug ("Creating Record UI Common");
42.704 -
42.705 - mmyth_ui->mmyth_recordui = mmyth_recordui_new ();
42.706 -
42.707 - // FIXME: Change MMythRecordUI to a GtkWidget child and avoid this call!
42.708 - gtk_widget_show_all (mmyth_ui->mmyth_recordui->scrolled_window);
42.709 -
42.710 - ui_common = mmyth_uicommon_new (mmyth_ui->mmyth_recordui->scrolled_window, "New", "Delete", "<<Back");
42.711 - g_object_ref (mmyth_ui->mmyth_recordui->scrolled_window);
42.712 -
42.713 - /* Button signals */
42.714 - g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
42.715 - G_CALLBACK (cb_schedule_button), mmyth_ui);
42.716 - g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
42.717 - G_CALLBACK (mmyth_recordui_delete_selected), mmyth_ui->mmyth_recordui);
42.718 - g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
42.719 - G_CALLBACK (cb_record_close_button), mmyth_ui);
42.720 - g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->notebook),
42.721 - "switch-page", G_CALLBACK (cb_switch_page), mmyth_ui);
42.722 - g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->rec_treeview),
42.723 - "row-activated", G_CALLBACK (cb_play_clicked_recorded), mmyth_ui);
42.724 - g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->sch_treeview),
42.725 - "row-activated", G_CALLBACK (cb_edit_scheduled), mmyth_ui);
42.726 - return ui_common;
42.727 -}
42.728 -
42.729 -
42.730 -/******************************************************************************
42.731 - * GST VIDEO WIDGET METHODS *
42.732 - *****************************************************************************/
42.733 -
42.734 -static void
42.735 -cb_video_close_button (GtkButton * button, gpointer user_data)
42.736 -{
42.737 - MMythUi *mmyth_ui = (MMythUi *) user_data;
42.738 -
42.739 - g_debug ("MMythUI video close button pressed");
42.740 -
42.741 - if (mmyth_ui && mmyth_ui->tvplayer) {
42.742 - gmyth_tvplayer_stop_playing (mmyth_ui->tvplayer);
42.743 -
42.744 - g_object_unref (mmyth_ui->tvplayer);
42.745 - mmyth_ui->tvplayer = NULL;
42.746 - } else {
42.747 - g_warning ("cb_video_close_button called with NULL pointer\n");
42.748 - }
42.749 -
42.750 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
42.751 -}
42.752 -
42.753 -
42.754 -static MMythUiCommon *
42.755 -create_video_view (MMythUi * mmyth_ui)
42.756 -{
42.757 -
42.758 - MMythUiCommon *ui_common;
42.759 -
42.760 - g_debug ("Creating Video UI Common");
42.761 -
42.762 - /* Creates widget to be user by MMythTVPlayer to draw the video */
42.763 - mmyth_ui->videow = gtk_drawing_area_new ();
42.764 - // FIXME: Get the widget size from settings
42.765 - gtk_widget_set_size_request (mmyth_ui->videow, 300, 240);
42.766 -
42.767 - //mmiptv_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
42.768 -
42.769 - // Creates an alignment to place the video widget inside
42.770 - mmyth_ui->video_alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
42.771 - gtk_widget_hide (mmyth_ui->video_alignment);
42.772 -
42.773 - gtk_container_add (GTK_CONTAINER (mmyth_ui->video_alignment),
42.774 - mmyth_ui->videow);
42.775 -
42.776 - /* Add the gst video widget to hbox. It should never be removed. */
42.777 - /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
42.778 - if((mmyth_ui->main_hbox != NULL) && (mmyth_ui->video_alignment != NULL)) {
42.779 - gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
42.780 - mmyth_ui->video_alignment, TRUE, TRUE, 0);
42.781 - } else {
42.782 - g_warning ("[%s] Error while adding video_alignment to main widget", __FUNCTION__);
42.783 - }
42.784 -
42.785 - g_object_ref (mmyth_ui->videow);
42.786 - g_object_ref (mmyth_ui->video_alignment);
42.787 -
42.788 - ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
42.789 - " Full\nScreen", "Other\nServices",
42.790 - "Close");
42.791 -
42.792 -
42.793 - g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
42.794 - G_CALLBACK (cb_not_impl_button), mmyth_ui);
42.795 - g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
42.796 - G_CALLBACK (cb_not_impl_button), mmyth_ui);
42.797 - g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
42.798 - G_CALLBACK (cb_video_close_button), mmyth_ui);
42.799 -
42.800 - if (ui_common)
42.801 - g_debug ("Video UI_Common sucessfull created");
42.802 -
42.803 - return ui_common;
42.804 -}
42.805 -
42.806 -
42.807 -
42.808 -GtkWidget*
42.809 -mmyth_ui_get_video_widget (MMythUi *mmyth_ui) {
42.810 -
42.811 - if (mmyth_ui && mmyth_ui->videow) {
42.812 -
42.813 - return mmyth_ui->videow;
42.814 - }
42.815 -
42.816 - return NULL;
42.817 -}
43.1 --- a/gmyth/src/gui/mmyth_ui.h Wed Sep 27 00:08:03 2006 +0100
43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
43.3 @@ -1,75 +0,0 @@
43.4 -#ifndef MMYTH_UI_H_
43.5 -#define MMYTH_UI_H_
43.6 -
43.7 -#include <gtk/gtk.h>
43.8 -#include <gst/gst.h>
43.9 -
43.10 -#include "config.h"
43.11 -
43.12 -#ifdef MAEMO_PLATFORM
43.13 -#include "hildon-widgets/hildon-program.h"
43.14 -#include "hildon-widgets/hildon-window.h"
43.15 -#endif
43.16 -
43.17 -#include "mmyth_uicommon.h"
43.18 -#include "mmyth_recordui.h"
43.19 -#include "mmyth_schedulerui.h"
43.20 -
43.21 -/* GMyth library includes */
43.22 -#include "gmyth_tvplayer.h"
43.23 -
43.24 -typedef struct _MMythUi
43.25 -{
43.26 -
43.27 - /* The main application window */
43.28 - GtkWidget *main_window;
43.29 - MMythUiCommon *current_uicommon;
43.30 -
43.31 - /* Main widget components */
43.32 - GtkWidget *main_hbox;
43.33 - GtkWidget *video_alignment;
43.34 - GdkPixbuf *logo;
43.35 -
43.36 - /* Main widgets grouping */
43.37 - MMythUiCommon *main_uicommon;
43.38 - MMythUiCommon *video_uicommon;
43.39 - MMythUiCommon *epg_grid_uicommon;
43.40 - MMythUiCommon *record_uicommon;
43.41 - MMythUiCommon *schedule_uicommon;
43.42 -
43.43 - GtkWidget *videow;
43.44 - int idle_id;
43.45 - //GstTagList *tagcache;
43.46 -
43.47 - MMythRecordUI *mmyth_recordui;
43.48 - MMythSchedulerUI *mmyth_schedulerui;
43.49 -
43.50 -#ifdef MAEMO_PLATFORM
43.51 - HildonProgram *program;
43.52 - GtkMenu *main_menu;
43.53 - GtkWidget *menu_setup;
43.54 -#endif
43.55 -
43.56 - GMythTVPlayer *tvplayer;
43.57 -
43.58 -} MMythUi;
43.59 -
43.60 -GdkPixbuf *icon_sports, *icon_news, *icon_movies, *icon_shows;
43.61 -GdkColor main_bg_color;
43.62 -
43.63 -void mmyth_set_main_widget (MMythUi * mmyth_ui, MMythUiCommon * new_ui);
43.64 -//void mmyth_play_selected(GtkButton * button, gpointer user_data);
43.65 -
43.66 -#ifdef MAEMO_PLATFORM
43.67 -MMythUi *mmyth_ui_initialize (HildonProgram *program, GtkWidget * main_window);
43.68 -#else
43.69 -MMythUi *mmyth_ui_initialize (GtkWidget * main_window);
43.70 -#endif
43.71 -
43.72 -void mmyth_ui_finalize (MMythUi * mmyth_ui);
43.73 -
43.74 -void mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon);
43.75 -
43.76 -GtkWidget* mmyth_ui_get_video_widget (MMythUi *mmyth_ui);
43.77 -
43.78 -#endif /* MMYTH_UI_H_ */
44.1 --- a/gmyth/src/gui/mmyth_uicommon.c Wed Sep 27 00:08:03 2006 +0100
44.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
44.3 @@ -1,134 +0,0 @@
44.4 -
44.5 -#include <gtk/gtk.h>
44.6 -#include <glib.h>
44.7 -#include <glib/gprintf.h>
44.8 -
44.9 -#include "mmyth_uicommon.h"
44.10 -#include "mmyth_ui.h"
44.11 -
44.12 -static void
44.13 -refresh_time_on_screen (GtkWidget *label)
44.14 -{
44.15 - time_t real_time;
44.16 - struct tm sched_time;
44.17 - GString *time_showed;
44.18 -
44.19 - time_showed = g_string_new("");
44.20 - time(&real_time);
44.21 -
44.22 - if (localtime_r((time_t *)&real_time, &sched_time) == NULL) {
44.23 - g_error ("localtime_r error in mmyth_epg_grid_view!\n");
44.24 - return NULL;
44.25 - }
44.26 -
44.27 - g_string_printf(time_showed, "%d:%02d:%02d",
44.28 - sched_time.tm_hour,
44.29 - sched_time.tm_min,
44.30 - sched_time.tm_sec);
44.31 -
44.32 - gtk_label_set_text (GTK_LABEL(label), time_showed->str);
44.33 -}
44.34 -
44.35 -MMythUiCommon *
44.36 -mmyth_uicommon_new (GtkWidget * main_widget, const gchar * label1,
44.37 - const gchar * label2, const gchar * label3)
44.38 -{
44.39 -
44.40 - MMythUiCommon *ui_common = g_new0 (MMythUiCommon, 1);
44.41 -
44.42 - if (!main_widget) {
44.43 - g_warning ("MMythUICommon created with a NULL main widget\n");
44.44 - }
44.45 -
44.46 - ui_common->main_widget = main_widget;
44.47 -
44.48 - ui_common->event_box = gtk_event_box_new();
44.49 -
44.50 - /* Vertical box that divides the control area into two (buttons + clock) */
44.51 - ui_common->vbox = gtk_vbox_new (FALSE, 0); /* spacing */
44.52 - gtk_container_set_border_width(GTK_CONTAINER (ui_common->vbox), 4);
44.53 -
44.54 - gtk_container_add (GTK_CONTAINER (ui_common->event_box),
44.55 - ui_common->vbox);
44.56 - gtk_widget_modify_bg(ui_common->event_box, GTK_STATE_NORMAL, &main_bg_color);
44.57 -
44.58 - /* Vertical box that divides the control area into four */
44.59 - ui_common->button_vbox = gtk_vbox_new (TRUE, 0); /* spacing */
44.60 -
44.61 - gtk_container_set_border_width (GTK_CONTAINER (ui_common->button_vbox), 0);
44.62 -
44.63 - /* The button 1 */
44.64 - ui_common->button1 = gtk_button_new_with_label (label1);
44.65 - gtk_widget_modify_bg(ui_common->button1, GTK_STATE_NORMAL, &main_bg_color);
44.66 - gtk_widget_set_size_request (ui_common->button1, BUTTON_WIDTH,
44.67 - BUTTON_HEIGHT);
44.68 -
44.69 - /* The button 2 */
44.70 - ui_common->button2 = gtk_button_new_with_label (label2);
44.71 - gtk_widget_modify_bg(ui_common->button2, GTK_STATE_NORMAL, &main_bg_color);
44.72 - gtk_widget_set_size_request (ui_common->button2, BUTTON_WIDTH,
44.73 - BUTTON_HEIGHT);
44.74 -
44.75 - /* The button 3 */
44.76 - ui_common->button3 = gtk_button_new_with_label (label3);
44.77 - gtk_widget_modify_bg(ui_common->button3, GTK_STATE_NORMAL, &main_bg_color);
44.78 - gtk_widget_set_size_request (ui_common->button3, BUTTON_WIDTH,
44.79 - BUTTON_HEIGHT);
44.80 -
44.81 - /* The clock label */
44.82 - ui_common->label = gtk_label_new ("Starting...");
44.83 - gtk_widget_show (ui_common->label);
44.84 - ui_common->source_id = g_timeout_add(500, (GSourceFunc) refresh_time_on_screen, ui_common->label);
44.85 -
44.86 - /* Packing components */
44.87 - gtk_box_pack_start (GTK_BOX (ui_common->vbox),
44.88 - ui_common->button_vbox, TRUE, TRUE, 0);
44.89 -
44.90 - gtk_box_pack_start (GTK_BOX (ui_common->vbox),
44.91 - ui_common->label, FALSE, FALSE, 0);
44.92 -
44.93 - gtk_box_pack_start (GTK_BOX (ui_common->button_vbox),
44.94 - ui_common->button1, FALSE, FALSE, 0);
44.95 -
44.96 - gtk_box_pack_start (GTK_BOX (ui_common->button_vbox),
44.97 - ui_common->button2, FALSE, FALSE, 0);
44.98 -
44.99 - gtk_box_pack_start (GTK_BOX (ui_common->button_vbox),
44.100 - ui_common->button3, FALSE, FALSE, 0);
44.101 -
44.102 - gtk_widget_show_all (ui_common->event_box);
44.103 -
44.104 - /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
44.105 - if(ui_common->main_widget != NULL)
44.106 - g_object_ref (ui_common->main_widget);
44.107 -
44.108 - g_object_ref (ui_common->vbox);
44.109 - g_object_ref (ui_common->button_vbox);
44.110 - g_object_ref (ui_common->label);
44.111 - g_object_ref (ui_common->button1);
44.112 - g_object_ref (ui_common->button2);
44.113 - g_object_ref (ui_common->button3);
44.114 - g_object_ref (ui_common->event_box);
44.115 - return ui_common;
44.116 -}
44.117 -
44.118 -void
44.119 -mmyth_uicommon_free (MMythUiCommon *ui_common)
44.120 -{
44.121 - g_debug ("[%s] Clean uicommon used memory", __FUNCTION__);
44.122 -
44.123 - g_source_remove (ui_common->source_id);
44.124 -
44.125 - g_object_unref (ui_common->main_widget);
44.126 - g_object_unref (ui_common->vbox);
44.127 - g_object_unref (ui_common->button_vbox);
44.128 - g_object_unref (ui_common->label);
44.129 - g_object_unref (ui_common->button1);
44.130 - g_object_unref (ui_common->button2);
44.131 - g_object_unref (ui_common->button3);
44.132 - g_object_unref (ui_common->event_box);
44.133 -
44.134 - g_free (ui_common);
44.135 -}
44.136 -
44.137 -
45.1 --- a/gmyth/src/gui/mmyth_uicommon.h Wed Sep 27 00:08:03 2006 +0100
45.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
45.3 @@ -1,51 +0,0 @@
45.4 -#ifndef MMYTH_UICOMMON_H_
45.5 -#define MMYTH_UICOMMON_H_
45.6 -
45.7 -#include "config.h"
45.8 -
45.9 -#include <gtk/gtk.h>
45.10 -#include <glib.h>
45.11 -
45.12 -#ifndef MAEMO_PLATFORM
45.13 -#define BUTTON_HEIGHT 50
45.14 -#define BUTTON_WIDTH 100
45.15 -#else
45.16 -#define BUTTON_HEIGHT 80
45.17 -#define BUTTON_WIDTH 150
45.18 -#endif
45.19 -
45.20 -#define MAIN_WINDOW_WIDTH 550
45.21 -#define MAIN_WINDOW_HEIGHT 250
45.22 -
45.23 -#define CHANNELS_DIALOG_WIDTH 300
45.24 -#define CHANNELS_DIALOG_HEIGHT 200
45.25 -
45.26 -#define SETTINGS_DIALOG_WIDTH 300
45.27 -#define SETTINGS_DIALOG_HEIGHT 120
45.28 -
45.29 -extern GdkColor main_bg_color;
45.30 -
45.31 -typedef struct _MMythUiCommon
45.32 -{
45.33 - GtkWidget *main_widget;
45.34 -
45.35 - /* event box to set the background color*/
45.36 - GtkWidget *event_box;
45.37 -
45.38 - GtkWidget *vbox;
45.39 - GtkWidget *button_vbox;
45.40 - GtkWidget *label;
45.41 -
45.42 - GtkWidget *button1;
45.43 - GtkWidget *button2;
45.44 - GtkWidget *button3;
45.45 -
45.46 - gint source_id;
45.47 -} MMythUiCommon;
45.48 -
45.49 -MMythUiCommon *mmyth_uicommon_new (GtkWidget * main_widget,
45.50 - const gchar * label1, const gchar * label2,
45.51 - const gchar * label3);
45.52 -void mmyth_uicommon_free (MMythUiCommon *ui_common);
45.53 -
45.54 -#endif /* MMYTH_UICOMMON_H_ */
46.1 --- a/gmyth/src/gui/mmyth_uisettings.c Wed Sep 27 00:08:03 2006 +0100
46.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
46.3 @@ -1,169 +0,0 @@
46.4 -#include<gtk/gtk.h>
46.5 -#include<glib.h>
46.6 -#include <sys/types.h>
46.7 -#include <sys/stat.h>
46.8 -#include <unistd.h>
46.9 -#include <string.h>
46.10 -#include <stdio.h>
46.11 -#include <stdlib.h>
46.12 -
46.13 -#include "mmyth_uisettings.h"
46.14 -
46.15 -#include "gmyth_context.h"
46.16 -
46.17 -static GtkWidget *settings_dialog;
46.18 -static GtkWidget *entry_hostname;
46.19 -static GtkWidget *entry_dbname;
46.20 -static GtkWidget *entry_username;
46.21 -static GtkWidget *entry_passwd;
46.22 -static GtkWidget *entry_port;
46.23 -
46.24 -static void settings_dialog_update_data (void);
46.25 -static GtkWidget* add_entry_to_table (GtkWidget *table, GString *init_str,
46.26 - guint pos_left, guint pos_right, guint pos_top, guint pos_bottom);
46.27 -static GtkWidget* add_label_to_table (GtkWidget *table, const gchar *str,
46.28 - guint pos_left, guint pos_right, guint pos_top, guint pos_bottom);
46.29 -
46.30 -
46.31 -gboolean
46.32 -mmyth_uisettings_run (GtkWindow *main_window)
46.33 -{
46.34 -
46.35 - GtkWidget *settings_table;
46.36 - GtkWidget *label_hostname, *label_dbname;
46.37 - GtkWidget *label_username, *label_passwd, *label_port;
46.38 -
46.39 - GMythSettings *msettings = gmyth_context_get_settings();
46.40 -
46.41 - settings_dialog = gtk_dialog_new_with_buttons ("Settings",
46.42 - main_window,
46.43 - GTK_DIALOG_DESTROY_WITH_PARENT,
46.44 - GTK_STOCK_OK,
46.45 - GTK_RESPONSE_ACCEPT,
46.46 - GTK_STOCK_CANCEL,
46.47 - GTK_RESPONSE_REJECT,
46.48 - NULL);
46.49 -
46.50 - gtk_widget_set_size_request (settings_dialog, 400, 244);
46.51 -
46.52 -/* scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
46.53 - gtk_widget_show (scrolledwindow1);
46.54 - gtk_container_add (GTK_CONTAINER (window1), scrolledwindow1);
46.55 - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
46.56 -
46.57 - viewport1 = gtk_viewport_new (NULL, NULL);
46.58 - gtk_widget_show (viewport1);
46.59 - gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);
46.60 - gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport1), GTK_SHADOW_NONE);
46.61 -*/
46.62 -
46.63 - // Creates the table and attach it to the settings dialog
46.64 - settings_table = gtk_table_new (5, 2, FALSE);
46.65 - gtk_widget_show (settings_table);
46.66 - gtk_box_pack_start (GTK_BOX (GTK_DIALOG(settings_dialog)->vbox), settings_table, FALSE, TRUE, 0);
46.67 - gtk_container_set_border_width (GTK_CONTAINER (settings_table), 3);
46.68 - gtk_table_set_row_spacings (GTK_TABLE (settings_table), 5);
46.69 - gtk_table_set_col_spacings (GTK_TABLE (settings_table), 10);
46.70 -
46.71 - label_hostname = add_label_to_table (settings_table, "Host Name:", 0, 1, 0, 1);
46.72 - label_dbname = add_label_to_table (settings_table, "Database Name:", 0, 1, 1, 2);
46.73 - label_username = add_label_to_table (settings_table, "Username:", 0, 1, 2, 3);
46.74 - label_passwd = add_label_to_table (settings_table, "Password:", 0, 1, 3, 4);
46.75 - label_port = add_label_to_table (settings_table, "Server port:", 0, 1, 4, 5);
46.76 -
46.77 - entry_hostname = add_entry_to_table (settings_table,
46.78 - gmyth_settings_get_backend_hostname (msettings),
46.79 - 1, 2, 0, 1);
46.80 - entry_dbname = add_entry_to_table (settings_table,
46.81 - gmyth_settings_get_dbname (msettings),
46.82 - 1, 2, 1, 2 );
46.83 - entry_username = add_entry_to_table (settings_table,
46.84 - gmyth_settings_get_username (msettings),
46.85 - 1, 2, 2, 3 );
46.86 - entry_passwd = add_entry_to_table (settings_table,
46.87 - gmyth_settings_get_password (msettings),
46.88 - 1, 2, 3, 4 );
46.89 -
46.90 - GString *str_port = g_string_new ("");
46.91 - g_string_printf (str_port, "%d",
46.92 - gmyth_settings_get_backend_port (msettings));
46.93 - entry_port = add_entry_to_table (settings_table, str_port,
46.94 - 1, 2, 4, 5 );
46.95 - g_string_free (str_port, TRUE);
46.96 -
46.97 - if (gtk_dialog_run (GTK_DIALOG (settings_dialog)) == GTK_RESPONSE_ACCEPT) {
46.98 - settings_dialog_update_data ();
46.99 - gtk_widget_destroy (settings_dialog);
46.100 - return TRUE;
46.101 - }
46.102 -
46.103 - gtk_widget_destroy (settings_dialog);
46.104 -
46.105 - return FALSE;
46.106 -
46.107 -}
46.108 -
46.109 -static GtkWidget*
46.110 -add_label_to_table (GtkWidget *table, const gchar *str, guint pos_left, guint pos_right,
46.111 - guint pos_top, guint pos_bottom )
46.112 -{
46.113 - GtkWidget *tmp_label = gtk_label_new (str);
46.114 -
46.115 - gtk_widget_show (tmp_label);
46.116 - gtk_table_attach (GTK_TABLE (table), tmp_label,
46.117 - pos_left, pos_right, pos_top, pos_bottom,
46.118 - (GtkAttachOptions) (GTK_FILL),
46.119 - (GtkAttachOptions) (0), 0, 0);
46.120 - gtk_misc_set_alignment (GTK_MISC (tmp_label), 0, 0.5);
46.121 -
46.122 - return tmp_label;
46.123 -}
46.124 -
46.125 -static GtkWidget*
46.126 -add_entry_to_table (GtkWidget *table, GString *init_str, guint pos_left, guint pos_right,
46.127 - guint pos_top, guint pos_bottom)
46.128 -{
46.129 - GtkWidget *tmp_entry = gtk_entry_new ();
46.130 - gtk_widget_show (tmp_entry);
46.131 - gtk_table_attach (GTK_TABLE (table), tmp_entry,
46.132 - pos_left, pos_right, pos_top, pos_bottom,
46.133 - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
46.134 - (GtkAttachOptions) (0), 0, 0);
46.135 - if (init_str)
46.136 - gtk_entry_set_text (GTK_ENTRY (tmp_entry), (init_str->str));
46.137 -
46.138 - //gtk_entry_set_invisible_char (GTK_ENTRY (entry_port), 9679);
46.139 -
46.140 - return tmp_entry;
46.141 -}
46.142 -
46.143 -static void
46.144 -settings_dialog_update_data (void)
46.145 -{
46.146 - GString *tmp_entry_text;
46.147 - GMythSettings *msettings = gmyth_context_get_settings();
46.148 -
46.149 - if (!msettings) {
46.150 - g_warning ("[%s] Could not get GMythSettings instance from context\n", __FUNCTION__);
46.151 - return;
46.152 - }
46.153 -
46.154 - tmp_entry_text = g_string_new("");
46.155 - g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_hostname)));
46.156 - gmyth_settings_set_backend_hostname(msettings, tmp_entry_text);
46.157 -
46.158 - g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_dbname)));
46.159 - gmyth_settings_set_dbname(msettings, tmp_entry_text);
46.160 -
46.161 - g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_username)));
46.162 - gmyth_settings_set_username(msettings, tmp_entry_text);
46.163 -
46.164 - g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_passwd)));
46.165 - gmyth_settings_set_password(msettings, tmp_entry_text);
46.166 -
46.167 - g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_port)));
46.168 - gmyth_settings_set_backend_port(msettings, atoi(tmp_entry_text->str));
46.169 -
46.170 - gmyth_settings_save (msettings);
46.171 -
46.172 -}
47.1 --- a/gmyth/src/gui/mmyth_uisettings.h Wed Sep 27 00:08:03 2006 +0100
47.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
47.3 @@ -1,6 +0,0 @@
47.4 -#ifndef MMYTH_SETTINGS_H_
47.5 -#define MMYTH_SETTINGS_H_
47.6 -
47.7 -gboolean mmyth_uisettings_run (GtkWindow *main_window);
47.8 -
47.9 -#endif /*MMYTH_SETTINGS_H_*/
48.1 --- a/gmyth/src/gui/mmyth_videoplayer.c Wed Sep 27 00:08:03 2006 +0100
48.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
48.3 @@ -1,369 +0,0 @@
48.4 -
48.5 -#include <gst/gst.h>
48.6 -#include <gtk/gtk.h>
48.7 -#include <gdk/gdkx.h>
48.8 -#include <gst/interfaces/xoverlay.h>
48.9 -#include <unistd.h>
48.10 -
48.11 -#include "mmyth_ui.h"
48.12 -#include "mmyth_videoplayer.h"
48.13 -#include "mmyth_sdpreader.h"
48.14 -
48.15 -#include "esg_database.h"
48.16 -
48.17 -#include "ipd_demux.h"
48.18 -#include "ipd_network.h"
48.19 -
48.20 -#ifdef INDT_IP_DECAPSULATOR
48.21 -#include <sys/types.h>
48.22 -#include <signal.h>
48.23 -#endif
48.24 -
48.25 -/* Global flag/semaphore to control IP decapsulator threads */
48.26 -gboolean state_keep_running = 0;
48.27 -
48.28 -
48.29 -typedef struct _GstPlayerWindowStateChange
48.30 -{
48.31 - GstElement *play;
48.32 - GstState old_state, new_state;
48.33 - MMythUi *mmyth_ui;
48.34 -} GstPlayerWindowStateChange;
48.35 -
48.36 -typedef struct _GstPlayerWindowTagFound
48.37 -{
48.38 - GstElement *play;
48.39 - GstTagList *taglist;
48.40 - MMythUi *mmyth_ui;
48.41 -} GstPlayerWindowTagFound;
48.42 -
48.43 -
48.44 -GstElement *gst_pipeline, *gst_decoder, *gst_videosink;
48.45 -
48.46 -static gboolean idle_state (gpointer data);
48.47 -
48.48 -static gboolean
48.49 -bus_call (GstBus * bus, GstMessage * msg, gpointer data)
48.50 -{
48.51 - MMythUi *mmyth_ui = (MMythUi *) data;
48.52 - GMainLoop *loop = mmyth_ui->loop;
48.53 -
48.54 - switch (GST_MESSAGE_TYPE (msg)) {
48.55 - case GST_MESSAGE_EOS:
48.56 -
48.57 - if (mmyth_ui->idle_id != 0) {
48.58 - g_source_remove (mmyth_ui->idle_id);
48.59 - mmyth_ui->idle_id = 0;
48.60 - }
48.61 -
48.62 - //g_idle_add ((GSourceFunc) idle_eos, data);
48.63 - gst_element_set_state (GST_ELEMENT (GST_MESSAGE_SRC (msg)),
48.64 - GST_STATE_READY);
48.65 - break;
48.66 - case GST_MESSAGE_ERROR:{
48.67 - gchar *debug;
48.68 - GError *err;
48.69 -
48.70 - gst_message_parse_error (msg, &err, &debug);
48.71 - g_free (debug);
48.72 -
48.73 - printf ("Error: %s\n", err->message);
48.74 - g_error_free (err);
48.75 -
48.76 - g_main_loop_quit (loop);
48.77 - }
48.78 - break;
48.79 - case GST_MESSAGE_STATE_CHANGED:{
48.80 - GstState oldstate;
48.81 - GstState newstate;
48.82 - GstState pending;
48.83 - GstPlayerWindowStateChange *st =
48.84 - g_new (GstPlayerWindowStateChange, 1);
48.85 -
48.86 - gst_message_parse_state_changed (msg,
48.87 - &oldstate,
48.88 - &newstate, &pending);
48.89 -
48.90 - st->play = mmyth_ui->play;
48.91 - gst_object_ref (GST_OBJECT (mmyth_ui->play));
48.92 - st->old_state = oldstate;
48.93 - st->new_state = newstate;
48.94 -
48.95 - st->mmyth_ui = mmyth_ui;
48.96 -
48.97 - /* State debug messages */
48.98 - printf ("oldstate = %s, newstate = %s, pendingstate = %s\n",
48.99 - gst_element_state_get_name (oldstate),
48.100 - gst_element_state_get_name (newstate),
48.101 - gst_element_state_get_name (pending));
48.102 -
48.103 - g_idle_add ((GSourceFunc) idle_state, st);
48.104 -
48.105 - }
48.106 - break;
48.107 - default:
48.108 - printf (gst_message_type_get_name (GST_MESSAGE_TYPE (msg)));
48.109 - printf ("\n");
48.110 - break;
48.111 - }
48.112 -
48.113 - return TRUE;
48.114 -}
48.115 -
48.116 -
48.117 -static gboolean
48.118 -cb_iterate (gpointer data)
48.119 -{
48.120 - MMythUi *mmyth_ui = (MMythUi *) data;
48.121 - //gboolean res;
48.122 -
48.123 - g_main_loop_run (mmyth_ui->loop);
48.124 -/*
48.125 - if (!GST_FLAG_IS_SET (mmyth_ui->play, GST_BIN_SELF_SCHEDULABLE)) {
48.126 - res = gst_bin_iterate (GST_BIN (mmyth_ui->play));
48.127 - } else {
48.128 - g_usleep (100);
48.129 - res = (gst_element_get_state (mmyth_ui->play) == GST_STATE_PLAYING);
48.130 - }
48.131 -
48.132 - if (!res)
48.133 - mmyth_ui->idle_id = 0;
48.134 -
48.135 - return res;
48.136 -*/
48.137 - return FALSE;
48.138 -
48.139 -}
48.140 -
48.141 -static gboolean
48.142 -idle_state (gpointer data)
48.143 -{
48.144 - GstPlayerWindowStateChange *st = data;
48.145 -
48.146 - if (st->old_state == GST_STATE_PLAYING) {
48.147 - if (st->mmyth_ui->idle_id != 0) {
48.148 - g_source_remove (st->mmyth_ui->idle_id);
48.149 - st->mmyth_ui->idle_id = 0;
48.150 - }
48.151 - }
48.152 - else if (st->new_state == GST_STATE_PLAYING) {
48.153 - if (st->mmyth_ui->idle_id != 0)
48.154 - g_source_remove (st->mmyth_ui->idle_id);
48.155 -
48.156 - st->mmyth_ui->idle_id = g_idle_add (cb_iterate, st->mmyth_ui);
48.157 - }
48.158 -
48.159 - /* new movie loaded? */
48.160 - if (st->old_state == GST_STATE_READY && st->new_state > GST_STATE_READY) {
48.161 -
48.162 - /* gboolean have_video = FALSE; */
48.163 -
48.164 - gtk_widget_show (st->mmyth_ui->videow);
48.165 -
48.166 - gtk_window_resize (GTK_WINDOW (st->mmyth_ui->main_window), 1, 1);
48.167 -
48.168 - }
48.169 -
48.170 - /* discarded movie? */
48.171 - if (st->old_state > GST_STATE_READY && st->new_state == GST_STATE_READY) {
48.172 -
48.173 - if (st->mmyth_ui->tagcache) {
48.174 - gst_tag_list_free (st->mmyth_ui->tagcache);
48.175 - st->mmyth_ui->tagcache = NULL;
48.176 - }
48.177 - }
48.178 -
48.179 - gst_object_unref (GST_OBJECT (st->play));
48.180 - //g_object_unref (G_OBJECT (st->win));
48.181 - g_free (st);
48.182 -
48.183 - /* once */
48.184 - return FALSE;
48.185 -}
48.186 -
48.187 -
48.188 -
48.189 -static gboolean
48.190 -expose (GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
48.191 -{
48.192 - MMythUi *mmyth_ui = (MMythUi *) user_data;
48.193 -
48.194 - gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (mmyth_ui->videosink),
48.195 - GDK_WINDOW_XWINDOW (mmyth_ui->videow->
48.196 - window));
48.197 - return TRUE;
48.198 -}
48.199 -
48.200 -
48.201 -void
48.202 -mmyth_player_init (MMythUi * mmyth_ui)
48.203 -{
48.204 - GstElement *play;
48.205 - GstElement *source, *parser, *decoder, *videosink;
48.206 -
48.207 - play = gst_pipeline_new ("video-player");
48.208 - source = gst_element_factory_make ("udpsrc", "file-source");
48.209 - parser = gst_element_factory_make ("rtph263pdepay", "rtp-demux");
48.210 - decoder = gst_element_factory_make ("ffdec_h263", "mpeg-decoder");
48.211 - videosink = gst_element_factory_make ("xvimagesink", "image-output");
48.212 - gst_pipeline = play;
48.213 - gst_decoder = decoder;
48.214 - gst_videosink = videosink;
48.215 -
48.216 - if (!(gst_pipeline && source && parser && decoder && videosink)) {
48.217 - /* FIXME: hanlde the error correctly */
48.218 - /* video_alignment is not being created (below)
48.219 - and is causing problems to the ui */
48.220 - g_print ("GstElement creation error!\n");
48.221 - return;
48.222 - }
48.223 -
48.224 - g_object_set (G_OBJECT (videosink), "sync", FALSE, NULL);
48.225 -
48.226 - gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (gst_pipeline)),
48.227 - bus_call, mmyth_ui);
48.228 -
48.229 - gst_bin_add_many (GST_BIN (gst_pipeline), source, parser, decoder,
48.230 - videosink, NULL);
48.231 -
48.232 - {
48.233 - GstCaps *rtpcaps = gst_caps_new_simple ("application/x-rtp", NULL);
48.234 - gst_element_link_filtered(source, parser, rtpcaps);
48.235 - }
48.236 -
48.237 - gst_element_link_many (/*source,*/ parser, decoder, videosink, NULL);
48.238 -
48.239 - /* actual window */
48.240 - mmyth_ui->play = play;
48.241 - mmyth_ui->videosink = videosink;
48.242 - mmyth_ui->udpsource = source;
48.243 -
48.244 - g_object_ref (mmyth_ui->play);
48.245 - g_object_ref (mmyth_ui->videosink);
48.246 -
48.247 - /* video widget */
48.248 - //mmyth_ui->videow = gst_player_video_new (videosink, play);
48.249 - mmyth_ui->videow = gtk_drawing_area_new ();
48.250 - gtk_widget_set_size_request (mmyth_ui->videow, 300, 240);
48.251 -
48.252 - mmyth_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
48.253 -
48.254 -
48.255 - mmyth_ui->video_alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
48.256 - gtk_widget_hide (mmyth_ui->video_alignment);
48.257 -
48.258 - gtk_container_add (GTK_CONTAINER (mmyth_ui->video_alignment),
48.259 - mmyth_ui->videow);
48.260 -
48.261 - g_signal_connect (mmyth_ui->videow, "expose-event", G_CALLBACK (expose),
48.262 - mmyth_ui);
48.263 - //g_signal_connect(mmyth_ui->videow, "size_request", G_CALLBACK(cb_preferred_video_size), mmyth_ui);
48.264 -
48.265 -
48.266 - g_object_ref (mmyth_ui->videow);
48.267 - g_object_ref (mmyth_ui->video_alignment);
48.268 -
48.269 - //gnome_app_set_contents (app, videow);
48.270 - //gtk_widget_show (mmyth_ui->videow);
48.271 -
48.272 -//fail:
48.273 -// gst_object_unref (GST_OBJECT (play));
48.274 -// return NULL;
48.275 -
48.276 -}
48.277 -
48.278 -void
48.279 -mmyth_player_stop (MMythUi * mmyth_ui)
48.280 -{
48.281 - gst_element_set_state (mmyth_ui->play, GST_STATE_NULL);
48.282 -
48.283 - if(mmyth_ui->videow != NULL)
48.284 - gtk_widget_hide (mmyth_ui->videow);
48.285 -
48.286 - /* Disable IP Decapsulator playing threads */
48.287 - state_keep_running = FALSE;
48.288 -
48.289 -}
48.290 -
48.291 -static gboolean
48.292 -idle_play (gpointer data)
48.293 -{
48.294 - MMythUi *mmyth_ui = (MMythUi *) data;
48.295 -
48.296 - sleep (2);
48.297 -
48.298 - gst_element_set_state (mmyth_ui->play, GST_STATE_PLAYING);
48.299 -
48.300 - return FALSE;
48.301 -}
48.302 -
48.303 -
48.304 -/* Run IP decapsulator play function in a new thread. The thread is finished setting the
48.305 - * semaphore "state_keep_running" to FALSE*/
48.306 -gpointer
48.307 -run_ipd(gpointer data)
48.308 -{
48.309 - GString *ip_addr = (GString*) data;
48.310 -
48.311 - state_keep_running = TRUE;
48.312 -
48.313 - printf("Inside thread\n");
48.314 -
48.315 - ipd_mpe_play_section (ip_addr->str, &state_keep_running);
48.316 -
48.317 - return 0;
48.318 -}
48.319 -
48.320 -void
48.321 -mmyth_play_channel (MMythUi * mmyth_ui, gint service_number)
48.322 -{
48.323 - ESGDatabase *esg_db;
48.324 - DVBHService *service;
48.325 - SDPData sdp_data;
48.326 - GString *service_ip_addr;
48.327 -
48.328 - /* First verifies if there is a tuned network */
48.329 - if ( !ipd_network_is_tuned() ) {
48.330 - /* FIXME: show alert and handle this error */
48.331 - g_warning ("Play not possible, network not tuned");
48.332 - return;
48.333 - }
48.334 -
48.335 - esg_db = esg_database_get_instance();
48.336 - /* Gets the service structure */
48.337 - service = (DVBHService *) esg_database_get_service_from_number
48.338 - (esg_db, service_number);
48.339 -
48.340 - /* Verifies if sdp fragment exists to this service */
48.341 - if ( service->sdp_file == NULL ) {
48.342 - /* FIXME: Implement error handling */
48.343 - g_warning ("SDP fragment not available to access service");
48.344 - return;
48.345 - }
48.346 -
48.347 - /* Parses the sdp to get ipv6 address and port */
48.348 - mmyth_sdp_parse_file (service->sdp_file->str, &sdp_data);
48.349 -
48.350 - /* Sets the gstreamer properties acording to the service access address */
48.351 - /* FIXME: Develop sdp_bin in gstreamer to give sdp file as pipeline config */
48.352 - g_object_set (G_OBJECT (mmyth_ui->udpsource), "multicast_group",
48.353 - sdp_data.ip_addr->str, NULL);
48.354 - g_object_set (G_OBJECT (mmyth_ui->udpsource), "port", sdp_data.video_port, NULL);
48.355 -
48.356 - /* Shows the video widget on screen */
48.357 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);
48.358 -
48.359 - gtk_widget_show (mmyth_ui->videow);
48.360 - gtk_widget_queue_draw (mmyth_ui->videow);
48.361 -
48.362 -#ifdef INDT_IP_DECAPSULATOR
48.363 - /* Will be dealocated in run_ipd */
48.364 - service_ip_addr = g_string_new (sdp_data.ip_addr->str);
48.365 -
48.366 - /* Requests the IP decapsulator to play the channel stream*/
48.367 - g_thread_create (run_ipd, (gpointer) service_ip_addr, FALSE, NULL);
48.368 -#endif
48.369 -
48.370 - //gst_element_set_state (mmyth_ui->play, GST_STATE_PLAYING);
48.371 - g_idle_add (idle_play, mmyth_ui);
48.372 -}
49.1 --- a/gmyth/src/gui/mmyth_videoplayer.h Wed Sep 27 00:08:03 2006 +0100
49.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
49.3 @@ -1,12 +0,0 @@
49.4 -#ifndef MMYTH_VIDEOPLAYER_H_
49.5 -#define MMYTH_VIDEOPLAYER_H_
49.6 -
49.7 -#include "mmyth_ui.h"
49.8 -
49.9 -void mmyth_player_init (MMythUi * mmyth_ui);
49.10 -void mmyth_player_stop (MMythUi * mmyth_ui);
49.11 -
49.12 -void mmyth_play_channel (MMythUi * mmyth_ui, gint service_id);
49.13 -
49.14 -
49.15 -#endif /* MMYTH_VIDEOPLAYER_H_ */
50.1 --- a/gmyth/src/libgmyth/gmyth_common.c Wed Sep 27 00:08:03 2006 +0100
50.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
50.3 @@ -1,85 +0,0 @@
50.4 -/**
50.5 - * GMyth Library
50.6 - *
50.7 - * @file gmyth/gmyth_common.c
50.8 - *
50.9 - * @brief <p> This file contains basic common functions for the gmyth library.
50.10 - *
50.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
50.12 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
50.13 - *
50.14 - *//*
50.15 - *
50.16 - * This program is free software; you can redistribute it and/or modify
50.17 - * it under the terms of the GNU Lesser General Public License as published by
50.18 - * the Free Software Foundation; either version 2 of the License, or
50.19 - * (at your option) any later version.
50.20 - *
50.21 - * This program is distributed in the hope that it will be useful,
50.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
50.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50.24 - * GNU General Public License for more details.
50.25 - *
50.26 - * You should have received a copy of the GNU Lesser General Public License
50.27 - * along with this program; if not, write to the Free Software
50.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
50.29 - */
50.30 -
50.31 -#include "gmyth_common.h"
50.32 -
50.33 -static void free_channel_data(gpointer data, gpointer user_data);
50.34 -static void free_program_data(gpointer data, gpointer user_data);
50.35 -
50.36 -/** Frees the memory allocated to the GMythChannelInfo objects inside list.
50.37 - * The list memory is also released by g_list_free(). If LIST is NULL it
50.38 - * simply returns.
50.39 - *
50.40 - * @param list the GList containing a list of GMythChannelInfo to free.
50.41 - */
50.42 -void
50.43 -gmyth_free_channel_list(GList *list)
50.44 -{
50.45 - if (list == NULL) {
50.46 - g_warning ("%s received null GList as parameter", __FUNCTION__);
50.47 - return;
50.48 - }
50.49 -
50.50 - g_list_foreach (list, free_channel_data, NULL);
50.51 -
50.52 - g_list_free (list);
50.53 -}
50.54 -
50.55 -/** Frees the memory allocated to the GMythProgramInfo objects inside list.
50.56 - * The list memory is also released by g_list_free(). If list is NULL it
50.57 - * simply returns.
50.58 - *
50.59 - * @param list the GList containing a list of GMythProgramInfo to free.
50.60 - */
50.61 -void
50.62 -gmyth_free_program_list(GList *list)
50.63 -{
50.64 - if (list == NULL) {
50.65 - g_warning ("%s received null GList as parameter", __FUNCTION__);
50.66 - return;
50.67 - }
50.68 -
50.69 - g_list_foreach (list, free_program_data, NULL);
50.70 -
50.71 - g_list_free (list);
50.72 -}
50.73 -
50.74 -
50.75 -static void
50.76 -free_channel_data(gpointer data, gpointer user_data)
50.77 -{
50.78 - if(data)
50.79 - g_free((GMythChannelInfo*) data);
50.80 -}
50.81 -
50.82 -static void
50.83 -free_program_data(gpointer data, gpointer user_data)
50.84 -{
50.85 - if(data)
50.86 - g_free((GMythProgramInfo*) data);
50.87 -}
50.88 -
51.1 --- a/gmyth/src/libgmyth/gmyth_common.h Wed Sep 27 00:08:03 2006 +0100
51.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
51.3 @@ -1,159 +0,0 @@
51.4 -/**
51.5 - * GMyth Library
51.6 - *
51.7 - * @file gmyth/gmyth_common.h
51.8 - *
51.9 - * @brief <p> This file contains basic common functions for the gmyth library.
51.10 - *
51.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
51.12 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
51.13 - *
51.14 - *//*
51.15 - *
51.16 - * This program is free software; you can redistribute it and/or modify
51.17 - * it under the terms of the GNU Lesser General Public License as published by
51.18 - * the Free Software Foundation; either version 2 of the License, or
51.19 - * (at your option) any later version.
51.20 - *
51.21 - * This program is distributed in the hope that it will be useful,
51.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
51.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51.24 - * GNU General Public License for more details.
51.25 - *
51.26 - * You should have received a copy of the GNU Lesser General Public License
51.27 - * along with this program; if not, write to the Free Software
51.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
51.29 - */
51.30 -
51.31 -#ifndef GMYTH_COMMON_H_
51.32 -#define GMYTH_COMMON_H_
51.33 -
51.34 -#include <glib.h>
51.35 -#include <time.h>
51.36 -
51.37 -G_BEGIN_DECLS
51.38 -
51.39 -/**
51.40 - * The GMythChannelInfo structure represents the channel information
51.41 - * stored in the backend database.
51.42 - */
51.43 -typedef struct {
51.44 - /** The channel ID in backend database */
51.45 - int channel_ID;
51.46 -
51.47 - /** The channel name in backend database */
51.48 - GString *channel_name;
51.49 -
51.50 -} GMythChannelInfo;
51.51 -
51.52 -
51.53 -/**
51.54 - * The GMythProgramInfo structure represents a program information
51.55 - * stored in the database. It could be a program from the EPG data,
51.56 - * a program scheduled to be recorded, or a program already recorded.
51.57 - */
51.58 -typedef struct {
51.59 -
51.60 - /** The channel unique ID. */
51.61 - GString *chanid;
51.62 -
51.63 - /** The program start time. */
51.64 - time_t startts;
51.65 - /** The program end time. */
51.66 - time_t endts;
51.67 - /** The recording schedule start time. */
51.68 - time_t recstartts;
51.69 - /** The recording schedule end time */
51.70 - time_t recendts;
51.71 -
51.72 - /** The program title. */
51.73 - GString *title;
51.74 - /** The program subtitle. */
51.75 - GString *subtitle;
51.76 - /** The program description. */
51.77 - GString *description;
51.78 - /** The program category. */
51.79 - GString *category;
51.80 -
51.81 - GString *chanstr;
51.82 - GString *chansign;
51.83 - /** The associated channel name. */
51.84 - GString *channame;
51.85 - int chancommfree;
51.86 - GString *chanOutputFilters;
51.87 -
51.88 - GString *seriesid;
51.89 - /** The program unique id. */
51.90 - GString *programid;
51.91 - GString * catType;
51.92 -
51.93 - GString * sortTitle;
51.94 -
51.95 - /** A flag informing if the program has video or not. */
51.96 - gboolean isVideo;
51.97 - int lenMins;
51.98 -
51.99 - GString *year;
51.100 - double stars;
51.101 - int repeat;
51.102 -
51.103 - time_t originalAirDate;
51.104 - time_t lastmodified;
51.105 - time_t lastInUseTime;
51.106 -
51.107 - gboolean hasAirDate;
51.108 -
51.109 - int spread;
51.110 - int startCol;
51.111 -
51.112 -// enum RecStatusType recstatus;
51.113 -// enum RecStatusType oldrecstatus;
51.114 -// enum RecStatusType savedrecstatus;
51.115 - int recpriority2;
51.116 - int reactivate;
51.117 -
51.118 - int recordid;
51.119 - int parentid;
51.120 - //enum RecordingType rectype;
51.121 - //enum RecordingDupInType dupin;
51.122 - //enum RecordingDupMethodType dupmethod;
51.123 -
51.124 - /** The backend video source id associated to this program.*/
51.125 - int sourceid;
51.126 - /** the backend input id associated to this program.*/
51.127 - int inputid;
51.128 - /** The backend card id associated to this program.*/
51.129 - int cardid;
51.130 - gboolean shareable;
51.131 - gboolean duplicate;
51.132 -
51.133 - GString * schedulerid;
51.134 - int findid;
51.135 -
51.136 - int programflags;
51.137 - int transcoder;
51.138 -
51.139 - //proginfo->spread = -1;
51.140 - //proginfo->programflags = proginfo->getProgramFlags();
51.141 -
51.142 - GString *recgroup;
51.143 - GString *playgroup;
51.144 - int recpriority;
51.145 -
51.146 - /** The file size of the recorded program.*/
51.147 - long long filesize;
51.148 - /** The file name of the recorded program.*/
51.149 - GString *pathname;
51.150 - GString *hostname;
51.151 -
51.152 - /* AvailableStatusType availableStatus;*/
51.153 -
51.154 -} GMythProgramInfo;
51.155 -
51.156 -
51.157 -void gmyth_free_channel_list(GList *list);
51.158 -void gmyth_free_program_list(GList *list);
51.159 -
51.160 -G_END_DECLS
51.161 -
51.162 -#endif /* GMYTH_COMMON_H_ */
52.1 --- a/gmyth/src/libgmyth/gmyth_context.c Wed Sep 27 00:08:03 2006 +0100
52.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
52.3 @@ -1,312 +0,0 @@
52.4 -/**
52.5 - * GMyth Library
52.6 - *
52.7 - * @file gmyth/gmyth_context.c
52.8 - *
52.9 - * @brief <p> GMythContext class contains general attributes and functions
52.10 - * that express the connection state of each mythtvfrontend.
52.11 - *
52.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
52.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
52.14 - *
52.15 - *//*
52.16 - *
52.17 - * This program is free software; you can redistribute it and/or modify
52.18 - * it under the terms of the GNU Lesser General Public License as published by
52.19 - * the Free Software Foundation; either version 2 of the License, or
52.20 - * (at your option) any later version.
52.21 - *
52.22 - * This program is distributed in the hope that it will be useful,
52.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
52.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52.25 - * GNU General Public License for more details.
52.26 - *
52.27 - * You should have received a copy of the GNU Lesser General Public License
52.28 - * along with this program; if not, write to the Free Software
52.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
52.30 - */
52.31 -
52.32 -#include "gmyth_context.h"
52.33 -
52.34 -#include <arpa/inet.h>
52.35 -#include <sys/types.h>
52.36 -#include <sys/socket.h>
52.37 -#include <netdb.h>
52.38 -#include <errno.h>
52.39 -#include <stdlib.h>
52.40 -
52.41 -#include "gmyth_query.h"
52.42 -#include "gmyth_socket.h"
52.43 -
52.44 -static void gmyth_context_class_init (GMythContextClass *klass);
52.45 -static void gmyth_context_init (GMythContext *object);
52.46 -
52.47 -static void gmyth_context_dispose (GObject *object);
52.48 -static void gmyth_context_finalize (GObject *object);
52.49 -
52.50 -
52.51 -G_DEFINE_TYPE(GMythContext, gmyth_context, G_TYPE_OBJECT)
52.52 -
52.53 -static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
52.54 -
52.55 -static GMythContext *gcontext = NULL;
52.56 -
52.57 -static void
52.58 -gmyth_context_class_init (GMythContextClass *klass)
52.59 -{
52.60 - GObjectClass *gobject_class;
52.61 -
52.62 - gobject_class = (GObjectClass *) klass;
52.63 -
52.64 - gobject_class->dispose = gmyth_context_dispose;
52.65 - gobject_class->finalize = gmyth_context_finalize;
52.66 -}
52.67 -
52.68 -static void
52.69 -gmyth_context_init (GMythContext *gmyth_context)
52.70 -{
52.71 -
52.72 -}
52.73 -
52.74 -static void
52.75 -gmyth_context_dispose (GObject *object)
52.76 -{
52.77 - GMythContext *gmyth_context = GMYTH_CONTEXT(object);
52.78 -
52.79 - if ( gmyth_context->gmyth_settings != NULL ) {
52.80 - g_object_unref (gmyth_context->gmyth_settings);
52.81 - gmyth_context->gmyth_settings = NULL;
52.82 - }
52.83 -
52.84 - if ( gmyth_context->localhostname != NULL ) {
52.85 - g_string_free ( gmyth_context->localhostname, TRUE );
52.86 - gmyth_context->localhostname = NULL;
52.87 - }
52.88 -
52.89 - if (gmyth_context->server_socket != NULL) {
52.90 - g_object_unref (gmyth_context->server_socket);
52.91 - gmyth_context->server_socket = NULL;
52.92 - }
52.93 -
52.94 - G_OBJECT_CLASS (gmyth_context_parent_class)->dispose (object);
52.95 -}
52.96 -
52.97 -static void
52.98 -gmyth_context_finalize (GObject *object)
52.99 -{
52.100 - g_signal_handlers_destroy (object);
52.101 -
52.102 - G_OBJECT_CLASS (gmyth_context_parent_class)->finalize (object);
52.103 -}
52.104 -
52.105 -/** Gets the some important address translation info,
52.106 - * from the client socket that will open a connection.
52.107 - *
52.108 - * @return gint error number
52.109 - */
52.110 -static gint
52.111 -myth_context_toaddrinfo( gchar *addr, gint port, struct addrinfo **addrInfo )
52.112 -{
52.113 - struct addrinfo hints;
52.114 - gchar *portStr = g_strnfill( 32, ' ' );
52.115 - gint errorn = EADDRNOTAVAIL;
52.116 -
52.117 - memset( &hints, 0, sizeof(hints) );
52.118 - hints.ai_family = AF_INET;
52.119 - hints.ai_socktype = SOCK_STREAM;
52.120 -
52.121 - /* hints.ai_flags = AI_NUMERICHOST; */
52.122 - if ( port != -1 )
52.123 - sprintf(portStr, "%d", port);
52.124 - else
52.125 - portStr = NULL;
52.126 -
52.127 - g_debug( "[%s] Address: %s, port: %s\n", __FUNCTION__, addr, portStr );
52.128 - if ( ( errorn = getaddrinfo(addr, portStr, &hints, addrInfo) ) != 0 ) {
52.129 - g_printerr( "[%s] Socket ERROR: %s\n", __FUNCTION__, gai_strerror(errorn) );
52.130 - }
52.131 -
52.132 - return errorn;
52.133 -
52.134 -}
52.135 -
52.136 -/** Initializes the GMythContext object. It reads local system information
52.137 - * load gmyth user settings and start connection to the database.
52.138 - *
52.139 - * @return TRUE if initialization was successfull,
52.140 - * FALSE if any error happens.
52.141 - */
52.142 -gboolean
52.143 -gmyth_context_initialize ()
52.144 -{
52.145 - GString *localhost = NULL;
52.146 -
52.147 - if (gcontext == NULL) {
52.148 - gcontext = GMYTH_CONTEXT ( g_object_new (GMYTH_CONTEXT_TYPE, FALSE));
52.149 - }
52.150 -
52.151 - localhost = gmyth_socket_get_local_hostname( );
52.152 -
52.153 - if (localhost==NULL || localhost->len <=0 ) {
52.154 - g_warning ("[%s] Could not determine local hostname. Setting to 127.0.0.1", __FUNCTION__);
52.155 - gcontext->localhostname = g_string_new ("127.0.0.1");
52.156 - } else {
52.157 - gcontext->localhostname = localhost;
52.158 - }
52.159 -
52.160 - if (gcontext->gmyth_settings) {
52.161 - g_object_unref (gcontext->gmyth_settings);
52.162 - gcontext->gmyth_settings = NULL;
52.163 - }
52.164 -
52.165 - gcontext->gmyth_settings = gmyth_settings_new ();
52.166 - if (!gmyth_settings_load (gcontext->gmyth_settings)) {
52.167 - g_warning ("GMythContext: Settings file not opened!\n");
52.168 - } else {
52.169 - g_debug ("GMythContext: Settings file loaded");
52.170 - }
52.171 -
52.172 - if (gcontext->server_socket != NULL) {
52.173 - g_object_unref (gcontext->server_socket);
52.174 - gcontext->server_socket = NULL;
52.175 - }
52.176 -
52.177 - GString *server_hostname =
52.178 - gmyth_settings_get_backend_hostname(gcontext->gmyth_settings);
52.179 - int server_port = gmyth_settings_get_backend_port(gcontext->gmyth_settings);
52.180 -
52.181 - gcontext->server_socket = gmyth_socket_new ();
52.182 - if (!gmyth_socket_connect_to_backend (gcontext->server_socket,
52.183 - server_hostname->str, server_port, FALSE)) {
52.184 - g_warning ("[%s] Socket connection to backend error!", __FUNCTION__);
52.185 - g_object_unref (gcontext->server_socket);
52.186 - gcontext->server_socket = NULL;
52.187 - return FALSE;
52.188 - }
52.189 -
52.190 - return TRUE;
52.191 -}
52.192 -
52.193 -/** Formats a Mythtv protocol command based on strlist and sends it to
52.194 - * the connected backend. The backend response is overwritten into strlist.
52.195 - *
52.196 - * @param strlist the string list to be sent,
52.197 - * and on which the answer will be written.
52.198 - * @return TRUE if command was sent and an answer was received, FALSE if any
52.199 - * error happens.
52.200 - */
52.201 -gboolean
52.202 -gmyth_context_send_receive_stringlist (GMythStringList *strlist)
52.203 -{
52.204 - gint ok = -1;
52.205 -
52.206 - if (!gcontext || !(gcontext->server_socket)) {
52.207 - g_warning ("[%s] GMythContext not initialized", __FUNCTION__);
52.208 - return FALSE;
52.209 - }
52.210 -
52.211 - //g_static_mutex_lock( &mutex );
52.212 -
52.213 - ok = gmyth_socket_sendreceive_stringlist (gcontext->server_socket, strlist);
52.214 -
52.215 - //g_static_mutex_unlock( &mutex );
52.216 -
52.217 - if (!ok) {
52.218 - g_warning ("Connection to backend server lost");
52.219 - }
52.220 -
52.221 - return (ok ? TRUE : FALSE);
52.222 -}
52.223 -
52.224 -/** Gets the GMythSettings object associated to this context.
52.225 - *
52.226 - * @return The GMythSettings object currently valid or NULL if the settings
52.227 - * were not opened.
52.228 - */
52.229 -GMythSettings*
52.230 -gmyth_context_get_settings ()
52.231 -{
52.232 - if (!gcontext) {
52.233 - g_warning ("[%s] GMythContext not initialized\n", __FUNCTION__);
52.234 - return NULL;
52.235 - }
52.236 -
52.237 - return gcontext->gmyth_settings;
52.238 -}
52.239 -
52.240 -/** Gets the machine local hostname.
52.241 - *
52.242 - * @param hostname a valid GString object to be overwritten with the local
52.243 - * hostname.
52.244 - * @return true if the hostname was read, false if any error happened.
52.245 - */
52.246 -gboolean
52.247 -gmyth_context_get_local_hostname (GString *hostname)
52.248 -{
52.249 - if (!hostname) {
52.250 - g_warning ("[%s] Received null argument", __FUNCTION__);
52.251 - return FALSE;
52.252 - }
52.253 -
52.254 - g_string_assign (hostname, gcontext->localhostname->str);
52.255 -
52.256 - return TRUE;
52.257 -}
52.258 -
52.259 -/** Gets a setting information from the backend mysql database.
52.260 - *
52.261 - * @param key The setting key to be retrieved.
52.262 - * @param host the hostname associated to the desired setting.
52.263 - * @param default_value the default setting value if could not query from
52.264 - * backend database.
52.265 - * @return The setting value loaded from database, or the given default value
52.266 - * if the query fails.
52.267 - */
52.268 -GString*
52.269 -gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value)
52.270 -{
52.271 - GString *query_str;
52.272 -
52.273 - // TODO: Reuse msql query in gmyth_context
52.274 - GMythQuery *gmyth_query = gmyth_query_new ();
52.275 -
52.276 - if (gmyth_query_connect (gmyth_query)) {
52.277 - MYSQL_RES *msql_res;
52.278 - MYSQL_ROW msql_row;
52.279 -
52.280 - query_str = g_string_new ("");
52.281 - g_string_printf (query_str, "SELECT data FROM settings WHERE value = \"%s\" "
52.282 - "AND hostname = \"%s\" ;", key->str, host->str);
52.283 -
52.284 - msql_res = gmyth_query_process_statement (gmyth_query, query_str->str);
52.285 - if (msql_res) {
52.286 - msql_row = mysql_fetch_row (msql_res);
52.287 - if (msql_row != NULL) {
52.288 - return g_string_new (msql_row[0]);
52.289 - }
52.290 - }
52.291 -
52.292 - g_object_unref (gmyth_query);
52.293 - } else {
52.294 - g_warning ("Database not open while trying to load setting: %s", key->str);
52.295 - }
52.296 -
52.297 -
52.298 - return default_value;
52.299 -}
52.300 -
52.301 -/** Verify if the context is currently connected to a backend.
52.302 - *
52.303 - * @return true if connection was opened, false if not.
52.304 - */
52.305 -gboolean
52.306 -gmyth_context_check_connection ()
52.307 -{
52.308 - // FIXME: Check this based on socket states
52.309 - if (!gcontext) {
52.310 - g_warning ("[%s] GMythContext not initialized", __FUNCTION__);
52.311 - return FALSE;
52.312 - }
52.313 -
52.314 - return (gcontext->server_socket != NULL);
52.315 -}
53.1 --- a/gmyth/src/libgmyth/gmyth_context.h Wed Sep 27 00:08:03 2006 +0100
53.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
53.3 @@ -1,88 +0,0 @@
53.4 -/**
53.5 - * GMyth Library
53.6 - *
53.7 - * @file gmyth/gmyth_context.h
53.8 - *
53.9 - * @brief <p> GMythContext class contains general attributes and functions
53.10 - * that express the connection state of each mythtvfrontend.
53.11 - *
53.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
53.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
53.14 - *
53.15 - *//*
53.16 - *
53.17 - * This program is free software; you can redistribute it and/or modify
53.18 - * it under the terms of the GNU Lesser General Public License as published by
53.19 - * the Free Software Foundation; either version 2 of the License, or
53.20 - * (at your option) any later version.
53.21 - *
53.22 - * This program is distributed in the hope that it will be useful,
53.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
53.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53.25 - * GNU General Public License for more details.
53.26 - *
53.27 - * You should have received a copy of the GNU Lesser General Public License
53.28 - * along with this program; if not, write to the Free Software
53.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53.30 - */
53.31 -
53.32 -#ifndef __GMYTH_CONTEXT_H__
53.33 -#define __GMYTH_CONTEXT_H__
53.34 -
53.35 -#include <glib-object.h>
53.36 -
53.37 -#include "gmyth_settings.h"
53.38 -#include "gmyth_socket.h"
53.39 -#include "gmyth_stringlist.h"
53.40 -
53.41 -G_BEGIN_DECLS
53.42 -
53.43 -#define GMYTH_CONTEXT_TYPE (gmyth_context_get_type ())
53.44 -#define GMYTH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_CONTEXT_TYPE, GMythContext))
53.45 -#define GMYTH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_CONTEXT_TYPE, GMythContextClass))
53.46 -#define IS_GMYTH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_CONTEXT_TYPE))
53.47 -#define IS_GMYTH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_CONTEXT_TYPE))
53.48 -#define GMYTH_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_CONTEXT_TYPE, GMythContextClass))
53.49 -
53.50 -#define MYTHTV_VERSION_DEFAULT 30
53.51 -
53.52 -typedef struct _GMythContext GMythContext;
53.53 -typedef struct _GMythContextClass GMythContextClass;
53.54 -
53.55 -struct _GMythContextClass
53.56 -{
53.57 - GObjectClass parent_class;
53.58 -
53.59 - /* callbacks */
53.60 - /* no one for now */
53.61 -};
53.62 -
53.63 -struct _GMythContext
53.64 -{
53.65 - GObject parent;
53.66 -
53.67 - GMythSettings *gmyth_settings;
53.68 - GMythSocket *server_socket;
53.69 -
53.70 - GString *localhostname;
53.71 -};
53.72 -
53.73 -
53.74 -GType gmyth_context_get_type (void);
53.75 -void gmyth_context_create();
53.76 -
53.77 -gboolean gmyth_context_initialize ();
53.78 -gboolean gmyth_context_check_connection ();
53.79 -GMythSettings* gmyth_context_get_settings ();
53.80 -
53.81 -gboolean gmyth_context_send_receive_stringlist (GMythStringList *strlist);
53.82 -
53.83 -GString* gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value);
53.84 -gboolean gmyth_context_get_local_hostname (GString *hostname);
53.85 -
53.86 -GString* gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value);
53.87 -
53.88 -
53.89 -G_END_DECLS
53.90 -
53.91 -#endif /* __GMYTH_CONTEXT_H__ */
54.1 --- a/gmyth/src/libgmyth/gmyth_epg.c Wed Sep 27 00:08:03 2006 +0100
54.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
54.3 @@ -1,278 +0,0 @@
54.4 -/**
54.5 - * GMyth Library
54.6 - *
54.7 - * @file gmyth/gmyth_epg.c
54.8 - *
54.9 - * @brief <p> GMythEPG class provides access to the program and channel data
54.10 - * from the Electronic Program Guide (EPG) of the Mythtv backend.
54.11 - *
54.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
54.13 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
54.14 - *
54.15 - *//*
54.16 - *
54.17 - * This program is free software; you can redistribute it and/or modify
54.18 - * it under the terms of the GNU Lesser General Public License as published by
54.19 - * the Free Software Foundation; either version 2 of the License, or
54.20 - * (at your option) any later version.
54.21 - *
54.22 - * This program is distributed in the hope that it will be useful,
54.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
54.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54.25 - * GNU General Public License for more details.
54.26 - *
54.27 - * You should have received a copy of the GNU Lesser General Public License
54.28 - * along with this program; if not, write to the Free Software
54.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
54.30 - */
54.31 -
54.32 -#include <mysql.h>
54.33 -#include <stdlib.h>
54.34 -#include <string.h>
54.35 -#include <assert.h>
54.36 -
54.37 -#include "gmyth_epg.h"
54.38 -#include "gmyth_util.h"
54.39 -
54.40 -static void gmyth_epg_class_init (GMythEPGClass *klass);
54.41 -static void gmyth_epg_init (GMythEPG *object);
54.42 -
54.43 -static void gmyth_epg_dispose (GObject *object);
54.44 -static void gmyth_epg_finalize (GObject *object);
54.45 -
54.46 -G_DEFINE_TYPE(GMythEPG, gmyth_epg, G_TYPE_OBJECT)
54.47 -
54.48 -static void
54.49 -gmyth_epg_class_init (GMythEPGClass *klass)
54.50 -{
54.51 - GObjectClass *gobject_class;
54.52 -
54.53 - gobject_class = (GObjectClass *) klass;
54.54 -
54.55 - gobject_class->dispose = gmyth_epg_dispose;
54.56 - gobject_class->finalize = gmyth_epg_finalize;
54.57 -}
54.58 -
54.59 -static void
54.60 -gmyth_epg_init (GMythEPG *gmyth_epg)
54.61 -{
54.62 - gmyth_epg->sqlquery = gmyth_query_new ();
54.63 -}
54.64 -
54.65 -static void
54.66 -gmyth_epg_dispose (GObject *object)
54.67 -{
54.68 - //GMythEPG *gmyth_epg = GMYTH_EPG(object);
54.69 -
54.70 - G_OBJECT_CLASS (gmyth_epg_parent_class)->dispose (object);
54.71 -}
54.72 -
54.73 -static void
54.74 -gmyth_epg_finalize (GObject *object)
54.75 -{
54.76 - g_signal_handlers_destroy (object);
54.77 -
54.78 - G_OBJECT_CLASS (gmyth_epg_parent_class)->finalize (object);
54.79 -}
54.80 -
54.81 -/**
54.82 - * Creates a new instance of GMythEPG.
54.83 - *
54.84 - * @return a new instance of GMythEPG.
54.85 - */
54.86 -GMythEPG*
54.87 -gmyth_epg_new (void)
54.88 -{
54.89 - GMythEPG *epg = GMYTH_EPG (g_object_new(GMYTH_EPG_TYPE, NULL));
54.90 -
54.91 - return epg;
54.92 -}
54.93 -
54.94 -/** Connects to the Mysql database in the backend. The backend address
54.95 - * is loaded from the GMythSettings instance.
54.96 - *
54.97 - * @param gmyth_epg the GMythEPG instance to be connected.
54.98 - * @return true if connection was success, false if failed.
54.99 - */
54.100 -gboolean
54.101 -gmyth_epg_connect (GMythEPG *gmyth_epg)
54.102 -{
54.103 - assert(gmyth_epg);
54.104 -
54.105 - if (gmyth_epg->sqlquery == NULL) {
54.106 - g_warning ("[%s] GMythEPG not initialized", __FUNCTION__);
54.107 - return FALSE;
54.108 - }
54.109 -
54.110 - if (!gmyth_query_connect(gmyth_epg->sqlquery)) {
54.111 - g_warning ("[%s] Error while connecting to db", __FUNCTION__);
54.112 - return FALSE;
54.113 - }
54.114 -
54.115 - return TRUE;
54.116 -}
54.117 -
54.118 -/** Disconnects from the Mysql database in the backend.
54.119 - *
54.120 - * @param gmyth_epg the GMythEPG instance to be disconnected
54.121 - * @return true if disconnection was success, false if failed.
54.122 - */
54.123 -gboolean
54.124 -gmyth_epg_disconnect (GMythEPG *gmyth_epg)
54.125 -{
54.126 - assert(gmyth_epg);
54.127 -
54.128 - if (gmyth_epg->sqlquery != NULL) {
54.129 - g_object_unref (gmyth_epg->sqlquery);
54.130 - }
54.131 -
54.132 - return TRUE;
54.133 -}
54.134 -
54.135 -/** Retrieves the available list of channels from the backend Mysql database.
54.136 - *
54.137 - * @param gmyth_epg the GMythEPG instance.
54.138 - * @param glist_ptr the GList pointer to be filled with the loaded list address.
54.139 - * @return The amount of channels retrieved from database, or -1 if error.
54.140 - */
54.141 -gint
54.142 -gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr)
54.143 -{
54.144 - MYSQL_RES *msql_res;
54.145 -
54.146 - assert(gmyth_epg);
54.147 -
54.148 - msql_res = gmyth_query_process_statement (gmyth_epg->sqlquery,
54.149 - "SELECT chanid,name FROM channel;");
54.150 -
54.151 - (*glist_ptr) = NULL;
54.152 -
54.153 - if (msql_res == NULL) {
54.154 - g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
54.155 - return -1;
54.156 - } else {
54.157 - MYSQL_ROW row;
54.158 - GMythChannelInfo *channel_info;
54.159 -
54.160 - while ((row = mysql_fetch_row (msql_res)) != NULL){
54.161 -
54.162 - channel_info = g_new0(GMythChannelInfo, 1);
54.163 - channel_info->channel_ID = atoi (row[0]);
54.164 - channel_info->channel_name = g_string_new (row[1]);
54.165 -
54.166 - (*glist_ptr) = g_list_append ((*glist_ptr), channel_info);
54.167 - }
54.168 - }
54.169 - mysql_free_result (msql_res);
54.170 - return (!(*glist_ptr)) ? 0 : g_list_length (*glist_ptr);
54.171 -}
54.172 -
54.173 -/**
54.174 - * Retrieves the available list of channels from the backend Mysql database.
54.175 - *
54.176 - * @param gmyth_epg the GMythEPG instance.
54.177 - * @param proglist the GList pointer to be filled with the loaded list.
54.178 - * @param chan_num the channel num on which to search for program.
54.179 - * @param starttime the start time to search for programs.
54.180 - * @param endtime the end time to search for programs.
54.181 - * @return The amount of channels retrieved from database, or -1 if error.
54.182 - */
54.183 -gint
54.184 -gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
54.185 - const gint chan_num, time_t starttime, time_t endtime)
54.186 -{
54.187 - GString *startts = gmyth_util_time_to_string(starttime);
54.188 - GString *endts = gmyth_util_time_to_string(endtime);
54.189 - MYSQL_ROW row;
54.190 - GString *querystr;
54.191 -
54.192 - assert(gmyth_epg);
54.193 -
54.194 - querystr = g_string_new(
54.195 - "SELECT DISTINCT program.chanid, program.starttime, program.endtime, "
54.196 - " program.title, program.subtitle, program.description, "
54.197 - " program.category, channel.channum, channel.callsign, "
54.198 - " channel.name, program.previouslyshown, channel.commfree, "
54.199 - " channel.outputfilters, program.seriesid, program.programid, "
54.200 - " program.airdate, program.stars, program.originalairdate, "
54.201 - " program.category_type, oldrecstatus.recordid, "
54.202 - " oldrecstatus.rectype, oldrecstatus.recstatus, "
54.203 - " oldrecstatus.findid "
54.204 - "FROM program "
54.205 - "LEFT JOIN channel ON program.chanid = channel.chanid "
54.206 - "LEFT JOIN oldrecorded AS oldrecstatus ON "
54.207 - " program.title = oldrecstatus.title AND "
54.208 - " channel.callsign = oldrecstatus.station AND "
54.209 - " program.starttime = oldrecstatus.starttime "
54.210 - );
54.211 -
54.212 - g_string_append_printf (querystr,
54.213 - "WHERE program.chanid = %d "
54.214 - " AND program.endtime >= '%s' "
54.215 - " AND program.starttime <= '%s' "
54.216 - " AND program.manualid = 0 ",
54.217 - chan_num, startts->str, endts->str);
54.218 -
54.219 - if (!g_strrstr(querystr->str, " GROUP BY "))
54.220 - querystr = g_string_append(querystr,
54.221 - " GROUP BY program.starttime, channel.channum, "
54.222 - " channel.callsign, program.title ");
54.223 -
54.224 - if (!g_strrstr(querystr->str, " LIMIT "))
54.225 - querystr = g_string_append(querystr, " LIMIT 1000 ");
54.226 -
54.227 - MYSQL_RES *res_set =
54.228 - gmyth_query_process_statement(gmyth_epg->sqlquery, querystr->str);
54.229 -
54.230 - if (res_set == NULL) {
54.231 - g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
54.232 - return -1;
54.233 - }
54.234 -
54.235 - (*proglist) = NULL;
54.236 - while ((row = mysql_fetch_row (res_set)) != NULL) {
54.237 -
54.238 - GMythProgramInfo *p = g_new0 (GMythProgramInfo, 1);
54.239 - p->chanid = g_string_new (row[0]);
54.240 -
54.241 - p->startts = gmyth_util_string_to_time (g_string_new (row[1]));
54.242 - p->endts = gmyth_util_string_to_time (g_string_new (row[2]));
54.243 -
54.244 - p->recstartts = p->startts;
54.245 - p->recendts = p->endts;
54.246 - p->lastmodified = p->startts;
54.247 -
54.248 - p->title = g_string_new (row[3]);
54.249 - p->subtitle = g_string_new (row[4]);
54.250 - p->description = g_string_new (row[5]);
54.251 - p->category = g_string_new (row[6]);
54.252 - p->chanstr = g_string_new (row[7]);
54.253 - p->chansign = g_string_new (row[8]);
54.254 - p->channame = g_string_new (row[9]);
54.255 - p->repeat = atoi(row[10]);
54.256 - p->chancommfree = atoi(row[11]);
54.257 - p->chanOutputFilters = g_string_new (row[12]);
54.258 - p->seriesid = g_string_new (row[13]);
54.259 - p->programid = g_string_new (row[14]);
54.260 - p->year = g_string_new (row[15]);
54.261 - p->stars = atof(row[16]);
54.262 -
54.263 - if (!row[17] || !strcmp(row[17], "")) {
54.264 - p->originalAirDate = 0;
54.265 - p->hasAirDate = FALSE;
54.266 - } else {
54.267 - p->originalAirDate = gmyth_util_string_to_time (g_string_new (row[17]));
54.268 - p->hasAirDate = TRUE;
54.269 - }
54.270 -
54.271 - p->catType = g_string_new (row[18]);
54.272 -
54.273 - *proglist = g_list_append((*proglist), p);
54.274 - }
54.275 -
54.276 - /* deallocate */
54.277 - mysql_free_result (res_set);
54.278 - g_string_free(querystr, TRUE);
54.279 -
54.280 - return TRUE;
54.281 -}
55.1 --- a/gmyth/src/libgmyth/gmyth_epg.h Wed Sep 27 00:08:03 2006 +0100
55.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
55.3 @@ -1,75 +0,0 @@
55.4 -/**
55.5 - * GMyth Library
55.6 - *
55.7 - * @file gmyth/gmyth_epg.h
55.8 - *
55.9 - * @brief <p> GMythEPG class provides access to the program and channel data
55.10 - * from the Electronic Program Guide (EPG) of the Mythtv backend.
55.11 - *
55.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
55.13 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
55.14 - *
55.15 - *//*
55.16 - *
55.17 - * This program is free software; you can redistribute it and/or modify
55.18 - * it under the terms of the GNU Lesser General Public License as published by
55.19 - * the Free Software Foundation; either version 2 of the License, or
55.20 - * (at your option) any later version.
55.21 - *
55.22 - * This program is distributed in the hope that it will be useful,
55.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
55.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55.25 - * GNU General Public License for more details.
55.26 - *
55.27 - * You should have received a copy of the GNU Lesser General Public License
55.28 - * along with this program; if not, write to the Free Software
55.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
55.30 - */
55.31 -
55.32 -#ifndef GMYTH_EPG_H_
55.33 -#define GMYTH_EPG_H_
55.34 -
55.35 -#include <glib-object.h>
55.36 -
55.37 -#include "gmyth_query.h"
55.38 -#include "gmyth_common.h"
55.39 -
55.40 -G_BEGIN_DECLS
55.41 -
55.42 -#define GMYTH_EPG_TYPE (gmyth_epg_get_type ())
55.43 -#define GMYTH_EPG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE, GMythEPG))
55.44 -#define GMYTH_EPG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE, GMythEPGClass))
55.45 -#define IS_GMYTH_EPG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE))
55.46 -#define IS_GMYTH_EPG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE))
55.47 -#define GMYTH_EPG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_EPG_TYPE, GMythEPGClass))
55.48 -
55.49 -typedef struct _GMythEPG GMythEPG;
55.50 -typedef struct _GMythEPGClass GMythEPGClass;
55.51 -
55.52 -struct _GMythEPGClass
55.53 -{
55.54 - GObjectClass parent_class;
55.55 -
55.56 - /* callbacks */
55.57 - /* no one for now */
55.58 -};
55.59 -
55.60 -struct _GMythEPG
55.61 -{
55.62 - GObject parent;
55.63 -
55.64 - GMythQuery *sqlquery;
55.65 -};
55.66 -
55.67 -GType gmyth_epg_get_type (void);
55.68 -
55.69 -GMythEPG* gmyth_epg_new (void);
55.70 -
55.71 -gboolean gmyth_epg_connect (GMythEPG *gmyth_epg);
55.72 -gboolean gmyth_epg_disconnect (GMythEPG *gmyth_epg);
55.73 -
55.74 -gint gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr);
55.75 -gint gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
55.76 - const gint chanNum, time_t starttime, time_t endtime);
55.77 -
55.78 -#endif /*GMYTH_EPG_H_*/
56.1 --- a/gmyth/src/libgmyth/gmyth_query.c Wed Sep 27 00:08:03 2006 +0100
56.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
56.3 @@ -1,221 +0,0 @@
56.4 -/**
56.5 - * GMyth Library
56.6 - *
56.7 - * @file gmyth/gmyth_query.c
56.8 - *
56.9 - * @brief <p> GMythQuery class provides a wrapper for accessing
56.10 - * the libmysqlclient funtions.
56.11 - *
56.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
56.13 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
56.14 - *
56.15 - *//*
56.16 - *
56.17 - * This program is free software; you can redistribute it and/or modify
56.18 - * it under the terms of the GNU Lesser General Public License as published by
56.19 - * the Free Software Foundation; either version 2 of the License, or
56.20 - * (at your option) any later version.
56.21 - *
56.22 - * This program is distributed in the hope that it will be useful,
56.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
56.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56.25 - * GNU General Public License for more details.
56.26 - *
56.27 - * You should have received a copy of the GNU Lesser General Public License
56.28 - * along with this program; if not, write to the Free Software
56.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
56.30 - */
56.31 -
56.32 -#include <stdlib.h>
56.33 -#include <stdio.h>
56.34 -#include <assert.h>
56.35 -
56.36 -#include "gmyth_query.h"
56.37 -#include "gmyth_settings.h"
56.38 -#include "gmyth_context.h"
56.39 -
56.40 -static void gmyth_query_class_init (GMythQueryClass *klass);
56.41 -static void gmyth_query_init (GMythQuery *object);
56.42 -
56.43 -static void gmyth_query_dispose (GObject *object);
56.44 -static void gmyth_query_finalize (GObject *object);
56.45 -
56.46 -static void gmyth_query_print_error (MYSQL *conn, char *message);
56.47 -
56.48 -G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT)
56.49 -
56.50 -static void
56.51 -gmyth_query_class_init (GMythQueryClass *klass)
56.52 -{
56.53 - GObjectClass *gobject_class;
56.54 -
56.55 - gobject_class = (GObjectClass *) klass;
56.56 -
56.57 - gobject_class->dispose = gmyth_query_dispose;
56.58 - gobject_class->finalize = gmyth_query_finalize;
56.59 -}
56.60 -
56.61 -static void
56.62 -gmyth_query_init (GMythQuery *gmyth_query)
56.63 -{
56.64 - GMythSettings *gmyth_settings = gmyth_context_get_settings ();
56.65 -
56.66 - gmyth_query->opt_host_name = gmyth_settings_get_backend_hostname(gmyth_settings);
56.67 - gmyth_query->opt_user_name = gmyth_settings_get_username(gmyth_settings);
56.68 - gmyth_query->opt_password = gmyth_settings_get_password(gmyth_settings);
56.69 - gmyth_query->opt_db_name = gmyth_settings_get_dbname(gmyth_settings);
56.70 -
56.71 - /* initialize connection handler */
56.72 - gmyth_query->conn = mysql_init (NULL);
56.73 -
56.74 - if (!(gmyth_query->conn))
56.75 - g_warning ("[%s] MSQL structure not initialized", __FUNCTION__);
56.76 -
56.77 -}
56.78 -
56.79 -static void
56.80 -gmyth_query_dispose (GObject *object)
56.81 -{
56.82 - GMythQuery *gmyth_query = GMYTH_QUERY (object);
56.83 -
56.84 - /* disconnect from server */
56.85 - gmyth_query_disconnect (gmyth_query);
56.86 -
56.87 - G_OBJECT_CLASS (gmyth_query_parent_class)->dispose (object);
56.88 -}
56.89 -
56.90 -static void
56.91 -gmyth_query_finalize (GObject *object)
56.92 -{
56.93 - g_signal_handlers_destroy (object);
56.94 -
56.95 - G_OBJECT_CLASS (gmyth_query_parent_class)->finalize (object);
56.96 -}
56.97 -
56.98 -/** Creates a new instance of GMythQuery.
56.99 - *
56.100 - * @return a new instance of GMythQuery.
56.101 - */
56.102 -GMythQuery*
56.103 -gmyth_query_new ()
56.104 -{
56.105 - GMythQuery *sql_query = GMYTH_QUERY (g_object_new(GMYTH_QUERY_TYPE, NULL));
56.106 -
56.107 - return sql_query;
56.108 -}
56.109 -
56.110 -/** Connects to the Mysql database in the backend. The backend address
56.111 - * is loaded from the GMythSettings instance.
56.112 - *
56.113 - * @param gmyth_query the GMythEPG instance to be connected.
56.114 - * @return true if connection was success, false if failed.
56.115 - */
56.116 -gboolean
56.117 -gmyth_query_connect (GMythQuery *gmyth_query)
56.118 -{
56.119 - char *opt_host_name;
56.120 - char *opt_user_name;
56.121 - char *opt_password;
56.122 - char *opt_db_name;
56.123 -
56.124 - assert(gmyth_query);
56.125 -
56.126 - opt_host_name = (gmyth_query->opt_host_name ? gmyth_query->opt_host_name->str : NULL);
56.127 - opt_db_name = (gmyth_query->opt_db_name ? gmyth_query->opt_db_name->str : NULL);
56.128 - opt_user_name = (gmyth_query->opt_user_name ? gmyth_query->opt_user_name->str : NULL);
56.129 - opt_password = (gmyth_query->opt_password ? gmyth_query->opt_password->str : NULL);
56.130 -
56.131 -
56.132 - if (gmyth_query->conn == NULL) {
56.133 - gmyth_query_print_error (NULL, "mysql_init() failed (probably out of memory)");
56.134 - return FALSE;
56.135 - }
56.136 -
56.137 - /* connect to server */
56.138 - if (mysql_real_connect (gmyth_query->conn, opt_host_name,
56.139 - opt_user_name, opt_password, opt_db_name,
56.140 - 0, NULL, 0) == NULL) {
56.141 -
56.142 - gmyth_query_print_error (gmyth_query->conn, "mysql_real_connect() failed");
56.143 - return FALSE;
56.144 - }
56.145 -
56.146 - g_debug ("[%s] Connection to Mysql server succeeded!", __FUNCTION__);
56.147 -
56.148 - return TRUE;
56.149 -}
56.150 -
56.151 -/** Disconnects from the Mysql database in the backend.
56.152 - *
56.153 - * @param gmyth_query the GMythQuery instance to be disconnected
56.154 - * @return true if disconnection was success, false if failed.
56.155 - */
56.156 -gboolean
56.157 -gmyth_query_disconnect (GMythQuery *gmyth_query)
56.158 -{
56.159 - assert(gmyth_query);
56.160 -
56.161 - /* TODO: Check how to return error */
56.162 - g_debug ("[%s] Closing gmyth_query->conn", __FUNCTION__);
56.163 - mysql_close (gmyth_query->conn);
56.164 -
56.165 - return TRUE;
56.166 -}
56.167 -
56.168 -static void
56.169 -gmyth_query_print_error (MYSQL *conn, char *message)
56.170 -{
56.171 - fprintf (stderr, "%s\n", message);
56.172 -
56.173 - if (conn != NULL) {
56.174 -#if MYSQL_VERSION_ID >= 40101
56.175 - fprintf (stderr, "Error %u (%s): %s\n",
56.176 - mysql_errno (conn), mysql_sqlstate(conn), mysql_error (conn));
56.177 -#else
56.178 - fprintf (stderr, "Error %u: %s\n",
56.179 - mysql_errno (conn), mysql_error (conn));
56.180 -#endif
56.181 - }
56.182 -}
56.183 -
56.184 -/** Sends the given query to the backend returning the query result as
56.185 - * MYSQL_RES pointer.
56.186 - *
56.187 - * FIXME: this function is returning NULL whether any error happens
56.188 - * or no rows are returned (e.g. UPDATE or REPLACE).
56.189 - *
56.190 - * @param gmyth_query the GMythQuery instance.
56.191 - * @param stmt_str the query text.
56.192 - * @return the MYSQL_RES result pointer or NULL if any error happens.
56.193 - */
56.194 -MYSQL_RES*
56.195 -gmyth_query_process_statement (GMythQuery *gmyth_query, char *stmt_str)
56.196 -{
56.197 - MYSQL_RES *res_set;
56.198 -
56.199 - assert(gmyth_query);
56.200 -
56.201 - g_debug ("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
56.202 -
56.203 - if (gmyth_query == NULL)
56.204 - return NULL;
56.205 -
56.206 - /* the statement failed */
56.207 - if (mysql_query (gmyth_query->conn, stmt_str) != 0) {
56.208 - gmyth_query_print_error (gmyth_query->conn, "Could not execute statement");
56.209 - return NULL;
56.210 - }
56.211 -
56.212 - /* the statement succeeded; determine whether it returned data */
56.213 - res_set = mysql_store_result (gmyth_query->conn);
56.214 - if (res_set) {
56.215 - return res_set;
56.216 - } else if (mysql_field_count (gmyth_query->conn) == 0) {
56.217 - g_debug ("%lu rows affected\n",
56.218 - (unsigned long) mysql_affected_rows (gmyth_query->conn));
56.219 - } else {
56.220 - gmyth_query_print_error (gmyth_query->conn, "Could not retrieve result set");
56.221 - }
56.222 -
56.223 - return NULL;
56.224 -}
57.1 --- a/gmyth/src/libgmyth/gmyth_query.h Wed Sep 27 00:08:03 2006 +0100
57.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
57.3 @@ -1,84 +0,0 @@
57.4 -/**
57.5 - * GMyth Library
57.6 - *
57.7 - * @file gmyth/gmyth_query.h
57.8 - *
57.9 - * @brief <p> GMythQuery class provides a wrapper for accessing
57.10 - * the libmysqlclient funtions.
57.11 - *
57.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
57.13 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
57.14 - *
57.15 - *//*
57.16 - *
57.17 - * This program is free software; you can redistribute it and/or modify
57.18 - * it under the terms of the GNU Lesser General Public License as published by
57.19 - * the Free Software Foundation; either version 2 of the License, or
57.20 - * (at your option) any later version.
57.21 - *
57.22 - * This program is distributed in the hope that it will be useful,
57.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
57.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57.25 - * GNU General Public License for more details.
57.26 - *
57.27 - * You should have received a copy of the GNU Lesser General Public License
57.28 - * along with this program; if not, write to the Free Software
57.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
57.30 - */
57.31 -
57.32 -#ifndef __GMYTH_QUERY_H__
57.33 -#define __GMYTH_QUERY_H__
57.34 -
57.35 -#include <glib-object.h>
57.36 -
57.37 -/* MYSQL includes */
57.38 -#include <mysql.h>
57.39 -
57.40 -G_BEGIN_DECLS
57.41 -
57.42 -#define GMYTH_QUERY_TYPE (gmyth_query_get_type ())
57.43 -#define GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE, GMythQuery))
57.44 -#define GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE, GMythQueryClass))
57.45 -#define IS_GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE))
57.46 -#define IS_GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE))
57.47 -#define GMYTH_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_QUERY_TYPE, GMythQueryClass))
57.48 -
57.49 -
57.50 -typedef struct _GMythQuery GMythQuery;
57.51 -typedef struct _GMythQueryClass GMythQueryClass;
57.52 -
57.53 -struct _GMythQueryClass
57.54 -{
57.55 - GObjectClass parent_class;
57.56 -
57.57 - /* callbacks */
57.58 - /* no one for now */
57.59 -};
57.60 -
57.61 -struct _GMythQuery
57.62 -{
57.63 - GObject parent;
57.64 -
57.65 - GString *opt_host_name; /* server host (default=localhost) */
57.66 - GString *opt_user_name; /* username (default=login name) */
57.67 - GString *opt_password; /* password (default=none) */
57.68 - unsigned int opt_port_num; /* port number (use built-in value) */
57.69 - GString *opt_socket_name; /* socket name (use built-in value) */
57.70 - GString *opt_db_name; /* database name (default=none) */
57.71 - unsigned int opt_flags; /* connection flags (none) */
57.72 - MYSQL *conn; /* pointer to connection handler */
57.73 -};
57.74 -
57.75 -
57.76 -GType gmyth_query_get_type (void);
57.77 -
57.78 -GMythQuery* gmyth_query_new ();
57.79 -MYSQL_RES * gmyth_query_process_statement
57.80 - (GMythQuery *gmyth_query, char *stmt_str);
57.81 -
57.82 -gboolean gmyth_query_connect (GMythQuery *gmyth_query);
57.83 -gboolean gmyth_query_disconnect (GMythQuery *gmyth_query);
57.84 -
57.85 -G_END_DECLS
57.86 -
57.87 -#endif /* __GMYTH_QUERY_H__ */
58.1 --- a/gmyth/src/libgmyth/gmyth_remote_encoder.c Wed Sep 27 00:08:03 2006 +0100
58.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
58.3 @@ -1,207 +0,0 @@
58.4 -/**
58.5 - * GMyth Library
58.6 - *
58.7 - * @file gmyth/gmyth_remote_encoder.c
58.8 - *
58.9 - * @brief <p> GMythRemoteEncoder class defines functions for playing live tv.
58.10 - *
58.11 - * The remote encoder is used by gmyth_tvplayer to setup livetv.
58.12 - *
58.13 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
58.14 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
58.15 - *
58.16 - *//*
58.17 - *
58.18 - * This program is free software; you can redistribute it and/or modify
58.19 - * it under the terms of the GNU Lesser General Public License as published by
58.20 - * the Free Software Foundation; either version 2 of the License, or
58.21 - * (at your option) any later version.
58.22 - *
58.23 - * This program is distributed in the hope that it will be useful,
58.24 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
58.25 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
58.26 - * GNU General Public License for more details.
58.27 - *
58.28 - * You should have received a copy of the GNU Lesser General Public License
58.29 - * along with this program; if not, write to the Free Software
58.30 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
58.31 - */
58.32 -
58.33 -#include "gmyth_remote_encoder.h"
58.34 -
58.35 -#include <assert.h>
58.36 -
58.37 -#include "gmyth_stringlist.h"
58.38 -
58.39 -static void gmyth_remote_encoder_class_init (GMythRemoteEncoderClass *klass);
58.40 -static void gmyth_remote_encoder_init (GMythRemoteEncoder *object);
58.41 -
58.42 -static void gmyth_remote_encoder_dispose (GObject *object);
58.43 -static void gmyth_remote_encoder_finalize (GObject *object);
58.44 -
58.45 -G_DEFINE_TYPE(GMythRemoteEncoder, gmyth_remote_encoder, G_TYPE_OBJECT)
58.46 -
58.47 -static void
58.48 -gmyth_remote_encoder_class_init (GMythRemoteEncoderClass *klass)
58.49 -{
58.50 - GObjectClass *gobject_class;
58.51 -
58.52 - gobject_class = (GObjectClass *) klass;
58.53 -
58.54 - gobject_class->dispose = gmyth_remote_encoder_dispose;
58.55 - gobject_class->finalize = gmyth_remote_encoder_finalize;
58.56 -}
58.57 -
58.58 -static void
58.59 -gmyth_remote_encoder_init (GMythRemoteEncoder *gmyth_remote_encoder)
58.60 -{
58.61 -}
58.62 -
58.63 -static void
58.64 -gmyth_remote_encoder_dispose (GObject *object)
58.65 -{
58.66 - // GMythRemoteEncoder *gmyth_remote_encoder = GMYTH_REMOTE_ENCODER(object);
58.67 -
58.68 - G_OBJECT_CLASS (gmyth_remote_encoder_parent_class)->dispose (object);
58.69 -}
58.70 -
58.71 -
58.72 -static void
58.73 -gmyth_remote_encoder_finalize (GObject *object)
58.74 -{
58.75 - g_signal_handlers_destroy (object);
58.76 -
58.77 - GMythRemoteEncoder *remote_encoder = GMYTH_REMOTE_ENCODER(object);
58.78 -
58.79 - g_debug ("[%s] Closing control socket", __FUNCTION__);
58.80 - gmyth_socket_close_connection(remote_encoder->myth_socket);
58.81 - g_object_unref (remote_encoder->myth_socket);
58.82 -
58.83 - G_OBJECT_CLASS (gmyth_remote_encoder_parent_class)->finalize (object);
58.84 -}
58.85 -
58.86 -/** Creates a new instance of GMythRemoteEncoder.
58.87 - *
58.88 - * @return a new instance of GMythRemoteEncoder.
58.89 - */
58.90 -GMythRemoteEncoder*
58.91 -gmyth_remote_encoder_new (int num, GString *hostname, gshort port)
58.92 -{
58.93 - GMythRemoteEncoder *encoder = GMYTH_REMOTE_ENCODER ( g_object_new (
58.94 - GMYTH_REMOTE_ENCODER_TYPE, FALSE ));
58.95 -
58.96 - encoder->recorder_num = num;
58.97 - encoder->hostname = g_string_new (hostname->str);
58.98 - encoder->port = port;
58.99 -
58.100 - return encoder;
58.101 -}
58.102 -
58.103 -/** Configures the remote encoder instance connecting it to Mythtv backend.
58.104 - *
58.105 - * @param remote_encoder the GMythRemoteEncoder instance.
58.106 - * @return TRUE if successfull, FALSE if any error happens.
58.107 - */
58.108 -gboolean
58.109 -gmyth_remote_encoder_setup (GMythRemoteEncoder *remote_encoder)
58.110 -{
58.111 - assert (remote_encoder);
58.112 - g_debug ("[%s] Creating socket and connecting to backend", __FUNCTION__);
58.113 -
58.114 - if (remote_encoder->myth_socket == NULL) {
58.115 -
58.116 - remote_encoder->myth_socket = gmyth_socket_new ();
58.117 -
58.118 - if (!gmyth_socket_connect_to_backend (remote_encoder->myth_socket, remote_encoder->hostname->str,
58.119 - remote_encoder->port, TRUE) ) {
58.120 - g_warning ("GMythRemoteEncoder: Connection to backend failed");
58.121 - return FALSE;
58.122 - }
58.123 -
58.124 - } else {
58.125 - g_warning("Remote encoder socket already created\n");
58.126 - }
58.127 -
58.128 - return TRUE;
58.129 -}
58.130 -
58.131 -/** Sends the SPAWN_LIVETV command through Mythtv protocol. This command
58.132 - * requests the backend to start capturing TV content.
58.133 - *
58.134 - * @param remote_encoder The GMythRemoteEncoder instance.
58.135 - * @param tvchain_id The tvchain unique id.
58.136 - * @return true if success, false if any error happens.
58.137 - */
58.138 -gboolean
58.139 -gmyth_remote_encoder_spawntv (GMythRemoteEncoder *remote_encoder, GString *tvchain_id)
58.140 -{
58.141 - GMythStringList *str_list;
58.142 - GString *tmp_str;
58.143 -
58.144 - g_debug ("[%s] Spawntv with tvchain_id = %s", __FUNCTION__, tvchain_id->str);
58.145 -
58.146 - str_list = gmyth_string_list_new ();
58.147 -
58.148 - tmp_str = g_string_new ("QUERY_RECORDER ");
58.149 - g_string_append_printf (tmp_str, "%d", remote_encoder->recorder_num);
58.150 -
58.151 - gmyth_string_list_append_string (str_list, tmp_str);
58.152 - gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
58.153 - gmyth_string_list_append_string (str_list, tvchain_id);
58.154 - gmyth_string_list_append_int (str_list, 0); // PIP = FALSE (0)
58.155 -
58.156 - gmyth_socket_sendreceive_stringlist (remote_encoder->myth_socket, str_list);
58.157 -
58.158 - g_string_free (tmp_str, TRUE);
58.159 -
58.160 - tmp_str = gmyth_string_list_get_string (str_list, 0);
58.161 - if (tmp_str == NULL) {
58.162 - g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
58.163 - return FALSE;
58.164 - }
58.165 -
58.166 - if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
58.167 - g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
58.168 - g_object_unref (str_list);
58.169 - return FALSE;
58.170 - }
58.171 -
58.172 - g_object_unref (str_list);
58.173 - return TRUE;
58.174 -
58.175 -}
58.176 -
58.177 -/** Sends the command STOP_LIVETV to Mythtv backend.
58.178 - *
58.179 - * @param remote_encoder the GMythRemoteEncoder instance.
58.180 - * @return true if success, false if any error happens.
58.181 - */
58.182 -gboolean
58.183 -gmyth_remote_encoder_stop_livetv (GMythRemoteEncoder *remote_encoder)
58.184 -{
58.185 - GMythStringList *str_list;
58.186 - GString *tmp_str;
58.187 -
58.188 - g_debug ("[%s]", __FUNCTION__);
58.189 -
58.190 - str_list = gmyth_string_list_new ();
58.191 -
58.192 - tmp_str = g_string_new ("QUERY_RECORDER ");
58.193 - g_string_append_printf (tmp_str, "%d", remote_encoder->recorder_num);
58.194 - gmyth_string_list_append_string (str_list, g_string_new ("STOP_LIVETV"));
58.195 -
58.196 - gmyth_socket_sendreceive_stringlist (remote_encoder->myth_socket, str_list);
58.197 -
58.198 - g_string_free (tmp_str, TRUE);
58.199 -
58.200 - tmp_str = gmyth_string_list_get_string (str_list, 0);
58.201 - if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
58.202 - g_warning ("[%s] Stop livetv request returned %s", __FUNCTION__, tmp_str->str);
58.203 - g_object_unref (str_list);
58.204 - return FALSE;
58.205 - }
58.206 -
58.207 - g_object_unref (str_list);
58.208 - return TRUE;
58.209 -
58.210 -}
59.1 --- a/gmyth/src/libgmyth/gmyth_remote_encoder.h Wed Sep 27 00:08:03 2006 +0100
59.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
59.3 @@ -1,89 +0,0 @@
59.4 -/**
59.5 - * GMyth Library
59.6 - *
59.7 - * @file gmyth/gmyth_remote_encoder.h
59.8 - *
59.9 - * @brief <p> GMythRemoteEncoder class defines functions for playing live tv.
59.10 - *
59.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
59.12 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
59.13 - *
59.14 - *//*
59.15 - *
59.16 - * This program is free software; you can redistribute it and/or modify
59.17 - * it under the terms of the GNU Lesser General Public License as published by
59.18 - * the Free Software Foundation; either version 2 of the License, or
59.19 - * (at your option) any later version.
59.20 - *
59.21 - * This program is distributed in the hope that it will be useful,
59.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
59.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59.24 - * GNU General Public License for more details.
59.25 - *
59.26 - * You should have received a copy of the GNU Lesser General Public License
59.27 - * along with this program; if not, write to the Free Software
59.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
59.29 - */
59.30 -
59.31 -#ifndef __GMYTH_REMOTE_ENCODER_H__
59.32 -#define __GMYTH_REMOTE_ENCODER_H__
59.33 -
59.34 -#include <glib-object.h>
59.35 -
59.36 -#include "gmyth_socket.h"
59.37 -
59.38 -#include <stdio.h>
59.39 -#include <stdlib.h>
59.40 -#include <string.h>
59.41 -#include <netdb.h>
59.42 -#include <sys/socket.h>
59.43 -#include <unistd.h>
59.44 -
59.45 -G_BEGIN_DECLS
59.46 -
59.47 -#define GMYTH_REMOTE_ENCODER_TYPE (gmyth_remote_encoder_get_type ())
59.48 -#define GMYTH_REMOTE_ENCODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoder))
59.49 -#define GMYTH_REMOTE_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoderClass))
59.50 -#define IS_GMYTH_REMOTE_ENCODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_REMOTE_ENCODER_TYPE))
59.51 -#define IS_GMYTH_REMOTE_ENCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_REMOTE_ENCODER_TYPE))
59.52 -#define GMYTH_REMOTE_ENCODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoderClass))
59.53 -
59.54 -
59.55 -typedef struct _GMythRemoteEncoder GMythRemoteEncoder;
59.56 -typedef struct _GMythRemoteEncoderClass GMythRemoteEncoderClass;
59.57 -
59.58 -struct _GMythRemoteEncoderClass
59.59 -{
59.60 - GObjectClass parent_class;
59.61 -
59.62 - /* callbacks */
59.63 - /* no one for now */
59.64 -};
59.65 -
59.66 -struct _GMythRemoteEncoder
59.67 -{
59.68 - GObject parent;
59.69 -
59.70 - /* socket descriptor */
59.71 - GMythSocket *myth_socket;
59.72 -
59.73 - int recorder_num;
59.74 - GString *hostname;
59.75 - int port;
59.76 -};
59.77 -
59.78 -
59.79 -GType gmyth_remote_encoder_get_type (void);
59.80 -
59.81 -GMythRemoteEncoder* gmyth_remote_encoder_new (int num,
59.82 - GString *hostname,
59.83 - gshort port);
59.84 -
59.85 -gboolean gmyth_remote_encoder_setup (GMythRemoteEncoder *encoder);
59.86 -gboolean gmyth_remote_encoder_spawntv (GMythRemoteEncoder *remote_encoder,
59.87 - GString *tvchain_id);
59.88 -gboolean gmyth_remote_encoder_stop_livetv (GMythRemoteEncoder *remote_encoder);
59.89 -
59.90 -G_END_DECLS
59.91 -
59.92 -#endif /* __GMYTH_REMOTE_ENCODER_H__ */
60.1 --- a/gmyth/src/libgmyth/gmyth_remote_util.c Wed Sep 27 00:08:03 2006 +0100
60.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
60.3 @@ -1,70 +0,0 @@
60.4 -/**
60.5 - * GMyth Library
60.6 - *
60.7 - * @file gmyth/gmyth_remote_util.c
60.8 - *
60.9 - * @brief <p> This component provides utility functions for accessing remote data.
60.10 - *
60.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
60.12 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
60.13 - *
60.14 - *//*
60.15 - *
60.16 - * This program is free software; you can redistribute it and/or modify
60.17 - * it under the terms of the GNU Lesser General Public License as published by
60.18 - * the Free Software Foundation; either version 2 of the License, or
60.19 - * (at your option) any later version.
60.20 - *
60.21 - * This program is distributed in the hope that it will be useful,
60.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
60.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60.24 - * GNU General Public License for more details.
60.25 - *
60.26 - * You should have received a copy of the GNU Lesser General Public License
60.27 - * along with this program; if not, write to the Free Software
60.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
60.29 - */
60.30 -
60.31 -#include "gmyth_remote_util.h"
60.32 -
60.33 -#include "gmyth_context.h"
60.34 -#include "gmyth_remote_encoder.h"
60.35 -#include "gmyth_stringlist.h"
60.36 -
60.37 -/** Requests the Mythtv backend for a free remote recorder.
60.38 - *
60.39 - * @param curr The recorder index, or -1 to consider the first one.
60.40 - * @return the remote encoder instance available, or NULL if any error happens.
60.41 - */
60.42 -GMythRemoteEncoder*
60.43 -remote_request_next_free_recorder (int curr)
60.44 -{
60.45 - GMythRemoteEncoder *encoder;
60.46 - GString *hostname;
60.47 - int num, port;
60.48 -
60.49 - GMythStringList *strlist = gmyth_string_list_new();
60.50 -
60.51 - g_debug ("[%s] Request next free recorder in the backend", __FUNCTION__);
60.52 -
60.53 - gmyth_string_list_append_char_array (strlist, "GET_NEXT_FREE_RECORDER");
60.54 - gmyth_string_list_append_int (strlist, curr);
60.55 -
60.56 - if (!gmyth_context_send_receive_stringlist(strlist)) {
60.57 - g_warning ("GET_NEXT_FREE_RECORDER request error!\n");
60.58 - return NULL;
60.59 - }
60.60 -
60.61 - num = gmyth_string_list_get_int (strlist, 0);
60.62 - hostname = gmyth_string_list_get_string (strlist, 1);
60.63 - port = gmyth_string_list_get_int (strlist, 2);
60.64 -
60.65 - g_debug ("[%s] Free recorder info received: num: %d, hostname: %s, port: %d",
60.66 - __FUNCTION__, num, hostname->str, port);
60.67 -
60.68 - encoder = gmyth_remote_encoder_new (num, hostname, port);
60.69 -
60.70 - g_object_unref (strlist);
60.71 -
60.72 - return encoder;
60.73 -}
61.1 --- a/gmyth/src/libgmyth/gmyth_remote_util.h Wed Sep 27 00:08:03 2006 +0100
61.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
61.3 @@ -1,40 +0,0 @@
61.4 -/**
61.5 - * GMyth Library
61.6 - *
61.7 - * @file gmyth/gmyth_remote_util.h
61.8 - *
61.9 - * @brief <p> This component provides utility functions for accessing remote data.
61.10 - *
61.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
61.12 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
61.13 - *
61.14 - *//*
61.15 - *
61.16 - * This program is free software; you can redistribute it and/or modify
61.17 - * it under the terms of the GNU Lesser General Public License as published by
61.18 - * the Free Software Foundation; either version 2 of the License, or
61.19 - * (at your option) any later version.
61.20 - *
61.21 - * This program is distributed in the hope that it will be useful,
61.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
61.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
61.24 - * GNU General Public License for more details.
61.25 - *
61.26 - * You should have received a copy of the GNU Lesser General Public License
61.27 - * along with this program; if not, write to the Free Software
61.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
61.29 - */
61.30 -
61.31 -#ifndef __REMOTE_UTIL_H__
61.32 -#define __REMOTE_UTIL_H__
61.33 -
61.34 -#include <glib.h>
61.35 -#include "gmyth_remote_encoder.h"
61.36 -
61.37 -G_BEGIN_DECLS
61.38 -
61.39 -GMythRemoteEncoder* remote_request_next_free_recorder (int curr);
61.40 -
61.41 -G_END_DECLS
61.42 -
61.43 -#endif
62.1 --- a/gmyth/src/libgmyth/gmyth_scheduler.c Wed Sep 27 00:08:03 2006 +0100
62.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
62.3 @@ -1,610 +0,0 @@
62.4 -/**
62.5 - * GMyth Library
62.6 - *
62.7 - * @file gmyth/gmyth_scheduler.c
62.8 - *
62.9 - * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
62.10 - * and modifying the recorded content.
62.11 - *
62.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
62.13 - * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
62.14 - *
62.15 - *//*
62.16 - *
62.17 - * This program is free software; you can redistribute it and/or modify
62.18 - * it under the terms of the GNU Lesser General Public License as published by
62.19 - * the Free Software Foundation; either version 2 of the License, or
62.20 - * (at your option) any later version.
62.21 - *
62.22 - * This program is distributed in the hope that it will be useful,
62.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
62.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
62.25 - * GNU General Public License for more details.
62.26 - *
62.27 - * You should have received a copy of the GNU Lesser General Public License
62.28 - * along with this program; if not, write to the Free Software
62.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
62.30 - */
62.31 -
62.32 -#include <assert.h>
62.33 -
62.34 -#include "gmyth_scheduler.h"
62.35 -
62.36 -#include "gmyth_context.h"
62.37 -#include "gmyth_util.h"
62.38 -#include "gmyth_query.h"
62.39 -
62.40 -static void gmyth_scheduler_class_init (GMythSchedulerClass *klass);
62.41 -static void gmyth_scheduler_init (GMythScheduler *object);
62.42 -
62.43 -static void gmyth_scheduler_dispose (GObject *object);
62.44 -static void gmyth_scheduler_finalize (GObject *object);
62.45 -
62.46 -static gint get_record_id_from_database (GMythScheduler *scheduler);
62.47 -static void update_backend (gint record_id);
62.48 -
62.49 -G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
62.50 -
62.51 -static void
62.52 -gmyth_scheduler_class_init (GMythSchedulerClass *klass)
62.53 -{
62.54 - GObjectClass *gobject_class;
62.55 -
62.56 - gobject_class = (GObjectClass *) klass;
62.57 -
62.58 - gobject_class->dispose = gmyth_scheduler_dispose;
62.59 - gobject_class->finalize = gmyth_scheduler_finalize;
62.60 -}
62.61 -
62.62 -static void
62.63 -gmyth_scheduler_init (GMythScheduler *sched)
62.64 -{
62.65 - sched->recordid =0;
62.66 - sched->type = 0;
62.67 - sched->search = 0;
62.68 - sched->profile = g_string_new("");
62.69 -
62.70 - sched->dupin = 0;
62.71 - sched->dupmethod = 0;
62.72 - sched->autoexpire = 0;
62.73 - sched->autotranscode = 0;
62.74 - sched->transcoder = 0;
62.75 -
62.76 - sched->autocommflag = 0;
62.77 - sched->autouserjob1 = 0;
62.78 - sched->autouserjob2 = 0;
62.79 - sched->autouserjob3 = 0;
62.80 - sched->autouserjob4 = 0;
62.81 -
62.82 - sched->startoffset = 0;
62.83 - sched->endoffset = 0;
62.84 - sched->maxepisodes = 0;
62.85 - sched->maxnewest = 0;
62.86 -
62.87 - sched->recpriority = 0;
62.88 - sched->recgroup = 0;
62.89 - sched->playgroup = 0;
62.90 -
62.91 - sched->prefinput = 0;
62.92 - sched->inactive = 0;
62.93 -
62.94 - sched->searchType = g_string_new("");
62.95 - sched->searchForWhat = g_string_new("");
62.96 -
62.97 - sched->msqlquery = gmyth_query_new ();
62.98 -}
62.99 -
62.100 -static void
62.101 -gmyth_scheduler_dispose (GObject *object)
62.102 -{
62.103 - G_OBJECT_CLASS (gmyth_scheduler_parent_class)->dispose (object);
62.104 -}
62.105 -
62.106 -static void
62.107 -gmyth_scheduler_finalize (GObject *object)
62.108 -{
62.109 - g_signal_handlers_destroy (object);
62.110 -
62.111 - G_OBJECT_CLASS (gmyth_scheduler_parent_class)->finalize (object);
62.112 -}
62.113 -
62.114 -/** Creates a new instance of GMythScheduler.
62.115 - *
62.116 - * @return a new instance of GMythScheduler.
62.117 - */
62.118 -GMythScheduler*
62.119 -gmyth_scheduler_new ()
62.120 -{
62.121 - GMythScheduler *scheduler =
62.122 - GMYTH_SCHEDULER (g_object_new(GMYTH_SCHEDULER_TYPE, NULL));
62.123 -
62.124 - return scheduler;
62.125 -}
62.126 -
62.127 -/** Connects to the Mysql database in the backend. The backend address
62.128 - * is loaded from the GMythSettings instance.
62.129 - *
62.130 - * @param scheduler the GMythScheduler instance to be connected.
62.131 - * @return true if connection was success, false if failed.
62.132 - */
62.133 -gboolean
62.134 -gmyth_scheduler_connect (GMythScheduler *scheduler)
62.135 -{
62.136 - assert(scheduler);
62.137 -
62.138 - if (scheduler->msqlquery == NULL) {
62.139 - g_warning ("[%s] MMythScheduler not initialized", __FUNCTION__);
62.140 - return FALSE;
62.141 - }
62.142 -
62.143 - if (!gmyth_query_connect(scheduler->msqlquery)) {
62.144 - g_warning ("[%s] Error while connecting to db", __FUNCTION__);
62.145 - return FALSE;
62.146 - }
62.147 -
62.148 - return TRUE;
62.149 -}
62.150 -
62.151 -/** Disconnects from the Mysql database in the backend.
62.152 - *
62.153 - * @param scheduler the GMythScheduler instance to be disconnected
62.154 - * @return true if disconnection was success, false if failed.
62.155 - */
62.156 -gboolean
62.157 -gmyth_scheduler_disconnect (GMythScheduler *scheduler)
62.158 -{
62.159 - assert(scheduler);
62.160 -
62.161 - if (scheduler->msqlquery != NULL) {
62.162 - g_object_unref (scheduler->msqlquery);
62.163 - }
62.164 -
62.165 - return TRUE;
62.166 -}
62.167 -
62.168 -/** Retrieves from the backend Mysql database the list of recording schedules.
62.169 - *
62.170 - * @param scheduler The GMythScheduler instance.
62.171 - * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
62.172 - * @return The amount of schedules retrieved from database, or -1 if error.
62.173 - */
62.174 -gint
62.175 -gmyth_scheduler_get_schedule_list ( GMythScheduler *scheduler, GList **schedule_list)
62.176 -{
62.177 - ScheduleInfo *schedule;
62.178 - MYSQL_RES *msql_res;
62.179 - GString *query_str = g_string_new ("");
62.180 - GString *date_time = g_string_new ("");
62.181 -
62.182 - assert(scheduler);
62.183 -
62.184 - g_string_printf (query_str,
62.185 - "SELECT recordid,programid,chanid,starttime,startdate,"
62.186 - "endtime,enddate,title,subtitle,description,category FROM record;");
62.187 -
62.188 - if (scheduler->msqlquery == NULL) {
62.189 - g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
62.190 - return -1;
62.191 - }
62.192 - msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
62.193 -
62.194 - if (msql_res == NULL) {
62.195 - g_warning ("DB retrieval of schedule list failed");
62.196 - return -1;
62.197 - } else {
62.198 - MYSQL_ROW row;
62.199 - *schedule_list = NULL;
62.200 -
62.201 - while((row = mysql_fetch_row (msql_res)) != NULL) {
62.202 - schedule = g_new0(ScheduleInfo, 1);
62.203 -
62.204 - schedule->record_id = atoi (row[0]);
62.205 - schedule->program_id = atoi (row[1]);
62.206 - schedule->channel_id = atoi (row[2]);
62.207 -
62.208 - /* generate a time_t from a time and a date db field */
62.209 - g_string_printf (date_time, "%s %s", row[4], row[3]);
62.210 -
62.211 - schedule->start_time = gmyth_util_string_to_time (date_time);
62.212 -
62.213 - /* generate a time_t from a time and a date db field */
62.214 - g_string_printf (date_time, "%s %s", row[6], row[5]);
62.215 -
62.216 - schedule->end_time = gmyth_util_string_to_time (date_time);
62.217 -
62.218 - schedule->title = g_string_new (row[7]);
62.219 - schedule->subtitle = g_string_new (row[8]);
62.220 - schedule->description = g_string_new (row[9]);
62.221 - schedule->category = g_string_new (row[10]);
62.222 -
62.223 - (*schedule_list) = g_list_append (*(schedule_list), schedule);
62.224 - }
62.225 - }
62.226 -
62.227 - mysql_free_result (msql_res);
62.228 - g_string_free(query_str, TRUE);
62.229 - g_string_free(date_time, TRUE);
62.230 -
62.231 - return (*schedule_list == NULL) ? 0 : g_list_length (*schedule_list);
62.232 -}
62.233 -
62.234 -/** Retrieves from the backend Mysql database the list of recorded programs.
62.235 - *
62.236 - * @param scheduler The GMythScheduler instance.
62.237 - * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
62.238 - * @return The amount of recorded retrieved from database, or -1 if error.
62.239 - */
62.240 -gint
62.241 -gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler, GList **recorded_list)
62.242 -{
62.243 - RecordedInfo *record;
62.244 - MYSQL_RES *msql_res;
62.245 - GString *query_str = g_string_new ("");
62.246 - GString *date_time = g_string_new ("");
62.247 -
62.248 - assert(scheduler);
62.249 -
62.250 - g_string_printf (query_str,
62.251 - "SELECT recordid,programid,chanid,starttime,progstart,"
62.252 - "endtime,progend,title,subtitle,description,category,basename FROM recorded;");
62.253 -
62.254 - if (scheduler->msqlquery == NULL) {
62.255 - g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
62.256 - return -1;
62.257 - }
62.258 -
62.259 - msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
62.260 -
62.261 - if (msql_res == NULL) {
62.262 - g_warning ("DB retrieval of recording list failed");
62.263 - return -1;
62.264 - } else {
62.265 - MYSQL_ROW row;
62.266 - *recorded_list = NULL;
62.267 -
62.268 - while((row = mysql_fetch_row (msql_res))!=NULL){
62.269 - record = g_new0(RecordedInfo, 1);
62.270 -
62.271 - record->record_id = atoi (row[0]);
62.272 - record->program_id = atoi (row[1]);
62.273 - record->channel_id = atoi (row[2]);
62.274 -
62.275 - /* the db field time already contains the date. therefore
62.276 - * we are not using the date field */
62.277 - /* generate a time_t from a time and a date db field */
62.278 - /* g_string_printf (date_time, "%s %s", row[4], row[3]); */
62.279 - g_string_printf (date_time, "%s", row[3]);
62.280 -
62.281 - record->start_time = gmyth_util_string_to_time (date_time);
62.282 -
62.283 - /* the db field time already contains the date. therefore
62.284 - * we are not using the date field */
62.285 - /* generate a time_t from a time and a date db field */
62.286 - /* g_string_printf (date_time, "%s %s", row[6], row[5]); */
62.287 - g_string_printf (date_time, "%s", row[5]);
62.288 -
62.289 - record->end_time = gmyth_util_string_to_time (date_time);
62.290 -
62.291 - record->title = g_string_new (row[7]);
62.292 - record->subtitle = g_string_new (row[8]);
62.293 - record->description = g_string_new (row[9]);
62.294 - record->category = g_string_new (row[10]);
62.295 - record->basename = g_string_new (row[11]);
62.296 -
62.297 - *recorded_list = g_list_append (*recorded_list, record);
62.298 - }
62.299 - }
62.300 -
62.301 - mysql_free_result (msql_res);
62.302 - g_string_free(query_str, TRUE);
62.303 - g_string_free(date_time, TRUE);
62.304 -
62.305 - return (*recorded_list == NULL) ? 0 : g_list_length (*recorded_list);
62.306 -}
62.307 -
62.308 -/** Requests the Mysql database in the backend to add a new schedule.
62.309 - *
62.310 - * @param scheduler the GMythScheduler instance.
62.311 - * @param schedule_info the ScheduleInfo with recording schedule information
62.312 - * to be added. record_id = -1 to add a new schedule, otherwise this
62.313 - * function will update the schedule in the db
62.314 - * @return gboolean returns FALSE if some error occurs, TRUE otherwise
62.315 - */
62.316 -gboolean
62.317 -gmyth_scheduler_add_schedule (GMythScheduler *scheduler,
62.318 - ScheduleInfo *schedule_info)
62.319 -{
62.320 - struct tm start_tm;
62.321 - struct tm end_tm;
62.322 -
62.323 - MYSQL_RES *msql_res;
62.324 - GString *query_str = g_string_new ("");
62.325 -
62.326 - assert(scheduler);
62.327 -
62.328 - if (scheduler->msqlquery == NULL) {
62.329 - g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
62.330 - return 0;
62.331 - }
62.332 -
62.333 - /* manipulating time */
62.334 - if(localtime_r(&schedule_info->start_time, &start_tm) == NULL) {
62.335 - g_warning ("localtime_r error in libgmyth scheduler!\n");
62.336 - return FALSE;
62.337 - }
62.338 -
62.339 - if(localtime_r(&schedule_info->end_time, &end_tm) == NULL) {
62.340 - g_warning ("localtime_r error in libgmyth scheduler!\n");
62.341 - return FALSE;
62.342 - }
62.343 -
62.344 - //TODO: verify if this funtion realy does what it should do!
62.345 - g_string_printf (query_str, "REPLACE INTO record "
62.346 - "(recordid, type, chanid, starttime, "
62.347 - "startdate, endtime, enddate, title,"
62.348 - "profile, recpriority, maxnewest, inactive, "
62.349 - "maxepisodes, autoexpire, startoffset, endoffset, "
62.350 - "recgroup, dupmethod, dupin, station, "
62.351 - "autocommflag, findday, findtime, findid, "
62.352 - "search, autotranscode, transcoder, tsdefault, "
62.353 - "autouserjob1, autouserjob2, autouserjob3, autouserjob4) "
62.354 - " values ( %d, 1, %d, \"%02d:%02d:00\"," //recordid, type, chanid, starttime
62.355 - " \"%d-%02d-%02d\", \"%02d:%02d:00\", \"%04d-%02d-%02d\", \"%s\","
62.356 - //startdate, endtime, enddate, title
62.357 - "DEFAULT, 0, 0, 0, " //profile, recpriority, maxnewest, inactive
62.358 - "0, 1, 0, 0, " //maxepisodes, autoexpire, startoffset, endoffset
62.359 - "DEFAULT, 6, 15, %d, " //recgroup, dupmethod, dupin, station
62.360 - "1, %d, \"%02d:%02d:00\", %d, " //autocommflag, findday, findtime, findid
62.361 - "5, 0, 29, 1, " //search, autotranscode, transcoder, tsdefault
62.362 - "0, 0, 0, 0 );", //autouserjob1, autouserjob2, autouserjob3, autouserjob4
62.363 - schedule_info->record_id, schedule_info->channel_id,
62.364 - start_tm.tm_hour, start_tm.tm_min,
62.365 - start_tm.tm_year+1900, start_tm.tm_mon+1,
62.366 - start_tm.tm_mday,
62.367 - end_tm.tm_hour, end_tm.tm_min,
62.368 - end_tm.tm_year+1900, end_tm.tm_mon+1,
62.369 - end_tm.tm_mday, schedule_info->title->str, //title
62.370 - schedule_info->channel_id,//station
62.371 - start_tm.tm_wday+1, //findday
62.372 - start_tm.tm_hour, start_tm.tm_min, //findtime
62.373 - (gint)(schedule_info->start_time/60/60/24 + 719528)//findid
62.374 - );
62.375 -
62.376 - msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
62.377 -
62.378 - /* FIXME: currently no way to detect db error in UPDATE, REPLACES!
62.379 - if (msql_res == NULL) {
62.380 - g_warning ("DB retrieval of recording list failed");
62.381 - return -1;
62.382 - }*/
62.383 -
62.384 - /* TODO: verify record_id = -1 semantics */
62.385 - if (schedule_info->record_id <= 0)
62.386 - schedule_info->record_id = get_record_id_from_database(scheduler);
62.387 -
62.388 - /* Notify the backend of changes */
62.389 - update_backend(schedule_info->record_id);
62.390 -
62.391 - /* free allocated memory */
62.392 - mysql_free_result (msql_res);
62.393 - g_string_free(query_str, TRUE);
62.394 -
62.395 - return 1;
62.396 -}
62.397 -
62.398 -/** Requests the Mysql database in the backend to remove an existing schedule.
62.399 - *
62.400 - * @param scheduler the GMythScheduler instance.
62.401 - * @param record_id The schedule's record id to be removed
62.402 - * @return gboolean TRUE if success, FALSE if error
62.403 - */
62.404 -gboolean
62.405 -gmyth_scheduler_delete_schedule (GMythScheduler *scheduler, gint record_id)
62.406 -{
62.407 -
62.408 - MYSQL_RES *msql_res;
62.409 - GString *query_str = g_string_new ("");
62.410 -
62.411 - assert(scheduler);
62.412 -
62.413 - if (scheduler->msqlquery == NULL) {
62.414 - g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
62.415 - return FALSE;
62.416 - }
62.417 -
62.418 - //========================================
62.419 - g_string_printf (query_str,
62.420 - "DELETE FROM record WHERE recordid=%d", record_id);
62.421 -
62.422 - msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
62.423 -
62.424 - if (msql_res == NULL) {
62.425 - g_warning ("[%s] Error while trying to delete a schedule in the database", __FUNCTION__);
62.426 - return FALSE;
62.427 - }
62.428 -
62.429 - update_backend(record_id);// Notify the backend of the changes
62.430 -
62.431 - mysql_free_result (msql_res);
62.432 - g_string_free(query_str, TRUE);
62.433 -
62.434 - return TRUE;
62.435 -}
62.436 -
62.437 -/** Requests the Mysql database in the backend to remove an existing recorded item.
62.438 - *
62.439 - * @param scheduler the GMythScheduler instance.
62.440 - * @param record_id The recorded item id to be removed
62.441 - * @return gboolean TRUE if success, FALSE if error
62.442 - */
62.443 -gboolean
62.444 -gmyth_scheduler_delete_recorded (GMythScheduler *scheduler, gint record_id)
62.445 -{
62.446 -
62.447 - MYSQL_RES *msql_res;
62.448 - GString *query_str = g_string_new ("");
62.449 -
62.450 - assert(scheduler);
62.451 -
62.452 - if (scheduler->msqlquery == NULL) {
62.453 - g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
62.454 - return FALSE;
62.455 - }
62.456 -
62.457 - //========================================
62.458 - g_string_printf (query_str,
62.459 - "DELETE FROM recorded WHERE recordid=%d", record_id);
62.460 -
62.461 - msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
62.462 -
62.463 - update_backend(record_id);// Notify the backend of the changes
62.464 -
62.465 - mysql_free_result (msql_res);
62.466 - g_string_free(query_str, TRUE);
62.467 -
62.468 - return TRUE;
62.469 -}
62.470 -
62.471 -/** Retrieves an existing recorded item information from database. The information
62.472 - * is used to fill the returned GMythProgramInfo.
62.473 - *
62.474 - * @param scheduler The GMythScheduler instance.
62.475 - * @param channel The channel associated to the record
62.476 - * @param starttime The record start time
62.477 - * @return A GMythProgramInfo struct with the requested record item
62.478 - * information, or NULL if error.
62.479 - */
62.480 -GMythProgramInfo*
62.481 -gmyth_scheduler_get_recorded (GMythScheduler *scheduler,
62.482 - GString *channel, time_t starttime)
62.483 -{
62.484 - MYSQL_RES *msql_res;
62.485 - GMythProgramInfo *proginfo = NULL;
62.486 - GString *query_str = g_string_new("");
62.487 - GString *time_str = gmyth_util_time_to_string (starttime);
62.488 -
62.489 - assert(scheduler);
62.490 -
62.491 - if (scheduler->msqlquery == NULL) {
62.492 - g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
62.493 - return NULL;
62.494 - }
62.495 -
62.496 - g_string_printf (query_str, "SELECT recorded.chanid,starttime,endtime,title, "
62.497 - "subtitle,description,channel.channum, "
62.498 - "channel.callsign,channel.name,channel.commfree, "
62.499 - "channel.outputfilters,seriesid,programid,filesize, "
62.500 - "lastmodified,stars,previouslyshown,originalairdate, "
62.501 - "hostname,recordid,transcoder,playgroup, "
62.502 - "recorded.recpriority,progstart,progend,basename,recgroup "
62.503 - "FROM recorded "
62.504 - "LEFT JOIN channel "
62.505 - "ON recorded.chanid = channel.chanid "
62.506 - "WHERE recorded.chanid = \"%s\" "
62.507 - "AND starttime = \"%s\" ;",
62.508 - channel->str, time_str->str);
62.509 -
62.510 - msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
62.511 -
62.512 - if (msql_res /*&& query.size() > 0*/) {
62.513 -
62.514 - MYSQL_ROW msql_row = mysql_fetch_row (msql_res);
62.515 - if (msql_row) {
62.516 -
62.517 - proginfo = g_new0 (GMythProgramInfo, 1);
62.518 -
62.519 - proginfo->chanid = g_string_new (msql_row[0]);
62.520 - proginfo->startts = gmyth_util_string_to_time (g_string_new (msql_row[23]));
62.521 - proginfo->endts = gmyth_util_string_to_time (g_string_new (msql_row[24]));
62.522 - proginfo->recstartts = gmyth_util_string_to_time (g_string_new (msql_row[1]));
62.523 - proginfo->recendts = gmyth_util_string_to_time (g_string_new (msql_row[2]));
62.524 - proginfo->title = g_string_new (msql_row[3]);
62.525 - proginfo->subtitle = g_string_new (msql_row[4]);
62.526 - proginfo->description = g_string_new (msql_row[5]);
62.527 -
62.528 - proginfo->chanstr = g_string_new (msql_row[6]);
62.529 - proginfo->chansign = g_string_new (msql_row[7]);
62.530 - proginfo->channame = g_string_new (msql_row[0]);
62.531 - proginfo->chancommfree = atoi (msql_row[9]);
62.532 - proginfo->chanOutputFilters = g_string_new (msql_row[10]);
62.533 - proginfo->seriesid = g_string_new (msql_row[11]);
62.534 - proginfo->programid = g_string_new (msql_row[12]);
62.535 - proginfo->filesize = atoll (msql_row[13]);
62.536 -
62.537 - proginfo->lastmodified = gmyth_util_string_to_time (g_string_new (msql_row[14]));
62.538 -
62.539 - proginfo->stars = atof (msql_row[15]);
62.540 - proginfo->repeat = atoi (msql_row[16]);
62.541 -
62.542 - if (msql_row[17] == NULL) {
62.543 - proginfo->originalAirDate = 0;
62.544 - proginfo->hasAirDate = FALSE;
62.545 - } else {
62.546 - proginfo->originalAirDate = gmyth_util_string_to_time (g_string_new (msql_row[17]));
62.547 - proginfo->hasAirDate = TRUE;
62.548 - }
62.549 -
62.550 - proginfo->hostname = g_string_new (msql_row[18]);
62.551 - proginfo->recordid = atoi (msql_row[19]);
62.552 - proginfo->transcoder = atoi (msql_row[20]);
62.553 -
62.554 - //proginfo->spread = -1;
62.555 - //proginfo->programflags = proginfo->getProgramFlags();
62.556 -
62.557 - proginfo->recgroup = g_string_new (msql_row[26]);
62.558 - proginfo->playgroup = g_string_new (msql_row[21]);
62.559 - proginfo->recpriority = atoi (msql_row[22]);
62.560 -
62.561 - proginfo->pathname = g_string_new (msql_row[25]);
62.562 -
62.563 - g_debug ("One program info loaded from mysql database\n");
62.564 - }
62.565 - }
62.566 -
62.567 - mysql_free_result (msql_res);
62.568 - g_string_free(query_str, TRUE);
62.569 - g_string_free(time_str, TRUE);
62.570 -
62.571 - return proginfo;
62.572 -}
62.573 -
62.574 -/** Retrieves the next record id.
62.575 - *
62.576 - * @param scheduler The GMythScheduler instance.
62.577 - * @return gint record_id if success, -1 otherwise
62.578 - */
62.579 -static gint
62.580 -get_record_id_from_database (GMythScheduler *scheduler)
62.581 -{
62.582 - gint record_id;
62.583 -
62.584 - assert(scheduler);
62.585 -
62.586 - if (scheduler->msqlquery == NULL) {
62.587 - g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
62.588 - return 0;
62.589 - }
62.590 -
62.591 - record_id = mysql_insert_id (scheduler->msqlquery->conn);
62.592 -
62.593 - return record_id;
62.594 -}
62.595 -
62.596 -/** Notifies the backend of an update in the db.
62.597 - *
62.598 - * @param record_id the id of the modified recording.
62.599 - */
62.600 -static void
62.601 -update_backend(gint record_id)//fixme: put void and discovery record_id inside
62.602 -{
62.603 - GMythStringList *strlist = gmyth_string_list_new ();
62.604 - GString *datastr = g_string_new ("RESCHEDULE_RECORDINGS ");
62.605 -
62.606 - g_string_append_printf (datastr, "%d", record_id);
62.607 - gmyth_string_list_append_string (strlist, datastr);
62.608 -
62.609 - gmyth_context_send_receive_stringlist (strlist);
62.610 -
62.611 - g_string_free(datastr, TRUE);
62.612 - g_object_unref(strlist);
62.613 -}
63.1 --- a/gmyth/src/libgmyth/gmyth_scheduler.h Wed Sep 27 00:08:03 2006 +0100
63.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
63.3 @@ -1,156 +0,0 @@
63.4 -/**
63.5 - * GMyth Library
63.6 - *
63.7 - * @file gmyth/gmyth_scheduler.h
63.8 - *
63.9 - * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
63.10 - * and modifying the recorded content.
63.11 - *
63.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
63.13 - * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
63.14 - *
63.15 - *//*
63.16 - *
63.17 - * This program is free software; you can redistribute it and/or modify
63.18 - * it under the terms of the GNU Lesser General Public License as published by
63.19 - * the Free Software Foundation; either version 2 of the License, or
63.20 - * (at your option) any later version.
63.21 - *
63.22 - * This program is distributed in the hope that it will be useful,
63.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
63.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63.25 - * GNU General Public License for more details.
63.26 - *
63.27 - * You should have received a copy of the GNU Lesser General Public License
63.28 - * along with this program; if not, write to the Free Software
63.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
63.30 - */
63.31 -
63.32 -#ifndef __GMYTH_SCHEDULER_H__
63.33 -#define __GMYTH_SCHEDULER_H__
63.34 -
63.35 -#include <glib-object.h>
63.36 -#include <time.h>
63.37 -
63.38 -#include "gmyth_common.h"
63.39 -#include "gmyth_query.h"
63.40 -
63.41 -G_BEGIN_DECLS
63.42 -
63.43 -#define GMYTH_SCHEDULER_TYPE (gmyth_scheduler_get_type ())
63.44 -#define GMYTH_SCHEDULER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE, GMythScheduler))
63.45 -#define GMYTH_SCHEDULER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
63.46 -#define IS_GMYTH_SCHEDULER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE))
63.47 -#define IS_GMYTH_SCHEDULER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE))
63.48 -#define GMYTH_SCHEDULER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
63.49 -
63.50 -
63.51 -typedef struct _GMythScheduler GMythScheduler;
63.52 -typedef struct _GMythSchedulerClass GMythSchedulerClass;
63.53 -
63.54 -struct _GMythSchedulerClass
63.55 -{
63.56 - GObjectClass parent_class;
63.57 -
63.58 - /* callbacks */
63.59 - /* no one for now */
63.60 -};
63.61 -
63.62 -struct _GMythScheduler
63.63 -{
63.64 - GObject parent;
63.65 -
63.66 - unsigned long recordid;
63.67 - unsigned long type;
63.68 - unsigned long search;
63.69 - GString *profile;
63.70 -
63.71 - long dupin;
63.72 - long dupmethod;
63.73 - long autoexpire;
63.74 - short int autotranscode;
63.75 - long transcoder;
63.76 -
63.77 - short int autocommflag;
63.78 - short int autouserjob1;
63.79 - short int autouserjob2;
63.80 - short int autouserjob3;
63.81 - short int autouserjob4;
63.82 -
63.83 - long startoffset;
63.84 - long endoffset;
63.85 - long maxepisodes;
63.86 - long maxnewest;
63.87 -
63.88 - long recpriority;
63.89 - GString *recgroup;
63.90 - GString *playgroup;
63.91 -
63.92 - long prefinput;
63.93 - short int inactive;
63.94 -
63.95 - GString *searchType;
63.96 - GString *searchForWhat;
63.97 -
63.98 - GMythQuery *msqlquery;
63.99 -};
63.100 -
63.101 -typedef struct {
63.102 - gint record_id;
63.103 - gint program_id;
63.104 - gint channel_id;
63.105 -
63.106 - time_t start_time;
63.107 - time_t end_time;
63.108 -
63.109 - GString *title;
63.110 - GString *subtitle;
63.111 - GString *description;
63.112 - GString *category;
63.113 -
63.114 -} ScheduleInfo;
63.115 -
63.116 -typedef struct {
63.117 - gint record_id;
63.118 - gint program_id;
63.119 - gint channel_id;
63.120 -
63.121 - time_t start_time;
63.122 - time_t end_time;
63.123 -
63.124 - GString *title;
63.125 - GString *subtitle;
63.126 - GString *description;
63.127 - GString *category;
63.128 -
63.129 - GString *basename;
63.130 -
63.131 -} RecordedInfo;
63.132 -
63.133 -
63.134 -GType gmyth_scheduler_get_type (void);
63.135 -
63.136 -GMythScheduler* gmyth_scheduler_new ();
63.137 -gboolean gmyth_scheduler_connect (GMythScheduler *scheduler);
63.138 -gboolean gmyth_scheduler_disconnect (GMythScheduler *scheduler);
63.139 -
63.140 -gint gmyth_scheduler_get_schedule_list (GMythScheduler *scheduler,
63.141 - GList **sched_list);
63.142 -gint gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler,
63.143 - GList **rec_list);
63.144 -
63.145 -GMythProgramInfo* gmyth_scheduler_get_recorded (GMythScheduler *scheduler,
63.146 - GString *channel, time_t starttime);
63.147 -
63.148 -gint gmyth_scheduler_add_schedule(GMythScheduler *scheduler,
63.149 - ScheduleInfo *schedule_info);
63.150 -
63.151 -gint gmyth_scheduler_delete_schedule (GMythScheduler *scheduler,
63.152 - gint record_id);
63.153 -gint gmyth_scheduler_delete_recorded (GMythScheduler *scheduler,
63.154 - gint record_id);
63.155 -
63.156 -G_END_DECLS
63.157 -
63.158 -#endif /* __GMYTH_SCHEDULER_H__ */
63.159 -
64.1 --- a/gmyth/src/libgmyth/gmyth_settings.c Wed Sep 27 00:08:03 2006 +0100
64.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
64.3 @@ -1,417 +0,0 @@
64.4 -/**
64.5 - * GMyth Library
64.6 - *
64.7 - * @file gmyth/gmyth_settings.c
64.8 - *
64.9 - * @brief <p> This component contains functions acessing and modifying
64.10 - * user and program settings.
64.11 - *
64.12 - * The standard settings file is created in the user home folder, in the
64.13 - * file ~/.mmyth/settings.dat.
64.14 - *
64.15 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
64.16 - * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
64.17 - *
64.18 - *//*
64.19 - *
64.20 - * This program is free software; you can redistribute it and/or modify
64.21 - * it under the terms of the GNU Lesser General Public License as published by
64.22 - * the Free Software Foundation; either version 2 of the License, or
64.23 - * (at your option) any later version.
64.24 - *
64.25 - * This program is distributed in the hope that it will be useful,
64.26 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
64.27 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
64.28 - * GNU General Public License for more details.
64.29 - *
64.30 - * You should have received a copy of the GNU Lesser General Public License
64.31 - * along with this program; if not, write to the Free Software
64.32 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
64.33 - */
64.34 -
64.35 -#include "gmyth_settings.h"
64.36 -
64.37 -#include <string.h>
64.38 -#include <stdlib.h>
64.39 -#include <unistd.h>
64.40 -#include <fcntl.h>
64.41 -
64.42 -#include <glib.h>
64.43 -#include <glib/gprintf.h>
64.44 -#include <glib/gstdio.h>
64.45 -
64.46 -#define GMYTH_SETTINGS_FILE_NAME "settings.dat"
64.47 -#define GMYTH_SETTINGS_DIR ".mmyth"
64.48 -
64.49 -static void gmyth_settings_class_init (GMythSettingsClass *klass);
64.50 -static void gmyth_settings_init (GMythSettings *object);
64.51 -
64.52 -static void gmyth_settings_dispose (GObject *object);
64.53 -static void gmyth_settings_finalize (GObject *object);
64.54 -
64.55 -static void fill_settings_data(GMythSettings *gmyth_settings, char* line);
64.56 -
64.57 -G_DEFINE_TYPE(GMythSettings, gmyth_settings, G_TYPE_OBJECT)
64.58 -
64.59 -static void
64.60 -gmyth_settings_class_init (GMythSettingsClass *klass)
64.61 -{
64.62 - GObjectClass *gobject_class;
64.63 -
64.64 - gobject_class = (GObjectClass *) klass;
64.65 -
64.66 - gobject_class->dispose = gmyth_settings_dispose;
64.67 - gobject_class->finalize = gmyth_settings_finalize;
64.68 -}
64.69 -
64.70 -static void
64.71 -gmyth_settings_init (GMythSettings *gmyth_settings)
64.72 -{
64.73 -
64.74 - gmyth_settings->settings_file = NULL;
64.75 -
64.76 - gmyth_settings->backend_hostname = g_string_new("127.0.0.1");
64.77 - gmyth_settings->backend_port = 6543;
64.78 - gmyth_settings->mysql_dbname = g_string_new("mythconverg");
64.79 - gmyth_settings->mysql_username = g_string_new("mythtv");
64.80 - gmyth_settings->mysql_password = g_string_new("mythtv");
64.81 - gmyth_settings->database_type = g_string_new("mysql");
64.82 -
64.83 -}
64.84 -
64.85 -
64.86 -static void
64.87 -gmyth_settings_dispose (GObject *object)
64.88 -{
64.89 - GMythSettings *gmyth_settings = GMYTH_SETTINGS(object);
64.90 -
64.91 - if ( gmyth_settings->backend_hostname != NULL )
64.92 - g_string_free( gmyth_settings->backend_hostname, TRUE );
64.93 - if ( gmyth_settings->mysql_dbname != NULL )
64.94 - g_string_free( gmyth_settings->mysql_dbname, TRUE );
64.95 - if ( gmyth_settings->mysql_username != NULL )
64.96 - g_string_free( gmyth_settings->mysql_username, TRUE );
64.97 - if ( gmyth_settings->mysql_password != NULL )
64.98 - g_string_free( gmyth_settings->mysql_password, TRUE );
64.99 - if ( gmyth_settings->database_type != NULL )
64.100 - g_string_free( gmyth_settings->database_type, TRUE );
64.101 -
64.102 - G_OBJECT_CLASS (gmyth_settings_parent_class)->dispose (object);
64.103 -}
64.104 -
64.105 -static void
64.106 -gmyth_settings_finalize (GObject *object)
64.107 -{
64.108 - g_signal_handlers_destroy (object);
64.109 -
64.110 - G_OBJECT_CLASS (gmyth_settings_parent_class)->finalize (object);
64.111 -}
64.112 -
64.113 -/** Creates a new instance of GMythSettings.
64.114 - *
64.115 - * @return a new instance of GMythSettings.
64.116 - */
64.117 -GMythSettings*
64.118 -gmyth_settings_new (void)
64.119 -{
64.120 - GMythSettings *gmyth_settings = GMYTH_SETTINGS (g_object_new(GMYTH_SETTINGS_TYPE, NULL));
64.121 -
64.122 - return gmyth_settings;
64.123 -}
64.124 -
64.125 -static gboolean
64.126 -gmyth_settings_ensure_dir_exists (const gchar *dir)
64.127 -{
64.128 -
64.129 - g_debug ("[%s] \tdir = %s\n", __FUNCTION__, dir);
64.130 -
64.131 - if (g_file_test (dir, G_FILE_TEST_IS_DIR) == FALSE) {
64.132 - if (g_file_test (dir, G_FILE_TEST_EXISTS) == TRUE) {
64.133 - g_warning ("%s exists, please move it out of the way.", dir);
64.134 - return FALSE;
64.135 - }
64.136 -
64.137 - if (mkdir (dir, 488) != 0) {
64.138 - g_warning ("Failed to create directory %s.", dir);
64.139 - return FALSE;
64.140 - }
64.141 - }
64.142 -
64.143 - return TRUE;
64.144 -}
64.145 -
64.146 -static gboolean
64.147 -gmyth_settings_ensure_file_exists (const gchar *file_name) {
64.148 -
64.149 - int file = 0;
64.150 -
64.151 - if ( g_file_test( file_name, G_FILE_TEST_EXISTS ) == FALSE ) {
64.152 - g_debug ( "\n\tCreating %s file...\n", file_name );
64.153 - file = creat( file_name, S_IRWXU | S_IRWXO | S_IRWXG );
64.154 -
64.155 - if ( close( file ) == -1 )
64.156 - return FALSE;
64.157 - }
64.158 -
64.159 - return TRUE;
64.160 -}
64.161 -
64.162 -/** Loads the GMyth settings from the given file.
64.163 - *
64.164 - * @param gmyth_settings the GMythSettings instance.
64.165 - * @param filename The desired file to be opened.
64.166 - * @return TRUE if success, FALSE if error.
64.167 - */
64.168 -gboolean
64.169 -gmyth_settings_load_from_file (GMythSettings *gmyth_settings, GString *filename)
64.170 -{
64.171 - FILE *file_desc;
64.172 - char line[100];
64.173 -
64.174 - g_debug ("[%s] Loading GMyth settings file: %s", __FUNCTION__, filename->str);
64.175 -
64.176 - file_desc = fopen(filename->str, "r");
64.177 - if( file_desc == NULL) {
64.178 - g_warning ("[%s] Settings file %s could not be opened", __FUNCTION__, filename->str);
64.179 - return FALSE;
64.180 - }
64.181 -
64.182 - gmyth_settings->settings_file = g_string_new (filename->str);
64.183 -
64.184 - while(fgets(line, 100, file_desc)) {
64.185 - int i;
64.186 -
64.187 - /* Removes the new line characters from the end of line */
64.188 - for ( i = strlen(line)-1; i >= 0; i--) {
64.189 - if ( !g_ascii_iscntrl (line[i]) ) {
64.190 - line[i+1] = '\0';
64.191 - break;
64.192 - }
64.193 - }
64.194 -
64.195 - fill_settings_data(gmyth_settings, line);
64.196 - }
64.197 -
64.198 - fclose (file_desc);
64.199 -
64.200 - return TRUE;
64.201 -}
64.202 -
64.203 -/** Loads the GMyth settings from the standard settings file
64.204 - * (~/.mmyth/settings.dat).
64.205 - *
64.206 - * @param gmyth_settings the GMythSettings instance.
64.207 - * @return TRUE if success, FALSE if error.
64.208 - */
64.209 -gboolean
64.210 -gmyth_settings_load (GMythSettings *gmyth_settings)
64.211 -{
64.212 - GString* file_full_path = g_string_new( g_build_filename( g_get_home_dir(),
64.213 - GMYTH_SETTINGS_DIR, GMYTH_SETTINGS_FILE_NAME, NULL ) );
64.214 -
64.215 - gmyth_settings->settings_file = file_full_path;
64.216 -
64.217 - gmyth_settings_ensure_dir_exists( g_build_filename( g_get_home_dir(), GMYTH_SETTINGS_DIR, NULL ) );
64.218 -
64.219 - // Verifies if the file already exist
64.220 - if ( g_file_test( file_full_path->str, G_FILE_TEST_EXISTS ) == FALSE ) {
64.221 - g_debug ("[%s] Settings file does not exist. A new one will be created.\n", __FUNCTION__);
64.222 -
64.223 - if ( gmyth_settings_ensure_file_exists( file_full_path->str ) == FALSE )
64.224 - return FALSE;
64.225 -
64.226 - // Creates the file with default values (see _init function)
64.227 - return gmyth_settings_save (gmyth_settings);
64.228 -
64.229 - } else {
64.230 - g_debug ("[%s] Opening settings from file %s", __FUNCTION__, file_full_path->str);
64.231 -
64.232 - return gmyth_settings_load_from_file (gmyth_settings, file_full_path);
64.233 - }
64.234 -}
64.235 -
64.236 -/** Saves the current gmyth_settings to the settings file related to the
64.237 - * given instance.
64.238 - *
64.239 - * @param gmyth_settings the GMythSettings instance.
64.240 - * @return TRUE if success, FALSE if error.
64.241 - */
64.242 -gboolean
64.243 -gmyth_settings_save (GMythSettings *gmyth_settings)
64.244 -{
64.245 - FILE *file_desc;
64.246 -
64.247 - if (gmyth_settings->settings_file == NULL) {
64.248 - g_warning ("[%s] Settings were not loaded from file, could not save!", __FUNCTION__);
64.249 - }
64.250 -
64.251 - file_desc = fopen(gmyth_settings->settings_file->str, "w");
64.252 - if( file_desc == NULL) {
64.253 - g_warning ("GMYTH_SETTINGS: settings file %s not found", gmyth_settings->settings_file->str);
64.254 - return FALSE;
64.255 - }
64.256 -
64.257 - g_fprintf(file_desc, "#Maemo-Myth Settings\n");
64.258 -
64.259 - g_fprintf(file_desc, "#General settings related with mythtv database\n");
64.260 - g_fprintf(file_desc, "dbname=%s\n", gmyth_settings->mysql_dbname->str);
64.261 - g_fprintf(file_desc, "username=%s\n", gmyth_settings->mysql_username->str);
64.262 - g_fprintf(file_desc, "password=%s\n", gmyth_settings->mysql_password->str);
64.263 -
64.264 - g_fprintf(file_desc, "\n#General settings related with mythtv backend\n");
64.265 - g_fprintf(file_desc, "hostname=%s\n", gmyth_settings->backend_hostname->str);
64.266 - g_fprintf(file_desc, "backend_port=%d\n", gmyth_settings->backend_port);
64.267 -
64.268 - fclose (file_desc);
64.269 -
64.270 - g_debug ("[%s] Settings file saved", __FUNCTION__);
64.271 - return TRUE;
64.272 -}
64.273 -
64.274 -/** Gets the backend hostname from the settings.
64.275 - *
64.276 - * @param gmyth_settings the GMythSettings instance.
64.277 - * @return The loaded backend hostname, or the default value "127.0.0.1" if settings
64.278 - * file was not opened.
64.279 - */
64.280 -GString*
64.281 -gmyth_settings_get_backend_hostname (GMythSettings *gmyth_settings)
64.282 -{
64.283 - return g_string_new (gmyth_settings->backend_hostname->str);
64.284 -}
64.285 -
64.286 -/** Sets the backend hostname to the settings.
64.287 - *
64.288 - * @param gmyth_settings the GMythSettings instance.
64.289 - * @param new_hostname The new hostname.
64.290 - */
64.291 -void
64.292 -gmyth_settings_set_backend_hostname (GMythSettings *gmyth_settings, GString *new_hostname)
64.293 -{
64.294 - g_string_assign (gmyth_settings->backend_hostname, new_hostname->str);
64.295 -}
64.296 -
64.297 -/** Gets the user name to connect to backend database.
64.298 - *
64.299 - * @param gmyth_settings the GMythSettings instance.
64.300 - * @return The loaded user name, or the default value "mythtv" if settings
64.301 - * file was not opened.
64.302 - */
64.303 -GString*
64.304 -gmyth_settings_get_username (GMythSettings *gmyth_settings)
64.305 -{
64.306 - return g_string_new (gmyth_settings->mysql_username->str);
64.307 -}
64.308 -
64.309 -/** Sets the username to connect to backend database.
64.310 - *
64.311 - * @param gmyth_settings the GMythSettings instance.
64.312 - * @param new_username The new username.
64.313 - */
64.314 -void
64.315 -gmyth_settings_set_username (GMythSettings *gmyth_settings, GString *new_username)
64.316 -{
64.317 - g_string_assign (gmyth_settings->mysql_username, new_username->str);
64.318 -}
64.319 -
64.320 -/** Gets the database password from the settings file.
64.321 - *
64.322 - * @param gmyth_settings the GMythSettings instance.
64.323 - * @return The loaded password, or the default value "mythtv" if settings
64.324 - * file was not opened.
64.325 - */
64.326 -GString*
64.327 -gmyth_settings_get_password (GMythSettings *gmyth_settings)
64.328 -{
64.329 - return g_string_new (gmyth_settings->mysql_password->str);
64.330 -}
64.331 -
64.332 -/** Sets the database password.
64.333 - *
64.334 - * @param gmyth_settings the GMythSettings instance.
64.335 - * @param new_password The new password.
64.336 - */
64.337 -
64.338 -void
64.339 -gmyth_settings_set_password (GMythSettings *gmyth_settings, GString *new_password)
64.340 -{
64.341 - g_string_assign (gmyth_settings->mysql_password, new_password->str);
64.342 -}
64.343 -
64.344 -/** Gets the backend database name from the settings file.
64.345 - *
64.346 - * @param gmyth_settings the GMythSettings instance.
64.347 - * @return The loaded database name, or the default value "mythconverg" if settings
64.348 - * file was not opened.
64.349 - */
64.350 -GString*
64.351 -gmyth_settings_get_dbname (GMythSettings *gmyth_settings)
64.352 -{
64.353 - return g_string_new (gmyth_settings->mysql_dbname->str);
64.354 -}
64.355 -
64.356 -/** Sets the Mythtv database name to the settings.
64.357 - *
64.358 - * @param gmyth_settings the GMythSettings instance.
64.359 - * @param new_dbname The new database name.
64.360 - */
64.361 -
64.362 -void
64.363 -gmyth_settings_set_dbname (GMythSettings *gmyth_settings, GString *new_dbname)
64.364 -{
64.365 - g_string_assign (gmyth_settings->mysql_dbname, new_dbname->str);
64.366 -}
64.367 -
64.368 -/** Gets the backend port from the settings.
64.369 - *
64.370 - * @param gmyth_settings the GMythSettings instance.
64.371 - * @return The loaded backend port, or the default value "6543" if settings
64.372 - * file was not opened.
64.373 - */
64.374 -int
64.375 -gmyth_settings_get_backend_port (GMythSettings *gmyth_settings)
64.376 -{
64.377 - return gmyth_settings->backend_port;
64.378 -}
64.379 -
64.380 -/** Sets the backend port.
64.381 - *
64.382 - * @param gmyth_settings the GMythSettings instance.
64.383 - * @param new_port The new port.
64.384 - */
64.385 -void
64.386 -gmyth_settings_set_backend_port (GMythSettings *gmyth_settings, gint new_port)
64.387 -{
64.388 - gmyth_settings->backend_port = new_port;
64.389 -}
64.390 -
64.391 -
64.392 -static void
64.393 -fill_settings_data(GMythSettings *gmyth_settings, char* line)
64.394 -{
64.395 - gchar** str_splited;
64.396 -
64.397 - GString *gstr_splited;
64.398 - gstr_splited = g_string_new("");
64.399 - str_splited = g_strsplit (line, "=", -1);
64.400 -
64.401 - if(!(strcmp(str_splited[0], "hostname"))){
64.402 - g_string_assign(gstr_splited, str_splited[1]);
64.403 - gmyth_settings_set_backend_hostname(gmyth_settings, gstr_splited);
64.404 - }
64.405 - else if (!(strcmp(str_splited[0], "dbname"))){
64.406 - g_string_assign(gstr_splited, str_splited[1]);
64.407 - gmyth_settings_set_dbname(gmyth_settings, gstr_splited);
64.408 - }
64.409 - else if (!(strcmp(str_splited[0], "username"))){
64.410 - g_string_assign(gstr_splited, str_splited[1]);
64.411 - gmyth_settings_set_username(gmyth_settings, gstr_splited);
64.412 - }
64.413 - else if (!(strcmp(str_splited[0], "password"))){
64.414 - g_string_assign(gstr_splited, str_splited[1]);
64.415 - gmyth_settings_set_password(gmyth_settings, gstr_splited);
64.416 - }
64.417 - else if (!(strcmp(str_splited[0], "backend_port"))){
64.418 - gmyth_settings_set_backend_port(gmyth_settings, atoi(str_splited[1]));
64.419 - }
64.420 -}
65.1 --- a/gmyth/src/libgmyth/gmyth_settings.h Wed Sep 27 00:08:03 2006 +0100
65.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
65.3 @@ -1,103 +0,0 @@
65.4 -/**
65.5 - * GMyth Library
65.6 - *
65.7 - * @file gmyth/gmyth_settings.h
65.8 - *
65.9 - * @brief <p> This component contains functions acessing and modifying
65.10 - * user and program settings.
65.11 - *
65.12 - * The standard settings file is created in the user home folder, in the
65.13 - * file ~/.mmyth/settings.dat.
65.14 - *
65.15 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
65.16 - * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
65.17 - *
65.18 - *//*
65.19 - *
65.20 - * This program is free software; you can redistribute it and/or modify
65.21 - * it under the terms of the GNU Lesser General Public License as published by
65.22 - * the Free Software Foundation; either version 2 of the License, or
65.23 - * (at your option) any later version.
65.24 - *
65.25 - * This program is distributed in the hope that it will be useful,
65.26 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
65.27 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
65.28 - * GNU General Public License for more details.
65.29 - *
65.30 - * You should have received a copy of the GNU Lesser General Public License
65.31 - * along with this program; if not, write to the Free Software
65.32 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
65.33 - */
65.34 -
65.35 -#ifndef __GMYTH_SETTINGS_H__
65.36 -#define __GMYTH_SETTINGS_H__
65.37 -
65.38 -#include <glib-object.h>
65.39 -
65.40 -//#include <stdio.h>
65.41 -//#include <stdlib.h>
65.42 -//#include <string.h>
65.43 -//#include <netdb.h>
65.44 -//#include <sys/socket.h>
65.45 -//#include <unistd.h>
65.46 -
65.47 -G_BEGIN_DECLS
65.48 -
65.49 -#define GMYTH_SETTINGS_TYPE (gmyth_settings_get_type ())
65.50 -#define GMYTH_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SETTINGS_TYPE, GMythSettings))
65.51 -#define GMYTH_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SETTINGS_TYPE, GMythSettingsClass))
65.52 -#define IS_GMYTH_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SETTINGS_TYPE))
65.53 -#define IS_GMYTH_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SETTINGS_TYPE))
65.54 -#define GMYTH_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SETTINGS_TYPE, GMythSettingsClass))
65.55 -
65.56 -
65.57 -typedef struct _GMythSettings GMythSettings;
65.58 -typedef struct _GMythSettingsClass GMythSettingsClass;
65.59 -
65.60 -struct _GMythSettingsClass
65.61 -{
65.62 - GObjectClass parent_class;
65.63 -
65.64 - /* callbacks */
65.65 - /* no one for now */
65.66 -};
65.67 -
65.68 -struct _GMythSettings
65.69 -{
65.70 - GObject parent;
65.71 -
65.72 - GString *settings_file;
65.73 -
65.74 - GString *backend_hostname;
65.75 - int backend_port;
65.76 -
65.77 - GString *mysql_dbname;
65.78 - GString *mysql_username;
65.79 - GString *mysql_password;
65.80 - // FIXME: Why do we need database_type? Do we intend to support other dbs?
65.81 - GString *database_type;
65.82 -};
65.83 -
65.84 -
65.85 -GType gmyth_settings_get_type (void);
65.86 -
65.87 -GMythSettings* gmyth_settings_new (void);
65.88 -gboolean gmyth_settings_load_from_file (GMythSettings *gmyth_settings, GString *filename);
65.89 -gboolean gmyth_settings_load (GMythSettings *msettings);
65.90 -gboolean gmyth_settings_save (GMythSettings *gmyth_settings);
65.91 -
65.92 -GString* gmyth_settings_get_backend_hostname (GMythSettings *gmyth_settings);
65.93 -void gmyth_settings_set_backend_hostname (GMythSettings *gmyth_settings, GString *new_hostname);
65.94 -GString* gmyth_settings_get_username (GMythSettings *gmyth_settings);
65.95 -void gmyth_settings_set_username (GMythSettings *gmyth_settings, GString *new_username);
65.96 -GString* gmyth_settings_get_password (GMythSettings *gmyth_settings);
65.97 -void gmyth_settings_set_password (GMythSettings *gmyth_settings, GString *new_password);
65.98 -GString* gmyth_settings_get_dbname (GMythSettings *gmyth_settings);
65.99 -void gmyth_settings_set_dbname (GMythSettings *gmyth_settings, GString *new_dbname);
65.100 -int gmyth_settings_get_backend_port (GMythSettings *gmyth_settings);
65.101 -void gmyth_settings_set_backend_port (GMythSettings *gmyth_settings, gint new_port);
65.102 -
65.103 -
65.104 -G_END_DECLS
65.105 -
65.106 -#endif /* __GMYTH_SETTINGS_H__ */
66.1 --- a/gmyth/src/libgmyth/gmyth_socket.c Wed Sep 27 00:08:03 2006 +0100
66.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
66.3 @@ -1,708 +0,0 @@
66.4 -/**
66.5 - * GMyth Library
66.6 - *
66.7 - * @file gmyth/gmyth_socket.c
66.8 - *
66.9 - * @brief <p> MythTV socket implementation, according to the MythTV Project
66.10 - * (www.mythtv.org).
66.11 - *
66.12 - * This component provides basic socket functionalities to interact with
66.13 - * the Mythtv backend.
66.14 - * <p>
66.15 - *
66.16 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
66.17 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
66.18 - *
66.19 - *//*
66.20 - *
66.21 - * This program is free software; you can redistribute it and/or modify
66.22 - * it under the terms of the GNU Lesser General Public License as published by
66.23 - * the Free Software Foundation; either version 2 of the License, or
66.24 - * (at your option) any later version.
66.25 - *
66.26 - * This program is distributed in the hope that it will be useful,
66.27 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
66.28 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66.29 - * GNU General Public License for more details.
66.30 - *
66.31 - * You should have received a copy of the GNU Lesser General Public License
66.32 - * along with this program; if not, write to the Free Software
66.33 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
66.34 - */
66.35 -
66.36 -#include <glib.h>
66.37 -#include <glib/gprintf.h>
66.38 -
66.39 -#include <arpa/inet.h>
66.40 -#include <sys/types.h>
66.41 -#include <sys/socket.h>
66.42 -#include <netdb.h>
66.43 -#include <errno.h>
66.44 -#include <stdlib.h>
66.45 -
66.46 -#include "gmyth_socket.h"
66.47 -#include "gmyth_stringlist.h"
66.48 -#include "gmyth_context.h"
66.49 -
66.50 -#define BUFLEN 512
66.51 -#define MYTH_SEPARATOR "[]:[]"
66.52 -#define MYTH_PROTOCOL_FIELD_SIZE 8
66.53 -
66.54 -static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
66.55 -
66.56 -static void gmyth_socket_class_init (GMythSocketClass *klass);
66.57 -static void gmyth_socket_init (GMythSocket *object);
66.58 -
66.59 -static void gmyth_socket_dispose (GObject *object);
66.60 -static void gmyth_socket_finalize (GObject *object);
66.61 -
66.62 -G_DEFINE_TYPE(GMythSocket, gmyth_socket, G_TYPE_OBJECT)
66.63 -
66.64 -static void
66.65 -gmyth_socket_class_init (GMythSocketClass *klass)
66.66 -{
66.67 - GObjectClass *gobject_class;
66.68 -
66.69 - gobject_class = (GObjectClass *) klass;
66.70 -
66.71 - gobject_class->dispose = gmyth_socket_dispose;
66.72 - gobject_class->finalize = gmyth_socket_finalize;
66.73 -}
66.74 -
66.75 -static void
66.76 -gmyth_socket_init (GMythSocket *gmyth_socket)
66.77 -{
66.78 -}
66.79 -
66.80 -/** Gets the some important address translation info, from the client socket
66.81 - * that will open a connection.
66.82 - *
66.83 - * @return gint that represents the error number from getaddrinfo().
66.84 - */
66.85 -static gint
66.86 -gmyth_socket_toaddrinfo( gchar *addr, gint port, struct addrinfo **addrInfo )
66.87 -{
66.88 - struct addrinfo hints;
66.89 - gchar *portStr = g_strnfill( 32, ' ' );
66.90 - gint errorn = EADDRNOTAVAIL;
66.91 -
66.92 - memset( &hints, 0, sizeof(hints) );
66.93 - hints.ai_family = AF_INET;
66.94 - hints.ai_socktype = SOCK_STREAM;
66.95 - /* hints.ai_flags = AI_NUMERICHOST; */
66.96 - if ( port != -1 )
66.97 - sprintf(portStr, "%d", port);
66.98 - else
66.99 - portStr = NULL;
66.100 -
66.101 - g_debug( "[%s] Address: %s, port: %s\n", __FUNCTION__, addr, portStr );
66.102 - if ( ( errorn = getaddrinfo(addr, portStr, &hints, addrInfo) ) != 0 ) {
66.103 - g_printerr( "[%s] Socket ERROR: %s\n", __FUNCTION__, gai_strerror(errorn) );
66.104 - }
66.105 -
66.106 - return errorn;
66.107 -}
66.108 -
66.109 -/** This function retrieves the local hostname of the
66.110 - * client machine.
66.111 - *
66.112 - * @return GString* get local hostname.
66.113 - */
66.114 -GString *
66.115 -gmyth_socket_get_local_hostname( )
66.116 -{
66.117 - GString *str = g_string_new("");
66.118 -
66.119 - gchar *localhostname = g_strnfill( 1024, ' ' );
66.120 - gchar *localaddr = g_strdup( "127.0.0.1" );
66.121 -
66.122 - gboolean found_addr = FALSE;
66.123 -
66.124 - struct addrinfo* addr_info_data = NULL, *addr_info0 = NULL;
66.125 -
66.126 - struct sockaddr_in* sa = NULL;
66.127 -
66.128 - g_static_mutex_lock( &mutex );
66.129 -
66.130 - gethostname(localhostname, 1024);
66.131 -
66.132 - gint err = gmyth_socket_toaddrinfo( localhostname, -1, &addr_info_data );
66.133 -
66.134 - addr_info0 = addr_info_data;
66.135 -
66.136 - while( addr_info0 != NULL && addr_info0->ai_addr != NULL &&
66.137 - ( sa = (struct sockaddr_in*)addr_info0->ai_addr ) != NULL && !found_addr ) {
66.138 - localaddr = inet_ntoa( sa->sin_addr );
66.139 - if ( localaddr != NULL )
66.140 - g_print( "[%s] localaddr = %s\n", __FUNCTION__, localaddr );
66.141 -
66.142 - if ( localaddr != NULL && ( g_strrstr( localaddr, "127" ) == NULL ) ) {
66.143 - g_print( "[%s] Trying the address %s (err = %d).\n",
66.144 - __FUNCTION__, localaddr, err );
66.145 - g_print( "[%s] Found local address %s!\n", __FUNCTION__, localaddr );
66.146 - str = g_string_assign( str, g_strdup( localaddr ) );
66.147 - found_addr = TRUE;
66.148 - break;
66.149 - }
66.150 - addr_info0 = addr_info0->ai_next;
66.151 - };
66.152 -
66.153 - if ( found_addr == FALSE ) {
66.154 - g_warning("[%s] Could not determine the local hostname address. Setting to %s\n",
66.155 - __FUNCTION__, localaddr );
66.156 - if ( localaddr != NULL )
66.157 - str = g_string_assign( str, localaddr );
66.158 - else
66.159 - str = g_string_assign( str, "127.0.0.1" );
66.160 - }
66.161 -
66.162 - g_static_mutex_unlock( &mutex );
66.163 -
66.164 - if (localhostname!=NULL)
66.165 - g_free( localhostname );
66.166 -
66.167 - return str;
66.168 -}
66.169 -
66.170 -static void
66.171 -gmyth_socket_dispose (GObject *object)
66.172 -{
66.173 - GMythSocket *gmyth_socket = GMYTH_SOCKET(object);
66.174 -
66.175 - gmyth_socket_close_connection (gmyth_socket);
66.176 - /* disconnect socket */
66.177 - G_OBJECT_CLASS (gmyth_socket_parent_class)->dispose (object);
66.178 -}
66.179 -
66.180 -static void
66.181 -gmyth_socket_finalize (GObject *object)
66.182 -{
66.183 - g_signal_handlers_destroy (object);
66.184 -
66.185 - G_OBJECT_CLASS (gmyth_socket_parent_class)->finalize (object);
66.186 -}
66.187 -
66.188 -/** Creates a new instance of GMythSocket.
66.189 - *
66.190 - * @return a new instance of GMythSocket.
66.191 - */
66.192 -GMythSocket*
66.193 -gmyth_socket_new ()
66.194 -{
66.195 - GMythSocket *gmyth_socket = GMYTH_SOCKET (g_object_new(GMYTH_SOCKET_TYPE, NULL));
66.196 -
66.197 - gmyth_socket->sd_io_ch = NULL;
66.198 -
66.199 - gmyth_socket->hostname = g_strdup("");
66.200 -
66.201 - gmyth_socket->port = 6543;
66.202 -
66.203 - return gmyth_socket;
66.204 -}
66.205 -
66.206 -/** Connects to the backend.
66.207 - *
66.208 - * @param gmyth_socket The GMythSocket instance.
66.209 - * @param hostname The backend hostname or IP address.
66.210 - * @param port The backend port.
66.211 - * @return TRUE if success, FALSE if error.
66.212 - */
66.213 -gboolean
66.214 -gmyth_socket_connect (GMythSocket **gmyth_socket,
66.215 - gchar *hostname, gint port)
66.216 -{
66.217 - struct addrinfo *addr_info_data = NULL, *addr_info0 = NULL;
66.218 - gint ret_code = -1;
66.219 - gint errno;
66.220 - gboolean ret = TRUE;
66.221 -
66.222 - if ( hostname == NULL )
66.223 - g_printerr ( "[%s] Invalid hostname parameter!\n", __FUNCTION__ );
66.224 -
66.225 - errno = gmyth_socket_toaddrinfo( hostname, port, &addr_info_data );
66.226 -
66.227 - g_return_val_if_fail( addr_info_data != NULL, FALSE );
66.228 -
66.229 - /* store hostname and port number */
66.230 - (*gmyth_socket)->hostname = g_strdup( hostname );
66.231 - (*gmyth_socket)->port = port;
66.232 -
66.233 - for ( addr_info0 = addr_info_data; addr_info0; addr_info0 = addr_info_data->ai_next ) {
66.234 -
66.235 - struct sockaddr_in *sa = (struct sockaddr_in*)addr_info0->ai_addr;
66.236 - /* init socket descriptor */
66.237 - (*gmyth_socket)->sd = socket( addr_info0->ai_family, addr_info0->ai_socktype,
66.238 - addr_info0->ai_protocol );
66.239 -
66.240 - if ( (*gmyth_socket)->sd < 0 )
66.241 - continue;
66.242 -
66.243 - g_debug( "[%s] hostname = %s, sock_fd = %d, addr = %s, addr_len = %d, \
66.244 - ai_family = %d, ai_protocol = %d\n",
66.245 - __FUNCTION__, hostname, (*gmyth_socket)->sd, inet_ntoa( sa->sin_addr ),
66.246 - addr_info0->ai_addrlen, addr_info0->ai_family, addr_info0->ai_protocol );
66.247 -
66.248 - if ( ( ret_code = connect( (*gmyth_socket)->sd, (struct sockaddr *)addr_info0->ai_addr,
66.249 - addr_info0->ai_addrlen ) ) < 0 )
66.250 - {
66.251 - g_printerr( "[%s] Error connecting to backend!\n", __FUNCTION__ );
66.252 - if ( ret_code == ETIMEDOUT )
66.253 - g_printerr( "[%s]\tBackend host unreachable!\n", __FUNCTION__ );
66.254 -
66.255 - g_printerr( "ERROR: %s\n", gai_strerror(ret_code) );
66.256 - continue;
66.257 - }
66.258 -
66.259 - /* only will be reached if none of the error above occurred */
66.260 - break;
66.261 -
66.262 - }
66.263 -
66.264 - (*gmyth_socket)->sd_io_ch = g_io_channel_unix_new( (*gmyth_socket)->sd );
66.265 -
66.266 - //if (addr_info_data != NULL )
66.267 - //freeaddrinfo( addr_info_data );
66.268 -
66.269 - ret = ( ret_code == 0 ) ? TRUE : FALSE ;
66.270 -
66.271 - return ret;
66.272 -
66.273 -}
66.274 -
66.275 -/** Gets the GIOChannel associated to the given GMythSocket.
66.276 - *
66.277 - * @param gmyth_socket The GMythSocket instance.
66.278 - */
66.279 -GIOChannel *
66.280 -gmyth_socket_get_io_channel( GMythSocket *gmyth_socket )
66.281 -{
66.282 - g_return_val_if_fail( gmyth_socket != NULL, NULL );
66.283 -
66.284 - return gmyth_socket->sd_io_ch;
66.285 -}
66.286 -
66.287 -/** Verifies if the socket is able to read.
66.288 - *
66.289 - * @param gmyth_socket The GMythSocket instance.
66.290 - * @return TRUE if the socket is able to read, FALSE if not.
66.291 - */
66.292 -gboolean
66.293 -gmyth_socket_is_able_to_read( GMythSocket *gmyth_socket )
66.294 -{
66.295 - gboolean ret = TRUE;
66.296 -
66.297 - /* verify if the input (read) buffer is ready to receive data */
66.298 - GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
66.299 -
66.300 - if ( ( io_cond & G_IO_IN ) == 0 ) {
66.301 - g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
66.302 - ret = FALSE;
66.303 - }
66.304 -
66.305 - return ret;
66.306 -
66.307 -}
66.308 -
66.309 -/** Verifies if the socket is able to write.
66.310 - *
66.311 - * @param gmyth_socket The GMythSocket instance.
66.312 - * @return TRUE if the socket is able to write, FALSE if not.
66.313 - */
66.314 -gboolean
66.315 -gmyth_socket_is_able_to_write( GMythSocket *gmyth_socket )
66.316 -{
66.317 - gboolean ret = TRUE;
66.318 -
66.319 - /* verify if the input (read) buffer is ready to receive data */
66.320 - GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
66.321 -
66.322 - if ( ( ( io_cond & G_IO_OUT ) == 0 ) || ( ( io_cond & G_IO_HUP ) == 0 ) ) {
66.323 - g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
66.324 - ret = FALSE;
66.325 - }
66.326 -
66.327 - return ret;
66.328 -
66.329 -}
66.330 -
66.331 -/** Sends a command to the backend.
66.332 - *
66.333 - * @param gmyth_socket the GMythSocket instance.
66.334 - * @param command The string command to be sent.
66.335 - */
66.336 -gboolean
66.337 -gmyth_socket_send_command(GMythSocket *gmyth_socket, GString *command)
66.338 -{
66.339 - gboolean ret = TRUE;
66.340 -
66.341 - GIOStatus io_status = G_IO_STATUS_NORMAL;
66.342 - //GIOCondition io_cond;
66.343 - GError* error = NULL;
66.344 - gchar *buffer = NULL;
66.345 -
66.346 - gsize bytes_written = 0;
66.347 -
66.348 - if( command == NULL || ( command->len <= 0 ) ) {
66.349 - g_warning ("[%s] Invalid NULL command parameter!\n", __FUNCTION__);
66.350 - ret = FALSE;
66.351 - goto done;
66.352 - }
66.353 -
66.354 - g_static_mutex_lock( &mutex );
66.355 - g_debug ("[%s] Sending command to backend: %s\n", __FUNCTION__, command->str);
66.356 -
66.357 - /*
66.358 - io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
66.359 -
66.360 - if ( ( io_cond & G_IO_IN ) == 0 ) {
66.361 - g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
66.362 - ret = FALSE;
66.363 - goto done;
66.364 - }
66.365 - */
66.366 -
66.367 - buffer = g_strnfill( BUFLEN, ' ' );
66.368 - snprintf( buffer, MYTH_PROTOCOL_FIELD_SIZE+1, "%-8d", command->len);
66.369 - g_print( "[%s] buffer = [%s]\n", __FUNCTION__, buffer );
66.370 -
66.371 - command = g_string_prepend(command, buffer);
66.372 -
66.373 - g_print( "[%s] command = [%s]\n", __FUNCTION__, command->str );
66.374 -
66.375 - /* write bytes to socket */
66.376 - io_status = g_io_channel_write_chars( gmyth_socket->sd_io_ch, command->str,
66.377 - command->len, &bytes_written, &error );
66.378 -
66.379 -
66.380 - if( (io_status == G_IO_STATUS_ERROR) || ( bytes_written <= 0 ) ) {
66.381 - g_warning ("[%s] Error while writing to socket", __FUNCTION__);
66.382 - ret = FALSE;
66.383 - } else if ( bytes_written < command->len ) {
66.384 - g_warning ("[%s] Not all data was written socket", __FUNCTION__);
66.385 - ret = FALSE;
66.386 - }
66.387 -
66.388 - io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
66.389 -
66.390 - if ( ( bytes_written != command->len ) || ( io_status == G_IO_STATUS_ERROR ) )
66.391 - {
66.392 - g_warning ("[%s] Some problem occurred when sending data to the socket\n", __FUNCTION__);
66.393 -
66.394 - ret = TRUE;
66.395 - }
66.396 -
66.397 - g_static_mutex_unlock( &mutex );
66.398 -done:
66.399 - if ( error != NULL ) {
66.400 - g_printerr( "[%s] Error found reading data from IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
66.401 - ret = FALSE;
66.402 - g_error_free( error );
66.403 - }
66.404 -
66.405 - if ( buffer!= NULL )
66.406 - g_free( buffer );
66.407 -
66.408 - return ret;
66.409 -}
66.410 -
66.411 -/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
66.412 - * supported by the backend and send the "ANN" command.
66.413 - *
66.414 - * @param gmyth_socket the GMythSocket instance.
66.415 - * @param hostname_backend The backend hostname or IP address.
66.416 - * @param port The backend port to connect.
66.417 - * @param blocking_client A flag to choose between blocking and non-blocking
66.418 - * backend connection.
66.419 - */
66.420 -gboolean
66.421 -gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket,
66.422 - gchar *hostname_backend, int port, gboolean blocking_client)
66.423 -{
66.424 - if (!gmyth_socket_connect (&gmyth_socket, hostname_backend, port)) {
66.425 - g_warning ("[%s] Could not open socket to backend machine", __FUNCTION__);
66.426 - return FALSE;
66.427 - }
66.428 -
66.429 - if (gmyth_socket_check_protocol_version (gmyth_socket)) {
66.430 -
66.431 - GString *result;
66.432 - GString *base_str = g_string_new("");
66.433 - GString *hostname = NULL;
66.434 -
66.435 - hostname = gmyth_socket_get_local_hostname();
66.436 -
66.437 - g_string_printf(base_str, "ANN %s %s 0",
66.438 - (blocking_client ? "Playback" : "Monitor"),
66.439 - hostname->str);
66.440 -
66.441 - g_debug ("[%s] Connection command sent to backend: %s", __FUNCTION__, base_str->str);
66.442 -
66.443 - gmyth_socket_send_command (gmyth_socket, base_str);
66.444 - result = gmyth_socket_receive_response(gmyth_socket);
66.445 -
66.446 - if (result != NULL) {
66.447 - g_debug ("[%s] Response received from backend: %s", __FUNCTION__, result->str);
66.448 - g_string_free (result, TRUE);
66.449 - }
66.450 -
66.451 - g_string_free (hostname, TRUE);
66.452 - g_string_free (base_str, TRUE);
66.453 -
66.454 - return TRUE;
66.455 - } else {
66.456 - g_warning ("[%s] GMythSocket could not connect to the backend", __FUNCTION__);
66.457 - return FALSE;
66.458 - }
66.459 -
66.460 -}
66.461 -
66.462 -/** Closes the socket connection to the backend.
66.463 - *
66.464 - * @param gmyth_socket The GMythSocket instance.
66.465 - */
66.466 -void
66.467 -gmyth_socket_close_connection (GMythSocket *gmyth_socket)
66.468 -{
66.469 - close (gmyth_socket->sd);
66.470 -}
66.471 -
66.472 -
66.473 -/** Try the MythTV version numbers, and get the version returned by
66.474 - * the possible REJECT message, in order to contruct a new
66.475 - * MythTV version request.
66.476 - *
66.477 - * @param gmyth_socket The GMythSocket instance.
66.478 - * @param mythtv_version The Mythtv protocol version to be tested
66.479 - */
66.480 -gboolean
66.481 -gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket, gint mythtv_version)
66.482 -{
66.483 - GString *response;
66.484 - GString *payload;
66.485 - gchar *new_version = g_strdup("");
66.486 - gboolean res = TRUE;
66.487 -
66.488 -try_new_version:
66.489 - payload = g_string_new ("MYTH_PROTO_VERSION");
66.490 - g_string_append_printf( payload, " %d", mythtv_version );
66.491 -
66.492 - gmyth_socket_send_command(gmyth_socket, payload);
66.493 - response = gmyth_socket_receive_response(gmyth_socket);
66.494 -
66.495 - if (response == NULL) {
66.496 - g_warning ("[%s] Check protocol version error! Not answered!", __FUNCTION__);
66.497 - res = FALSE;
66.498 - goto done;
66.499 - }
66.500 -
66.501 - res = g_str_has_prefix (response->str, "ACCEPT");
66.502 - if (!res) {
66.503 - g_warning ("[%s] Protocol version request error: %s", __FUNCTION__, response->str);
66.504 - /* get the version number returned by the REJECT message */
66.505 - if ( ( res = g_str_has_prefix (response->str, "REJECT") ) == TRUE ) {
66.506 - new_version = g_strrstr( response->str, "]" );
66.507 - if (new_version!=NULL) {
66.508 - ++new_version; /* skip ']' character */
66.509 - if ( new_version != NULL ) {
66.510 - g_print( "[%s] got MythTV version = %s\n", __FUNCTION__, new_version );
66.511 - mythtv_version = g_ascii_strtoull( g_strdup( new_version ), NULL, 10 );
66.512 - /* do reconnection to the socket (socket is closed if the MythTV version was wrong) */
66.513 - gmyth_socket_connect( &gmyth_socket, gmyth_socket->hostname, gmyth_socket->port );
66.514 - /* g_free( new_version ); */
66.515 - goto try_new_version;
66.516 - }
66.517 - }
66.518 - }
66.519 - }
66.520 -
66.521 -done:
66.522 - if ( payload != NULL )
66.523 - g_string_free (payload, TRUE);
66.524 - if ( response != NULL )
66.525 - g_string_free (response, TRUE);
66.526 -// if (new_version!=NULL)
66.527 -// g_free( new_version );
66.528 -
66.529 - return res;
66.530 -}
66.531 -
66.532 -/** Verifies if the Mythtv backend supported the GMyth supported version.
66.533 - *
66.534 - * @param gmyth_socket The GMythSocket instance.
66.535 - * @return TRUE if supports, FALSE if not.
66.536 - */
66.537 -gboolean
66.538 -gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket)
66.539 -{
66.540 - return gmyth_socket_check_protocol_version_number( gmyth_socket, MYTHTV_VERSION_DEFAULT );
66.541 -}
66.542 -
66.543 -/** Receives a backend answer after a gmyth_socket_send_command_call ().
66.544 - *
66.545 - * @param gmyth_socket The GMythSocket instance.
66.546 - * @return The response received, or NULL if error or nothing was received.
66.547 - */
66.548 -GString*
66.549 -gmyth_socket_receive_response(GMythSocket *gmyth_socket)
66.550 -{
66.551 - GIOStatus io_status = G_IO_STATUS_NORMAL;
66.552 - GError* error = NULL;
66.553 - gchar *buffer = NULL;
66.554 -
66.555 - GString *str = NULL;
66.556 -
66.557 - gsize bytes_read = 0;
66.558 - gint len = 0;
66.559 - GIOCondition io_cond;
66.560 -
66.561 - g_return_val_if_fail( gmyth_socket != NULL, NULL );
66.562 -
66.563 - /* verify if the input (read) buffer is ready to receive data */
66.564 -
66.565 - buffer = g_strnfill( BUFLEN, ' ' );
66.566 -
66.567 - g_static_mutex_lock( &mutex );
66.568 -
66.569 - io_status = g_io_channel_read_chars( gmyth_socket->sd_io_ch, buffer, MYTH_PROTOCOL_FIELD_SIZE, &bytes_read, &error );
66.570 -
66.571 -
66.572 - /* verify if the input (read) buffer is ready to receive data */
66.573 - io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
66.574 -
66.575 - g_print ( "[%s] Bytes read = %d\n", __FUNCTION__, bytes_read );
66.576 -
66.577 - if( (io_status == G_IO_STATUS_ERROR) || (bytes_read <= 0) ) {
66.578 - g_warning ("[%s] Error in mythprotocol response from backend\n", __FUNCTION__);
66.579 - str = NULL;
66.580 - //return NULL;
66.581 - } else {
66.582 -
66.583 - io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
66.584 - /* verify if the input (read) buffer is ready to receive data */
66.585 - io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
66.586 -
66.587 - if ( ( io_cond & G_IO_IN ) != 0 ) {
66.588 -
66.589 - snprintf( buffer, MYTH_PROTOCOL_FIELD_SIZE+1, "%-8s", g_strdup(buffer));
66.590 - g_print( "[%s] buffer = [%s]\n", __FUNCTION__, buffer );
66.591 -
66.592 - /* removes trailing whitespace */
66.593 - buffer = g_strstrip( buffer );
66.594 -
66.595 - len = (gint)strtoull ( buffer, NULL, 10 );
66.596 -
66.597 - bytes_read = 0;
66.598 - io_status = g_io_channel_read_chars( gmyth_socket->sd_io_ch, buffer, len, &bytes_read, &error );
66.599 - buffer[bytes_read] = '\0';
66.600 - }
66.601 - }
66.602 -
66.603 - g_static_mutex_unlock( &mutex );
66.604 -
66.605 - g_debug ("[%s] Response received from backend: {%s}\n", __FUNCTION__, buffer);
66.606 -
66.607 - if ( ( bytes_read != len ) || ( io_status == G_IO_STATUS_ERROR ) )
66.608 - str = NULL;
66.609 - else
66.610 - str = g_string_new( buffer );
66.611 -
66.612 - if ( buffer != NULL )
66.613 - g_free( buffer );
66.614 -
66.615 - if ( error != NULL ) {
66.616 - g_printerr( "[%s] Error found receiving response from the IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
66.617 - str = NULL;
66.618 - g_error_free( error );
66.619 - }
66.620 -
66.621 - return str;
66.622 -}
66.623 -
66.624 -/** Format a Mythtv command from the str_list entries and send it to backend.
66.625 - *
66.626 - * @param gmyth_socket The GMythSocket instance.
66.627 - * @param str_list The string list to form the command
66.628 - * @return TRUE if command was sent, FALSE if any error happens.
66.629 - */
66.630 -gboolean
66.631 -gmyth_socket_write_stringlist(GMythSocket *gmyth_socket, GMythStringList* str_list)
66.632 -{
66.633 -
66.634 - GList *tmp_list;
66.635 - GPtrArray *ptr_array;
66.636 - gchar *str_array;
66.637 -
66.638 - g_static_mutex_lock( &mutex );
66.639 -
66.640 - ptr_array = g_ptr_array_sized_new(g_list_length(str_list->glist));
66.641 -
66.642 - g_print( "[%s] Number of parameters = %d\n", __FUNCTION__, g_list_length(str_list->glist) );
66.643 -
66.644 - // FIXME: change this implementation!
66.645 - tmp_list = str_list->glist;
66.646 - for(; tmp_list; tmp_list = tmp_list->next) {
66.647 - if ( tmp_list->data != NULL )
66.648 - g_ptr_array_add(ptr_array, ((GString*)tmp_list->data)->str);
66.649 - }
66.650 - g_ptr_array_add(ptr_array, NULL); // g_str_joinv() needs a NULL terminated string
66.651 -
66.652 - str_array = g_strjoinv (MYTH_SEPARATOR, (gchar **) (ptr_array->pdata));
66.653 -
66.654 - g_static_mutex_unlock( &mutex );
66.655 -
66.656 - // Sends message to backend
66.657 - // TODO: implement looping to send remaining data, and add timeout testing!
66.658 - gmyth_socket_send_command(gmyth_socket, g_string_new(str_array));
66.659 -
66.660 - g_free (str_array);
66.661 - g_ptr_array_free (ptr_array, TRUE);
66.662 -
66.663 - return TRUE;
66.664 -}
66.665 -
66.666 -/* Receives a backend command response and split it into the given string list.
66.667 - *
66.668 - * @param gmyth_socket The GMythSocket instance.
66.669 - * @param str_list the string list to be filled.
66.670 - * @return The number of received strings.
66.671 - */
66.672 -gint
66.673 -gmyth_socket_read_stringlist (GMythSocket *gmyth_socket, GMythStringList* str_list)
66.674 -{
66.675 - GString *response;
66.676 - gchar **str_array;
66.677 - gint i;
66.678 -
66.679 - response = gmyth_socket_receive_response(gmyth_socket);
66.680 - g_static_mutex_lock( &mutex );
66.681 -
66.682 - gmyth_string_list_clear_all (str_list);
66.683 - str_array = g_strsplit (response->str, MYTH_SEPARATOR, -1);
66.684 -
66.685 - for (i=0; i< g_strv_length (str_array); i++) {
66.686 - gmyth_string_list_append_string (str_list, g_string_new (str_array[i]));
66.687 - }
66.688 - g_static_mutex_unlock( &mutex );
66.689 -
66.690 - g_string_free (response, TRUE);
66.691 - g_strfreev (str_array);
66.692 -
66.693 - return gmyth_string_list_length (str_list);
66.694 -}
66.695 -
66.696 -/** Formats a Mythtv protocol command based on str_list and sends it to
66.697 - * the connected backend. The backend response is overwritten into str_list.
66.698 - *
66.699 - * @param gmyth_socket The GMythSocket instance.
66.700 - * @param str_list The string list to be sent, and on which the answer
66.701 - * will be written.
66.702 - * @return TRUE if command was sent and an answer was received, FALSE if any
66.703 - * error happens.
66.704 - */
66.705 -gint
66.706 -gmyth_socket_sendreceive_stringlist (GMythSocket *gmyth_socket, GMythStringList *str_list)
66.707 -{
66.708 - gmyth_socket_write_stringlist (gmyth_socket, str_list);
66.709 -
66.710 - return gmyth_socket_read_stringlist (gmyth_socket, str_list);
66.711 -}
67.1 --- a/gmyth/src/libgmyth/gmyth_socket.h Wed Sep 27 00:08:03 2006 +0100
67.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
67.3 @@ -1,116 +0,0 @@
67.4 -/**
67.5 - * GMyth Library
67.6 - *
67.7 - * @file gmyth/gmyth_socket.h
67.8 - *
67.9 - * @brief <p> MythTV socket implementation, according to the MythTV Project
67.10 - * (www.mythtv.org).
67.11 - *
67.12 - * This component provides basic socket functionalities to interact with
67.13 - * the Mythtv backend.
67.14 - * <p>
67.15 - *
67.16 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
67.17 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
67.18 - *
67.19 - *//*
67.20 - *
67.21 - * This program is free software; you can redistribute it and/or modify
67.22 - * it under the terms of the GNU Lesser General Public License as published by
67.23 - * the Free Software Foundation; either version 2 of the License, or
67.24 - * (at your option) any later version.
67.25 - *
67.26 - * This program is distributed in the hope that it will be useful,
67.27 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
67.28 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
67.29 - * GNU General Public License for more details.
67.30 - *
67.31 - * You should have received a copy of the GNU Lesser General Public License
67.32 - * along with this program; if not, write to the Free Software
67.33 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
67.34 - */
67.35 -
67.36 -#ifndef __GMYTH_SOCKET_H__
67.37 -#define __GMYTH_SOCKET_H__
67.38 -
67.39 -#include <glib-object.h>
67.40 -
67.41 -#include <string.h>
67.42 -#include <netdb.h>
67.43 -#include <sys/socket.h>
67.44 -#include <unistd.h>
67.45 -#include <glib.h>
67.46 -
67.47 -#include "gmyth_stringlist.h"
67.48 -
67.49 -G_BEGIN_DECLS
67.50 -
67.51 -#define GMYTH_SOCKET_TYPE (gmyth_socket_get_type ())
67.52 -#define GMYTH_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE, GMythSocket))
67.53 -#define GMYTH_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE, GMythSocketClass))
67.54 -#define IS_GMYTH_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE))
67.55 -#define IS_GMYTH_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE))
67.56 -#define GMYTH_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SOCKET_TYPE, GMythSocketClass))
67.57 -
67.58 -
67.59 -typedef struct _GMythSocket GMythSocket;
67.60 -typedef struct _GMythSocketClass GMythSocketClass;
67.61 -
67.62 -struct _GMythSocketClass
67.63 -{
67.64 - GObjectClass parent_class;
67.65 -
67.66 - /* callbacks */
67.67 - /* no one for now */
67.68 -};
67.69 -
67.70 -struct _GMythSocket
67.71 -{
67.72 - GObject parent;
67.73 -
67.74 - /* socket descriptor */
67.75 - int sd;
67.76 - GIOChannel *sd_io_ch;
67.77 -
67.78 - gchar *hostname;
67.79 - gint port;
67.80 -};
67.81 -
67.82 -
67.83 -GType gmyth_socket_get_type (void);
67.84 -
67.85 -GMythSocket * gmyth_socket_new (void);
67.86 -
67.87 -GIOChannel * gmyth_socket_get_io_channel (GMythSocket *gmyth_socket );
67.88 -
67.89 -gboolean gmyth_socket_is_able_to_read (GMythSocket *gmyth_socket );
67.90 -gboolean gmyth_socket_is_able_to_write (GMythSocket *gmyth_socket );
67.91 -
67.92 -gboolean gmyth_socket_send_command (GMythSocket *gmyth_socket,
67.93 - GString *command);
67.94 -GString * gmyth_socket_receive_response (GMythSocket *gmyth_socket);
67.95 -int gmyth_socket_sendreceive_stringlist (GMythSocket * gmyth_socket,
67.96 - GMythStringList *str_list);
67.97 -
67.98 -gboolean gmyth_socket_connect (GMythSocket **gmyth_socket,
67.99 - gchar *hostname, gint port);
67.100 -gboolean gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket,
67.101 - gchar *hostname_backend, int port,
67.102 - gboolean blocking_client);
67.103 -
67.104 -GString * gmyth_socket_get_local_hostname (void);
67.105 -
67.106 -void gmyth_socket_close_connection (GMythSocket *gmyth_socket);
67.107 -
67.108 -gboolean gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket);
67.109 -gboolean gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket,
67.110 - gint mythtv_version);
67.111 -
67.112 -gboolean gmyth_socket_write_stringlist(GMythSocket *gmyth_socket,
67.113 - GMythStringList* str_list);
67.114 -int gmyth_socket_read_stringlist(GMythSocket *gmyth_socket,
67.115 - GMythStringList* str_list);
67.116 -
67.117 -G_END_DECLS
67.118 -
67.119 -#endif /* __GMYTH_SOCKET_H__ */
68.1 --- a/gmyth/src/libgmyth/gmyth_stringlist.c Wed Sep 27 00:08:03 2006 +0100
68.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
68.3 @@ -1,272 +0,0 @@
68.4 -/**
68.5 - * GMyth Library
68.6 - *
68.7 - * @file gmyth/gmyth_stringlist.c
68.8 - *
68.9 - * @brief <p> This component contains functions for dealing with the stringlist
68.10 - * format of the mythprotocol.
68.11 - *
68.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
68.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
68.14 - *
68.15 - *//*
68.16 - *
68.17 - * This program is free software; you can redistribute it and/or modify
68.18 - * it under the terms of the GNU Lesser General Public License as published by
68.19 - * the Free Software Foundation; either version 2 of the License, or
68.20 - * (at your option) any later version.
68.21 - *
68.22 - * This program is distributed in the hope that it will be useful,
68.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
68.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
68.25 - * GNU General Public License for more details.
68.26 - *
68.27 - * You should have received a copy of the GNU Lesser General Public License
68.28 - * along with this program; if not, write to the Free Software
68.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
68.30 - */
68.31 -
68.32 -#include "gmyth_stringlist.h"
68.33 -
68.34 -static void gmyth_string_list_class_init (GMythStringListClass *klass);
68.35 -static void gmyth_string_list_init (GMythStringList *object);
68.36 -
68.37 -static void gmyth_string_list_dispose (GObject *object);
68.38 -static void gmyth_string_list_finalize (GObject *object);
68.39 -
68.40 -G_DEFINE_TYPE(GMythStringList, gmyth_string_list, G_TYPE_OBJECT)
68.41 -
68.42 -static void
68.43 -gmyth_string_list_class_init (GMythStringListClass *klass)
68.44 -{
68.45 - GObjectClass *gobject_class;
68.46 -
68.47 - gobject_class = (GObjectClass *) klass;
68.48 -
68.49 - gobject_class->dispose = gmyth_string_list_dispose;
68.50 - gobject_class->finalize = gmyth_string_list_finalize;
68.51 -}
68.52 -
68.53 -static void
68.54 -gmyth_string_list_init (GMythStringList *gmyth_string_list)
68.55 -{
68.56 - gmyth_string_list->glist = NULL;
68.57 -}
68.58 -
68.59 -static void
68.60 -gmyth_string_list_dispose (GObject *object)
68.61 -{
68.62 - GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
68.63 -
68.64 - if (gmyth_string_list->glist)
68.65 - gmyth_string_list_clear_all(gmyth_string_list);
68.66 -
68.67 - G_OBJECT_CLASS (gmyth_string_list_parent_class)->dispose (object);
68.68 -}
68.69 -
68.70 -static void
68.71 -gmyth_string_list_finalize (GObject *object)
68.72 -{
68.73 - //GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
68.74 -
68.75 - g_signal_handlers_destroy (object);
68.76 -
68.77 - G_OBJECT_CLASS (gmyth_string_list_parent_class)->finalize (object);
68.78 -}
68.79 -
68.80 -/** Creates a new instance of GStringList.
68.81 - *
68.82 - * @return a new instance of GStringList.
68.83 - */
68.84 -GMythStringList *
68.85 -gmyth_string_list_new ()
68.86 -{
68.87 - GMythStringList *gmyth_string_list = GMYTH_STRING_LIST (g_object_new(GMYTH_STRING_LIST_TYPE, NULL));
68.88 -
68.89 - return gmyth_string_list;
68.90 -}
68.91 -
68.92 -/** Appends a guint64 to the string list.
68.93 - *
68.94 - * @param strlist The GMythStringList instance.
68.95 - * @param value The guint64 to be appended.
68.96 - *
68.97 - * @return The appended guint64 converted to a GString object.
68.98 - */
68.99 -GString*
68.100 -gmyth_string_list_append_int ( GMythStringList *strlist, const gint value )
68.101 -{
68.102 - GString *tmp_str = g_string_new ("");
68.103 -
68.104 - g_string_printf (tmp_str, "%d", value);
68.105 -
68.106 - gmyth_string_list_append_string (strlist, tmp_str);
68.107 -
68.108 - return tmp_str;
68.109 -}
68.110 -
68.111 -/** Appends a guint64 to the string list.
68.112 - *
68.113 - * @param strlist The GMythStringList instance.
68.114 - * @param value The guint64 to be appended.
68.115 - *
68.116 - * @return The appended guint64 converted to a GString object.
68.117 - */
68.118 -GString*
68.119 -gmyth_string_list_append_uint64 ( GMythStringList *strlist, const guint64 value)
68.120 -{
68.121 - GString *tmp_str = g_string_new ("");
68.122 -
68.123 - glong l2 = ( (guint64)(value) & 0xffffffffLL );
68.124 - glong l1 = ( ((guint64)(value) >> 32 ) & 0xffffffffLL );
68.125 -
68.126 - /* high order part of guint64 value */
68.127 - g_string_printf (tmp_str, "%ld", l1);
68.128 -
68.129 - g_debug( "[%s] uint64 (high) = %s\n", __FUNCTION__, tmp_str->str );
68.130 -
68.131 - gmyth_string_list_append_string (strlist, tmp_str);
68.132 -
68.133 - /* low order part of guint64 value */
68.134 - g_string_printf (tmp_str, "%ld", l2);
68.135 -
68.136 - g_debug( "[%s] uint64 (low) = %s\n", __FUNCTION__, tmp_str->str );
68.137 -
68.138 - gmyth_string_list_append_string (strlist, tmp_str);
68.139 -
68.140 - return tmp_str;
68.141 -}
68.142 -
68.143 -/** Appends a char array to the string list.
68.144 - *
68.145 - * @param strlist The GMythStringList instance.
68.146 - * @param value The char array to be appended.
68.147 - *
68.148 - * @return The appended char array converted to a GString object.
68.149 - */
68.150 -GString*
68.151 -gmyth_string_list_append_char_array ( GMythStringList *strlist, const gchar* value )
68.152 -{
68.153 - GString *tmp_str = NULL;
68.154 -
68.155 - g_return_val_if_fail( strlist != NULL, NULL );
68.156 -
68.157 - tmp_str = g_string_new (value);
68.158 -
68.159 - g_return_val_if_fail( tmp_str != NULL, NULL );
68.160 -
68.161 - gmyth_string_list_append_string (strlist, tmp_str);
68.162 -
68.163 - return tmp_str;
68.164 -}
68.165 -
68.166 -/** Appends a string to the string list.
68.167 - *
68.168 - * @param strlist The GMythStringList instance.
68.169 - * @param value The string to be appended.
68.170 - *
68.171 - * @return The appended string itself.
68.172 - */
68.173 -GString*
68.174 -gmyth_string_list_append_string ( GMythStringList *strlist, GString *value )
68.175 -{
68.176 - g_return_val_if_fail( strlist != NULL, NULL );
68.177 -
68.178 - strlist->glist = g_list_append (strlist->glist, value);
68.179 -
68.180 - return value;
68.181 -}
68.182 -
68.183 -/** Gets an integer value from the string list at the given position.
68.184 - *
68.185 - * @param strlist The GMythStringList instance.
68.186 - * @param index the integer position in the list, starting with zero.
68.187 - * @return The integer value.
68.188 - */
68.189 -gint
68.190 -gmyth_string_list_get_int ( GMythStringList *strlist, const gint index )
68.191 -{
68.192 - //TODO: Create static method check_index()
68.193 - GString *tmp_str = NULL;
68.194 -
68.195 - g_return_val_if_fail( strlist != NULL, 0 );
68.196 -
68.197 - tmp_str = (GString *) g_list_nth_data (strlist->glist, index);
68.198 -
68.199 - g_return_val_if_fail( tmp_str != NULL && tmp_str->str != NULL, 0 );
68.200 -
68.201 - return (gint) ( 0x00000000ffffffffL & g_ascii_strtoull ( tmp_str->str, NULL, 0 ) );
68.202 -}
68.203 -
68.204 -/** Gets a guint64 value from the string list at the given position.
68.205 - * According to the Mythtv protocol, the 64 bits value is formed by
68.206 - * two strings.
68.207 - *
68.208 - * @param strlist The GMythStringList instance.
68.209 - * @param index the index of the first string forming the 64 bits value.
68.210 - * Index starts with zero.
68.211 - * @return The guint64 value.
68.212 - */
68.213 -guint64
68.214 -gmyth_string_list_get_uint64 ( GMythStringList *strlist, const gint index )
68.215 -{
68.216 - //TODO: Create static method check_index()
68.217 - guint64 ret_value = 0;
68.218 -
68.219 - g_return_val_if_fail( strlist != NULL, 0 );
68.220 -
68.221 - const GString *tmp_str1 = (GString *) g_list_nth_data (strlist->glist, index);
68.222 - const GString *tmp_str2 = (GString *) g_list_nth_data (strlist->glist, index+1);
68.223 -
68.224 - glong l1 = (glong)g_ascii_strtoull (tmp_str1->str, NULL, 10);
68.225 - glong l2 = (glong)g_ascii_strtoull (tmp_str2->str, NULL, 10);
68.226 -
68.227 - ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
68.228 -
68.229 - g_debug( "[%s] returning uint64 value = %llu\n", __FUNCTION__, ret_value );
68.230 -
68.231 - return ret_value;
68.232 -}
68.233 -
68.234 -/** Gets a string from the string list at the given position.
68.235 - *
68.236 - * @param strlist The GMythStringList instance.
68.237 - * @param index the string position in the list, starting with zero.
68.238 - * @return A pointer to the string data.
68.239 - */
68.240 -GString*
68.241 -gmyth_string_list_get_string ( GMythStringList *strlist, const gint index )
68.242 -{
68.243 - if (!strlist || !(strlist->glist)) {
68.244 - g_warning ("%s received Null arguments", __FUNCTION__);
68.245 - return NULL;
68.246 - }
68.247 -
68.248 - return (GString *) g_list_nth_data (strlist->glist, index);
68.249 -}
68.250 -
68.251 -/** Removes all strings from the string list.
68.252 - *
68.253 - * @param strlist The GMythStringList instance.
68.254 - */
68.255 -void
68.256 -gmyth_string_list_clear_all ( GMythStringList *strlist )
68.257 -{
68.258 - if ( strlist != NULL && strlist->glist ) {
68.259 - g_list_free (strlist->glist);
68.260 - strlist->glist = NULL;
68.261 - }
68.262 -}
68.263 -
68.264 -/** Retrieves the number of elements in the string list.
68.265 - *
68.266 - * @param strlist The GMythStringList instance.
68.267 - * @return the string list length.
68.268 - */
68.269 -gint
68.270 -gmyth_string_list_length ( GMythStringList *strlist )
68.271 -{
68.272 - g_return_val_if_fail( strlist != NULL && strlist->glist != NULL, 0 );
68.273 -
68.274 - return g_list_length (strlist->glist);
68.275 -}
69.1 --- a/gmyth/src/libgmyth/gmyth_stringlist.h Wed Sep 27 00:08:03 2006 +0100
69.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
69.3 @@ -1,97 +0,0 @@
69.4 -/**
69.5 - * GMyth Library
69.6 - *
69.7 - * @file gmyth/gmyth_stringlist.h
69.8 - *
69.9 - * @brief <p> This component contains functions for dealing with the stringlist
69.10 - * format of the mythprotocol.
69.11 - *
69.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
69.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
69.14 - *
69.15 - *//*
69.16 - *
69.17 - * This program is free software; you can redistribute it and/or modify
69.18 - * it under the terms of the GNU Lesser General Public License as published by
69.19 - * the Free Software Foundation; either version 2 of the License, or
69.20 - * (at your option) any later version.
69.21 - *
69.22 - * This program is distributed in the hope that it will be useful,
69.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
69.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
69.25 - * GNU General Public License for more details.
69.26 - *
69.27 - * You should have received a copy of the GNU Lesser General Public License
69.28 - * along with this program; if not, write to the Free Software
69.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
69.30 - */
69.31 -
69.32 -#ifndef GMYTH_STRING_LIST_H_
69.33 -#define GMYTH_STRING_LIST_H_
69.34 -
69.35 -#include <glib-object.h>
69.36 -
69.37 -#include <stdio.h>
69.38 -#include <stdlib.h>
69.39 -#include <string.h>
69.40 -#include <netdb.h>
69.41 -#include <sys/socket.h>
69.42 -#include <unistd.h>
69.43 -
69.44 -G_BEGIN_DECLS
69.45 -
69.46 -#define GMYTH_STRING_LIST_TYPE (gmyth_string_list_get_type ())
69.47 -#define GMYTH_STRING_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE, GMythStringList))
69.48 -#define GMYTH_STRING_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
69.49 -#define IS_GMYTH_STRING_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE))
69.50 -#define IS_GMYTH_STRING_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE))
69.51 -#define GMYTH_STRING_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
69.52 -
69.53 -
69.54 -typedef struct _GMythStringList GMythStringList;
69.55 -typedef struct _GMythStringListClass GMythStringListClass;
69.56 -
69.57 -struct _GMythStringListClass
69.58 -{
69.59 - GObjectClass parent_class;
69.60 -
69.61 - /* callbacks */
69.62 - /* no one for now */
69.63 -};
69.64 -
69.65 -struct _GMythStringList
69.66 -{
69.67 - GObject parent;
69.68 -
69.69 - /* string list */
69.70 - GList *glist;
69.71 -};
69.72 -
69.73 -
69.74 -GType gmyth_string_list_get_type (void);
69.75 -
69.76 -GMythStringList * gmyth_string_list_new ();
69.77 -
69.78 -void gmyth_string_list_clear_all (GMythStringList *strlist);
69.79 -int gmyth_string_list_length (GMythStringList *strlist);
69.80 -
69.81 -GString * gmyth_string_list_append_int (GMythStringList *strlist,
69.82 - const gint value);
69.83 -GString * gmyth_string_list_append_uint64 (GMythStringList *strlist,
69.84 - const guint64 value);
69.85 -
69.86 -GString * gmyth_string_list_append_char_array (GMythStringList *strlist,
69.87 - const char* value);
69.88 -GString * gmyth_string_list_append_string (GMythStringList *strlist,
69.89 - GString *value);
69.90 -
69.91 -int gmyth_string_list_get_int (GMythStringList *strlist, const gint index);
69.92 -guint64 gmyth_string_list_get_uint64 (GMythStringList *strlist, const gint index);
69.93 -GString * gmyth_string_list_get_string (GMythStringList *strlist, const gint index);
69.94 -
69.95 -#define gmyth_string_list_get_char_array(strlist, index) \
69.96 - (gmyth_string_list_get_string(strlist, index))->str
69.97 -
69.98 -G_END_DECLS
69.99 -
69.100 -#endif /*GMYTH_STRING_LIST_H_*/
70.1 --- a/gmyth/src/libgmyth/gmyth_tvchain.c Wed Sep 27 00:08:03 2006 +0100
70.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
70.3 @@ -1,355 +0,0 @@
70.4 -/**
70.5 - * GMyth Library
70.6 - *
70.7 - * @file gmyth/gmyth_tvchain.c
70.8 - *
70.9 - * @brief <p> This component contains functions for creating and accessing
70.10 - * the tvchain functions for live tv playback.
70.11 - *
70.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
70.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
70.14 - *
70.15 - *//*
70.16 - *
70.17 - * This program is free software; you can redistribute it and/or modify
70.18 - * it under the terms of the GNU Lesser General Public License as published by
70.19 - * the Free Software Foundation; either version 2 of the License, or
70.20 - * (at your option) any later version.
70.21 - *
70.22 - * This program is distributed in the hope that it will be useful,
70.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
70.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
70.25 - * GNU General Public License for more details.
70.26 - *
70.27 - * You should have received a copy of the GNU Lesser General Public License
70.28 - * along with this program; if not, write to the Free Software
70.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
70.30 - */
70.31 -
70.32 -#include <glib.h>
70.33 -#include <time.h>
70.34 -#include <stdio.h>
70.35 -#include <stdlib.h>
70.36 -
70.37 -#include "gmyth_epg.h"
70.38 -#include "gmyth_tvchain.h"
70.39 -#include "gmyth_util.h"
70.40 -#include "gmyth_query.h"
70.41 -#include "gmyth_scheduler.h"
70.42 -
70.43 -static void gmyth_tvchain_class_init (GMythTVChainClass *klass);
70.44 -static void gmyth_tvchain_init (GMythTVChain *object);
70.45 -
70.46 -static void gmyth_tvchain_dispose (GObject *object);
70.47 -static void gmyth_tvchain_finalize (GObject *object);
70.48 -
70.49 -G_DEFINE_TYPE(GMythTVChain, gmyth_tvchain, G_TYPE_OBJECT)
70.50 -
70.51 -static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
70.52 -
70.53 -static void
70.54 -gmyth_tvchain_class_init (GMythTVChainClass *klass)
70.55 -{
70.56 - GObjectClass *gobject_class;
70.57 -
70.58 - gobject_class = (GObjectClass *) klass;
70.59 -
70.60 - gobject_class->dispose = gmyth_tvchain_dispose;
70.61 - gobject_class->finalize = gmyth_tvchain_finalize;
70.62 -}
70.63 -
70.64 -static void
70.65 -gmyth_tvchain_init (GMythTVChain *tvchain)
70.66 -{
70.67 - tvchain->tvchain_id = NULL;
70.68 -
70.69 - tvchain->cur_chanid = g_string_new ("");
70.70 - tvchain->cur_startts = 0;
70.71 -}
70.72 -
70.73 -static void
70.74 -gmyth_tvchain_dispose (GObject *object)
70.75 -{
70.76 - GMythTVChain *tvchain = GMYTH_TVCHAIN(object);
70.77 -
70.78 - if ( tvchain->tvchain_id != NULL ) {
70.79 - g_string_free( tvchain->tvchain_id, TRUE );
70.80 - tvchain->tvchain_id = NULL;
70.81 - }
70.82 -
70.83 - if ( tvchain->tvchain_list != NULL ) {
70.84 - g_list_free( tvchain->tvchain_list );
70.85 - tvchain->tvchain_list = NULL;
70.86 - }
70.87 -
70.88 - if ( tvchain->cur_chanid != NULL ) {
70.89 - g_string_free( tvchain->cur_chanid, TRUE );
70.90 - tvchain->cur_chanid = NULL;
70.91 - }
70.92 -
70.93 - G_OBJECT_CLASS (gmyth_tvchain_parent_class)->dispose (object);
70.94 -}
70.95 -
70.96 -static void
70.97 -gmyth_tvchain_finalize (GObject *object)
70.98 -{
70.99 - g_signal_handlers_destroy (object);
70.100 -
70.101 - G_OBJECT_CLASS (gmyth_tvchain_parent_class)->finalize (object);
70.102 -}
70.103 -
70.104 -/** Initializes the tvchain and generates the tvchain id.
70.105 - *
70.106 - * @param tvchain The GMythTVChain instance.
70.107 - * @param hostname The local hostname used to generate the tvchain id.
70.108 - */
70.109 -void
70.110 -gmyth_tvchain_initialize (GMythTVChain *tvchain, GString *hostname)
70.111 -{
70.112 - if (tvchain->tvchain_id == NULL) {
70.113 - GString *isodate;
70.114 - time_t cur_time;
70.115 -
70.116 - time(&cur_time);
70.117 - isodate = gmyth_util_time_to_isoformat (cur_time);
70.118 -
70.119 - tvchain->tvchain_id = g_string_sized_new(7 + hostname->len + isodate->len);
70.120 - g_string_printf(tvchain->tvchain_id,
70.121 - "live-%s-%s", hostname->str, isodate->str);
70.122 -
70.123 - g_print("tv_chain_id: %s\n", tvchain->tvchain_id->str);
70.124 -
70.125 - g_string_free(isodate, TRUE);
70.126 -
70.127 - } else {
70.128 - g_warning ("[%s] TVchain already initialized", __FUNCTION__);
70.129 - }
70.130 -}
70.131 -
70.132 -/** Gets the tvchain id.
70.133 - *
70.134 - * @param tvchain The GMythTVChain instance.
70.135 - * @return The tvchain id.
70.136 - */
70.137 -GString*
70.138 -gmyth_tvchain_get_id (GMythTVChain *tvchain)
70.139 -{
70.140 - g_return_val_if_fail( tvchain != NULL && tvchain->tvchain_id != NULL, NULL );
70.141 -
70.142 - return g_string_new (tvchain->tvchain_id->str);
70.143 -}
70.144 -
70.145 -/** Reloads all tvchain entries in the database.
70.146 - *
70.147 - * @param tvchain The GMythTVChain instance.
70.148 - * @return TRUE if success, or FALSE if error.
70.149 - */
70.150 -gboolean
70.151 -gmyth_tvchain_reload_all (GMythTVChain *tvchain)
70.152 -{
70.153 - MYSQL_ROW msql_row;
70.154 - MYSQL_RES *msql_res;
70.155 - GMythQuery *gmyth_query;
70.156 - gboolean ret = TRUE;
70.157 -
70.158 - GString *stmt_str;
70.159 -
70.160 - g_static_mutex_lock( &mutex );
70.161 -
70.162 - guint prev_size = g_list_length (tvchain->tvchain_list);
70.163 -
70.164 - g_debug ("[%s] chainid: %s", __FUNCTION__, tvchain->tvchain_id->str);
70.165 -
70.166 - if ( tvchain != NULL && tvchain->tvchain_list != NULL ) {
70.167 - g_list_free (tvchain->tvchain_list);
70.168 - tvchain->tvchain_list = NULL;
70.169 - }
70.170 -
70.171 - // TODO: Reuse gmyth_query already connected from context
70.172 - gmyth_query = gmyth_query_new ();
70.173 - if (!gmyth_query_connect (gmyth_query)) {
70.174 - g_warning ("[%s] Could not connect to db", __FUNCTION__);
70.175 - g_static_mutex_unlock( &mutex );
70.176 -
70.177 - ret = FALSE;
70.178 -
70.179 - goto done;
70.180 - }
70.181 -
70.182 - stmt_str = g_string_new ("");
70.183 - g_string_printf (stmt_str,
70.184 - "SELECT chanid, starttime, endtime, discontinuity, "
70.185 - "chainpos, hostprefix, cardtype, channame, input "
70.186 - "FROM tvchain "
70.187 - "WHERE chainid = \"%s\" ORDER BY chainpos;",
70.188 - tvchain->tvchain_id->str);
70.189 -
70.190 - msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
70.191 - if (msql_res != NULL) {
70.192 -
70.193 - while ((msql_row = mysql_fetch_row (msql_res)) != NULL) {
70.194 - struct LiveTVChainEntry *entry = g_new0 (struct LiveTVChainEntry, 1);
70.195 - entry->chanid = g_string_new (msql_row[0]);
70.196 - entry->starttime = gmyth_util_string_to_time (g_string_new ((gchar*)msql_row[1]));
70.197 - entry->endtime = gmyth_util_string_to_time (g_string_new (msql_row[2]));
70.198 - entry->discontinuity = atoi (msql_row[3]) != 0;
70.199 - entry->hostprefix = g_string_new (msql_row[5]);
70.200 - entry->cardtype = g_string_new (msql_row[6]);
70.201 - entry->channum = g_string_new (msql_row[7]);
70.202 - entry->inputname = g_string_new (msql_row[8]);
70.203 -
70.204 - //m_maxpos = query.value(4).toInt() + 1;
70.205 -
70.206 - tvchain->tvchain_list = g_list_append (tvchain->tvchain_list, entry);
70.207 - }
70.208 - } else {
70.209 - g_warning ("gmyth_tvchain_reload_all query error!\n");
70.210 - g_static_mutex_unlock( &mutex );
70.211 -
70.212 - ret = FALSE;
70.213 - goto done;
70.214 - }
70.215 -
70.216 - g_static_mutex_unlock( &mutex );
70.217 -
70.218 - tvchain->cur_pos = gmyth_tvchain_program_is_at (tvchain, tvchain->cur_chanid, tvchain->cur_startts);
70.219 -
70.220 - if (tvchain->cur_pos < 0)
70.221 - tvchain->cur_pos = 0;
70.222 -
70.223 - // if (m_switchid >= 0)
70.224 - // m_switchid = ProgramIsAt(m_switchentry.chanid,m_switchentry.starttime);
70.225 -
70.226 - if (prev_size != g_list_length (tvchain->tvchain_list)) {
70.227 - g_debug ("[%s] Added new recording", __FUNCTION__);
70.228 - }
70.229 -
70.230 -done:
70.231 - if ( stmt_str != NULL )
70.232 - g_string_free (stmt_str, TRUE);
70.233 -
70.234 - if ( msql_res != NULL )
70.235 - mysql_free_result (msql_res);
70.236 -
70.237 - if ( gmyth_query != NULL )
70.238 - g_object_unref (gmyth_query);
70.239 -
70.240 - return ret;
70.241 -}
70.242 -
70.243 -/** Returns the internal index for the TV chain related to the given
70.244 - * channel and start time.
70.245 - *
70.246 - * @param tvchain The GMythTVChain instance.
70.247 - * @param chanid The channel id.
70.248 - * @param startts The program start time.
70.249 - */
70.250 -int
70.251 -gmyth_tvchain_program_is_at (GMythTVChain *tvchain, GString *chanid, time_t startts)
70.252 -{
70.253 - int count = 0;
70.254 - struct LiveTVChainEntry *entry;
70.255 - GList *tmp_list = tvchain->tvchain_list;
70.256 -
70.257 - g_static_mutex_lock( &mutex );
70.258 -
70.259 - for (; tmp_list; tmp_list = tvchain->tvchain_list->next, ++count)
70.260 - {
70.261 - entry = (struct LiveTVChainEntry*) tmp_list->data;
70.262 - if (!g_strncasecmp (entry->chanid->str, chanid->str, chanid->len)
70.263 - && entry->starttime == startts)
70.264 - {
70.265 - g_static_mutex_unlock( &mutex );
70.266 - return count;
70.267 - }
70.268 - }
70.269 - g_static_mutex_unlock( &mutex );
70.270 -
70.271 - return -1;
70.272 -}
70.273 -
70.274 -/** Get the program info associated to the tvchain.
70.275 - *
70.276 - * @param tvchain The GMythTVChain instance.
70.277 - * @param index The tvchain index.
70.278 - * @return The program info structure.
70.279 - */
70.280 -GMythProgramInfo*
70.281 -gmyth_tvchain_get_program_at (GMythTVChain *tvchain, int index)
70.282 -{
70.283 - struct LiveTVChainEntry *entry;
70.284 -
70.285 - entry = gmyth_tvchain_get_entry_at (tvchain, index);
70.286 -
70.287 - if (entry)
70.288 - return gmyth_tvchain_entry_to_program (tvchain, entry);
70.289 -
70.290 - return NULL;
70.291 -}
70.292 -
70.293 -/** Gets a LiveTVChainEntry associated to the tvchain by its index.
70.294 - *
70.295 - * @param tvchain The GMythTVChain instance.
70.296 - * @param index The tvchain entry index
70.297 - * @return The LiveTVchainEntry structure.
70.298 - */
70.299 -struct LiveTVChainEntry*
70.300 -gmyth_tvchain_get_entry_at (GMythTVChain *tvchain, int index)
70.301 -{
70.302 - struct LiveTVChainEntry* chain_entry = NULL;
70.303 -
70.304 - g_return_val_if_fail( tvchain != NULL && tvchain->tvchain_list != NULL, NULL );
70.305 -
70.306 - g_static_mutex_lock( &mutex );
70.307 -
70.308 - int size = g_list_length (tvchain->tvchain_list);
70.309 - int new_index = (index < 0 || index >= size) ? size - 1 : index;
70.310 -
70.311 - if (new_index >= 0)
70.312 - chain_entry = (struct LiveTVChainEntry*) g_list_nth_data (tvchain->tvchain_list, new_index);
70.313 -
70.314 - g_static_mutex_unlock( &mutex );
70.315 -
70.316 - if ( chain_entry != NULL ) {
70.317 - g_debug ("[%s] Got TV Chain entry at %d.\n", __FUNCTION__, new_index );
70.318 -
70.319 - } else {
70.320 - g_warning ("[%s] failed to get entry at index %d", __FUNCTION__, index);
70.321 - }
70.322 -
70.323 - return chain_entry;
70.324 -}
70.325 -
70.326 -/** Gets the program info from backend database associated to the tv chain entry.
70.327 - *
70.328 - * @param tvchain The GMythTVChain instance.
70.329 - * @param entry the LiveTVChainEntry to be converted.
70.330 - * @return The progrma info.
70.331 - */
70.332 -GMythProgramInfo*
70.333 -gmyth_tvchain_entry_to_program (GMythTVChain *tvchain, struct LiveTVChainEntry *entry)
70.334 -{
70.335 - GMythProgramInfo *proginfo = NULL;
70.336 -
70.337 - g_return_val_if_fail( tvchain != NULL, NULL );
70.338 -
70.339 - if (!entry || !tvchain) {
70.340 - g_warning ("gmyth_tvchain_entry_to_program() received NULL argument");
70.341 - return NULL;
70.342 - }
70.343 -
70.344 - GMythScheduler *scheduler = gmyth_scheduler_new ();
70.345 -
70.346 - gmyth_scheduler_connect( scheduler );
70.347 - proginfo = gmyth_scheduler_get_recorded (scheduler,
70.348 - entry->chanid, entry->starttime);
70.349 - gmyth_scheduler_disconnect( scheduler );
70.350 -
70.351 - if (proginfo) {
70.352 - proginfo->pathname = g_string_prepend (proginfo->pathname, entry->hostprefix->str);
70.353 - } else {
70.354 - g_warning ("tvchain_entry_to_program(%s, %ld) failed!", entry->chanid->str, entry->starttime);
70.355 - }
70.356 -
70.357 - return proginfo;
70.358 -}
71.1 --- a/gmyth/src/libgmyth/gmyth_tvchain.h Wed Sep 27 00:08:03 2006 +0100
71.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
71.3 @@ -1,105 +0,0 @@
71.4 -/**
71.5 - * GMyth Library
71.6 - *
71.7 - * @file gmyth/gmyth_tvchain.h
71.8 - *
71.9 - * @brief <p> This component contains functions for creating and accessing
71.10 - * the tvchain functions for live tv playback.
71.11 - *
71.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
71.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
71.14 - *
71.15 - *//*
71.16 - *
71.17 - * This program is free software; you can redistribute it and/or modify
71.18 - * it under the terms of the GNU Lesser General Public License as published by
71.19 - * the Free Software Foundation; either version 2 of the License, or
71.20 - * (at your option) any later version.
71.21 - *
71.22 - * This program is distributed in the hope that it will be useful,
71.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
71.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
71.25 - * GNU General Public License for more details.
71.26 - *
71.27 - * You should have received a copy of the GNU Lesser General Public License
71.28 - * along with this program; if not, write to the Free Software
71.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
71.30 - */
71.31 -
71.32 -#ifndef LIVETVCHAIN_H_
71.33 -#define LIVETVCHAIN_H_
71.34 -
71.35 -#include <glib-object.h>
71.36 -#include <time.h>
71.37 -
71.38 -#include "gmyth_common.h"
71.39 -
71.40 -G_BEGIN_DECLS
71.41 -
71.42 -#define GMYTH_TVCHAIN_TYPE (gmyth_tvchain_get_type ())
71.43 -#define GMYTH_TVCHAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChain))
71.44 -#define GMYTH_TVCHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
71.45 -#define IS_GMYTH_TVCHAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE))
71.46 -#define IS_GMYTH_TVCHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE))
71.47 -#define GMYTH_TVCHAIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
71.48 -
71.49 -
71.50 -typedef struct _GMythTVChain GMythTVChain;
71.51 -typedef struct _GMythTVChainClass GMythTVChainClass;
71.52 -
71.53 -
71.54 -struct LiveTVChainEntry
71.55 -{
71.56 - GString *chanid;
71.57 -
71.58 - time_t starttime;
71.59 - time_t endtime;
71.60 -
71.61 - gboolean discontinuity; // if true, can't play smooth from last entry
71.62 - GString *hostprefix;
71.63 - GString *cardtype;
71.64 - GString *channum;
71.65 - GString *inputname;
71.66 -};
71.67 -
71.68 -
71.69 -struct _GMythTVChainClass
71.70 -{
71.71 - GObjectClass parent_class;
71.72 -
71.73 - /* callbacks */
71.74 - /* no one for now */
71.75 -};
71.76 -
71.77 -struct _GMythTVChain
71.78 -{
71.79 - GObject parent;
71.80 -
71.81 - GString *tvchain_id;
71.82 - GList *tvchain_list;
71.83 -
71.84 - time_t cur_startts;
71.85 - GString *cur_chanid;
71.86 - int cur_pos;
71.87 -};
71.88 -
71.89 -
71.90 -GType gmyth_tvchain_get_type (void);
71.91 -
71.92 -void gmyth_tvchain_initialize (GMythTVChain *tvchain,
71.93 - GString *hostname);
71.94 -gboolean gmyth_tvchain_reload_all (GMythTVChain *tvchain);
71.95 -GString* gmyth_tvchain_get_id (GMythTVChain *tvchain);
71.96 -int gmyth_tvchain_program_is_at (GMythTVChain *tvchain,
71.97 - GString *chanid, time_t startts);
71.98 -
71.99 -struct LiveTVChainEntry* gmyth_tvchain_get_entry_at (GMythTVChain *tvchain,
71.100 - gint index);
71.101 -
71.102 -GMythProgramInfo* gmyth_tvchain_entry_to_program (GMythTVChain *tvchain,
71.103 - struct LiveTVChainEntry *entry);
71.104 -GMythProgramInfo* gmyth_tvchain_get_program_at (GMythTVChain *tvchain, gint index);
71.105 -
71.106 -G_END_DECLS
71.107 -
71.108 -#endif /*LIVETVCHAIN_H_*/
72.1 --- a/gmyth/src/libgmyth/gmyth_tvplayer.c Wed Sep 27 00:08:03 2006 +0100
72.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
72.3 @@ -1,684 +0,0 @@
72.4 -/**
72.5 - * GMyth Library
72.6 - *
72.7 - * @file gmyth/gmyth_tvplayer.c
72.8 - *
72.9 - * @brief <p> This component provides playback of the remote A/V using
72.10 - * GStreamer.
72.11 - *
72.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
72.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
72.14 - *
72.15 - *//*
72.16 - *
72.17 - * This program is free software; you can redistribute it and/or modify
72.18 - * it under the terms of the GNU Lesser General Public License as published by
72.19 - * the Free Software Foundation; either version 2 of the License, or
72.20 - * (at your option) any later version.
72.21 - *
72.22 - * This program is distributed in the hope that it will be useful,
72.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
72.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72.25 - * GNU General Public License for more details.
72.26 - *
72.27 - * You should have received a copy of the GNU Lesser General Public License
72.28 - * along with this program; if not, write to the Free Software
72.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
72.30 - */
72.31 -
72.32 -#include "gmyth_tvplayer.h"
72.33 -
72.34 -#include <gdk/gdkx.h>
72.35 -
72.36 -#include "gmyth_context.h"
72.37 -#include "gmyth_remote_util.h"
72.38 -
72.39 -typedef struct _GstPlayerWindowStateChange
72.40 -{
72.41 - GstElement *play;
72.42 - GstState old_state, new_state;
72.43 - GMythTVPlayer *tvplayer;
72.44 -} GstPlayerWindowStateChange;
72.45 -
72.46 -typedef struct _GstPlayerWindowTagFound
72.47 -{
72.48 - GstElement *play;
72.49 - GstTagList *taglist;
72.50 - GMythTVPlayer *tvplayer;
72.51 -} GstPlayerWindowTagFound;
72.52 -
72.53 -/*
72.54 -static gboolean idle_state (gpointer data);
72.55 -*/
72.56 -static gboolean bus_call (GstBus * bus, GstMessage * msg, gpointer data);
72.57 -
72.58 -static void gmyth_tvplayer_class_init (GMythTVPlayerClass *klass);
72.59 -static void gmyth_tvplayer_init (GMythTVPlayer *object);
72.60 -
72.61 -static void gmyth_tvplayer_dispose (GObject *object);
72.62 -static void gmyth_tvplayer_finalize (GObject *object);
72.63 -
72.64 -G_DEFINE_TYPE(GMythTVPlayer, gmyth_tvplayer, G_TYPE_OBJECT)
72.65 -
72.66 -static gboolean gmyth_tvplayer_create_pipeline (GMythTVPlayer* tvplayer);
72.67 -static void new_pad_cb (GstElement *element,
72.68 - GstPad *pad, gpointer data);
72.69 -
72.70 -static gboolean expose_cb (GtkWidget * widget,
72.71 - GdkEventExpose * event,
72.72 - gpointer user_data);
72.73 -
72.74 -static void
72.75 -gmyth_tvplayer_class_init (GMythTVPlayerClass *klass)
72.76 -{
72.77 - GObjectClass *gobject_class;
72.78 -
72.79 - gobject_class = (GObjectClass *) klass;
72.80 -
72.81 - gobject_class->dispose = gmyth_tvplayer_dispose;
72.82 - gobject_class->finalize = gmyth_tvplayer_finalize;
72.83 -}
72.84 -
72.85 -static void
72.86 -new_pad_cb (GstElement *element, GstPad *pad, gpointer data)
72.87 -{
72.88 - GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (data);
72.89 - GstPadLinkReturn ret;
72.90 - char *s;
72.91 -
72.92 - s = gst_caps_to_string (pad->caps);
72.93 -
72.94 - if ( s[0] == 'a') {
72.95 - ret = gst_pad_link (pad, gst_element_get_pad (tvplayer->audioqueue, "sink"));
72.96 - } else {
72.97 - ret = gst_pad_link (pad, gst_element_get_pad (tvplayer->videoqueue, "sink"));
72.98 - }
72.99 -
72.100 - g_free(s);
72.101 -}
72.102 -
72.103 -static gboolean
72.104 -expose_cb (GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
72.105 -{
72.106 - GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (user_data);
72.107 -
72.108 - if (tvplayer && tvplayer->videow) {
72.109 - gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (tvplayer->gst_videosink),
72.110 - GDK_WINDOW_XWINDOW (widget->window));
72.111 - return TRUE;
72.112 - }
72.113 -
72.114 - g_warning ("GMythTVPlayer expose called before setting video window\n");
72.115 -
72.116 - return FALSE;
72.117 -}
72.118 -
72.119 -static void
72.120 -gmyth_tvplayer_init (GMythTVPlayer *tvplayer)
72.121 -{
72.122 - tvplayer->gst_pipeline = NULL;
72.123 - tvplayer->gst_source = NULL;
72.124 - tvplayer->gst_videodec = NULL;
72.125 - tvplayer->gst_videosink = NULL;
72.126 - tvplayer->videoqueue = NULL;
72.127 - tvplayer->audioqueue = NULL;
72.128 -
72.129 - /* GTKWidget for rendering the video */
72.130 - tvplayer->videow = NULL;
72.131 - tvplayer->expose_handler = 0;
72.132 -
72.133 - tvplayer->backend_hostname = NULL;
72.134 - tvplayer->backend_port = 0;
72.135 - tvplayer->local_hostname = NULL;
72.136 -
72.137 - tvplayer->remote_encoder = NULL;
72.138 - tvplayer->tvchain = NULL;
72.139 - tvplayer->proginfo = NULL;
72.140 -}
72.141 -
72.142 -static void
72.143 -gmyth_tvplayer_dispose (GObject *object)
72.144 -{
72.145 -
72.146 - G_OBJECT_CLASS (gmyth_tvplayer_parent_class)->dispose (object);
72.147 -}
72.148 -
72.149 -static void
72.150 -gmyth_tvplayer_finalize (GObject *object)
72.151 -{
72.152 - g_signal_handlers_destroy (object);
72.153 -
72.154 - GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (object);
72.155 -
72.156 - g_debug ("[%s] Finalizing tvplayer", __FUNCTION__);
72.157 -
72.158 - if (tvplayer->videow != NULL) {
72.159 - if (g_signal_handler_is_connected (tvplayer->videow,
72.160 - tvplayer->expose_handler)) {
72.161 - g_signal_handler_disconnect (tvplayer->videow,
72.162 - tvplayer->expose_handler);
72.163 - }
72.164 - g_object_unref (tvplayer->videow);
72.165 - }
72.166 -
72.167 - if ( tvplayer->remote_encoder != NULL )
72.168 - g_object_unref (tvplayer->remote_encoder);
72.169 - if ( tvplayer->tvchain != NULL )
72.170 - g_object_unref (tvplayer->tvchain);
72.171 - if ( tvplayer->proginfo != NULL )
72.172 - g_object_unref (tvplayer->proginfo);
72.173 -
72.174 - // Release Gstreamer elements
72.175 - if ( tvplayer->gst_pipeline != NULL )
72.176 - g_object_unref (tvplayer->gst_pipeline);
72.177 - if ( tvplayer->gst_source != NULL )
72.178 - g_object_unref (tvplayer->gst_source);
72.179 - if ( tvplayer->gst_videodec != NULL )
72.180 - g_object_unref (tvplayer->gst_videodec);
72.181 - if ( tvplayer->gst_videosink != NULL )
72.182 - g_object_unref (tvplayer->gst_videosink);
72.183 - if ( tvplayer->videoqueue != NULL )
72.184 - g_object_unref (tvplayer->videoqueue);
72.185 - if ( tvplayer->audioqueue != NULL )
72.186 - g_object_unref (tvplayer->audioqueue);
72.187 -
72.188 - G_OBJECT_CLASS (gmyth_tvplayer_parent_class)->finalize (object);
72.189 -}
72.190 -
72.191 -/** Creates a new instance of GMythTVPlayer.
72.192 - *
72.193 - * @return a new instance of GMythTVPlayer.
72.194 - */
72.195 -GMythTVPlayer *
72.196 -gmyth_tvplayer_new ()
72.197 -{
72.198 - GMythTVPlayer *tvplayer =
72.199 - GMYTH_TVPLAYER (g_object_new(GMYTH_TVPLAYER_TYPE, NULL));
72.200 -
72.201 - return tvplayer;
72.202 -}
72.203 -
72.204 -/** Initializes the tv player.
72.205 - *
72.206 - * @param tvplayer the object instance.
72.207 - * @return gboolean TRUE if the pipeline was created
72.208 - * successfully, FALSE otherwise.
72.209 - */
72.210 -gboolean
72.211 -gmyth_tvplayer_initialize (GMythTVPlayer *tvplayer)
72.212 -{
72.213 -
72.214 - if (!gmyth_tvplayer_create_pipeline (tvplayer)) {
72.215 - g_warning ("[%s] Error while creating pipeline. TV Player not initialized", __FUNCTION__);
72.216 - return FALSE;
72.217 - } else {
72.218 - g_debug ("[%s] GStreamer pipeline created", __FUNCTION__);
72.219 - }
72.220 -
72.221 - return TRUE;
72.222 -}
72.223 -
72.224 -/** Creates the GStreamer pipeline used by the player.
72.225 - *
72.226 - * @param tvplayer the object instance.
72.227 - * @return gboolean TRUE if the pipeline was created
72.228 - * successfully, FALSE otherwise.
72.229 - */
72.230 -static gboolean
72.231 -gmyth_tvplayer_create_pipeline (GMythTVPlayer* tvplayer)
72.232 -{
72.233 - GstElement *pipeline;
72.234 - GstElement *source, *parser;
72.235 - GstElement *videodec, *videosink;
72.236 -#ifndef MAEMO_PLATFORM
72.237 - GstElement *audiodec, *audioconv;
72.238 -#endif
72.239 - GstElement *audiosink;
72.240 - GstElement *videoqueue, *audioqueue;
72.241 -
72.242 - g_debug ("GMythTVPlayer: Setting the Gstreamer pipeline\n");
72.243 -
72.244 - pipeline = gst_pipeline_new ("video-player");
72.245 - source = gst_element_factory_make ("mythtvsrc", "myth-source");
72.246 - parser = gst_element_factory_make ("ffdemux_nuv", "nuv-demux");
72.247 -
72.248 - /* Gstreamer Video elements */
72.249 - videoqueue = gst_element_factory_make ("queue", "video-queue");
72.250 - videodec = gst_element_factory_make ("ffdec_mpeg4", "video-decoder");
72.251 -#ifdef MAEMO_PLATFORM
72.252 - videosink = gst_element_factory_make ("sdlvideosink", "image-output");
72.253 -#else
72.254 - videosink = gst_element_factory_make ("xvimagesink", "image-output");
72.255 -#endif
72.256 -
72.257 - /* Gstreamer Audio elements */
72.258 - audioqueue = gst_element_factory_make ("queue", "audio-queue");
72.259 -#ifdef MAEMO_PLATFORM
72.260 - audiosink = gst_element_factory_make ("dspmp3sink", "audio-output");
72.261 -#else
72.262 - audiodec = gst_element_factory_make ("ffdec_mp3", "audio-decoder");
72.263 - audioconv = gst_element_factory_make ("audioconvert", "audio-converter");
72.264 - audiosink = gst_element_factory_make ("alsasink", "audio-output");
72.265 -#endif
72.266 -
72.267 - if (!(pipeline && source && parser && videodec && videosink) ||
72.268 - !(videoqueue && audioqueue && audiosink)) {
72.269 - /* FIXME: hanlde the error correctly */
72.270 - /* video_alignment is not being created (below)
72.271 - and is causing problems to the ui */
72.272 -
72.273 - tvplayer->gst_pipeline = NULL;
72.274 - tvplayer->gst_videodec = NULL;
72.275 - tvplayer->gst_videosink = NULL;
72.276 -
72.277 - g_warning ("GstElement creation error!\n");
72.278 - return FALSE;
72.279 - }
72.280 -
72.281 -#ifndef MAEMO_PLATFORM
72.282 - if (!(audiodec && audioconv)) {
72.283 - g_warning ("GstElement for audio stream creation error!");
72.284 - return FALSE;
72.285 - }
72.286 -#endif
72.287 -
72.288 -
72.289 - tvplayer->gst_pipeline = pipeline;
72.290 - tvplayer->gst_source = source;
72.291 - tvplayer->gst_videodec = videodec;
72.292 - tvplayer->gst_videosink = videosink;
72.293 - g_object_ref (tvplayer->gst_pipeline);
72.294 - g_object_ref (tvplayer->gst_source);
72.295 - g_object_ref (tvplayer->gst_videodec);
72.296 - g_object_ref (tvplayer->gst_videosink);
72.297 -
72.298 - tvplayer->videoqueue = videoqueue;
72.299 - tvplayer->audioqueue = audioqueue;
72.300 - g_object_ref (tvplayer->videoqueue);
72.301 - g_object_ref (tvplayer->audioqueue);
72.302 -
72.303 - g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
72.304 - g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
72.305 -
72.306 - gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (tvplayer->gst_pipeline)),
72.307 - bus_call, tvplayer);
72.308 -
72.309 - gst_bin_add_many (GST_BIN (pipeline), source, parser, videoqueue,
72.310 - videodec, videosink, audioqueue, audiodec, audioconv, audiosink, NULL);
72.311 -
72.312 - {
72.313 -// GstCaps *rtpcaps = gst_caps_new_simple ("application/x-rtp", NULL);
72.314 -// gst_element_link_filtered(source, parser, rtpcaps);
72.315 - }
72.316 -
72.317 - gst_element_link (source, parser);
72.318 - gst_element_link_many (videoqueue, videodec, videosink, NULL);
72.319 - gst_element_link_many (audioqueue, audiodec, audioconv, audiosink, NULL);
72.320 -
72.321 - g_signal_connect (parser, "pad-added", G_CALLBACK (new_pad_cb), tvplayer);
72.322 -
72.323 - return TRUE;
72.324 -}
72.325 -
72.326 -/** Configures the backend and the tv player
72.327 - * for playing the recorded content A/V.
72.328 - *
72.329 - * FIXME: Change filename to program info or other structure about the recorded
72.330 - *
72.331 - * @param tvplayer the object instance.
72.332 - * @param filename the file uri of the recorded content to be played.
72.333 - * @return TRUE if successfull, FALSE if any error happens.
72.334 - */
72.335 -gboolean
72.336 -gmyth_tvplayer_record_setup (GMythTVPlayer *tvplayer, gchar *filename)
72.337 -{
72.338 - GMythSettings *msettings = gmyth_context_get_settings();
72.339 -
72.340 - // FIXME: we should receive the uri instead of filename
72.341 - GString *hostname = gmyth_settings_get_backend_hostname (msettings);
72.342 - int port = gmyth_settings_get_backend_port(msettings);
72.343 -
72.344 - GString *fullpath = g_string_new ("myth://");
72.345 - g_string_append_printf (fullpath, "%s:%d/%s", hostname->str, port, filename);
72.346 -
72.347 - tvplayer->is_livetv = FALSE;
72.348 -
72.349 - g_debug ("[%s] Setting record uri to gstreamer pipeline to %s", __FUNCTION__, fullpath->str);
72.350 -
72.351 - g_object_set (G_OBJECT (tvplayer->gst_source), "location",
72.352 - fullpath->str, NULL);
72.353 -
72.354 - return TRUE;
72.355 -}
72.356 -
72.357 -/** Configures the backend and the tv player
72.358 - * for playing the live tv.
72.359 - *
72.360 - * @param tvplayer the object instance.
72.361 - * @return TRUE if successfull, FALSE if any error happens.
72.362 - */
72.363 -gboolean
72.364 -gmyth_tvplayer_livetv_setup (GMythTVPlayer *tvplayer)
72.365 -{
72.366 - GMythSettings *msettings = gmyth_context_get_settings ();
72.367 - gboolean res = TRUE;
72.368 -
72.369 - res = gmyth_context_check_connection();
72.370 - if (!res) {
72.371 - g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);
72.372 - res = FALSE;
72.373 - goto error;
72.374 - }
72.375 -
72.376 - tvplayer->backend_hostname = gmyth_settings_get_backend_hostname(msettings);
72.377 - tvplayer->backend_port = gmyth_settings_get_backend_port (msettings);
72.378 -
72.379 - tvplayer->local_hostname = g_string_new("");
72.380 - gmyth_context_get_local_hostname (tvplayer->local_hostname);
72.381 -
72.382 - if ( tvplayer->local_hostname == NULL ) {
72.383 - res = FALSE;
72.384 - goto error;
72.385 - }
72.386 -
72.387 - // Gets the remote encoder num
72.388 - tvplayer->remote_encoder = remote_request_next_free_recorder (-1);
72.389 -
72.390 - if ( tvplayer->remote_encoder == NULL ) {
72.391 - g_warning ("[%s] None remote encoder available", __FUNCTION__);
72.392 - res = FALSE;
72.393 - goto error;
72.394 - }
72.395 -
72.396 - // Creates livetv chain handler
72.397 - tvplayer->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
72.398 - gmyth_tvchain_initialize ( tvplayer->tvchain, tvplayer->local_hostname );
72.399 -
72.400 - if ( tvplayer->tvchain == NULL || tvplayer->tvchain->tvchain_id == NULL ) {
72.401 - res = FALSE;
72.402 - goto error;
72.403 - }
72.404 -
72.405 - // Init remote encoder. Opens its control socket.
72.406 - res = gmyth_remote_encoder_setup(tvplayer->remote_encoder);
72.407 - if ( !res ) {
72.408 - g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
72.409 - res = FALSE;
72.410 - goto error;
72.411 - }
72.412 - // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
72.413 - res = gmyth_remote_encoder_spawntv ( tvplayer->remote_encoder,
72.414 - gmyth_tvchain_get_id(tvplayer->tvchain) );
72.415 - if (!res) {
72.416 - g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
72.417 - res = FALSE;
72.418 - goto error;
72.419 - }
72.420 -
72.421 - // Reload all TV chain from Mysql database.
72.422 - gmyth_tvchain_reload_all (tvplayer->tvchain);
72.423 -
72.424 - if ( tvplayer->tvchain == NULL ) {
72.425 - res = FALSE;
72.426 - goto error;
72.427 - }
72.428 -
72.429 - // Get program info from database using chanid and starttime
72.430 - tvplayer->proginfo = gmyth_tvchain_get_program_at (tvplayer->tvchain, -1);
72.431 - if ( tvplayer->proginfo == NULL ) {
72.432 - g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
72.433 - res = FALSE;
72.434 - goto error;
72.435 - } else {
72.436 - g_debug ("[%s] MythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ );
72.437 - }
72.438 -
72.439 - return res;
72.440 -
72.441 -error:
72.442 - if ( tvplayer->backend_hostname != NULL ) {
72.443 - g_string_free( tvplayer->backend_hostname, TRUE );
72.444 - res = FALSE;
72.445 - }
72.446 -
72.447 - if ( tvplayer->local_hostname != NULL ) {
72.448 - g_string_free( tvplayer->local_hostname, TRUE );
72.449 - res = FALSE;
72.450 - }
72.451 -
72.452 - if ( tvplayer->remote_encoder != NULL ) {
72.453 - g_object_unref (tvplayer->remote_encoder);
72.454 - tvplayer->remote_encoder = NULL;
72.455 - }
72.456 -
72.457 - if ( tvplayer->tvchain != NULL ) {
72.458 - g_object_unref (tvplayer->tvchain);
72.459 - tvplayer->tvchain = NULL;
72.460 - }
72.461 -
72.462 - if ( tvplayer->proginfo != NULL ) {
72.463 - g_object_unref (tvplayer->proginfo);
72.464 - tvplayer->proginfo = NULL;
72.465 - }
72.466 -
72.467 - return res;
72.468 -
72.469 -}
72.470 -
72.471 -/** Sets the GTK video widget for the tv player.
72.472 - *
72.473 - * @param tvplayer the object instance.
72.474 - * @param videow the GTK video window.
72.475 - * @return TRUE if successfull, FALSE if any error happens.
72.476 - */
72.477 -gboolean
72.478 -gmyth_tvplayer_set_widget (GMythTVPlayer *tvplayer, GtkWidget *videow)
72.479 -{
72.480 - tvplayer->videow = videow;
72.481 - g_object_ref (videow);
72.482 -
72.483 - g_debug ("[%s] Setting widget for tv player render", __FUNCTION__);
72.484 -
72.485 - tvplayer->expose_handler = g_signal_connect (tvplayer->videow, "expose-event",
72.486 - G_CALLBACK (expose_cb), tvplayer);
72.487 -
72.488 - //g_signal_connect(miptv_ui->videow, "size_request", G_CALLBACK(cb_preferred_video_size), miptv_ui);
72.489 -
72.490 - return TRUE;
72.491 -}
72.492 -
72.493 -static gboolean
72.494 -bus_call (GstBus * bus, GstMessage * msg, gpointer data)
72.495 -{
72.496 - //GMythTVPlayer *tvplayer = GMYTH_TVPLAYER ( data );
72.497 - //GMainLoop *loop = tvplayer->loop;
72.498 -
72.499 - switch (GST_MESSAGE_TYPE (msg)) {
72.500 - case GST_MESSAGE_EOS:
72.501 - printf ("End of stream\n");
72.502 - //g_idle_add ((GSourceFunc) idle_eos, data);
72.503 - gst_element_set_state ( GST_ELEMENT (GST_MESSAGE_SRC (msg)), GST_STATE_NULL );
72.504 - gst_element_set_locked_state ( GST_ELEMENT (GST_MESSAGE_SRC (msg)), FALSE );
72.505 - break;
72.506 - case GST_MESSAGE_ERROR:
72.507 - {
72.508 - gchar *debug;
72.509 - GError *err;
72.510 -
72.511 - gst_message_parse_error (msg, &err, &debug);
72.512 - g_free (debug);
72.513 -
72.514 - printf ("Error: %s\n", err->message);
72.515 - g_error_free (err);
72.516 -
72.517 - //g_main_loop_quit (loop);
72.518 - }
72.519 - break;
72.520 - default:
72.521 - printf (gst_message_type_get_name (GST_MESSAGE_TYPE (msg)));
72.522 - printf ("\n");
72.523 - break;
72.524 - }
72.525 -
72.526 - return TRUE;
72.527 -}
72.528 -
72.529 -
72.530 -#if 0
72.531 -static gboolean
72.532 -idle_state (gpointer data)
72.533 -{
72.534 - GstPlayerWindowStateChange *st = data;
72.535 -
72.536 - if (st->old_state == GST_STATE_PLAYING) {
72.537 - if (st->miptv_ui->idle_id != 0) {
72.538 - g_source_remove (st->miptv_ui->idle_id);
72.539 - st->miptv_ui->idle_id = 0;
72.540 - }
72.541 - }
72.542 - else if (st->new_state == GST_STATE_PLAYING) {
72.543 - if (st->miptv_ui->idle_id != 0)
72.544 - g_source_remove (st->miptv_ui->idle_id);
72.545 -
72.546 - st->miptv_ui->idle_id = g_idle_add (cb_iterate, st->miptv_ui);
72.547 - }
72.548 -
72.549 - /* new movie loaded? */
72.550 - if (st->old_state == GST_STATE_READY && st->new_state > GST_STATE_READY) {
72.551 -
72.552 - /* gboolean have_video = FALSE; */
72.553 -
72.554 - gtk_widget_show (st->miptv_ui->videow);
72.555 -
72.556 - gtk_window_resize (GTK_WINDOW (st->miptv_ui->main_window), 1, 1);
72.557 -
72.558 - }
72.559 -
72.560 - /* discarded movie? */
72.561 - if (st->old_state > GST_STATE_READY && st->new_state == GST_STATE_READY) {
72.562 -
72.563 - if (st->miptv_ui->tagcache) {
72.564 - gst_tag_list_free (st->miptv_ui->tagcache);
72.565 - st->miptv_ui->tagcache = NULL;
72.566 - }
72.567 - }
72.568 -
72.569 - gst_object_unref (GST_OBJECT (st->play));
72.570 - //g_object_unref (G_OBJECT (st->win));
72.571 - g_free (st);
72.572 -
72.573 - /* once */
72.574 - return FALSE;
72.575 -}
72.576 -
72.577 -#endif
72.578 -
72.579 -/** Stops playing the current A/V.
72.580 - *
72.581 - * FIXME: How to proceed differently between livetv
72.582 - * and recorded content?
72.583 - *
72.584 - * @param tvplayer the object instance.
72.585 - * @return void
72.586 - */
72.587 -void
72.588 -gmyth_tvplayer_stop_playing (GMythTVPlayer *tvplayer)
72.589 -{
72.590 - g_debug ("[%s] Setting gstreamer pipeline state to NULL", __FUNCTION__);
72.591 -
72.592 - gst_element_set_state (tvplayer->gst_pipeline, GST_STATE_NULL);
72.593 -
72.594 - if (tvplayer->is_livetv) {
72.595 - if (!gmyth_remote_encoder_stop_livetv (tvplayer->remote_encoder)) {
72.596 - g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);
72.597 - }
72.598 - }
72.599 -}
72.600 -
72.601 -/** Queries if the tvplayer is active playing A/V content.
72.602 - *
72.603 - * @param tvplayer the object instance.
72.604 - * @return TRUE if the tvplayer is active, FALSE otherwise.
72.605 - */
72.606 -gboolean
72.607 -gmyth_tvplayer_is_playing (GMythTVPlayer *tvplayer)
72.608 -{
72.609 - return (GST_STATE (tvplayer->gst_pipeline) == GST_STATE_PLAYING);
72.610 -}
72.611 -
72.612 -/** Static function that sets the tvplayer state to PLAYING.
72.613 - *
72.614 - * @param tvplayer the object instance.
72.615 - * @return TRUE if the tvplayer is active, FALSE otherwise.
72.616 - */
72.617 -static gboolean
72.618 -idle_play (gpointer data)
72.619 -{
72.620 - GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (data);
72.621 -
72.622 - g_debug ("GMythTVPlayer: Setting pipeline state to PLAYING\n");
72.623 -
72.624 - gst_element_set_state (tvplayer->gst_pipeline, GST_STATE_PLAYING);
72.625 -
72.626 - return FALSE;
72.627 -}
72.628 -
72.629 -/** Start playing A/V with the tvplayer attributes.
72.630 - *
72.631 - * @param tvplayer the object instance.
72.632 - */
72.633 -void
72.634 -gmyth_tvplayer_start_playing (GMythTVPlayer *tvplayer)
72.635 -{
72.636 -
72.637 - // FIXME: Move this to livetv_setup??
72.638 - if (tvplayer->is_livetv) {
72.639 -
72.640 - #if 0
72.641 - if (!tvplayer || !(tvplayer->proginfo) || !(tvplayer->local_hostname)
72.642 - || !(tvplayer->gst_source)) {
72.643 - g_warning ("GMythtvPlayer not ready to start playing\n");
72.644 - }
72.645 -
72.646 - if (!(tvplayer->proginfo->pathname)) {
72.647 - g_warning ("[%s] Playback url is null, could not play the myth content", __FUNCTION__);
72.648 - return;
72.649 - }
72.650 -
72.651 - g_debug ("GMythTVPlayer: Start playing %s", tvplayer->proginfo->pathname->str);
72.652 -#endif
72.653 - g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live",
72.654 - TRUE, NULL);
72.655 -#if 0
72.656 - if ( tvplayer->tvchain != NULL ) {
72.657 - GString *str_chainid = gmyth_tvchain_get_id(tvplayer->tvchain);
72.658 - g_print( "[%s]\tCHAIN ID: %s\n", __FUNCTION__, str_chainid->str );
72.659 -
72.660 - g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live-chainid",
72.661 - g_strdup( str_chainid->str ), NULL);
72.662 - if ( str_chainid!=NULL)
72.663 - g_string_free( str_chainid, FALSE );
72.664 - }
72.665 -
72.666 - if ( tvplayer->remote_encoder != NULL )
72.667 - g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live-id",
72.668 - tvplayer->remote_encoder->recorder_num, NULL );
72.669 - g_debug ("[%s] Setting location to %s", __FUNCTION__,
72.670 - tvplayer->proginfo->pathname->str);
72.671 -
72.672 - /* Sets the gstreamer properties acording to the service access address */
72.673 - g_object_set (G_OBJECT (tvplayer->gst_source), "location",
72.674 - tvplayer->proginfo->pathname->str, NULL);
72.675 -#endif
72.676 - }
72.677 -
72.678 - g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-version",
72.679 - MYTHTV_VERSION_DEFAULT, NULL);
72.680 -
72.681 - g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-debug",
72.682 - TRUE, NULL);
72.683 -
72.684 - g_idle_add (idle_play, tvplayer);
72.685 -
72.686 -}
72.687 -
73.1 --- a/gmyth/src/libgmyth/gmyth_tvplayer.h Wed Sep 27 00:08:03 2006 +0100
73.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
73.3 @@ -1,112 +0,0 @@
73.4 -/**
73.5 - * GMyth Library
73.6 - *
73.7 - * @file gmyth/gmyth_tvplayer.h
73.8 - *
73.9 - * @brief <p> This component provides playback of the remote A/V using
73.10 - * GStreamer.
73.11 - *
73.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
73.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
73.14 - *
73.15 - *//*
73.16 - *
73.17 - * This program is free software; you can redistribute it and/or modify
73.18 - * it under the terms of the GNU Lesser General Public License as published by
73.19 - * the Free Software Foundation; either version 2 of the License, or
73.20 - * (at your option) any later version.
73.21 - *
73.22 - * This program is distributed in the hope that it will be useful,
73.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
73.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
73.25 - * GNU General Public License for more details.
73.26 - *
73.27 - * You should have received a copy of the GNU Lesser General Public License
73.28 - * along with this program; if not, write to the Free Software
73.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
73.30 - */
73.31 -
73.32 -#ifndef GMYTH_TVPLAYER_H_
73.33 -#define GMYTH_TVPLAYER_H_
73.34 -
73.35 -#include <glib-object.h>
73.36 -#include <gtk/gtk.h>
73.37 -
73.38 -/* GStreamer includes */
73.39 -#include <gst/gst.h>
73.40 -#include <gst/interfaces/xoverlay.h>
73.41 -
73.42 -#include "gmyth_remote_encoder.h"
73.43 -#include "gmyth_tvchain.h"
73.44 -#include "gmyth_common.h"
73.45 -
73.46 -G_BEGIN_DECLS
73.47 -
73.48 -#define GMYTH_TVPLAYER_TYPE (gmyth_tvplayer_get_type ())
73.49 -#define GMYTH_TVPLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVPLAYER_TYPE, GMythTVPlayer))
73.50 -#define GMYTH_TVPLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVPLAYER_TYPE, GMythTVPlayerClass))
73.51 -#define IS_GMYTH_TVPLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVPLAYER_TYPE))
73.52 -#define IS_GMYTH_TVPLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVPLAYER_TYPE))
73.53 -#define GMYTH_TVPLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVPLAYER_TYPE, GMythTVPlayerClass))
73.54 -
73.55 -
73.56 -typedef struct _GMythTVPlayer GMythTVPlayer;
73.57 -typedef struct _GMythTVPlayerClass GMythTVPlayerClass;
73.58 -
73.59 -struct _GMythTVPlayerClass
73.60 -{
73.61 - GObjectClass parent_class;
73.62 -
73.63 - /* callbacks */
73.64 - /* no one for now */
73.65 -};
73.66 -
73.67 -struct _GMythTVPlayer
73.68 -{
73.69 - GObject parent;
73.70 -
73.71 - GstElement *gst_pipeline;
73.72 - GstElement *gst_source;
73.73 - GstElement *gst_videodec;
73.74 - GstElement *gst_videosink;
73.75 - GstElement *videoqueue;
73.76 - GstElement *audioqueue;
73.77 -
73.78 - gulong expose_handler;
73.79 -// GMainLoop *loop;
73.80 -
73.81 - GtkWidget *videow;
73.82 -
73.83 - /* Backend connection related variables */
73.84 - GString *backend_hostname;
73.85 - gint backend_port;
73.86 - GString *local_hostname;
73.87 -
73.88 - GMythRemoteEncoder *remote_encoder;
73.89 - GMythTVChain *tvchain;
73.90 - GMythProgramInfo *proginfo;
73.91 -
73.92 - gboolean is_livetv;
73.93 -};
73.94 -
73.95 -
73.96 -GType gmyth_tvplayer_get_type (void);
73.97 -
73.98 -GMythTVPlayer* gmyth_tvplayer_new ();
73.99 -gboolean gmyth_tvplayer_initialize (GMythTVPlayer *tvplayer);
73.100 -
73.101 -void gmyth_tvplayer_start_playing (GMythTVPlayer *tvplayer);
73.102 -void gmyth_tvplayer_stop_playing (GMythTVPlayer *tvplayer);
73.103 -
73.104 -gboolean gmyth_tvplayer_set_widget (GMythTVPlayer *tvplayer,
73.105 - GtkWidget *videow);
73.106 -
73.107 -gboolean gmyth_tvplayer_is_playing (GMythTVPlayer *tvplayer);
73.108 -
73.109 -gboolean gmyth_tvplayer_record_setup (GMythTVPlayer *tvplayer,
73.110 - gchar *filename);
73.111 -gboolean gmyth_tvplayer_livetv_setup (GMythTVPlayer *tvplayer);
73.112 -
73.113 -G_END_DECLS
73.114 -
73.115 -#endif /*GMYTH_TVPLAYER_H_*/
74.1 --- a/gmyth/src/libgmyth/gmyth_util.c Wed Sep 27 00:08:03 2006 +0100
74.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
74.3 @@ -1,138 +0,0 @@
74.4 -/**
74.5 -* GMyth Library
74.6 -*
74.7 -* @file gmyth/gmyth_util.c
74.8 -*
74.9 -* @brief <p> This component provides utility functions.
74.10 -*
74.11 -* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
74.12 -* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
74.13 -*
74.14 -*//*
74.15 -*
74.16 -* This program is free software; you can redistribute it and/or modify
74.17 -* it under the terms of the GNU Lesser General Public License as published by
74.18 -* the Free Software Foundation; either version 2 of the License, or
74.19 -* (at your option) any later version.
74.20 -*
74.21 -* This program is distributed in the hope that it will be useful,
74.22 -* but WITHOUT ANY WARRANTY; without even the implied warranty of
74.23 -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
74.24 -* GNU General Public License for more details.
74.25 -*
74.26 -* You should have received a copy of the GNU Lesser General Public License
74.27 -* along with this program; if not, write to the Free Software
74.28 -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
74.29 -*/
74.30 -
74.31 -#include "gmyth_util.h"
74.32 -
74.33 -#include <glib.h>
74.34 -#include <glib/gprintf.h>
74.35 -
74.36 -/** Converts a time_t struct in a GString at ISO standard format
74.37 - * (e.g. 2006-07-20T09:56:41).
74.38 - *
74.39 - * The returned GString memory should be deallocated from
74.40 - * the calling function.
74.41 - *
74.42 - * @param time_value the time value to be converted
74.43 - * @return GString* the converted isoformat string
74.44 - */
74.45 -GString*
74.46 -gmyth_util_time_to_isoformat (time_t time_value)
74.47 -{
74.48 - struct tm tm_time;
74.49 - GString *result;
74.50 -
74.51 - if (localtime_r(&time_value, &tm_time) == NULL) {
74.52 - g_warning ("gmyth_util_time_to_isoformat convertion error!\n");
74.53 - return NULL;
74.54 - }
74.55 -
74.56 - result = g_string_sized_new(20);
74.57 - g_string_printf(result, "%04d-%02d-%02dT%02d:%02d:%02d",
74.58 - tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
74.59 - tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);
74.60 -
74.61 - return result;
74.62 -}
74.63 -
74.64 -/** Converts a time_t struct in a GString to the following
74.65 - * format (e.g. 2006-07-20 09:56:41).
74.66 - *
74.67 - * The returned GString memory should be deallocated from
74.68 - * the calling function.
74.69 - *
74.70 - * @param time_value the time value to be converted
74.71 - * @return GString* the converted string
74.72 - */
74.73 -GString*
74.74 -gmyth_util_time_to_string (time_t time_value)
74.75 -{
74.76 - GString *result = gmyth_util_time_to_isoformat (time_value);
74.77 - result->str[10] = ' ';
74.78 -
74.79 - return result;
74.80 -}
74.81 -
74.82 -/** Converts a GString in the following format
74.83 - * (e.g. 2006-07-20 09:56:41) to a time_t struct.
74.84 - *
74.85 - * @param time_str the string to be converted
74.86 - * @return time_t the time converted value
74.87 - */
74.88 -time_t
74.89 -gmyth_util_string_to_time (GString* time_str)
74.90 -{
74.91 - int year, month, day, hour, min, sec;
74.92 -
74.93 - g_debug( "[%s] time_str = %s.\n", __FUNCTION__, time_str != NULL ? time_str->str : "[time string is NULL!]" );
74.94 -
74.95 - if (sscanf (time_str->str, "%04d-%02d-%02d %02d:%02d:%02d",
74.96 - &year, &month, &day, &hour, &min, &sec) < 3) { /* At least date */
74.97 - g_warning ("GMythUtil: isoformat_to_time converter error!\n");
74.98 - return 0;
74.99 - } else {
74.100 - struct tm tm_time;
74.101 - tm_time.tm_year = year - 1900;
74.102 - tm_time.tm_mon = month - 1;
74.103 - tm_time.tm_mday = day;
74.104 - tm_time.tm_hour = hour;
74.105 - tm_time.tm_min = min;
74.106 - tm_time.tm_sec = sec;
74.107 -
74.108 - return mktime (&tm_time);
74.109 - }
74.110 -}
74.111 -
74.112 -/** Decodes a long long variable from the string list
74.113 - * format of the myhtprotocol.
74.114 - *
74.115 - * @param strlist the string list of mythprotocol values
74.116 - * @param offset the list node offset of the long long variable
74.117 - * @return guint64 the long long converted value
74.118 - */
74.119 -guint64
74.120 -gmyth_util_decode_long_long(GMythStringList *strlist, guint offset)
74.121 -{
74.122 -
74.123 - guint64 ret_value = 0LL;
74.124 -
74.125 - g_return_val_if_fail( strlist != NULL, ret_value );
74.126 -
74.127 - if ( offset < gmyth_string_list_length( strlist ))
74.128 - g_printerr( "[%s] Offset is lower than the Stringlist (offset = %d)!\n",
74.129 - __FUNCTION__, offset );
74.130 -
74.131 - g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value );
74.132 -
74.133 - gint l1 = gmyth_string_list_get_int( strlist, offset );
74.134 - gint l2 = gmyth_string_list_get_int( strlist, offset + 1 );
74.135 -
74.136 - ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
74.137 -
74.138 - return ret_value;
74.139 -
74.140 -}
74.141 -
75.1 --- a/gmyth/src/libgmyth/gmyth_util.h Wed Sep 27 00:08:03 2006 +0100
75.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
75.3 @@ -1,45 +0,0 @@
75.4 -/**
75.5 -* GMyth Library
75.6 -*
75.7 -* @file gmyth/gmyth_util.h
75.8 -*
75.9 -* @brief <p> This component provides utility functions.
75.10 -*
75.11 -* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
75.12 -* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
75.13 -*
75.14 -*//*
75.15 -*
75.16 -* This program is free software; you can redistribute it and/or modify
75.17 -* it under the terms of the GNU Lesser General Public License as published by
75.18 -* the Free Software Foundation; either version 2 of the License, or
75.19 -* (at your option) any later version.
75.20 -*
75.21 -* This program is distributed in the hope that it will be useful,
75.22 -* but WITHOUT ANY WARRANTY; without even the implied warranty of
75.23 -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75.24 -* GNU General Public License for more details.
75.25 -*
75.26 -* You should have received a copy of the GNU Lesser General Public License
75.27 -* along with this program; if not, write to the Free Software
75.28 -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
75.29 -*/
75.30 -
75.31 -#ifndef GMYTH_UTIL_H_
75.32 -#define GMYTH_UTIL_H_
75.33 -
75.34 -#include <time.h>
75.35 -#include <glib.h>
75.36 -
75.37 -#include "gmyth_stringlist.h"
75.38 -
75.39 -G_BEGIN_DECLS
75.40 -
75.41 -GString * gmyth_util_time_to_isoformat(time_t time_value);
75.42 -GString * gmyth_util_time_to_string (time_t time_value);
75.43 -time_t gmyth_util_string_to_time (GString* time_str);
75.44 -guint64 gmyth_util_decode_long_long (GMythStringList *strlist,
75.45 - guint offset);
75.46 -G_END_DECLS
75.47 -
75.48 -#endif /*GMYTH_UTIL_H_*/