# HG changeset patch
# User leo_sobral
# Date 1158792335 -3600
# Node ID ffdf467315ec951e1a30d48a902bb0fb20cb1538
# Parent  20b1f3062855fef06a97f16546cefd9c410ca70b
[svn r2] imported to sf repository

diff -r 20b1f3062855 -r ffdf467315ec gmyth/COPYING
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/COPYING	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/ChangeLog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/ChangeLog	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,24 @@
+2006-08-17 Rosfran Borges <rosfran.borges@indt.org.br>
+	* Added the correct gstreamer-base package (GSTBASE) at the configure.ac; 
+	GSTBASE_CFLAGS and GSTBASE_LIBS variables had the same values from
+	the GST_CFLAGS/GST_LIBS.
+
+2006-08-16 Rosfran Borges <rosfran.borges@indt.org.br>
+	* Fixed some installation issues, regarding lib-installing to the
+	correct directory, and copying the header files to the destination
+	dir (make install).
+	* Put 'pkg-config' resource to the Maemo Myth library. The name of the
+	PKG-CONFIG resource is 'maemo-myth', plus the minor and major version.
+	Actually, the version is '0.1', so the library config file is:  
+	'maemo-myth-0.1.pc'. You can type: 'pkg-config --cflags --libs 
+	maemo-myth-0.1'.
+	* Many adjustments in the automake/autoconf configuration files
+	(configure.ac, Makefile.am) - some autotools misusage fixed.
+	* Added the MythURI structure, and the URI parsing utility functions
+	(missing in the GLib).
+	* Some functions were exported (myth_socket, mmyth_context), that's 
+	why many ther modules need to use them.
+	* Fixed some library dependencies.
+	* Prepared to be used inside the GStreamer (linking with the MythTV
+	plug-in).
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/INSTALL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/INSTALL	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,182 @@
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff -r 20b1f3062855 -r ffdf467315ec gmyth/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,23 @@
+SUBDIRS= src pixmaps
+
+### all of the standard pc files we need to generate
+pcfiles = gmyth-@GMYTH_MAJORMINOR@.pc
+
+all-local: $(pcfiles)
+
+### how to generate pc files
+%-@GMYTH_MAJORMINOR@.pc: %.pc
+	cp $< $@
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = $(pcfiles)
+
+include aminclude.am
+
+EXTRA_DIST =                            \
+        autogen.sh                      \
+        gmyth.pc.in			\
+        AUTHORS                         \
+        COPYING                         \
+        README
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/aminclude.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/aminclude.am	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,186 @@
+# Copyright (C) 2004 Oren Ben-Kiki
+# This file is distributed under the same terms as the Automake macro files.
+
+# Generate automatic documentation using Doxygen. Goals and variables values
+# are controlled by the various DX_COND_??? conditionals set by autoconf.
+#
+# The provided goals are:
+# doxygen-doc: Generate all doxygen documentation.
+# doxygen-run: Run doxygen, which will generate some of the documentation
+#              (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post
+#              processing required for the rest of it (PS, PDF, and some MAN).
+# doxygen-man: Rename some doxygen generated man pages.
+# doxygen-ps: Generate doxygen PostScript documentation.
+# doxygen-pdf: Generate doxygen PDF documentation.
+#
+# Note that by default these are not integrated into the automake goals. If
+# doxygen is used to generate man pages, you can achieve this integration by
+# setting man3_MANS to the list of man pages generated and then adding the
+# dependency:
+#
+#   $(man3_MANS): doxygen-doc
+#
+# This will cause make to run doxygen and generate all the documentation.
+#
+# The following variable is intended for use in Makefile.am:
+#
+# DX_CLEANFILES = everything to clean.
+#
+# This is usually added to MOSTLYCLEANFILES.
+
+## --------------------------------- ##
+## Format-independent Doxygen rules. ##
+## --------------------------------- ##
+
+if DX_COND_doc
+
+## ------------------------------- ##
+## Rules specific for HTML output. ##
+## ------------------------------- ##
+
+if DX_COND_html
+
+DX_CLEAN_HTML = @DX_DOCDIR@/html
+
+endif DX_COND_html
+
+## ------------------------------ ##
+## Rules specific for CHM output. ##
+## ------------------------------ ##
+
+if DX_COND_chm
+
+DX_CLEAN_CHM = @DX_DOCDIR@/chm
+
+if DX_COND_chi
+
+DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
+
+endif DX_COND_chi
+
+endif DX_COND_chm
+
+## ------------------------------ ##
+## Rules specific for MAN output. ##
+## ------------------------------ ##
+
+if DX_COND_man
+
+DX_CLEAN_MAN = @DX_DOCDIR@/man
+
+endif DX_COND_man
+
+## ------------------------------ ##
+## Rules specific for RTF output. ##
+## ------------------------------ ##
+
+if DX_COND_rtf
+
+DX_CLEAN_RTF = @DX_DOCDIR@/rtf
+
+endif DX_COND_rtf
+
+## ------------------------------ ##
+## Rules specific for XML output. ##
+## ------------------------------ ##
+
+if DX_COND_xml
+
+DX_CLEAN_XML = @DX_DOCDIR@/xml
+
+endif DX_COND_xml
+
+## ----------------------------- ##
+## Rules specific for PS output. ##
+## ----------------------------- ##
+
+if DX_COND_ps
+
+DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
+
+DX_PS_GOAL = doxygen-ps
+
+doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
+
+@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
+	cd @DX_DOCDIR@/latex; \
+	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+	$(DX_LATEX) refman.tex; \
+	$(MAKEINDEX_PATH) refman.idx; \
+	$(DX_LATEX) refman.tex; \
+	countdown=5; \
+	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+	                  refman.log > /dev/null 2>&1 \
+	   && test $$countdown -gt 0; do \
+	    $(DX_LATEX) refman.tex; \
+	    countdown=`expr $$countdown - 1`; \
+	done; \
+	$(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
+
+endif DX_COND_ps
+
+## ------------------------------ ##
+## Rules specific for PDF output. ##
+## ------------------------------ ##
+
+if DX_COND_pdf
+
+DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
+
+DX_PDF_GOAL = doxygen-pdf
+
+doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
+
+@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
+	cd @DX_DOCDIR@/latex; \
+	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+	$(DX_PDFLATEX) refman.tex; \
+	$(DX_MAKEINDEX) refman.idx; \
+	$(DX_PDFLATEX) refman.tex; \
+	countdown=5; \
+	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+	                  refman.log > /dev/null 2>&1 \
+	   && test $$countdown -gt 0; do \
+	    $(DX_PDFLATEX) refman.tex; \
+	    countdown=`expr $$countdown - 1`; \
+	done; \
+	mv refman.pdf ../@PACKAGE@.pdf
+
+endif DX_COND_pdf
+
+## ------------------------------------------------- ##
+## Rules specific for LaTeX (shared for PS and PDF). ##
+## ------------------------------------------------- ##
+
+if DX_COND_latex
+
+DX_CLEAN_LATEX = @DX_DOCDIR@/latex
+
+endif DX_COND_latex
+
+.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
+
+doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
+	rm -rf @DX_DOCDIR@
+	$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
+
+DX_CLEANFILES = \
+    @DX_DOCDIR@/@PACKAGE@.tag \
+    -r \
+    $(DX_CLEAN_HTML) \
+    $(DX_CLEAN_CHM) \
+    $(DX_CLEAN_CHI) \
+    $(DX_CLEAN_MAN) \
+    $(DX_CLEAN_RTF) \
+    $(DX_CLEAN_XML) \
+    $(DX_CLEAN_PS) \
+    $(DX_CLEAN_PDF) \
+    $(DX_CLEAN_LATEX)
+
+endif DX_COND_doc
diff -r 20b1f3062855 -r ffdf467315ec gmyth/autogen.sh
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/autogen.sh	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,99 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+DIE=0
+package=gmyth
+srcfile=configure.ac
+
+# a quick cvs co if necessary to alleviate the pain - may remove this
+# when developers get a clue ;)
+if test ! -d common; 
+then 
+  echo "+ getting common/ from svn"
+ svn co common 
+fi
+
+# source helper functions
+if test ! -f common/autogen-helper.sh;
+then
+  echo There is something wrong with your source tree.
+  echo You are missing common/autogen-helper.sh
+  exit 1
+fi
+. common/autogen-helper.sh
+
+CONFIGURE_DEF_OPT='--enable-maintainer-mode'
+
+autogen_options 
+
+echo -n "+ check for build tools"
+if test ! -z "$NOCHECK"; then echo " skipped"; else  echo; fi
+version_check "autoconf" "$AUTOCONF autoconf autoconf-2.54 autoconf-2.53" \
+              "ftp://ftp.gnu.org/pub/gnu/autoconf/" 2 53 || DIE=1
+version_check "automake" "$AUTOMAKE automake automake-1.9 automake-1.8 automake-1.7 automake-1.6" \
+              "ftp://ftp.gnu.org/pub/gnu/automake/" 1 6 || DIE=1
+version_check "libtoolize" "$LIBTOOLIZE libtoolize" \
+              "ftp://ftp.gnu.org/pub/gnu/libtool/" 1 5 0 || DIE=1
+version_check "pkg-config" "" \
+              "http://www.freedesktop.org/software/pkgconfig" 0 8 0 || DIE=1
+
+die_check $DIE
+
+aclocal_check || DIE=1
+autoheader_check || DIE=1
+
+die_check $DIE
+
+# if no arguments specified then this will be printed
+if test -z "$*"; then
+  echo "+ checking for autogen.sh options"
+  echo "  This autogen script will automatically run ./configure as:"
+  echo "  ./configure $CONFIGURE_DEF_OPT"
+  echo "  To pass any additional options, please specify them on the $0"
+  echo "  command line."
+fi
+
+toplevel_check $srcfile
+
+tool_run "$aclocal" "-I m4 $ACLOCAL_FLAGS"
+tool_run "$libtoolize" "--copy --force"
+tool_run "$autoheader"
+
+# touch the stamp-h.in build stamp so we don't re-run autoheader in maintainer mode -- wingo
+echo timestamp > stamp-h.in 2> /dev/null
+
+tool_run "$autoconf"
+tool_run "$automake" "-a -c"
+
+# if enable exists, add an -enable option for each of the lines in that file
+if test -f enable; then
+  for a in `cat enable`; do
+    CONFIGURE_FILE_OPT="--enable-$a"
+  done
+fi
+
+# if disable exists, add an -disable option for each of the lines in that file
+if test -f disable; then
+  for a in `cat disable`; do
+    CONFIGURE_FILE_OPT="$CONFIGURE_FILE_OPT --disable-$a"
+  done
+fi
+
+test -n "$NOCONFIGURE" && {
+  echo "+ skipping configure stage for package $package, as requested."
+  echo "+ autogen.sh done."
+  exit 0
+}
+
+echo "+ running configure ... "
+test ! -z "$CONFIGURE_DEF_OPT" && echo "  ./configure default flags: $CONFIGURE_DEF_OPT"
+test ! -z "$CONFIGURE_EXT_OPT" && echo "  ./configure external flags: $CONFIGURE_EXT_OPT"
+test ! -z "$CONFIGURE_FILE_OPT" && echo "  ./configure enable/disable flags: $CONFIGURE_FILE_OPT"
+echo
+
+./configure $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT $CONFIGURE_FILE_OPT || {
+        echo "  configure failed"
+        exit 1
+}
+
+echo "Now type 'make' to compile $package."
diff -r 20b1f3062855 -r ffdf467315ec gmyth/common/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/common/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,1 @@
+EXTRA_DIST = autogen-helper.sh
diff -r 20b1f3062855 -r ffdf467315ec gmyth/common/autogen-helper.sh
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/common/autogen-helper.sh	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,302 @@
+# a silly hack that generates autoregen.sh but it's handy
+echo "#!/bin/sh" > autoregen.sh
+echo "./autogen.sh $@ \$@" >> autoregen.sh
+chmod +x autoregen.sh
+
+# helper functions for autogen.sh
+
+debug ()
+# print out a debug message if DEBUG is a defined variable
+{
+  if test ! -z "$DEBUG"
+  then
+    echo "DEBUG: $1"
+  fi
+}
+
+version_check ()
+# check the version of a package
+# first argument : package name (executable)
+# second argument : optional path where to look for it instead
+# third argument : source download url
+# rest of arguments : major, minor, micro version
+# all consecutive ones : suggestions for binaries to use
+# (if not specified in second argument)
+{
+  PACKAGE=$1
+  PKG_PATH=$2
+  URL=$3
+  MAJOR=$4
+  MINOR=$5
+  MICRO=$6
+
+  # for backwards compatibility, we let PKG_PATH=PACKAGE when PKG_PATH null
+  if test -z "$PKG_PATH"; then PKG_PATH=$PACKAGE; fi
+  debug "major $MAJOR minor $MINOR micro $MICRO"
+  VERSION=$MAJOR
+  if test ! -z "$MINOR"; then VERSION=$VERSION.$MINOR; else MINOR=0; fi
+  if test ! -z "$MICRO"; then VERSION=$VERSION.$MICRO; else MICRO=0; fi
+
+  debug "major $MAJOR minor $MINOR micro $MICRO"
+  
+  for SUGGESTION in $PKG_PATH; do 
+    COMMAND="$SUGGESTION"
+
+    # don't check if asked not to
+    test -z "$NOCHECK" && {
+      echo -n "  checking for $COMMAND >= $VERSION ... "
+    } || {
+      # we set a var with the same name as the package, but stripped of
+      # unwanted chars
+      VAR=`echo $PACKAGE | sed 's/-//g'`
+      debug "setting $VAR"
+      eval $VAR="$COMMAND"
+      return 0
+    }
+
+    debug "checking version with $COMMAND"
+    ($COMMAND --version) < /dev/null > /dev/null 2>&1 || 
+    {
+      echo "not found."
+      continue
+    }
+    # strip everything that's not a digit, then use cut to get the first field
+    pkg_version=`$COMMAND --version|head -n 1|sed 's/^[^0-9]*//'|cut -d' ' -f1`
+    debug "pkg_version $pkg_version"
+    # remove any non-digit characters from the version numbers to permit numeric
+    # comparison
+    pkg_major=`echo $pkg_version | cut -d. -f1 | sed s/[a-zA-Z\-].*//g`
+    pkg_minor=`echo $pkg_version | cut -d. -f2 | sed s/[a-zA-Z\-].*//g`
+    pkg_micro=`echo $pkg_version | cut -d. -f3 | sed s/[a-zA-Z\-].*//g`
+    test -z "$pkg_major" && pkg_major=0
+    test -z "$pkg_minor" && pkg_minor=0
+    test -z "$pkg_micro" && pkg_micro=0
+    debug "found major $pkg_major minor $pkg_minor micro $pkg_micro"
+
+    #start checking the version
+    debug "version check"
+
+    # reset check
+    WRONG=
+
+    if [ ! "$pkg_major" -gt "$MAJOR" ]; then
+      debug "major: $pkg_major <= $MAJOR"
+      if [ "$pkg_major" -lt "$MAJOR" ]; then
+        debug "major: $pkg_major < $MAJOR"
+        WRONG=1
+      elif [ ! "$pkg_minor" -gt "$MINOR" ]; then
+        debug "minor: $pkg_minor <= $MINOR"
+        if [ "$pkg_minor" -lt "$MINOR" ]; then
+          debug "minor: $pkg_minor < $MINOR"
+          WRONG=1
+        elif [ "$pkg_micro" -lt "$MICRO" ]; then
+          debug "micro: $pkg_micro < $MICRO"
+	  WRONG=1
+        fi
+      fi
+    fi
+
+    if test ! -z "$WRONG"; then
+      echo "found $pkg_version, not ok !"
+      continue
+    else
+      echo "found $pkg_version, ok."
+      # we set a var with the same name as the package, but stripped of
+      # unwanted chars
+      VAR=`echo $PACKAGE | sed 's/-//g'`
+      debug "setting $VAR"
+      eval $VAR="$COMMAND"
+      return 0
+    fi
+  done
+
+  echo "not found !"
+  echo "You must have $PACKAGE installed to compile $package."
+  echo "Download the appropriate package for your distribution,"
+  echo "or get the source tarball at $URL"
+  return 1;
+}
+
+aclocal_check ()
+{
+  # normally aclocal is part of automake
+  # so we expect it to be in the same place as automake
+  # so if a different automake is supplied, we need to adapt as well
+  # so how's about replacing automake with aclocal in the set var,
+  # and saving that in $aclocal ?
+  # note, this will fail if the actual automake isn't called automake*
+  # or if part of the path before it contains it
+  if [ -z "$automake" ]; then
+    echo "Error: no automake variable set !"
+    return 1
+  else
+    aclocal=`echo $automake | sed s/automake/aclocal/`
+    debug "aclocal: $aclocal"
+    if [ "$aclocal" != "aclocal" ];
+    then
+      CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-aclocal=$aclocal"
+    fi
+    if [ ! -x `which $aclocal` ]; then
+      echo "Error: cannot execute $aclocal !"
+      return 1
+    fi
+  fi
+}
+
+autoheader_check ()
+{
+  # same here - autoheader is part of autoconf
+  # use the same voodoo
+  if [ -z "$autoconf" ]; then
+    echo "Error: no autoconf variable set !"
+    return 1
+  else
+    autoheader=`echo $autoconf | sed s/autoconf/autoheader/`
+    debug "autoheader: $autoheader"
+    if [ "$autoheader" != "autoheader" ];
+    then
+      CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoheader=$autoheader"
+    fi
+    if [ ! -x `which $autoheader` ]; then
+      echo "Error: cannot execute $autoheader !"
+      return 1
+    fi
+  fi
+
+}
+
+autoconf_2_52d_check ()
+{
+  # autoconf 2.52d has a weird issue involving a yes:no error
+  # so don't allow it's use
+  test -z "$NOCHECK" && {
+    ac_version=`$autoconf --version|head -n 1|sed 's/^[a-zA-Z\.\ ()]*//;s/ .*$//'`
+    if test "$ac_version" = "2.52d"; then
+      echo "autoconf 2.52d has an issue with our current build."
+      echo "We don't know who's to blame however.  So until we do, get a"
+      echo "regular version.  RPM's of a working version are on the gstreamer site."
+      exit 1
+    fi
+  }
+  return 0
+}
+
+die_check ()
+{
+  # call with $DIE
+  # if set to 1, we need to print something helpful then die
+  DIE=$1
+  if test "x$DIE" = "x1";
+  then
+    echo
+    echo "- Please get the right tools before proceeding."
+    echo "- Alternatively, if you're sure we're wrong, run with --nocheck."
+    exit 1
+  fi
+}
+
+autogen_options ()
+{
+  if test "x$1" = "x"; then
+    return 0
+  fi
+
+  while test "x$1" != "x" ; do
+    optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    case "$1" in
+      --noconfigure)
+          NOCONFIGURE=defined
+	  AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --noconfigure"
+          echo "+ configure run disabled"
+          shift
+          ;;
+      --nocheck)
+	  AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --nocheck"
+          NOCHECK=defined
+          echo "+ autotools version check disabled"
+          shift
+          ;;
+      --debug)
+          DEBUG=defined
+	  AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --debug"
+          echo "+ debug output enabled"
+          shift
+          ;;
+      --prefix=*)
+	  CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$optarg"
+	  echo "+ passing --prefix=$optarg to configure"
+          shift
+          ;;
+      --prefix)
+	  shift
+	  echo "DEBUG: $1"
+	  CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$1"
+	  echo "+ passing --prefix=$1 to configure"
+          shift
+          ;;
+      -h|--help)
+          echo "autogen.sh (autogen options) -- (configure options)"
+          echo "autogen.sh help options: "
+          echo " --noconfigure            don't run the configure script"
+          echo " --nocheck                don't do version checks"
+          echo " --debug                  debug the autogen process"
+	  echo " --prefix		  will be passed on to configure"
+          echo
+          echo " --with-autoconf PATH     use autoconf in PATH"
+          echo " --with-automake PATH     use automake in PATH"
+          echo
+          echo "to pass options to configure, put them as arguments after -- "
+	  exit 1
+          ;;
+      --with-automake=*)
+          AUTOMAKE=$optarg
+          echo "+ using alternate automake in $optarg"
+	  CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-automake=$AUTOMAKE"
+          shift
+          ;;
+      --with-autoconf=*)
+          AUTOCONF=$optarg
+          echo "+ using alternate autoconf in $optarg"
+	  CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoconf=$AUTOCONF"
+          shift
+          ;;
+      --disable*|--enable*|--with*)
+          echo "+ passing option $1 to configure"
+	  CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $1"
+          shift
+          ;;
+       --) shift ; break ;;
+      *) echo "- ignoring unknown autogen.sh argument $1"; shift ;;
+    esac
+  done
+
+  for arg do CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $arg"; done
+  if test ! -z "$CONFIGURE_EXT_OPT"
+  then
+    echo "+ options passed to configure: $CONFIGURE_EXT_OPT"
+  fi
+}
+
+toplevel_check ()
+{
+  srcfile=$1
+  test -f $srcfile || {
+        echo "You must run this script in the top-level $package directory"
+        exit 1
+  }
+}
+
+
+tool_run ()
+{
+  tool=$1
+  options=$2
+  run_if_fail=$3
+  echo "+ running $tool $options..."
+  $tool $options || {
+    echo
+    echo $tool failed
+    eval $run_if_fail
+    exit 1
+  }
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/configure.ac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/configure.ac	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,224 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.50)
+
+AC_INIT([gmyth],[0.1])
+
+dnl AC_CONFIG_SRCDIR([src/mmyth_main.c])
+AC_CONFIG_HEADER(config.h)
+
+dnl when going to/from release please set the nano (fourth number) right !
+dnl releases only do Wall, SVN and prerelease does Werror too
+AS_VERSION(gmyth, GMYTH, 0, 1, 0, 3, GMYTH_SVN="no", GMYTH_SVN="yes")
+
+GMYTH_MAJORMINOR=$GMYTH_MAJOR_VERSION.$GMYTH_MINOR_VERSION
+
+AC_SUBST(GMYTH_MAJORMINOR)
+
+dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode
+AM_MAINTAINER_MODE
+dnl make aclocal work in maintainer mode
+AC_SUBST(ACLOCAL_AMFLAGS, "-I m4")
+
+# Checks for programs.
+# check for tools
+# Make sure CFLAGS is defined to stop AC_PROC_CC adding -g
+CFLAGS="$CFLAGS -Wall"
+AC_PROG_CC
+AC_PROG_LIBTOOL
+
+dnl Generate doxygen documentation
+DX_HTML_FEATURE(ON)
+DX_CHM_FEATURE(OFF)
+DX_CHI_FEATURE(OFF)
+DX_MAN_FEATURE(OFF)
+DX_RTF_FEATURE(OFF)
+DX_XML_FEATURE(OFF)
+DX_PDF_FEATURE(OFF)
+DX_PS_FEATURE(OFF)
+DX_INIT_DOXYGEN(gmyth, doxygen.cfg, docs)
+
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_PID_T
+AC_STRUCT_TM
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_MALLOC
+AC_FUNC_MKTIME
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([memset socket stime strstr strtoul])
+
+AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
+
+# Checks required packages
+
+dnl Test if --disable-debug given
+AC_ARG_ENABLE(debug,
+	[AC_HELP_STRING([--disable-debug], [disable debugging mode])],
+	enable_debug="$enableval",
+	enable_debug=yes)
+
+if test "x$enable_debug" = "xyes" ; then
+      CFLAGS="$CFLAGS -g"
+else
+      AC_DEFINE( NDEBUG, 1, [disable debug messages] )
+      CFLAGS="$CFLAGS -O2 -DG_DISABLE_CHECKS -DNDEBUG"
+fi          
+
+AM_CONDITIONAL( NDEBUG, test "x$enable_debug" = "xyes" )
+
+# Check for pkgconfig
+AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, yes, no)
+# Give error and exit if we don't have pkgconfig
+if test "x$HAVE_PKGCONFIG" = "xno"; then
+  AC_MSG_ERROR(you need to have pkgconfig installed !)
+fi
+
+# Check for Glib2.0
+PKG_CHECK_MODULES(GLIB, glib-2.0, HAVE_GLIB=yes,HAVE_GLIB=no)
+
+# Give error and exit if we don't have glib
+if test "x$HAVE_GLIB" = "xno"; then
+  AC_MSG_ERROR(you need glib-2.0 installed)
+fi
+
+# make GLIB_CFLAGS and GLIB_LIBS available
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+# Check for GObject2.0
+PKG_CHECK_MODULES(GOBJECT,
+  gobject-2.0,
+  HAVE_GOBJECT=yes, HAVE_GOBJECT=no)
+
+# Give error and exit if we don't have gobject
+if test "x$HAVE_GOBJECT" = "xno"; then
+  AC_MSG_ERROR(you need gobject-2.0 installed)
+fi
+
+# make GOBJECT_CFLAGS and GOBJECT_LIBS available
+AC_SUBST(GOBJECT_CFLAGS)
+AC_SUBST(GOBJECT_LIBS)
+
+# Check for GTK+-2.0
+PKG_CHECK_MODULES(GTK, gtk+-2.0, HAVE_GTK=yes,HAVE_GTK=no)
+
+# Give error and exit if we don't have gtk
+if test "x$HAVE_GTK" = "xyes"; then
+  AC_DEFINE(WITH_GTK, 1, [build with GTK+ related stuff])
+  dnl AC_MSG_ERROR(you need gtk+-2.0 installed)
+else
+  AC_MSG_RESULT(no)
+fi
+
+AM_CONDITIONAL(WITH_GTK, test "x$HAVE_GTK" = "xyes" )
+
+# make GTK_CFLAGS and GTK_LIBS available
+AC_SUBST(GTK_CFLAGS)
+AC_SUBST(GTK_LIBS)
+
+dnl ========== Check for Hildon Libraries
+PKG_CHECK_MODULES(HILDON,
+  hildon-lgpl libosso hildon-status-bar-lib libhildonmenu hildon-base-lib hildon-control-panel hildon-libs,
+  HAVE_HILDON=yes, HAVE_HILDON=no)
+
+if test "x$HAVE_HILDON" = "xyes"; then
+  AC_DEFINE(MAEMO_PLATFORM, 1, [build with hildon libs])
+  HILDON_CFLAGS="$HILDON_CFLAGS -DMAEMO_PLATFORM=1"
+else
+  AC_MSG_RESULT(no)
+fi
+
+AM_CONDITIONAL(MAEMO_PLATFORM, test "x$HAVE_HILDON" = "xyes")
+
+dnl make HILDON_CFLAGS and HILDON_LIBS available
+AC_SUBST(HILDON_CFLAGS)
+AC_SUBST(HILDON_LIBS)
+
+# Check for libxml-2.0
+PKG_CHECK_MODULES(LIBXML, libxml-2.0, HAVE_LIBXML=yes,HAVE_LIBXML=no)
+
+# Give error and exit if we don't have gtk
+if test "x$HAVE_LIBXML" = "xno"; then
+  AC_MSG_ERROR(you need libxml-2.0 installed)
+fi
+
+# make LIBXML_CFLAGS and LIBXML_LIBS available
+AC_SUBST(LIBXML_CFLAGS)
+AC_SUBST(LIBXML_LIBS)
+
+
+# check for gstreamer development files
+GST_REQUIRED=0.10
+GST_MAJORMINOR=0.10
+PKG_CHECK_MODULES(GST, \
+  gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED,
+  HAVE_GST=yes, HAVE_GST=no)
+
+# Give error and exit if we don't have gstreamer
+if test "x$HAVE_GST" = "xno"; then
+  AC_MSG_ERROR(you need gstreamer development packages installed !)
+fi
+
+# make GST_CFLAGS and GST_LIBS available
+AC_SUBST(GST_CFLAGS)
+AC_SUBST(GST_LIBS)
+
+# check for gstreamer-base plugins (xoverlay interface)
+GSTBASE_REQUIRED=0.10
+GSTBASE_MAJORMINOR=0.10
+PKG_CHECK_MODULES(GSTBASE, \
+  gstreamer-base-$GSTBASE_MAJORMINOR >= $GSTBASE_REQUIRED,
+  HAVE_GSTBASE=yes, HAVE_GSTBASE=no)
+
+# Give error and exit if we don't have gstreamer base libraries
+if test "x$HAVE_GSTBASE" = "xno"; then
+  AC_MSG_ERROR(you need gstreamer base development packages installed !)
+fi
+
+# make GSTBASE_CFLAGS and GSTBASE_LIBS available
+AC_SUBST(GSTBASE_CFLAGS)
+AC_SUBST(GSTBASE_LIBS)
+
+
+# make GST_MAJORMINOR available in Makefile.am
+AC_SUBST(GST_MAJORMINOR)
+
+#
+# mysql libraries
+#
+AC_CHECK_PROG(MYSQL_CFLAGS,mysql_config,`mysql_config --cflags`)
+if test -z "$MYSQL_CFLAGS"; then 
+        AC_MSG_ERROR([Could not find mysql_config script. Make sure the mysql client libraries are installed])
+fi
+AC_SUBST(MYSQL_CFLAGS)
+
+
+AC_CHECK_PROG(MYSQL_LIBS,mysql_config,`mysql_config --libs`)
+if test -z "$MYSQL_LIBS"; then 
+        AC_MSG_ERROR([Could not find mysql_config script. Make sure the mysql client libraries are installed])
+fi
+AC_SUBST(MYSQL_LIBS)
+
+#dnl Enable gtk-doc
+#GTK_DOC_CHECK(1.4)
+
+
+AC_CONFIG_FILES([Makefile
+                pixmaps/Makefile
+                src/Makefile
+                src/libgmyth/Makefile
+                src/gui/Makefile
+		gmyth.pc])
+AC_OUTPUT
diff -r 20b1f3062855 -r ffdf467315ec gmyth/data/settings/history.dat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/data/settings/history.dat	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,3 @@
+# MIPTV history file
+# Stores the last network frequency used
+602000000
diff -r 20b1f3062855 -r ffdf467315ec gmyth/debian/changelog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/debian/changelog	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,6 @@
+mmyth (0.1-indt1) unstable; urgency=low
+
+  * Initial Maemo Package.
+
+ -- Hallyson Melo <hallyson.melo@indt.org.br>  Fri, 15 Sep 2006 10:26:16 -0300
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/debian/compat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/debian/compat	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,1 @@
+4
diff -r 20b1f3062855 -r ffdf467315ec gmyth/debian/control
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/debian/control	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,17 @@
+Source: mmyth 
+Section: user/accessories
+Priority: optional
+Maintainer: Hallyson Melo <hallyson.melo@indt.org.br> 
+Build-Depends: debhelper, libgtk2.0-dev (>= 2.4.0),
+ libosso-dev, hildon-libs-dev, hildon-fm-dev
+Standards-Version: 3.6.2
+
+Package: mmyth
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, maemo-select-menu-location
+Provides: MythTV
+Description: MythTV frontend
+ NONONONONONONONONONONONONONONONONO
+ NONONONONONONONONONONo
+ .
+ NONNONONONON
diff -r 20b1f3062855 -r ffdf467315ec gmyth/debian/control.in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/debian/control.in	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,17 @@
+Source: mmyth 
+Section: user/accessories
+Priority: optional
+Maintainer: Hallyson Melo <hallyson.melo@indt.org.br> 
+Build-Depends: debhelper, libgtk2.0-dev (>= 2.4.0),
+ libosso-dev, hildon-libs-dev, hildon-fm-dev
+Standards-Version: 3.6.2
+
+Package: mmyth
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, maemo-select-menu-location
+Provides: MythTV
+Description: MythTV frontend
+ NONONONONONONONONONONONONONONONONO
+ NONONONONONONONONONONo
+ .
+ NONNONONONON
diff -r 20b1f3062855 -r ffdf467315ec gmyth/debian/mmyth.desktop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/debian/mmyth.desktop	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.1
+Type=Application
+Name=Maemo Myth
+Exec=/usr/bin/mmyth
+Terminal=false
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
+StartupWMClass=mmyth
diff -r 20b1f3062855 -r ffdf467315ec gmyth/debian/mmyth.dirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/debian/mmyth.dirs	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,3 @@
+usr/share/pixmaps
+usr/share/applications/hildon
+usr/share/dbus-1/services
diff -r 20b1f3062855 -r ffdf467315ec gmyth/debian/mmyth.postinst
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/debian/mmyth.postinst	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,5 @@
+#! /bin/sh
+
+maemo-select-menu-location mmyth.desktop tana_fi_extras
+
+exit 0
diff -r 20b1f3062855 -r ffdf467315ec gmyth/debian/mmyth.service
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/debian/mmyth.service	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=com.nokia.xournal
+Exec=/usr/bin/xournal
diff -r 20b1f3062855 -r ffdf467315ec gmyth/debian/rules
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/debian/rules	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,15 @@
+#!/usr/bin/make -f
+# -*- mode: makefile; coding: utf-8 -*-
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/gnome.mk
+include /usr/share/cdbs/1/rules/simple-patchsys.mk
+include /usr/share/gnome-pkg-tools/1/rules/uploaders.mk
+
+DEB_CONFIGURE_EXTRA_FLAGS := --prefix=/usr
+
+binary-install/mmyth::
+#	/usr/bin/install -p -m 644 debian/mmyth.png `pwd`/debian/mmyth/usr/share/pixmaps
+	/usr/bin/install -p -m 644 debian/mmyth.desktop `pwd`/debian/mmyth/usr/share/applications/hildon
+#	/usr/bin/install -p -m 644 debian/mmyth.service `pwd`/debian/mmyth/usr/share/dbus-1/services
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/doxygen.cfg
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/doxygen.cfg	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,212 @@
+# Doxyfile 1.4.2
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = $(PROJECT)-$(VERSION)
+PROJECT_NUMBER         = 
+OUTPUT_DIRECTORY       = $(DOCDIR)
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = YES
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+STRIP_FROM_INC_PATH    = $(SRCDIR)/src/libgmyth
+FULL_PATH_NAMES        = YES
+STRIP_FROM_PATH        = $(SRCDIR)/src/libgmyth
+SHORT_NAMES            = YES
+JAVADOC_AUTOBRIEF      = YES
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = YES
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = YES
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = NO
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = YES
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = $(SRCDIR)/src/libgmyth
+FILE_PATTERNS          = *.c *.h
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = $(SRCDIR)/src/gui
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = $(GENERATE_HTML)
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = $(GENERATE_CHM)
+CHM_FILE               = ../$(PROJECT).chm
+HHC_LOCATION           = $(HHC_PATH)
+GENERATE_CHI           = $(GENERATE_CHI)
+BINARY_TOC             = YES
+TOC_EXPAND             = YES
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = YES
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = $(GENERATE_LATEX)
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = $(PAPER_SIZE)
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = YES
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = $(GENERATE_RTF)
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = $(GENERATE_MAN)
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .1
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = $(GENERATE_XML)
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = $(DOCDIR)/$(PROJECT).tag
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = $(PERL_PATH)
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = $(HAVE_DOT)
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = $(DOT_PATH)
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff -r 20b1f3062855 -r ffdf467315ec gmyth/gmyth.pc.in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/gmyth.pc.in	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gmyth
+Description: Myth TV library based upon GLib/GObject paradigm
+Version: @VERSION@
+Requires: gobject-2.0 glib-2.0 gtk+-2.0 
+
+Libs: @MYSQL_LIBS@ -L${libdir} -lgmyth
+Cflags: @MYSQL_CFLAGS@ -I${includedir}/gmyth
diff -r 20b1f3062855 -r ffdf467315ec gmyth/m4/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/m4/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,7 @@
+EXTRA_DIST = \
+        ac_doxygen.m4 \
+        as-compiler-flag.m4 \
+        as-expand.m4 \
+        as-version.m4 \
+        as-gtk-doc.m4
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/m4/ac_doxygen.m4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/m4/ac_doxygen.m4	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,312 @@
+# This file is part of Autoconf.                       -*- Autoconf -*-
+
+# Copyright (C) 2004 Oren Ben-Kiki
+# This file is distributed under the same terms as the Autoconf macro files.
+
+# Generate automatic documentation using Doxygen. Works in concert with the
+# aminclude.m4 file and a compatible doxygen configuration file. Defines the
+# following public macros:
+#
+# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
+# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
+# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
+# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
+# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
+# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
+# paper size.
+#
+# By default, HTML, PDF and PS documentation is generated as this seems to be
+# the most popular and portable combination. MAN pages created by Doxygen are
+# usually problematic, though by picking an appropriate subset and doing some
+# massaging they might be better than nothing. CHM and RTF are specific for MS
+# (note that you can't generate both HTML and CHM at the same time). The XML is
+# rather useless unless you apply specialized post-processing to it.
+#
+# The macro mainly controls the default state of the feature. The use can
+# override the default by specifying --enable or --disable. The macros ensure
+# that contradictory flags are not given (e.g., --enable-doxygen-html and
+# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
+# Finally, each feature will be automatically disabled (with a warning) if the
+# required programs are missing.
+#
+# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
+# the following parameters: a one-word name for the project for use as a
+# filename base etc., an optional configuration file name (the default is
+# 'Doxyfile', the same as Doxygen's default), and an optional output directory
+# name (the default is 'doxygen-doc').
+
+## ----------##
+## Defaults. ##
+## ----------##
+
+DX_ENV=""
+AC_DEFUN([DX_FEATURE_doc],  ON)
+AC_DEFUN([DX_FEATURE_dot],  ON)
+AC_DEFUN([DX_FEATURE_man],  OFF)
+AC_DEFUN([DX_FEATURE_html], ON)
+AC_DEFUN([DX_FEATURE_chm],  OFF)
+AC_DEFUN([DX_FEATURE_chi],  OFF)
+AC_DEFUN([DX_FEATURE_rtf],  OFF)
+AC_DEFUN([DX_FEATURE_xml],  OFF)
+AC_DEFUN([DX_FEATURE_pdf],  ON)
+AC_DEFUN([DX_FEATURE_ps],   ON)
+
+## --------------- ##
+## Private macros. ##
+## --------------- ##
+
+# DX_ENV_APPEND(VARIABLE, VALUE)
+# ------------------------------
+# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
+AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
+
+# DX_DIRNAME_EXPR
+# ---------------
+# Expand into a shell expression prints the directory part of a path.
+AC_DEFUN([DX_DIRNAME_EXPR],
+         [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
+
+# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
+# -------------------------------------
+# Expands according to the M4 (static) status of the feature.
+AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
+
+# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
+# ----------------------------------
+# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
+AC_DEFUN([DX_REQUIRE_PROG], [
+AC_PATH_TOOL([$1], [$2])
+if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
+    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
+    AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
+fi
+])
+
+# DX_TEST_FEATURE(FEATURE)
+# ------------------------
+# Expand to a shell expression testing whether the feature is active.
+AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
+
+# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
+# -------------------------------------------------
+# Verify that a required features has the right state before trying to turn on
+# the DX_CURRENT_FEATURE.
+AC_DEFUN([DX_CHECK_DEPEND], [
+test "$DX_FLAG_$1" = "$2" \
+|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
+                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])
+])
+
+# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
+# ----------------------------------------------------------
+# Turn off the DX_CURRENT_FEATURE if the required feature is off.
+AC_DEFUN([DX_CLEAR_DEPEND], [
+test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
+])
+
+# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
+#                CHECK_DEPEND, CLEAR_DEPEND,
+#                REQUIRE, DO-IF-ON, DO-IF-OFF)
+# --------------------------------------------
+# Parse the command-line option controlling a feature. CHECK_DEPEND is called
+# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
+# otherwise CLEAR_DEPEND is called to turn off the default state if a required
+# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
+# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
+# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
+AC_DEFUN([DX_ARG_ABLE], [
+    AC_DEFUN([DX_CURRENT_FEATURE], [$1])
+    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
+    AC_ARG_ENABLE(doxygen-$1,
+                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
+                                                      [--enable-doxygen-$1]),
+                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],
+                  [
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    AC_SUBST([DX_FLAG_$1], 1)
+    $3
+;; #(
+n|N|no|No|NO)
+    AC_SUBST([DX_FLAG_$1], 0)
+;; #(
+*)
+    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
+;;
+esac
+], [
+AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
+$4
+])
+if DX_TEST_FEATURE([$1]); then
+    $5
+    :
+fi
+if DX_TEST_FEATURE([$1]); then
+    AM_CONDITIONAL(DX_COND_$1, :)
+    $6
+    :
+else
+    AM_CONDITIONAL(DX_COND_$1, false)
+    $7
+    :
+fi
+])
+
+## -------------- ##
+## Public macros. ##
+## -------------- ##
+
+# DX_XXX_FEATURE(DEFAULT_STATE)
+# -----------------------------
+AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
+AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
+AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
+AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
+AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
+AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
+AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
+
+# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
+# ---------------------------------------------------------
+# PROJECT also serves as the base name for the documentation files.
+# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
+AC_DEFUN([DX_INIT_DOXYGEN], [
+
+# Files:
+AC_SUBST([DX_PROJECT], [$1])
+AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
+AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
+
+# Environment variables used inside doxygen.cfg:
+DX_ENV_APPEND(SRCDIR, $srcdir)
+DX_ENV_APPEND(PROJECT, $DX_PROJECT)
+DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
+DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
+
+# Doxygen itself:
+DX_ARG_ABLE(doc, [generate any doxygen documentation],
+            [],
+            [],
+            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
+             DX_REQUIRE_PROG([DX_PERL], perl)],
+            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
+
+# Dot for graphics:
+DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_DOT], dot)],
+            [DX_ENV_APPEND(HAVE_DOT, YES)
+             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
+            [DX_ENV_APPEND(HAVE_DOT, NO)])
+
+# Man pages generation:
+DX_ARG_ABLE(man, [generate doxygen manual pages],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_MAN, YES)],
+            [DX_ENV_APPEND(GENERATE_MAN, NO)])
+
+# RTF file generation:
+DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_RTF, YES)],
+            [DX_ENV_APPEND(GENERATE_RTF, NO)])
+
+# XML file generation:
+DX_ARG_ABLE(xml, [generate doxygen XML documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_XML, YES)],
+            [DX_ENV_APPEND(GENERATE_XML, NO)])
+
+# (Compressed) HTML help generation:
+DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_HHC], hhc)],
+            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
+             DX_ENV_APPEND(GENERATE_HTML, YES)
+             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
+            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
+
+# Seperate CHI file generation.
+DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
+            [DX_CHECK_DEPEND(chm, 1)],
+            [DX_CLEAR_DEPEND(chm, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_CHI, YES)],
+            [DX_ENV_APPEND(GENERATE_CHI, NO)])
+
+# Plain HTML pages generation:
+DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
+            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
+            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
+            [],
+            [DX_ENV_APPEND(GENERATE_HTML, YES)],
+            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
+
+# PostScript file generation:
+DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_LATEX], latex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_DVIPS], dvips)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# PDF file generation:
+DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# LaTeX generation for PS and/or PDF:
+if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
+    AM_CONDITIONAL(DX_COND_latex, :)
+    DX_ENV_APPEND(GENERATE_LATEX, YES)
+else
+    AM_CONDITIONAL(DX_COND_latex, false)
+    DX_ENV_APPEND(GENERATE_LATEX, NO)
+fi
+
+# Paper size for PS and/or PDF:
+AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
+           [a4wide (default), a4, letter, legal or executive])
+case "$DOXYGEN_PAPER_SIZE" in
+#(
+"")
+    AC_SUBST(DOXYGEN_PAPER_SIZE, "")
+;; #(
+a4wide|a4|letter|legal|executive)
+    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
+;; #(
+*)
+    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
+;;
+esac
+
+#For debugging:
+#echo DX_FLAG_doc=$DX_FLAG_doc
+#echo DX_FLAG_dot=$DX_FLAG_dot
+#echo DX_FLAG_man=$DX_FLAG_man
+#echo DX_FLAG_html=$DX_FLAG_html
+#echo DX_FLAG_chm=$DX_FLAG_chm
+#echo DX_FLAG_chi=$DX_FLAG_chi
+#echo DX_FLAG_rtf=$DX_FLAG_rtf
+#echo DX_FLAG_xml=$DX_FLAG_xml
+#echo DX_FLAG_pdf=$DX_FLAG_pdf
+#echo DX_FLAG_ps=$DX_FLAG_ps
+#echo DX_ENV=$DX_ENV
+])
diff -r 20b1f3062855 -r ffdf467315ec gmyth/m4/as-compiler-flag.m4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/m4/as-compiler-flag.m4	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,33 @@
+dnl as-compiler-flag.m4 0.1.0
+
+dnl autostars m4 macro for detection of compiler flags
+
+dnl David Schleef <ds@schleef.org>
+
+dnl $Id: as-compiler-flag.m4,v 1.1.1.1 2005/08/26 00:42:44 andrunko Exp $
+
+dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])
+dnl Tries to compile with the given CFLAGS.
+dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,
+dnl and ACTION-IF-NOT-ACCEPTED otherwise.
+
+AC_DEFUN([AS_COMPILER_FLAG],
+[
+  AC_MSG_CHECKING([to see if compiler understands $1])
+
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $1"
+
+  AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
+  CFLAGS="$save_CFLAGS"
+
+  if test "X$flag_ok" = Xyes ; then
+    $2
+    true
+  else
+    $3
+    true
+  fi
+  AC_MSG_RESULT([$flag_ok])
+])
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/m4/as-expand.m4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/m4/as-expand.m4	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,40 @@
+dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR)
+dnl
+dnl example
+dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
+dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local
+
+AC_DEFUN([AS_AC_EXPAND],
+[
+  EXP_VAR=[$1]
+  FROM_VAR=[$2]
+
+  dnl first expand prefix and exec_prefix if necessary
+  prefix_save=$prefix
+  exec_prefix_save=$exec_prefix
+
+  dnl if no prefix given, then use /usr/local, the default prefix
+  if test "x$prefix" = "xNONE"; then
+    prefix=$ac_default_prefix
+  fi
+  dnl if no exec_prefix given, then use prefix
+  if test "x$exec_prefix" = "xNONE"; then
+    exec_prefix=$prefix
+  fi
+
+  full_var="$FROM_VAR"
+  dnl loop until it doesn't change anymore
+  while true; do
+    new_full_var="`eval echo $full_var`"
+    if test "x$new_full_var"="x$full_var"; then break; fi
+    full_var=$new_full_var
+  done
+
+  dnl clean up
+  full_var=$new_full_var
+  AC_SUBST([$1], "$full_var")
+
+  dnl restore prefix and exec_prefix
+  prefix=$prefix_save
+  exec_prefix=$exec_prefix_save
+])
diff -r 20b1f3062855 -r ffdf467315ec gmyth/m4/as-version.m4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/m4/as-version.m4	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,59 @@
+dnl version.m4 0.0.5
+dnl autostars m4 macro for versioning
+dnl thomas@apestaart.org
+dnl
+dnl AS_VERSION(PACKAGE, PREFIX, MAJOR, MINOR, MICRO, NANO, ACTION_IF_NO_NANO, ACTION_IF_NANO)
+dnl example
+dnl AS_VERSION(gstreamer, GST_VERSION, 0, 3, 2,)
+dnl for a 0.3.2 release version
+dnl
+dnl this macro
+dnl - defines [$PREFIX]_MAJOR, MINOR and MICRO
+dnl - if NANO is empty, then we're in release mode, else in cvs/dev mode
+dnl - defines [$PREFIX], VERSION, and [$PREFIX]_RELEASE
+dnl - executes the relevant action
+dnl - AC_SUBST's PACKAGE, VERSION, [$PREFIX] and [$PREFIX]_RELEASE
+dnl   as well as the little ones
+dnl - doesn't call AM_INIT_AUTOMAKE anymore because it prevents
+dnl   maintainer mode from running ok
+dnl
+dnl don't forget to put #undef [$2] and [$2]_RELEASE in acconfig.h
+
+AC_DEFUN([AS_VERSION],
+[
+  PACKAGE=[$1]
+  [$2]_MAJOR_VERSION=[$3]
+  [$2]_MINOR_VERSION=[$4]
+  [$2]_MICRO_VERSION=[$5]
+  NANO=[$6]
+  [$2]_NANO_VERSION=$NANO
+  if test "x$NANO" = "x" || test "x$NANO" = "x0";
+  then
+      AC_MSG_NOTICE(configuring [$1] for release)
+      VERSION=[$3].[$4].[$5]
+      [$2]_RELEASE=1
+      dnl execute action
+      ifelse([$7], , :, [$7])
+  else
+      AC_MSG_NOTICE(configuring [$1] for development with nano $NANO)
+      VERSION=[$3].[$4].[$5].$NANO
+      [$2]_RELEASE=`date +%Y%m%d_%H%M%S`
+      dnl execute action
+      ifelse([$8], , :, [$8])
+  fi
+
+  [$2]_VERSION=$VERSION
+  AC_DEFINE_UNQUOTED([$2]_VERSION, "$[$2]_VERSION", [Define the version])
+  AC_SUBST([$2]_VERSION)
+  
+  AC_SUBST([$2]_RELEASE)
+
+  AC_SUBST([$2]_MAJOR_VERSION)
+  AC_SUBST([$2]_MINOR_VERSION)
+  AC_SUBST([$2]_MICRO_VERSION)
+  AC_SUBST([$2]_NANO_VERSION)
+  AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Define the package name])
+  AC_SUBST(PACKAGE)
+  AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Define the version])
+  AC_SUBST(VERSION)
+])
diff -r 20b1f3062855 -r ffdf467315ec gmyth/pixmaps/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/pixmaps/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,11 @@
+# Adding the application icon
+#icondir = $(datadir)/miptv/pixmaps
+#icon_DATA = \
+#	miptv.png
+
+
+# Adding the application resources
+pixmapdir = $(pkgdatadir)/pixmaps
+pixmap_DATA = mmyth_logo.png
+
+EXTRA_DIST = $(pixmap_DATA)
diff -r 20b1f3062855 -r ffdf467315ec gmyth/pixmaps/main_logo.gif
Binary file gmyth/pixmaps/main_logo.gif has changed
diff -r 20b1f3062855 -r ffdf467315ec gmyth/pixmaps/mmyth_logo.png
Binary file gmyth/pixmaps/mmyth_logo.png has changed
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,29 @@
+SUBDIRS = libgmyth gui .
+
+bin_PROGRAMS = mmyth
+
+mmyth_SOURCES = mmyth_main.c
+
+mmyth_CFLAGS = 								\
+	$(GTK_CFLAGS) 							\
+	$(GLIB_CFLAGS) 							\
+	$(GST_CFLAGS) 							\
+	$(MYSQL_CFLAGS) 						\
+	-g3 -O0 								\
+	-I$(top_srcdir)/src/libgmyth 			\
+	-I$(top_srcdir)/src/gui 				\
+	-DDATA_DIR=\""$(pkgdatadir)"\" 			\
+	-DPIX_DIR=\""$(pkgdatadir)/pixmaps/"\" 	\
+	-DESG_DIR=\""$(pkgdatadir)/pixmaps/"\" 	\
+	-DICON_DIR=\""$(pkgdatadir)/pixmaps/"\"
+
+mmyth_LDFLAGS = 
+
+mmyth_LDADD = 								\
+	$(GTK_LIBS) 							\
+	$(GLIB_LIBS) 							\
+	$(GST_LIBS) 							\
+	$(GSTBASE_LIBS) 						\
+	$(HILDON_LIBS)							\
+	$(top_srcdir)/src/libgmyth/libgmyth.la	\
+	$(top_srcdir)/src/gui/libmmythgui.la
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,29 @@
+noinst_LTLIBRARIES = libmmythgui.la
+
+libmmythgui_la_SOURCES =		\
+		mmyth_ui.c				\
+		mmyth_uicommon.c		\
+		mmyth_epg_grid_view.c	\
+		mmyth_epg_grid_widget.c	\
+		mmyth_recordui.c		\
+		mmyth_uisettings.c		\
+		mmyth_schedulerui.c
+
+libmmythgui_la_CFLAGS = \
+		$(GTK_CFLAGS) \
+		$(GLIB_CFLAGS) \
+		$(GST_CFLAGS) \
+		$(MYSQL_CFLAGS) \
+		-I$(top_srcdir)/src/libgmyth \
+		-I$(top_srcdir)/src \
+		-DDATA_DIR=\""$(pkgdatadir)"\" \
+		-DPIX_DIR=\""$(pkgdatadir)/pixmaps/"\" \
+		-DICON_DIR=\""$(datadir)/pixmaps/"\" \
+		-g3 -O0
+
+libmmythgui_la_LIBADD = 	\
+	      $(top_srcdir)/src/libgmyth/libgmyth.la
+
+libmmythgui_la_LDFLAGS = -export-dynamic		
+
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_epg_grid_view.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_epg_grid_view.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,213 @@
+#include <string.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <time.h>
+
+#include "mmyth_epg_grid_view.h"
+#include "mmyth_epg_grid_widget.h"
+
+/* Service genre */
+#define GENRE_MIN               0
+#define GENRE_MAX               10
+#define GENRE_UNDEFINED         0
+#define GENRE_MOVIE             1
+#define GENRE_NEWS              2
+#define GENRE_SHOW              3
+#define GENRE_SPORTS            4
+#define GENRE_CHILDREN          5
+#define GENRE_MUSIC             6
+#define GENRE_CULTURE           7
+#define GENRE_SOCIAL            8
+#define GENRE_EDUCATION         9
+#define GENRE_LEISURE           10
+
+#define NRO_HOURS 3
+
+/* Function prototypes*/
+static void update_service_details(MMythEpgGridWidget *object, 
+                                   gpointer arg1, gpointer user_data);
+static gboolean key_press_epg_grid_view(GtkWidget * widget, 
+                                        GdkEventKey * event, 
+                                        gpointer user_data);
+
+static GtkWidget *mmyth_epg_grid_widget = NULL;
+
+/* is a GtkEventBox */
+static GtkWidget *program_details_area = NULL;
+static GtkWidget *details_main_hbox = NULL;
+static GtkWidget *details_vbox = NULL;
+static GtkWidget *details_logo_vbox = NULL;
+
+/* update signal callback from MMythEpgGridWidget */
+static void
+update_service_details(MMythEpgGridWidget *object, gpointer arg1, gpointer user_data) 
+{
+	g_return_if_fail(arg1 != NULL);
+
+	EpgGridItem *epg_grid_item = (EpgGridItem *) arg1;
+	
+	gchar sel_prog_desc[100] = "<big><b>";
+	gchar time_buffer[50];
+
+    /* FIXME: get first content from content_list*/
+    GMythProgramInfo *proginfo = (GMythProgramInfo *) epg_grid_item->proginfo;
+
+    if(proginfo) {
+        GString *prog_name = proginfo->title;    
+        GString *service_name = proginfo->chanid;
+           
+    	if(details_vbox != NULL)
+  	        gtk_container_remove (GTK_CONTAINER (details_main_hbox), details_vbox);	
+    
+        /* update service description */
+        strcat(sel_prog_desc, service_name->str);
+        strcat(sel_prog_desc, "</b></big>");
+    
+        GtkWidget *fst_line_lbl = gtk_label_new(NULL);
+        gtk_misc_set_alignment (GTK_MISC(fst_line_lbl), 0.0, 0.0); 
+        gtk_label_set_markup(GTK_LABEL(fst_line_lbl), sel_prog_desc);     
+
+        /* freeing char[] */
+        sel_prog_desc[0] = 0;
+        strcat(sel_prog_desc, "\t");
+        strcat(sel_prog_desc, prog_name->str);    
+            	        		
+        struct tm loctime_start, loctime_end;
+    
+        // Convert it to local time representation. 
+        /* FIXME: conversion from time to localtime is different
+        in different machines */
+        long int schedule_start_time = proginfo->startts;
+        long int schedule_end_time   = proginfo->endts;
+    
+        if (localtime_r(&schedule_start_time, &loctime_start) == NULL) {
+            g_warning ("localtime_r error in mmyth_epg_grid_view!\n");
+        }
+    
+        #if 0 
+            fprintf (stderr, asctime (loctime_start)); 
+        #endif
+    
+        strftime (time_buffer, 100, "  %H:%M - ", &loctime_start);
+        strcat(sel_prog_desc, time_buffer );
+    
+        if (localtime_r(&schedule_end_time, &loctime_end) == NULL) {
+            g_warning ("localtime_r error in mmyth_epg_grid_view!\n");
+        }
+
+        #if 0
+            fprintf (stderr, asctime (loctime_end));     		    
+        #endif
+    
+        strftime (time_buffer, 100, "%H:%M\n", &loctime_end);
+        strcat(sel_prog_desc, time_buffer );
+    
+        GtkWidget *snd_line_lbl = gtk_label_new(NULL);
+        gtk_misc_set_alignment (GTK_MISC(snd_line_lbl), 0.0, 0.0); 
+        gtk_label_set_markup(GTK_LABEL(snd_line_lbl), sel_prog_desc);     
+    
+        // add the current selected program description to the label
+        details_vbox = gtk_vbox_new(FALSE, 0);
+        GtkWidget *fst_line_hbox = gtk_hbox_new(FALSE, 0);        
+        
+        gtk_box_pack_start (GTK_BOX (fst_line_hbox),
+                            fst_line_lbl, FALSE, FALSE, 6);
+        gtk_box_pack_start (GTK_BOX (details_vbox),
+                            fst_line_hbox, FALSE, FALSE, 0);
+        gtk_box_pack_start (GTK_BOX (details_vbox),
+                            snd_line_lbl, FALSE, FALSE, 0);
+        gtk_box_pack_start (GTK_BOX (details_main_hbox),
+                            details_vbox, FALSE, FALSE, 0);
+        
+        gtk_widget_show_all(details_main_hbox);
+    }        
+}
+
+/* Callback for hardware keys */
+static gboolean
+key_press_epg_grid_view(GtkWidget * widget, 
+                        GdkEventKey * event, gpointer user_data)
+{
+    MMythEpgGridWidget *mmyth_epg_grid_widget = (MMythEpgGridWidget *) user_data;
+
+    return mmyth_epg_grid_widget_key_press(mmyth_epg_grid_widget, widget, event); 
+}
+
+GtkWidget *
+epg_grid_view_new (MMythUi* mmyth_ui) 
+{
+    GtkWidget *scrolled_window;
+    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                    GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);                   
+    
+    gtk_widget_modify_bg(scrolled_window, GTK_STATE_NORMAL, &main_bg_color);  
+    
+    GtkWidget *main_vbox = gtk_vbox_new (FALSE, 0);      
+    //gtk_container_set_border_width(main_vbox, 4);        
+    
+    GtkWidget *details_event_box = gtk_event_box_new();               
+    gtk_widget_modify_bg(details_event_box, GTK_STATE_NORMAL, &main_bg_color);  
+    
+    program_details_area = gtk_vbox_new (FALSE, 0);
+    gtk_container_add (GTK_CONTAINER (details_event_box),
+                       program_details_area);   
+    gtk_container_set_border_width(GTK_CONTAINER (program_details_area), 4);        
+
+	details_main_hbox = gtk_hbox_new (FALSE, 10);    
+
+	gtk_box_pack_start (GTK_BOX (program_details_area),
+	                    details_main_hbox, FALSE, FALSE, 0);                    
+	                    
+	details_logo_vbox = gtk_vbox_new (FALSE, 0);      	 
+    
+	GtkWidget *details_desc_vbox = gtk_vbox_new (FALSE, 0);      
+
+    gtk_box_pack_start (GTK_BOX (details_main_hbox),
+	                    details_desc_vbox, FALSE, FALSE, 0);                    
+    gtk_box_pack_start (GTK_BOX (details_main_hbox),
+	                    details_logo_vbox, FALSE, FALSE, 0);                    	
+	
+    gtk_widget_set_size_request (program_details_area, -1, 120);          
+    
+    mmyth_epg_grid_widget = mmyth_epg_grid_widget_new();
+    g_signal_connect(mmyth_epg_grid_widget, "selection_updated", 
+                     G_CALLBACK (update_service_details), NULL);    
+
+    /* select by default the first service */
+    /* depends on mount services */
+    if (MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget)->epg_view_model) {
+	    GList *fst_service = (GList *) 
+	    	MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget)->epg_view_model->data;
+    	mmyth_epg_grid_widget_update_service(MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget),
+                                         fst_service);
+    }
+    
+    gtk_box_pack_start (GTK_BOX (main_vbox),
+                        details_event_box, FALSE, FALSE, 0); 
+    gtk_box_pack_start (GTK_BOX (main_vbox),
+                        gtk_hseparator_new(), FALSE, FALSE, 0);         
+    gtk_box_pack_start (GTK_BOX (main_vbox),
+                        mmyth_epg_grid_widget, FALSE, FALSE, 0);                    
+
+    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window),
+                                           main_vbox);    
+    
+    /* Add hardware button listener to application */
+    g_signal_connect(mmyth_ui->main_window, "key_press_event", 
+                     G_CALLBACK (key_press_epg_grid_view), mmyth_epg_grid_widget);    
+
+    gtk_widget_show_all (scrolled_window);
+    
+    return scrolled_window;
+}
+
+/*
+DVBHScheduleEvent * 
+mmyth_epg_grid_view_get_selected_schedule()
+{
+    return mmyth_epg_grid_get_selected_schedule
+            (MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget));
+}
+*/
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_epg_grid_view.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_epg_grid_view.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,8 @@
+#ifndef MMYTH_ESG_GRID_VIEW_H_
+#define MMYTH_ESG_GRID_VIEW_H_
+
+#include "mmyth_ui.h"
+
+GtkWidget *epg_grid_view_new(MMythUi * mmyth_ui);
+
+#endif /* MMYTH_ESG_GRID_VIEW_H_ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_epg_grid_widget.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_epg_grid_widget.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,622 @@
+#include <gtk/gtksignal.h>
+#include <gdk/gdkevents.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "mmyth_uicommon.h"
+#include "mmyth_epg_grid_widget.h"
+
+#include "gmyth_util.h" 
+#include "gmyth_epg.h"
+
+#define PIXELS_HOUR 105
+#define PROGRAM_SEPARATION 2
+
+enum {
+  SELECTION_UPDATED_SIGNAL,
+  LAST_SIGNAL
+};
+
+struct _MMythEpgGridWidgetPrivate {
+    /* private widget components */
+    GtkWidget *epg_channels_vbox;
+    GtkWidget *epg_programs_vbox;
+ 
+    GHashTable *service_model_hash;
+    
+    /* guidegrid attributes */
+    gboolean show_favorites;
+    gint current_start_channel_id;
+    
+    time_t current_start_time;
+    time_t current_end_time;
+
+    guint selected_channel_index;
+    
+    /* GList of ProgramInfo for each Channel */
+    GList * program_list[MAX_DISPLAY_CHANS];
+    GList * channel_list;
+    
+    GMythEPG *mmyth_epg;
+    
+    gint DISPLAY_CHANS;
+};
+
+static void mmyth_epg_grid_widget_class_init          (MMythEpgGridWidgetClass *klass);
+static void mmyth_epg_grid_widget_init                (MMythEpgGridWidget *object);
+static void mmyth_epg_grid_widget_private_init        (MMythEpgGridWidgetPrivate *private);
+static void mmyth_epg_grid_widget_mount_services      (MMythEpgGridWidget *object, 
+                                                       int start_time, int end_time);
+static void mmyth_epg_grid_widget_mount_header        (MMythEpgGridWidget *object);
+static void mmyth_epg_grid_widget_clicked             (GtkWidget* widget, 
+                                                       GdkEventExpose *event, 
+                                                       gpointer data);
+static GtkWidget *create_event_box_lbl                (gchar *str, int width, 
+                                                       const GdkColor *bg_color, 
+                                                       const GdkColor *fg_color);
+
+static void mmyth_epg_grid_widget_fill_programinfos(MMythEpgGridWidgetPrivate *private);
+static void mmyth_epg_grid_widget_fill_program_row_infos(
+                    MMythEpgGridWidgetPrivate *private, 
+                    unsigned int chanNum, unsigned int row);
+
+static gint mmyth_epg_grid_widget_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE(MMythEpgGridWidget, mmyth_epg_grid_widget, GTK_TYPE_EVENT_BOX)
+    
+static void
+mmyth_epg_grid_widget_class_init (MMythEpgGridWidgetClass *klass)
+{
+  g_type_class_add_private (klass, sizeof (MMythEpgGridWidgetPrivate));
+  
+  mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL] = g_signal_new (
+                     "selection_updated",
+					 G_TYPE_FROM_CLASS(klass), 
+					 G_SIGNAL_RUN_FIRST,
+					 0,
+                     NULL,
+                     NULL,
+					 g_cclosure_marshal_VOID__POINTER, 
+                     G_TYPE_NONE, 
+                     1,
+                     G_TYPE_POINTER);
+}
+
+static void 
+mmyth_epg_grid_widget_private_init (MMythEpgGridWidgetPrivate *private)
+{
+    time_t cur_time;
+    
+    g_return_if_fail(private != NULL);     
+
+    private->epg_channels_vbox   = NULL;
+    private->epg_programs_vbox   = NULL;
+    private->service_model_hash  = NULL;
+
+    private->show_favorites = FALSE;
+    private->current_start_channel_id = -1;
+
+    /* Selected the first diplayable channel initially */
+    private->selected_channel_index = 0;
+        
+    /* TODO fix the current start/end time */
+    private->current_start_time = time(&cur_time);
+    private->current_end_time = time(&cur_time) + 10800;   
+    
+    private->DISPLAY_CHANS = MAX_DISPLAY_CHANS;
+    
+    // TODO: Close the epg and unref it in dispose call
+    private->mmyth_epg = gmyth_epg_new ();
+    if (!gmyth_epg_connect (private->mmyth_epg)) {
+    	g_warning ("[%s] Could not connect mysql handler to db", __FUNCTION__);
+    	g_object_unref (private->mmyth_epg);
+    	private->mmyth_epg = NULL;
+    }
+}
+
+static void
+mmyth_epg_grid_widget_init (MMythEpgGridWidget *mmyth_epg_grid_widget)
+{
+    MMythEpgGridWidgetPrivate *private = 
+        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
+    
+    /* init private fields */
+    mmyth_epg_grid_widget_private_init(private);
+
+    mmyth_epg_grid_widget->epg_view_model      = NULL;
+    mmyth_epg_grid_widget->selected_grid_item  = NULL;
+
+    GtkWidget *epg_event_box = GTK_WIDGET(mmyth_epg_grid_widget);
+    gtk_widget_modify_bg(epg_event_box, GTK_STATE_NORMAL, &main_bg_color);
+    gtk_widget_set_size_request (epg_event_box, 0, 125);
+    
+    GtkWidget *epg_main_hbox = gtk_hbox_new (FALSE, 10);
+    gtk_container_set_border_width(GTK_CONTAINER (epg_main_hbox), 10);
+    
+    gtk_container_add (GTK_CONTAINER (epg_event_box),
+                       epg_main_hbox);
+		        
+    /* channels vbox */
+    GtkWidget *epg_channels_vbox = gtk_vbox_new (FALSE, 3); 
+    private->epg_channels_vbox = epg_channels_vbox; 
+
+    /* programs vbox */
+    GtkWidget *epg_programs_vbox = gtk_vbox_new (FALSE, 3);
+    private->epg_programs_vbox = epg_programs_vbox;
+    
+    /* packing start */
+    gtk_box_pack_start (GTK_BOX (epg_main_hbox),
+	                epg_channels_vbox, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (epg_main_hbox),
+                        epg_programs_vbox, FALSE, FALSE, 0);
+
+    /* table header (first line) */  
+    mmyth_epg_grid_widget_mount_header(mmyth_epg_grid_widget);                 
+    
+    /* service programs */ 
+    /* mount service programs with current time */
+    mmyth_epg_grid_widget_mount_services(mmyth_epg_grid_widget, 
+                                         private->current_start_time,
+                                         private->current_end_time);                                           
+}
+
+GtkWidget*
+mmyth_epg_grid_widget_new ()
+{
+  return GTK_WIDGET ( gtk_type_new (mmyth_epg_grid_widget_get_type ()));
+}
+
+static void
+mmyth_epg_grid_widget_mount_services(MMythEpgGridWidget *mmyth_epg_grid_widget, 
+                                     int start_time, int end_time)
+{
+    GList *proglist;
+    GList *channel_list = NULL;
+    GMythChannelInfo *channel_info;
+
+    int chanid;
+    MMythEpgGridWidgetPrivate *private = 
+        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
+	
+	// update view_model
+	/* FIXME shallow free or recursive? */
+	if(mmyth_epg_grid_widget->epg_view_model != NULL) {
+		g_list_free(mmyth_epg_grid_widget->epg_view_model);
+		mmyth_epg_grid_widget->epg_view_model = NULL;
+	}
+	
+	if(private->service_model_hash != NULL) {
+		g_hash_table_destroy(private->service_model_hash);
+	}
+
+	private->service_model_hash = g_hash_table_new(NULL, NULL);
+
+    /* fill program infos from db */
+    mmyth_epg_grid_widget_fill_programinfos(private);
+    
+    channel_list = private->channel_list;
+ 
+    /* for each channel get_programs() */
+    for (chanid=0; channel_list &&
+                   chanid < private->DISPLAY_CHANS; chanid++) {
+        proglist = (GList *) private->program_list[chanid];        
+    
+        channel_info = (GMythChannelInfo *) channel_list->data;
+        channel_list = g_list_next(channel_list);        
+
+        /* Service Title*/
+        GString *name = NULL;
+        if (channel_info->channel_name)
+        	name = g_string_new (channel_info->channel_name->str);
+		
+		GdkColor title_bg_color;
+		title_bg_color.red = 5000;
+		title_bg_color.green = 9000;
+		title_bg_color.blue = 40000;        
+		
+		GdkColor title_fg_color;
+		title_fg_color.red = 60000;
+		title_fg_color.green = 60000;
+		title_fg_color.blue = 60000;        
+		
+		GtkWidget *event_box_channel = create_event_box_lbl(
+                                                        name->str, 90, 
+									                    &title_bg_color, 
+									                    &title_fg_color);
+
+        gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
+		                    event_box_channel, FALSE, FALSE, 0);
+
+  		GtkWidget *epg_line_hbox = gtk_hbox_new (FALSE, 0);      
+
+	    GdkColor bg_color;
+	    bg_color.red = 5000;
+	    bg_color.green = 30000;
+	    bg_color.blue = 60000;        
+	
+	    GdkColor fg_color;
+	    fg_color.red = 60000;
+	    fg_color.green = 60000;
+	    fg_color.blue = 60000;        
+		
+		/* Content parsing */
+        GList *epg_grid_list = NULL;
+
+        GMythProgramInfo *proginfo;
+        int pixel_count = 0;
+        for (; proglist; proglist = proglist->next) {
+            proginfo = (GMythProgramInfo *) proglist->data;
+            
+            GString *content_name = proginfo->title;
+                    
+       	    int initial_time, last_time, duration;
+
+            int schedule_start_time = proginfo->startts;
+            int schedule_end_time   = proginfo->endts;
+
+	        initial_time = 
+                (schedule_start_time < start_time) ? start_time : schedule_start_time;
+            last_time = (schedule_end_time > end_time) ? end_time : schedule_end_time;
+	        duration = last_time - initial_time;
+		    
+            // Verify program time 
+            #if 0
+			    g_debug ("ServiceID: %d, ScheduleID: %d\n", service->id, schedule->id);
+                fprintf (stderr, "program time\nfrom = %d, to = %d\n", 
+                         schedule->validFrom, schedule->validTo); 
+                
+                struct tm loctime;
+    
+                /* Convert it to local time representation. */
+                if (localtime_r((time_t *)&schedule->validFrom, &loctime) == NULL) {
+                    g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
+                    return NULL;
+                }            
+                fprintf (stderr, asctime (&loctime)); 
+                
+                if (localtime_r((time_t *)&schedule->validTo, &loctime) == NULL) {
+                    g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
+                    return NULL;
+                } 
+                fprintf (stderr, asctime (&loctime)); 
+            #endif
+    		
+    	    /* fprintf(stderr, "duration = %d\n", duration); */
+    	    double duration_hour = duration / (double) 3600.0;
+    	    /* fprintf(stderr, "duration_hour = %lf\n", duration_hour); */
+    		
+            int size = PIXELS_HOUR * duration_hour;
+                
+            /* complete hour */
+            /* FIXME: UGLY WRONG HACK TO ALIGN PROGRAM TIME!!!*/
+            if(last_time%3600 != 0) {
+                size -= PROGRAM_SEPARATION;                
+            }
+            if(initial_time%3600 != 0) {
+                size -= PROGRAM_SEPARATION;                
+            }
+
+            pixel_count += size + PROGRAM_SEPARATION;
+	        GtkWidget *event_box = create_event_box_lbl(content_name->str, 
+							  size, &bg_color, 
+							  &fg_color);
+							  gtk_widget_add_events(event_box, 
+							  GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+            
+            /* create EpgGridItem */
+            EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
+            epg_grid_item->proginfo  = proginfo;
+            epg_grid_item->event_box = event_box;
+            epg_grid_item->object    = mmyth_epg_grid_widget;
+            
+            epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);                                   		                        
+
+     	    gtk_box_pack_start (GTK_BOX (epg_line_hbox),
+	                            event_box, FALSE, FALSE, PROGRAM_SEPARATION);
+	                                 
+   	        g_signal_connect (G_OBJECT (event_box), "button-press-event",
+		                      G_CALLBACK (mmyth_epg_grid_widget_clicked), 
+                              (gpointer*) epg_grid_list);
+        }
+#if 0
+        printf("chaind = %d!!!!" chanid);fflush(stdout);
+#endif        
+
+        if(!epg_grid_list) {
+            /* No programs for current channel */
+            /* FIXME: size HARDCODED */
+            GtkWidget *event_box = create_event_box_lbl("No program list available",
+                              PIXELS_HOUR * 3, &bg_color,
+                              &fg_color);
+                              gtk_widget_add_events(event_box,
+                              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+            /* create EpgGridItem */
+            EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
+            epg_grid_item->proginfo  = NULL;
+            epg_grid_item->event_box = event_box;
+            epg_grid_item->object    = mmyth_epg_grid_widget;
+
+            epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);
+            
+            gtk_box_pack_start (GTK_BOX (epg_line_hbox),
+	                            event_box, FALSE, FALSE, PROGRAM_SEPARATION);            	
+	                                 
+   	        g_signal_connect (G_OBJECT (event_box), "button-press-event",
+		                      G_CALLBACK (mmyth_epg_grid_widget_clicked),
+                              (gpointer*) epg_grid_list);
+        }
+
+        epg_grid_list = g_list_reverse(epg_grid_list);
+        mmyth_epg_grid_widget->epg_view_model = 
+              g_list_append(mmyth_epg_grid_widget->epg_view_model, epg_grid_list);
+        
+	    gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
+	                        epg_line_hbox, FALSE, FALSE,  0);                    		    		
+    }
+}
+
+static void
+mmyth_epg_grid_widget_mount_header(MMythEpgGridWidget *mmyth_epg_grid_widget)
+{	          	    
+    MMythEpgGridWidgetPrivate *private = 
+        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
+    
+    struct tm hour_tm;
+    const gchar name_title[] = "Today";    
+    GtkWidget * lbl_title = gtk_label_new(name_title);
+
+    gtk_misc_set_alignment (GTK_MISC(lbl_title), 0.0, 0.5);
+    
+    gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
+                        lbl_title, FALSE, FALSE, 0);
+
+	/* hours title line */
+    GtkWidget *epg_programs_hours_hbox = gtk_hbox_new (TRUE, 0); 
+
+    if (localtime_r((time_t *)&private->current_start_time, &hour_tm) == NULL) {
+        g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
+        return NULL;
+    }    
+
+    if (hour_tm.tm_min>30) {
+        hour_tm.tm_min = 30;
+    } else if (hour_tm.tm_min>0) {
+        hour_tm.tm_min = 0;
+    }
+        
+    gchar hour1_str[10];
+    strftime(hour1_str, 8, "%H:%M", &hour_tm);
+    GtkWidget * lbl_hour1 = gtk_label_new(hour1_str);
+    gtk_misc_set_alignment (GTK_MISC(lbl_hour1), 0.0, 0.5);    
+	
+    hour_tm.tm_hour++;
+    gchar hour2_str[10];    
+    strftime(hour2_str, 8, "%H:%M", &hour_tm);
+    GtkWidget * lbl_hour2 = gtk_label_new(hour2_str);
+    gtk_misc_set_alignment (GTK_MISC(lbl_hour2), 0.0, 0.5);        
+
+    hour_tm.tm_hour++;
+	gchar hour3_str[10];    
+    strftime(hour3_str, 8, "%H:%M", &hour_tm);
+    GtkWidget * lbl_hour3 = gtk_label_new(hour3_str);
+    gtk_misc_set_alignment (GTK_MISC(lbl_hour3), 0.0, 0.5);        
+    
+    gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
+                        lbl_hour1, TRUE, TRUE, 0);                    
+    gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
+                        lbl_hour2, TRUE, TRUE, 0);                    
+    gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
+                        lbl_hour3, TRUE, TRUE, 0); 
+ 
+    gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
+                        epg_programs_hours_hbox, FALSE, FALSE, 0);                        
+}
+
+/******************************************************************************
+ *              INTERNAL CALLBACKS FOR STATE CHANGE                           *
+ *****************************************************************************/
+static void 
+mmyth_epg_grid_widget_deselect_service(MMythEpgGridWidget *mmyth_epg_grid_widget)
+{
+	EpgGridItem *epg_grid_item;
+	
+  	/* deselect*/
+    if(mmyth_epg_grid_widget->selected_grid_item != NULL) {
+    	epg_grid_item = 
+            (EpgGridItem*) mmyth_epg_grid_widget->selected_grid_item->data;
+    	gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_NORMAL);
+    }            
+}
+
+static void 
+mmyth_epg_grid_widget_clicked (GtkWidget* widget, 
+                               GdkEventExpose *event, gpointer data)
+{           
+    g_return_if_fail(data != NULL);
+
+    GList *epg_grid_item_list = (GList *) data;
+    EpgGridItem *epg_grid_item = (EpgGridItem *) epg_grid_item_list->data;
+
+    /* update the selected service */
+    mmyth_epg_grid_widget_update_service( epg_grid_item->object, (GList*) data );       
+}
+
+void
+mmyth_epg_grid_widget_update_service(MMythEpgGridWidget * object,
+                                     GList *selected_grid_list)
+{
+    g_return_if_fail(object != NULL);
+    g_return_if_fail(selected_grid_list != NULL);
+		
+	EpgGridItem *epg_grid_item = (EpgGridItem *) selected_grid_list->data;
+
+    mmyth_epg_grid_widget_deselect_service(epg_grid_item->object);
+
+    /* updating current selected schedule_item and schedule_list*/
+    object->selected_grid_item = selected_grid_list;
+    
+    /* set state of the event box */
+    gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_SELECTED);
+    /* emit update signal for listeners */
+    g_signal_emit(object, 
+                  mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL],
+                  0,
+                  (gpointer) epg_grid_item);
+}
+
+static GtkWidget * 
+create_event_box_lbl(gchar *str, int width, const GdkColor *bg_color, 
+                     const GdkColor *fg_color) 
+{
+    GtkWidget *event_box = gtk_event_box_new();
+	GtkWidget *lbl = gtk_label_new(str);
+    gtk_label_set_ellipsize(GTK_LABEL(lbl), PANGO_ELLIPSIZE_END);
+
+    gtk_widget_modify_bg(event_box, GTK_STATE_NORMAL, bg_color);    
+    gtk_widget_modify_fg(lbl, GTK_STATE_NORMAL, fg_color);    
+    
+    /* selected colors are const*/
+    GdkColor selected_bg_color;
+    selected_bg_color.red = 100;
+    selected_bg_color.green = 40000;
+    selected_bg_color.blue = 100;        
+
+    GdkColor selected_fg_color;
+    selected_fg_color.red = 100;
+    selected_fg_color.green = 100;
+    selected_fg_color.blue = 100;        
+            
+    gtk_widget_modify_bg(event_box, GTK_STATE_SELECTED, &selected_bg_color);    
+    gtk_widget_modify_fg(lbl, GTK_STATE_SELECTED, &selected_fg_color);    
+    
+    gtk_misc_set_alignment (GTK_MISC(lbl), 0.0, 0.5);    
+	gtk_container_add (GTK_CONTAINER (event_box),
+                       lbl);
+	gtk_widget_set_size_request(event_box, width, -1);
+	                       
+    return event_box;
+}
+
+/******************************************************************************
+ *                            METHODS                                         *
+ *****************************************************************************/
+
+/* Callback for hardware keys */
+gboolean
+mmyth_epg_grid_widget_key_press (MMythEpgGridWidget * object, 
+                                 GtkWidget * widget, GdkEventKey * event)
+{
+    MMythEpgGridWidgetPrivate *private = 
+        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(object);
+  
+    EpgGridItem *epg_grid_item;
+    GList *tmp;
+    
+    /* List of selected_grid_item */
+    GList *selected_view_model;
+    
+    gint channel_index;
+    
+	if(object->selected_grid_item == NULL) {
+        g_warning ("No program selected");
+	    return FALSE;
+	} 
+    
+    epg_grid_item = (EpgGridItem*) object->selected_grid_item->data;    
+    
+    channel_index = private->selected_channel_index;
+    
+    switch (event->keyval) {
+        case GDK_Up:        
+            selected_view_model = g_list_nth( object->epg_view_model, channel_index - 1 );
+            if(selected_view_model != NULL) {
+                private->selected_channel_index = channel_index - 1;
+   	            tmp = (GList *) selected_view_model->data;               
+                /* TODO: select a better centralized item 
+                   currently is picking the 1st or last item */
+                if(g_list_next(object->selected_grid_item) == NULL &&
+                   g_list_previous(object->selected_grid_item) != NULL) {
+                    /* in this case the new selected will be the last */ 
+                    tmp = g_list_last(tmp);
+                }
+
+	            /* update the selected service */
+                mmyth_epg_grid_widget_update_service( object, tmp );
+            }    
+        return TRUE;         
+        case GDK_Down:
+            selected_view_model = g_list_nth( object->epg_view_model, channel_index + 1 );            
+            if(selected_view_model != NULL) {   	            
+                private->selected_channel_index = channel_index + 1;
+   	            tmp = (GList *) selected_view_model->data;
+                /* TODO: select a better centralized item 
+                   currently is picking the 1st or last item */
+                if(g_list_next(object->selected_grid_item) == NULL &&
+                   g_list_previous(object->selected_grid_item) != NULL) {
+                    /* in this case the new selected will be the last */ 
+                    tmp = g_list_last(tmp);
+                }
+
+	            /* update the selected service */
+                mmyth_epg_grid_widget_update_service( object, tmp );
+            }
+        return TRUE;        
+        case GDK_Left:    
+            tmp = g_list_previous( object->selected_grid_item );
+            if(tmp != NULL) {
+	            /* update the selected service */
+                mmyth_epg_grid_widget_update_service( object, tmp );
+            }
+        return TRUE;        
+        case GDK_Right:
+            tmp = g_list_next( object->selected_grid_item );
+            if(tmp != NULL) {
+	            /* update the selected service */
+                mmyth_epg_grid_widget_update_service( object, tmp );
+            }
+        return TRUE;        
+	    default:
+	    return TRUE;
+    }
+    
+    return FALSE;
+}
+
+static void 
+mmyth_epg_grid_widget_fill_programinfos (MMythEpgGridWidgetPrivate *private)
+{
+    GList *channels_list = NULL;
+    int y;
+
+    if ((private->mmyth_epg != NULL) &&
+	   	(gmyth_epg_get_channel_list (private->mmyth_epg, &channels_list) < 0 )) {
+			private->channel_list = NULL;
+			return;
+    }
+    
+    private->channel_list = channels_list;
+    
+    for (y = 0; y < private->DISPLAY_CHANS && channels_list; y++) {
+        GMythChannelInfo *channel_info = (GMythChannelInfo *) channels_list->data;
+
+        mmyth_epg_grid_widget_fill_program_row_infos(
+                            private, channel_info->channel_ID, y);
+
+        channels_list = g_list_next (channels_list);
+    }
+}
+
+static void 
+mmyth_epg_grid_widget_fill_program_row_infos(MMythEpgGridWidgetPrivate *private,
+                                             guint chanNum, guint row)
+{    
+    gint res =  gmyth_epg_get_program_list (private->mmyth_epg,
+    					&(private->program_list[row]),
+                        chanNum, private->current_start_time, 
+                        private->current_end_time);
+                        
+    if (res < 0) {
+    	g_warning ("[%s] Error while retrieving epg programs", __FUNCTION__);
+    }
+}
+    
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_epg_grid_widget.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_epg_grid_widget.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,74 @@
+#ifndef __MMYTH_EPG_GRID_WIDGET_H__
+#define __MMYTH_EPG_GRID_WIDGET_H__
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkeventbox.h>
+
+#include "gmyth_common.h"
+
+#define MAX_DISPLAY_CHANS 4
+
+#define G_BEGIN_DECLS
+
+#define MMYTH_EPG_GRID_WIDGET_TYPE               (mmyth_epg_grid_widget_get_type ())
+#define MMYTH_EPG_GRID_WIDGET(obj)               (GTK_CHECK_CAST ((obj), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidget))
+#define MMYTH_EPG_GRID_WIDGET_CLASS(klass)       (GTK_CHECK_CLASS_CAST ((klass), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidgetClass))
+#define IS_MMYTH_EPG_GRID_WIDGET(obj)            (GTK_CHECK_TYPE ((obj), MMYTH_EPG_GRID_WIDGET_TYPE))
+#define IS_MMYTH_EPG_GRID_WIDGET_CLASS(klass)    (GTK_CHECK_CLASS_TYPE ((klass), MMYTH_EPG_GRID_WIDGET_TYPE))
+#define MMYTH_EPG_GRID_WIDGET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidgetClass))
+#define MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(obj)   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidgetPrivate))
+
+
+typedef struct _MMythEpgGridWidget         MMythEpgGridWidget;
+typedef struct _MMythEpgGridWidgetClass    MMythEpgGridWidgetClass;
+typedef struct _MMythEpgGridWidgetPrivate  MMythEpgGridWidgetPrivate;
+
+struct _MMythEpgGridWidgetClass
+{
+  GtkEventBoxClass parent_class;
+
+  /* callbacks */
+  /* no one for now */
+};
+
+struct _MMythEpgGridWidget
+{
+    GtkEventBox event_box;
+
+    /* Selected Widgets Logic*/
+    /* List os Service Model in the current view
+     * the data of this list are GList for the programs
+     * of each service */
+    GList *epg_view_model;
+
+    /* Selected Schedule Item*/
+    GList *selected_grid_item;  
+};
+
+
+GType          mmyth_epg_grid_widget_get_type        (void);
+GtkWidget*     mmyth_epg_grid_widget_new             (void);
+/*DVBHScheduleEvent*    mmyth_epg_grid_get_selected_schedule  (MMythEpgGridWidget * object);*/
+void           mmyth_epg_grid_widget_update_service  (MMythEpgGridWidget * object, 
+                                                      GList *epg_grid_item_node);
+gboolean       mmyth_epg_grid_widget_key_press       (MMythEpgGridWidget * object, 
+                                                      GtkWidget * widget, 
+                                                      GdkEventKey * event);
+
+typedef struct _EpgGridItem EpgGridItem;
+
+/* FIXME: auxiliary struct */
+struct _EpgGridItem {
+
+    GMythProgramInfo *proginfo;
+    GtkWidget *event_box;
+
+    /* for callback purposes */
+    MMythEpgGridWidget *object;
+};
+
+#define G_END_DECLS
+
+#endif /* __MMYTH_EPG_GRID_WIDGET_H__ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_recordui.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_recordui.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,332 @@
+#include<gtk/gtk.h>
+#include<glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mmyth_ui.h"
+#include "mmyth_recordui.h"
+
+/* GMyth library includes */
+#include "gmyth_scheduler.h"
+#include "gmyth_util.h"
+
+enum {
+	START_DATE_COLUMN = 0,
+	TITLE_COLUMN,
+	CHAN_ID_COLUMN,
+	END_TIME_COLUMN,
+	RECORD_ID_COLUMN,
+	BASENAME_COLUMN,
+	N_COLUMNS
+};
+
+gboolean
+mmyth_recordui_reload_all (MMythRecordUI *recordui)
+{
+	gboolean res = FALSE;
+
+	res = mmyth_recordui_reload_schedule (recordui);
+		
+	res = res & mmyth_recordui_reload_record (recordui);
+	
+	
+	if (!res)
+		g_warning ("[%s] Error while reloading schedule and recording content", __FUNCTION__);
+		
+	return res;
+}
+
+gboolean
+mmyth_recordui_reload_schedule (MMythRecordUI *recordui)
+{
+	gint new_row = 0;
+	ScheduleInfo *schedule_info;
+	GList *schedule_list;
+	GtkTreeIter iter;
+    GString *start_date_time = NULL;
+    GString *end_date_time = NULL;
+    GString *str_aux = g_string_new("");
+	gint res;
+
+	gtk_tree_store_clear(recordui->sch_tree_store);	
+
+	res = gmyth_scheduler_get_schedule_list(recordui->scheduler, &(schedule_list));
+	if (res < 0) {
+		g_warning ("[%s] Retrieved NULL list of scheduled data from database", 
+                   __FUNCTION__);
+		return FALSE;
+	}
+
+	for ( ; schedule_list; schedule_list = schedule_list->next) {
+ 	  	schedule_info = (ScheduleInfo*) schedule_list->data;
+
+  	  	gtk_tree_store_insert(recordui->sch_tree_store, &iter, NULL, new_row++);
+        
+        start_date_time = gmyth_util_time_to_string(schedule_info->start_time);
+        end_date_time = gmyth_util_time_to_string(schedule_info->end_time);
+        
+        g_string_printf(str_aux, "%d", schedule_info->channel_id);
+        
+	  	gtk_tree_store_set(recordui->sch_tree_store, &iter,
+	  		START_DATE_COLUMN, start_date_time->str, 
+	  		TITLE_COLUMN, schedule_info->title->str,
+	  		CHAN_ID_COLUMN, str_aux->str,
+	  		END_TIME_COLUMN, end_date_time->str, //It doesn't appear
+	  		RECORD_ID_COLUMN, schedule_info->record_id, 
+			-1); //the last line is a hidden item to be used in searching tasks
+ 	}
+  	
+  	g_debug ("[%s] %d lines added to schedule list UI", __FUNCTION__, new_row);
+  	
+    /* free allocated memory */
+    if(!start_date_time)
+        g_string_free(start_date_time, FALSE);
+    if(!end_date_time)
+        g_string_free(end_date_time, FALSE);
+    g_string_free(str_aux,  FALSE);
+    
+  	return TRUE;
+}
+
+gboolean
+mmyth_recordui_reload_record (MMythRecordUI *recordui)
+{
+	gint new_row = 0;
+	RecordedInfo *recorded_info;
+	GList *record_list = NULL;
+	GtkTreeIter iter;
+    GString *start_date_time = NULL;
+    GString *end_date_time = NULL;
+    GString *str_aux = g_string_new("");
+	gint res;
+	
+	gtk_tree_store_clear(recordui->rec_tree_store);		
+
+	res = gmyth_scheduler_get_recorded_list(recordui->scheduler, &record_list);
+	if (res < 0) {
+		g_warning ("[%s] Retrieved NULL list of recorded data from database", __FUNCTION__);
+		return FALSE;
+	}
+	
+	for (; record_list; record_list = record_list->next) {
+ 	  	recorded_info = (RecordedInfo*) record_list->data;
+
+  	  	gtk_tree_store_insert(recordui->rec_tree_store, &iter, NULL, new_row++);
+
+        start_date_time = gmyth_util_time_to_string(recorded_info->start_time);
+        end_date_time = gmyth_util_time_to_string(recorded_info->end_time);
+
+        g_string_printf(str_aux, "%d", recorded_info->channel_id);
+
+	  	gtk_tree_store_set(recordui->rec_tree_store, &iter,
+	  		START_DATE_COLUMN, start_date_time->str, 
+	  		TITLE_COLUMN, recorded_info->title->str,
+	  		CHAN_ID_COLUMN, str_aux->str,
+	  		END_TIME_COLUMN, end_date_time->str, //It doesn't appear
+	  		RECORD_ID_COLUMN, recorded_info->record_id,
+			BASENAME_COLUMN, recorded_info->basename->str, -1); 
+            //the last line is a hidden item to be used in searching tasks	  		
+  	}
+  	
+  	g_debug ("[%s] %d lines added to record list UI", __FUNCTION__, new_row);
+  	  	
+  	return TRUE;
+}
+
+
+MMythRecordUI*
+mmyth_recordui_new(void)
+{
+	MMythRecordUI *recordui = g_new0 (MMythRecordUI, 1);
+	
+	recordui->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (recordui->scrolled_window),
+			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+	recordui->viewport = gtk_viewport_new (NULL, NULL);
+  	gtk_container_add (GTK_CONTAINER (recordui->scrolled_window), recordui->viewport);
+
+  	recordui->notebook = gtk_notebook_new ();
+  	gtk_container_set_border_width (GTK_CONTAINER (recordui->notebook), 1);
+  	gtk_notebook_set_scrollable (GTK_NOTEBOOK (recordui->notebook), TRUE);
+  	gtk_notebook_popup_enable (GTK_NOTEBOOK (recordui->notebook));
+  	gtk_container_add (GTK_CONTAINER (recordui->viewport), recordui->notebook);
+  	gtk_notebook_popup_disable(GTK_NOTEBOOK (recordui->notebook));
+
+	/* Schedule tab */
+  	recordui->sch_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+  	gtk_container_add (GTK_CONTAINER (recordui->notebook), recordui->sch_scrolled_window);
+  	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (recordui->sch_scrolled_window), 
+                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (recordui->sch_scrolled_window), 
+                                         GTK_SHADOW_IN);
+
+    /* The basename column in the sched_tree_store is not being used*/
+  	recordui->sch_tree_store = 
+        gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
+  		                    G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING );
+    
+  	recordui->sch_treeview = 
+        gtk_tree_view_new_with_model(GTK_TREE_MODEL(recordui->sch_tree_store));
+  	gtk_container_add (GTK_CONTAINER (recordui->sch_scrolled_window), 
+                       recordui->sch_treeview);
+  	recordui->sch_renderer = gtk_cell_renderer_text_new();
+  	//g_object_set(G_OBJECT(renderer1), "foreground", "green", "background", "black", NULL);
+  	recordui->sch_column1 = 
+        gtk_tree_view_column_new_with_attributes("Start time", recordui->sch_renderer, 
+                                                 "text", START_DATE_COLUMN, NULL);
+  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview), 
+                                recordui->sch_column1); 
+  	recordui->sch_column2 = 
+        gtk_tree_view_column_new_with_attributes("Title", recordui->sch_renderer, 
+                                                 "text", TITLE_COLUMN, NULL);
+  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview), 
+                                recordui->sch_column2);
+  	recordui->sch_column3 = 
+        gtk_tree_view_column_new_with_attributes("Channel", recordui->sch_renderer, 
+                                                 "text", CHAN_ID_COLUMN, NULL);
+  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview), 
+                                recordui->sch_column3);
+  	gtk_tree_view_column_set_resizable(recordui->sch_column1, TRUE);
+  	gtk_tree_view_column_set_resizable(recordui->sch_column2, TRUE);
+  	gtk_tree_view_column_set_resizable(recordui->sch_column3, TRUE);
+  	gtk_tree_view_column_set_reorderable(recordui->sch_column1, TRUE);
+  	gtk_tree_view_column_set_reorderable(recordui->sch_column2, TRUE);
+  	gtk_tree_view_column_set_reorderable(recordui->sch_column3, TRUE);  	  	  	  	
+//  recordui->sch_column4 = 
+//      gtk_tree_view_column_new_with_attributes("", recordui->sch_renderer, "text", END_TIME_COLUMN, NULL);
+//  gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview), 
+//                                            recordui->sch_column4);
+
+  	recordui->sch_label = gtk_label_new (("Schedule"));
+  	gtk_notebook_set_tab_label (GTK_NOTEBOOK (recordui->notebook), 
+                                gtk_notebook_get_nth_page (
+                                               GTK_NOTEBOOK (recordui->notebook), 0), 
+                                recordui->sch_label);
+
+  // Record items  tab
+  //   g_object_set(G_OBJECT(renderer2), "foreground", "blue", NULL);
+  	recordui->rec_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+  	gtk_container_add (GTK_CONTAINER (recordui->notebook), 
+                       recordui->rec_scrolled_window);
+  	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (recordui->rec_scrolled_window), 
+                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (recordui->rec_scrolled_window), 
+                                         GTK_SHADOW_IN);
+
+  	recordui->rec_tree_store = 
+        gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
+                	        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
+  	recordui->rec_treeview = 
+        gtk_tree_view_new_with_model(GTK_TREE_MODEL(recordui->rec_tree_store));
+  	gtk_container_add (GTK_CONTAINER (recordui->rec_scrolled_window), 
+                       recordui->rec_treeview);
+  	recordui->rec_renderer = gtk_cell_renderer_text_new();
+  	//g_object_set(G_OBJECT(renderer1), "foreground", "green", "background", "black", NULL);
+ 
+  	recordui->rec_column1 = 
+        gtk_tree_view_column_new_with_attributes("Start time", recordui->rec_renderer, 
+                                                 "text", START_DATE_COLUMN, NULL);
+  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview), 
+                                recordui->rec_column1);
+  	recordui->rec_column2 = 
+        gtk_tree_view_column_new_with_attributes("Title", recordui->rec_renderer, 
+                                                 "text", TITLE_COLUMN, NULL);
+  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview), 
+                                recordui->rec_column2);
+  	recordui->rec_column3 = 
+        gtk_tree_view_column_new_with_attributes("Channel", recordui->rec_renderer, 
+                                                 "text", CHAN_ID_COLUMN, NULL);
+  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview), 
+                                recordui->rec_column3);
+  	gtk_tree_view_column_set_resizable(recordui->rec_column1, TRUE);
+  	gtk_tree_view_column_set_resizable(recordui->rec_column2, TRUE);
+  	gtk_tree_view_column_set_resizable(recordui->rec_column3, TRUE);
+  	gtk_tree_view_column_set_reorderable(recordui->rec_column1, TRUE);
+  	gtk_tree_view_column_set_reorderable(recordui->rec_column2, TRUE);
+  	gtk_tree_view_column_set_reorderable(recordui->rec_column3, TRUE);
+//  recordui->rec_column4 = gtk_tree_view_column_new_with_attributes("", recordui->rec_renderer, "text", END_TIME_COLUMN, NULL);
+//  gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview), recordui->rec_column4);
+
+  	recordui->rec_label = gtk_label_new (("Recorded"));
+  	gtk_notebook_set_tab_label (GTK_NOTEBOOK (recordui->notebook), 
+                                gtk_notebook_get_nth_page (
+                                      GTK_NOTEBOOK (recordui->notebook), 1), 
+                                recordui->rec_label);
+  
+  	// Gets the mmyth scheduler manager
+  	recordui->scheduler = gmyth_scheduler_new ();
+    
+    /* init connection to the backend */
+    gmyth_scheduler_connect (recordui->scheduler);
+    
+	return recordui;
+}
+
+void
+mmyth_recordui_free (MMythRecordUI *recordui)
+{
+	// FIXME: Release memory here!
+    /* close connection to the backend */
+    gmyth_scheduler_disconnect (recordui->scheduler);
+}
+
+void
+mmyth_recordui_delete_selected (GtkButton *button, MMythRecordUI *recordui)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel *list_store;
+	GtkTreeIter iter;
+	int index;
+	int curr_page = 0;
+	
+	curr_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(recordui->notebook));
+
+	if ( curr_page == 0) {
+		selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(recordui->sch_treeview));
+		if (selection != NULL) {
+			gtk_tree_selection_get_selected(selection, &list_store, &iter);
+			gtk_tree_model_get(list_store, &iter, RECORD_ID_COLUMN, &index, -1);
+			gmyth_scheduler_delete_schedule(recordui->scheduler, index);
+			mmyth_recordui_reload_schedule (recordui);
+			return;
+		}
+			
+	} else if (curr_page == 1) {
+		selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(recordui->rec_treeview));
+		if (selection != NULL) {
+			gtk_tree_selection_get_selected(selection, &list_store, &iter);
+			gtk_tree_model_get(list_store, &iter, RECORD_ID_COLUMN, &index, -1);
+			gmyth_scheduler_delete_recorded(recordui->scheduler, index);
+			mmyth_recordui_reload_record (recordui);
+			return;
+		}
+	}
+	
+	g_warning ("[%s] None element was removed from the list", __FUNCTION__);
+}
+
+/* FIXME: change this function name, it is returning the 
+ * basename_column that represents the nuv filename of 
+ * the recorded content */
+gchar*
+mmyth_recordui_get_selected_recorded (MMythRecordUI *recordui)
+{
+	GtkTreeSelection *selection = NULL;
+	GtkTreeModel *list_store = NULL;
+	GtkTreeIter iter;
+	gchar *path = NULL;
+
+	/* returning nuv filename, basename_column */
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(recordui->rec_treeview));
+	if (gtk_tree_selection_get_selected (selection, &list_store, &iter)) {
+		gtk_tree_model_get(list_store, &iter, BASENAME_COLUMN, &path, -1);
+	}
+
+	// FIXME: MOVE THIS TO OTHER PLACE
+	return path;
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_recordui.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_recordui.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,48 @@
+#ifndef MMYTH_RECORD_H_
+#define MMYTH_RECORD_H_
+
+#include "gmyth_scheduler.h"
+
+typedef struct _MMythRecordUI
+{
+	GtkWidget *scrolled_window;
+	GtkWidget *viewport;
+	GtkWidget *notebook;
+	
+	GtkWidget *rec_scrolled_window;
+	GtkWidget *sch_scrolled_window;
+	GtkWidget *rec_treeview;
+	GtkWidget *sch_treeview;
+	GtkWidget *rec_label;
+	GtkWidget *sch_label;
+	
+	GtkTreeViewColumn *rec_column1;
+	GtkTreeViewColumn *rec_column2;
+	GtkTreeViewColumn *rec_column3;
+	GtkTreeViewColumn *rec_column4;
+	GtkTreeViewColumn *sch_column1;
+	GtkTreeViewColumn *sch_column2;
+	GtkTreeViewColumn *sch_column3;
+	GtkTreeViewColumn *sch_column4;
+	
+	GtkCellRenderer *rec_renderer;
+	GtkCellRenderer *sch_renderer;
+
+	GtkTreeStore *sch_tree_store;
+	GtkTreeStore *rec_tree_store;
+	
+	GMythScheduler *scheduler;
+	
+} MMythRecordUI;
+
+MMythRecordUI* mmyth_recordui_new(void);
+void mmyth_recordui_free (MMythRecordUI *recordui);
+
+void mmyth_recordui_delete_selected (GtkButton *button, MMythRecordUI *recordui);
+gboolean mmyth_recordui_reload_all (MMythRecordUI *recordui);
+gboolean mmyth_recordui_reload_schedule (MMythRecordUI *recordui);
+gboolean mmyth_recordui_reload_record (MMythRecordUI *recordui);
+
+gchar* mmyth_recordui_get_selected_recorded (MMythRecordUI *recordui);
+
+#endif /*MMYTH_RECORD_H_*/
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_schedulerui.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_schedulerui.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,368 @@
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "mmyth_ui.h"
+#include "mmyth_uicommon.h"
+#include "mmyth_recordui.h"
+#include "mmyth_schedulerui.h"
+
+/* GMyth library includes */
+#include "gmyth_scheduler.h"
+#include "gmyth_common.h"
+#include "gmyth_epg.h"
+
+static void run_calendar_dialog (GtkButton *button, gpointer data);
+
+static void add_channel_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
+static void add_time_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
+static void add_date_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
+static void add_duration_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
+static void add_frequency_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
+static void add_title_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
+
+MMythSchedulerUI*
+mmyth_schedulerui_new (void)
+{
+	GtkWidget *scrolledwindow;	
+	GtkWidget *viewport;	
+	GtkWidget *head_hbox;
+	GtkWidget *fields_vbox;
+	GtkWidget *hseparator;
+	GtkWidget *label;
+
+	MMythSchedulerUI *scheduler_ui = g_new0 (MMythSchedulerUI, 1);
+	
+	scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
+	scheduler_ui->main_widget = scrolledwindow;
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
+  			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+	//Is this needed?  
+	viewport = gtk_viewport_new (NULL, NULL);
+	gtk_container_add (GTK_CONTAINER (scrolledwindow), viewport);
+
+	//Is this needed?
+	head_hbox = gtk_hbox_new (FALSE, 0);
+	gtk_container_add (GTK_CONTAINER (viewport), head_hbox);
+
+	fields_vbox = gtk_vbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (head_hbox), fields_vbox, TRUE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (fields_vbox), 10);
+
+	label = gtk_label_new_with_mnemonic (("Manual Schedule Recording"));
+	gtk_box_pack_start (GTK_BOX (fields_vbox), label, FALSE, FALSE, 0);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+	hseparator = gtk_hseparator_new ();
+	gtk_box_pack_start (GTK_BOX (fields_vbox), hseparator, FALSE, TRUE, 0);
+
+	add_channel_field (scheduler_ui, fields_vbox);
+	add_time_field (scheduler_ui, fields_vbox);
+	add_date_field (scheduler_ui, fields_vbox);
+	add_duration_field (scheduler_ui, fields_vbox);
+	add_frequency_field (scheduler_ui, fields_vbox);
+	add_title_field (scheduler_ui, fields_vbox);
+	
+	return scheduler_ui;
+}
+
+static void
+set_date_from_calendar (GtkCalendar *calendar, gpointer data)
+{
+	char sched_date[24];
+
+	MMythSchedulerUI *scheduler_ui = (MMythSchedulerUI*) data;
+
+	// FIXME: Change this, save another value instead of month_temp, day_temp, ...	
+	gtk_calendar_get_date(GTK_CALENDAR(calendar), 
+		&(scheduler_ui->year_temp), &(scheduler_ui->month_temp), &(scheduler_ui->day_temp));
+
+	sched_date[23]='\0';
+	g_sprintf(sched_date, "%04d %02d %02d (yyyy mm dd)",
+		scheduler_ui->year_temp, scheduler_ui->month_temp+1, scheduler_ui->day_temp);
+
+	gtk_button_set_label(GTK_BUTTON(scheduler_ui->date_button), sched_date);
+
+	gtk_widget_destroy(scheduler_ui->calendar_dialog);
+	scheduler_ui->calendar_dialog = NULL;
+	scheduler_ui->calendar = NULL;
+}
+
+//calendar
+static void
+run_calendar_dialog (GtkButton *button, gpointer data)
+{
+
+	GtkWidget *dialog_vbox;
+	MMythSchedulerUI *scheduler_ui = (MMythSchedulerUI*) data;
+
+	// calendar_dialog and calendar are been released at set_date_from_calendar ()
+	scheduler_ui->calendar_dialog = gtk_dialog_new ();
+	gtk_container_set_border_width (GTK_CONTAINER (scheduler_ui->calendar_dialog), 1);
+  	gtk_window_set_title (GTK_WINDOW (scheduler_ui->calendar_dialog), "Select starting date");
+  	gtk_window_set_position (GTK_WINDOW (scheduler_ui->calendar_dialog), GTK_WIN_POS_CENTER);
+	gtk_window_set_decorated (GTK_WINDOW (scheduler_ui->calendar_dialog), FALSE);
+
+	dialog_vbox = GTK_DIALOG (scheduler_ui->calendar_dialog)->vbox;
+
+	scheduler_ui->calendar = gtk_calendar_new ();
+
+	gtk_box_pack_start (GTK_BOX (dialog_vbox), scheduler_ui->calendar, TRUE, TRUE, 0);
+	gtk_calendar_display_options (GTK_CALENDAR (scheduler_ui->calendar),
+        GTK_CALENDAR_SHOW_HEADING | GTK_CALENDAR_SHOW_DAY_NAMES);
+
+	gtk_widget_show_all (scheduler_ui->calendar_dialog);
+
+	g_signal_connect (G_OBJECT (scheduler_ui->calendar), "day-selected-double-click",
+                      G_CALLBACK (set_date_from_calendar), data);
+}
+
+
+gboolean
+mmyth_schedulerui_save (MMythSchedulerUI *scheduler_ui)
+{
+    GMythScheduler *scheduler;
+	ScheduleInfo *schedule_info;
+	GMythChannelInfo *channel_info;
+
+	GList *clist;
+	gint index, duration;
+    gint frequency;
+    struct tm start_tm;
+	
+	schedule_info = g_new0(ScheduleInfo, 1);
+    if(schedule_info == NULL) {
+        g_warning ("Error allocating memory");
+        return FALSE;
+    }
+        
+    clist = scheduler_ui->channel_list;
+      
+    index = gtk_combo_box_get_active(GTK_COMBO_BOX(scheduler_ui->channel_combobox));
+
+    if (clist != NULL)
+		clist = g_list_nth(clist, index);
+    
+    if (clist) {
+	    g_debug ("[%s] New schedule: %d", __FUNCTION__, index);
+    } else {
+	    g_warning ("[%s] Error when adding new schedule", __FUNCTION__);
+	    return FALSE;
+    }
+    
+    channel_info = clist->data;
+    
+    /* initialize schedule_info */
+    schedule_info->channel_id = channel_info->channel_ID;
+    
+    start_tm.tm_hour = 
+        (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(scheduler_ui->hour_spinbutton));
+	start_tm.tm_min = 
+        (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(scheduler_ui->min_spinbutton));
+    start_tm.tm_sec = 0;
+
+	start_tm.tm_mday = (gint)scheduler_ui->day_temp;
+	start_tm.tm_mon =  (gint)scheduler_ui->month_temp;
+	start_tm.tm_year = (gint)scheduler_ui->year_temp - 1900; //years since 1900
+
+    schedule_info->start_time = timelocal(&start_tm);
+    if (schedule_info->start_time == (time_t)(-1)) {
+        g_warning ("timelocal error!\n");
+        return FALSE;
+    }
+
+	duration = (gint) gtk_spin_button_get_value(
+                        GTK_SPIN_BUTTON(scheduler_ui->duration_spinbutton));
+    schedule_info->end_time = schedule_info->start_time + (duration*60);
+
+    /* TODO: frequency is not implemented yet */
+	frequency = gtk_combo_box_get_active(GTK_COMBO_BOX(scheduler_ui->freq_combobox));
+
+	schedule_info->title = g_string_new("");
+	g_string_printf(schedule_info->title, "%s", 
+                    gtk_entry_get_text(GTK_ENTRY(scheduler_ui->title_entry)));
+	
+    /* FIXME: Architecture change to reuse the scheduler created in the recordui! */
+    scheduler = gmyth_scheduler_new ();
+
+    gmyth_scheduler_connect(scheduler);
+
+    /* FIXME: set record_id = -1 to add a new schedule */
+    schedule_info->record_id = -1;
+    gmyth_scheduler_add_schedule (scheduler, schedule_info);
+
+    gmyth_scheduler_disconnect(scheduler);
+    
+    /* free allocated memory */
+    g_object_unref (scheduler);
+    g_free (schedule_info);
+	
+    return TRUE;
+} 
+
+static GtkWidget*
+add_line (GtkWidget *vbox, const gchar *str)
+{
+	GtkWidget *label;
+	GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
+
+	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (hbox), 3);
+	
+	label = gtk_label_new (str);
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);	
+
+	return hbox;
+}
+
+static void
+add_channel_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
+{
+	GtkWidget *combobox;
+	
+	GtkWidget *hbox = add_line (vbox, "Channel:    ");
+	
+	combobox = gtk_combo_box_new_text ();
+
+	scheduler_ui->channel_combobox = combobox;
+	gtk_box_pack_start (GTK_BOX (hbox), combobox, FALSE, FALSE, 0);
+			
+	GMythEPG *mmyth_epg = gmyth_epg_new ();
+	if (!gmyth_epg_connect (mmyth_epg)) {
+		// FIXME: Without this list the scheduler UI should not be shown!
+		g_warning ("[%s] Error when getting list of channels", __FUNCTION__);
+	}
+  	
+	if (gmyth_epg_get_channel_list (mmyth_epg, &(scheduler_ui->channel_list)) < 0) {
+		g_debug ("[%s] Error while trying to retrieve channel list", __FUNCTION__);
+	} else {
+ 		GList *clist =  scheduler_ui->channel_list;
+		GMythChannelInfo *channel_info;
+
+		while (clist != NULL) {
+  	  		channel_info = clist->data;
+  	  		clist = clist->next;
+  	  		gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->channel_combobox), 
+                                       (channel_info->channel_name->str));
+  		}
+
+       gtk_combo_box_set_active(GTK_COMBO_BOX (scheduler_ui->channel_combobox), 0);
+  	}
+}
+
+static void
+add_time_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
+{
+	GtkWidget *label;
+	GtkObject *spinbutton_adj;
+	GtkWidget *hbox = add_line (vbox, "Time:         ");
+
+	time_t real_time;
+	struct tm sched_time;
+
+	time(&real_time);
+
+    if (localtime_r((time_t *)&real_time, &sched_time) == NULL) {
+        g_warning ("localtime_r error in mmyth_epg_grid_view!\n");
+        return NULL;
+    }
+ 
+	if (sched_time.tm_min>30){
+  		sched_time.tm_hour = sched_time.tm_hour+1;
+  		sched_time.tm_min = 0;
+	} else if (sched_time.tm_min>0) {
+  		sched_time.tm_min = 30;
+	}
+
+  	scheduler_ui->year_temp = (guint)sched_time.tm_year + 1900;
+  	scheduler_ui->month_temp = (guint)sched_time.tm_mon;
+  	scheduler_ui->day_temp = (guint)sched_time.tm_mday;
+   
+	//hour entry
+	spinbutton_adj = gtk_adjustment_new (sched_time.tm_hour, 00, 23, 1, 10, 10);
+	scheduler_ui->hour_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adj), 1, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->hour_spinbutton, FALSE, FALSE, 0);
+
+	label = gtk_label_new ((" : "));
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+	//minute entry
+	spinbutton_adj = gtk_adjustment_new (sched_time.tm_min, 0, 59, 1, 10, 10);
+	scheduler_ui->min_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adj), 1, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->min_spinbutton, FALSE, FALSE, 0);
+
+	label = gtk_label_new ((" (hh:mm)"));
+
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+}	
+
+static void
+add_date_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
+{
+	char sched_date[24];
+	GtkWidget *hbox = add_line (vbox, "Date:        ");
+		
+	//sched_date = ctime(&real_time);
+  	g_sprintf (sched_date, "%04d %02d %02d (yyyy mm dd)", scheduler_ui->year_temp, scheduler_ui->month_temp+1, scheduler_ui->day_temp);
+  	sched_date[23]='\0';
+  
+  	scheduler_ui->date_button = gtk_button_new_with_label (sched_date);
+  	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->date_button, FALSE, FALSE, 0);
+  	gtk_button_set_relief (GTK_BUTTON (scheduler_ui->date_button), GTK_RELIEF_NONE);
+
+	g_signal_connect (G_OBJECT (scheduler_ui->date_button), "clicked",
+                      G_CALLBACK (run_calendar_dialog), scheduler_ui);
+
+}
+
+static void
+add_duration_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
+{
+	GtkWidget *hbox = add_line (vbox, "Duration:   ");
+	GtkWidget *label;
+	GtkObject *spinbutton_adj;
+	
+	spinbutton_adj = gtk_adjustment_new (60, 5, 360, 5, 60, 60);
+  	scheduler_ui->duration_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adj), 1, 0);
+  	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->duration_spinbutton, FALSE, TRUE, 0);
+  	gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (scheduler_ui->duration_spinbutton), TRUE);
+
+	label = gtk_label_new ((" (minutes)     "));
+  	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+}
+
+static void
+add_frequency_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
+{
+	
+	GtkWidget *hbox = add_line (vbox, "Frequency: ");	
+	
+	scheduler_ui->freq_combobox = gtk_combo_box_new_text ();
+	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->freq_combobox, FALSE, FALSE, 0);
+	gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->freq_combobox), ("Only this day               "));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->freq_combobox), ("Daily                            "));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->freq_combobox), ("Weekly                         "));
+	gtk_combo_box_set_active(GTK_COMBO_BOX (scheduler_ui->freq_combobox), 0);
+
+}
+
+static void
+add_title_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
+{
+	GtkWidget *hbox = add_line (vbox, "Title:           ");
+	
+  	scheduler_ui->title_entry = gtk_entry_new ();
+  	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->title_entry, FALSE, FALSE, 0);
+  	gtk_entry_set_text (GTK_ENTRY (scheduler_ui->title_entry), "(Optional)");
+	
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_schedulerui.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_schedulerui.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,45 @@
+#ifndef MMYTH_SCHEDULERECORDING_H_
+#define MMYTH_SCHEDULERECORDING_H_
+
+#include <glib.h>
+
+typedef struct _MMythSchedulerUI {
+	
+	GList *channel_list;
+	
+	GtkWidget *main_widget;
+
+	GtkWidget *channel_combobox;
+	GtkWidget *freq_combobox;
+	GtkWidget *hour_spinbutton;
+	GtkWidget *min_spinbutton;
+	GtkWidget *duration_spinbutton;
+	GtkWidget *title_entry;
+	GtkWidget *date_button;
+
+	GtkWidget *calendar_dialog;
+	GtkWidget *calendar;
+	
+	guint year_temp, month_temp, day_temp;
+} MMythSchedulerUI;
+
+typedef struct {
+    long int channel_id;
+
+    struct tm start_tm;
+
+    int duration;
+    int frequency;
+
+    GString *title;
+
+} ScheduleEntry;
+
+MMythSchedulerUI* mmyth_schedulerui_new (void);
+
+gboolean mmyth_schedulerui_save (MMythSchedulerUI *scheduler_ui);
+
+void mmyth_schedulerui_cb_schedule_button (GtkButton * button, gpointer user_data);
+
+
+#endif /*MMYTH_SCHEDULERECORDING_H_*/
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_ui.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_ui.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,814 @@
+
+#include <glib-object.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gst/interfaces/xoverlay.h>
+#include <assert.h>
+
+#include "mmyth_ui.h"
+#include "mmyth_uicommon.h"
+#include "mmyth_schedulerui.h"
+#include "mmyth_recordui.h"
+#include "mmyth_uisettings.h"
+#include "mmyth_epg_grid_view.h"
+
+/* GMyth library includes */
+#include "gmyth_context.h"
+#include "gmyth_tvplayer.h"
+
+#ifndef MAEMO_PLATFORM
+static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
+#endif
+
+static MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
+static MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
+static MMythUiCommon *create_epg_grid_view (MMythUi * mmyth_ui);
+static MMythUiCommon *create_record_view (MMythUi * mmyth_ui);
+static MMythUiCommon *create_schedule_view (MMythUi * mmyth_ui);
+
+static void cb_video_close_button (GtkButton * button, gpointer user_data);
+static void cb_record_button (GtkButton * button, gpointer user_data);
+static void cb_menu_item_settings (GtkMenuItem *menuitem, gpointer user_data);
+
+/* main box from button box separator*/
+static GtkWidget *main_vseparator = NULL;
+
+GdkPixbuf *icon_sports, *icon_news, 
+          *icon_movies, *icon_shows, *icon_default;
+
+#ifndef MAEMO_PLATFORM
+/* FIXME: */
+static MMythUi *popup_mmyth_ui;
+#endif
+
+MMythUi *
+mmyth_ui_initialize (
+#ifdef MAEMO_PLATFORM
+	HildonProgram *program,
+#endif
+	GtkWidget * main_window)
+{
+    MMythUi *mmyth_ui;
+
+    mmyth_ui = g_new0 (MMythUi, 1);
+
+    mmyth_ui->main_window = main_window;    
+    mmyth_ui->videow = NULL;
+    mmyth_ui->mmyth_recordui = NULL;
+    mmyth_ui->mmyth_schedulerui = NULL;
+	
+    /* Horizontal box that divides the view into control and video area */
+    mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
+    gtk_widget_show (mmyth_ui->main_hbox);
+    g_object_ref (mmyth_ui->main_hbox);
+
+    main_bg_color.red   = 65000;
+    main_bg_color.green = 65000;
+    main_bg_color.blue  = 65000;
+    
+    
+#ifndef MAEMO_PLATFORM
+    /* Popup menu */
+    popup_mmyth_ui = mmyth_ui;
+    g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
+                      G_CALLBACK (button_press_handler),
+                      G_OBJECT (mmyth_ui->main_hbox));    
+
+#else // #ifdef MAEMO
+
+    mmyth_ui->main_menu = GTK_MENU(gtk_menu_new());
+    hildon_program_set_common_menu(program, mmyth_ui->main_menu);
+
+    mmyth_ui->menu_setup = gtk_menu_item_new_with_label("Setup");
+    gtk_widget_set_size_request (GTK_WIDGET (mmyth_ui->menu_setup), 150, 40);
+    gtk_menu_append(mmyth_ui->main_menu, mmyth_ui->menu_setup);
+
+    g_signal_connect(G_OBJECT(mmyth_ui->menu_setup), "activate", G_CALLBACK(cb_menu_item_settings), mmyth_ui);
+
+    gtk_widget_show_all (GTK_WIDGET (mmyth_ui->main_menu));
+#endif
+    
+    // Main widget is mmyth_ui->main_hbox
+    mmyth_ui->main_uicommon       = create_main_view (mmyth_ui);
+
+    gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
+                       mmyth_ui->main_hbox);
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+
+    return mmyth_ui;
+}
+
+void
+mmyth_ui_finalize (MMythUi * mmyth_ui)
+{
+    if (mmyth_ui != NULL) {
+    	if (mmyth_ui->main_uicommon)
+	    	mmyth_uicommon_free (mmyth_ui->main_uicommon);
+    	if (mmyth_ui->video_uicommon)
+		    mmyth_uicommon_free (mmyth_ui->video_uicommon);
+		if (mmyth_ui->epg_grid_uicommon)
+		    mmyth_uicommon_free (mmyth_ui->epg_grid_uicommon);
+		if (mmyth_ui->record_uicommon)
+		    mmyth_uicommon_free (mmyth_ui->record_uicommon);	    
+		if (mmyth_ui->schedule_uicommon)
+		    mmyth_uicommon_free (mmyth_ui->schedule_uicommon);
+
+	    g_free (mmyth_ui);
+    }
+}
+
+void
+mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
+{
+	if (new_uicommon == NULL) {
+		g_warning ("MMythUI setting a NULL UI_Common as current display\n");
+		return;
+	}
+		
+    if (mmyth_ui->current_uicommon) {
+        if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
+            gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
+            gtk_widget_hide (mmyth_ui->videow);
+        }
+        else {
+            gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                                  mmyth_ui->current_uicommon->main_widget);
+        }
+
+        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                              mmyth_ui->current_uicommon->event_box);
+        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                              main_vseparator);        
+
+    }
+
+    if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
+        //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
+        gtk_widget_show (mmyth_ui->video_alignment);
+        gtk_widget_show (mmyth_ui->videow);
+    }
+    else {
+        /* FIXME: Fst call is NULL when mmyth_player_init fails */
+        if(mmyth_ui->video_alignment != NULL)
+            gtk_widget_hide (mmyth_ui->video_alignment);
+        /* FIXME: Fst call is NULL when mmyth_player_init fails */
+        if(mmyth_ui->videow != NULL)
+            gtk_widget_hide (mmyth_ui->videow);
+
+        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                            new_uicommon->main_widget, TRUE, TRUE, 0);
+    }
+
+    if(main_vseparator == NULL) {
+        /* FIXME: should free this variable*/
+        main_vseparator = gtk_vseparator_new();
+        g_object_ref (main_vseparator);                   
+    }  
+    gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                        main_vseparator, FALSE, FALSE, 0);    
+    gtk_widget_show (main_vseparator);
+
+    gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
+                      FALSE, 0);         
+
+    mmyth_ui->current_uicommon = new_uicommon;
+
+}
+
+/* The close callback is the same for all windows*/
+static void
+cb_not_impl_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    GtkWidget *msg_dialog = gtk_message_dialog_new (
+                                           GTK_WINDOW(mmyth_ui->main_window),
+                                           GTK_DIALOG_MODAL |
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_INFO,
+                                           GTK_BUTTONS_OK,
+                                           "Feature not implemented");
+    gtk_widget_set_size_request (msg_dialog, 350, 120);
+
+    gtk_dialog_run (GTK_DIALOG (msg_dialog));
+
+    gtk_widget_destroy(GTK_WIDGET(msg_dialog)); 
+}
+
+/******************************************************************************
+ *                        POPUP MENU WIDGET METHODS                           *
+ *****************************************************************************/
+
+static void 
+cb_menu_item_settings (GtkMenuItem *menuitem,
+                            gpointer user_data)
+{
+    
+    MMythUi *mmyth_ui = (MMythUi*) user_data;
+   
+    if (mmyth_uisettings_run (GTK_WINDOW (mmyth_ui->main_window))) {
+    	// If user changes the settings, we restart the context
+    	g_debug ("[%s] Restarting mmyth_context to new settings", __FUNCTION__);
+    	gmyth_context_initialize();
+    }
+}
+
+#ifndef MAEMO_PLATFORM
+
+static void 
+detacher (GtkWidget *attach_widget,GtkMenu *menu) 
+{
+	
+}
+
+static void
+do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
+{
+    GtkWidget *popup;
+
+  int button, event_time;
+
+  GtkWidget *item_general;
+  GtkWidget *image;
+
+  popup = gtk_menu_new ();
+
+  item_general = gtk_image_menu_item_new_with_mnemonic ("Setup");
+  gtk_widget_show (item_general);
+  gtk_container_add (GTK_CONTAINER (popup), item_general);
+
+  image = gtk_image_new_from_stock ("gtk-edit", GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image);
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item_general), image);
+
+  g_signal_connect (G_OBJECT(item_general), "activate", G_CALLBACK (cb_menu_item_settings), popup_mmyth_ui);
+
+    if (event) {
+      button = event->button;
+      event_time = event->time;
+    } else {
+      button = 0;
+      event_time = gtk_get_current_event_time ();
+    }
+    
+    gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
+    gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
+                  button, event_time);
+    gtk_widget_show_all(popup);
+}
+
+/* Respond to a button-press by posting a menu passed in as widget.
+ *
+ * Note that the "widget" argument is the menu being posted, NOT
+ * the button that was pressed.
+ */
+static gint 
+button_press_handler (GtkWidget *widget, GdkEvent *event)
+{
+
+    if (event->type == GDK_BUTTON_PRESS) {
+      GdkEventButton *bevent = (GdkEventButton *) event; 
+          /* Ignore double-clicks and triple-clicks */
+      if (bevent->button == 3)
+        {
+          do_popup_menu (widget, bevent);
+          return TRUE;
+        }
+    }
+
+    /* Tell calling code that we have not handled this event; pass it on. */
+    return FALSE;
+}
+#endif
+
+/******************************************************************************
+ *                          MAIN APP VIEW METHODS                             *
+ *****************************************************************************/
+
+static void
+cb_close_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+}
+
+static void
+cb_watch_tv_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+	gboolean res = FALSE;
+	
+	if (!(mmyth_ui->video_uicommon))
+		mmyth_ui->video_uicommon = create_video_view (mmyth_ui);
+	
+	// Creates the tv player that will retrieve the mythtv content, decode and show it
+	mmyth_ui->tvplayer = gmyth_tvplayer_new ();
+	/* choose here if this is a LiveTV session */
+	mmyth_ui->tvplayer->is_livetv = TRUE;
+
+	res = gmyth_tvplayer_initialize (mmyth_ui->tvplayer);
+
+	if (!res) {
+		g_warning ("[%s] Could not initialize tvplayer", __FUNCTION__);
+
+		g_object_unref (mmyth_ui->tvplayer);
+		mmyth_ui->tvplayer = NULL;
+
+		GtkWidget *dialog = gtk_message_dialog_new (
+				GTK_WINDOW(mmyth_ui->main_window),
+				GTK_DIALOG_DESTROY_WITH_PARENT,
+                GTK_MESSAGE_ERROR,
+                GTK_BUTTONS_CLOSE,
+			 	"MMyth found errors while starting TV Player, please check "
+			 	"the GStreamer installation");
+
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+		
+		return;
+	}
+	//res = mmyth_tvplayer_livetv_setup (mmyth_ui->tvplayer);
+	//
+	if (mmyth_ui && mmyth_ui->tvplayer && res) {
+		gmyth_tvplayer_set_widget (mmyth_ui->tvplayer, mmyth_ui->videow);
+		gmyth_tvplayer_start_playing (mmyth_ui->tvplayer);
+	} else {
+		// TODO: Show Alert with error description!
+		g_warning ("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
+		g_object_unref (mmyth_ui->tvplayer);
+		mmyth_ui->tvplayer = NULL;
+		// FIXME: Show the exact error that happened
+		GtkWidget *dialog = gtk_message_dialog_new (
+				GTK_WINDOW(mmyth_ui->main_window),
+				GTK_DIALOG_DESTROY_WITH_PARENT,
+                GTK_MESSAGE_ERROR,
+                GTK_BUTTONS_CLOSE,
+                "Error while starting TV Player, please check if the backend"
+                " is running properly and a tv card is available!");
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);		
+		return;
+	}
+	mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);
+	
+}
+
+static void 
+cb_epg_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+    
+    if (!(mmyth_ui->epg_grid_uicommon))
+    	mmyth_ui->epg_grid_uicommon = create_epg_grid_view(mmyth_ui);
+    	
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->epg_grid_uicommon);
+}
+
+static MMythUiCommon *
+create_main_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;
+    GtkWidget *main_widget;
+    GtkWidget *image;
+
+	g_debug ("Creating Main UI Common");
+	
+    // FIXME: file path
+#ifdef MMYTH_DEV
+    image = gtk_image_new_from_file ("../pixmaps/mmyth_logo.png");
+#else
+    image = gtk_image_new_from_file ( PIX_DIR "mmyth_logo.png");
+#endif
+    
+    main_widget = gtk_event_box_new();
+    
+    gtk_container_add (GTK_CONTAINER (main_widget),
+                       image);
+
+
+    gtk_widget_show_all (main_widget);
+    g_object_ref (main_widget);
+
+    ui_common = mmyth_uicommon_new (main_widget,
+                                    "Watch TV", "EPG", "Recording");
+
+    /* Button signals */
+    // FIXME
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_watch_tv_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_epg_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_record_button), mmyth_ui);
+
+    return ui_common;
+
+}
+
+/******************************************************************************
+ *                         epg GRID VIEW METHODS                              *
+ *****************************************************************************/
+
+static MMythUiCommon *
+create_epg_grid_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;        
+
+	g_debug ("Creating EPG Grid UI Common");
+	
+    GtkWidget *epg_grid_view = GTK_WIDGET (epg_grid_view_new (mmyth_ui));
+    
+    ui_common = mmyth_uicommon_new (epg_grid_view,
+                                    "Play", "Record",
+                                    "Close");    
+    
+    /* Button signals */
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_record_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_close_button), mmyth_ui);
+    
+    return ui_common;
+}
+/******************************************************************************
+ *                         SCHEDULE VIEW METHODS                                *
+ ******************************************************************************/
+
+static void
+cb_save_new_schedule (GtkButton *button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+	if (!(mmyth_ui->schedule_uicommon))
+		mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
+		
+    mmyth_schedulerui_save (mmyth_ui->mmyth_schedulerui);
+    
+    mmyth_recordui_reload_schedule (mmyth_ui->mmyth_recordui);
+    
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
+    
+}
+
+static void
+cb_edit_scheduled (GtkTreeView * tree_view, GtkTreePath *path, 
+		           GtkTreeViewColumn *column, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+    GtkTreeSelection *selection;
+	GtkTreeModel *list_store;
+	GtkTreeIter iter;
+	int index;
+    //gint new_row = 0, record_id = 0;
+	ScheduleInfo *schedule_info;
+	GList *schedule_list;
+	//GtkTreeIter iter;
+	gint res;
+
+	//gtk_tree_store_clear(recordui->sch_tree_store);	
+
+	res = gmyth_scheduler_get_schedule_list(mmyth_ui->mmyth_recordui->scheduler, &(schedule_list));
+	if (res < 0) {
+		g_warning ("[%s] Retrieved NULL list of scheduled data from database", __FUNCTION__);
+		//return FALSE;
+	}
+	printf("\nX %d", res); fflush(stdout);
+    
+   	selection = 
+        gtk_tree_view_get_selection(GTK_TREE_VIEW(mmyth_ui->mmyth_recordui->sch_treeview));
+    
+    gtk_tree_selection_get_selected(selection, &list_store, &iter);
+	gtk_tree_model_get(list_store, &iter, 4, &index, -1);
+    
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
+    
+	if (!(mmyth_ui->schedule_uicommon))
+		mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
+		
+	schedule_list = g_list_nth(schedule_list, atoi(gtk_tree_path_to_string(path)));
+	schedule_info = (ScheduleInfo*) schedule_list->data;
+
+    printf("\nstarttime: %ld", schedule_info->start_time); fflush(stdout);		
+}
+
+static MMythUiCommon *
+create_schedule_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;        
+    GtkWidget *schedule_widget;
+    
+    g_debug ("Creating Schedule UI Common");
+
+	mmyth_ui->mmyth_schedulerui = mmyth_schedulerui_new ();
+	if (mmyth_ui->mmyth_schedulerui == NULL) {
+		g_warning ("[%s] Error while creating scheduler ui", __FUNCTION__);
+		return NULL;
+	}
+	
+	schedule_widget = mmyth_ui->mmyth_schedulerui->main_widget;
+
+    gtk_widget_show_all (schedule_widget);
+    g_object_ref (schedule_widget);
+    
+    ui_common = mmyth_uicommon_new (schedule_widget,
+                                    "Save", "Clear",
+                                    "Cancel");    
+
+    /* Button signals */
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_save_new_schedule), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_record_button), mmyth_ui);
+    
+    return ui_common;
+}
+/******************************************************************************
+ *                         RECORD VIEW METHODS                                *
+ ******************************************************************************/
+static void
+cb_record_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+	if (!(mmyth_ui->record_uicommon)) {
+		mmyth_ui->record_uicommon = create_record_view (mmyth_ui);
+		mmyth_ui->schedule_uicommon = create_schedule_view (mmyth_ui);
+	}
+	
+	mmyth_recordui_reload_all (mmyth_ui->mmyth_recordui);
+	
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
+
+} 
+
+static void
+cb_record_close_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+	mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
+
+	mmyth_recordui_free(mmyth_ui->mmyth_recordui);
+	
+	if (mmyth_ui->record_uicommon) {
+		gtk_widget_destroy (mmyth_ui->record_uicommon->main_widget);
+		mmyth_uicommon_free(mmyth_ui->record_uicommon);
+		mmyth_ui->record_uicommon = NULL;
+	}
+
+	if (mmyth_ui->schedule_uicommon) {
+	//	mmyth_uicommon_free(mmyth_ui->schedule_uicommon);
+	}	
+} 
+
+
+
+
+static void
+play_selected_recorded (gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+    gboolean res = FALSE;
+
+    gchar *path = mmyth_recordui_get_selected_recorded (mmyth_ui->mmyth_recordui);
+    
+    if (path == NULL) {
+    	// This should never happens. Play button is just activated when
+    	// a recording is selected.
+    	g_warning ("[%s] Play button pressed while none recorded is selected", __FUNCTION__);
+    	return;
+    }
+
+	if (!(mmyth_ui->video_uicommon))
+		mmyth_ui->video_uicommon = create_video_view (mmyth_ui);
+	
+	// Creates the tv player that will retrieve the mythtv content, decode and show it
+	mmyth_ui->tvplayer = gmyth_tvplayer_new ();
+	g_debug ("[%s] New TV Player created: %d\n", __FUNCTION__, (int) (mmyth_ui->tvplayer));
+	res = gmyth_tvplayer_initialize (mmyth_ui->tvplayer);
+	if (!res) {
+		g_warning ("[%s] Could not initialize tvplayer", __FUNCTION__);
+
+		g_object_unref (mmyth_ui->tvplayer);
+		mmyth_ui->tvplayer = NULL;
+
+		GtkWidget *dialog = gtk_message_dialog_new (
+				GTK_WINDOW(mmyth_ui->main_window),
+				GTK_DIALOG_DESTROY_WITH_PARENT,
+                GTK_MESSAGE_ERROR,
+                GTK_BUTTONS_CLOSE,
+			 	"MMyth found errors while starting TV Player, please check "
+			 	"the GStreamer installation");
+
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+		
+		return;
+	}		
+
+	res = gmyth_tvplayer_record_setup (mmyth_ui->tvplayer, path);
+	
+	if (mmyth_ui && mmyth_ui->tvplayer && res) {
+		gmyth_tvplayer_set_widget (mmyth_ui->tvplayer, mmyth_ui->videow);
+		gmyth_tvplayer_start_playing (mmyth_ui->tvplayer);
+	} else {
+		// TODO: Show Alert with error description!
+		g_warning ("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
+		g_object_unref (mmyth_ui->tvplayer);
+		mmyth_ui->tvplayer = NULL;
+		// FIXME: Show the exact error that happened
+		GtkWidget *dialog = gtk_message_dialog_new (
+				GTK_WINDOW(mmyth_ui->main_window),
+				GTK_DIALOG_DESTROY_WITH_PARENT,
+                GTK_MESSAGE_ERROR,
+                GTK_BUTTONS_CLOSE,
+                "Error while starting TV Player, please check if the backend"
+                " is running properly and a tv card is available!");
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);		
+		return;
+	}
+	
+	mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);    
+}
+
+static void
+cb_play_clicked_recorded (GtkTreeView * tree_view, GtkTreePath *path, 
+		GtkTreeViewColumn *column, gpointer user_data)
+{
+	play_selected_recorded (user_data);
+}
+
+static void
+cb_play_selected (GtkButton * button, gpointer user_data)
+{
+	play_selected_recorded (user_data);
+}
+
+static void
+cb_schedule_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
+}
+
+void
+cb_switch_page (GtkNotebook *notebook, GtkNotebookPage *page,
+		guint page_num, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+    MMythUiCommon *ui_common; 
+    
+	assert (mmyth_ui);
+	assert (mmyth_ui->record_uicommon);
+	
+    ui_common = mmyth_ui->record_uicommon;
+    
+    if (page_num == 0) { // Switched to Schedule list
+    	gtk_button_set_label (GTK_BUTTON (ui_common->button1), "New");
+		g_signal_handlers_disconnect_by_func (
+			G_OBJECT (ui_common->button1), G_CALLBACK (cb_play_selected), mmyth_ui);
+	    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+            G_CALLBACK (cb_schedule_button), mmyth_ui);
+    } else if (page_num == 1) {
+    	gtk_button_set_label (GTK_BUTTON (ui_common->button1), "Play");
+		g_signal_handlers_disconnect_by_func (
+			G_OBJECT (ui_common->button1), G_CALLBACK (cb_schedule_button), mmyth_ui);
+	    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+            G_CALLBACK (cb_play_selected), mmyth_ui);
+    }
+}
+                                            
+                                            
+static MMythUiCommon *
+create_record_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;        
+    
+   	g_debug ("Creating Record UI Common");
+   	
+	mmyth_ui->mmyth_recordui = mmyth_recordui_new ();
+
+	// FIXME: Change MMythRecordUI to a GtkWidget child and avoid this call!
+    gtk_widget_show_all (mmyth_ui->mmyth_recordui->scrolled_window);
+    
+    ui_common = mmyth_uicommon_new (mmyth_ui->mmyth_recordui->scrolled_window, "New", "Delete", "<<Back");    
+    g_object_ref (mmyth_ui->mmyth_recordui->scrolled_window);
+        
+    /* Button signals */
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_schedule_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (mmyth_recordui_delete_selected), mmyth_ui->mmyth_recordui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_record_close_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->notebook),
+		      "switch-page", G_CALLBACK (cb_switch_page), mmyth_ui);
+    g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->rec_treeview),
+		      "row-activated", G_CALLBACK (cb_play_clicked_recorded), mmyth_ui);
+    g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->sch_treeview),
+		      "row-activated", G_CALLBACK (cb_edit_scheduled), mmyth_ui);
+    return ui_common;
+}
+
+
+/******************************************************************************
+ *                         GST VIDEO WIDGET METHODS                           *
+ *****************************************************************************/
+
+static void
+cb_video_close_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+	
+	g_debug ("MMythUI video close button pressed");
+	
+	if (mmyth_ui && mmyth_ui->tvplayer) {
+	    gmyth_tvplayer_stop_playing (mmyth_ui->tvplayer);
+
+		g_object_unref (mmyth_ui->tvplayer);
+		mmyth_ui->tvplayer = NULL;	    
+	} else {
+		g_warning ("cb_video_close_button called with NULL pointer\n");
+	}
+	
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+}
+
+
+static MMythUiCommon *
+create_video_view (MMythUi * mmyth_ui)
+{
+
+    MMythUiCommon *ui_common;
+
+	g_debug ("Creating Video UI Common");
+	
+	/* Creates widget to be user by MMythTVPlayer to draw the video */
+    mmyth_ui->videow = gtk_drawing_area_new ();
+    // FIXME: Get the widget size from settings
+    gtk_widget_set_size_request (mmyth_ui->videow, 300, 240);
+
+    //mmiptv_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
+
+	// Creates an alignment to place the video widget inside
+    mmyth_ui->video_alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
+    gtk_widget_hide (mmyth_ui->video_alignment);
+
+    gtk_container_add (GTK_CONTAINER (mmyth_ui->video_alignment),
+                       mmyth_ui->videow);
+
+    /* Add the gst video widget to hbox. It should never be removed. */    
+    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
+    if((mmyth_ui->main_hbox != NULL) && (mmyth_ui->video_alignment != NULL)) {
+        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                            mmyth_ui->video_alignment, TRUE, TRUE, 0);    
+	} else {
+		g_warning ("[%s] Error while adding video_alignment to main widget", __FUNCTION__);	
+    }
+
+    g_object_ref (mmyth_ui->videow);
+    g_object_ref (mmyth_ui->video_alignment);
+
+    ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
+                                    "  Full\nScreen", "Other\nServices",
+                                    "Close");
+                                    
+    
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);    
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_video_close_button), mmyth_ui);
+
+	if (ui_common)
+		g_debug ("Video UI_Common sucessfull created");
+		
+    return ui_common;
+}
+
+
+
+GtkWidget*
+mmyth_ui_get_video_widget (MMythUi *mmyth_ui) {
+	
+	if (mmyth_ui && mmyth_ui->videow) {
+	
+		return mmyth_ui->videow;
+	}
+	
+	return NULL;	
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_ui.c.mine
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_ui.c.mine	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,451 @@
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gst/interfaces/xoverlay.h>
+
+#include "mmyth_ui.h"
+#include "mmyth_uicommon.h"
+/* FIXME
+#include "mmyth_videoplayer.h"
+*/
+#include "mmyth_esg_grid_view.h"
+
+static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
+
+MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
+MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
+MMythUiCommon *create_esg_grid_view (MMythUi * mmyth_ui);
+static void cb_video_close_button (GtkButton * button, gpointer user_data);
+
+/* main box from button box separator*/
+static GtkWidget *main_vseparator = NULL;
+
+GdkPixbuf *icon_sports, *icon_news, 
+          *icon_movies, *icon_shows, *icon_default;
+
+/* FIXME: UGLY HACK */
+MMythUi *popup_mmyth_ui;
+
+void
+mmyth_ui_initialize_icons ()
+{
+    GError *error = NULL;
+
+#ifdef MMYTH_DEVEL
+    icon_sports =
+        gdk_pixbuf_new_from_file ("../pixmaps/ico_sports.png", &error);
+#else
+    icon_sports = gdk_pixbuf_new_from_file (PIX_DIR "ico_sports.png", &error);
+#endif
+
+    if (error) {
+        g_warning ("Could not load icon sports: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_news = gdk_pixbuf_new_from_file ("../pixmaps/ico_news.png", &error);
+#else
+    icon_news = gdk_pixbuf_new_from_file (PIX_DIR "ico_news.png", &error);
+#endif
+
+    if (error) {
+        g_warning ("Could not load icon news: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_movies =
+        gdk_pixbuf_new_from_file ("../pixmaps/ico_movies.png", &error);
+#else
+    icon_movies = gdk_pixbuf_new_from_file (PIX_DIR "ico_movies.png", &error);
+#endif
+    if (error) {
+        g_warning ("Could not load icon movies: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_shows = gdk_pixbuf_new_from_file ("../pixmaps/ico_shows.png", &error);
+#else
+    icon_shows = gdk_pixbuf_new_from_file (PIX_DIR "ico_shows.png", &error);
+#endif
+    if (error) {
+        g_warning ("Could not load icon shows: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_default =
+        gdk_pixbuf_new_from_file ("../pixmaps/ico_default.png", &error);
+#else
+    icon_default = gdk_pixbuf_new_from_file (PIX_DIR "ico_default.png", &error);
+#endif
+
+    if (error) {
+        g_warning ("Could not load icon default: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+}
+
+MMythUi *
+mmyth_ui_initialize (GtkWidget * main_window)
+{
+    MMythUi *mmyth_ui;
+
+	// FIXME: REMOVE ME
+	//mmyth_settings_load ( );
+    
+    mmyth_ui = g_new0 (MMythUi, 1);
+
+    mmyth_ui->main_window = main_window;    
+
+    /* Horizontal box that divides the view into control and video area */
+    mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
+    gtk_widget_show (mmyth_ui->main_hbox);
+    g_object_ref (mmyth_ui->main_hbox);
+
+    mmyth_ui_initialize_icons ();
+    
+    main_bg_color.red   = 65000;
+    main_bg_color.green = 65000;
+    main_bg_color.blue  = 65000;
+    
+    // Main widget is mmyth_ui->main_hbox
+    mmyth_ui->main_uicommon       = create_main_view (mmyth_ui);
+    mmyth_ui->video_uicommon      = create_video_view (mmyth_ui);
+    mmyth_ui->esg_grid_uicommon   = create_esg_grid_view (mmyth_ui);
+
+    /* Popup menu */
+    /* FIXME: URGENT ugly, ugly hack */
+    popup_mmyth_ui = mmyth_ui;
+    g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
+                      G_CALLBACK (button_press_handler),
+                      G_OBJECT (mmyth_ui->main_hbox));    
+    
+    gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
+                       mmyth_ui->main_hbox);
+
+    /* Add the gst video widget to hbox. It should never be removed. */    
+    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
+    if(mmyth_ui->video_alignment != NULL)
+        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                            mmyth_ui->video_alignment, TRUE, TRUE, 0);    
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+
+    return mmyth_ui;
+}
+
+void
+mmyth_ui_finalize (MMythUi * mmyth_ui)
+{
+    if (mmyth_ui != NULL)
+        g_free (mmyth_ui);
+
+    mmyth_uicommon_unref_all (mmyth_ui->main_uicommon);
+    mmyth_uicommon_unref_all (mmyth_ui->video_uicommon);
+    mmyth_uicommon_unref_all (mmyth_ui->esgcurrent_uicommon);
+}
+
+void
+mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
+{
+    if (mmyth_ui->current_uicommon) {
+        if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
+            gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
+            gtk_widget_hide (mmyth_ui->videow);
+        }
+        else {
+            gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                                  mmyth_ui->current_uicommon->main_widget);
+        }
+
+        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                              mmyth_ui->current_uicommon->event_box);
+        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                              main_vseparator);        
+
+    }
+
+    if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
+        //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
+        gtk_widget_show (mmyth_ui->video_alignment);
+        gtk_widget_show (mmyth_ui->videow);
+    }
+    else {
+        /* FIXME: Fst call is NULL when mmyth_player_init fails */
+        if(mmyth_ui->video_alignment != NULL)
+            gtk_widget_hide (mmyth_ui->video_alignment);
+        /* FIXME: Fst call is NULL when mmyth_player_init fails */
+        if(mmyth_ui->videow != NULL)
+            gtk_widget_hide (mmyth_ui->videow);
+
+        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                            new_uicommon->main_widget, TRUE, TRUE, 0);
+    }
+
+    if(main_vseparator == NULL) {
+        /* FIXME: should free this variable*/
+        main_vseparator = gtk_vseparator_new();
+        g_object_ref (main_vseparator);                   
+    }  
+    gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                        main_vseparator, FALSE, FALSE, 0);    
+    gtk_widget_show (main_vseparator);
+
+    gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
+                      FALSE, 0);         
+
+    mmyth_ui->current_uicommon = new_uicommon;
+
+}
+
+/* The close callback is the same for all windows*/
+static void
+cb_not_impl_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    GtkWidget *msg_dialog = gtk_message_dialog_new (
+                                           GTK_WINDOW(mmyth_ui->main_window),
+                                           GTK_DIALOG_MODAL |
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_INFO,
+                                           GTK_BUTTONS_OK,
+                                           "Feature not implemented yet");
+    gtk_widget_set_size_request (msg_dialog, 300, 120);
+
+    gtk_dialog_run (GTK_DIALOG (msg_dialog));
+
+    gtk_widget_destroy(GTK_WIDGET(msg_dialog)); 
+}
+
+/******************************************************************************
+ *                        POPUP MENU WIDGET METHODS                           *
+ *****************************************************************************/
+
+void 
+detacher (GtkWidget *attach_widget,GtkMenu *menu) 
+{
+}
+
+void 
+menu_item_settings_cb (GtkMenuItem *menuitem,
+                            gpointer user_data)
+{
+    /* MMythUi *mmyth_ui = (MMythUi *) user_data; */
+
+    /* FIXME
+    MMythUi *mmyth_ui = popup_mmyth_ui;
+    
+    settings_show_dialog (GTK_WINDOW (mmyth_ui->main_window));    
+    */
+}
+
+static void
+do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
+{
+    GtkWidget *popup;
+    int button, event_time;
+    
+    popup = gtk_menu_new ();
+    
+    /* ... add menu items ... */
+    GtkWidget *menu_item = gtk_menu_item_new_with_label("Settings");
+    gtk_menu_append(popup, menu_item);
+    
+    g_signal_connect (G_OBJECT(menu_item), "activate", 
+                      G_CALLBACK (menu_item_settings_cb), NULL);
+    
+    if (event)
+    {
+      button = event->button;
+      event_time = event->time;
+    }
+    else
+    {
+      button = 0;
+      event_time = gtk_get_current_event_time ();
+    }
+    
+    //gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
+    gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
+                  button, event_time);
+    gtk_widget_show_all(popup);
+}
+
+/* Respond to a button-press by posting a menu passed in as widget.
+ *
+ * Note that the "widget" argument is the menu being posted, NOT
+ * the button that was pressed.
+ */
+
+static gint 
+button_press_handler (GtkWidget *widget, GdkEvent *event)
+{
+
+    if (event->type == GDK_BUTTON_PRESS) {
+      GdkEventButton *bevent = (GdkEventButton *) event; 
+          /* Ignore double-clicks and triple-clicks */
+      if (bevent->button == 3)
+        {
+          do_popup_menu (widget, bevent);
+          return TRUE;
+        }
+    }
+
+    /* Tell calling code that we have not handled this event; pass it on. */
+    return FALSE;
+}
+
+
+/******************************************************************************
+ *                          MAIN APP VIEW METHODS                             *
+ *****************************************************************************/
+
+/* The close callback is the same for all windows*/
+static void
+cb_close_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+}
+
+static void 
+cb_esg_today_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->esg_grid_uicommon);
+}
+
+MMythUiCommon *
+create_main_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;
+    GtkWidget *main_widget;
+    GtkWidget *image;
+
+    // FIXME: file path
+#ifdef MMYTH_DEV
+    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
+#else
+    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
+#endif
+    
+    main_widget = gtk_event_box_new();
+    
+    gtk_container_add (GTK_CONTAINER (main_widget),
+                       image);
+    
+
+    gtk_widget_show_all (main_widget);
+    g_object_ref (main_widget);
+
+    ui_common = mmyth_uicommon_new (main_widget,
+                                    "Channels", "Current", "Today");
+
+    /* Button signals */
+    /* FIXME
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_channels_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_esg_current_button), mmyth_ui);
+    */
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_esg_today_button), mmyth_ui);
+
+    return ui_common;
+
+}
+
+/******************************************************************************
+ *                         ESG GRID VIEW METHODS                              *
+ *****************************************************************************/
+
+static void
+cb_esg_grid_view_button (GtkButton * button, gpointer user_data)
+{
+    /* FIXME 
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+    guint32 service_id = -1;
+
+    // Retrieves the user selected service ID 
+    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
+    
+    if(schedule != NULL) {
+        service_id = schedule->service->number;
+        mmyth_play_channel (mmyth_ui, service_id);    
+    }
+    */
+}
+
+MMythUiCommon *
+create_esg_grid_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;        
+    GtkWidget *esg_grid_view = GTK_WIDGET (esg_grid_view_new (mmyth_ui));
+    
+    
+    ui_common = mmyth_uicommon_new (esg_grid_view,
+                                    "View", "Remind",
+                                    "Close");    
+    
+    /* Button signals */
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_esg_grid_view_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_close_button), mmyth_ui);
+    
+    return ui_common;
+}
+
+/******************************************************************************
+ *                         GST VIDEO WIDGET METHODS                           *
+ *****************************************************************************/
+
+static void
+cb_video_close_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    /* FIXME
+    mmyth_player_stop (mmyth_ui);
+    */
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+}
+
+MMythUiCommon *
+create_video_view (MMythUi * mmyth_ui)
+{
+
+    MMythUiCommon *ui_common;
+
+    /* FIXME
+    mmyth_player_init (mmyth_ui);
+    */
+
+    ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
+                                    "  Full\nScreen", "Other\nServices",
+                                    "Close");
+
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);    
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_video_close_button), mmyth_ui);
+
+    return ui_common;
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_ui.c.r2518
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_ui.c.r2518	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,456 @@
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gst/interfaces/xoverlay.h>
+
+#include "mmyth_ui.h"
+#include "mmyth_uicommon.h"
+/* FIXME
+#include "mmyth_videoplayer.h"
+#include "mmyth_esg_grid_view.h"
+#include "mmyth_common.h"
+*/
+
+static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
+
+MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
+MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
+MMythUiCommon *create_esg_grid_view (MMythUi * mmyth_ui);
+static void cb_video_close_button (GtkButton * button, gpointer user_data);
+
+/* main box from button box separator*/
+static GtkWidget *main_vseparator = NULL;
+
+GdkPixbuf *icon_sports, *icon_news, 
+          *icon_movies, *icon_shows, *icon_default;
+
+/* FIXME: UGLY HACK */
+MMythUi *popup_mmyth_ui;
+
+void
+mmyth_ui_initialize_icons ()
+{
+    GError *error = NULL;
+
+#ifdef MMYTH_DEVEL
+    icon_sports =
+        gdk_pixbuf_new_from_file ("../pixmaps/ico_sports.png", &error);
+#else
+    icon_sports = gdk_pixbuf_new_from_file (PIX_DIR "ico_sports.png", &error);
+#endif
+
+    if (error) {
+        g_warning ("Could not load icon sports: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_news = gdk_pixbuf_new_from_file ("../pixmaps/ico_news.png", &error);
+#else
+    icon_news = gdk_pixbuf_new_from_file (PIX_DIR "ico_news.png", &error);
+#endif
+
+    if (error) {
+        g_warning ("Could not load icon news: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_movies =
+        gdk_pixbuf_new_from_file ("../pixmaps/ico_movies.png", &error);
+#else
+    icon_movies = gdk_pixbuf_new_from_file (PIX_DIR "ico_movies.png", &error);
+#endif
+    if (error) {
+        g_warning ("Could not load icon movies: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_shows = gdk_pixbuf_new_from_file ("../pixmaps/ico_shows.png", &error);
+#else
+    icon_shows = gdk_pixbuf_new_from_file (PIX_DIR "ico_shows.png", &error);
+#endif
+    if (error) {
+        g_warning ("Could not load icon shows: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_default =
+        gdk_pixbuf_new_from_file ("../pixmaps/ico_default.png", &error);
+#else
+    icon_default = gdk_pixbuf_new_from_file (PIX_DIR "ico_default.png", &error);
+#endif
+
+    if (error) {
+        g_warning ("Could not load icon default: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+}
+
+MMythUi *
+mmyth_ui_initialize (GtkWidget * main_window)
+{
+    MMythUi *mmyth_ui;
+
+	// FIXME: REMOVE ME
+	//mmyth_settings_load ( );
+    
+    mmyth_ui = g_new0 (MMythUi, 1);
+
+    mmyth_ui->main_window = main_window;    
+
+    /* Horizontal box that divides the view into control and video area */
+    mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
+    gtk_widget_show (mmyth_ui->main_hbox);
+    g_object_ref (mmyth_ui->main_hbox);
+
+    mmyth_ui_initialize_icons ();
+    
+    main_bg_color.red   = 65000;
+    main_bg_color.green = 65000;
+    main_bg_color.blue  = 65000;
+    
+    // Main widget is mmyth_ui->main_hbox
+    mmyth_ui->main_uicommon       = create_main_view (mmyth_ui);
+    mmyth_ui->video_uicommon      = create_video_view (mmyth_ui);
+    mmyth_ui->esg_grid_uicommon   = create_esg_grid_view (mmyth_ui);
+
+    /* Popup menu */
+    /* FIXME: URGENT ugly, ugly hack */
+    popup_mmyth_ui = mmyth_ui;
+    g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
+                      G_CALLBACK (button_press_handler),
+                      G_OBJECT (mmyth_ui->main_hbox));    
+    
+    gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
+                       mmyth_ui->main_hbox);
+
+    /* Add the gst video widget to hbox. It should never be removed. */    
+    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
+    if(mmyth_ui->video_alignment != NULL)
+        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                            mmyth_ui->video_alignment, TRUE, TRUE, 0);    
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+
+    return mmyth_ui;
+}
+
+void
+mmyth_ui_finalize (MMythUi * mmyth_ui)
+{
+    if (mmyth_ui != NULL)
+        g_free (mmyth_ui);
+
+    mmyth_uicommon_unref_all (mmyth_ui->main_uicommon);
+    mmyth_uicommon_unref_all (mmyth_ui->video_uicommon);
+    mmyth_uicommon_unref_all (mmyth_ui->esgcurrent_uicommon);
+}
+
+void
+mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
+{
+    if (mmyth_ui->current_uicommon) {
+        if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
+            gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
+            gtk_widget_hide (mmyth_ui->videow);
+        }
+        else {
+            gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                                  mmyth_ui->current_uicommon->main_widget);
+        }
+
+        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                              mmyth_ui->current_uicommon->event_box);
+        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                              main_vseparator);        
+
+    }
+
+    if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
+        //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
+        gtk_widget_show (mmyth_ui->video_alignment);
+        gtk_widget_show (mmyth_ui->videow);
+    }
+    else {
+        /* FIXME: Fst call is NULL when mmyth_player_init fails */
+        if(mmyth_ui->video_alignment != NULL)
+            gtk_widget_hide (mmyth_ui->video_alignment);
+        /* FIXME: Fst call is NULL when mmyth_player_init fails */
+        if(mmyth_ui->videow != NULL)
+            gtk_widget_hide (mmyth_ui->videow);
+
+        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                            new_uicommon->main_widget, TRUE, TRUE, 0);
+    }
+
+    if(main_vseparator == NULL) {
+        /* FIXME: should free this variable*/
+        main_vseparator = gtk_vseparator_new();
+        g_object_ref (main_vseparator);                   
+    }  
+    gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                        main_vseparator, FALSE, FALSE, 0);    
+    gtk_widget_show (main_vseparator);
+
+    gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
+                      FALSE, 0);         
+
+    mmyth_ui->current_uicommon = new_uicommon;
+
+}
+
+/* The close callback is the same for all windows*/
+static void
+cb_not_impl_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    GtkWidget *msg_dialog = gtk_message_dialog_new (
+                                           GTK_WINDOW(mmyth_ui->main_window),
+                                           GTK_DIALOG_MODAL |
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_INFO,
+                                           GTK_BUTTONS_OK,
+                                           "Feature not implemented yet");
+    gtk_widget_set_size_request (msg_dialog, 300, 120);
+
+    gtk_dialog_run (GTK_DIALOG (msg_dialog));
+
+    gtk_widget_destroy(GTK_WIDGET(msg_dialog)); 
+}
+
+/******************************************************************************
+ *                        POPUP MENU WIDGET METHODS                           *
+ *****************************************************************************/
+
+void 
+detacher (GtkWidget *attach_widget,GtkMenu *menu) 
+{
+}
+
+void 
+menu_item_settings_cb (GtkMenuItem *menuitem,
+                            gpointer user_data)
+{
+    /* MMythUi *mmyth_ui = (MMythUi *) user_data; */
+
+    /* FIXME
+    MMythUi *mmyth_ui = popup_mmyth_ui;
+    
+    settings_show_dialog (GTK_WINDOW (mmyth_ui->main_window));    
+    */
+}
+
+static void
+do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
+{
+    GtkWidget *popup;
+    int button, event_time;
+    
+    popup = gtk_menu_new ();
+    
+    /* ... add menu items ... */
+    GtkWidget *menu_item = gtk_menu_item_new_with_label("Settings");
+    gtk_menu_append(popup, menu_item);
+    
+    g_signal_connect (G_OBJECT(menu_item), "activate", 
+                      G_CALLBACK (menu_item_settings_cb), NULL);
+    
+    if (event)
+    {
+      button = event->button;
+      event_time = event->time;
+    }
+    else
+    {
+      button = 0;
+      event_time = gtk_get_current_event_time ();
+    }
+    
+    //gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
+    gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
+                  button, event_time);
+    gtk_widget_show_all(popup);
+}
+
+/* Respond to a button-press by posting a menu passed in as widget.
+ *
+ * Note that the "widget" argument is the menu being posted, NOT
+ * the button that was pressed.
+ */
+
+static gint 
+button_press_handler (GtkWidget *widget, GdkEvent *event)
+{
+
+    if (event->type == GDK_BUTTON_PRESS) {
+      GdkEventButton *bevent = (GdkEventButton *) event; 
+          /* Ignore double-clicks and triple-clicks */
+      if (bevent->button == 3)
+        {
+          do_popup_menu (widget, bevent);
+          return TRUE;
+        }
+    }
+
+    /* Tell calling code that we have not handled this event; pass it on. */
+    return FALSE;
+}
+
+
+/******************************************************************************
+ *                          MAIN APP VIEW METHODS                             *
+ *****************************************************************************/
+
+/* The close callback is the same for all windows*/
+static void
+cb_close_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+}
+
+/* FIXME
+static void 
+cb_esg_today_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->esg_grid_uicommon);
+}
+*/
+
+MMythUiCommon *
+create_main_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;
+    GtkWidget *main_widget;
+    GtkWidget *image;
+
+    // FIXME: file path
+#ifdef MMYTH_DEV
+    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
+#else
+    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
+#endif
+    
+    main_widget = gtk_event_box_new();
+    
+    gtk_container_add (GTK_CONTAINER (main_widget),
+                       image);
+    
+
+    gtk_widget_show_all (main_widget);
+    g_object_ref (main_widget);
+
+    ui_common = mmyth_uicommon_new (main_widget,
+                                    "Channels", "Current", "Today");
+
+    /* Button signals */
+    /* FIXME
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_channels_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_esg_current_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_esg_today_button), mmyth_ui);
+    */
+
+    return ui_common;
+
+}
+
+/******************************************************************************
+ *                         ESG GRID VIEW METHODS                              *
+ *****************************************************************************/
+
+static void
+cb_esg_grid_view_button (GtkButton * button, gpointer user_data)
+{
+    /* FIXME 
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+    guint32 service_id = -1;
+
+    // Retrieves the user selected service ID 
+    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
+    
+    if(schedule != NULL) {
+        service_id = schedule->service->number;
+        mmyth_play_channel (mmyth_ui, service_id);    
+    }
+    */
+}
+
+MMythUiCommon *
+create_esg_grid_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;        
+    /* FIXME
+    GtkWidget *esg_grid_view = GTK_WIDGET (esg_grid_view_new (mmyth_ui));
+    
+    
+    ui_common = mmyth_uicommon_new (esg_grid_view,
+                                    "View", "Remind",
+                                    "Close");    
+    */
+    
+    /* Button signals */
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_esg_grid_view_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_close_button), mmyth_ui);
+    
+    return ui_common;
+}
+
+/******************************************************************************
+ *                         GST VIDEO WIDGET METHODS                           *
+ *****************************************************************************/
+
+static void
+cb_video_close_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    /* FIXME
+    mmyth_player_stop (mmyth_ui);
+    */
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+}
+
+MMythUiCommon *
+create_video_view (MMythUi * mmyth_ui)
+{
+
+    MMythUiCommon *ui_common;
+
+    /* FIXME
+    mmyth_player_init (mmyth_ui);
+    */
+
+    ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
+                                    "  Full\nScreen", "Other\nServices",
+                                    "Close");
+
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);    
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_video_close_button), mmyth_ui);
+
+    return ui_common;
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_ui.c.r2535
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_ui.c.r2535	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,567 @@
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gst/interfaces/xoverlay.h>
+
+#include "mmyth_ui.h"
+#include "mmyth_uicommon.h"
+#include "mmyth_uischedulerecording.h"
+#include "mmyth_uirecord.h"
+/* FIXME
+#include "mmyth_videoplayer.h"
+#include "mmyth_esg_grid_view.h"
+#include "mmyth_common.h"
+*/
+
+static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
+
+MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
+MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
+MMythUiCommon *create_esg_grid_view (MMythUi * mmyth_ui);
+MMythUiCommon *create_record_view (MMythUi * mmyth_ui);
+MMythUiCommon *create_schedule_view (MMythUi * mmyth_ui);
+static void cb_video_close_button (GtkButton * button, gpointer user_data);
+static void cb_record_button (GtkButton * button, gpointer user_data);
+
+/* main box from button box separator*/
+static GtkWidget *main_vseparator = NULL;
+
+GdkPixbuf *icon_sports, *icon_news, 
+          *icon_movies, *icon_shows, *icon_default;
+
+/* FIXME: UGLY HACK */
+MMythUi *popup_mmyth_ui;
+
+void
+mmyth_ui_initialize_icons ()
+{
+    GError *error = NULL;
+
+#ifdef MMYTH_DEVEL
+    icon_sports =
+        gdk_pixbuf_new_from_file ("../pixmaps/ico_sports.png", &error);
+#else
+    icon_sports = gdk_pixbuf_new_from_file (PIX_DIR "ico_sports.png", &error);
+#endif
+
+    if (error) {
+        g_warning ("Could not load icon sports: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_news = gdk_pixbuf_new_from_file ("../pixmaps/ico_news.png", &error);
+#else
+    icon_news = gdk_pixbuf_new_from_file (PIX_DIR "ico_news.png", &error);
+#endif
+
+    if (error) {
+        g_warning ("Could not load icon news: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_movies =
+        gdk_pixbuf_new_from_file ("../pixmaps/ico_movies.png", &error);
+#else
+    icon_movies = gdk_pixbuf_new_from_file (PIX_DIR "ico_movies.png", &error);
+#endif
+    if (error) {
+        g_warning ("Could not load icon movies: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_shows = gdk_pixbuf_new_from_file ("../pixmaps/ico_shows.png", &error);
+#else
+    icon_shows = gdk_pixbuf_new_from_file (PIX_DIR "ico_shows.png", &error);
+#endif
+    if (error) {
+        g_warning ("Could not load icon shows: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+#ifdef MMYTH_DEVEL
+    icon_default =
+        gdk_pixbuf_new_from_file ("../pixmaps/ico_default.png", &error);
+#else
+    icon_default = gdk_pixbuf_new_from_file (PIX_DIR "ico_default.png", &error);
+#endif
+
+    if (error) {
+        g_warning ("Could not load icon default: %s\n", error->message);
+        g_error_free (error);
+        error = NULL;
+    }
+
+}
+
+MMythUi *
+mmyth_ui_initialize (GtkWidget * main_window)
+{
+    MMythUi *mmyth_ui;
+
+	// FIXME: REMOVE ME
+	//mmyth_settings_load ( );
+    
+    mmyth_ui = g_new0 (MMythUi, 1);
+
+    mmyth_ui->main_window = main_window;    
+
+    /* Horizontal box that divides the view into control and video area */
+    mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
+    gtk_widget_show (mmyth_ui->main_hbox);
+    g_object_ref (mmyth_ui->main_hbox);
+
+    mmyth_ui_initialize_icons ();
+    
+    main_bg_color.red   = 65000;
+    main_bg_color.green = 65000;
+    main_bg_color.blue  = 65000;
+    
+    // Main widget is mmyth_ui->main_hbox
+    mmyth_ui->main_uicommon       = create_main_view (mmyth_ui);
+    mmyth_ui->video_uicommon      = create_video_view (mmyth_ui);
+    mmyth_ui->esg_grid_uicommon   = create_esg_grid_view (mmyth_ui);
+    mmyth_ui->record_uicommon     = create_record_view (mmyth_ui);    
+    mmyth_ui->schedule_uicommon   = create_schedule_view (mmyth_ui);
+    /* Popup menu */
+    /* FIXME: URGENT ugly, ugly hack */
+    popup_mmyth_ui = mmyth_ui;
+    g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
+                      G_CALLBACK (button_press_handler),
+                      G_OBJECT (mmyth_ui->main_hbox));    
+    
+    gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
+                       mmyth_ui->main_hbox);
+
+    /* Add the gst video widget to hbox. It should never be removed. */    
+    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
+    if(mmyth_ui->video_alignment != NULL)
+        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                            mmyth_ui->video_alignment, TRUE, TRUE, 0);    
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+
+    return mmyth_ui;
+}
+
+void
+mmyth_ui_finalize (MMythUi * mmyth_ui)
+{
+    if (mmyth_ui != NULL)
+        g_free (mmyth_ui);
+
+    mmyth_uicommon_unref_all (mmyth_ui->main_uicommon);
+    mmyth_uicommon_unref_all (mmyth_ui->video_uicommon);
+    mmyth_uicommon_unref_all (mmyth_ui->esgcurrent_uicommon);
+}
+
+void
+mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
+{
+    if (mmyth_ui->current_uicommon) {
+        if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
+            gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
+            gtk_widget_hide (mmyth_ui->videow);
+        }
+        else {
+            gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                                  mmyth_ui->current_uicommon->main_widget);
+        }
+
+        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                              mmyth_ui->current_uicommon->event_box);
+        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
+                              main_vseparator);        
+
+    }
+
+    if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
+        //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
+        gtk_widget_show (mmyth_ui->video_alignment);
+        gtk_widget_show (mmyth_ui->videow);
+    }
+    else {
+        /* FIXME: Fst call is NULL when mmyth_player_init fails */
+        if(mmyth_ui->video_alignment != NULL)
+            gtk_widget_hide (mmyth_ui->video_alignment);
+        /* FIXME: Fst call is NULL when mmyth_player_init fails */
+        if(mmyth_ui->videow != NULL)
+            gtk_widget_hide (mmyth_ui->videow);
+
+        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                            new_uicommon->main_widget, TRUE, TRUE, 0);
+    }
+
+    if(main_vseparator == NULL) {
+        /* FIXME: should free this variable*/
+        main_vseparator = gtk_vseparator_new();
+        g_object_ref (main_vseparator);                   
+    }  
+    gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
+                        main_vseparator, FALSE, FALSE, 0);    
+    gtk_widget_show (main_vseparator);
+
+    gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
+                      FALSE, 0);         
+
+    mmyth_ui->current_uicommon = new_uicommon;
+
+}
+
+/* The close callback is the same for all windows*/
+static void
+cb_not_impl_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    GtkWidget *msg_dialog = gtk_message_dialog_new (
+                                           GTK_WINDOW(mmyth_ui->main_window),
+                                           GTK_DIALOG_MODAL |
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_INFO,
+                                           GTK_BUTTONS_OK,
+                                           "Feature not implemented yet");
+    gtk_widget_set_size_request (msg_dialog, 300, 120);
+
+    gtk_dialog_run (GTK_DIALOG (msg_dialog));
+
+    gtk_widget_destroy(GTK_WIDGET(msg_dialog)); 
+}
+
+/******************************************************************************
+ *                        POPUP MENU WIDGET METHODS                           *
+ *****************************************************************************/
+
+void 
+detacher (GtkWidget *attach_widget,GtkMenu *menu) 
+{
+}
+
+void 
+menu_item_settings_cb (GtkMenuItem *menuitem,
+                            gpointer user_data)
+{
+    /* MMythUi *mmyth_ui = (MMythUi *) user_data; */
+
+    /* FIXME
+    MMythUi *mmyth_ui = popup_mmyth_ui;
+    
+    settings_show_dialog (GTK_WINDOW (mmyth_ui->main_window));    
+    */
+}
+
+static void
+do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
+{
+    GtkWidget *popup;
+    int button, event_time;
+    
+    popup = gtk_menu_new ();
+    
+    /* ... add menu items ... */
+    GtkWidget *menu_item = gtk_menu_item_new_with_label("Settings");
+    gtk_menu_append(popup, menu_item);
+    
+    g_signal_connect (G_OBJECT(menu_item), "activate", 
+                      G_CALLBACK (menu_item_settings_cb), NULL);
+    
+    if (event)
+    {
+      button = event->button;
+      event_time = event->time;
+    }
+    else
+    {
+      button = 0;
+      event_time = gtk_get_current_event_time ();
+    }
+    
+    //gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
+    gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
+                  button, event_time);
+    gtk_widget_show_all(popup);
+}
+
+/* Respond to a button-press by posting a menu passed in as widget.
+ *
+ * Note that the "widget" argument is the menu being posted, NOT
+ * the button that was pressed.
+ */
+
+static gint 
+button_press_handler (GtkWidget *widget, GdkEvent *event)
+{
+
+    if (event->type == GDK_BUTTON_PRESS) {
+      GdkEventButton *bevent = (GdkEventButton *) event; 
+          /* Ignore double-clicks and triple-clicks */
+      if (bevent->button == 3)
+        {
+          do_popup_menu (widget, bevent);
+          return TRUE;
+        }
+    }
+
+    /* Tell calling code that we have not handled this event; pass it on. */
+    return FALSE;
+}
+
+
+/******************************************************************************
+ *                          MAIN APP VIEW METHODS                             *
+ *****************************************************************************/
+
+/* The close callback is the same for all windows*/
+static void
+cb_close_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+}
+
+// FIXME
+//static void 
+//cb_record_button (GtkButton * button, gpointer user_data)
+//{
+//    MMythUi *mmyth_ui = (MMythUi *) user_data;
+//
+//    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
+//}
+
+
+MMythUiCommon *
+create_main_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;
+    GtkWidget *main_widget;
+    GtkWidget *image;
+
+    // FIXME: file path
+#ifdef MMYTH_DEV
+    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
+#else
+    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
+#endif
+    
+    main_widget = gtk_event_box_new();
+    
+    gtk_container_add (GTK_CONTAINER (main_widget),
+                       image);
+    
+
+    gtk_widget_show_all (main_widget);
+    g_object_ref (main_widget);
+
+    ui_common = mmyth_uicommon_new (main_widget,
+                                    "Channels", "Current", "Recording");
+
+    /* Button signals */
+    // FIXME
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_record_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_record_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_record_button), mmyth_ui);
+    
+
+    return ui_common;
+
+}
+
+/******************************************************************************
+ *                         ESG GRID VIEW METHODS                              *
+ *****************************************************************************/
+
+static void
+cb_esg_grid_view_button (GtkButton * button, gpointer user_data)
+{
+    /* FIXME 
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+    guint32 service_id = -1;
+
+    // Retrieves the user selected service ID 
+    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
+    
+    if(schedule != NULL) {
+        service_id = schedule->service->number;
+        mmyth_play_channel (mmyth_ui, service_id);    
+    }
+    */
+}
+
+MMythUiCommon *
+create_esg_grid_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;        
+    /* FIXME
+    GtkWidget *esg_grid_view = GTK_WIDGET (esg_grid_view_new (mmyth_ui));
+    
+    
+    ui_common = mmyth_uicommon_new (esg_grid_view,
+                                    "View", "Remind",
+                                    "Close");    
+    */
+    
+    /* Button signals */
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_esg_grid_view_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_close_button), mmyth_ui);
+    
+    return ui_common;
+}
+/******************************************************************************
+ *                         SCHEDULE VIEW METHODS                                *
+ ******************************************************************************/
+ 
+static void
+cb_schedule_button (GtkButton * button, gpointer user_data)
+{
+	    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
+    /* FIXME 
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+    guint32 service_id = -1;
+
+    // Retrieves the user selected service ID 
+    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
+    
+    if(schedule != NULL) {
+        service_id = schedule->service->number;
+        mmyth_play_channel (mmyth_ui, service_id);    
+    }
+    */
+} 
+ 
+MMythUiCommon *
+create_schedule_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;        
+    
+    GtkWidget *schedule_view = GTK_WIDGET (schedule_view_new ());
+        //record_view = gtk_event_box_new();
+
+
+    gtk_widget_show_all (schedule_view);
+    g_object_ref (schedule_view);
+    
+    ui_common = mmyth_uicommon_new (schedule_view,
+                                    "Save", "Clear",
+                                    "Cancel");    
+
+    //ui->
+    
+    /* Button signals */
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_close_button), mmyth_ui);
+    
+    return ui_common;
+}
+/******************************************************************************
+ *                         RECORD VIEW METHODS                                *
+ ******************************************************************************/
+ 
+static void
+cb_record_button (GtkButton * button, gpointer user_data)
+{
+	    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
+    /* FIXME 
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+    guint32 service_id = -1;
+
+    // Retrieves the user selected service ID 
+    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
+    
+    if(schedule != NULL) {
+        service_id = schedule->service->number;
+        mmyth_play_channel (mmyth_ui, service_id);    
+    }
+    */
+} 
+ 
+MMythUiCommon *
+create_record_view (MMythUi * mmyth_ui)
+{
+    MMythUiCommon *ui_common;        
+    
+    GtkWidget *record_view = GTK_WIDGET (record_view_new ());
+        //record_view = gtk_event_box_new();
+    
+
+    
+
+    gtk_widget_show_all (record_view);
+    g_object_ref (record_view);
+    
+    ui_common = mmyth_uicommon_new (record_view,
+                                    "Play (!)", "Schedule",
+                                    "Delete(!)");    
+    
+    //ui->
+    
+    
+    /* Button signals */
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_schedule_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_close_button), mmyth_ui);
+    
+    return ui_common;
+}
+/******************************************************************************
+ *                         GST VIDEO WIDGET METHODS                           *
+ *****************************************************************************/
+
+static void
+cb_video_close_button (GtkButton * button, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    /* FIXME
+    mmyth_player_stop (mmyth_ui);
+    */
+
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
+}
+
+MMythUiCommon *
+create_video_view (MMythUi * mmyth_ui)
+{
+
+    MMythUiCommon *ui_common;
+
+    /* FIXME
+    mmyth_player_init (mmyth_ui);
+    */
+
+    ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
+                                    "  Full\nScreen", "Other\nServices",
+                                    "Close");
+
+    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
+    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
+                      G_CALLBACK (cb_not_impl_button), mmyth_ui);    
+    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
+                      G_CALLBACK (cb_video_close_button), mmyth_ui);
+
+    return ui_common;
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_ui.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_ui.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,75 @@
+#ifndef MMYTH_UI_H_
+#define MMYTH_UI_H_
+
+#include <gtk/gtk.h>
+#include <gst/gst.h>
+
+#include "config.h"
+
+#ifdef MAEMO_PLATFORM
+#include "hildon-widgets/hildon-program.h"
+#include "hildon-widgets/hildon-window.h"
+#endif
+
+#include "mmyth_uicommon.h"
+#include "mmyth_recordui.h"
+#include "mmyth_schedulerui.h"
+
+/* GMyth library includes */
+#include "gmyth_tvplayer.h"
+
+typedef struct _MMythUi
+{
+
+    /* The main application window */
+    GtkWidget *main_window;
+    MMythUiCommon *current_uicommon;
+
+    /* Main widget components */
+    GtkWidget *main_hbox;
+    GtkWidget *video_alignment;
+    GdkPixbuf *logo;
+
+    /* Main widgets grouping */
+    MMythUiCommon *main_uicommon;
+    MMythUiCommon *video_uicommon;
+    MMythUiCommon *epg_grid_uicommon;
+    MMythUiCommon *record_uicommon;
+    MMythUiCommon *schedule_uicommon;
+    
+    GtkWidget *videow;
+    int idle_id;
+    //GstTagList *tagcache;
+    
+    MMythRecordUI *mmyth_recordui;
+    MMythSchedulerUI *mmyth_schedulerui;
+
+#ifdef MAEMO_PLATFORM
+    HildonProgram *program;
+    GtkMenu *main_menu;
+    GtkWidget *menu_setup;
+#endif
+
+    GMythTVPlayer *tvplayer;
+    
+} MMythUi;
+
+GdkPixbuf *icon_sports, *icon_news, *icon_movies, *icon_shows;
+GdkColor main_bg_color;
+
+void mmyth_set_main_widget (MMythUi * mmyth_ui, MMythUiCommon * new_ui);
+//void mmyth_play_selected(GtkButton * button, gpointer user_data);
+
+#ifdef MAEMO_PLATFORM
+MMythUi *mmyth_ui_initialize (HildonProgram *program, GtkWidget * main_window);
+#else
+MMythUi *mmyth_ui_initialize (GtkWidget * main_window);
+#endif
+
+void mmyth_ui_finalize (MMythUi * mmyth_ui);
+
+void mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon);
+
+GtkWidget* mmyth_ui_get_video_widget (MMythUi *mmyth_ui);
+
+#endif /* MMYTH_UI_H_ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_uicommon.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_uicommon.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,134 @@
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+
+#include "mmyth_uicommon.h"
+#include "mmyth_ui.h"
+
+static void
+refresh_time_on_screen (GtkWidget *label)
+{
+	time_t real_time;
+  	struct tm sched_time;
+	GString *time_showed;
+
+	time_showed = g_string_new("");
+	time(&real_time);
+
+    if (localtime_r((time_t *)&real_time, &sched_time) == NULL) {
+        g_error ("localtime_r error in mmyth_epg_grid_view!\n");
+        return NULL;
+    }
+
+	g_string_printf(time_showed, "%d:%02d:%02d", 
+		sched_time.tm_hour, 
+		sched_time.tm_min, 
+		sched_time.tm_sec);
+
+	gtk_label_set_text (GTK_LABEL(label), time_showed->str);
+}
+
+MMythUiCommon *
+mmyth_uicommon_new (GtkWidget * main_widget, const gchar * label1,
+                    const gchar * label2, const gchar * label3)
+{
+
+    MMythUiCommon *ui_common = g_new0 (MMythUiCommon, 1); 
+    
+    if (!main_widget) {
+    	g_warning ("MMythUICommon created with a NULL main widget\n");
+    }
+    
+    ui_common->main_widget = main_widget;
+
+    ui_common->event_box = gtk_event_box_new();
+    
+    /* Vertical box that divides the control area into two (buttons + clock) */
+    ui_common->vbox = gtk_vbox_new (FALSE, 0);  /* spacing */
+    gtk_container_set_border_width(GTK_CONTAINER (ui_common->vbox), 4);
+    
+    gtk_container_add (GTK_CONTAINER (ui_common->event_box),
+                       ui_common->vbox);
+    gtk_widget_modify_bg(ui_common->event_box, GTK_STATE_NORMAL, &main_bg_color);  
+    
+    /* Vertical box that divides the control area into four */
+    ui_common->button_vbox = gtk_vbox_new (TRUE, 0);    /* spacing */
+
+    gtk_container_set_border_width (GTK_CONTAINER (ui_common->button_vbox), 0);
+
+    /* The button 1 */
+    ui_common->button1 = gtk_button_new_with_label (label1);
+    gtk_widget_modify_bg(ui_common->button1, GTK_STATE_NORMAL, &main_bg_color);  
+    gtk_widget_set_size_request (ui_common->button1, BUTTON_WIDTH,
+                                 BUTTON_HEIGHT);
+
+    /* The button 2 */
+    ui_common->button2 = gtk_button_new_with_label (label2);
+    gtk_widget_modify_bg(ui_common->button2, GTK_STATE_NORMAL, &main_bg_color);  
+    gtk_widget_set_size_request (ui_common->button2, BUTTON_WIDTH,
+                                 BUTTON_HEIGHT);
+
+    /* The button 3 */
+    ui_common->button3 = gtk_button_new_with_label (label3);
+    gtk_widget_modify_bg(ui_common->button3, GTK_STATE_NORMAL, &main_bg_color);  
+    gtk_widget_set_size_request (ui_common->button3, BUTTON_WIDTH,
+                                 BUTTON_HEIGHT);
+
+    /* The clock label */
+    ui_common->label = gtk_label_new ("Starting...");
+    gtk_widget_show (ui_common->label);
+    ui_common->source_id = g_timeout_add(500, (GSourceFunc) refresh_time_on_screen, ui_common->label);
+
+    /* Packing components */
+    gtk_box_pack_start (GTK_BOX (ui_common->vbox),
+                        ui_common->button_vbox, TRUE, TRUE, 0);
+
+    gtk_box_pack_start (GTK_BOX (ui_common->vbox),
+                        ui_common->label, FALSE, FALSE, 0);
+
+    gtk_box_pack_start (GTK_BOX (ui_common->button_vbox),
+                        ui_common->button1, FALSE, FALSE, 0);
+
+    gtk_box_pack_start (GTK_BOX (ui_common->button_vbox),
+                        ui_common->button2, FALSE, FALSE, 0);
+
+    gtk_box_pack_start (GTK_BOX (ui_common->button_vbox),
+                        ui_common->button3, FALSE, FALSE, 0);
+
+    gtk_widget_show_all (ui_common->event_box);
+
+    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
+    if(ui_common->main_widget != NULL)
+        g_object_ref (ui_common->main_widget);
+        
+    g_object_ref (ui_common->vbox);
+    g_object_ref (ui_common->button_vbox);
+    g_object_ref (ui_common->label);
+    g_object_ref (ui_common->button1);
+    g_object_ref (ui_common->button2);
+    g_object_ref (ui_common->button3);
+    g_object_ref (ui_common->event_box);
+    return ui_common;
+}
+
+void
+mmyth_uicommon_free (MMythUiCommon *ui_common)
+{
+	g_debug ("[%s] Clean uicommon used memory", __FUNCTION__);
+
+    g_source_remove (ui_common->source_id);
+    	
+    g_object_unref (ui_common->main_widget);
+    g_object_unref (ui_common->vbox);
+    g_object_unref (ui_common->button_vbox);
+    g_object_unref (ui_common->label);
+    g_object_unref (ui_common->button1);
+    g_object_unref (ui_common->button2);
+    g_object_unref (ui_common->button3);
+    g_object_unref (ui_common->event_box);    
+    
+    g_free (ui_common);
+}
+
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_uicommon.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_uicommon.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,51 @@
+#ifndef MMYTH_UICOMMON_H_
+#define MMYTH_UICOMMON_H_
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#ifndef MAEMO_PLATFORM
+#define BUTTON_HEIGHT        50
+#define BUTTON_WIDTH        100
+#else
+#define BUTTON_HEIGHT       80
+#define BUTTON_WIDTH        150
+#endif
+
+#define MAIN_WINDOW_WIDTH	550
+#define MAIN_WINDOW_HEIGHT	250
+
+#define CHANNELS_DIALOG_WIDTH	300
+#define CHANNELS_DIALOG_HEIGHT	200
+
+#define SETTINGS_DIALOG_WIDTH	300
+#define SETTINGS_DIALOG_HEIGHT	120
+
+extern GdkColor main_bg_color;
+
+typedef struct _MMythUiCommon
+{
+    GtkWidget *main_widget;
+
+    /* event box to set the background color*/
+    GtkWidget *event_box;
+    
+    GtkWidget *vbox;
+    GtkWidget *button_vbox;
+    GtkWidget *label;
+
+    GtkWidget *button1;
+    GtkWidget *button2;
+    GtkWidget *button3;
+    
+    gint source_id;
+} MMythUiCommon;
+
+MMythUiCommon *mmyth_uicommon_new (GtkWidget * main_widget,
+                                   const gchar * label1, const gchar * label2,
+                                   const gchar * label3);
+void mmyth_uicommon_free (MMythUiCommon *ui_common);
+
+#endif /* MMYTH_UICOMMON_H_ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_uisettings.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_uisettings.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,169 @@
+#include<gtk/gtk.h>
+#include<glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mmyth_uisettings.h"
+
+#include "gmyth_context.h"
+
+static GtkWidget *settings_dialog;
+static GtkWidget *entry_hostname;
+static GtkWidget *entry_dbname;
+static GtkWidget *entry_username;
+static GtkWidget *entry_passwd;
+static GtkWidget *entry_port;
+
+static void settings_dialog_update_data (void);
+static GtkWidget* add_entry_to_table (GtkWidget *table, GString *init_str,
+	guint pos_left, guint pos_right, guint pos_top, guint pos_bottom);
+static GtkWidget* add_label_to_table (GtkWidget *table, const gchar *str, 
+	guint pos_left, guint pos_right,  guint pos_top, guint pos_bottom);
+	
+	
+gboolean
+mmyth_uisettings_run (GtkWindow *main_window)
+{
+
+	GtkWidget *settings_table;
+	GtkWidget *label_hostname, *label_dbname;
+	GtkWidget *label_username, *label_passwd, *label_port;
+
+	GMythSettings *msettings = gmyth_context_get_settings();
+	
+	settings_dialog = gtk_dialog_new_with_buttons ("Settings",
+                                         main_window,
+                                         GTK_DIALOG_DESTROY_WITH_PARENT,
+                                         GTK_STOCK_OK,
+                                         GTK_RESPONSE_ACCEPT,
+                                         GTK_STOCK_CANCEL,
+                                         GTK_RESPONSE_REJECT,
+                                         NULL);
+                                         
+  gtk_widget_set_size_request (settings_dialog, 400, 244);
+
+/*  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_show (scrolledwindow1);
+  gtk_container_add (GTK_CONTAINER (window1), scrolledwindow1);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
+
+  viewport1 = gtk_viewport_new (NULL, NULL);
+  gtk_widget_show (viewport1);
+  gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);
+  gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport1), GTK_SHADOW_NONE);
+*/
+
+	// Creates the table and attach it to the settings dialog
+	settings_table = gtk_table_new (5, 2, FALSE);
+	gtk_widget_show (settings_table);
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG(settings_dialog)->vbox), settings_table, FALSE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (settings_table), 3);
+	gtk_table_set_row_spacings (GTK_TABLE (settings_table), 5);
+	gtk_table_set_col_spacings (GTK_TABLE (settings_table), 10);
+
+	label_hostname = add_label_to_table (settings_table, "Host Name:", 0, 1, 0, 1);
+	label_dbname   = add_label_to_table (settings_table, "Database Name:", 0, 1, 1, 2);
+	label_username = add_label_to_table (settings_table, "Username:", 0, 1, 2, 3);
+	label_passwd = add_label_to_table (settings_table, "Password:", 0, 1, 3, 4);
+	label_port = add_label_to_table (settings_table, "Server port:", 0, 1, 4, 5);
+	
+	entry_hostname = add_entry_to_table (settings_table,
+		gmyth_settings_get_backend_hostname (msettings),
+		1, 2, 0, 1);
+	entry_dbname = add_entry_to_table (settings_table,
+		gmyth_settings_get_dbname (msettings),
+		1, 2, 1, 2 );
+	entry_username = add_entry_to_table (settings_table,
+		gmyth_settings_get_username (msettings),
+		1, 2, 2, 3 );
+	entry_passwd = add_entry_to_table (settings_table,
+		gmyth_settings_get_password (msettings),
+		1, 2, 3, 4 );
+		
+	GString *str_port = g_string_new ("");
+	g_string_printf (str_port, "%d", 
+		gmyth_settings_get_backend_port (msettings));
+	entry_port = add_entry_to_table (settings_table, str_port,
+		1, 2, 4, 5 );
+	g_string_free (str_port, TRUE);
+		
+	if (gtk_dialog_run (GTK_DIALOG (settings_dialog)) == GTK_RESPONSE_ACCEPT) {
+		settings_dialog_update_data ();
+		gtk_widget_destroy (settings_dialog);
+		return TRUE;
+	}
+	
+	gtk_widget_destroy (settings_dialog);
+	
+	return FALSE;
+	
+}
+
+static GtkWidget*
+add_label_to_table (GtkWidget *table, const gchar *str, guint pos_left, guint pos_right, 
+		guint pos_top, guint pos_bottom )
+{
+	GtkWidget *tmp_label = gtk_label_new (str);
+	
+	gtk_widget_show (tmp_label);
+	gtk_table_attach (GTK_TABLE (table), tmp_label, 
+					pos_left, pos_right, pos_top, pos_bottom,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (tmp_label), 0, 0.5);
+	
+	return tmp_label;
+}
+
+static GtkWidget*
+add_entry_to_table (GtkWidget *table, GString *init_str, guint pos_left, guint pos_right,
+		guint pos_top, guint pos_bottom)
+{
+	GtkWidget *tmp_entry = gtk_entry_new ();
+	gtk_widget_show (tmp_entry);
+	gtk_table_attach (GTK_TABLE (table), tmp_entry, 
+					pos_left, pos_right, pos_top, pos_bottom,
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+    if (init_str)
+		gtk_entry_set_text (GTK_ENTRY (tmp_entry), (init_str->str));
+		
+	//gtk_entry_set_invisible_char (GTK_ENTRY (entry_port), 9679);
+	
+	return tmp_entry;
+}
+
+static void
+settings_dialog_update_data (void) 
+{
+	GString *tmp_entry_text;
+	GMythSettings *msettings = gmyth_context_get_settings();
+	
+	if (!msettings) {
+		g_warning ("[%s] Could not get GMythSettings instance from context\n", __FUNCTION__);
+		return;
+	}
+		
+	tmp_entry_text = g_string_new("");
+	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_hostname)));
+	gmyth_settings_set_backend_hostname(msettings, tmp_entry_text);
+	
+	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_dbname)));
+	gmyth_settings_set_dbname(msettings, tmp_entry_text);
+	
+	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_username)));
+	gmyth_settings_set_username(msettings, tmp_entry_text);
+	
+	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_passwd)));
+	gmyth_settings_set_password(msettings, tmp_entry_text);	
+	
+	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_port)));
+	gmyth_settings_set_backend_port(msettings, atoi(tmp_entry_text->str));
+	
+	gmyth_settings_save (msettings);
+	
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_uisettings.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_uisettings.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,6 @@
+#ifndef MMYTH_SETTINGS_H_
+#define MMYTH_SETTINGS_H_
+
+gboolean mmyth_uisettings_run (GtkWindow *main_window);
+
+#endif /*MMYTH_SETTINGS_H_*/
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_videoplayer.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_videoplayer.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,369 @@
+
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gst/interfaces/xoverlay.h>
+#include <unistd.h>
+
+#include "mmyth_ui.h"
+#include "mmyth_videoplayer.h"
+#include "mmyth_sdpreader.h"
+
+#include "esg_database.h"
+
+#include "ipd_demux.h"
+#include "ipd_network.h"
+
+#ifdef INDT_IP_DECAPSULATOR
+#include <sys/types.h>
+#include <signal.h>
+#endif
+
+/* Global flag/semaphore to control IP decapsulator threads */
+gboolean state_keep_running = 0;
+
+
+typedef struct _GstPlayerWindowStateChange
+{
+    GstElement *play;
+    GstState old_state, new_state;
+    MMythUi *mmyth_ui;
+} GstPlayerWindowStateChange;
+
+typedef struct _GstPlayerWindowTagFound
+{
+    GstElement *play;
+    GstTagList *taglist;
+    MMythUi *mmyth_ui;
+} GstPlayerWindowTagFound;
+
+
+GstElement *gst_pipeline, *gst_decoder, *gst_videosink;
+
+static gboolean idle_state (gpointer data);
+
+static gboolean
+bus_call (GstBus * bus, GstMessage * msg, gpointer data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) data;
+    GMainLoop *loop = mmyth_ui->loop;
+
+    switch (GST_MESSAGE_TYPE (msg)) {
+        case GST_MESSAGE_EOS:
+
+            if (mmyth_ui->idle_id != 0) {
+                g_source_remove (mmyth_ui->idle_id);
+                mmyth_ui->idle_id = 0;
+            }
+
+            //g_idle_add ((GSourceFunc) idle_eos, data);
+            gst_element_set_state (GST_ELEMENT (GST_MESSAGE_SRC (msg)),
+                                   GST_STATE_READY);
+            break;
+        case GST_MESSAGE_ERROR:{
+                gchar *debug;
+                GError *err;
+
+                gst_message_parse_error (msg, &err, &debug);
+                g_free (debug);
+
+                printf ("Error: %s\n", err->message);
+                g_error_free (err);
+
+                g_main_loop_quit (loop);
+            }
+            break;
+        case GST_MESSAGE_STATE_CHANGED:{
+                GstState oldstate;
+                GstState newstate;
+                GstState pending;
+                GstPlayerWindowStateChange *st =
+                    g_new (GstPlayerWindowStateChange, 1);
+
+                gst_message_parse_state_changed (msg,
+                                                 &oldstate,
+                                                 &newstate, &pending);
+
+                st->play = mmyth_ui->play;
+                gst_object_ref (GST_OBJECT (mmyth_ui->play));
+                st->old_state = oldstate;
+                st->new_state = newstate;
+
+                st->mmyth_ui = mmyth_ui;
+
+                /* State debug messages */
+                printf ("oldstate = %s, newstate = %s, pendingstate = %s\n",
+                        gst_element_state_get_name (oldstate),
+                        gst_element_state_get_name (newstate),
+                        gst_element_state_get_name (pending));
+
+                g_idle_add ((GSourceFunc) idle_state, st);
+
+            }
+            break;
+        default:
+            printf (gst_message_type_get_name (GST_MESSAGE_TYPE (msg)));
+            printf ("\n");
+            break;
+    }
+
+    return TRUE;
+}
+
+
+static gboolean
+cb_iterate (gpointer data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) data;
+    //gboolean res;
+
+    g_main_loop_run (mmyth_ui->loop);
+/*
+	if (!GST_FLAG_IS_SET (mmyth_ui->play, GST_BIN_SELF_SCHEDULABLE)) {
+    	res = gst_bin_iterate (GST_BIN (mmyth_ui->play));
+	} else {
+    	g_usleep (100);
+		res = (gst_element_get_state (mmyth_ui->play) == GST_STATE_PLAYING);
+	}
+
+	if (!res)
+    	mmyth_ui->idle_id = 0;
+    	
+    return res;
+*/
+    return FALSE;
+
+}
+
+static gboolean
+idle_state (gpointer data)
+{
+    GstPlayerWindowStateChange *st = data;
+
+    if (st->old_state == GST_STATE_PLAYING) {
+        if (st->mmyth_ui->idle_id != 0) {
+            g_source_remove (st->mmyth_ui->idle_id);
+            st->mmyth_ui->idle_id = 0;
+        }
+    }
+    else if (st->new_state == GST_STATE_PLAYING) {
+        if (st->mmyth_ui->idle_id != 0)
+            g_source_remove (st->mmyth_ui->idle_id);
+
+        st->mmyth_ui->idle_id = g_idle_add (cb_iterate, st->mmyth_ui);
+    }
+
+    /* new movie loaded? */
+    if (st->old_state == GST_STATE_READY && st->new_state > GST_STATE_READY) {
+
+        /* gboolean have_video = FALSE; */
+
+        gtk_widget_show (st->mmyth_ui->videow);
+
+        gtk_window_resize (GTK_WINDOW (st->mmyth_ui->main_window), 1, 1);
+
+    }
+
+    /* discarded movie? */
+    if (st->old_state > GST_STATE_READY && st->new_state == GST_STATE_READY) {
+
+        if (st->mmyth_ui->tagcache) {
+            gst_tag_list_free (st->mmyth_ui->tagcache);
+            st->mmyth_ui->tagcache = NULL;
+        }
+    }
+
+    gst_object_unref (GST_OBJECT (st->play));
+    //g_object_unref (G_OBJECT (st->win));
+    g_free (st);
+
+    /* once */
+    return FALSE;
+}
+
+
+
+static gboolean
+expose (GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) user_data;
+
+    gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (mmyth_ui->videosink),
+                                  GDK_WINDOW_XWINDOW (mmyth_ui->videow->
+                                                      window));
+    return TRUE;
+}
+
+
+void
+mmyth_player_init (MMythUi * mmyth_ui)
+{
+    GstElement *play;
+    GstElement *source, *parser, *decoder, *videosink;
+
+    play = gst_pipeline_new ("video-player");
+    source = gst_element_factory_make ("udpsrc", "file-source");
+    parser = gst_element_factory_make ("rtph263pdepay", "rtp-demux");
+    decoder = gst_element_factory_make ("ffdec_h263", "mpeg-decoder");
+    videosink = gst_element_factory_make ("xvimagesink", "image-output");
+    gst_pipeline = play;
+    gst_decoder = decoder;
+    gst_videosink = videosink;
+
+    if (!(gst_pipeline && source && parser && decoder && videosink)) {
+        /* FIXME: hanlde the error correctly */
+        /* video_alignment is not being created (below) 
+           and is causing problems to the ui */
+        g_print ("GstElement creation error!\n");
+        return;
+    }
+
+    g_object_set (G_OBJECT (videosink), "sync", FALSE, NULL);
+
+    gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (gst_pipeline)),
+                       bus_call, mmyth_ui);
+
+    gst_bin_add_many (GST_BIN (gst_pipeline), source, parser, decoder,
+                      videosink, NULL);
+
+    {
+        GstCaps *rtpcaps = gst_caps_new_simple ("application/x-rtp", NULL);
+        gst_element_link_filtered(source, parser, rtpcaps);
+    }
+    
+    gst_element_link_many (/*source,*/ parser, decoder, videosink, NULL);
+
+    /* actual window */
+    mmyth_ui->play = play;
+    mmyth_ui->videosink = videosink;
+    mmyth_ui->udpsource = source;
+
+    g_object_ref (mmyth_ui->play);
+    g_object_ref (mmyth_ui->videosink);
+
+    /* video widget */
+    //mmyth_ui->videow = gst_player_video_new (videosink, play);
+    mmyth_ui->videow = gtk_drawing_area_new ();
+    gtk_widget_set_size_request (mmyth_ui->videow, 300, 240);
+
+    mmyth_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
+
+
+    mmyth_ui->video_alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
+    gtk_widget_hide (mmyth_ui->video_alignment);
+
+    gtk_container_add (GTK_CONTAINER (mmyth_ui->video_alignment),
+                       mmyth_ui->videow);
+
+    g_signal_connect (mmyth_ui->videow, "expose-event", G_CALLBACK (expose),
+                      mmyth_ui);
+    //g_signal_connect(mmyth_ui->videow, "size_request", G_CALLBACK(cb_preferred_video_size), mmyth_ui);
+
+
+    g_object_ref (mmyth_ui->videow);
+    g_object_ref (mmyth_ui->video_alignment);
+
+    //gnome_app_set_contents (app, videow);
+    //gtk_widget_show (mmyth_ui->videow);
+
+//fail:
+//  gst_object_unref (GST_OBJECT (play));
+//  return NULL;  
+
+}
+
+void
+mmyth_player_stop (MMythUi * mmyth_ui)
+{
+    gst_element_set_state (mmyth_ui->play, GST_STATE_NULL);
+
+    if(mmyth_ui->videow != NULL)
+        gtk_widget_hide (mmyth_ui->videow);
+
+    /* Disable IP Decapsulator playing threads */
+    state_keep_running = FALSE;	
+
+}
+
+static gboolean
+idle_play (gpointer data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) data;
+
+    sleep (2);
+
+    gst_element_set_state (mmyth_ui->play, GST_STATE_PLAYING);
+
+    return FALSE;
+}
+
+
+/* Run IP decapsulator play function in a new thread. The thread is finished setting the
+ * semaphore "state_keep_running" to FALSE*/
+gpointer
+run_ipd(gpointer data)
+{
+    GString *ip_addr = (GString*) data;
+
+	state_keep_running = TRUE;
+
+	printf("Inside thread\n");
+
+	ipd_mpe_play_section (ip_addr->str, &state_keep_running);
+
+	return 0;
+}
+
+void
+mmyth_play_channel (MMythUi * mmyth_ui, gint service_number)
+{
+	ESGDatabase *esg_db;
+    DVBHService *service;
+	SDPData sdp_data;
+	GString *service_ip_addr;
+	
+	/* First verifies if there is a tuned network */
+	if ( !ipd_network_is_tuned() ) {
+		/* FIXME: show alert and handle this error */
+        g_warning ("Play not possible, network not tuned");
+		return;
+	}
+
+    esg_db = esg_database_get_instance();
+    /* Gets the service structure */
+    service = (DVBHService *) esg_database_get_service_from_number
+                                 (esg_db, service_number);
+
+	/* Verifies if sdp fragment exists to this service */
+	if ( service->sdp_file == NULL ) {
+		/* FIXME: Implement error handling */
+        g_warning ("SDP fragment not available to access service");
+		return;
+    }
+	
+	/* Parses the sdp to get ipv6 address and port */
+	mmyth_sdp_parse_file (service->sdp_file->str, &sdp_data);
+
+    /* Sets the gstreamer properties acording to the service access address */
+	/* FIXME: Develop sdp_bin in gstreamer to give sdp file as pipeline config */
+    g_object_set (G_OBJECT (mmyth_ui->udpsource), "multicast_group",
+                  sdp_data.ip_addr->str, NULL);
+    g_object_set (G_OBJECT (mmyth_ui->udpsource), "port", sdp_data.video_port, NULL);
+
+    /* Shows the video widget on screen */
+    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);
+
+    gtk_widget_show (mmyth_ui->videow);
+    gtk_widget_queue_draw (mmyth_ui->videow);
+
+#ifdef INDT_IP_DECAPSULATOR
+    /* Will be dealocated in run_ipd */	
+	service_ip_addr = g_string_new (sdp_data.ip_addr->str);
+	
+	/* Requests the IP decapsulator to play the channel stream*/
+	g_thread_create (run_ipd, (gpointer) service_ip_addr, FALSE, NULL);
+#endif
+		
+    //gst_element_set_state (mmyth_ui->play, GST_STATE_PLAYING);
+    g_idle_add (idle_play, mmyth_ui);
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/gui/mmyth_videoplayer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/gui/mmyth_videoplayer.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,12 @@
+#ifndef MMYTH_VIDEOPLAYER_H_
+#define MMYTH_VIDEOPLAYER_H_
+
+#include "mmyth_ui.h"
+
+void mmyth_player_init (MMythUi * mmyth_ui);
+void mmyth_player_stop (MMythUi * mmyth_ui);
+
+void mmyth_play_channel (MMythUi * mmyth_ui, gint service_id);
+
+
+#endif /* MMYTH_VIDEOPLAYER_H_ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,59 @@
+SUBDIRS = .
+
+lib_LTLIBRARIES = libgmyth.la
+
+libgmyth_la_SOURCES = 			\
+	gmyth_common.c				\
+	gmyth_context.c				\
+	gmyth_epg.c 				\
+	gmyth_remote_encoder.c		\
+	gmyth_remote_util.c			\
+	gmyth_settings.c			\
+	gmyth_tvchain.c				\
+	gmyth_tvplayer.c			\
+	gmyth_scheduler.c 			\
+	gmyth_util.c				\
+	gmyth_query.c				\
+	gmyth_socket.c				\
+	gmyth_stringlist.c				
+
+libgmyth_la_CFLAGS = 			\
+	-DDATADIR=\"$(pkgdatadir)\" \
+	$(GLIB_CFLAGS) 				\
+	$(GTK_CFLAGS) 				\
+	$(GOBJECT_CFLAGS)			\
+	$(GST_CFLAGS) 				\
+	$(GSTBASE_CFLAGS)			\
+	$(MYSQL_CFLAGS)				\
+	-g3 -O0
+
+#libgmyth_la_LIBADD =			\
+#	$(MYSQL_LIBS)
+
+libgmyth_la_LDFLAGS = 			\
+	-export-dynamic 			\
+	-lgstinterfaces-0.10 		\
+	$(MYSQL_LIBS) 				\
+	$(GST_LIBS) 				\
+	$(GSTBASE_LIBS)
+
+libgmyth_includedir = 			\
+	$(pkgincludedir)
+
+libgmyth_include_HEADERS =    	\
+	gmyth_common.h	 			\
+	gmyth_context.h 			\
+	gmyth_epg.h 				\
+	gmyth_remote_encoder.h 		\
+	gmyth_scheduler.h 			\
+	gmyth_settings.h 			\
+	gmyth_tvchain.h 			\
+	gmyth_tvplayer.h 			\
+	gmyth_util.h 				\
+	gmyth_query.h 				\
+	gmyth_socket.h 				\
+	gmyth_remote_util.h			\
+	gmyth_stringlist.h 				
+
+CLEANFILES = $(BUILT_SOURCES)
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_common.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_common.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,85 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_common.c
+ * 
+ * @brief <p> This file contains basic common functions for the gmyth library.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "gmyth_common.h"
+
+static void free_channel_data(gpointer data, gpointer user_data);
+static void free_program_data(gpointer data, gpointer user_data);
+
+/** Frees the memory allocated to the GMythChannelInfo objects inside list.
+ * The list memory is also released by g_list_free(). If LIST is NULL it
+ * simply returns.
+ * 
+ * @param list the GList containing a list of GMythChannelInfo to free.
+ */
+void 
+gmyth_free_channel_list(GList *list) 
+{
+	if (list == NULL) {
+		g_warning ("%s received null GList as parameter", __FUNCTION__);
+		return;
+	}
+	
+	g_list_foreach (list, free_channel_data, NULL);
+	
+	g_list_free (list);
+}
+
+/** Frees the memory allocated to the GMythProgramInfo objects inside list.
+ * The list memory is also released by g_list_free(). If list is NULL it
+ * simply returns.
+ * 
+ * @param list the GList containing a list of GMythProgramInfo to free.
+ */
+void
+gmyth_free_program_list(GList *list)
+{
+	if (list == NULL) {
+		g_warning ("%s received null GList as parameter", __FUNCTION__);
+		return;
+	}
+	
+	g_list_foreach (list, free_program_data, NULL);
+	
+	g_list_free (list);
+}
+
+
+static void 
+free_channel_data(gpointer data, gpointer user_data)
+{
+    if(data)
+        g_free((GMythChannelInfo*) data);
+}
+
+static void
+free_program_data(gpointer data, gpointer user_data)
+{
+    if(data)
+        g_free((GMythProgramInfo*) data);
+}
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_common.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_common.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,155 @@
+/**
+ * GMyth Library
+ * 
+ * @file gmyth/gmyth_common.h
+ * 
+ * @brief <p> This file contains basic common functions for the gmyth library.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef GMYTH_COMMON_H_
+#define GMYTH_COMMON_H_
+
+#include <glib.h>
+#include <time.h>
+
+/**
+ * The GMythChannelInfo structure represents the channel information
+ * stored in the backend database.
+ */
+typedef struct {
+	/** The channel ID in backend database */
+	int channel_ID;
+	
+	/** The channel name in backend database */
+	GString *channel_name;
+
+} GMythChannelInfo;
+
+
+/**
+ * The GMythProgramInfo structure represents a program information
+ * stored in the database. It could be a program from the EPG data,
+ * a program scheduled to be recorded, or a program already recorded.
+ */
+typedef struct {
+	
+	/** The channel unique ID. */
+    GString *chanid;
+    
+    /** The program start time. */
+    time_t startts;
+    /** The program end time. */
+    time_t endts;
+    /** The recording schedule start time. */
+    time_t recstartts;
+    /** The recording schedule end time */
+    time_t recendts;
+    
+    /** The program title. */
+    GString *title;
+    /** The program subtitle. */
+    GString *subtitle;
+    /** The program description. */
+    GString *description;
+    /** The program category. */
+    GString *category;
+    
+    GString *chanstr;
+    GString *chansign;
+    /** The associated channel name. */
+    GString *channame;
+    int chancommfree;
+    GString *chanOutputFilters;
+    
+    GString *seriesid;
+    /** The program unique id. */
+    GString *programid;
+    GString * catType;
+
+    GString * sortTitle;  
+
+	/** A flag informing if the program has video or not. */    
+    gboolean isVideo;
+    int lenMins;
+    
+    GString *year;    
+    double stars;
+    int repeat;
+    
+    time_t originalAirDate;
+    time_t lastmodified;
+    time_t lastInUseTime;
+    
+    gboolean hasAirDate;
+
+    int spread;
+    int startCol;
+
+//    enum RecStatusType recstatus;
+//    enum RecStatusType oldrecstatus;
+//    enum RecStatusType savedrecstatus;
+    int recpriority2;
+    int reactivate;    
+
+    int recordid;
+    int parentid;   
+    //enum RecordingType rectype;
+    //enum RecordingDupInType dupin;
+    //enum RecordingDupMethodType dupmethod;
+    
+    /** The backend video source id associated to this program.*/
+    int sourceid;
+    /** the backend input id associated to this program.*/
+    int inputid;
+    /** The backend card id associated to this program.*/
+    int cardid;
+    gboolean shareable;
+    gboolean duplicate;
+  
+    GString * schedulerid;
+    int findid;
+
+    int programflags;
+    int transcoder;
+
+    //proginfo->spread = -1;
+    //proginfo->programflags = proginfo->getProgramFlags();
+
+    GString *recgroup;
+    GString *playgroup;
+    int recpriority;
+
+	/** The file size of the recorded program.*/
+    long long filesize;
+    /** The file name of the recorded program.*/
+    GString *pathname;
+    GString *hostname;
+        
+    /* AvailableStatusType availableStatus;*/
+ 
+} GMythProgramInfo;
+
+
+void gmyth_free_channel_list(GList *list);
+void gmyth_free_program_list(GList *list);
+
+#endif /* GMYTH_COMMON_H_ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_context.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_context.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,312 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_context.c
+ * 
+ * @brief <p> GMythContext class contains general attributes and functions
+ * that express the connection state of each mythtvfrontend.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "gmyth_context.h"
+
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "gmyth_query.h"
+#include "gmyth_socket.h"
+
+static void gmyth_context_class_init          (GMythContextClass *klass);
+static void gmyth_context_init                (GMythContext *object);
+
+static void gmyth_context_dispose  (GObject *object);
+static void gmyth_context_finalize (GObject *object);
+
+
+G_DEFINE_TYPE(GMythContext, gmyth_context, G_TYPE_OBJECT)
+
+static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+static GMythContext *gcontext = NULL; 
+
+static void
+gmyth_context_class_init (GMythContextClass *klass)
+{
+	GObjectClass *gobject_class;
+
+	gobject_class = (GObjectClass *) klass;
+
+	gobject_class->dispose  = gmyth_context_dispose;
+	gobject_class->finalize = gmyth_context_finalize;	
+}
+
+static void
+gmyth_context_init (GMythContext *gmyth_context)
+{
+
+}
+
+static void
+gmyth_context_dispose  (GObject *object)
+{
+	GMythContext *gmyth_context = GMYTH_CONTEXT(object);
+
+	if ( gmyth_context->gmyth_settings != NULL ) {
+		g_object_unref (gmyth_context->gmyth_settings);	
+		gmyth_context->gmyth_settings = NULL;
+	}
+
+	if ( gmyth_context->localhostname != NULL ) {
+		g_string_free ( gmyth_context->localhostname, TRUE );
+		gmyth_context->localhostname = NULL;
+	}
+
+	if (gmyth_context->server_socket != NULL) {
+		g_object_unref (gmyth_context->server_socket);
+		gmyth_context->server_socket = NULL;
+	}
+
+	G_OBJECT_CLASS (gmyth_context_parent_class)->dispose (object);
+}
+
+static void
+gmyth_context_finalize (GObject *object)
+{
+	g_signal_handlers_destroy (object);
+
+	G_OBJECT_CLASS (gmyth_context_parent_class)->finalize (object);
+}
+
+/** Gets the some important address translation info, 
+ * from the client socket that will open a connection.
+ *
+ * @return gint error number
+ */
+static gint
+myth_context_toaddrinfo( gchar *addr, gint port, struct addrinfo **addrInfo )
+{
+	struct addrinfo hints;
+	gchar *portStr = g_strnfill( 32, ' ' );
+	gint errorn = EADDRNOTAVAIL;
+
+	memset( &hints, 0, sizeof(hints) );
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = SOCK_STREAM;
+
+	/* hints.ai_flags = AI_NUMERICHOST; */
+	if ( port != -1 )
+		sprintf(portStr, "%d", port);
+	else
+		portStr = NULL;
+
+	g_debug( "[%s] Address: %s, port: %s\n", __FUNCTION__, addr, portStr );
+	if ( ( errorn = getaddrinfo(addr, portStr, &hints, addrInfo) ) != 0 ) {
+		g_printerr( "[%s] Socket ERROR: %s\n", __FUNCTION__, gai_strerror(errorn) );
+	}
+
+	return errorn;
+
+}
+
+/** Initializes the GMythContext object. It reads local system information
+ * load gmyth user settings and start connection to the database.
+ * 
+ * @return TRUE if initialization was successfull, 
+ * FALSE if any error happens.
+ */
+gboolean
+gmyth_context_initialize ()
+{
+	GString *localhost = NULL;
+
+	if (gcontext == NULL) {
+		gcontext = GMYTH_CONTEXT ( g_object_new (GMYTH_CONTEXT_TYPE, FALSE));
+	}
+
+	localhost = gmyth_socket_get_local_hostname( );
+
+	if (localhost==NULL || localhost->len <=0 ) {
+		g_warning ("[%s] Could not determine local hostname. Setting to 127.0.0.1", __FUNCTION__);
+		gcontext->localhostname = g_string_new ("127.0.0.1");
+	} else {
+		gcontext->localhostname = localhost;
+	}
+
+	if (gcontext->gmyth_settings) {
+		g_object_unref (gcontext->gmyth_settings);	
+		gcontext->gmyth_settings = NULL;
+	}
+
+	gcontext->gmyth_settings = gmyth_settings_new ();
+	if (!gmyth_settings_load (gcontext->gmyth_settings)) {
+		g_warning ("GMythContext: Settings file not opened!\n");	
+	} else {
+		g_debug ("GMythContext: Settings file loaded");
+	}
+
+	if (gcontext->server_socket != NULL) {
+		g_object_unref (gcontext->server_socket);
+		gcontext->server_socket = NULL;
+	}
+
+	GString *server_hostname = 
+        gmyth_settings_get_backend_hostname(gcontext->gmyth_settings);
+	int server_port = gmyth_settings_get_backend_port(gcontext->gmyth_settings);
+
+	gcontext->server_socket = gmyth_socket_new ();
+	if (!gmyth_socket_connect_to_backend (gcontext->server_socket,
+				server_hostname->str, server_port, FALSE)) {
+		g_warning ("[%s] Socket connection to backend error!", __FUNCTION__);
+		g_object_unref (gcontext->server_socket);
+		gcontext->server_socket = NULL;
+		return FALSE;	
+	}
+
+	return TRUE;
+}
+
+/** Formats a Mythtv protocol command based on strlist and sends it to
+ * the connected backend. The backend response is overwritten into strlist.
+ * 
+ * @param strlist the string list to be sent, 
+ * and on which the answer will be written.
+ * @return TRUE if command was sent and an answer was received, FALSE if any
+ * error happens.
+ */
+gboolean
+gmyth_context_send_receive_stringlist (GMythStringList *strlist)
+{
+	gint ok = -1;
+
+	if (!gcontext || !(gcontext->server_socket)) {
+		g_warning ("[%s] GMythContext not initialized", __FUNCTION__);
+		return FALSE;
+	}
+
+	//g_static_mutex_lock( &mutex );
+
+	ok = gmyth_socket_sendreceive_stringlist (gcontext->server_socket, strlist);
+
+	//g_static_mutex_unlock( &mutex );
+
+	if (!ok) {
+		g_warning ("Connection to backend server lost");
+	}
+
+	return (ok ? TRUE : FALSE);
+}
+
+/** Gets the GMythSettings object associated to this context.
+ * 
+ * @return The GMythSettings object currently valid or NULL if the settings
+ * were not opened.
+ */
+GMythSettings*
+gmyth_context_get_settings ()
+{
+	if (!gcontext) {
+		g_warning ("[%s] GMythContext not initialized\n", __FUNCTION__);
+		return NULL;
+	}
+
+	return gcontext->gmyth_settings;
+}
+
+/** Gets the machine local hostname.
+ * 
+ * @param hostname a valid GString object to be overwritten with the local
+ * hostname.
+ * @return true if the hostname was read, false if any error happened.
+ */
+gboolean
+gmyth_context_get_local_hostname (GString *hostname)
+{
+	if (!hostname) {
+		g_warning ("[%s] Received null argument", __FUNCTION__);
+		return FALSE;
+	}
+
+	g_string_assign (hostname, gcontext->localhostname->str);
+
+	return TRUE;
+}
+
+/** Gets a setting information from the backend mysql database.
+ * 
+ * @param key The setting key to be retrieved.
+ * @param host the hostname associated to the desired setting.
+ * @param default_value the default setting value if could not query from
+ * backend database.
+ * @return The setting value loaded from database, or the given default value
+ * if the query fails.
+ */
+GString*
+gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value)
+{
+	GString *query_str;
+
+	// TODO: Reuse msql query in gmyth_context
+	GMythQuery *gmyth_query = gmyth_query_new ();
+
+	if (gmyth_query_connect (gmyth_query)) {
+		MYSQL_RES *msql_res;
+		MYSQL_ROW msql_row;
+
+		query_str = g_string_new ("");
+		g_string_printf (query_str, "SELECT data FROM settings WHERE value = \"%s\" "
+				"AND hostname = \"%s\" ;", key->str, host->str);
+
+		msql_res = gmyth_query_process_statement (gmyth_query, query_str->str);
+		if (msql_res) {
+			msql_row = mysql_fetch_row (msql_res);
+			if (msql_row != NULL) {
+				return g_string_new (msql_row[0]);
+			}
+		}
+
+		g_object_unref (gmyth_query);
+	} else {
+		g_warning ("Database not open while trying to load setting: %s", key->str);
+	}
+
+
+	return default_value;
+}
+
+/** Verify if the context is currently connected to a backend.
+ * 
+ * @return true if connection was opened, false if not.
+ */
+gboolean
+gmyth_context_check_connection ()
+{
+	// FIXME: Check this based on socket states
+	if (!gcontext) {
+		g_warning ("[%s] GMythContext not initialized", __FUNCTION__);
+		return FALSE;
+	}
+
+	return (gcontext->server_socket != NULL);
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_context.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_context.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,88 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_context.h
+ * 
+ * @brief <p> GMythContext class contains general attributes and functions
+ * that express the connection state of each mythtvfrontend.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __GMYTH_CONTEXT_H__
+#define __GMYTH_CONTEXT_H__
+
+#include <glib-object.h>
+
+#include "gmyth_settings.h"
+#include "gmyth_socket.h"
+#include "gmyth_stringlist.h"
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_CONTEXT_TYPE               (gmyth_context_get_type ())
+#define GMYTH_CONTEXT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_CONTEXT_TYPE, GMythContext))
+#define GMYTH_CONTEXT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_CONTEXT_TYPE, GMythContextClass))
+#define IS_GMYTH_CONTEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_CONTEXT_TYPE))
+#define IS_GMYTH_CONTEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_CONTEXT_TYPE))
+#define GMYTH_CONTEXT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_CONTEXT_TYPE, GMythContextClass))
+
+#define MYTHTV_VERSION_DEFAULT          30
+
+typedef struct _GMythContext         GMythContext;
+typedef struct _GMythContextClass    GMythContextClass;
+
+struct _GMythContextClass
+{
+  GObjectClass parent_class;
+
+  /* callbacks */
+  /* no one for now */
+};
+
+struct _GMythContext
+{
+    GObject parent;
+
+	GMythSettings *gmyth_settings;
+	GMythSocket *server_socket;  
+	
+	GString *localhostname;
+};
+
+
+GType           gmyth_context_get_type (void);
+void            gmyth_context_create();
+
+gboolean gmyth_context_initialize ();
+gboolean gmyth_context_check_connection ();
+GMythSettings* gmyth_context_get_settings ();
+
+gboolean gmyth_context_send_receive_stringlist (GMythStringList *strlist);
+
+GString* gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value);
+gboolean gmyth_context_get_local_hostname (GString *hostname);
+
+GString* gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value);
+
+
+#define G_END_DECLS
+
+#endif /* __GMYTH_CONTEXT_H__ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_epg.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_epg.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,278 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_epg.c
+ * 
+ * @brief <p> GMythEPG class provides access to the program and channel data
+ * from the Electronic Program Guide (EPG) of the Mythtv backend.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <mysql.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "gmyth_epg.h"
+#include "gmyth_util.h"
+
+static void gmyth_epg_class_init          (GMythEPGClass *klass);
+static void gmyth_epg_init                (GMythEPG *object);
+
+static void gmyth_epg_dispose  (GObject *object);
+static void gmyth_epg_finalize (GObject *object);
+
+G_DEFINE_TYPE(GMythEPG, gmyth_epg, G_TYPE_OBJECT)
+    
+static void
+gmyth_epg_class_init (GMythEPGClass *klass)
+{
+	GObjectClass *gobject_class;
+
+    gobject_class = (GObjectClass *) klass;
+	
+    gobject_class->dispose  = gmyth_epg_dispose;
+    gobject_class->finalize = gmyth_epg_finalize;	
+}
+
+static void
+gmyth_epg_init (GMythEPG *gmyth_epg)
+{
+	gmyth_epg->sqlquery = gmyth_query_new ();
+}
+
+static void
+gmyth_epg_dispose  (GObject *object)
+{
+    //GMythEPG *gmyth_epg = GMYTH_EPG(object);
+    
+	G_OBJECT_CLASS (gmyth_epg_parent_class)->dispose (object);
+}
+
+static void
+gmyth_epg_finalize (GObject *object)
+{
+	g_signal_handlers_destroy (object);
+
+    G_OBJECT_CLASS (gmyth_epg_parent_class)->finalize (object);
+}
+
+/**
+ * Creates a new instance of GMythEPG.
+ * 
+ * @return a new instance of GMythEPG.
+ */
+GMythEPG*
+gmyth_epg_new ()
+{
+    GMythEPG *epg = GMYTH_EPG (g_object_new(GMYTH_EPG_TYPE, NULL));
+
+    return epg;
+}
+
+/** Connects to the Mysql database in the backend. The backend address
+ * is loaded from the GMythSettings instance.
+ * 
+ * @param gmyth_epg the GMythEPG instance to be connected.
+ * @return true if connection was success, false if failed.
+ */
+gboolean
+gmyth_epg_connect (GMythEPG *gmyth_epg)
+{
+	assert(gmyth_epg);
+
+	if (gmyth_epg->sqlquery	== NULL) {
+		g_warning ("[%s] GMythEPG not initialized", __FUNCTION__);
+		return FALSE;
+	}
+
+    if (!gmyth_query_connect(gmyth_epg->sqlquery)) {
+        g_warning ("[%s] Error while connecting to db", __FUNCTION__);
+        return FALSE;
+    }
+
+    return TRUE;	
+}
+
+/** Disconnects from the Mysql database in the backend.
+ * 
+ * @param gmyth_epg the GMythEPG instance to be disconnected
+ * @return true if disconnection was success, false if failed.
+ */
+gboolean
+gmyth_epg_disconnect (GMythEPG *gmyth_epg)
+{
+	assert(gmyth_epg);
+
+	if (gmyth_epg->sqlquery	!= NULL) {	
+		g_object_unref (gmyth_epg->sqlquery);
+	}
+	
+	return TRUE;
+}
+
+/** Retrieves the available list of channels from the backend Mysql database.
+ * 
+ * @param gmyth_epg the GMythEPG instance.
+ * @param glist_ptr the GList pointer to be filled with the loaded list address.
+ * @return The amount of channels retrieved from database,  or -1 if error.
+ */
+gint
+gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr)
+{
+	MYSQL_RES *msql_res;
+
+    assert(gmyth_epg);
+
+    msql_res = gmyth_query_process_statement (gmyth_epg->sqlquery, 
+    		"SELECT chanid,name FROM channel;");
+
+	(*glist_ptr) = NULL;
+	
+    if (msql_res == NULL) {
+        g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
+		return -1;
+    } else {
+        MYSQL_ROW row;
+		GMythChannelInfo *channel_info;        
+
+        while ((row = mysql_fetch_row (msql_res)) != NULL){
+
+        	channel_info = g_new0(GMythChannelInfo, 1);
+            channel_info->channel_ID = atoi (row[0]);
+            channel_info->channel_name = g_string_new (row[1]);
+        
+            (*glist_ptr) = g_list_append ((*glist_ptr), channel_info);
+    	}
+    }
+    mysql_free_result (msql_res);
+    return (!(*glist_ptr)) ?  0 : g_list_length (*glist_ptr);
+}
+
+/** 
+ * Retrieves the available list of channels from the backend Mysql database.
+ * 
+ * @param gmyth_epg the GMythEPG instance.
+ * @param proglist the GList pointer to be filled with the loaded list.
+ * @param chan_num the channel num on which to search for program.
+ * @param starttime the start time to search for programs.
+ * @param endtime the end time to search for programs.
+ * @return The amount of channels retrieved from database, or -1 if error.
+ */
+gint
+gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
+		const gint chan_num, time_t starttime, time_t endtime)
+{
+    GString *startts = gmyth_util_time_to_string(starttime);
+    GString *endts = gmyth_util_time_to_string(endtime);
+    MYSQL_ROW row;
+    GString *querystr;
+    
+    assert(gmyth_epg);
+    
+    querystr = g_string_new(
+        "SELECT DISTINCT program.chanid, program.starttime, program.endtime, "
+        "    program.title, program.subtitle, program.description, "
+        "    program.category, channel.channum, channel.callsign, "
+        "    channel.name, program.previouslyshown, channel.commfree, "
+        "    channel.outputfilters, program.seriesid, program.programid, "
+        "    program.airdate, program.stars, program.originalairdate, "
+        "    program.category_type, oldrecstatus.recordid, "
+        "    oldrecstatus.rectype, oldrecstatus.recstatus, "
+        "    oldrecstatus.findid "
+        "FROM program "
+        "LEFT JOIN channel ON program.chanid = channel.chanid "
+        "LEFT JOIN oldrecorded AS oldrecstatus ON "
+        "    program.title = oldrecstatus.title AND "
+        "    channel.callsign = oldrecstatus.station AND "
+        "    program.starttime = oldrecstatus.starttime "
+        );
+        
+    g_string_append_printf (querystr, 
+        "WHERE program.chanid = %d "
+        "  AND program.endtime >= '%s' "
+        "  AND program.starttime <= '%s' "
+        "  AND program.manualid = 0 ",
+        chan_num, startts->str, endts->str);
+
+    if (!g_strrstr(querystr->str, " GROUP BY "))
+        querystr = g_string_append(querystr,
+            " GROUP BY program.starttime, channel.channum, "
+            "  channel.callsign, program.title ");
+
+    if (!g_strrstr(querystr->str, " LIMIT "))
+        querystr = g_string_append(querystr, " LIMIT 1000 ");
+
+    MYSQL_RES *res_set = 
+        gmyth_query_process_statement(gmyth_epg->sqlquery, querystr->str);
+
+    if (res_set == NULL) {
+        g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
+		return -1;
+    }
+
+    (*proglist) = NULL;        
+    while ((row = mysql_fetch_row (res_set)) != NULL) {
+
+        GMythProgramInfo *p = g_new0 (GMythProgramInfo, 1);
+        p->chanid = g_string_new (row[0]);
+
+        p->startts = gmyth_util_string_to_time (g_string_new (row[1]));
+        p->endts = gmyth_util_string_to_time (g_string_new (row[2]));
+                                                     
+        p->recstartts = p->startts;
+        p->recendts = p->endts;
+        p->lastmodified = p->startts;
+    
+        p->title = g_string_new (row[3]);
+        p->subtitle = g_string_new (row[4]);
+        p->description = g_string_new (row[5]);
+        p->category = g_string_new (row[6]);
+        p->chanstr = g_string_new (row[7]);
+        p->chansign = g_string_new (row[8]);
+        p->channame = g_string_new (row[9]);
+        p->repeat = atoi(row[10]);
+        p->chancommfree = atoi(row[11]);
+        p->chanOutputFilters = g_string_new (row[12]);
+        p->seriesid = g_string_new (row[13]);
+        p->programid = g_string_new (row[14]);
+        p->year = g_string_new (row[15]);
+        p->stars = atof(row[16]);
+
+        if (!row[17] || !strcmp(row[17], "")) {
+            p->originalAirDate = 0;
+            p->hasAirDate = FALSE;
+        } else {
+            p->originalAirDate = gmyth_util_string_to_time (g_string_new (row[17]));
+            p->hasAirDate = TRUE;
+        }
+        
+        p->catType = g_string_new (row[18]);
+
+        *proglist = g_list_append((*proglist), p);
+    }
+
+    /* deallocate */
+    mysql_free_result (res_set);
+    g_string_free(querystr, TRUE);
+
+    return TRUE;
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_epg.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_epg.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,75 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_epg.h
+ * 
+ * @brief <p> GMythEPG class provides access to the program and channel data
+ * from the Electronic Program Guide (EPG) of the Mythtv backend.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef GMYTH_EPG_H_
+#define GMYTH_EPG_H_
+
+#include <glib-object.h>
+
+#include "gmyth_query.h"
+#include "gmyth_common.h"
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_EPG_TYPE               (gmyth_epg_get_type ())
+#define GMYTH_EPG(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE, GMythEPG))
+#define GMYTH_EPG_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE, GMythEPGClass))
+#define IS_GMYTH_EPG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE))
+#define IS_GMYTH_EPG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE))
+#define GMYTH_EPG_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_EPG_TYPE, GMythEPGClass))
+
+typedef struct _GMythEPG         GMythEPG;
+typedef struct _GMythEPGClass    GMythEPGClass;
+
+struct _GMythEPGClass
+{
+  GObjectClass parent_class;
+
+  /* callbacks */
+  /* no one for now */
+};
+
+struct _GMythEPG
+{
+    GObject parent;
+
+	GMythQuery *sqlquery;
+};
+
+GType          gmyth_epg_get_type (void);
+
+GMythEPG* gmyth_epg_new ();
+
+gboolean gmyth_epg_connect (GMythEPG *gmyth_epg);
+gboolean gmyth_epg_disconnect (GMythEPG *gmyth_epg);
+
+gint gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr);
+gint gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
+		const gint chanNum, time_t  starttime, time_t  endtime);
+
+#endif /*GMYTH_EPG_H_*/
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_query.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_query.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,221 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_query.c
+ * 
+ * @brief <p> GMythQuery class provides a wrapper for accessing
+ * the libmysqlclient funtions.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "gmyth_query.h"
+#include "gmyth_settings.h"
+#include "gmyth_context.h"
+
+static void gmyth_query_class_init          (GMythQueryClass *klass);
+static void gmyth_query_init                (GMythQuery *object);
+
+static void gmyth_query_dispose  (GObject *object);
+static void gmyth_query_finalize (GObject *object);
+
+static void gmyth_query_print_error (MYSQL *conn, char *message);
+
+G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT)
+    
+static void
+gmyth_query_class_init (GMythQueryClass *klass)
+{
+	GObjectClass *gobject_class;
+
+    gobject_class = (GObjectClass *) klass;
+	
+    gobject_class->dispose  = gmyth_query_dispose;
+    gobject_class->finalize = gmyth_query_finalize;	
+}
+
+static void
+gmyth_query_init (GMythQuery *gmyth_query)
+{
+	GMythSettings *gmyth_settings = gmyth_context_get_settings ();
+	
+    gmyth_query->opt_host_name = gmyth_settings_get_backend_hostname(gmyth_settings);
+    gmyth_query->opt_user_name = gmyth_settings_get_username(gmyth_settings);
+    gmyth_query->opt_password = gmyth_settings_get_password(gmyth_settings);
+    gmyth_query->opt_db_name = gmyth_settings_get_dbname(gmyth_settings);
+
+    /* initialize connection handler */
+    gmyth_query->conn = mysql_init (NULL);
+    
+    if (!(gmyth_query->conn))
+    	g_warning ("[%s] MSQL structure not initialized", __FUNCTION__);
+
+}
+
+static void
+gmyth_query_dispose  (GObject *object)
+{
+    GMythQuery *gmyth_query = GMYTH_QUERY (object);
+    
+    /* disconnect from server */
+	gmyth_query_disconnect (gmyth_query);
+	
+	G_OBJECT_CLASS (gmyth_query_parent_class)->dispose (object);
+}
+
+static void
+gmyth_query_finalize (GObject *object)
+{
+	g_signal_handlers_destroy (object);
+
+    G_OBJECT_CLASS (gmyth_query_parent_class)->finalize (object);
+}
+
+/** Creates a new instance of GMythQuery.
+ * 
+ * @return a new instance of GMythQuery.
+ */
+GMythQuery*
+gmyth_query_new ()
+{
+    GMythQuery *sql_query = GMYTH_QUERY (g_object_new(GMYTH_QUERY_TYPE, NULL));
+
+    return sql_query;
+}
+
+/** Connects to the Mysql database in the backend. The backend address
+ * is loaded from the GMythSettings instance.
+ * 
+ * @param gmyth_query the GMythEPG instance to be connected.
+ * @return true if connection was success, false if failed.
+ */
+gboolean
+gmyth_query_connect (GMythQuery *gmyth_query) 
+{
+    char *opt_host_name;
+    char *opt_user_name;
+    char *opt_password;
+    char *opt_db_name;
+
+    assert(gmyth_query);
+    
+    opt_host_name   = (gmyth_query->opt_host_name ? gmyth_query->opt_host_name->str : NULL);
+    opt_db_name     = (gmyth_query->opt_db_name ? gmyth_query->opt_db_name->str : NULL);
+    opt_user_name   = (gmyth_query->opt_user_name ? gmyth_query->opt_user_name->str : NULL);
+    opt_password    = (gmyth_query->opt_password ? gmyth_query->opt_password->str : NULL);
+
+    
+    if (gmyth_query->conn == NULL) {
+        gmyth_query_print_error (NULL, "mysql_init() failed (probably out of memory)");
+        return FALSE;
+    }
+    
+    /* connect to server */
+    if (mysql_real_connect (gmyth_query->conn, opt_host_name, 
+            opt_user_name, opt_password, opt_db_name, 
+            0, NULL, 0) == NULL) {
+            	
+        gmyth_query_print_error (gmyth_query->conn, "mysql_real_connect() failed");
+		return FALSE;
+    }
+
+    g_debug ("[%s] Connection to Mysql server succeeded!", __FUNCTION__);
+    
+    return TRUE;
+}
+
+/** Disconnects from the Mysql database in the backend.
+ * 
+ * @param gmyth_query the GMythQuery instance to be disconnected
+ * @return true if disconnection was success, false if failed.
+ */
+gboolean
+gmyth_query_disconnect (GMythQuery *gmyth_query) 
+{
+    assert(gmyth_query);
+    
+    /* TODO: Check how to return error */
+    g_debug ("[%s] Closing gmyth_query->conn", __FUNCTION__);
+    mysql_close (gmyth_query->conn);
+
+	return TRUE;	
+}
+
+static void
+gmyth_query_print_error (MYSQL *conn, char *message)
+{
+    fprintf (stderr, "%s\n", message);
+    
+    if (conn != NULL) {
+#if MYSQL_VERSION_ID >= 40101
+        fprintf (stderr, "Error %u (%s): %s\n",
+                mysql_errno (conn), mysql_sqlstate(conn), mysql_error (conn));
+#else
+        fprintf (stderr, "Error %u: %s\n",
+               mysql_errno (conn), mysql_error (conn));
+#endif
+    }
+}
+
+/** Sends the given query to the backend returning the query result as
+ * MYSQL_RES pointer.
+ * 
+ * FIXME: this function is returning NULL whether any error happens
+ * or no rows are returned (e.g. UPDATE or REPLACE).
+ * 
+ * @param gmyth_query the GMythQuery instance.
+ * @param stmt_str the query text.
+ * @return the MYSQL_RES result pointer or NULL if any error happens.
+ */
+MYSQL_RES*
+gmyth_query_process_statement (GMythQuery *gmyth_query, char *stmt_str)
+{
+    MYSQL_RES *res_set;
+    
+    assert(gmyth_query);
+    
+    g_debug ("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
+
+    if (gmyth_query == NULL)
+    	return NULL;
+    
+    /* the statement failed */
+    if (mysql_query (gmyth_query->conn, stmt_str) != 0) {
+        gmyth_query_print_error (gmyth_query->conn, "Could not execute statement");
+        return NULL;
+    }
+
+    /* the statement succeeded; determine whether it returned data */
+    res_set = mysql_store_result (gmyth_query->conn);
+    if (res_set) {
+        return res_set;
+    } else if (mysql_field_count (gmyth_query->conn) == 0) {
+             g_debug ("%lu rows affected\n",
+                     (unsigned long) mysql_affected_rows (gmyth_query->conn));
+    } else {
+            gmyth_query_print_error (gmyth_query->conn, "Could not retrieve result set");
+    }
+    
+    return NULL;
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_query.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_query.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,84 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_query.h
+ * 
+ * @brief <p> GMythQuery class provides a wrapper for accessing
+ * the libmysqlclient funtions.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __GMYTH_QUERY_H__
+#define __GMYTH_QUERY_H__
+
+#include <glib-object.h>
+
+/* MYSQL includes */
+#include <mysql.h>
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_QUERY_TYPE               (gmyth_query_get_type ())
+#define GMYTH_QUERY(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE, GMythQuery))
+#define GMYTH_QUERY_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE, GMythQueryClass))
+#define IS_GMYTH_QUERY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE))
+#define IS_GMYTH_QUERY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE))
+#define GMYTH_QUERY_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_QUERY_TYPE, GMythQueryClass))
+
+
+typedef struct _GMythQuery         GMythQuery;
+typedef struct _GMythQueryClass    GMythQueryClass;
+
+struct _GMythQueryClass
+{
+  GObjectClass parent_class;
+
+  /* callbacks */
+  /* no one for now */
+};
+
+struct _GMythQuery
+{
+    GObject parent;
+  
+    GString *opt_host_name; /* server host (default=localhost) */
+    GString *opt_user_name; /* username (default=login name) */
+    GString *opt_password; /* password (default=none) */
+    unsigned int opt_port_num; /* port number (use built-in value) */
+    GString *opt_socket_name; /* socket name (use built-in value) */
+    GString *opt_db_name; /* database name (default=none) */
+    unsigned int opt_flags; /* connection flags (none) */
+    MYSQL *conn; /* pointer to connection handler */  
+};
+
+
+GType gmyth_query_get_type (void);
+
+GMythQuery* gmyth_query_new ();
+MYSQL_RES * gmyth_query_process_statement 
+                (GMythQuery *gmyth_query, char *stmt_str);
+
+gboolean gmyth_query_connect (GMythQuery *gmyth_query);
+gboolean gmyth_query_disconnect (GMythQuery *gmyth_query);
+
+#define G_END_DECLS
+
+#endif /* __GMYTH_QUERY_H__ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_remote_encoder.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_remote_encoder.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,207 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_remote_encoder.c
+ * 
+ * @brief <p> GMythRemoteEncoder class defines functions for playing live tv.
+ *
+ * The remote encoder is used by gmyth_tvplayer to setup livetv. 
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "gmyth_remote_encoder.h"
+
+#include <assert.h>
+
+#include "gmyth_stringlist.h"
+
+static void gmyth_remote_encoder_class_init          (GMythRemoteEncoderClass *klass);
+static void gmyth_remote_encoder_init                (GMythRemoteEncoder *object);
+
+static void gmyth_remote_encoder_dispose  (GObject *object);
+static void gmyth_remote_encoder_finalize (GObject *object);
+
+G_DEFINE_TYPE(GMythRemoteEncoder, gmyth_remote_encoder, G_TYPE_OBJECT)
+    
+static void
+gmyth_remote_encoder_class_init (GMythRemoteEncoderClass *klass)
+{
+    GObjectClass *gobject_class;
+
+    gobject_class = (GObjectClass *) klass;
+	
+    gobject_class->dispose  = gmyth_remote_encoder_dispose;
+    gobject_class->finalize = gmyth_remote_encoder_finalize;	
+}
+
+static void
+gmyth_remote_encoder_init (GMythRemoteEncoder *gmyth_remote_encoder)
+{
+}
+
+static void
+gmyth_remote_encoder_dispose  (GObject *object)
+{
+    // GMythRemoteEncoder *gmyth_remote_encoder = GMYTH_REMOTE_ENCODER(object);
+    
+	G_OBJECT_CLASS (gmyth_remote_encoder_parent_class)->dispose (object);
+}
+
+
+static void
+gmyth_remote_encoder_finalize (GObject *object)
+{
+	g_signal_handlers_destroy (object);
+
+    GMythRemoteEncoder *remote_encoder = GMYTH_REMOTE_ENCODER(object);
+
+	g_debug ("[%s] Closing control socket", __FUNCTION__);
+	gmyth_socket_close_connection(remote_encoder->myth_socket);
+	g_object_unref (remote_encoder->myth_socket);
+    
+    G_OBJECT_CLASS (gmyth_remote_encoder_parent_class)->finalize (object);
+}
+
+/** Creates a new instance of GMythRemoteEncoder.
+ * 
+ * @return a new instance of GMythRemoteEncoder.
+ */
+GMythRemoteEncoder*
+gmyth_remote_encoder_new (int num, GString *hostname, gshort port)
+{
+	GMythRemoteEncoder *encoder = GMYTH_REMOTE_ENCODER ( g_object_new (
+			GMYTH_REMOTE_ENCODER_TYPE, FALSE ));
+			
+	encoder->recorder_num = num;
+	encoder->hostname = g_string_new (hostname->str);
+	encoder->port = port;
+	
+	return encoder;
+}
+
+/** Configures the remote encoder instance connecting it to Mythtv backend.
+ * 
+ * @param remote_encoder the GMythRemoteEncoder instance.
+ * @return TRUE if successfull, FALSE if any error happens.
+ */
+gboolean
+gmyth_remote_encoder_setup (GMythRemoteEncoder *remote_encoder)
+{
+	assert (remote_encoder);
+	g_debug ("[%s] Creating socket and connecting to backend", __FUNCTION__);
+
+	if (remote_encoder->myth_socket == NULL) { 
+		
+		remote_encoder->myth_socket = gmyth_socket_new ();
+		
+		if (!gmyth_socket_connect_to_backend (remote_encoder->myth_socket, remote_encoder->hostname->str, 
+					remote_encoder->port, TRUE) ) {
+			g_warning ("GMythRemoteEncoder: Connection to backend failed");	
+			return FALSE;
+		}
+
+	} else {
+		g_warning("Remote encoder socket already created\n");
+	}
+
+	return TRUE;
+}
+
+/** Sends the SPAWN_LIVETV command through Mythtv protocol. This command
+ * requests the backend to start capturing TV content.
+ * 
+ * @param remote_encoder The GMythRemoteEncoder instance.
+ * @param tvchain_id The tvchain unique id.
+ * @return true if success, false if any error happens.
+ */
+gboolean
+gmyth_remote_encoder_spawntv (GMythRemoteEncoder *remote_encoder, GString *tvchain_id)
+{
+	GMythStringList *str_list;
+	GString *tmp_str;
+	
+	g_debug ("[%s] Spawntv with tvchain_id = %s", __FUNCTION__, tvchain_id->str);
+	
+	str_list = gmyth_string_list_new ();
+	
+	tmp_str = g_string_new ("QUERY_RECORDER ");
+	g_string_append_printf (tmp_str, "%d", remote_encoder->recorder_num); 
+	
+	gmyth_string_list_append_string (str_list, tmp_str);
+	gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
+	gmyth_string_list_append_string (str_list, tvchain_id);
+	gmyth_string_list_append_int (str_list, 0); // PIP = FALSE (0)
+
+	gmyth_socket_sendreceive_stringlist (remote_encoder->myth_socket, str_list);
+	
+    g_string_free (tmp_str, TRUE);
+    
+    tmp_str = gmyth_string_list_get_string (str_list, 0);
+    if (tmp_str == NULL) {
+    	g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
+    	return FALSE;
+	}
+	
+    if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
+    	g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
+	    g_object_unref (str_list);
+    	return FALSE;
+    }
+
+    g_object_unref (str_list);
+    return TRUE;
+
+}
+
+/** Sends the command STOP_LIVETV to Mythtv backend.
+ * 
+ * @param remote_encoder the GMythRemoteEncoder instance.
+ * @return true if success, false if any error happens.
+ */
+gboolean
+gmyth_remote_encoder_stop_livetv (GMythRemoteEncoder *remote_encoder)
+{
+	GMythStringList *str_list;
+	GString *tmp_str;
+
+	g_debug ("[%s]", __FUNCTION__);
+
+	str_list = gmyth_string_list_new ();
+
+	tmp_str = g_string_new ("QUERY_RECORDER ");
+	g_string_append_printf (tmp_str, "%d", remote_encoder->recorder_num); 
+	gmyth_string_list_append_string (str_list, g_string_new ("STOP_LIVETV"));
+
+	gmyth_socket_sendreceive_stringlist (remote_encoder->myth_socket, str_list);
+
+	g_string_free (tmp_str, TRUE);
+
+	tmp_str = gmyth_string_list_get_string (str_list, 0);
+	if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
+		g_warning ("[%s] Stop livetv request returned %s", __FUNCTION__, tmp_str->str);
+		g_object_unref (str_list);
+		return FALSE;
+	}
+
+	g_object_unref (str_list);
+	return TRUE;
+
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_remote_encoder.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_remote_encoder.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,89 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_remote_encoder.h
+ * 
+ * @brief <p> GMythRemoteEncoder class defines functions for playing live tv.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __GMYTH_REMOTE_ENCODER_H__
+#define __GMYTH_REMOTE_ENCODER_H__
+
+#include <glib-object.h>
+
+#include "gmyth_socket.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_REMOTE_ENCODER_TYPE               (gmyth_remote_encoder_get_type ())
+#define GMYTH_REMOTE_ENCODER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoder))
+#define GMYTH_REMOTE_ENCODER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoderClass))
+#define IS_GMYTH_REMOTE_ENCODER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_REMOTE_ENCODER_TYPE))
+#define IS_GMYTH_REMOTE_ENCODER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_REMOTE_ENCODER_TYPE))
+#define GMYTH_REMOTE_ENCODER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoderClass))
+
+
+typedef struct _GMythRemoteEncoder         GMythRemoteEncoder;
+typedef struct _GMythRemoteEncoderClass    GMythRemoteEncoderClass;
+
+struct _GMythRemoteEncoderClass
+{
+  GObjectClass parent_class;
+
+  /* callbacks */
+  /* no one for now */
+};
+
+struct _GMythRemoteEncoder
+{
+    GObject parent;
+
+    /* socket descriptor */
+    GMythSocket *myth_socket;
+    
+    int recorder_num;
+    GString *hostname;
+    int port;
+};
+
+
+GType   gmyth_remote_encoder_get_type   (void);
+
+GMythRemoteEncoder* gmyth_remote_encoder_new    (int num,
+                                                 GString *hostname,
+                                                 gshort port);
+
+gboolean gmyth_remote_encoder_setup     (GMythRemoteEncoder *encoder);
+gboolean gmyth_remote_encoder_spawntv   (GMythRemoteEncoder *remote_encoder,
+                                         GString *tvchain_id);
+gboolean gmyth_remote_encoder_stop_livetv (GMythRemoteEncoder *remote_encoder);
+
+#define G_END_DECLS
+
+#endif /* __GMYTH_REMOTE_ENCODER_H__ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_remote_util.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_remote_util.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,70 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_remote_util.c
+ * 
+ * @brief <p> This component provides utility functions for accessing remote data.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "gmyth_remote_util.h"
+ 
+#include "gmyth_context.h"
+#include "gmyth_remote_encoder.h"
+#include "gmyth_stringlist.h"
+
+/** Requests the Mythtv backend for a free remote recorder.
+ * 
+ * @param curr The recorder index, or -1 to consider the first one.
+ * @return the remote encoder instance available, or NULL if any error happens.
+ */
+GMythRemoteEncoder*
+remote_request_next_free_recorder (int curr)
+{
+	GMythRemoteEncoder *encoder;
+	GString *hostname;
+	int num, port;
+	
+	GMythStringList *strlist = gmyth_string_list_new();
+	
+	g_debug ("[%s] Request next free recorder in the backend", __FUNCTION__);
+	
+    gmyth_string_list_append_char_array (strlist, "GET_NEXT_FREE_RECORDER");
+    gmyth_string_list_append_int (strlist, curr);
+
+    if (!gmyth_context_send_receive_stringlist(strlist)) {
+    	g_warning ("GET_NEXT_FREE_RECORDER request error!\n");
+        return NULL;
+    }
+
+    num = gmyth_string_list_get_int (strlist, 0);
+    hostname = gmyth_string_list_get_string (strlist, 1);
+    port = gmyth_string_list_get_int (strlist, 2);
+
+	g_debug ("[%s] Free recorder info received: num: %d, hostname: %s, port: %d", 
+				__FUNCTION__, num, hostname->str, port);
+	
+	encoder = gmyth_remote_encoder_new (num, hostname, port);
+	
+	g_object_unref (strlist);
+	
+	return encoder;
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_remote_util.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_remote_util.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,35 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_remote_util.h
+ * 
+ * @brief <p> This component provides utility functions for accessing remote data.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __REMOTE_UTIL_H__
+#define __REMOTE_UTIL_H__
+
+#include "gmyth_remote_encoder.h"
+
+GMythRemoteEncoder* remote_request_next_free_recorder (int curr);
+
+#endif
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_scheduler.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_scheduler.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,610 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_scheduler.c
+ * 
+ * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
+ * and modifying the recorded content.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+
+#include "gmyth_scheduler.h"
+
+#include "gmyth_context.h"
+#include "gmyth_util.h"
+#include "gmyth_query.h"
+
+static void gmyth_scheduler_class_init          (GMythSchedulerClass *klass);
+static void gmyth_scheduler_init                (GMythScheduler *object);
+
+static void gmyth_scheduler_dispose  (GObject *object);
+static void gmyth_scheduler_finalize (GObject *object);
+
+static gint get_record_id_from_database (GMythScheduler *scheduler);
+static void update_backend (gint record_id);
+
+G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
+    
+static void
+gmyth_scheduler_class_init (GMythSchedulerClass *klass)
+{
+	GObjectClass *gobject_class;
+
+    gobject_class = (GObjectClass *) klass;
+
+    gobject_class->dispose  = gmyth_scheduler_dispose;
+    gobject_class->finalize = gmyth_scheduler_finalize;	
+}
+
+static void
+gmyth_scheduler_init (GMythScheduler *sched)
+{
+	sched->recordid =0;
+    sched->type = 0;
+    sched->search = 0;
+    sched->profile =  g_string_new("");
+    
+    sched->dupin = 0;
+    sched->dupmethod = 0;
+    sched->autoexpire = 0;
+    sched->autotranscode = 0;
+    sched->transcoder = 0;
+
+    sched->autocommflag = 0;
+    sched->autouserjob1 = 0;
+    sched->autouserjob2 = 0;
+    sched->autouserjob3 = 0;
+    sched->autouserjob4 = 0;
+    
+    sched->startoffset = 0;
+    sched->endoffset = 0;
+    sched->maxepisodes = 0;
+    sched->maxnewest = 0;
+
+    sched->recpriority = 0;
+    sched->recgroup = 0;
+    sched->playgroup = 0;
+    
+    sched->prefinput = 0;
+    sched->inactive = 0;
+    
+    sched->searchType = g_string_new("");
+    sched->searchForWhat = g_string_new("");
+    
+    sched->msqlquery = gmyth_query_new ();
+}
+
+static void
+gmyth_scheduler_dispose  (GObject *object)
+{
+	G_OBJECT_CLASS (gmyth_scheduler_parent_class)->dispose (object);
+}
+
+static void
+gmyth_scheduler_finalize (GObject *object)
+{
+	g_signal_handlers_destroy (object);
+
+    G_OBJECT_CLASS (gmyth_scheduler_parent_class)->finalize (object);
+}
+
+/** Creates a new instance of GMythScheduler.
+ * 
+ * @return a new instance of GMythScheduler.
+ */
+GMythScheduler*
+gmyth_scheduler_new ()
+{
+    GMythScheduler *scheduler = 
+        GMYTH_SCHEDULER (g_object_new(GMYTH_SCHEDULER_TYPE, NULL));
+    
+    return scheduler;
+}
+
+/** Connects to the Mysql database in the backend. The backend address
+ * is loaded from the GMythSettings instance.
+ * 
+ * @param scheduler the GMythScheduler instance to be connected.
+ * @return true if connection was success, false if failed.
+ */
+gboolean
+gmyth_scheduler_connect (GMythScheduler *scheduler)
+{
+    assert(scheduler);
+
+    if (scheduler->msqlquery == NULL) {
+        g_warning ("[%s] MMythScheduler not initialized", __FUNCTION__);
+        return FALSE;
+    }
+
+    if (!gmyth_query_connect(scheduler->msqlquery)) {
+    	g_warning ("[%s] Error while connecting to db", __FUNCTION__);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/** Disconnects from the Mysql database in the backend.
+ * 
+ * @param scheduler the GMythScheduler instance to be disconnected
+ * @return true if disconnection was success, false if failed.
+ */
+gboolean
+gmyth_scheduler_disconnect (GMythScheduler *scheduler)
+{
+    assert(scheduler);
+
+    if (scheduler->msqlquery != NULL) {
+        g_object_unref (scheduler->msqlquery);
+    }
+
+    return TRUE;
+}
+
+/** Retrieves from the backend Mysql database the list of recording schedules.
+ * 
+ * @param scheduler The GMythScheduler instance.
+ * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
+ * @return The amount of schedules retrieved from database, or -1 if error.
+ */
+gint
+gmyth_scheduler_get_schedule_list ( GMythScheduler *scheduler, GList **schedule_list)
+{
+	ScheduleInfo *schedule;
+	MYSQL_RES *msql_res;
+    GString *query_str = g_string_new ("");
+    GString *date_time = g_string_new ("");
+    
+    assert(scheduler);
+    
+    g_string_printf (query_str, 
+    	"SELECT recordid,programid,chanid,starttime,startdate,"
+    	"endtime,enddate,title,subtitle,description,category FROM record;");
+
+	if (scheduler->msqlquery == NULL) {
+		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
+		return -1;
+	}
+    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
+
+    if (msql_res == NULL) {
+        g_warning ("DB retrieval of schedule list failed");
+        return -1;
+    } else {
+        MYSQL_ROW row;
+        *schedule_list = NULL;
+        
+        while((row = mysql_fetch_row (msql_res)) != NULL) {
+        	schedule = g_new0(ScheduleInfo, 1);
+        	
+        	schedule->record_id  = atoi (row[0]);
+        	schedule->program_id = atoi (row[1]);
+            schedule->channel_id = atoi (row[2]);
+            
+            /* generate a time_t from a time and a date db field */
+            g_string_printf (date_time, "%s %s", row[4], row[3]);
+            
+            schedule->start_time = gmyth_util_string_to_time (date_time);
+            
+            /* generate a time_t from a time and a date db field */
+            g_string_printf (date_time, "%s %s", row[6], row[5]);
+            
+            schedule->end_time = gmyth_util_string_to_time (date_time);
+
+            schedule->title = g_string_new (row[7]);
+            schedule->subtitle = g_string_new (row[8]);
+            schedule->description = g_string_new (row[9]);
+            schedule->category = g_string_new (row[10]);
+
+           (*schedule_list) = g_list_append (*(schedule_list), schedule);
+    	}
+    }
+
+    mysql_free_result (msql_res);
+    g_string_free(query_str, TRUE);
+    g_string_free(date_time, TRUE);
+
+    return (*schedule_list == NULL) ? 0 : g_list_length (*schedule_list);
+}
+
+/** Retrieves from the backend Mysql database the list of recorded programs.
+ * 
+ * @param scheduler The GMythScheduler instance.
+ * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
+ * @return The amount of recorded retrieved from database, or -1 if error.
+ */
+gint
+gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler, GList **recorded_list)
+{
+	RecordedInfo *record;
+	MYSQL_RES *msql_res;
+    GString *query_str = g_string_new ("");
+    GString *date_time = g_string_new ("");
+	
+    assert(scheduler);
+    
+    g_string_printf (query_str, 
+    	"SELECT recordid,programid,chanid,starttime,progstart,"
+    	"endtime,progend,title,subtitle,description,category,basename FROM recorded;");
+
+	if (scheduler->msqlquery == NULL) {
+		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
+		return -1;
+	}
+
+    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
+
+    if (msql_res == NULL) {
+        g_warning ("DB retrieval of recording list failed");
+        return -1;
+	} else {
+        MYSQL_ROW row;
+        *recorded_list = NULL;
+        
+        while((row = mysql_fetch_row (msql_res))!=NULL){
+        	record = g_new0(RecordedInfo, 1);
+            
+            record->record_id  = atoi (row[0]);
+            record->program_id = atoi (row[1]);
+            record->channel_id = atoi (row[2]);
+            
+            /* the db field time already contains the date. therefore
+             * we are not using the date field */
+            /* generate a time_t from a time and a date db field */
+            /* g_string_printf (date_time, "%s %s", row[4], row[3]); */
+            g_string_printf (date_time, "%s", row[3]); 
+            
+            record->start_time = gmyth_util_string_to_time (date_time);
+
+            /* the db field time already contains the date. therefore
+             * we are not using the date field */
+            /* generate a time_t from a time and a date db field */
+            /* g_string_printf (date_time, "%s %s", row[6], row[5]); */
+            g_string_printf (date_time, "%s", row[5]); 
+
+            record->end_time = gmyth_util_string_to_time (date_time);
+	
+            record->title = g_string_new (row[7]);
+            record->subtitle = g_string_new (row[8]);
+            record->description = g_string_new (row[9]);
+            record->category = g_string_new (row[10]);
+            record->basename = g_string_new (row[11]);
+
+		    *recorded_list = g_list_append (*recorded_list, record);
+    	}
+    }
+    
+    mysql_free_result (msql_res);
+    g_string_free(query_str, TRUE);
+    g_string_free(date_time, TRUE);
+
+    return (*recorded_list == NULL) ? 0 : g_list_length (*recorded_list);
+}
+
+/** Requests the Mysql database in the backend to add a new schedule.
+ * 
+ * @param scheduler the GMythScheduler instance.
+ * @param schedule_info the ScheduleInfo with recording schedule information
+ * to be added. record_id = -1 to add a new schedule, otherwise this
+ * function will update the schedule in the db
+ * @return gboolean returns FALSE if some error occurs, TRUE otherwise
+ */
+gboolean
+gmyth_scheduler_add_schedule (GMythScheduler *scheduler,
+                        	  ScheduleInfo *schedule_info)
+{
+    struct tm start_tm;
+    struct tm end_tm;
+
+	MYSQL_RES *msql_res;
+    GString *query_str = g_string_new ("");
+
+    assert(scheduler);
+    
+	if (scheduler->msqlquery == NULL) {
+		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
+		return 0;
+	}
+	
+	/* manipulating time */
+ 	if(localtime_r(&schedule_info->start_time, &start_tm) == NULL) {
+        g_warning ("localtime_r error in libgmyth scheduler!\n");
+        return FALSE;                 
+    }
+        
+ 	if(localtime_r(&schedule_info->end_time, &end_tm) == NULL) {
+        g_warning ("localtime_r error in libgmyth scheduler!\n");
+        return FALSE;
+    }	
+	
+	//TODO: verify if this funtion realy does what it should do!
+	g_string_printf (query_str, "REPLACE INTO record "
+	    "(recordid, type, chanid, starttime, "
+	    "startdate, endtime, enddate, title,"
+	    "profile, recpriority, maxnewest, inactive, "
+	    "maxepisodes, autoexpire, startoffset, endoffset, "
+	    "recgroup, dupmethod, dupin, station, "
+	    "autocommflag, findday, findtime, findid, "
+	    "search, autotranscode, transcoder, tsdefault, "
+	    "autouserjob1, autouserjob2, autouserjob3, autouserjob4) "
+	    " values ( %d, 1, %d, \"%02d:%02d:00\","	//recordid, type, chanid, starttime
+	    " \"%d-%02d-%02d\", \"%02d:%02d:00\", \"%04d-%02d-%02d\", \"%s\","
+        //startdate, endtime, enddate, title
+	    "DEFAULT, 0, 0, 0, "	//profile, recpriority, maxnewest, inactive
+	    "0, 1, 0, 0, "			//maxepisodes, autoexpire, startoffset, endoffset
+	    "DEFAULT, 6, 15, %d, " 	//recgroup, dupmethod, dupin, station
+	    "1, %d, \"%02d:%02d:00\", %d, "	//autocommflag, findday, findtime, findid
+	    "5, 0, 29, 1, "			//search, autotranscode, transcoder, tsdefault
+	    "0, 0, 0, 0 );",		//autouserjob1, autouserjob2, autouserjob3, autouserjob4
+	    schedule_info->record_id, schedule_info->channel_id,
+        start_tm.tm_hour, start_tm.tm_min,
+	    start_tm.tm_year+1900, start_tm.tm_mon+1, 
+        start_tm.tm_mday,
+        end_tm.tm_hour, end_tm.tm_min,
+        end_tm.tm_year+1900, end_tm.tm_mon+1, 
+        end_tm.tm_mday, schedule_info->title->str, //title
+    	schedule_info->channel_id,//station
+    	start_tm.tm_wday+1, //findday
+   		start_tm.tm_hour, start_tm.tm_min, //findtime
+   		(gint)(schedule_info->start_time/60/60/24 + 719528)//findid
+    );
+
+    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
+    
+    /* FIXME: currently no way to detect db error in UPDATE, REPLACES!
+    if (msql_res == NULL) {
+        g_warning ("DB retrieval of recording list failed");
+        return -1;
+	}*/
+    
+    /* TODO: verify record_id = -1 semantics */
+    if (schedule_info->record_id <= 0)
+	    schedule_info->record_id = get_record_id_from_database(scheduler);
+    
+    /* Notify the backend of changes */
+    update_backend(schedule_info->record_id);
+    
+    /* free allocated memory */
+    mysql_free_result (msql_res);
+    g_string_free(query_str, TRUE);
+    
+    return 1;
+}
+
+/** Requests the Mysql database in the backend to remove an existing schedule.
+ * 
+ * @param scheduler the GMythScheduler instance.
+ * @param record_id The schedule's record id to be removed
+ * @return gboolean TRUE if success, FALSE if error
+ */
+gboolean
+gmyth_scheduler_delete_schedule (GMythScheduler *scheduler, gint record_id)
+{
+
+	MYSQL_RES *msql_res;
+    GString *query_str = g_string_new ("");
+
+    assert(scheduler);
+    
+	if (scheduler->msqlquery == NULL) {
+		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
+		return FALSE;
+	}
+
+    //========================================
+    g_string_printf (query_str, 
+    	"DELETE FROM record WHERE recordid=%d", record_id);
+
+    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
+
+    if (msql_res == NULL) {
+    	g_warning ("[%s] Error while trying to delete a schedule in the database", __FUNCTION__);
+    	return FALSE;
+    }
+
+	update_backend(record_id);// Notify the backend of the changes
+    
+    mysql_free_result (msql_res);
+    g_string_free(query_str, TRUE);
+
+	return TRUE;
+}
+
+/** Requests the Mysql database in the backend to remove an existing recorded item.
+ * 
+ * @param scheduler the GMythScheduler instance.
+ * @param record_id The recorded item id to be removed
+ * @return gboolean TRUE if success, FALSE if error
+ */
+gboolean
+gmyth_scheduler_delete_recorded (GMythScheduler *scheduler, gint record_id)
+{
+
+	MYSQL_RES *msql_res;
+    GString *query_str = g_string_new ("");
+
+    assert(scheduler);
+    
+	if (scheduler->msqlquery == NULL) {
+		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
+		return FALSE;
+	}
+
+    //========================================
+    g_string_printf (query_str, 
+    	"DELETE FROM recorded WHERE recordid=%d", record_id);
+
+    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
+
+	update_backend(record_id);// Notify the backend of the changes
+    
+    mysql_free_result (msql_res);
+    g_string_free(query_str, TRUE);
+
+	return TRUE;
+}
+
+/** Retrieves an existing recorded item information from database. The information
+ * is used to fill the returned GMythProgramInfo.
+ * 
+ * @param scheduler The GMythScheduler instance.
+ * @param channel The channel associated to the record
+ * @param starttime The record start time
+ * @return A GMythProgramInfo struct with the requested record item
+ * information, or NULL if error.
+ */
+GMythProgramInfo*
+gmyth_scheduler_get_recorded (GMythScheduler *scheduler, 
+                              GString *channel, time_t starttime)
+{
+	MYSQL_RES *msql_res;
+	GMythProgramInfo *proginfo = NULL;
+	GString *query_str = g_string_new("");
+	GString *time_str = gmyth_util_time_to_string (starttime);
+
+    assert(scheduler);
+    
+	if (scheduler->msqlquery == NULL) {
+		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
+		return NULL;
+	}
+
+	g_string_printf (query_str, "SELECT recorded.chanid,starttime,endtime,title, "
+                  "subtitle,description,channel.channum, "
+                  "channel.callsign,channel.name,channel.commfree, "
+                  "channel.outputfilters,seriesid,programid,filesize, "
+                  "lastmodified,stars,previouslyshown,originalairdate, "
+                  "hostname,recordid,transcoder,playgroup, "
+                  "recorded.recpriority,progstart,progend,basename,recgroup "
+                  "FROM recorded "
+                  "LEFT JOIN channel "
+                  "ON recorded.chanid = channel.chanid "
+                  "WHERE recorded.chanid = \"%s\" "
+                  "AND starttime = \"%s\" ;",
+                  channel->str, time_str->str);
+
+    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
+
+    if (msql_res /*&& query.size() > 0*/) {
+    	
+    	MYSQL_ROW msql_row = mysql_fetch_row (msql_res);
+    	if (msql_row) {
+
+    		proginfo = g_new0 (GMythProgramInfo, 1);
+    	
+	        proginfo->chanid = g_string_new (msql_row[0]);
+	        proginfo->startts = gmyth_util_string_to_time (g_string_new (msql_row[23]));
+	        proginfo->endts = gmyth_util_string_to_time (g_string_new (msql_row[24]));
+	        proginfo->recstartts = gmyth_util_string_to_time (g_string_new (msql_row[1]));
+	        proginfo->recendts = gmyth_util_string_to_time (g_string_new (msql_row[2]));
+	        proginfo->title = g_string_new (msql_row[3]);
+	        proginfo->subtitle = g_string_new (msql_row[4]);
+	        proginfo->description = g_string_new (msql_row[5]);
+	
+	        proginfo->chanstr = g_string_new (msql_row[6]);
+	        proginfo->chansign = g_string_new (msql_row[7]);
+	        proginfo->channame = g_string_new (msql_row[0]);
+	        proginfo->chancommfree = atoi (msql_row[9]);
+	        proginfo->chanOutputFilters = g_string_new (msql_row[10]);
+	        proginfo->seriesid = g_string_new (msql_row[11]);
+	        proginfo->programid = g_string_new (msql_row[12]);
+	        proginfo->filesize = atoll (msql_row[13]);
+	
+	        proginfo->lastmodified = gmyth_util_string_to_time (g_string_new (msql_row[14]));
+	        
+	        proginfo->stars = atof (msql_row[15]);
+	        proginfo->repeat = atoi (msql_row[16]);
+	        
+	        if (msql_row[17] == NULL) {
+	            proginfo->originalAirDate = 0;
+	            proginfo->hasAirDate = FALSE;
+	        } else {
+	            proginfo->originalAirDate = gmyth_util_string_to_time (g_string_new (msql_row[17]));
+	            proginfo->hasAirDate = TRUE;
+	        }
+	        
+	        proginfo->hostname = g_string_new (msql_row[18]);
+	        proginfo->recordid = atoi (msql_row[19]);
+	        proginfo->transcoder = atoi (msql_row[20]);
+	
+	        //proginfo->spread = -1;
+			//proginfo->programflags = proginfo->getProgramFlags();
+	
+	        proginfo->recgroup = g_string_new (msql_row[26]);
+	        proginfo->playgroup = g_string_new (msql_row[21]);
+	        proginfo->recpriority = atoi (msql_row[22]);
+	
+	        proginfo->pathname = g_string_new (msql_row[25]);
+
+	        g_debug ("One program info loaded from mysql database\n");
+    	}
+    }
+
+	mysql_free_result (msql_res);
+    g_string_free(query_str, TRUE);
+    g_string_free(time_str, TRUE);
+
+    return proginfo;
+}
+
+/** Retrieves the next record id.
+ * 
+ * @param scheduler The GMythScheduler instance.
+ * @return gint record_id if success, -1 otherwise 
+ */
+static gint
+get_record_id_from_database (GMythScheduler *scheduler)
+{
+    gint record_id;
+
+    assert(scheduler);
+    
+	if (scheduler->msqlquery == NULL) {
+		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
+		return 0;
+	}
+
+    record_id = mysql_insert_id (scheduler->msqlquery->conn);
+
+	return record_id;
+}	
+	
+/** Notifies the backend of an update in the db.
+ * 
+ * @param record_id the id of the modified recording.
+ */
+static void
+update_backend(gint record_id)//fixme: put void and discovery record_id inside
+{
+    GMythStringList *strlist = gmyth_string_list_new ();
+    GString *datastr = g_string_new ("RESCHEDULE_RECORDINGS ");
+
+    g_string_append_printf (datastr, "%d", record_id);
+    gmyth_string_list_append_string (strlist, datastr);
+
+    gmyth_context_send_receive_stringlist (strlist);
+    
+    g_string_free(datastr, TRUE);
+    g_object_unref(strlist);
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_scheduler.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_scheduler.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,156 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_scheduler.h
+ * 
+ * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
+ * and modifying the recorded content.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __GMYTH_SCHEDULER_H__
+#define __GMYTH_SCHEDULER_H__
+
+#include <glib-object.h>
+#include <time.h>
+
+#include "gmyth_common.h"
+#include "gmyth_query.h"
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_SCHEDULER_TYPE               (gmyth_scheduler_get_type ())
+#define GMYTH_SCHEDULER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE, GMythScheduler))
+#define GMYTH_SCHEDULER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
+#define IS_GMYTH_SCHEDULER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE))
+#define IS_GMYTH_SCHEDULER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE))
+#define GMYTH_SCHEDULER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
+
+
+typedef struct _GMythScheduler         GMythScheduler;
+typedef struct _GMythSchedulerClass    GMythSchedulerClass;
+
+struct _GMythSchedulerClass
+{
+  GObjectClass parent_class;
+
+  /* callbacks */
+  /* no one for now */
+};
+
+struct _GMythScheduler
+{
+    GObject parent;
+
+  	unsigned long recordid;
+    unsigned long type;
+    unsigned long search;
+    GString *profile;
+    
+    long dupin;
+    long dupmethod;
+    long autoexpire;
+    short int autotranscode;
+    long transcoder;
+    
+    short int autocommflag;
+    short int autouserjob1;
+    short int autouserjob2;
+    short int autouserjob3;
+    short int autouserjob4;
+    
+    long startoffset;
+    long endoffset;
+    long maxepisodes;
+    long maxnewest;
+    
+    long recpriority;
+    GString *recgroup;
+    GString *playgroup;
+    
+    long prefinput;
+    short int inactive;
+    
+    GString *searchType;
+    GString *searchForWhat;
+    
+    GMythQuery *msqlquery;
+};
+
+typedef struct {
+	gint    record_id;
+	gint    program_id;
+	gint    channel_id;
+	
+    time_t start_time;
+	time_t end_time;
+    
+	GString *title;
+	GString *subtitle;
+	GString *description;
+	GString *category;
+    
+} ScheduleInfo;
+
+typedef struct {
+    gint    record_id;
+    gint    program_id;
+    gint    channel_id;
+
+    time_t start_time;
+    time_t end_time;
+
+	GString *title;
+	GString *subtitle;
+	GString *description;
+	GString *category;
+    
+	GString *basename;
+    
+} RecordedInfo;
+
+
+GType           gmyth_scheduler_get_type (void);
+
+GMythScheduler* gmyth_scheduler_new ();
+gboolean        gmyth_scheduler_connect      (GMythScheduler *scheduler);
+gboolean        gmyth_scheduler_disconnect   (GMythScheduler *scheduler);
+
+gint            gmyth_scheduler_get_schedule_list (GMythScheduler *scheduler, 
+                                                   GList **sched_list);
+gint            gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler, 
+                                                   GList **rec_list);
+
+GMythProgramInfo* gmyth_scheduler_get_recorded (GMythScheduler *scheduler, 
+                                        		GString *channel, time_t starttime);
+
+gint            gmyth_scheduler_add_schedule(GMythScheduler *scheduler, 
+                                             ScheduleInfo *schedule_info);
+
+gint            gmyth_scheduler_delete_schedule (GMythScheduler *scheduler, 
+                                                 gint record_id);
+gint            gmyth_scheduler_delete_recorded (GMythScheduler *scheduler, 
+                                                 gint record_id);
+
+#define G_END_DECLS
+
+#endif /* __GMYTH_SCHEDULER_H__ */
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_settings.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_settings.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,417 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_settings.c
+ * 
+ * @brief <p> This component contains functions acessing and modifying 
+ * user and program settings.
+ * 
+ * The standard settings file is created in the user home folder, in the
+ * file ~/.mmyth/settings.dat.  
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "gmyth_settings.h"
+ 
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+
+#define GMYTH_SETTINGS_FILE_NAME	"settings.dat"
+#define GMYTH_SETTINGS_DIR		".mmyth"
+
+static void gmyth_settings_class_init          (GMythSettingsClass *klass);
+static void gmyth_settings_init                (GMythSettings *object);
+
+static void gmyth_settings_dispose  (GObject *object);
+static void gmyth_settings_finalize (GObject *object);
+
+static void fill_settings_data(GMythSettings *gmyth_settings, char* line);
+
+G_DEFINE_TYPE(GMythSettings, gmyth_settings, G_TYPE_OBJECT)
+
+static void
+gmyth_settings_class_init (GMythSettingsClass *klass)
+{
+	GObjectClass *gobject_class;
+
+    gobject_class = (GObjectClass *) klass;
+
+    gobject_class->dispose  = gmyth_settings_dispose;
+    gobject_class->finalize = gmyth_settings_finalize;	
+}
+
+static void
+gmyth_settings_init (GMythSettings *gmyth_settings)
+{
+
+	gmyth_settings->settings_file = NULL;
+	
+    gmyth_settings->backend_hostname = g_string_new("127.0.0.1");
+    gmyth_settings->backend_port = 6543;
+    gmyth_settings->mysql_dbname = g_string_new("mythconverg");
+	gmyth_settings->mysql_username = g_string_new("mythtv");
+    gmyth_settings->mysql_password = g_string_new("mythtv");
+    gmyth_settings->database_type = g_string_new("mysql");
+    	
+}
+
+
+static void
+gmyth_settings_dispose  (GObject *object)
+{
+	GMythSettings *gmyth_settings = GMYTH_SETTINGS(object);
+
+	if ( gmyth_settings->backend_hostname != NULL )
+		g_string_free( gmyth_settings->backend_hostname, TRUE );
+	if ( gmyth_settings->mysql_dbname != NULL )
+		g_string_free( gmyth_settings->mysql_dbname, TRUE );
+	if ( gmyth_settings->mysql_username != NULL )
+		g_string_free( gmyth_settings->mysql_username, TRUE );
+	if ( gmyth_settings->mysql_password != NULL )
+		g_string_free( gmyth_settings->mysql_password, TRUE );
+	if ( gmyth_settings->database_type != NULL )
+		g_string_free( gmyth_settings->database_type, TRUE );
+
+	G_OBJECT_CLASS (gmyth_settings_parent_class)->dispose (object);
+}
+
+static void
+gmyth_settings_finalize (GObject *object)
+{
+	g_signal_handlers_destroy (object);
+
+    G_OBJECT_CLASS (gmyth_settings_parent_class)->finalize (object);
+}
+
+/** Creates a new instance of GMythSettings.
+ * 
+ * @return a new instance of GMythSettings.
+ */
+GMythSettings*
+gmyth_settings_new ()
+{
+    GMythSettings *gmyth_settings = GMYTH_SETTINGS (g_object_new(GMYTH_SETTINGS_TYPE, NULL));
+
+    return gmyth_settings;
+}
+
+static gboolean
+gmyth_settings_ensure_dir_exists (const gchar *dir)
+{
+
+	g_debug ("[%s] \tdir = %s\n", __FUNCTION__, dir);
+
+    if (g_file_test (dir, G_FILE_TEST_IS_DIR) == FALSE) {
+	    if (g_file_test (dir, G_FILE_TEST_EXISTS) == TRUE) {
+            g_warning ("%s exists, please move it out of the way.", dir);
+            return FALSE;
+	    }
+
+        if (mkdir (dir, 488) != 0) {
+            g_warning ("Failed to create directory %s.", dir);
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+static gboolean
+gmyth_settings_ensure_file_exists (const gchar *file_name) {
+
+	int file = 0;
+	
+    if ( g_file_test( file_name, G_FILE_TEST_EXISTS ) == FALSE ) {
+        g_debug ( "\n\tCreating %s file...\n", file_name );
+        file = creat( file_name, S_IRWXU | S_IRWXO | S_IRWXG );
+
+		if ( close( file ) == -1 )
+			return FALSE;
+    }
+
+	return TRUE;
+}
+
+/** Loads the GMyth settings from the given file.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @param filename The desired file to be opened.
+ * @return TRUE if success, FALSE if error.
+ */
+gboolean
+gmyth_settings_load_from_file (GMythSettings *gmyth_settings, GString *filename)
+{
+    FILE *file_desc;
+    char line[100];
+	
+	g_debug ("[%s] Loading GMyth settings file: %s", __FUNCTION__, filename->str);
+	
+    file_desc = fopen(filename->str, "r");
+    if( file_desc == NULL) {
+        g_warning ("[%s] Settings file %s could not be opened", __FUNCTION__, filename->str);
+        return FALSE;
+    }
+	
+	gmyth_settings->settings_file = g_string_new (filename->str);
+	
+    while(fgets(line, 100, file_desc)) {
+        int i;
+
+        /* Removes the new line characters from the end of line */
+        for ( i = strlen(line)-1; i >= 0; i--) {
+            if ( !g_ascii_iscntrl (line[i]) ) {
+                line[i+1] = '\0';
+                break;
+            }
+        }
+        
+        fill_settings_data(gmyth_settings, line);
+    }
+
+    fclose (file_desc);
+
+    return TRUE;
+}
+
+/** Loads the GMyth settings from the standard settings file
+ * (~/.mmyth/settings.dat).
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @return TRUE if success, FALSE if error.
+ */
+gboolean
+gmyth_settings_load (GMythSettings *gmyth_settings)
+{
+	GString* file_full_path = g_string_new( g_build_filename( g_get_home_dir(), 
+				GMYTH_SETTINGS_DIR, GMYTH_SETTINGS_FILE_NAME, NULL ) );
+
+	gmyth_settings->settings_file = file_full_path;
+		
+	gmyth_settings_ensure_dir_exists( g_build_filename( g_get_home_dir(), GMYTH_SETTINGS_DIR, NULL ) );
+
+	// Verifies if the file already exist
+	if ( g_file_test( file_full_path->str, G_FILE_TEST_EXISTS ) == FALSE ) {
+		g_debug ("[%s] Settings file does not exist. A new one will be created.\n", __FUNCTION__);
+
+		if ( gmyth_settings_ensure_file_exists( file_full_path->str ) == FALSE )
+			return FALSE;
+
+		// Creates the file with default values (see _init function)
+		return gmyth_settings_save (gmyth_settings);
+		
+	} else {
+		g_debug ("[%s] Opening settings from file %s", __FUNCTION__, file_full_path->str);
+		
+		return gmyth_settings_load_from_file (gmyth_settings, file_full_path);
+	}	
+}	
+
+/** Saves the current gmyth_settings to the settings file related to the
+ * given instance.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @return TRUE if success, FALSE if error.
+ */
+gboolean
+gmyth_settings_save (GMythSettings *gmyth_settings)
+{
+    FILE *file_desc;
+	
+	if (gmyth_settings->settings_file == NULL) {
+		g_warning ("[%s] Settings were not loaded from file, could not save!", __FUNCTION__);
+	}
+	
+    file_desc = fopen(gmyth_settings->settings_file->str, "w");
+    if( file_desc == NULL) {
+        g_warning ("GMYTH_SETTINGS: settings file %s not found", gmyth_settings->settings_file->str);
+        return FALSE;
+    }
+    
+	g_fprintf(file_desc, "#Maemo-Myth Settings\n");
+
+	g_fprintf(file_desc, "#General settings related with mythtv database\n");
+	g_fprintf(file_desc, "dbname=%s\n", gmyth_settings->mysql_dbname->str);
+	g_fprintf(file_desc, "username=%s\n", gmyth_settings->mysql_username->str);
+	g_fprintf(file_desc, "password=%s\n", gmyth_settings->mysql_password->str);
+
+	g_fprintf(file_desc, "\n#General settings related with mythtv backend\n");
+	g_fprintf(file_desc, "hostname=%s\n", gmyth_settings->backend_hostname->str);
+	g_fprintf(file_desc, "backend_port=%d\n", gmyth_settings->backend_port);
+
+    fclose (file_desc);
+
+	g_debug ("[%s] Settings file saved", __FUNCTION__);
+    return TRUE;
+}
+
+/** Gets the backend hostname from the settings.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @return The loaded backend hostname, or the default value "127.0.0.1" if settings
+ * file was not opened.
+ */
+GString*
+gmyth_settings_get_backend_hostname (GMythSettings *gmyth_settings)
+{
+	return g_string_new (gmyth_settings->backend_hostname->str);
+}
+
+/** Sets the backend hostname to the settings.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @param new_hostname The new hostname.
+ */
+void
+gmyth_settings_set_backend_hostname (GMythSettings *gmyth_settings, GString *new_hostname)
+{
+	g_string_assign (gmyth_settings->backend_hostname, new_hostname->str);
+}
+
+/** Gets the user name to connect to backend database.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @return The loaded user name, or the default value "mythtv" if settings
+ * file was not opened.
+ */
+GString*
+gmyth_settings_get_username (GMythSettings *gmyth_settings)
+{
+	return g_string_new (gmyth_settings->mysql_username->str);
+}
+
+/** Sets the username to connect to backend database.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @param new_username The new username.
+ */
+void
+gmyth_settings_set_username (GMythSettings *gmyth_settings, GString *new_username)
+{
+	g_string_assign (gmyth_settings->mysql_username, new_username->str);
+}
+
+/** Gets the database password from the settings file.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @return The loaded password, or the default value "mythtv" if settings
+ * file was not opened.
+ */
+GString*
+gmyth_settings_get_password (GMythSettings *gmyth_settings)
+{
+	return g_string_new (gmyth_settings->mysql_password->str);	
+}
+
+/** Sets the database password.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @param new_password The new password.
+ */
+
+void
+gmyth_settings_set_password (GMythSettings *gmyth_settings, GString *new_password)
+{
+	g_string_assign (gmyth_settings->mysql_password, new_password->str);
+}
+
+/** Gets the backend database name from the settings file.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @return The loaded database name, or the default value "mythconverg" if settings
+ * file was not opened.
+ */
+GString*
+gmyth_settings_get_dbname (GMythSettings *gmyth_settings)
+{
+	return g_string_new (gmyth_settings->mysql_dbname->str);
+}
+
+/** Sets the Mythtv database name to the settings.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @param new_dbname The new database name.
+ */
+
+void
+gmyth_settings_set_dbname (GMythSettings *gmyth_settings, GString *new_dbname)
+{
+	g_string_assign (gmyth_settings->mysql_dbname, new_dbname->str);
+}
+
+/** Gets the backend port from the settings.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @return The loaded backend port, or the default value "6543" if settings
+ * file was not opened.
+ */
+int
+gmyth_settings_get_backend_port (GMythSettings *gmyth_settings)
+{
+	return gmyth_settings->backend_port;
+}
+
+/** Sets the backend port.
+ * 
+ * @param gmyth_settings the GMythSettings instance.
+ * @param new_port The new port.
+ */
+void
+gmyth_settings_set_backend_port (GMythSettings *gmyth_settings, gint new_port)
+{
+	gmyth_settings->backend_port = new_port;
+}
+
+
+static void
+fill_settings_data(GMythSettings *gmyth_settings, char* line)
+{
+    gchar** str_splited;
+
+	GString *gstr_splited;
+	gstr_splited = g_string_new("");
+	str_splited = g_strsplit (line, "=", -1);
+
+	if(!(strcmp(str_splited[0], "hostname"))){
+		g_string_assign(gstr_splited, str_splited[1]);
+		gmyth_settings_set_backend_hostname(gmyth_settings, gstr_splited);
+	}
+	else if (!(strcmp(str_splited[0], "dbname"))){
+		g_string_assign(gstr_splited, str_splited[1]);
+		gmyth_settings_set_dbname(gmyth_settings, gstr_splited);	
+	}
+	else if (!(strcmp(str_splited[0], "username"))){
+		g_string_assign(gstr_splited, str_splited[1]);
+		gmyth_settings_set_username(gmyth_settings, gstr_splited);
+	}	
+	else if (!(strcmp(str_splited[0], "password"))){
+		g_string_assign(gstr_splited, str_splited[1]);
+		gmyth_settings_set_password(gmyth_settings, gstr_splited);
+	}
+	else if (!(strcmp(str_splited[0], "backend_port"))){
+		gmyth_settings_set_backend_port(gmyth_settings, atoi(str_splited[1]));
+	}		
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_settings.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_settings.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,103 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_settings.h
+ * 
+ * @brief <p> This component contains functions acessing and modifying 
+ * user and program settings.
+ * 
+ * The standard settings file is created in the user home folder, in the
+ * file ~/.mmyth/settings.dat.  
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __GMYTH_SETTINGS_H__
+#define __GMYTH_SETTINGS_H__
+
+#include <glib-object.h>
+
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <string.h>
+//#include <netdb.h>
+//#include <sys/socket.h>
+//#include <unistd.h>
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_SETTINGS_TYPE               (gmyth_settings_get_type ())
+#define GMYTH_SETTINGS(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SETTINGS_TYPE, GMythSettings))
+#define GMYTH_SETTINGS_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SETTINGS_TYPE, GMythSettingsClass))
+#define IS_GMYTH_SETTINGS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SETTINGS_TYPE))
+#define IS_GMYTH_SETTINGS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SETTINGS_TYPE))
+#define GMYTH_SETTINGS_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SETTINGS_TYPE, GMythSettingsClass))
+
+
+typedef struct _GMythSettings         GMythSettings;
+typedef struct _GMythSettingsClass    GMythSettingsClass;
+
+struct _GMythSettingsClass
+{
+  GObjectClass parent_class;
+
+  /* callbacks */
+  /* no one for now */
+};
+
+struct _GMythSettings
+{
+    GObject parent;
+
+	GString *settings_file;
+	
+    GString *backend_hostname;
+    int backend_port;
+
+    GString *mysql_dbname;
+	GString *mysql_username;
+    GString *mysql_password;
+    // FIXME: Why do we need database_type? Do we intend to support other dbs?
+    GString *database_type;
+};
+
+
+GType gmyth_settings_get_type (void);
+
+GMythSettings* gmyth_settings_new ();
+gboolean gmyth_settings_load_from_file (GMythSettings *gmyth_settings, GString *filename);
+gboolean gmyth_settings_load (GMythSettings *msettings);
+gboolean gmyth_settings_save (GMythSettings *gmyth_settings);
+
+GString* gmyth_settings_get_backend_hostname (GMythSettings *gmyth_settings);
+void gmyth_settings_set_backend_hostname (GMythSettings *gmyth_settings, GString *new_hostname);
+GString* gmyth_settings_get_username (GMythSettings *gmyth_settings);
+void gmyth_settings_set_username (GMythSettings *gmyth_settings, GString *new_username);
+GString* gmyth_settings_get_password (GMythSettings *gmyth_settings);
+void gmyth_settings_set_password (GMythSettings *gmyth_settings, GString *new_password);
+GString* gmyth_settings_get_dbname (GMythSettings *gmyth_settings);
+void gmyth_settings_set_dbname (GMythSettings *gmyth_settings, GString *new_dbname);
+int gmyth_settings_get_backend_port (GMythSettings *gmyth_settings);
+void gmyth_settings_set_backend_port (GMythSettings *gmyth_settings, gint new_port);
+
+
+#define G_END_DECLS
+
+#endif /* __GMYTH_SETTINGS_H__ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_socket.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_socket.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,708 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_socket.c
+ * 
+ * @brief <p> MythTV socket implementation, according to the MythTV Project
+ * (www.mythtv.org). 
+ * 
+ * This component provides basic socket functionalities to interact with
+ * the Mythtv backend.
+ * <p>
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Rosfran Lins Borges <rosfran.borges@indt.org.br> 
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <glib.h> 
+#include <glib/gprintf.h>
+
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "gmyth_socket.h"
+#include "gmyth_stringlist.h"
+#include "gmyth_context.h"
+
+#define BUFLEN 				        512
+#define MYTH_SEPARATOR 			    "[]:[]"
+#define MYTH_PROTOCOL_FIELD_SIZE	8
+
+static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+static void gmyth_socket_class_init          (GMythSocketClass *klass);
+static void gmyth_socket_init                (GMythSocket *object);
+
+static void gmyth_socket_dispose  (GObject *object);
+static void gmyth_socket_finalize (GObject *object);
+
+G_DEFINE_TYPE(GMythSocket, gmyth_socket, G_TYPE_OBJECT)
+
+static void
+gmyth_socket_class_init (GMythSocketClass *klass)
+{
+    GObjectClass *gobject_class;
+
+    gobject_class = (GObjectClass *) klass;
+
+    gobject_class->dispose  = gmyth_socket_dispose;
+    gobject_class->finalize = gmyth_socket_finalize;	
+}
+
+static void
+gmyth_socket_init (GMythSocket *gmyth_socket)
+{
+}
+
+/** Gets the some important address translation info, from the client socket
+ * that will open a connection.
+ * 
+ * @return gint that represents the error number from getaddrinfo(). 
+ */
+static gint
+gmyth_socket_toaddrinfo( gchar *addr, gint port, struct addrinfo **addrInfo )
+{
+    struct addrinfo hints;
+    gchar *portStr = g_strnfill( 32, ' ' );
+    gint errorn = EADDRNOTAVAIL;
+
+    memset( &hints, 0, sizeof(hints) );
+    hints.ai_family = AF_INET;
+    hints.ai_socktype = SOCK_STREAM;
+    /* hints.ai_flags = AI_NUMERICHOST; */
+    if ( port != -1 )	
+		sprintf(portStr, "%d", port);
+    else
+		portStr = NULL;
+
+    g_debug( "[%s] Address: %s, port: %s\n", __FUNCTION__, addr, portStr );
+    if ( ( errorn = getaddrinfo(addr, portStr, &hints, addrInfo) ) != 0 ) {
+		g_printerr( "[%s] Socket ERROR: %s\n", __FUNCTION__, gai_strerror(errorn) );
+    }
+
+    return errorn;
+}
+
+/** This function retrieves the local hostname of the 
+ * client machine.
+ *
+ * @return GString* get local hostname.
+ */
+GString *
+gmyth_socket_get_local_hostname( )
+{
+    GString *str = g_string_new("");
+
+    gchar *localhostname = g_strnfill( 1024, ' ' );
+    gchar *localaddr = g_strdup( "127.0.0.1" );
+
+    gboolean found_addr = FALSE;
+
+    struct addrinfo* addr_info_data = NULL, *addr_info0 = NULL;
+
+    struct sockaddr_in* sa = NULL;
+
+    g_static_mutex_lock( &mutex );
+
+    gethostname(localhostname, 1024);
+
+    gint err = gmyth_socket_toaddrinfo( localhostname, -1,  &addr_info_data );
+
+    addr_info0 = addr_info_data;
+
+    while( addr_info0 != NULL && addr_info0->ai_addr != NULL && 
+	    ( sa = (struct sockaddr_in*)addr_info0->ai_addr ) != NULL && !found_addr ) {
+    	localaddr = inet_ntoa( sa->sin_addr );
+	    if ( localaddr != NULL ) 
+            g_print( "[%s] localaddr = %s\n", __FUNCTION__, localaddr );
+
+	    if ( localaddr != NULL && ( g_strrstr( localaddr, "127" ) == NULL ) ) {
+    	    g_print( "[%s] Trying the address %s (err = %d).\n", 
+                    __FUNCTION__, localaddr, err );
+	        g_print( "[%s] Found local address %s!\n", __FUNCTION__, localaddr );
+	        str = g_string_assign( str, g_strdup( localaddr ) );
+	        found_addr = TRUE;
+	        break;
+	    }
+	    addr_info0 = addr_info0->ai_next;
+    };
+
+    if ( found_addr == FALSE ) {
+	    g_warning("[%s] Could not determine the local hostname address. Setting to %s\n",
+                    __FUNCTION__, localaddr );
+    	if ( localaddr != NULL )
+	        str = g_string_assign( str, localaddr );
+    	else
+	        str = g_string_assign( str, "127.0.0.1" );
+    }
+
+    g_static_mutex_unlock( &mutex );
+
+    if (localhostname!=NULL)
+	g_free( localhostname );
+
+    return str;
+}
+
+static void
+gmyth_socket_dispose  (GObject *object)
+{
+    GMythSocket *gmyth_socket = GMYTH_SOCKET(object);
+
+    gmyth_socket_close_connection (gmyth_socket);
+    /* disconnect socket */
+    G_OBJECT_CLASS (gmyth_socket_parent_class)->dispose (object);
+}
+
+static void
+gmyth_socket_finalize (GObject *object)
+{
+    g_signal_handlers_destroy (object);
+
+    G_OBJECT_CLASS (gmyth_socket_parent_class)->finalize (object);
+}
+
+/** Creates a new instance of GMythSocket.
+ * 
+ * @return a new instance of GMythSocket.
+ */
+GMythSocket*
+gmyth_socket_new ()
+{
+    GMythSocket *gmyth_socket = GMYTH_SOCKET (g_object_new(GMYTH_SOCKET_TYPE, NULL));
+
+    gmyth_socket->sd_io_ch = NULL;
+
+    gmyth_socket->hostname = g_strdup("");
+
+    gmyth_socket->port = 6543;
+
+    return gmyth_socket;
+}
+
+/** Connects to the backend.
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ * @param hostname The backend hostname or IP address.
+ * @param port The backend port.
+ * @return TRUE if success, FALSE if error.
+ */
+gboolean
+gmyth_socket_connect (GMythSocket **gmyth_socket,
+	gchar *hostname, gint port)
+{
+    struct addrinfo *addr_info_data = NULL, *addr_info0 = NULL;
+    gint ret_code = -1;
+    gint errno;
+    gboolean ret = TRUE;
+
+    if ( hostname == NULL )
+		g_printerr ( "[%s] Invalid hostname parameter!\n", __FUNCTION__ );
+
+    errno = gmyth_socket_toaddrinfo( hostname, port, &addr_info_data );
+
+    g_return_val_if_fail( addr_info_data != NULL, FALSE );
+
+    /* store hostname and port number */
+    (*gmyth_socket)->hostname = g_strdup( hostname );
+    (*gmyth_socket)->port = port;
+
+    for ( addr_info0 = addr_info_data; addr_info0; addr_info0 = addr_info_data->ai_next ) {
+
+	struct sockaddr_in *sa = (struct sockaddr_in*)addr_info0->ai_addr;
+	/* init socket descriptor */
+	(*gmyth_socket)->sd = socket( addr_info0->ai_family, addr_info0->ai_socktype,
+				     addr_info0->ai_protocol );
+
+	if ( (*gmyth_socket)->sd < 0 )
+	    continue;
+
+	g_debug( "[%s] hostname = %s, sock_fd = %d, addr = %s, addr_len = %d, \
+		ai_family = %d, ai_protocol = %d\n",
+		__FUNCTION__, hostname, (*gmyth_socket)->sd, inet_ntoa( sa->sin_addr ),
+		addr_info0->ai_addrlen, addr_info0->ai_family, addr_info0->ai_protocol );
+
+	if ( ( ret_code = connect( (*gmyth_socket)->sd, (struct sockaddr *)addr_info0->ai_addr,
+			addr_info0->ai_addrlen ) ) < 0 )
+	{
+	    g_printerr( "[%s] Error connecting to backend!\n", __FUNCTION__ );
+	    if ( ret_code == ETIMEDOUT )
+		g_printerr( "[%s]\tBackend host unreachable!\n", __FUNCTION__ );
+
+	    g_printerr( "ERROR: %s\n", gai_strerror(ret_code) );
+	    continue;
+	}
+
+	/* only will be reached if none of the error above occurred */
+	break;
+
+    }
+
+    (*gmyth_socket)->sd_io_ch = g_io_channel_unix_new( (*gmyth_socket)->sd );
+
+    //if (addr_info_data != NULL )
+    //freeaddrinfo( addr_info_data );
+
+    ret = ( ret_code == 0 ) ? TRUE : FALSE ;
+
+    return ret;
+
+}
+
+/** Gets the GIOChannel associated to the given GMythSocket.
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ */
+GIOChannel *
+gmyth_socket_get_io_channel( GMythSocket *gmyth_socket )
+{
+    g_return_val_if_fail( gmyth_socket != NULL, NULL );
+
+    return gmyth_socket->sd_io_ch;
+}
+
+/** Verifies if the socket is able to read.
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ * @return TRUE if the socket is able to read, FALSE if not.
+ */
+gboolean
+gmyth_socket_is_able_to_read( GMythSocket *gmyth_socket )
+{
+    gboolean ret = TRUE;
+
+    /* verify if the input (read) buffer is ready to receive data */
+    GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
+
+    if ( ( io_cond & G_IO_IN ) == 0 ) {
+	g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
+	ret = FALSE;
+    }
+
+    return ret;
+
+}
+
+/** Verifies if the socket is able to write.
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ * @return TRUE if the socket is able to write, FALSE if not.
+ */
+gboolean
+gmyth_socket_is_able_to_write( GMythSocket *gmyth_socket )
+{
+    gboolean ret = TRUE;
+
+    /* verify if the input (read) buffer is ready to receive data */
+    GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
+
+    if ( ( ( io_cond & G_IO_OUT ) == 0 ) || ( ( io_cond & G_IO_HUP ) == 0 ) ) {
+	g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
+	ret = FALSE;
+    }
+
+    return ret;
+
+}
+
+/** Sends a command to the backend.
+ * 
+ * @param gmyth_socket the GMythSocket instance.
+ * @param command The string command to be sent.
+ */
+gboolean
+gmyth_socket_send_command(GMythSocket *gmyth_socket, GString *command) 
+{
+    gboolean ret = TRUE;
+
+    GIOStatus io_status = G_IO_STATUS_NORMAL;
+    //GIOCondition io_cond;
+    GError* error = NULL;
+    gchar *buffer = NULL;
+
+    gsize bytes_written = 0;
+
+    if( command == NULL || ( command->len <= 0 ) ) {
+		g_warning ("[%s] Invalid NULL command parameter!\n", __FUNCTION__);
+		ret = FALSE;
+		goto done;
+    }
+
+    g_static_mutex_lock( &mutex );
+    g_debug ("[%s] Sending command to backend: %s\n", __FUNCTION__, command->str);
+
+    /*
+       io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
+
+       if ( ( io_cond & G_IO_IN ) == 0 ) {
+       g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
+       ret = FALSE;
+       goto done;
+       }
+       */
+
+    buffer = g_strnfill( BUFLEN, ' ' );
+    snprintf( buffer, MYTH_PROTOCOL_FIELD_SIZE+1, "%-8d", command->len);
+    g_print( "[%s] buffer = [%s]\n", __FUNCTION__, buffer  );
+
+    command = g_string_prepend(command, buffer);
+
+    g_print( "[%s] command = [%s]\n", __FUNCTION__, command->str  );
+
+    /* write bytes to socket */    
+    io_status = g_io_channel_write_chars( gmyth_socket->sd_io_ch, command->str, 
+	    command->len, &bytes_written, &error );
+
+
+    if( (io_status == G_IO_STATUS_ERROR) || ( bytes_written <= 0 ) ) {
+		g_warning ("[%s] Error while writing to socket", __FUNCTION__);
+		ret = FALSE;
+    } else if ( bytes_written < command->len ) {
+		g_warning ("[%s] Not all data was written socket", __FUNCTION__);
+		ret = FALSE;
+    }
+
+    io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
+
+    if ( ( bytes_written != command->len ) || ( io_status == G_IO_STATUS_ERROR ) )
+    {
+		g_warning ("[%s] Some problem occurred when sending data to the socket\n", __FUNCTION__);
+	
+		ret = TRUE;
+    }
+
+    g_static_mutex_unlock( &mutex );
+done:
+    if ( error != NULL ) {
+		g_printerr( "[%s] Error found reading data from IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
+		ret = FALSE;
+		g_error_free( error );
+    }
+
+    if ( buffer!= NULL )
+		g_free( buffer );
+
+    return ret;
+}
+
+/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
+ * supported by the backend and send the "ANN" command.
+ * 
+ * @param gmyth_socket the GMythSocket instance.
+ * @param hostname_backend The backend hostname or IP address.
+ * @param port The backend port to connect.
+ * @param blocking_client A flag to choose between blocking and non-blocking 
+ * backend connection.
+ */
+gboolean
+gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket, 
+	gchar *hostname_backend, int port, gboolean blocking_client)
+{
+    if (!gmyth_socket_connect (&gmyth_socket, hostname_backend, port)) {
+		g_warning ("[%s] Could not open socket to backend machine", __FUNCTION__);
+		return FALSE;
+    }
+
+    if (gmyth_socket_check_protocol_version (gmyth_socket)) {
+
+	GString *result;
+	GString *base_str = g_string_new("");
+	GString *hostname = NULL;
+
+	hostname = gmyth_socket_get_local_hostname();
+
+	g_string_printf(base_str, "ANN %s %s 0", 
+		(blocking_client ? "Playback" : "Monitor"),
+		hostname->str);
+
+	g_debug ("[%s] Connection command sent to backend: %s", __FUNCTION__, base_str->str);
+
+	gmyth_socket_send_command (gmyth_socket, base_str);
+	result = gmyth_socket_receive_response(gmyth_socket);
+
+	if (result != NULL) {
+	    g_debug ("[%s] Response received from backend: %s", __FUNCTION__, result->str);
+	    g_string_free (result, TRUE);
+	}
+
+	g_string_free (hostname, TRUE);
+	g_string_free (base_str, TRUE);
+
+	return TRUE;
+    } else {
+		g_warning ("[%s] GMythSocket could not connect to the backend", __FUNCTION__);	
+		return FALSE;
+	}
+
+}
+
+/** Closes the socket connection to the backend.
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ */
+void
+gmyth_socket_close_connection (GMythSocket *gmyth_socket)
+{
+    close (gmyth_socket->sd);	
+}
+
+
+/** Try the MythTV version numbers, and get the version returned by
+ * the possible REJECT message, in order to contruct a new
+ * MythTV version request.
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ * @param mythtv_version The Mythtv protocol version to be tested
+ */
+gboolean
+gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket, gint mythtv_version)
+{
+    GString *response;
+    GString *payload;
+    gchar *new_version = g_strdup("");
+    gboolean res = TRUE;
+
+try_new_version:
+    payload = g_string_new ("MYTH_PROTO_VERSION");
+    g_string_append_printf( payload, " %d", mythtv_version );
+
+    gmyth_socket_send_command(gmyth_socket, payload);
+    response = gmyth_socket_receive_response(gmyth_socket);
+
+    if (response == NULL) {
+		g_warning ("[%s] Check protocol version error! Not answered!", __FUNCTION__);
+		res = FALSE;	
+		goto done;
+    }
+
+    res = g_str_has_prefix (response->str, "ACCEPT");
+    if (!res) {
+		g_warning ("[%s] Protocol version request error: %s", __FUNCTION__, response->str);
+	/* get the version number returned by the REJECT message */
+	if ( ( res = g_str_has_prefix (response->str, "REJECT") ) == TRUE ) {
+	    new_version = g_strrstr( response->str, "]" );
+	    if (new_version!=NULL) {
+		++new_version; /* skip ']' character */
+		if ( new_version != NULL ) {
+		    g_print( "[%s] got MythTV version = %s\n", __FUNCTION__, new_version );
+		    mythtv_version = g_ascii_strtoull( g_strdup( new_version ), NULL, 10 );
+		    /* do reconnection to the socket (socket is closed if the MythTV version was wrong) */
+		    gmyth_socket_connect( &gmyth_socket, gmyth_socket->hostname, gmyth_socket->port );
+		    /* g_free( new_version ); */
+		    goto try_new_version;
+		}
+	    }
+	}
+    }
+
+done:
+    if ( payload != NULL )
+		g_string_free (payload, TRUE);
+    if ( response != NULL )
+		g_string_free (response, TRUE);
+//   if (new_version!=NULL)
+//	g_free( new_version );
+
+    return res;
+}
+
+/** Verifies if the Mythtv backend supported the GMyth supported version.
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ * @return TRUE if supports, FALSE if not.
+ */
+gboolean
+gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket)
+{
+    return gmyth_socket_check_protocol_version_number( gmyth_socket, MYTHTV_VERSION_DEFAULT );
+}
+
+/** Receives a backend answer after a gmyth_socket_send_command_call ().
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ * @return The response received, or NULL if error or nothing was received.
+ */
+GString*
+gmyth_socket_receive_response(GMythSocket *gmyth_socket)
+{
+    GIOStatus io_status = G_IO_STATUS_NORMAL;
+    GError* error = NULL;
+    gchar *buffer = NULL;
+
+    GString *str = NULL;
+
+    gsize bytes_read = 0;
+    gint  len = 0;
+    GIOCondition io_cond;
+
+    g_return_val_if_fail( gmyth_socket != NULL, NULL );
+
+    /* verify if the input (read) buffer is ready to receive data */
+
+    buffer = g_strnfill( BUFLEN, ' ' );
+
+    g_static_mutex_lock( &mutex );
+
+    io_status = g_io_channel_read_chars( gmyth_socket->sd_io_ch, buffer, MYTH_PROTOCOL_FIELD_SIZE, &bytes_read, &error );
+
+
+    /* verify if the input (read) buffer is ready to receive data */
+    io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
+
+    g_print ( "[%s] Bytes read = %d\n", __FUNCTION__, bytes_read );
+
+    if( (io_status == G_IO_STATUS_ERROR) || (bytes_read <= 0) ) {
+		g_warning ("[%s] Error in mythprotocol response from backend\n", __FUNCTION__);
+		str = NULL;
+		//return NULL;
+    } else {
+
+		io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
+		/* verify if the input (read) buffer is ready to receive data */
+		io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
+	
+		if ( ( io_cond & G_IO_IN ) != 0 ) {
+	
+		    snprintf( buffer, MYTH_PROTOCOL_FIELD_SIZE+1, "%-8s", g_strdup(buffer));
+		    g_print( "[%s] buffer = [%s]\n", __FUNCTION__, buffer  );
+	
+		    /* removes trailing whitespace */
+		    buffer = g_strstrip( buffer );
+	
+		    len = (gint)strtoull ( buffer, NULL, 10 );  
+	
+		    bytes_read = 0;
+		    io_status = g_io_channel_read_chars( gmyth_socket->sd_io_ch, buffer, len, &bytes_read, &error );
+		    buffer[bytes_read] = '\0';
+		}
+    }  
+
+    g_static_mutex_unlock( &mutex );
+
+    g_debug ("[%s] Response received from backend: {%s}\n", __FUNCTION__, buffer);
+
+    if ( ( bytes_read != len ) || ( io_status == G_IO_STATUS_ERROR ) )
+		str = NULL;
+    else
+		str = g_string_new( buffer );
+
+    if ( buffer != NULL )
+		g_free( buffer );
+
+    if ( error != NULL ) {
+		g_printerr( "[%s] Error found receiving response from the IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
+		str = NULL;
+		g_error_free( error );
+    }
+
+    return str;
+}
+
+/** Format a Mythtv command from the str_list entries and send it to backend.
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ * @param str_list The string list to form the command
+ * @return TRUE if command was sent, FALSE if any error happens.
+ */
+gboolean
+gmyth_socket_write_stringlist(GMythSocket *gmyth_socket, GMythStringList* str_list)
+{
+
+    GList *tmp_list;
+    GPtrArray *ptr_array;
+    gchar *str_array;
+
+    g_static_mutex_lock( &mutex );
+
+    ptr_array = g_ptr_array_sized_new(g_list_length(str_list->glist));
+
+    g_print( "[%s] Number of parameters = %d\n", __FUNCTION__, g_list_length(str_list->glist) );    
+
+    // FIXME: change this implementation!
+    tmp_list = str_list->glist;
+    for(; tmp_list; tmp_list = tmp_list->next) {
+	if ( tmp_list->data != NULL )
+	    g_ptr_array_add(ptr_array, ((GString*)tmp_list->data)->str);
+    }
+    g_ptr_array_add(ptr_array, NULL); // g_str_joinv() needs a NULL terminated string
+
+    str_array = g_strjoinv (MYTH_SEPARATOR, (gchar **) (ptr_array->pdata));
+
+    g_static_mutex_unlock( &mutex );
+
+    // Sends message to backend	
+    // TODO: implement looping to send remaining data, and add timeout testing!
+    gmyth_socket_send_command(gmyth_socket, g_string_new(str_array));
+
+    g_free (str_array);
+    g_ptr_array_free (ptr_array, TRUE);
+
+    return TRUE;
+}
+
+/* Receives a backend command response and split it into the given string list.
+ * 
+ * @param gmyth_socket The GMythSocket instance.
+ * @param str_list the string list to be filled.
+ * @return The number of received strings.
+ */
+gint
+gmyth_socket_read_stringlist (GMythSocket *gmyth_socket, GMythStringList* str_list)
+{
+    GString *response;
+    gchar **str_array;
+    gint i;
+
+    response = gmyth_socket_receive_response(gmyth_socket);
+    g_static_mutex_lock( &mutex );
+
+    gmyth_string_list_clear_all (str_list);	
+    str_array = g_strsplit (response->str, MYTH_SEPARATOR, -1);
+
+    for (i=0; i< g_strv_length (str_array); i++) {
+	gmyth_string_list_append_string (str_list, g_string_new (str_array[i]));
+    }
+    g_static_mutex_unlock( &mutex );
+
+    g_string_free (response, TRUE);
+    g_strfreev (str_array);
+
+    return gmyth_string_list_length (str_list);
+}
+
+/** Formats a Mythtv protocol command based on str_list and sends it to
+ * the connected backend. The backend response is overwritten into str_list.
+ *
+ * @param gmyth_socket The GMythSocket instance.
+ * @param str_list The string list to be sent, and on which the answer 
+ * will be written.
+ * @return TRUE if command was sent and an answer was received, FALSE if any
+ * error happens.
+ */
+gint
+gmyth_socket_sendreceive_stringlist (GMythSocket *gmyth_socket, GMythStringList *str_list)
+{
+    gmyth_socket_write_stringlist (gmyth_socket, str_list);
+
+    return gmyth_socket_read_stringlist (gmyth_socket, str_list);
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_socket.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_socket.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,116 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_socket.h
+ * 
+ * @brief <p> MythTV socket implementation, according to the MythTV Project
+ * (www.mythtv.org). 
+ * 
+ * This component provides basic socket functionalities to interact with
+ * the Mythtv backend.
+ * <p>
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Rosfran Lins Borges <rosfran.borges@indt.org.br> 
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __GMYTH_SOCKET_H__
+#define __GMYTH_SOCKET_H__
+
+#include <glib-object.h>
+
+#include <string.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include "gmyth_stringlist.h"
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_SOCKET_TYPE               (gmyth_socket_get_type ())
+#define GMYTH_SOCKET(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE, GMythSocket))
+#define GMYTH_SOCKET_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE, GMythSocketClass))
+#define IS_GMYTH_SOCKET(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE))
+#define IS_GMYTH_SOCKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE))
+#define GMYTH_SOCKET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SOCKET_TYPE, GMythSocketClass))
+
+
+typedef struct _GMythSocket         GMythSocket;
+typedef struct _GMythSocketClass    GMythSocketClass;
+
+struct _GMythSocketClass
+{
+	GObjectClass parent_class;
+
+	/* callbacks */
+	/* no one for now */
+};
+
+struct _GMythSocket
+{
+	GObject parent;
+
+	/* socket descriptor */
+	int sd;  
+	GIOChannel *sd_io_ch;
+
+	gchar *hostname;
+	gint port;
+};
+
+
+GType           gmyth_socket_get_type (void);
+
+GMythSocket *   gmyth_socket_new ();
+
+GIOChannel *    gmyth_socket_get_io_channel (GMythSocket *gmyth_socket );
+
+gboolean        gmyth_socket_is_able_to_read (GMythSocket *gmyth_socket );
+gboolean        gmyth_socket_is_able_to_write (GMythSocket *gmyth_socket );
+
+gboolean        gmyth_socket_send_command (GMythSocket *gmyth_socket, 
+                                           GString *command);
+GString *       gmyth_socket_receive_response (GMythSocket *gmyth_socket);
+int             gmyth_socket_sendreceive_stringlist (GMythSocket * gmyth_socket, 
+                                                     GMythStringList *str_list);
+
+gboolean        gmyth_socket_connect (GMythSocket **gmyth_socket,
+                                      gchar *hostname, gint port);
+gboolean        gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket, 
+                                                 gchar *hostname_backend, int port,
+                                          		 gboolean blocking_client);
+
+GString *       gmyth_socket_get_local_hostname ();
+
+void            gmyth_socket_close_connection (GMythSocket *gmyth_socket);
+
+gboolean		gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket);
+gboolean		gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket, 
+                                                            gint mythtv_version);
+
+gboolean		gmyth_socket_write_stringlist(GMythSocket *gmyth_socket, 
+                                              GMythStringList* str_list);
+int			    gmyth_socket_read_stringlist(GMythSocket *gmyth_socket, 
+                                             GMythStringList* str_list);
+
+#define G_END_DECLS
+
+#endif /* __GMYTH_SOCKET_H__ */
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_stringlist.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_stringlist.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,272 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_stringlist.c
+ * 
+ * @brief <p> This component contains functions for dealing with the stringlist
+ * format of the mythprotocol.
+ * 
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "gmyth_stringlist.h"
+
+static void gmyth_string_list_class_init          (GMythStringListClass *klass);
+static void gmyth_string_list_init                (GMythStringList *object);
+
+static void gmyth_string_list_dispose  (GObject *object);
+static void gmyth_string_list_finalize (GObject *object);
+
+G_DEFINE_TYPE(GMythStringList, gmyth_string_list, G_TYPE_OBJECT)
+    
+static void
+gmyth_string_list_class_init (GMythStringListClass *klass)
+{
+	GObjectClass *gobject_class;
+
+    gobject_class = (GObjectClass *) klass;
+	
+    gobject_class->dispose  = gmyth_string_list_dispose;
+    gobject_class->finalize = gmyth_string_list_finalize;	
+}
+
+static void
+gmyth_string_list_init (GMythStringList *gmyth_string_list)
+{
+	gmyth_string_list->glist = NULL;
+}
+
+static void
+gmyth_string_list_dispose  (GObject *object)
+{
+	GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
+
+	if (gmyth_string_list->glist)
+		gmyth_string_list_clear_all(gmyth_string_list);
+
+	G_OBJECT_CLASS (gmyth_string_list_parent_class)->dispose (object);
+}
+
+static void
+gmyth_string_list_finalize (GObject *object)
+{
+	//GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
+
+	g_signal_handlers_destroy (object);
+
+	G_OBJECT_CLASS (gmyth_string_list_parent_class)->finalize (object);
+}
+
+/** Creates a new instance of GStringList.
+ * 
+ * @return a new instance of GStringList.
+ */
+GMythStringList *
+gmyth_string_list_new ()
+{
+    GMythStringList *gmyth_string_list = GMYTH_STRING_LIST (g_object_new(GMYTH_STRING_LIST_TYPE, NULL));
+
+    return gmyth_string_list;
+}
+
+/** Appends a guint64 to the string list.
+ * 
+ * @param strlist The GMythStringList instance.
+ * @param value The guint64 to be appended.
+ * 
+ * @return The appended guint64 converted to a GString object.
+ */
+GString*
+gmyth_string_list_append_int ( GMythStringList *strlist, const gint value )
+{
+	GString *tmp_str = g_string_new ("");
+
+	g_string_printf (tmp_str, "%d", value);
+
+	gmyth_string_list_append_string (strlist, tmp_str);
+
+	return tmp_str;	
+}
+
+/** Appends a guint64 to the string list.
+ * 
+ * @param strlist The GMythStringList instance.
+ * @param value The guint64 to be appended.
+ * 
+ * @return The appended guint64 converted to a GString object.
+ */
+GString*
+gmyth_string_list_append_uint64 ( GMythStringList *strlist, const guint64 value)
+{
+	GString *tmp_str = g_string_new ("");	
+
+	glong l2 = ( (guint64)(value) & 0xffffffffLL );
+	glong l1 = ( ((guint64)(value) >> 32 ) & 0xffffffffLL );
+  
+	/* high order part of guint64 value */
+	g_string_printf (tmp_str, "%ld", l1);
+	
+	g_debug( "[%s] uint64 (high) = %s\n", __FUNCTION__, tmp_str->str );
+
+	gmyth_string_list_append_string (strlist, tmp_str);
+
+ 	/* low order part of guint64 value */
+	g_string_printf (tmp_str, "%ld", l2);	
+
+	g_debug( "[%s] uint64 (low) = %s\n", __FUNCTION__, tmp_str->str );
+
+	gmyth_string_list_append_string (strlist, tmp_str);
+
+	return tmp_str;	
+}
+
+/** Appends a char array to the string list.
+ * 
+ * @param strlist The GMythStringList instance.
+ * @param value The char array to be appended.
+ * 
+ * @return The appended char array converted to a GString object.
+ */
+GString*
+gmyth_string_list_append_char_array ( GMythStringList *strlist, const gchar* value )
+{
+	GString *tmp_str = NULL;
+	
+	g_return_val_if_fail( strlist != NULL, NULL );
+	
+	tmp_str = g_string_new (value);
+
+	g_return_val_if_fail( tmp_str != NULL, NULL );
+
+	gmyth_string_list_append_string (strlist, tmp_str);
+
+	return tmp_str;		
+}
+
+/** Appends a string to the string list.
+ * 
+ * @param strlist The GMythStringList instance.
+ * @param value The string to be appended.
+ * 
+ * @return The appended string itself. 
+ */
+GString*
+gmyth_string_list_append_string ( GMythStringList *strlist, GString *value )
+{
+	g_return_val_if_fail( strlist != NULL, NULL );
+
+	strlist->glist = g_list_append (strlist->glist, value);
+
+	return value;
+}
+
+/** Gets an integer value from the string list at the given position.
+ * 
+ * @param strlist The GMythStringList instance.
+ * @param index the integer position in the list, starting with zero.
+ * @return The integer value.
+ */
+gint
+gmyth_string_list_get_int ( GMythStringList *strlist, const gint index )
+{
+	//TODO: Create static method check_index()
+	GString *tmp_str = NULL;
+	
+	g_return_val_if_fail( strlist != NULL, 0 );
+
+	tmp_str = (GString *) g_list_nth_data (strlist->glist, index);
+
+	g_return_val_if_fail( tmp_str != NULL && tmp_str->str != NULL, 0 );
+	
+	return (int) ( 0x00000000ffffffffL & g_ascii_strtoull ( tmp_str->str, NULL, 0 ) );
+}
+
+/** Gets a guint64 value from the string list at the given position.
+ * According to the Mythtv protocol, the 64 bits value is formed by
+ * two strings.
+ * 
+ * @param strlist The GMythStringList instance.
+ * @param index the index of the first string forming the 64 bits value. 
+ * Index starts with zero.
+ * @return The guint64 value.
+ */
+guint64
+gmyth_string_list_get_uint64 ( GMythStringList *strlist, const gint index )
+{
+	//TODO: Create static method check_index()
+	guint64 ret_value = 0;
+
+	g_return_val_if_fail( strlist != NULL, 0 );
+  
+	const GString *tmp_str1 = (GString *) g_list_nth_data (strlist->glist, index);
+	const GString *tmp_str2 = (GString *) g_list_nth_data (strlist->glist, index+1);
+	
+	glong l1 = (glong)g_ascii_strtoull (tmp_str1->str, NULL, 10);
+	glong l2 = (glong)g_ascii_strtoull (tmp_str2->str, NULL, 10);
+	
+	ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
+  
+	g_debug( "[%s] returning uint64 value = %llu\n", __FUNCTION__, ret_value );	
+	
+	return ret_value;
+}
+
+/** Gets a string from the string list at the given position.
+ * 
+ * @param strlist The GMythStringList instance.
+ * @param index the string position in the list, starting with zero.
+ * @return A pointer to the string data.
+ */
+GString*
+gmyth_string_list_get_string ( GMythStringList *strlist, const gint index )
+{
+	if (!strlist || !(strlist->glist)) {
+		g_warning ("%s received Null arguments", __FUNCTION__);
+		return NULL;
+	}
+
+	return (GString *) g_list_nth_data (strlist->glist, index);
+}
+
+/** Removes all strings from the string list.
+ * 
+ * @param strlist The GMythStringList instance.
+ */
+void
+gmyth_string_list_clear_all ( GMythStringList *strlist )
+{
+	if ( strlist != NULL && strlist->glist ) {
+		g_list_free (strlist->glist);
+		strlist->glist = NULL;
+	}
+}
+
+/** Retrieves the number of elements in the string list.
+ * 
+ * @param strlist The GMythStringList instance.
+ * @return the string list length.
+ */
+gint
+gmyth_string_list_length ( GMythStringList *strlist )
+{
+	g_return_val_if_fail( strlist != NULL && strlist->glist != NULL, 0 );
+
+	return g_list_length (strlist->glist);
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_stringlist.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_stringlist.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,97 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_stringlist.h
+ * 
+ * @brief <p> This component contains functions for dealing with the stringlist
+ * format of the mythprotocol.
+ * 
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef GMYTH_STRING_LIST_H_
+#define GMYTH_STRING_LIST_H_
+
+#include <glib-object.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_STRING_LIST_TYPE               (gmyth_string_list_get_type ())
+#define GMYTH_STRING_LIST(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE, GMythStringList))
+#define GMYTH_STRING_LIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
+#define IS_GMYTH_STRING_LIST(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE))
+#define IS_GMYTH_STRING_LIST_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE))
+#define GMYTH_STRING_LIST_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
+
+
+typedef struct _GMythStringList         GMythStringList;
+typedef struct _GMythStringListClass    GMythStringListClass;
+
+struct _GMythStringListClass
+{
+  GObjectClass parent_class;
+
+  /* callbacks */
+  /* no one for now */
+};
+
+struct _GMythStringList
+{
+    GObject parent;
+
+    /* string list */
+    GList *glist;  
+};
+
+
+GType               gmyth_string_list_get_type (void);
+
+GMythStringList *   gmyth_string_list_new ();
+
+void                gmyth_string_list_clear_all (GMythStringList *strlist);
+int                 gmyth_string_list_length (GMythStringList *strlist);
+
+GString *           gmyth_string_list_append_int (GMythStringList *strlist, 
+                                                  const gint value);
+GString *           gmyth_string_list_append_uint64 (GMythStringList *strlist, 
+                                                     const guint64 value);
+
+GString *           gmyth_string_list_append_char_array (GMythStringList *strlist, 
+                                                         const char* value);
+GString *           gmyth_string_list_append_string (GMythStringList *strlist, 
+                                                     GString *value);
+
+int                 gmyth_string_list_get_int (GMythStringList *strlist, const gint index);
+guint64             gmyth_string_list_get_uint64 (GMythStringList *strlist, const gint index);
+GString *           gmyth_string_list_get_string (GMythStringList *strlist, const gint index);
+
+#define gmyth_string_list_get_char_array(strlist, index) \
+            (gmyth_string_list_get_string(strlist, index))->str
+
+#define G_END_DECLS
+
+#endif /*GMYTH_STRING_LIST_H_*/
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_tvchain.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_tvchain.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,324 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_tvchain.c
+ * 
+ * @brief <p> This component contains functions for creating and accessing
+ * the tvchain functions for live tv playback.
+ * 
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <glib.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gmyth_epg.h"
+#include "gmyth_tvchain.h"
+#include "gmyth_util.h"
+#include "gmyth_query.h"
+#include "gmyth_scheduler.h"
+
+static void gmyth_tvchain_class_init          (GMythTVChainClass *klass);
+static void gmyth_tvchain_init                (GMythTVChain *object);
+
+static void gmyth_tvchain_dispose  (GObject *object);
+static void gmyth_tvchain_finalize (GObject *object);
+
+G_DEFINE_TYPE(GMythTVChain, gmyth_tvchain, G_TYPE_OBJECT)
+
+static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+static void
+gmyth_tvchain_class_init (GMythTVChainClass *klass)
+{
+	GObjectClass *gobject_class;
+
+	gobject_class = (GObjectClass *) klass;
+
+	gobject_class->dispose  = gmyth_tvchain_dispose;
+	gobject_class->finalize = gmyth_tvchain_finalize;	
+}
+
+static void
+gmyth_tvchain_init (GMythTVChain *tvchain)
+{
+	tvchain->tvchain_id = NULL;
+
+	tvchain->cur_chanid = g_string_new ("");
+	tvchain->cur_startts = 0;
+}
+
+static void
+gmyth_tvchain_dispose  (GObject *object)
+{
+    //GMythTVChain *tvchain = GMYTH_TVCHAIN(object);
+    
+	G_OBJECT_CLASS (gmyth_tvchain_parent_class)->dispose (object);
+}
+
+static void
+gmyth_tvchain_finalize (GObject *object)
+{
+	g_signal_handlers_destroy (object);
+
+	G_OBJECT_CLASS (gmyth_tvchain_parent_class)->finalize (object);
+}
+
+/** Initializes the tvchain and generates the tvchain id.
+ * 
+ * @param tvchain The GMythTVChain instance.
+ * @param hostname The local hostname used to generate the tvchain id.
+ */
+void
+gmyth_tvchain_initialize (GMythTVChain *tvchain, GString *hostname)
+{
+	if (tvchain->tvchain_id == NULL) {
+		GString *isodate;
+		time_t cur_time;
+
+		time(&cur_time);
+		isodate = gmyth_util_time_to_isoformat (cur_time);
+
+		tvchain->tvchain_id = g_string_sized_new(7 + hostname->len + isodate->len);
+		g_string_printf(tvchain->tvchain_id, 
+				"live-%s-%s", hostname->str, isodate->str);
+
+		g_print("tv_chain_id: %s\n", tvchain->tvchain_id->str);
+
+		g_string_free(isodate, TRUE);
+
+	} else {
+		g_warning ("[%s] TVchain already initialized", __FUNCTION__);
+	}
+}
+
+/** Gets the tvchain id.
+ * 
+ * @param tvchain The GMythTVChain instance.
+ * @return The tvchain id.
+ */
+GString*
+gmyth_tvchain_get_id (GMythTVChain *tvchain)
+{
+	return g_string_new (tvchain->tvchain_id->str);
+}
+
+/** Reloads all tvchain entries in the database.
+ * 
+ * @param tvchain The GMythTVChain instance.
+ * @return  TRUE if success, or FALSE if error.
+ */
+gboolean
+gmyth_tvchain_reload_all (GMythTVChain *tvchain)
+{
+	MYSQL_ROW msql_row;
+	MYSQL_RES *msql_res;
+	GMythQuery *gmyth_query;
+
+	GString *stmt_str;
+
+	g_static_mutex_lock( &mutex );
+
+	guint prev_size = g_list_length (tvchain->tvchain_list);
+
+	g_debug ("[%s] chainid: %s", __FUNCTION__, tvchain->tvchain_id->str);
+
+	g_list_free (tvchain->tvchain_list);
+	tvchain->tvchain_list = NULL;
+
+	// TODO: Reuse gmyth_query already connected from context
+	gmyth_query = gmyth_query_new ();
+	if (!gmyth_query_connect (gmyth_query)) {
+		g_warning ("[%s] Could not connect to db", __FUNCTION__);
+		g_static_mutex_unlock( &mutex );
+
+		return FALSE;	
+	}
+
+	stmt_str = g_string_new ("");
+	g_string_printf (stmt_str, 
+			"SELECT chanid, starttime, endtime, discontinuity, "
+			"chainpos, hostprefix, cardtype, channame, input "
+			"FROM tvchain "
+			"WHERE chainid = \"%s\" ORDER BY chainpos;",
+			tvchain->tvchain_id->str);
+
+	msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
+	if (msql_res != NULL) {
+
+		while ((msql_row = mysql_fetch_row (msql_res)) != NULL) {
+			struct LiveTVChainEntry *entry = g_new0 (struct LiveTVChainEntry, 1);
+			entry->chanid = g_string_new (msql_row[0]);
+			entry->starttime = gmyth_util_string_to_time (g_string_new ((gchar*)msql_row[1]));
+			entry->endtime = gmyth_util_string_to_time (g_string_new (msql_row[2]));
+			entry->discontinuity = atoi (msql_row[3]) != 0;
+			entry->hostprefix = g_string_new (msql_row[5]);
+			entry->cardtype = g_string_new (msql_row[6]);
+			entry->channum = g_string_new (msql_row[7]);
+			entry->inputname = g_string_new (msql_row[8]);
+
+			//m_maxpos = query.value(4).toInt() + 1;
+
+			tvchain->tvchain_list = g_list_append (tvchain->tvchain_list, entry);			
+		}
+	} else {
+		g_warning ("gmyth_tvchain_reload_all query error!\n");
+		g_static_mutex_unlock( &mutex );
+
+		return FALSE;
+	}
+
+	g_static_mutex_unlock( &mutex );
+	
+	tvchain->cur_pos = gmyth_tvchain_program_is_at (tvchain, tvchain->cur_chanid, tvchain->cur_startts);
+
+	if (tvchain->cur_pos < 0)
+		tvchain->cur_pos = 0;
+
+	//    if (m_switchid >= 0)
+	//        m_switchid = ProgramIsAt(m_switchentry.chanid,m_switchentry.starttime);
+
+	if (prev_size != g_list_length (tvchain->tvchain_list)) {
+		g_debug ("[%s] Added new recording", __FUNCTION__);
+	}	
+
+	g_string_free (stmt_str, TRUE);
+
+	mysql_free_result (msql_res);
+
+	g_object_unref (gmyth_query);
+
+	return TRUE;
+}
+
+/** Returns the internal index for the TV chain related to the given
+ * channel and start time.
+ * 
+ * @param tvchain The GMythTVChain instance.
+ * @param chanid The channel id.
+ * @param startts The program start time.
+ */
+int
+gmyth_tvchain_program_is_at (GMythTVChain *tvchain, GString *chanid, time_t startts)
+{
+	int count = 0;
+	struct LiveTVChainEntry *entry;
+	GList *tmp_list = tvchain->tvchain_list;
+
+	g_static_mutex_lock( &mutex );
+	
+	for (; tmp_list; tmp_list = tvchain->tvchain_list->next, ++count)
+	{
+		entry = (struct LiveTVChainEntry*) tmp_list->data;
+		if (!g_strncasecmp (entry->chanid->str, chanid->str, chanid->len)
+				&& entry->starttime == startts)
+		{
+			g_static_mutex_unlock( &mutex );
+			return count;
+		}
+	}
+	g_static_mutex_unlock( &mutex );
+
+	return -1;	
+}
+
+/** Get the program info associated to the tvchain.
+ * 
+ * @param tvchain The GMythTVChain instance.
+ * @param index The tvchain index.
+ * @return The program info structure.
+ */
+GMythProgramInfo*
+gmyth_tvchain_get_program_at (GMythTVChain *tvchain, int index)
+{
+	struct LiveTVChainEntry *entry;
+
+	entry = gmyth_tvchain_get_entry_at (tvchain, index);
+
+	if (entry)
+		return gmyth_tvchain_entry_to_program (tvchain, entry);	
+
+	return NULL;
+}
+
+/** Gets a LiveTVChainEntry associated to the tvchain by its index.
+ * 
+ * @param tvchain The GMythTVChain instance.
+ * @param index The tvchain entry index
+ * @return The LiveTVchainEntry structure.
+ */
+struct LiveTVChainEntry*
+gmyth_tvchain_get_entry_at (GMythTVChain *tvchain, int index)
+{
+	struct LiveTVChainEntry* chain_entry = NULL;
+	
+	g_static_mutex_lock( &mutex );
+	
+	int size = g_list_length (tvchain->tvchain_list);
+	int new_index = (index < 0 || index >= size) ? size - 1 : index;
+
+	if (new_index >= 0) 
+		chain_entry = (struct LiveTVChainEntry*) g_list_nth_data (tvchain->tvchain_list, new_index);
+
+	g_static_mutex_unlock( &mutex );
+	
+	if ( chain_entry != NULL ) {
+		g_debug ("[%s] Got TV Chain entry at %d.\n", __FUNCTION__, new_index );
+
+	} else {
+		g_warning ("[%s] failed to get entry at index %d", __FUNCTION__, index);
+	}
+
+	return chain_entry;
+}
+
+/** Gets the program info from backend database associated to the tv chain entry.
+ * 
+ * @param tvchain The GMythTVChain instance.
+ * @param entry the LiveTVChainEntry to be converted.
+ * @return The progrma info.
+ */
+GMythProgramInfo*
+gmyth_tvchain_entry_to_program (GMythTVChain *tvchain, struct LiveTVChainEntry *entry)
+{
+	GMythProgramInfo *proginfo = NULL;
+
+	if (!entry || !tvchain) {
+		g_warning ("gmyth_tvchain_entry_to_program() received NULL argument");
+		return NULL;
+	}
+
+	GMythScheduler *scheduler = gmyth_scheduler_new ();
+
+	gmyth_scheduler_connect( scheduler );
+	proginfo = gmyth_scheduler_get_recorded (scheduler, 
+			entry->chanid, entry->starttime);
+	gmyth_scheduler_disconnect( scheduler );
+
+	if (proginfo) {
+		proginfo->pathname = g_string_prepend (proginfo->pathname, entry->hostprefix->str);
+	} else {
+		g_warning ("tvchain_entry_to_program(%s, %ld) failed!", entry->chanid->str, entry->starttime);
+	}
+
+	return proginfo;
+}
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_tvchain.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_tvchain.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,105 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_tvchain.h
+ * 
+ * @brief <p> This component contains functions for creating and accessing
+ * the tvchain functions for live tv playback.
+ * 
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef LIVETVCHAIN_H_
+#define LIVETVCHAIN_H_
+
+#include <glib-object.h>
+#include <time.h>
+
+#include "gmyth_common.h"
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_TVCHAIN_TYPE               (gmyth_tvchain_get_type ())
+#define GMYTH_TVCHAIN(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChain))
+#define GMYTH_TVCHAIN_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
+#define IS_GMYTH_TVCHAIN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE))
+#define IS_GMYTH_TVCHAIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE))
+#define GMYTH_TVCHAIN_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
+
+
+typedef struct _GMythTVChain         GMythTVChain;
+typedef struct _GMythTVChainClass    GMythTVChainClass;
+
+
+struct LiveTVChainEntry
+{
+    GString *chanid;
+
+    time_t starttime;
+    time_t endtime;
+    
+    gboolean discontinuity; // if true, can't play smooth from last entry
+    GString *hostprefix;
+    GString *cardtype;
+    GString *channum;
+    GString *inputname;
+};
+
+
+struct _GMythTVChainClass
+{
+    GObjectClass parent_class;
+
+    /* callbacks */
+    /* no one for now */
+};
+
+struct _GMythTVChain
+{
+    GObject parent;
+
+	GString *tvchain_id;
+	GList   *tvchain_list;
+	
+	time_t  cur_startts;
+	GString *cur_chanid;
+	int     cur_pos;
+};
+
+
+GType       gmyth_tvchain_get_type (void);
+
+void        gmyth_tvchain_initialize    (GMythTVChain *tvchain, 
+                                         GString *hostname);
+gboolean    gmyth_tvchain_reload_all    (GMythTVChain *tvchain);
+GString*    gmyth_tvchain_get_id        (GMythTVChain *tvchain);
+int         gmyth_tvchain_program_is_at (GMythTVChain *tvchain, 
+                                         GString *chanid, time_t startts);
+
+struct LiveTVChainEntry* gmyth_tvchain_get_entry_at (GMythTVChain *tvchain, 
+                                                     gint index);
+
+GMythProgramInfo*   gmyth_tvchain_entry_to_program (GMythTVChain *tvchain, 
+                                                    struct LiveTVChainEntry *entry);
+GMythProgramInfo*   gmyth_tvchain_get_program_at (GMythTVChain *tvchain, gint index);
+
+#define G_END_DECLS
+
+#endif /*LIVETVCHAIN_H_*/
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_tvplayer.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_tvplayer.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,719 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_tvplayer.c
+ * 
+ * @brief <p> This component provides playback of the remote A/V using
+ * GStreamer.
+ * 
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "gmyth_tvplayer.h"
+ 
+#include <gdk/gdkx.h>
+
+#include "gmyth_context.h"
+#include "gmyth_remote_util.h"
+
+typedef struct _GstPlayerWindowStateChange
+{
+    GstElement *play;
+    GstState old_state, new_state;
+    GMythTVPlayer *tvplayer;
+} GstPlayerWindowStateChange;
+
+typedef struct _GstPlayerWindowTagFound
+{
+    GstElement *play;
+    GstTagList *taglist;
+    GMythTVPlayer *tvplayer;
+} GstPlayerWindowTagFound;
+
+/*
+static gboolean idle_state (gpointer data);
+static gboolean bus_call (GstBus * bus, GstMessage * msg, gpointer data);
+*/
+
+static void gmyth_tvplayer_class_init          (GMythTVPlayerClass *klass);
+static void gmyth_tvplayer_init                (GMythTVPlayer *object);
+
+static void gmyth_tvplayer_dispose  (GObject *object);
+static void gmyth_tvplayer_finalize (GObject *object);
+
+G_DEFINE_TYPE(GMythTVPlayer, gmyth_tvplayer, G_TYPE_OBJECT)
+
+static gboolean gmyth_tvplayer_create_pipeline (GMythTVPlayer* tvplayer);
+static void     new_pad_cb (GstElement *element, 
+                            GstPad *pad, gpointer data);
+
+static gboolean expose_cb (GtkWidget * widget, 
+                           GdkEventExpose * event, 
+                           gpointer user_data);
+
+static void
+gmyth_tvplayer_class_init (GMythTVPlayerClass *klass)
+{
+	GObjectClass *gobject_class;
+
+    gobject_class = (GObjectClass *) klass;
+	
+    gobject_class->dispose  = gmyth_tvplayer_dispose;
+    gobject_class->finalize = gmyth_tvplayer_finalize;	
+}
+
+static void
+new_pad_cb (GstElement *element, GstPad *pad, gpointer data)
+{
+	GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (data);
+	GstPadLinkReturn ret;
+	char *s;
+	
+	s = gst_caps_to_string (pad->caps);
+
+	if ( s[0] == 'a') {
+		ret = gst_pad_link (pad, gst_element_get_pad (tvplayer->audioqueue, "sink"));
+	} else {
+		ret = gst_pad_link (pad, gst_element_get_pad (tvplayer->videoqueue, "sink")); 
+	}
+	
+	g_free(s);
+}
+
+static gboolean
+expose_cb (GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
+{
+    GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (user_data);
+
+	if (tvplayer && tvplayer->videow) {
+	    gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (tvplayer->gst_videosink),
+                                  GDK_WINDOW_XWINDOW (widget->window));
+		return TRUE;
+	}
+	
+	g_warning ("GMythTVPlayer expose called before setting video window\n");
+	
+    return FALSE;
+}
+
+static void
+gmyth_tvplayer_init (GMythTVPlayer *tvplayer)
+{
+    tvplayer->gst_pipeline = NULL;
+    tvplayer->gst_source = NULL;
+    tvplayer->gst_videodec = NULL;
+    tvplayer->gst_videosink = NULL;
+    tvplayer->videoqueue = NULL;
+    tvplayer->audioqueue = NULL;
+    
+    /* GTKWidget for rendering the video */
+    tvplayer->videow = NULL;
+	tvplayer->expose_handler = 0;
+	    
+	tvplayer->backend_hostname = NULL;
+	tvplayer->backend_port = 0;
+	tvplayer->local_hostname = NULL;
+
+	tvplayer->remote_encoder = NULL;
+	tvplayer->tvchain = NULL;
+	tvplayer->proginfo = NULL;
+}
+
+static void
+gmyth_tvplayer_dispose (GObject *object)
+{
+
+	G_OBJECT_CLASS (gmyth_tvplayer_parent_class)->dispose (object);
+}
+
+static void
+gmyth_tvplayer_finalize (GObject *object)
+{
+	g_signal_handlers_destroy (object);
+
+	GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (object);
+
+	g_debug ("[%s] Finalizing tvplayer", __FUNCTION__);
+	
+	if (tvplayer->videow != NULL) {
+		if (g_signal_handler_is_connected (tvplayer->videow, 
+						tvplayer->expose_handler)) {
+			g_signal_handler_disconnect (tvplayer->videow,
+				tvplayer->expose_handler);
+		}
+		g_object_unref (tvplayer->videow);
+	}
+	
+	if ( tvplayer->remote_encoder != NULL )
+		g_object_unref (tvplayer->remote_encoder);
+	if ( tvplayer->tvchain != NULL )
+		g_object_unref (tvplayer->tvchain);
+	if ( tvplayer->proginfo != NULL )
+		g_object_unref (tvplayer->proginfo);	
+
+	// Release Gstreamer elements
+	if ( tvplayer->gst_pipeline != NULL )
+		g_object_unref (tvplayer->gst_pipeline);	
+	if ( tvplayer->gst_source != NULL )
+		g_object_unref (tvplayer->gst_source);	
+	if ( tvplayer->gst_videodec != NULL )
+		g_object_unref (tvplayer->gst_videodec);	
+	if ( tvplayer->gst_videosink != NULL )
+		g_object_unref (tvplayer->gst_videosink);	
+	if ( tvplayer->videoqueue != NULL )
+		g_object_unref (tvplayer->videoqueue);	
+	if ( tvplayer->audioqueue != NULL )
+		g_object_unref (tvplayer->audioqueue);	
+
+	G_OBJECT_CLASS (gmyth_tvplayer_parent_class)->finalize (object);
+}
+
+/** Creates a new instance of GMythTVPlayer. 
+ * 
+ * @return a new instance of GMythTVPlayer.
+ */
+GMythTVPlayer *
+gmyth_tvplayer_new ()
+{
+    GMythTVPlayer *tvplayer = 
+        GMYTH_TVPLAYER (g_object_new(GMYTH_TVPLAYER_TYPE, NULL));
+    
+    return tvplayer;
+}
+
+/** Initializes the tv player.
+ *
+ * @param tvplayer the object instance.
+ * @return gboolean TRUE if the pipeline was created 
+ * successfully, FALSE otherwise.
+ */
+gboolean
+gmyth_tvplayer_initialize (GMythTVPlayer *tvplayer)
+{
+	
+    if (!gmyth_tvplayer_create_pipeline (tvplayer)) {
+    	g_warning ("[%s] Error while creating pipeline. TV Player not initialized", __FUNCTION__);
+		return FALSE;
+	} else {
+		g_debug ("[%s] GStreamer pipeline created", __FUNCTION__);	
+    }
+
+	return TRUE;
+}
+
+/** Creates the GStreamer pipeline used by the player.
+ *
+ * @param tvplayer the object instance.
+ * @return gboolean TRUE if the pipeline was created 
+ * successfully, FALSE otherwise.
+ */
+static gboolean
+gmyth_tvplayer_create_pipeline (GMythTVPlayer* tvplayer)
+{
+    GstElement *pipeline;
+    GstElement *source, *parser;
+    GstElement *videodec, *videosink;
+#ifndef MAEMO_PLATFORM    
+    GstElement *audiodec, *audioconv;
+#endif
+    GstElement *audiosink;
+    GstElement *videoqueue, *audioqueue;
+
+    g_debug ("GMythTVPlayer: Setting the Gstreamer pipeline\n");
+	
+    pipeline = gst_pipeline_new ("video-player");
+    source = gst_element_factory_make ("mythtvsrc", "myth-source");
+    parser = gst_element_factory_make ("ffdemux_nuv", "nuv-demux");
+
+    /* Gstreamer Video elements */
+    videoqueue = gst_element_factory_make ("queue", "video-queue");
+    videodec = gst_element_factory_make ("ffdec_mpeg4", "video-decoder");
+#ifdef MAEMO_PLATFORM
+    videosink = gst_element_factory_make ("sdlvideosink", "image-output");
+#else
+    videosink = gst_element_factory_make ("xvimagesink", "image-output");
+#endif
+    
+    /* Gstreamer Audio elements */
+    audioqueue = gst_element_factory_make ("queue", "audio-queue");    
+#ifdef MAEMO_PLATFORM    
+    audiosink = gst_element_factory_make ("dspmp3sink", "audio-output");
+#else    
+    audiodec = gst_element_factory_make ("ffdec_mp3", "audio-decoder");
+    audioconv = gst_element_factory_make ("audioconvert", "audio-converter");
+    audiosink = gst_element_factory_make ("alsasink", "audio-output");
+#endif    
+    
+    if (!(pipeline && source && parser && videodec && videosink) ||
+    	!(videoqueue && audioqueue && audiosink)) {
+        /* FIXME: hanlde the error correctly */
+        /* video_alignment is not being created (below) 
+           and is causing problems to the ui */
+
+	    tvplayer->gst_pipeline = NULL;
+	    tvplayer->gst_videodec = NULL;
+	    tvplayer->gst_videosink = NULL;
+           
+        g_warning ("GstElement creation error!\n");
+        return FALSE;
+    }
+
+#ifndef MAEMO_PLATFORM    
+    if (!(audiodec && audioconv)) {
+        g_warning ("GstElement for audio stream creation error!");
+        return FALSE;
+    }
+#endif    
+    
+    
+    tvplayer->gst_pipeline = pipeline;
+    tvplayer->gst_source = source;
+    tvplayer->gst_videodec = videodec;
+    tvplayer->gst_videosink = videosink;
+    g_object_ref (tvplayer->gst_pipeline);
+    g_object_ref (tvplayer->gst_source);
+    g_object_ref (tvplayer->gst_videodec);
+    g_object_ref (tvplayer->gst_videosink);
+
+    tvplayer->videoqueue = videoqueue;
+    tvplayer->audioqueue = audioqueue;
+    g_object_ref (tvplayer->videoqueue);
+    g_object_ref (tvplayer->audioqueue);
+   	
+    g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
+    g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
+
+//    gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (tvplayer->gst_pipeline)),
+//                       bus_call, tvplayer);
+
+    gst_bin_add_many (GST_BIN (pipeline), source, parser, videoqueue,
+    			videodec, videosink, audioqueue, audiodec, audioconv, audiosink, NULL);
+
+    {
+//        GstCaps *rtpcaps = gst_caps_new_simple ("application/x-rtp", NULL);
+//        gst_element_link_filtered(source, parser, rtpcaps);
+    }
+    
+    gst_element_link (source, parser);
+    gst_element_link_many (videoqueue, videodec, videosink, NULL);
+    gst_element_link_many (audioqueue, audiodec, audioconv, audiosink, NULL);
+    
+    g_signal_connect (parser, "pad-added", G_CALLBACK (new_pad_cb), tvplayer);
+    
+    return TRUE;
+}
+
+/** Configures the backend and the tv player 
+ * for playing the recorded content A/V.
+ *
+ * FIXME: Change filename to program info or other structure about the recorded
+ *
+ * @param tvplayer the object instance.
+ * @param filename the file uri of the recorded content to be played.
+ * @return TRUE if successfull, FALSE if any error happens.
+ */
+gboolean
+gmyth_tvplayer_record_setup (GMythTVPlayer *tvplayer, gchar *filename)
+{
+	GMythSettings *msettings = gmyth_context_get_settings();
+	
+	// FIXME: we should receive the uri instead of filename
+	GString *hostname = gmyth_settings_get_backend_hostname (msettings);
+	int port = gmyth_settings_get_backend_port(msettings);
+	
+	GString *fullpath = g_string_new ("myth://");
+	g_string_append_printf (fullpath, "%s:%d/%s", hostname->str, port, filename);
+	
+	tvplayer->is_livetv = FALSE;
+
+	g_debug ("[%s] Setting record uri to gstreamer pipeline to %s", __FUNCTION__, fullpath->str);
+		
+    g_object_set (G_OBJECT (tvplayer->gst_source), "location",
+          fullpath->str, NULL);
+          
+    return TRUE;
+}
+
+/** Configures the backend and the tv player 
+ * for playing the live tv.
+ *
+ * @param tvplayer the object instance.
+ * @return TRUE if successfull, FALSE if any error happens.
+ */
+gboolean
+gmyth_tvplayer_livetv_setup (GMythTVPlayer *tvplayer)
+{
+	GMythSettings *msettings = gmyth_context_get_settings ();
+	gboolean res = TRUE;
+
+	res = gmyth_context_check_connection();
+	if (!res) {
+		g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);	
+		res = FALSE;
+		goto error;
+	}
+
+	tvplayer->backend_hostname = gmyth_settings_get_backend_hostname(msettings);
+	tvplayer->backend_port = gmyth_settings_get_backend_port (msettings);
+
+	tvplayer->local_hostname  = g_string_new("");    
+	gmyth_context_get_local_hostname (tvplayer->local_hostname);
+
+	if ( tvplayer->local_hostname == NULL ) {
+		res = FALSE;
+		goto error;
+	}
+
+	// Gets the remote encoder num
+	tvplayer->remote_encoder = remote_request_next_free_recorder (-1);
+
+	if ( tvplayer->remote_encoder == NULL ) {
+		g_warning ("[%s] None remote encoder available", __FUNCTION__);
+		res = FALSE;
+		goto error;
+	}
+
+	// Creates livetv chain handler
+	tvplayer->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
+	gmyth_tvchain_initialize ( tvplayer->tvchain, tvplayer->local_hostname );
+
+	if ( tvplayer->tvchain == NULL || tvplayer->tvchain->tvchain_id == NULL ) {
+		res = FALSE;
+		goto error;
+	}
+
+	// Init remote encoder. Opens its control socket.
+	res = gmyth_remote_encoder_setup(tvplayer->remote_encoder);
+	if ( !res ) {
+		g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
+		res = FALSE;
+		goto error;
+	}
+	// Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
+	res = gmyth_remote_encoder_spawntv ( tvplayer->remote_encoder,
+			gmyth_tvchain_get_id(tvplayer->tvchain) );
+	if (!res) {
+		g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
+		res = FALSE;
+		goto error;
+	}
+
+	// Reload all TV chain from Mysql database.
+	gmyth_tvchain_reload_all (tvplayer->tvchain);
+
+	if ( tvplayer->tvchain == NULL ) {
+		res = FALSE;
+		goto error;
+	}
+
+	// Get program info from database using chanid and starttime
+	tvplayer->proginfo = gmyth_tvchain_get_program_at (tvplayer->tvchain, -1);
+	if ( tvplayer->proginfo == NULL ) {
+		g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
+		res = FALSE;
+		goto error;
+	} else {
+		g_debug ("[%s] MythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ );
+	}
+
+	return res;
+
+error:
+	if ( tvplayer->backend_hostname != NULL ) {
+		g_string_free( tvplayer->backend_hostname, TRUE );
+		res = FALSE;
+	}
+
+	if ( tvplayer->local_hostname != NULL ) {
+		g_string_free( tvplayer->local_hostname, TRUE );
+		res = FALSE;
+	}
+
+	if ( tvplayer->remote_encoder != NULL ) {
+		g_object_unref (tvplayer->remote_encoder);
+		tvplayer->remote_encoder = NULL;
+	}
+
+	if ( tvplayer->tvchain != NULL ) {
+		g_object_unref (tvplayer->tvchain);
+		tvplayer->tvchain = NULL;
+	}
+
+	if ( tvplayer->proginfo != NULL ) {
+		g_object_unref (tvplayer->proginfo);
+		tvplayer->proginfo = NULL;
+	}
+
+	return res;
+
+}
+
+/** Sets the GTK video widget for the tv player. 
+ *
+ * @param tvplayer the object instance.
+ * @param videow the GTK video window.
+ * @return TRUE if successfull, FALSE if any error happens.
+ */
+gboolean
+gmyth_tvplayer_set_widget (GMythTVPlayer *tvplayer, GtkWidget *videow)
+{
+	tvplayer->videow = videow;
+	g_object_ref (videow);
+	
+	g_debug ("[%s] Setting widget for tv player render", __FUNCTION__);
+	
+    tvplayer->expose_handler = g_signal_connect (tvplayer->videow, "expose-event", 
+                                                 G_CALLBACK (expose_cb), tvplayer);
+
+    //g_signal_connect(miptv_ui->videow, "size_request", G_CALLBACK(cb_preferred_video_size), miptv_ui);
+
+    return TRUE;
+}
+
+#if 0
+static gboolean
+bus_call (GstBus * bus, GstMessage * msg, gpointer data)
+{
+    GMythTVPlayer *tvplayer = GMYTH_TVPLAYER ( data );
+    GMainLoop *loop = tvplayer->loop;
+
+    switch (GST_MESSAGE_TYPE (msg)) {
+        case GST_MESSAGE_EOS:
+			printf ("End of stream\n");
+/*            if (miptv_ui->idle_id != 0) {
+                g_source_remove (miptv_ui->idle_id);
+                miptv_ui->idle_id = 0;
+            }*/
+
+            //g_idle_add ((GSourceFunc) idle_eos, data);
+            gst_element_set_state (GST_ELEMENT (GST_MESSAGE_SRC (msg)),
+                                   GST_STATE_READY);
+            break;
+        case GST_MESSAGE_ERROR:
+        {
+                gchar *debug;
+                GError *err;
+
+                gst_message_parse_error (msg, &err, &debug);
+                g_free (debug);
+
+                printf ("Error: %s\n", err->message);
+                g_error_free (err);
+
+                g_main_loop_quit (loop);
+        }
+            break;
+        case GST_MESSAGE_STATE_CHANGED:{
+                GstState oldstate;
+                GstState newstate;
+                GstState pending;
+                GstPlayerWindowStateChange *st =
+                    g_new (GstPlayerWindowStateChange, 1);
+
+                gst_message_parse_state_changed (msg,
+                                                 &oldstate,
+                                                 &newstate, &pending);
+
+                st->play = tvplayer->gst_pipeline;
+                gst_object_ref (GST_OBJECT (tvplayer->gst_pipeline));
+                st->old_state = oldstate;
+                st->new_state = newstate;
+
+                st->tvplayer = tvplayer;
+
+                /* State debug messages */
+                printf ("oldstate = %s, newstate = %s, pendingstate = %s\n",
+                        gst_element_state_get_name (oldstate),
+                        gst_element_state_get_name (newstate),
+                        gst_element_state_get_name (pending));
+
+                //g_idle_add ((GSourceFunc) idle_state, st);
+
+            }
+            break;
+        default:
+            printf (gst_message_type_get_name (GST_MESSAGE_TYPE (msg)));
+            printf ("\n");
+            break;
+    }
+
+    return TRUE;
+}
+#endif
+
+
+#if 0
+static gboolean
+idle_state (gpointer data)
+{
+    GstPlayerWindowStateChange *st = data;
+
+    if (st->old_state == GST_STATE_PLAYING) {
+        if (st->miptv_ui->idle_id != 0) {
+            g_source_remove (st->miptv_ui->idle_id);
+            st->miptv_ui->idle_id = 0;
+        }
+    }
+    else if (st->new_state == GST_STATE_PLAYING) {
+        if (st->miptv_ui->idle_id != 0)
+            g_source_remove (st->miptv_ui->idle_id);
+
+        st->miptv_ui->idle_id = g_idle_add (cb_iterate, st->miptv_ui);
+    }
+
+    /* new movie loaded? */
+    if (st->old_state == GST_STATE_READY && st->new_state > GST_STATE_READY) {
+
+        /* gboolean have_video = FALSE; */
+
+        gtk_widget_show (st->miptv_ui->videow);
+
+        gtk_window_resize (GTK_WINDOW (st->miptv_ui->main_window), 1, 1);
+
+    }
+
+    /* discarded movie? */
+    if (st->old_state > GST_STATE_READY && st->new_state == GST_STATE_READY) {
+
+        if (st->miptv_ui->tagcache) {
+            gst_tag_list_free (st->miptv_ui->tagcache);
+            st->miptv_ui->tagcache = NULL;
+        }
+    }
+
+    gst_object_unref (GST_OBJECT (st->play));
+    //g_object_unref (G_OBJECT (st->win));
+    g_free (st);
+
+    /* once */
+    return FALSE;
+}
+
+#endif
+
+/** Stops playing the current A/V.
+ *
+ * FIXME: How to proceed differently between livetv 
+ * and recorded content?
+ *
+ * @param tvplayer the object instance.
+ * @return void 
+ */
+void
+gmyth_tvplayer_stop_playing (GMythTVPlayer *tvplayer) 
+{
+    g_debug ("[%s] Setting gstreamer pipeline state to NULL", __FUNCTION__);
+
+    gst_element_set_state (tvplayer->gst_pipeline, GST_STATE_NULL);
+    
+    if (tvplayer->is_livetv) {
+	    if (!gmyth_remote_encoder_stop_livetv (tvplayer->remote_encoder)) {
+	    	g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);	
+	    }
+    }
+}
+
+/** Queries if the tvplayer is active playing A/V content.
+ *
+ * @param tvplayer the object instance.
+ * @return TRUE if the tvplayer is active, FALSE otherwise.
+ */
+gboolean
+gmyth_tvplayer_is_playing (GMythTVPlayer *tvplayer)
+{
+	return (GST_STATE (tvplayer->gst_pipeline) == GST_STATE_PLAYING);
+}
+
+/** Static function that sets the tvplayer state to PLAYING.
+ *
+ * @param tvplayer the object instance.
+ * @return TRUE if the tvplayer is active, FALSE otherwise.
+ */
+static gboolean
+idle_play (gpointer data)
+{
+    GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (data);
+
+	g_debug ("GMythTVPlayer: Setting pipeline state to PLAYING\n");
+
+    gst_element_set_state (tvplayer->gst_pipeline, GST_STATE_PLAYING);
+
+    return FALSE;
+}
+
+/** Start playing A/V with the tvplayer attributes.
+ *
+ * @param tvplayer the object instance.
+ */
+void
+gmyth_tvplayer_start_playing (GMythTVPlayer *tvplayer)
+{
+
+	// FIXME: Move this to livetv_setup??
+	if (tvplayer->is_livetv) {
+
+	#if 0
+		if (!tvplayer || !(tvplayer->proginfo) || !(tvplayer->local_hostname)
+				|| !(tvplayer->gst_source)) {
+			g_warning ("GMythtvPlayer not ready to start playing\n");		
+		}
+
+		if (!(tvplayer->proginfo->pathname)) {
+			g_warning ("[%s] Playback url is null, could not play the myth content", __FUNCTION__);
+			return;
+		}
+
+		g_debug ("GMythTVPlayer: Start playing %s", tvplayer->proginfo->pathname->str);
+#endif
+		g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live",
+				TRUE, NULL);
+#if 0
+		if ( tvplayer->tvchain != NULL ) {
+			GString *str_chainid = gmyth_tvchain_get_id(tvplayer->tvchain);
+			g_print( "[%s]\tCHAIN ID: %s\n", __FUNCTION__, str_chainid->str );
+
+			g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live-chainid", 
+					g_strdup( str_chainid->str ), NULL);      
+			if ( str_chainid!=NULL)
+				g_string_free( str_chainid, FALSE );
+		}
+
+		if ( tvplayer->remote_encoder != NULL )	
+			g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live-id",
+					tvplayer->remote_encoder->recorder_num, NULL );
+		g_debug ("[%s] Setting location to %s", __FUNCTION__, 
+				tvplayer->proginfo->pathname->str);
+
+		/* Sets the gstreamer properties acording to the service access address */
+		g_object_set (G_OBJECT (tvplayer->gst_source), "location",
+				tvplayer->proginfo->pathname->str, NULL);              
+#endif
+	}
+
+	g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-version",
+              MYTHTV_VERSION_DEFAULT, NULL);
+
+    g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-debug",
+              TRUE, NULL);
+
+    g_idle_add (idle_play, tvplayer);
+
+}
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_tvplayer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_tvplayer.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,112 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_tvplayer.h
+ * 
+ * @brief <p> This component provides playback of the remote A/V using
+ * GStreamer.
+ * 
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+ *
+ *//*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef GMYTH_TVPLAYER_H_
+#define GMYTH_TVPLAYER_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+/* GStreamer includes */
+#include <gst/gst.h>
+#include <gst/interfaces/xoverlay.h>
+
+#include "gmyth_remote_encoder.h"
+#include "gmyth_tvchain.h"
+#include "gmyth_common.h"
+
+#define G_BEGIN_DECLS
+
+#define GMYTH_TVPLAYER_TYPE               (gmyth_tvplayer_get_type ())
+#define GMYTH_TVPLAYER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVPLAYER_TYPE, GMythTVPlayer))
+#define GMYTH_TVPLAYER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVPLAYER_TYPE, GMythTVPlayerClass))
+#define IS_GMYTH_TVPLAYER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVPLAYER_TYPE))
+#define IS_GMYTH_TVPLAYER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVPLAYER_TYPE))
+#define GMYTH_TVPLAYER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVPLAYER_TYPE, GMythTVPlayerClass))
+
+
+typedef struct _GMythTVPlayer         GMythTVPlayer;
+typedef struct _GMythTVPlayerClass    GMythTVPlayerClass;
+
+struct _GMythTVPlayerClass
+{
+    GObjectClass parent_class;
+
+      /* callbacks */
+      /*  no one for now */
+};
+
+struct _GMythTVPlayer
+{
+    GObject parent;
+    
+    GstElement *gst_pipeline;
+    GstElement *gst_source;
+    GstElement *gst_videodec;
+    GstElement *gst_videosink;
+    GstElement *videoqueue;
+    GstElement *audioqueue;
+    
+    gulong expose_handler;
+//    GMainLoop *loop;
+    
+    GtkWidget *videow;
+
+	/* Backend connection related variables */
+	GString *backend_hostname;
+	gint backend_port;
+	GString *local_hostname;
+
+	GMythRemoteEncoder *remote_encoder;
+	GMythTVChain *tvchain;
+	GMythProgramInfo *proginfo;
+	
+	gboolean is_livetv;
+};
+
+
+GType          gmyth_tvplayer_get_type (void);
+
+GMythTVPlayer* gmyth_tvplayer_new ();
+gboolean       gmyth_tvplayer_initialize (GMythTVPlayer *tvplayer);
+
+void           gmyth_tvplayer_start_playing   (GMythTVPlayer *tvplayer);
+void           gmyth_tvplayer_stop_playing    (GMythTVPlayer *tvplayer);
+
+gboolean       gmyth_tvplayer_set_widget   (GMythTVPlayer *tvplayer, 
+                                            GtkWidget *videow);
+
+gboolean       gmyth_tvplayer_is_playing   (GMythTVPlayer *tvplayer);
+
+gboolean       gmyth_tvplayer_record_setup (GMythTVPlayer *tvplayer, 
+                                            gchar *filename);
+gboolean       gmyth_tvplayer_livetv_setup (GMythTVPlayer *tvplayer);
+
+#define G_END_DECLS
+
+#endif /*GMYTH_TVPLAYER_H_*/
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_util.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_util.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,138 @@
+/**
+* GMyth Library
+*
+* @file gmyth/gmyth_util.c
+* 
+* @brief <p> This component provides utility functions.
+* 
+* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+*
+*//*
+* 
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "gmyth_util.h"
+
+#include <glib.h>
+#include <glib/gprintf.h>
+
+/** Converts a time_t struct in a GString at ISO standard format 
+ * (e.g. 2006-07-20T09:56:41).
+ * 
+ * The returned GString memory should be deallocated from 
+ * the calling function.
+ *
+ * @param time_value the time value to be converted
+ * @return GString* the converted isoformat string 
+ */
+GString*
+gmyth_util_time_to_isoformat (time_t time_value)
+{
+	struct tm tm_time;
+	GString *result;
+	
+	if (localtime_r(&time_value, &tm_time) == NULL) {
+		g_warning ("gmyth_util_time_to_isoformat convertion error!\n");
+        return NULL;
+	}
+	
+	result = g_string_sized_new(20);
+	g_string_printf(result, "%04d-%02d-%02dT%02d:%02d:%02d",
+		tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
+		tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);
+	
+	return result;
+}
+
+/** Converts a time_t struct in a GString to the following 
+ * format (e.g. 2006-07-20 09:56:41).
+ * 
+ * The returned GString memory should be deallocated from 
+ * the calling function.
+ *
+ * @param time_value the time value to be converted
+ * @return GString* the converted string 
+ */
+GString*
+gmyth_util_time_to_string (time_t time_value)
+{
+	GString *result = gmyth_util_time_to_isoformat (time_value);
+	result->str[10] = ' ';	
+
+	return result;
+}
+
+/** Converts a GString in the following format 
+ * (e.g. 2006-07-20 09:56:41) to a time_t struct.
+ * 
+ * @param time_str the string to be converted
+ * @return time_t the time converted value
+ */
+time_t
+gmyth_util_string_to_time (GString* time_str)
+{
+	int year, month, day, hour, min, sec;
+
+	g_debug( "[%s] time_str = %s.\n", __FUNCTION__, time_str != NULL ? time_str->str : "[time string is NULL!]" );
+
+	if (sscanf (time_str->str, "%04d-%02d-%02d %02d:%02d:%02d",
+			&year, &month, &day, &hour, &min, &sec) < 3) { /* At least date */
+		g_warning ("GMythUtil: isoformat_to_time converter error!\n");
+		return 0;
+	} else {
+		struct tm tm_time;
+		tm_time.tm_year = year - 1900;
+		tm_time.tm_mon = month - 1;
+		tm_time.tm_mday = day;
+		tm_time.tm_hour = hour;
+		tm_time.tm_min = min;
+		tm_time.tm_sec = sec;
+		
+		return mktime (&tm_time);
+	}
+}
+
+/** Decodes a long long variable from the string list
+ * format of the myhtprotocol.
+ * 
+ * @param strlist the string list of mythprotocol values
+ * @param offset  the list node offset of the long long variable
+ * @return guint64  the long long converted value
+ */
+guint64
+gmyth_util_decode_long_long(GMythStringList *strlist, guint offset) 
+{
+
+	guint64 ret_value = 0LL;
+
+	g_return_val_if_fail( strlist != NULL, ret_value );
+
+	if ( offset < gmyth_string_list_length( strlist ))
+		g_printerr( "[%s] Offset is lower than the Stringlist (offset = %d)!\n", 
+                    __FUNCTION__, offset );
+    
+	g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value );
+
+	gint l1 = gmyth_string_list_get_int( strlist, offset );
+	gint l2 = gmyth_string_list_get_int( strlist, offset + 1 );
+
+	ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
+
+	return ret_value;
+
+}
+
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/libgmyth/gmyth_util.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/libgmyth/gmyth_util.h	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,42 @@
+/**
+* GMyth Library
+*
+* @file gmyth/gmyth_util.h
+* 
+* @brief <p> This component provides utility functions.
+* 
+* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
+*
+*//*
+* 
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef GMYTH_UTIL_H_
+#define GMYTH_UTIL_H_
+
+#include <time.h>
+#include <glib.h>
+
+#include "gmyth_stringlist.h"
+
+GString *   gmyth_util_time_to_isoformat(time_t time_value);
+GString *   gmyth_util_time_to_string   (time_t time_value);
+time_t      gmyth_util_string_to_time   (GString* time_str);
+guint64     gmyth_util_decode_long_long (GMythStringList *strlist, 
+                                         guint offset);
+	
+#endif /*GMYTH_UTIL_H_*/
diff -r 20b1f3062855 -r ffdf467315ec gmyth/src/mmyth_main.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gmyth/src/mmyth_main.c	Wed Sep 20 23:45:35 2006 +0100
@@ -0,0 +1,103 @@
+
+#include <gtk/gtk.h>
+
+#include "config.h"
+
+#ifdef MAEMO_PLATFORM
+#include "hildon-widgets/hildon-program.h"
+#include "hildon-widgets/hildon-window.h"
+#endif
+
+#include "gmyth_remote_encoder.h"
+#include "gmyth_settings.h"
+#include "gmyth_context.h"
+#include "gmyth_tvchain.h"
+#include "gmyth_tvplayer.h"
+#include "gmyth_remote_util.h"
+
+#include "mmyth_ui.h"
+
+static void
+cb_destroy (GtkWidget * widget, gpointer data)
+{
+    MMythUi *mmyth_ui = (MMythUi *) data;
+
+    if (mmyth_ui->tvplayer != NULL) {
+    	if (gmyth_tvplayer_is_playing (mmyth_ui->tvplayer) )
+    		gmyth_tvplayer_stop_playing (mmyth_ui->tvplayer);
+    }
+
+	mmyth_ui_finalize (mmyth_ui);
+	
+    gtk_main_quit ();
+}
+
+#ifdef NDEBUG
+static void
+debug_error_func( const gchar*log_domain, GLogLevelFlags log_level, const gchar *message,
+	gpointer user_data )
+
+{
+	/* leave this with NO print out messages, once you need to disable debug messages! */
+	//g_print ( "[%s] DEBUG messages disabled!\n", __FUNCTION__ );
+}
+#endif
+
+gint
+main (gint argc, gchar * argv[])
+{
+    GtkWidget *window;
+    MMythUi *mmyth_ui;
+#ifdef MAEMO_PLATFORM
+    HildonProgram *program = NULL;
+#endif
+
+    /* init threads */
+    g_thread_init (NULL);
+
+    /* Initializes GTK */
+    gtk_init (&argc, &argv);
+    gst_init (&argc, &argv);
+#ifdef NDEBUG
+ g_log_set_default_handler( debug_error_func, NULL );
+#endif
+
+    /* Init libmmyth context */
+    gmyth_context_initialize ();
+	
+#ifndef MAEMO_PLATFORM
+    /* create the main window */
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_widget_set_size_request (window, MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT);
+    gtk_window_set_title (GTK_WINDOW (window), "Mythtv Frontend");
+#else
+    /* Creating Hildonized main view */
+    program = HILDON_PROGRAM(hildon_program_get_instance());
+    window = hildon_window_new();
+
+    //g_signal_connect(G_OBJECT(window), "delete_event", gtk_main_quit, NULL);
+
+    hildon_program_add_window(program, HILDON_WINDOW (window));
+    g_set_application_name("Maemo Mythtv"); 
+#endif
+   
+    /* Initializes MMyth Widgets */
+#ifdef MAEMO_PLATFORM
+    mmyth_ui = mmyth_ui_initialize (program, window);
+#else    
+    mmyth_ui = mmyth_ui_initialize (window);
+#endif
+    
+    //mmyth_ui->loop = g_main_loop_new (NULL, FALSE);
+
+    /* Connect destroy signal handling */
+    g_signal_connect (window, "destroy", G_CALLBACK (cb_destroy), mmyth_ui);
+
+    /* Shows main window and start gtk loop */
+    gtk_widget_show (window);
+
+    gtk_main ();
+
+    return 0;
+}
+