[svn r2] imported to sf repository trunk
authorleo_sobral
Wed Sep 20 23:45:35 2006 +0100 (2006-09-20)
branchtrunk
changeset 1ffdf467315ec
parent 0 20b1f3062855
child 2 bd3829c2e9c9
[svn r2] imported to sf repository
gmyth/AUTHORS
gmyth/COPYING
gmyth/ChangeLog
gmyth/INSTALL
gmyth/Makefile.am
gmyth/NEWS
gmyth/README
gmyth/aminclude.am
gmyth/autogen.sh
gmyth/common/Makefile.am
gmyth/common/autogen-helper.sh
gmyth/configure.ac
gmyth/data/settings/history.dat
gmyth/debian/changelog
gmyth/debian/compat
gmyth/debian/control
gmyth/debian/control.in
gmyth/debian/mmyth.desktop
gmyth/debian/mmyth.dirs
gmyth/debian/mmyth.postinst
gmyth/debian/mmyth.service
gmyth/debian/rules
gmyth/doxygen.cfg
gmyth/gmyth.pc.in
gmyth/m4/Makefile.am
gmyth/m4/ac_doxygen.m4
gmyth/m4/as-compiler-flag.m4
gmyth/m4/as-expand.m4
gmyth/m4/as-version.m4
gmyth/pixmaps/Makefile.am
gmyth/pixmaps/main_logo.gif
gmyth/pixmaps/mmyth_logo.png
gmyth/src/Makefile.am
gmyth/src/gui/Makefile.am
gmyth/src/gui/mmyth_epg_grid_view.c
gmyth/src/gui/mmyth_epg_grid_view.h
gmyth/src/gui/mmyth_epg_grid_widget.c
gmyth/src/gui/mmyth_epg_grid_widget.h
gmyth/src/gui/mmyth_recordui.c
gmyth/src/gui/mmyth_recordui.h
gmyth/src/gui/mmyth_schedulerui.c
gmyth/src/gui/mmyth_schedulerui.h
gmyth/src/gui/mmyth_ui.c
gmyth/src/gui/mmyth_ui.c.mine
gmyth/src/gui/mmyth_ui.c.r2518
gmyth/src/gui/mmyth_ui.c.r2535
gmyth/src/gui/mmyth_ui.h
gmyth/src/gui/mmyth_uicommon.c
gmyth/src/gui/mmyth_uicommon.h
gmyth/src/gui/mmyth_uisettings.c
gmyth/src/gui/mmyth_uisettings.h
gmyth/src/gui/mmyth_videoplayer.c
gmyth/src/gui/mmyth_videoplayer.h
gmyth/src/libgmyth/Makefile.am
gmyth/src/libgmyth/gmyth_common.c
gmyth/src/libgmyth/gmyth_common.h
gmyth/src/libgmyth/gmyth_context.c
gmyth/src/libgmyth/gmyth_context.h
gmyth/src/libgmyth/gmyth_epg.c
gmyth/src/libgmyth/gmyth_epg.h
gmyth/src/libgmyth/gmyth_query.c
gmyth/src/libgmyth/gmyth_query.h
gmyth/src/libgmyth/gmyth_remote_encoder.c
gmyth/src/libgmyth/gmyth_remote_encoder.h
gmyth/src/libgmyth/gmyth_remote_util.c
gmyth/src/libgmyth/gmyth_remote_util.h
gmyth/src/libgmyth/gmyth_scheduler.c
gmyth/src/libgmyth/gmyth_scheduler.h
gmyth/src/libgmyth/gmyth_settings.c
gmyth/src/libgmyth/gmyth_settings.h
gmyth/src/libgmyth/gmyth_socket.c
gmyth/src/libgmyth/gmyth_socket.h
gmyth/src/libgmyth/gmyth_stringlist.c
gmyth/src/libgmyth/gmyth_stringlist.h
gmyth/src/libgmyth/gmyth_tvchain.c
gmyth/src/libgmyth/gmyth_tvchain.h
gmyth/src/libgmyth/gmyth_tvplayer.c
gmyth/src/libgmyth/gmyth_tvplayer.h
gmyth/src/libgmyth/gmyth_util.c
gmyth/src/libgmyth/gmyth_util.h
gmyth/src/mmyth_main.c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gmyth/COPYING	Wed Sep 20 23:45:35 2006 +0100
     1.3 @@ -0,0 +1,504 @@
     1.4 +		  GNU LESSER GENERAL PUBLIC LICENSE
     1.5 +		       Version 2.1, February 1999
     1.6 +
     1.7 + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
     1.8 +     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     1.9 + Everyone is permitted to copy and distribute verbatim copies
    1.10 + of this license document, but changing it is not allowed.
    1.11 +
    1.12 +[This is the first released version of the Lesser GPL.  It also counts
    1.13 + as the successor of the GNU Library Public License, version 2, hence
    1.14 + the version number 2.1.]
    1.15 +
    1.16 +			    Preamble
    1.17 +
    1.18 +  The licenses for most software are designed to take away your
    1.19 +freedom to share and change it.  By contrast, the GNU General Public
    1.20 +Licenses are intended to guarantee your freedom to share and change
    1.21 +free software--to make sure the software is free for all its users.
    1.22 +
    1.23 +  This license, the Lesser General Public License, applies to some
    1.24 +specially designated software packages--typically libraries--of the
    1.25 +Free Software Foundation and other authors who decide to use it.  You
    1.26 +can use it too, but we suggest you first think carefully about whether
    1.27 +this license or the ordinary General Public License is the better
    1.28 +strategy to use in any particular case, based on the explanations below.
    1.29 +
    1.30 +  When we speak of free software, we are referring to freedom of use,
    1.31 +not price.  Our General Public Licenses are designed to make sure that
    1.32 +you have the freedom to distribute copies of free software (and charge
    1.33 +for this service if you wish); that you receive source code or can get
    1.34 +it if you want it; that you can change the software and use pieces of
    1.35 +it in new free programs; and that you are informed that you can do
    1.36 +these things.
    1.37 +
    1.38 +  To protect your rights, we need to make restrictions that forbid
    1.39 +distributors to deny you these rights or to ask you to surrender these
    1.40 +rights.  These restrictions translate to certain responsibilities for
    1.41 +you if you distribute copies of the library or if you modify it.
    1.42 +
    1.43 +  For example, if you distribute copies of the library, whether gratis
    1.44 +or for a fee, you must give the recipients all the rights that we gave
    1.45 +you.  You must make sure that they, too, receive or can get the source
    1.46 +code.  If you link other code with the library, you must provide
    1.47 +complete object files to the recipients, so that they can relink them
    1.48 +with the library after making changes to the library and recompiling
    1.49 +it.  And you must show them these terms so they know their rights.
    1.50 +
    1.51 +  We protect your rights with a two-step method: (1) we copyright the
    1.52 +library, and (2) we offer you this license, which gives you legal
    1.53 +permission to copy, distribute and/or modify the library.
    1.54 +
    1.55 +  To protect each distributor, we want to make it very clear that
    1.56 +there is no warranty for the free library.  Also, if the library is
    1.57 +modified by someone else and passed on, the recipients should know
    1.58 +that what they have is not the original version, so that the original
    1.59 +author's reputation will not be affected by problems that might be
    1.60 +introduced by others.
    1.61 +
    1.62 +  Finally, software patents pose a constant threat to the existence of
    1.63 +any free program.  We wish to make sure that a company cannot
    1.64 +effectively restrict the users of a free program by obtaining a
    1.65 +restrictive license from a patent holder.  Therefore, we insist that
    1.66 +any patent license obtained for a version of the library must be
    1.67 +consistent with the full freedom of use specified in this license.
    1.68 +
    1.69 +  Most GNU software, including some libraries, is covered by the
    1.70 +ordinary GNU General Public License.  This license, the GNU Lesser
    1.71 +General Public License, applies to certain designated libraries, and
    1.72 +is quite different from the ordinary General Public License.  We use
    1.73 +this license for certain libraries in order to permit linking those
    1.74 +libraries into non-free programs.
    1.75 +
    1.76 +  When a program is linked with a library, whether statically or using
    1.77 +a shared library, the combination of the two is legally speaking a
    1.78 +combined work, a derivative of the original library.  The ordinary
    1.79 +General Public License therefore permits such linking only if the
    1.80 +entire combination fits its criteria of freedom.  The Lesser General
    1.81 +Public License permits more lax criteria for linking other code with
    1.82 +the library.
    1.83 +
    1.84 +  We call this license the "Lesser" General Public License because it
    1.85 +does Less to protect the user's freedom than the ordinary General
    1.86 +Public License.  It also provides other free software developers Less
    1.87 +of an advantage over competing non-free programs.  These disadvantages
    1.88 +are the reason we use the ordinary General Public License for many
    1.89 +libraries.  However, the Lesser license provides advantages in certain
    1.90 +special circumstances.
    1.91 +
    1.92 +  For example, on rare occasions, there may be a special need to
    1.93 +encourage the widest possible use of a certain library, so that it becomes
    1.94 +a de-facto standard.  To achieve this, non-free programs must be
    1.95 +allowed to use the library.  A more frequent case is that a free
    1.96 +library does the same job as widely used non-free libraries.  In this
    1.97 +case, there is little to gain by limiting the free library to free
    1.98 +software only, so we use the Lesser General Public License.
    1.99 +
   1.100 +  In other cases, permission to use a particular library in non-free
   1.101 +programs enables a greater number of people to use a large body of
   1.102 +free software.  For example, permission to use the GNU C Library in
   1.103 +non-free programs enables many more people to use the whole GNU
   1.104 +operating system, as well as its variant, the GNU/Linux operating
   1.105 +system.
   1.106 +
   1.107 +  Although the Lesser General Public License is Less protective of the
   1.108 +users' freedom, it does ensure that the user of a program that is
   1.109 +linked with the Library has the freedom and the wherewithal to run
   1.110 +that program using a modified version of the Library.
   1.111 +
   1.112 +  The precise terms and conditions for copying, distribution and
   1.113 +modification follow.  Pay close attention to the difference between a
   1.114 +"work based on the library" and a "work that uses the library".  The
   1.115 +former contains code derived from the library, whereas the latter must
   1.116 +be combined with the library in order to run.
   1.117 +
   1.118 +		  GNU LESSER GENERAL PUBLIC LICENSE
   1.119 +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
   1.120 +
   1.121 +  0. This License Agreement applies to any software library or other
   1.122 +program which contains a notice placed by the copyright holder or
   1.123 +other authorized party saying it may be distributed under the terms of
   1.124 +this Lesser General Public License (also called "this License").
   1.125 +Each licensee is addressed as "you".
   1.126 +
   1.127 +  A "library" means a collection of software functions and/or data
   1.128 +prepared so as to be conveniently linked with application programs
   1.129 +(which use some of those functions and data) to form executables.
   1.130 +
   1.131 +  The "Library", below, refers to any such software library or work
   1.132 +which has been distributed under these terms.  A "work based on the
   1.133 +Library" means either the Library or any derivative work under
   1.134 +copyright law: that is to say, a work containing the Library or a
   1.135 +portion of it, either verbatim or with modifications and/or translated
   1.136 +straightforwardly into another language.  (Hereinafter, translation is
   1.137 +included without limitation in the term "modification".)
   1.138 +
   1.139 +  "Source code" for a work means the preferred form of the work for
   1.140 +making modifications to it.  For a library, complete source code means
   1.141 +all the source code for all modules it contains, plus any associated
   1.142 +interface definition files, plus the scripts used to control compilation
   1.143 +and installation of the library.
   1.144 +
   1.145 +  Activities other than copying, distribution and modification are not
   1.146 +covered by this License; they are outside its scope.  The act of
   1.147 +running a program using the Library is not restricted, and output from
   1.148 +such a program is covered only if its contents constitute a work based
   1.149 +on the Library (independent of the use of the Library in a tool for
   1.150 +writing it).  Whether that is true depends on what the Library does
   1.151 +and what the program that uses the Library does.
   1.152 +  
   1.153 +  1. You may copy and distribute verbatim copies of the Library's
   1.154 +complete source code as you receive it, in any medium, provided that
   1.155 +you conspicuously and appropriately publish on each copy an
   1.156 +appropriate copyright notice and disclaimer of warranty; keep intact
   1.157 +all the notices that refer to this License and to the absence of any
   1.158 +warranty; and distribute a copy of this License along with the
   1.159 +Library.
   1.160 +
   1.161 +  You may charge a fee for the physical act of transferring a copy,
   1.162 +and you may at your option offer warranty protection in exchange for a
   1.163 +fee.
   1.164 +
   1.165 +  2. You may modify your copy or copies of the Library or any portion
   1.166 +of it, thus forming a work based on the Library, and copy and
   1.167 +distribute such modifications or work under the terms of Section 1
   1.168 +above, provided that you also meet all of these conditions:
   1.169 +
   1.170 +    a) The modified work must itself be a software library.
   1.171 +
   1.172 +    b) You must cause the files modified to carry prominent notices
   1.173 +    stating that you changed the files and the date of any change.
   1.174 +
   1.175 +    c) You must cause the whole of the work to be licensed at no
   1.176 +    charge to all third parties under the terms of this License.
   1.177 +
   1.178 +    d) If a facility in the modified Library refers to a function or a
   1.179 +    table of data to be supplied by an application program that uses
   1.180 +    the facility, other than as an argument passed when the facility
   1.181 +    is invoked, then you must make a good faith effort to ensure that,
   1.182 +    in the event an application does not supply such function or
   1.183 +    table, the facility still operates, and performs whatever part of
   1.184 +    its purpose remains meaningful.
   1.185 +
   1.186 +    (For example, a function in a library to compute square roots has
   1.187 +    a purpose that is entirely well-defined independent of the
   1.188 +    application.  Therefore, Subsection 2d requires that any
   1.189 +    application-supplied function or table used by this function must
   1.190 +    be optional: if the application does not supply it, the square
   1.191 +    root function must still compute square roots.)
   1.192 +
   1.193 +These requirements apply to the modified work as a whole.  If
   1.194 +identifiable sections of that work are not derived from the Library,
   1.195 +and can be reasonably considered independent and separate works in
   1.196 +themselves, then this License, and its terms, do not apply to those
   1.197 +sections when you distribute them as separate works.  But when you
   1.198 +distribute the same sections as part of a whole which is a work based
   1.199 +on the Library, the distribution of the whole must be on the terms of
   1.200 +this License, whose permissions for other licensees extend to the
   1.201 +entire whole, and thus to each and every part regardless of who wrote
   1.202 +it.
   1.203 +
   1.204 +Thus, it is not the intent of this section to claim rights or contest
   1.205 +your rights to work written entirely by you; rather, the intent is to
   1.206 +exercise the right to control the distribution of derivative or
   1.207 +collective works based on the Library.
   1.208 +
   1.209 +In addition, mere aggregation of another work not based on the Library
   1.210 +with the Library (or with a work based on the Library) on a volume of
   1.211 +a storage or distribution medium does not bring the other work under
   1.212 +the scope of this License.
   1.213 +
   1.214 +  3. You may opt to apply the terms of the ordinary GNU General Public
   1.215 +License instead of this License to a given copy of the Library.  To do
   1.216 +this, you must alter all the notices that refer to this License, so
   1.217 +that they refer to the ordinary GNU General Public License, version 2,
   1.218 +instead of to this License.  (If a newer version than version 2 of the
   1.219 +ordinary GNU General Public License has appeared, then you can specify
   1.220 +that version instead if you wish.)  Do not make any other change in
   1.221 +these notices.
   1.222 +
   1.223 +  Once this change is made in a given copy, it is irreversible for
   1.224 +that copy, so the ordinary GNU General Public License applies to all
   1.225 +subsequent copies and derivative works made from that copy.
   1.226 +
   1.227 +  This option is useful when you wish to copy part of the code of
   1.228 +the Library into a program that is not a library.
   1.229 +
   1.230 +  4. You may copy and distribute the Library (or a portion or
   1.231 +derivative of it, under Section 2) in object code or executable form
   1.232 +under the terms of Sections 1 and 2 above provided that you accompany
   1.233 +it with the complete corresponding machine-readable source code, which
   1.234 +must be distributed under the terms of Sections 1 and 2 above on a
   1.235 +medium customarily used for software interchange.
   1.236 +
   1.237 +  If distribution of object code is made by offering access to copy
   1.238 +from a designated place, then offering equivalent access to copy the
   1.239 +source code from the same place satisfies the requirement to
   1.240 +distribute the source code, even though third parties are not
   1.241 +compelled to copy the source along with the object code.
   1.242 +
   1.243 +  5. A program that contains no derivative of any portion of the
   1.244 +Library, but is designed to work with the Library by being compiled or
   1.245 +linked with it, is called a "work that uses the Library".  Such a
   1.246 +work, in isolation, is not a derivative work of the Library, and
   1.247 +therefore falls outside the scope of this License.
   1.248 +
   1.249 +  However, linking a "work that uses the Library" with the Library
   1.250 +creates an executable that is a derivative of the Library (because it
   1.251 +contains portions of the Library), rather than a "work that uses the
   1.252 +library".  The executable is therefore covered by this License.
   1.253 +Section 6 states terms for distribution of such executables.
   1.254 +
   1.255 +  When a "work that uses the Library" uses material from a header file
   1.256 +that is part of the Library, the object code for the work may be a
   1.257 +derivative work of the Library even though the source code is not.
   1.258 +Whether this is true is especially significant if the work can be
   1.259 +linked without the Library, or if the work is itself a library.  The
   1.260 +threshold for this to be true is not precisely defined by law.
   1.261 +
   1.262 +  If such an object file uses only numerical parameters, data
   1.263 +structure layouts and accessors, and small macros and small inline
   1.264 +functions (ten lines or less in length), then the use of the object
   1.265 +file is unrestricted, regardless of whether it is legally a derivative
   1.266 +work.  (Executables containing this object code plus portions of the
   1.267 +Library will still fall under Section 6.)
   1.268 +
   1.269 +  Otherwise, if the work is a derivative of the Library, you may
   1.270 +distribute the object code for the work under the terms of Section 6.
   1.271 +Any executables containing that work also fall under Section 6,
   1.272 +whether or not they are linked directly with the Library itself.
   1.273 +
   1.274 +  6. As an exception to the Sections above, you may also combine or
   1.275 +link a "work that uses the Library" with the Library to produce a
   1.276 +work containing portions of the Library, and distribute that work
   1.277 +under terms of your choice, provided that the terms permit
   1.278 +modification of the work for the customer's own use and reverse
   1.279 +engineering for debugging such modifications.
   1.280 +
   1.281 +  You must give prominent notice with each copy of the work that the
   1.282 +Library is used in it and that the Library and its use are covered by
   1.283 +this License.  You must supply a copy of this License.  If the work
   1.284 +during execution displays copyright notices, you must include the
   1.285 +copyright notice for the Library among them, as well as a reference
   1.286 +directing the user to the copy of this License.  Also, you must do one
   1.287 +of these things:
   1.288 +
   1.289 +    a) Accompany the work with the complete corresponding
   1.290 +    machine-readable source code for the Library including whatever
   1.291 +    changes were used in the work (which must be distributed under
   1.292 +    Sections 1 and 2 above); and, if the work is an executable linked
   1.293 +    with the Library, with the complete machine-readable "work that
   1.294 +    uses the Library", as object code and/or source code, so that the
   1.295 +    user can modify the Library and then relink to produce a modified
   1.296 +    executable containing the modified Library.  (It is understood
   1.297 +    that the user who changes the contents of definitions files in the
   1.298 +    Library will not necessarily be able to recompile the application
   1.299 +    to use the modified definitions.)
   1.300 +
   1.301 +    b) Use a suitable shared library mechanism for linking with the
   1.302 +    Library.  A suitable mechanism is one that (1) uses at run time a
   1.303 +    copy of the library already present on the user's computer system,
   1.304 +    rather than copying library functions into the executable, and (2)
   1.305 +    will operate properly with a modified version of the library, if
   1.306 +    the user installs one, as long as the modified version is
   1.307 +    interface-compatible with the version that the work was made with.
   1.308 +
   1.309 +    c) Accompany the work with a written offer, valid for at
   1.310 +    least three years, to give the same user the materials
   1.311 +    specified in Subsection 6a, above, for a charge no more
   1.312 +    than the cost of performing this distribution.
   1.313 +
   1.314 +    d) If distribution of the work is made by offering access to copy
   1.315 +    from a designated place, offer equivalent access to copy the above
   1.316 +    specified materials from the same place.
   1.317 +
   1.318 +    e) Verify that the user has already received a copy of these
   1.319 +    materials or that you have already sent this user a copy.
   1.320 +
   1.321 +  For an executable, the required form of the "work that uses the
   1.322 +Library" must include any data and utility programs needed for
   1.323 +reproducing the executable from it.  However, as a special exception,
   1.324 +the materials to be distributed need not include anything that is
   1.325 +normally distributed (in either source or binary form) with the major
   1.326 +components (compiler, kernel, and so on) of the operating system on
   1.327 +which the executable runs, unless that component itself accompanies
   1.328 +the executable.
   1.329 +
   1.330 +  It may happen that this requirement contradicts the license
   1.331 +restrictions of other proprietary libraries that do not normally
   1.332 +accompany the operating system.  Such a contradiction means you cannot
   1.333 +use both them and the Library together in an executable that you
   1.334 +distribute.
   1.335 +
   1.336 +  7. You may place library facilities that are a work based on the
   1.337 +Library side-by-side in a single library together with other library
   1.338 +facilities not covered by this License, and distribute such a combined
   1.339 +library, provided that the separate distribution of the work based on
   1.340 +the Library and of the other library facilities is otherwise
   1.341 +permitted, and provided that you do these two things:
   1.342 +
   1.343 +    a) Accompany the combined library with a copy of the same work
   1.344 +    based on the Library, uncombined with any other library
   1.345 +    facilities.  This must be distributed under the terms of the
   1.346 +    Sections above.
   1.347 +
   1.348 +    b) Give prominent notice with the combined library of the fact
   1.349 +    that part of it is a work based on the Library, and explaining
   1.350 +    where to find the accompanying uncombined form of the same work.
   1.351 +
   1.352 +  8. You may not copy, modify, sublicense, link with, or distribute
   1.353 +the Library except as expressly provided under this License.  Any
   1.354 +attempt otherwise to copy, modify, sublicense, link with, or
   1.355 +distribute the Library is void, and will automatically terminate your
   1.356 +rights under this License.  However, parties who have received copies,
   1.357 +or rights, from you under this License will not have their licenses
   1.358 +terminated so long as such parties remain in full compliance.
   1.359 +
   1.360 +  9. You are not required to accept this License, since you have not
   1.361 +signed it.  However, nothing else grants you permission to modify or
   1.362 +distribute the Library or its derivative works.  These actions are
   1.363 +prohibited by law if you do not accept this License.  Therefore, by
   1.364 +modifying or distributing the Library (or any work based on the
   1.365 +Library), you indicate your acceptance of this License to do so, and
   1.366 +all its terms and conditions for copying, distributing or modifying
   1.367 +the Library or works based on it.
   1.368 +
   1.369 +  10. Each time you redistribute the Library (or any work based on the
   1.370 +Library), the recipient automatically receives a license from the
   1.371 +original licensor to copy, distribute, link with or modify the Library
   1.372 +subject to these terms and conditions.  You may not impose any further
   1.373 +restrictions on the recipients' exercise of the rights granted herein.
   1.374 +You are not responsible for enforcing compliance by third parties with
   1.375 +this License.
   1.376 +
   1.377 +  11. If, as a consequence of a court judgment or allegation of patent
   1.378 +infringement or for any other reason (not limited to patent issues),
   1.379 +conditions are imposed on you (whether by court order, agreement or
   1.380 +otherwise) that contradict the conditions of this License, they do not
   1.381 +excuse you from the conditions of this License.  If you cannot
   1.382 +distribute so as to satisfy simultaneously your obligations under this
   1.383 +License and any other pertinent obligations, then as a consequence you
   1.384 +may not distribute the Library at all.  For example, if a patent
   1.385 +license would not permit royalty-free redistribution of the Library by
   1.386 +all those who receive copies directly or indirectly through you, then
   1.387 +the only way you could satisfy both it and this License would be to
   1.388 +refrain entirely from distribution of the Library.
   1.389 +
   1.390 +If any portion of this section is held invalid or unenforceable under any
   1.391 +particular circumstance, the balance of the section is intended to apply,
   1.392 +and the section as a whole is intended to apply in other circumstances.
   1.393 +
   1.394 +It is not the purpose of this section to induce you to infringe any
   1.395 +patents or other property right claims or to contest validity of any
   1.396 +such claims; this section has the sole purpose of protecting the
   1.397 +integrity of the free software distribution system which is
   1.398 +implemented by public license practices.  Many people have made
   1.399 +generous contributions to the wide range of software distributed
   1.400 +through that system in reliance on consistent application of that
   1.401 +system; it is up to the author/donor to decide if he or she is willing
   1.402 +to distribute software through any other system and a licensee cannot
   1.403 +impose that choice.
   1.404 +
   1.405 +This section is intended to make thoroughly clear what is believed to
   1.406 +be a consequence of the rest of this License.
   1.407 +
   1.408 +  12. If the distribution and/or use of the Library is restricted in
   1.409 +certain countries either by patents or by copyrighted interfaces, the
   1.410 +original copyright holder who places the Library under this License may add
   1.411 +an explicit geographical distribution limitation excluding those countries,
   1.412 +so that distribution is permitted only in or among countries not thus
   1.413 +excluded.  In such case, this License incorporates the limitation as if
   1.414 +written in the body of this License.
   1.415 +
   1.416 +  13. The Free Software Foundation may publish revised and/or new
   1.417 +versions of the Lesser General Public License from time to time.
   1.418 +Such new versions will be similar in spirit to the present version,
   1.419 +but may differ in detail to address new problems or concerns.
   1.420 +
   1.421 +Each version is given a distinguishing version number.  If the Library
   1.422 +specifies a version number of this License which applies to it and
   1.423 +"any later version", you have the option of following the terms and
   1.424 +conditions either of that version or of any later version published by
   1.425 +the Free Software Foundation.  If the Library does not specify a
   1.426 +license version number, you may choose any version ever published by
   1.427 +the Free Software Foundation.
   1.428 +
   1.429 +  14. If you wish to incorporate parts of the Library into other free
   1.430 +programs whose distribution conditions are incompatible with these,
   1.431 +write to the author to ask for permission.  For software which is
   1.432 +copyrighted by the Free Software Foundation, write to the Free
   1.433 +Software Foundation; we sometimes make exceptions for this.  Our
   1.434 +decision will be guided by the two goals of preserving the free status
   1.435 +of all derivatives of our free software and of promoting the sharing
   1.436 +and reuse of software generally.
   1.437 +
   1.438 +			    NO WARRANTY
   1.439 +
   1.440 +  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
   1.441 +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
   1.442 +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
   1.443 +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
   1.444 +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
   1.445 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   1.446 +PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
   1.447 +LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
   1.448 +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
   1.449 +
   1.450 +  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
   1.451 +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
   1.452 +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
   1.453 +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
   1.454 +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
   1.455 +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
   1.456 +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
   1.457 +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
   1.458 +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
   1.459 +DAMAGES.
   1.460 +
   1.461 +		     END OF TERMS AND CONDITIONS
   1.462 +
   1.463 +           How to Apply These Terms to Your New Libraries
   1.464 +
   1.465 +  If you develop a new library, and you want it to be of the greatest
   1.466 +possible use to the public, we recommend making it free software that
   1.467 +everyone can redistribute and change.  You can do so by permitting
   1.468 +redistribution under these terms (or, alternatively, under the terms of the
   1.469 +ordinary General Public License).
   1.470 +
   1.471 +  To apply these terms, attach the following notices to the library.  It is
   1.472 +safest to attach them to the start of each source file to most effectively
   1.473 +convey the exclusion of warranty; and each file should have at least the
   1.474 +"copyright" line and a pointer to where the full notice is found.
   1.475 +
   1.476 +    <one line to give the library's name and a brief idea of what it does.>
   1.477 +    Copyright (C) <year>  <name of author>
   1.478 +
   1.479 +    This library is free software; you can redistribute it and/or
   1.480 +    modify it under the terms of the GNU Lesser General Public
   1.481 +    License as published by the Free Software Foundation; either
   1.482 +    version 2.1 of the License, or (at your option) any later version.
   1.483 +
   1.484 +    This library is distributed in the hope that it will be useful,
   1.485 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   1.486 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   1.487 +    Lesser General Public License for more details.
   1.488 +
   1.489 +    You should have received a copy of the GNU Lesser General Public
   1.490 +    License along with this library; if not, write to the Free Software
   1.491 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   1.492 +
   1.493 +Also add information on how to contact you by electronic and paper mail.
   1.494 +
   1.495 +You should also get your employer (if you work as a programmer) or your
   1.496 +school, if any, to sign a "copyright disclaimer" for the library, if
   1.497 +necessary.  Here is a sample; alter the names:
   1.498 +
   1.499 +  Yoyodyne, Inc., hereby disclaims all copyright interest in the
   1.500 +  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
   1.501 +
   1.502 +  <signature of Ty Coon>, 1 April 1990
   1.503 +  Ty Coon, President of Vice
   1.504 +
   1.505 +That's all there is to it!
   1.506 +
   1.507 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/gmyth/ChangeLog	Wed Sep 20 23:45:35 2006 +0100
     2.3 @@ -0,0 +1,24 @@
     2.4 +2006-08-17 Rosfran Borges <rosfran.borges@indt.org.br>
     2.5 +	* Added the correct gstreamer-base package (GSTBASE) at the configure.ac; 
     2.6 +	GSTBASE_CFLAGS and GSTBASE_LIBS variables had the same values from
     2.7 +	the GST_CFLAGS/GST_LIBS.
     2.8 +
     2.9 +2006-08-16 Rosfran Borges <rosfran.borges@indt.org.br>
    2.10 +	* Fixed some installation issues, regarding lib-installing to the
    2.11 +	correct directory, and copying the header files to the destination
    2.12 +	dir (make install).
    2.13 +	* Put 'pkg-config' resource to the Maemo Myth library. The name of the
    2.14 +	PKG-CONFIG resource is 'maemo-myth', plus the minor and major version.
    2.15 +	Actually, the version is '0.1', so the library config file is:  
    2.16 +	'maemo-myth-0.1.pc'. You can type: 'pkg-config --cflags --libs 
    2.17 +	maemo-myth-0.1'.
    2.18 +	* Many adjustments in the automake/autoconf configuration files
    2.19 +	(configure.ac, Makefile.am) - some autotools misusage fixed.
    2.20 +	* Added the MythURI structure, and the URI parsing utility functions
    2.21 +	(missing in the GLib).
    2.22 +	* Some functions were exported (myth_socket, mmyth_context), that's 
    2.23 +	why many ther modules need to use them.
    2.24 +	* Fixed some library dependencies.
    2.25 +	* Prepared to be used inside the GStreamer (linking with the MythTV
    2.26 +	plug-in).
    2.27 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/gmyth/INSTALL	Wed Sep 20 23:45:35 2006 +0100
     3.3 @@ -0,0 +1,182 @@
     3.4 +Basic Installation
     3.5 +==================
     3.6 +
     3.7 +   These are generic installation instructions.
     3.8 +
     3.9 +   The `configure' shell script attempts to guess correct values for
    3.10 +various system-dependent variables used during compilation.  It uses
    3.11 +those values to create a `Makefile' in each directory of the package.
    3.12 +It may also create one or more `.h' files containing system-dependent
    3.13 +definitions.  Finally, it creates a shell script `config.status' that
    3.14 +you can run in the future to recreate the current configuration, a file
    3.15 +`config.cache' that saves the results of its tests to speed up
    3.16 +reconfiguring, and a file `config.log' containing compiler output
    3.17 +(useful mainly for debugging `configure').
    3.18 +
    3.19 +   If you need to do unusual things to compile the package, please try
    3.20 +to figure out how `configure' could check whether to do them, and mail
    3.21 +diffs or instructions to the address given in the `README' so they can
    3.22 +be considered for the next release.  If at some point `config.cache'
    3.23 +contains results you don't want to keep, you may remove or edit it.
    3.24 +
    3.25 +   The file `configure.in' is used to create `configure' by a program
    3.26 +called `autoconf'.  You only need `configure.in' if you want to change
    3.27 +it or regenerate `configure' using a newer version of `autoconf'.
    3.28 +
    3.29 +The simplest way to compile this package is:
    3.30 +
    3.31 +  1. `cd' to the directory containing the package's source code and type
    3.32 +     `./configure' to configure the package for your system.  If you're
    3.33 +     using `csh' on an old version of System V, you might need to type
    3.34 +     `sh ./configure' instead to prevent `csh' from trying to execute
    3.35 +     `configure' itself.
    3.36 +
    3.37 +     Running `configure' takes awhile.  While running, it prints some
    3.38 +     messages telling which features it is checking for.
    3.39 +
    3.40 +  2. Type `make' to compile the package.
    3.41 +
    3.42 +  3. Optionally, type `make check' to run any self-tests that come with
    3.43 +     the package.
    3.44 +
    3.45 +  4. Type `make install' to install the programs and any data files and
    3.46 +     documentation.
    3.47 +
    3.48 +  5. You can remove the program binaries and object files from the
    3.49 +     source code directory by typing `make clean'.  To also remove the
    3.50 +     files that `configure' created (so you can compile the package for
    3.51 +     a different kind of computer), type `make distclean'.  There is
    3.52 +     also a `make maintainer-clean' target, but that is intended mainly
    3.53 +     for the package's developers.  If you use it, you may have to get
    3.54 +     all sorts of other programs in order to regenerate files that came
    3.55 +     with the distribution.
    3.56 +
    3.57 +Compilers and Options
    3.58 +=====================
    3.59 +
    3.60 +   Some systems require unusual options for compilation or linking that
    3.61 +the `configure' script does not know about.  You can give `configure'
    3.62 +initial values for variables by setting them in the environment.  Using
    3.63 +a Bourne-compatible shell, you can do that on the command line like
    3.64 +this:
    3.65 +     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
    3.66 +
    3.67 +Or on systems that have the `env' program, you can do it like this:
    3.68 +     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
    3.69 +
    3.70 +Compiling For Multiple Architectures
    3.71 +====================================
    3.72 +
    3.73 +   You can compile the package for more than one kind of computer at the
    3.74 +same time, by placing the object files for each architecture in their
    3.75 +own directory.  To do this, you must use a version of `make' that
    3.76 +supports the `VPATH' variable, such as GNU `make'.  `cd' to the
    3.77 +directory where you want the object files and executables to go and run
    3.78 +the `configure' script.  `configure' automatically checks for the
    3.79 +source code in the directory that `configure' is in and in `..'.
    3.80 +
    3.81 +   If you have to use a `make' that does not supports the `VPATH'
    3.82 +variable, you have to compile the package for one architecture at a time
    3.83 +in the source code directory.  After you have installed the package for
    3.84 +one architecture, use `make distclean' before reconfiguring for another
    3.85 +architecture.
    3.86 +
    3.87 +Installation Names
    3.88 +==================
    3.89 +
    3.90 +   By default, `make install' will install the package's files in
    3.91 +`/usr/local/bin', `/usr/local/man', etc.  You can specify an
    3.92 +installation prefix other than `/usr/local' by giving `configure' the
    3.93 +option `--prefix=PATH'.
    3.94 +
    3.95 +   You can specify separate installation prefixes for
    3.96 +architecture-specific files and architecture-independent files.  If you
    3.97 +give `configure' the option `--exec-prefix=PATH', the package will use
    3.98 +PATH as the prefix for installing programs and libraries.
    3.99 +Documentation and other data files will still use the regular prefix.
   3.100 +
   3.101 +   In addition, if you use an unusual directory layout you can give
   3.102 +options like `--bindir=PATH' to specify different values for particular
   3.103 +kinds of files.  Run `configure --help' for a list of the directories
   3.104 +you can set and what kinds of files go in them.
   3.105 +
   3.106 +   If the package supports it, you can cause programs to be installed
   3.107 +with an extra prefix or suffix on their names by giving `configure' the
   3.108 +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
   3.109 +
   3.110 +Optional Features
   3.111 +=================
   3.112 +
   3.113 +   Some packages pay attention to `--enable-FEATURE' options to
   3.114 +`configure', where FEATURE indicates an optional part of the package.
   3.115 +They may also pay attention to `--with-PACKAGE' options, where PACKAGE
   3.116 +is something like `gnu-as' or `x' (for the X Window System).  The
   3.117 +`README' should mention any `--enable-' and `--with-' options that the
   3.118 +package recognizes.
   3.119 +
   3.120 +   For packages that use the X Window System, `configure' can usually
   3.121 +find the X include and library files automatically, but if it doesn't,
   3.122 +you can use the `configure' options `--x-includes=DIR' and
   3.123 +`--x-libraries=DIR' to specify their locations.
   3.124 +
   3.125 +Specifying the System Type
   3.126 +==========================
   3.127 +
   3.128 +   There may be some features `configure' can not figure out
   3.129 +automatically, but needs to determine by the type of host the package
   3.130 +will run on.  Usually `configure' can figure that out, but if it prints
   3.131 +a message saying it can not guess the host type, give it the
   3.132 +`--host=TYPE' option.  TYPE can either be a short name for the system
   3.133 +type, such as `sun4', or a canonical name with three fields:
   3.134 +     CPU-COMPANY-SYSTEM
   3.135 +
   3.136 +See the file `config.sub' for the possible values of each field.  If
   3.137 +`config.sub' isn't included in this package, then this package doesn't
   3.138 +need to know the host type.
   3.139 +
   3.140 +   If you are building compiler tools for cross-compiling, you can also
   3.141 +use the `--target=TYPE' option to select the type of system they will
   3.142 +produce code for and the `--build=TYPE' option to select the type of
   3.143 +system on which you are compiling the package.
   3.144 +
   3.145 +Sharing Defaults
   3.146 +================
   3.147 +
   3.148 +   If you want to set default values for `configure' scripts to share,
   3.149 +you can create a site shell script called `config.site' that gives
   3.150 +default values for variables like `CC', `cache_file', and `prefix'.
   3.151 +`configure' looks for `PREFIX/share/config.site' if it exists, then
   3.152 +`PREFIX/etc/config.site' if it exists.  Or, you can set the
   3.153 +`CONFIG_SITE' environment variable to the location of the site script.
   3.154 +A warning: not all `configure' scripts look for a site script.
   3.155 +
   3.156 +Operation Controls
   3.157 +==================
   3.158 +
   3.159 +   `configure' recognizes the following options to control how it
   3.160 +operates.
   3.161 +
   3.162 +`--cache-file=FILE'
   3.163 +     Use and save the results of the tests in FILE instead of
   3.164 +     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
   3.165 +     debugging `configure'.
   3.166 +
   3.167 +`--help'
   3.168 +     Print a summary of the options to `configure', and exit.
   3.169 +
   3.170 +`--quiet'
   3.171 +`--silent'
   3.172 +`-q'
   3.173 +     Do not print messages saying which checks are being made.  To
   3.174 +     suppress all normal output, redirect it to `/dev/null' (any error
   3.175 +     messages will still be shown).
   3.176 +
   3.177 +`--srcdir=DIR'
   3.178 +     Look for the package's source code in directory DIR.  Usually
   3.179 +     `configure' can determine that directory automatically.
   3.180 +
   3.181 +`--version'
   3.182 +     Print the version of Autoconf used to generate the `configure'
   3.183 +     script, and exit.
   3.184 +
   3.185 +`configure' also accepts some other, not widely useful, options.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/gmyth/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
     4.3 @@ -0,0 +1,23 @@
     4.4 +SUBDIRS= src pixmaps
     4.5 +
     4.6 +### all of the standard pc files we need to generate
     4.7 +pcfiles = gmyth-@GMYTH_MAJORMINOR@.pc
     4.8 +
     4.9 +all-local: $(pcfiles)
    4.10 +
    4.11 +### how to generate pc files
    4.12 +%-@GMYTH_MAJORMINOR@.pc: %.pc
    4.13 +	cp $< $@
    4.14 +
    4.15 +pkgconfigdir = $(libdir)/pkgconfig
    4.16 +pkgconfig_DATA = $(pcfiles)
    4.17 +
    4.18 +include aminclude.am
    4.19 +
    4.20 +EXTRA_DIST =                            \
    4.21 +        autogen.sh                      \
    4.22 +        gmyth.pc.in			\
    4.23 +        AUTHORS                         \
    4.24 +        COPYING                         \
    4.25 +        README
    4.26 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/gmyth/aminclude.am	Wed Sep 20 23:45:35 2006 +0100
     5.3 @@ -0,0 +1,186 @@
     5.4 +# Copyright (C) 2004 Oren Ben-Kiki
     5.5 +# This file is distributed under the same terms as the Automake macro files.
     5.6 +
     5.7 +# Generate automatic documentation using Doxygen. Goals and variables values
     5.8 +# are controlled by the various DX_COND_??? conditionals set by autoconf.
     5.9 +#
    5.10 +# The provided goals are:
    5.11 +# doxygen-doc: Generate all doxygen documentation.
    5.12 +# doxygen-run: Run doxygen, which will generate some of the documentation
    5.13 +#              (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post
    5.14 +#              processing required for the rest of it (PS, PDF, and some MAN).
    5.15 +# doxygen-man: Rename some doxygen generated man pages.
    5.16 +# doxygen-ps: Generate doxygen PostScript documentation.
    5.17 +# doxygen-pdf: Generate doxygen PDF documentation.
    5.18 +#
    5.19 +# Note that by default these are not integrated into the automake goals. If
    5.20 +# doxygen is used to generate man pages, you can achieve this integration by
    5.21 +# setting man3_MANS to the list of man pages generated and then adding the
    5.22 +# dependency:
    5.23 +#
    5.24 +#   $(man3_MANS): doxygen-doc
    5.25 +#
    5.26 +# This will cause make to run doxygen and generate all the documentation.
    5.27 +#
    5.28 +# The following variable is intended for use in Makefile.am:
    5.29 +#
    5.30 +# DX_CLEANFILES = everything to clean.
    5.31 +#
    5.32 +# This is usually added to MOSTLYCLEANFILES.
    5.33 +
    5.34 +## --------------------------------- ##
    5.35 +## Format-independent Doxygen rules. ##
    5.36 +## --------------------------------- ##
    5.37 +
    5.38 +if DX_COND_doc
    5.39 +
    5.40 +## ------------------------------- ##
    5.41 +## Rules specific for HTML output. ##
    5.42 +## ------------------------------- ##
    5.43 +
    5.44 +if DX_COND_html
    5.45 +
    5.46 +DX_CLEAN_HTML = @DX_DOCDIR@/html
    5.47 +
    5.48 +endif DX_COND_html
    5.49 +
    5.50 +## ------------------------------ ##
    5.51 +## Rules specific for CHM output. ##
    5.52 +## ------------------------------ ##
    5.53 +
    5.54 +if DX_COND_chm
    5.55 +
    5.56 +DX_CLEAN_CHM = @DX_DOCDIR@/chm
    5.57 +
    5.58 +if DX_COND_chi
    5.59 +
    5.60 +DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
    5.61 +
    5.62 +endif DX_COND_chi
    5.63 +
    5.64 +endif DX_COND_chm
    5.65 +
    5.66 +## ------------------------------ ##
    5.67 +## Rules specific for MAN output. ##
    5.68 +## ------------------------------ ##
    5.69 +
    5.70 +if DX_COND_man
    5.71 +
    5.72 +DX_CLEAN_MAN = @DX_DOCDIR@/man
    5.73 +
    5.74 +endif DX_COND_man
    5.75 +
    5.76 +## ------------------------------ ##
    5.77 +## Rules specific for RTF output. ##
    5.78 +## ------------------------------ ##
    5.79 +
    5.80 +if DX_COND_rtf
    5.81 +
    5.82 +DX_CLEAN_RTF = @DX_DOCDIR@/rtf
    5.83 +
    5.84 +endif DX_COND_rtf
    5.85 +
    5.86 +## ------------------------------ ##
    5.87 +## Rules specific for XML output. ##
    5.88 +## ------------------------------ ##
    5.89 +
    5.90 +if DX_COND_xml
    5.91 +
    5.92 +DX_CLEAN_XML = @DX_DOCDIR@/xml
    5.93 +
    5.94 +endif DX_COND_xml
    5.95 +
    5.96 +## ----------------------------- ##
    5.97 +## Rules specific for PS output. ##
    5.98 +## ----------------------------- ##
    5.99 +
   5.100 +if DX_COND_ps
   5.101 +
   5.102 +DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
   5.103 +
   5.104 +DX_PS_GOAL = doxygen-ps
   5.105 +
   5.106 +doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
   5.107 +
   5.108 +@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
   5.109 +	cd @DX_DOCDIR@/latex; \
   5.110 +	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
   5.111 +	$(DX_LATEX) refman.tex; \
   5.112 +	$(MAKEINDEX_PATH) refman.idx; \
   5.113 +	$(DX_LATEX) refman.tex; \
   5.114 +	countdown=5; \
   5.115 +	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
   5.116 +	                  refman.log > /dev/null 2>&1 \
   5.117 +	   && test $$countdown -gt 0; do \
   5.118 +	    $(DX_LATEX) refman.tex; \
   5.119 +	    countdown=`expr $$countdown - 1`; \
   5.120 +	done; \
   5.121 +	$(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
   5.122 +
   5.123 +endif DX_COND_ps
   5.124 +
   5.125 +## ------------------------------ ##
   5.126 +## Rules specific for PDF output. ##
   5.127 +## ------------------------------ ##
   5.128 +
   5.129 +if DX_COND_pdf
   5.130 +
   5.131 +DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
   5.132 +
   5.133 +DX_PDF_GOAL = doxygen-pdf
   5.134 +
   5.135 +doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
   5.136 +
   5.137 +@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
   5.138 +	cd @DX_DOCDIR@/latex; \
   5.139 +	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
   5.140 +	$(DX_PDFLATEX) refman.tex; \
   5.141 +	$(DX_MAKEINDEX) refman.idx; \
   5.142 +	$(DX_PDFLATEX) refman.tex; \
   5.143 +	countdown=5; \
   5.144 +	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
   5.145 +	                  refman.log > /dev/null 2>&1 \
   5.146 +	   && test $$countdown -gt 0; do \
   5.147 +	    $(DX_PDFLATEX) refman.tex; \
   5.148 +	    countdown=`expr $$countdown - 1`; \
   5.149 +	done; \
   5.150 +	mv refman.pdf ../@PACKAGE@.pdf
   5.151 +
   5.152 +endif DX_COND_pdf
   5.153 +
   5.154 +## ------------------------------------------------- ##
   5.155 +## Rules specific for LaTeX (shared for PS and PDF). ##
   5.156 +## ------------------------------------------------- ##
   5.157 +
   5.158 +if DX_COND_latex
   5.159 +
   5.160 +DX_CLEAN_LATEX = @DX_DOCDIR@/latex
   5.161 +
   5.162 +endif DX_COND_latex
   5.163 +
   5.164 +.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
   5.165 +
   5.166 +.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
   5.167 +
   5.168 +doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
   5.169 +
   5.170 +doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
   5.171 +
   5.172 +@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
   5.173 +	rm -rf @DX_DOCDIR@
   5.174 +	$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
   5.175 +
   5.176 +DX_CLEANFILES = \
   5.177 +    @DX_DOCDIR@/@PACKAGE@.tag \
   5.178 +    -r \
   5.179 +    $(DX_CLEAN_HTML) \
   5.180 +    $(DX_CLEAN_CHM) \
   5.181 +    $(DX_CLEAN_CHI) \
   5.182 +    $(DX_CLEAN_MAN) \
   5.183 +    $(DX_CLEAN_RTF) \
   5.184 +    $(DX_CLEAN_XML) \
   5.185 +    $(DX_CLEAN_PS) \
   5.186 +    $(DX_CLEAN_PDF) \
   5.187 +    $(DX_CLEAN_LATEX)
   5.188 +
   5.189 +endif DX_COND_doc
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/gmyth/autogen.sh	Wed Sep 20 23:45:35 2006 +0100
     6.3 @@ -0,0 +1,99 @@
     6.4 +#!/bin/sh
     6.5 +# Run this to generate all the initial makefiles, etc.
     6.6 +
     6.7 +DIE=0
     6.8 +package=gmyth
     6.9 +srcfile=configure.ac
    6.10 +
    6.11 +# a quick cvs co if necessary to alleviate the pain - may remove this
    6.12 +# when developers get a clue ;)
    6.13 +if test ! -d common; 
    6.14 +then 
    6.15 +  echo "+ getting common/ from svn"
    6.16 + svn co common 
    6.17 +fi
    6.18 +
    6.19 +# source helper functions
    6.20 +if test ! -f common/autogen-helper.sh;
    6.21 +then
    6.22 +  echo There is something wrong with your source tree.
    6.23 +  echo You are missing common/autogen-helper.sh
    6.24 +  exit 1
    6.25 +fi
    6.26 +. common/autogen-helper.sh
    6.27 +
    6.28 +CONFIGURE_DEF_OPT='--enable-maintainer-mode'
    6.29 +
    6.30 +autogen_options 
    6.31 +
    6.32 +echo -n "+ check for build tools"
    6.33 +if test ! -z "$NOCHECK"; then echo " skipped"; else  echo; fi
    6.34 +version_check "autoconf" "$AUTOCONF autoconf autoconf-2.54 autoconf-2.53" \
    6.35 +              "ftp://ftp.gnu.org/pub/gnu/autoconf/" 2 53 || DIE=1
    6.36 +version_check "automake" "$AUTOMAKE automake automake-1.9 automake-1.8 automake-1.7 automake-1.6" \
    6.37 +              "ftp://ftp.gnu.org/pub/gnu/automake/" 1 6 || DIE=1
    6.38 +version_check "libtoolize" "$LIBTOOLIZE libtoolize" \
    6.39 +              "ftp://ftp.gnu.org/pub/gnu/libtool/" 1 5 0 || DIE=1
    6.40 +version_check "pkg-config" "" \
    6.41 +              "http://www.freedesktop.org/software/pkgconfig" 0 8 0 || DIE=1
    6.42 +
    6.43 +die_check $DIE
    6.44 +
    6.45 +aclocal_check || DIE=1
    6.46 +autoheader_check || DIE=1
    6.47 +
    6.48 +die_check $DIE
    6.49 +
    6.50 +# if no arguments specified then this will be printed
    6.51 +if test -z "$*"; then
    6.52 +  echo "+ checking for autogen.sh options"
    6.53 +  echo "  This autogen script will automatically run ./configure as:"
    6.54 +  echo "  ./configure $CONFIGURE_DEF_OPT"
    6.55 +  echo "  To pass any additional options, please specify them on the $0"
    6.56 +  echo "  command line."
    6.57 +fi
    6.58 +
    6.59 +toplevel_check $srcfile
    6.60 +
    6.61 +tool_run "$aclocal" "-I m4 $ACLOCAL_FLAGS"
    6.62 +tool_run "$libtoolize" "--copy --force"
    6.63 +tool_run "$autoheader"
    6.64 +
    6.65 +# touch the stamp-h.in build stamp so we don't re-run autoheader in maintainer mode -- wingo
    6.66 +echo timestamp > stamp-h.in 2> /dev/null
    6.67 +
    6.68 +tool_run "$autoconf"
    6.69 +tool_run "$automake" "-a -c"
    6.70 +
    6.71 +# if enable exists, add an -enable option for each of the lines in that file
    6.72 +if test -f enable; then
    6.73 +  for a in `cat enable`; do
    6.74 +    CONFIGURE_FILE_OPT="--enable-$a"
    6.75 +  done
    6.76 +fi
    6.77 +
    6.78 +# if disable exists, add an -disable option for each of the lines in that file
    6.79 +if test -f disable; then
    6.80 +  for a in `cat disable`; do
    6.81 +    CONFIGURE_FILE_OPT="$CONFIGURE_FILE_OPT --disable-$a"
    6.82 +  done
    6.83 +fi
    6.84 +
    6.85 +test -n "$NOCONFIGURE" && {
    6.86 +  echo "+ skipping configure stage for package $package, as requested."
    6.87 +  echo "+ autogen.sh done."
    6.88 +  exit 0
    6.89 +}
    6.90 +
    6.91 +echo "+ running configure ... "
    6.92 +test ! -z "$CONFIGURE_DEF_OPT" && echo "  ./configure default flags: $CONFIGURE_DEF_OPT"
    6.93 +test ! -z "$CONFIGURE_EXT_OPT" && echo "  ./configure external flags: $CONFIGURE_EXT_OPT"
    6.94 +test ! -z "$CONFIGURE_FILE_OPT" && echo "  ./configure enable/disable flags: $CONFIGURE_FILE_OPT"
    6.95 +echo
    6.96 +
    6.97 +./configure $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT $CONFIGURE_FILE_OPT || {
    6.98 +        echo "  configure failed"
    6.99 +        exit 1
   6.100 +}
   6.101 +
   6.102 +echo "Now type 'make' to compile $package."
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/gmyth/common/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
     7.3 @@ -0,0 +1,1 @@
     7.4 +EXTRA_DIST = autogen-helper.sh
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/gmyth/common/autogen-helper.sh	Wed Sep 20 23:45:35 2006 +0100
     8.3 @@ -0,0 +1,302 @@
     8.4 +# a silly hack that generates autoregen.sh but it's handy
     8.5 +echo "#!/bin/sh" > autoregen.sh
     8.6 +echo "./autogen.sh $@ \$@" >> autoregen.sh
     8.7 +chmod +x autoregen.sh
     8.8 +
     8.9 +# helper functions for autogen.sh
    8.10 +
    8.11 +debug ()
    8.12 +# print out a debug message if DEBUG is a defined variable
    8.13 +{
    8.14 +  if test ! -z "$DEBUG"
    8.15 +  then
    8.16 +    echo "DEBUG: $1"
    8.17 +  fi
    8.18 +}
    8.19 +
    8.20 +version_check ()
    8.21 +# check the version of a package
    8.22 +# first argument : package name (executable)
    8.23 +# second argument : optional path where to look for it instead
    8.24 +# third argument : source download url
    8.25 +# rest of arguments : major, minor, micro version
    8.26 +# all consecutive ones : suggestions for binaries to use
    8.27 +# (if not specified in second argument)
    8.28 +{
    8.29 +  PACKAGE=$1
    8.30 +  PKG_PATH=$2
    8.31 +  URL=$3
    8.32 +  MAJOR=$4
    8.33 +  MINOR=$5
    8.34 +  MICRO=$6
    8.35 +
    8.36 +  # for backwards compatibility, we let PKG_PATH=PACKAGE when PKG_PATH null
    8.37 +  if test -z "$PKG_PATH"; then PKG_PATH=$PACKAGE; fi
    8.38 +  debug "major $MAJOR minor $MINOR micro $MICRO"
    8.39 +  VERSION=$MAJOR
    8.40 +  if test ! -z "$MINOR"; then VERSION=$VERSION.$MINOR; else MINOR=0; fi
    8.41 +  if test ! -z "$MICRO"; then VERSION=$VERSION.$MICRO; else MICRO=0; fi
    8.42 +
    8.43 +  debug "major $MAJOR minor $MINOR micro $MICRO"
    8.44 +  
    8.45 +  for SUGGESTION in $PKG_PATH; do 
    8.46 +    COMMAND="$SUGGESTION"
    8.47 +
    8.48 +    # don't check if asked not to
    8.49 +    test -z "$NOCHECK" && {
    8.50 +      echo -n "  checking for $COMMAND >= $VERSION ... "
    8.51 +    } || {
    8.52 +      # we set a var with the same name as the package, but stripped of
    8.53 +      # unwanted chars
    8.54 +      VAR=`echo $PACKAGE | sed 's/-//g'`
    8.55 +      debug "setting $VAR"
    8.56 +      eval $VAR="$COMMAND"
    8.57 +      return 0
    8.58 +    }
    8.59 +
    8.60 +    debug "checking version with $COMMAND"
    8.61 +    ($COMMAND --version) < /dev/null > /dev/null 2>&1 || 
    8.62 +    {
    8.63 +      echo "not found."
    8.64 +      continue
    8.65 +    }
    8.66 +    # strip everything that's not a digit, then use cut to get the first field
    8.67 +    pkg_version=`$COMMAND --version|head -n 1|sed 's/^[^0-9]*//'|cut -d' ' -f1`
    8.68 +    debug "pkg_version $pkg_version"
    8.69 +    # remove any non-digit characters from the version numbers to permit numeric
    8.70 +    # comparison
    8.71 +    pkg_major=`echo $pkg_version | cut -d. -f1 | sed s/[a-zA-Z\-].*//g`
    8.72 +    pkg_minor=`echo $pkg_version | cut -d. -f2 | sed s/[a-zA-Z\-].*//g`
    8.73 +    pkg_micro=`echo $pkg_version | cut -d. -f3 | sed s/[a-zA-Z\-].*//g`
    8.74 +    test -z "$pkg_major" && pkg_major=0
    8.75 +    test -z "$pkg_minor" && pkg_minor=0
    8.76 +    test -z "$pkg_micro" && pkg_micro=0
    8.77 +    debug "found major $pkg_major minor $pkg_minor micro $pkg_micro"
    8.78 +
    8.79 +    #start checking the version
    8.80 +    debug "version check"
    8.81 +
    8.82 +    # reset check
    8.83 +    WRONG=
    8.84 +
    8.85 +    if [ ! "$pkg_major" -gt "$MAJOR" ]; then
    8.86 +      debug "major: $pkg_major <= $MAJOR"
    8.87 +      if [ "$pkg_major" -lt "$MAJOR" ]; then
    8.88 +        debug "major: $pkg_major < $MAJOR"
    8.89 +        WRONG=1
    8.90 +      elif [ ! "$pkg_minor" -gt "$MINOR" ]; then
    8.91 +        debug "minor: $pkg_minor <= $MINOR"
    8.92 +        if [ "$pkg_minor" -lt "$MINOR" ]; then
    8.93 +          debug "minor: $pkg_minor < $MINOR"
    8.94 +          WRONG=1
    8.95 +        elif [ "$pkg_micro" -lt "$MICRO" ]; then
    8.96 +          debug "micro: $pkg_micro < $MICRO"
    8.97 +	  WRONG=1
    8.98 +        fi
    8.99 +      fi
   8.100 +    fi
   8.101 +
   8.102 +    if test ! -z "$WRONG"; then
   8.103 +      echo "found $pkg_version, not ok !"
   8.104 +      continue
   8.105 +    else
   8.106 +      echo "found $pkg_version, ok."
   8.107 +      # we set a var with the same name as the package, but stripped of
   8.108 +      # unwanted chars
   8.109 +      VAR=`echo $PACKAGE | sed 's/-//g'`
   8.110 +      debug "setting $VAR"
   8.111 +      eval $VAR="$COMMAND"
   8.112 +      return 0
   8.113 +    fi
   8.114 +  done
   8.115 +
   8.116 +  echo "not found !"
   8.117 +  echo "You must have $PACKAGE installed to compile $package."
   8.118 +  echo "Download the appropriate package for your distribution,"
   8.119 +  echo "or get the source tarball at $URL"
   8.120 +  return 1;
   8.121 +}
   8.122 +
   8.123 +aclocal_check ()
   8.124 +{
   8.125 +  # normally aclocal is part of automake
   8.126 +  # so we expect it to be in the same place as automake
   8.127 +  # so if a different automake is supplied, we need to adapt as well
   8.128 +  # so how's about replacing automake with aclocal in the set var,
   8.129 +  # and saving that in $aclocal ?
   8.130 +  # note, this will fail if the actual automake isn't called automake*
   8.131 +  # or if part of the path before it contains it
   8.132 +  if [ -z "$automake" ]; then
   8.133 +    echo "Error: no automake variable set !"
   8.134 +    return 1
   8.135 +  else
   8.136 +    aclocal=`echo $automake | sed s/automake/aclocal/`
   8.137 +    debug "aclocal: $aclocal"
   8.138 +    if [ "$aclocal" != "aclocal" ];
   8.139 +    then
   8.140 +      CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-aclocal=$aclocal"
   8.141 +    fi
   8.142 +    if [ ! -x `which $aclocal` ]; then
   8.143 +      echo "Error: cannot execute $aclocal !"
   8.144 +      return 1
   8.145 +    fi
   8.146 +  fi
   8.147 +}
   8.148 +
   8.149 +autoheader_check ()
   8.150 +{
   8.151 +  # same here - autoheader is part of autoconf
   8.152 +  # use the same voodoo
   8.153 +  if [ -z "$autoconf" ]; then
   8.154 +    echo "Error: no autoconf variable set !"
   8.155 +    return 1
   8.156 +  else
   8.157 +    autoheader=`echo $autoconf | sed s/autoconf/autoheader/`
   8.158 +    debug "autoheader: $autoheader"
   8.159 +    if [ "$autoheader" != "autoheader" ];
   8.160 +    then
   8.161 +      CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoheader=$autoheader"
   8.162 +    fi
   8.163 +    if [ ! -x `which $autoheader` ]; then
   8.164 +      echo "Error: cannot execute $autoheader !"
   8.165 +      return 1
   8.166 +    fi
   8.167 +  fi
   8.168 +
   8.169 +}
   8.170 +
   8.171 +autoconf_2_52d_check ()
   8.172 +{
   8.173 +  # autoconf 2.52d has a weird issue involving a yes:no error
   8.174 +  # so don't allow it's use
   8.175 +  test -z "$NOCHECK" && {
   8.176 +    ac_version=`$autoconf --version|head -n 1|sed 's/^[a-zA-Z\.\ ()]*//;s/ .*$//'`
   8.177 +    if test "$ac_version" = "2.52d"; then
   8.178 +      echo "autoconf 2.52d has an issue with our current build."
   8.179 +      echo "We don't know who's to blame however.  So until we do, get a"
   8.180 +      echo "regular version.  RPM's of a working version are on the gstreamer site."
   8.181 +      exit 1
   8.182 +    fi
   8.183 +  }
   8.184 +  return 0
   8.185 +}
   8.186 +
   8.187 +die_check ()
   8.188 +{
   8.189 +  # call with $DIE
   8.190 +  # if set to 1, we need to print something helpful then die
   8.191 +  DIE=$1
   8.192 +  if test "x$DIE" = "x1";
   8.193 +  then
   8.194 +    echo
   8.195 +    echo "- Please get the right tools before proceeding."
   8.196 +    echo "- Alternatively, if you're sure we're wrong, run with --nocheck."
   8.197 +    exit 1
   8.198 +  fi
   8.199 +}
   8.200 +
   8.201 +autogen_options ()
   8.202 +{
   8.203 +  if test "x$1" = "x"; then
   8.204 +    return 0
   8.205 +  fi
   8.206 +
   8.207 +  while test "x$1" != "x" ; do
   8.208 +    optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
   8.209 +    case "$1" in
   8.210 +      --noconfigure)
   8.211 +          NOCONFIGURE=defined
   8.212 +	  AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --noconfigure"
   8.213 +          echo "+ configure run disabled"
   8.214 +          shift
   8.215 +          ;;
   8.216 +      --nocheck)
   8.217 +	  AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --nocheck"
   8.218 +          NOCHECK=defined
   8.219 +          echo "+ autotools version check disabled"
   8.220 +          shift
   8.221 +          ;;
   8.222 +      --debug)
   8.223 +          DEBUG=defined
   8.224 +	  AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --debug"
   8.225 +          echo "+ debug output enabled"
   8.226 +          shift
   8.227 +          ;;
   8.228 +      --prefix=*)
   8.229 +	  CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$optarg"
   8.230 +	  echo "+ passing --prefix=$optarg to configure"
   8.231 +          shift
   8.232 +          ;;
   8.233 +      --prefix)
   8.234 +	  shift
   8.235 +	  echo "DEBUG: $1"
   8.236 +	  CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$1"
   8.237 +	  echo "+ passing --prefix=$1 to configure"
   8.238 +          shift
   8.239 +          ;;
   8.240 +      -h|--help)
   8.241 +          echo "autogen.sh (autogen options) -- (configure options)"
   8.242 +          echo "autogen.sh help options: "
   8.243 +          echo " --noconfigure            don't run the configure script"
   8.244 +          echo " --nocheck                don't do version checks"
   8.245 +          echo " --debug                  debug the autogen process"
   8.246 +	  echo " --prefix		  will be passed on to configure"
   8.247 +          echo
   8.248 +          echo " --with-autoconf PATH     use autoconf in PATH"
   8.249 +          echo " --with-automake PATH     use automake in PATH"
   8.250 +          echo
   8.251 +          echo "to pass options to configure, put them as arguments after -- "
   8.252 +	  exit 1
   8.253 +          ;;
   8.254 +      --with-automake=*)
   8.255 +          AUTOMAKE=$optarg
   8.256 +          echo "+ using alternate automake in $optarg"
   8.257 +	  CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-automake=$AUTOMAKE"
   8.258 +          shift
   8.259 +          ;;
   8.260 +      --with-autoconf=*)
   8.261 +          AUTOCONF=$optarg
   8.262 +          echo "+ using alternate autoconf in $optarg"
   8.263 +	  CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoconf=$AUTOCONF"
   8.264 +          shift
   8.265 +          ;;
   8.266 +      --disable*|--enable*|--with*)
   8.267 +          echo "+ passing option $1 to configure"
   8.268 +	  CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $1"
   8.269 +          shift
   8.270 +          ;;
   8.271 +       --) shift ; break ;;
   8.272 +      *) echo "- ignoring unknown autogen.sh argument $1"; shift ;;
   8.273 +    esac
   8.274 +  done
   8.275 +
   8.276 +  for arg do CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $arg"; done
   8.277 +  if test ! -z "$CONFIGURE_EXT_OPT"
   8.278 +  then
   8.279 +    echo "+ options passed to configure: $CONFIGURE_EXT_OPT"
   8.280 +  fi
   8.281 +}
   8.282 +
   8.283 +toplevel_check ()
   8.284 +{
   8.285 +  srcfile=$1
   8.286 +  test -f $srcfile || {
   8.287 +        echo "You must run this script in the top-level $package directory"
   8.288 +        exit 1
   8.289 +  }
   8.290 +}
   8.291 +
   8.292 +
   8.293 +tool_run ()
   8.294 +{
   8.295 +  tool=$1
   8.296 +  options=$2
   8.297 +  run_if_fail=$3
   8.298 +  echo "+ running $tool $options..."
   8.299 +  $tool $options || {
   8.300 +    echo
   8.301 +    echo $tool failed
   8.302 +    eval $run_if_fail
   8.303 +    exit 1
   8.304 +  }
   8.305 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/gmyth/configure.ac	Wed Sep 20 23:45:35 2006 +0100
     9.3 @@ -0,0 +1,224 @@
     9.4 +#                                               -*- Autoconf -*-
     9.5 +# Process this file with autoconf to produce a configure script.
     9.6 +
     9.7 +AC_PREREQ(2.50)
     9.8 +
     9.9 +AC_INIT([gmyth],[0.1])
    9.10 +
    9.11 +dnl AC_CONFIG_SRCDIR([src/mmyth_main.c])
    9.12 +AC_CONFIG_HEADER(config.h)
    9.13 +
    9.14 +dnl when going to/from release please set the nano (fourth number) right !
    9.15 +dnl releases only do Wall, SVN and prerelease does Werror too
    9.16 +AS_VERSION(gmyth, GMYTH, 0, 1, 0, 3, GMYTH_SVN="no", GMYTH_SVN="yes")
    9.17 +
    9.18 +GMYTH_MAJORMINOR=$GMYTH_MAJOR_VERSION.$GMYTH_MINOR_VERSION
    9.19 +
    9.20 +AC_SUBST(GMYTH_MAJORMINOR)
    9.21 +
    9.22 +dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode
    9.23 +AM_MAINTAINER_MODE
    9.24 +dnl make aclocal work in maintainer mode
    9.25 +AC_SUBST(ACLOCAL_AMFLAGS, "-I m4")
    9.26 +
    9.27 +# Checks for programs.
    9.28 +# check for tools
    9.29 +# Make sure CFLAGS is defined to stop AC_PROC_CC adding -g
    9.30 +CFLAGS="$CFLAGS -Wall"
    9.31 +AC_PROG_CC
    9.32 +AC_PROG_LIBTOOL
    9.33 +
    9.34 +dnl Generate doxygen documentation
    9.35 +DX_HTML_FEATURE(ON)
    9.36 +DX_CHM_FEATURE(OFF)
    9.37 +DX_CHI_FEATURE(OFF)
    9.38 +DX_MAN_FEATURE(OFF)
    9.39 +DX_RTF_FEATURE(OFF)
    9.40 +DX_XML_FEATURE(OFF)
    9.41 +DX_PDF_FEATURE(OFF)
    9.42 +DX_PS_FEATURE(OFF)
    9.43 +DX_INIT_DOXYGEN(gmyth, doxygen.cfg, docs)
    9.44 +
    9.45 +
    9.46 +# Checks for libraries.
    9.47 +
    9.48 +# Checks for header files.
    9.49 +AC_HEADER_STDC
    9.50 +AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h unistd.h])
    9.51 +
    9.52 +# Checks for typedefs, structures, and compiler characteristics.
    9.53 +AC_C_CONST
    9.54 +AC_TYPE_PID_T
    9.55 +AC_STRUCT_TM
    9.56 +
    9.57 +# Checks for library functions.
    9.58 +AC_FUNC_FORK
    9.59 +AC_PROG_GCC_TRADITIONAL
    9.60 +AC_FUNC_MALLOC
    9.61 +AC_FUNC_MKTIME
    9.62 +AC_FUNC_VPRINTF
    9.63 +AC_CHECK_FUNCS([memset socket stime strstr strtoul])
    9.64 +
    9.65 +AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
    9.66 +
    9.67 +# Checks required packages
    9.68 +
    9.69 +dnl Test if --disable-debug given
    9.70 +AC_ARG_ENABLE(debug,
    9.71 +	[AC_HELP_STRING([--disable-debug], [disable debugging mode])],
    9.72 +	enable_debug="$enableval",
    9.73 +	enable_debug=yes)
    9.74 +
    9.75 +if test "x$enable_debug" = "xyes" ; then
    9.76 +      CFLAGS="$CFLAGS -g"
    9.77 +else
    9.78 +      AC_DEFINE( NDEBUG, 1, [disable debug messages] )
    9.79 +      CFLAGS="$CFLAGS -O2 -DG_DISABLE_CHECKS -DNDEBUG"
    9.80 +fi          
    9.81 +
    9.82 +AM_CONDITIONAL( NDEBUG, test "x$enable_debug" = "xyes" )
    9.83 +
    9.84 +# Check for pkgconfig
    9.85 +AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, yes, no)
    9.86 +# Give error and exit if we don't have pkgconfig
    9.87 +if test "x$HAVE_PKGCONFIG" = "xno"; then
    9.88 +  AC_MSG_ERROR(you need to have pkgconfig installed !)
    9.89 +fi
    9.90 +
    9.91 +# Check for Glib2.0
    9.92 +PKG_CHECK_MODULES(GLIB, glib-2.0, HAVE_GLIB=yes,HAVE_GLIB=no)
    9.93 +
    9.94 +# Give error and exit if we don't have glib
    9.95 +if test "x$HAVE_GLIB" = "xno"; then
    9.96 +  AC_MSG_ERROR(you need glib-2.0 installed)
    9.97 +fi
    9.98 +
    9.99 +# make GLIB_CFLAGS and GLIB_LIBS available
   9.100 +AC_SUBST(GLIB_CFLAGS)
   9.101 +AC_SUBST(GLIB_LIBS)
   9.102 +
   9.103 +# Check for GObject2.0
   9.104 +PKG_CHECK_MODULES(GOBJECT,
   9.105 +  gobject-2.0,
   9.106 +  HAVE_GOBJECT=yes, HAVE_GOBJECT=no)
   9.107 +
   9.108 +# Give error and exit if we don't have gobject
   9.109 +if test "x$HAVE_GOBJECT" = "xno"; then
   9.110 +  AC_MSG_ERROR(you need gobject-2.0 installed)
   9.111 +fi
   9.112 +
   9.113 +# make GOBJECT_CFLAGS and GOBJECT_LIBS available
   9.114 +AC_SUBST(GOBJECT_CFLAGS)
   9.115 +AC_SUBST(GOBJECT_LIBS)
   9.116 +
   9.117 +# Check for GTK+-2.0
   9.118 +PKG_CHECK_MODULES(GTK, gtk+-2.0, HAVE_GTK=yes,HAVE_GTK=no)
   9.119 +
   9.120 +# Give error and exit if we don't have gtk
   9.121 +if test "x$HAVE_GTK" = "xyes"; then
   9.122 +  AC_DEFINE(WITH_GTK, 1, [build with GTK+ related stuff])
   9.123 +  dnl AC_MSG_ERROR(you need gtk+-2.0 installed)
   9.124 +else
   9.125 +  AC_MSG_RESULT(no)
   9.126 +fi
   9.127 +
   9.128 +AM_CONDITIONAL(WITH_GTK, test "x$HAVE_GTK" = "xyes" )
   9.129 +
   9.130 +# make GTK_CFLAGS and GTK_LIBS available
   9.131 +AC_SUBST(GTK_CFLAGS)
   9.132 +AC_SUBST(GTK_LIBS)
   9.133 +
   9.134 +dnl ========== Check for Hildon Libraries
   9.135 +PKG_CHECK_MODULES(HILDON,
   9.136 +  hildon-lgpl libosso hildon-status-bar-lib libhildonmenu hildon-base-lib hildon-control-panel hildon-libs,
   9.137 +  HAVE_HILDON=yes, HAVE_HILDON=no)
   9.138 +
   9.139 +if test "x$HAVE_HILDON" = "xyes"; then
   9.140 +  AC_DEFINE(MAEMO_PLATFORM, 1, [build with hildon libs])
   9.141 +  HILDON_CFLAGS="$HILDON_CFLAGS -DMAEMO_PLATFORM=1"
   9.142 +else
   9.143 +  AC_MSG_RESULT(no)
   9.144 +fi
   9.145 +
   9.146 +AM_CONDITIONAL(MAEMO_PLATFORM, test "x$HAVE_HILDON" = "xyes")
   9.147 +
   9.148 +dnl make HILDON_CFLAGS and HILDON_LIBS available
   9.149 +AC_SUBST(HILDON_CFLAGS)
   9.150 +AC_SUBST(HILDON_LIBS)
   9.151 +
   9.152 +# Check for libxml-2.0
   9.153 +PKG_CHECK_MODULES(LIBXML, libxml-2.0, HAVE_LIBXML=yes,HAVE_LIBXML=no)
   9.154 +
   9.155 +# Give error and exit if we don't have gtk
   9.156 +if test "x$HAVE_LIBXML" = "xno"; then
   9.157 +  AC_MSG_ERROR(you need libxml-2.0 installed)
   9.158 +fi
   9.159 +
   9.160 +# make LIBXML_CFLAGS and LIBXML_LIBS available
   9.161 +AC_SUBST(LIBXML_CFLAGS)
   9.162 +AC_SUBST(LIBXML_LIBS)
   9.163 +
   9.164 +
   9.165 +# check for gstreamer development files
   9.166 +GST_REQUIRED=0.10
   9.167 +GST_MAJORMINOR=0.10
   9.168 +PKG_CHECK_MODULES(GST, \
   9.169 +  gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED,
   9.170 +  HAVE_GST=yes, HAVE_GST=no)
   9.171 +
   9.172 +# Give error and exit if we don't have gstreamer
   9.173 +if test "x$HAVE_GST" = "xno"; then
   9.174 +  AC_MSG_ERROR(you need gstreamer development packages installed !)
   9.175 +fi
   9.176 +
   9.177 +# make GST_CFLAGS and GST_LIBS available
   9.178 +AC_SUBST(GST_CFLAGS)
   9.179 +AC_SUBST(GST_LIBS)
   9.180 +
   9.181 +# check for gstreamer-base plugins (xoverlay interface)
   9.182 +GSTBASE_REQUIRED=0.10
   9.183 +GSTBASE_MAJORMINOR=0.10
   9.184 +PKG_CHECK_MODULES(GSTBASE, \
   9.185 +  gstreamer-base-$GSTBASE_MAJORMINOR >= $GSTBASE_REQUIRED,
   9.186 +  HAVE_GSTBASE=yes, HAVE_GSTBASE=no)
   9.187 +
   9.188 +# Give error and exit if we don't have gstreamer base libraries
   9.189 +if test "x$HAVE_GSTBASE" = "xno"; then
   9.190 +  AC_MSG_ERROR(you need gstreamer base development packages installed !)
   9.191 +fi
   9.192 +
   9.193 +# make GSTBASE_CFLAGS and GSTBASE_LIBS available
   9.194 +AC_SUBST(GSTBASE_CFLAGS)
   9.195 +AC_SUBST(GSTBASE_LIBS)
   9.196 +
   9.197 +
   9.198 +# make GST_MAJORMINOR available in Makefile.am
   9.199 +AC_SUBST(GST_MAJORMINOR)
   9.200 +
   9.201 +#
   9.202 +# mysql libraries
   9.203 +#
   9.204 +AC_CHECK_PROG(MYSQL_CFLAGS,mysql_config,`mysql_config --cflags`)
   9.205 +if test -z "$MYSQL_CFLAGS"; then 
   9.206 +        AC_MSG_ERROR([Could not find mysql_config script. Make sure the mysql client libraries are installed])
   9.207 +fi
   9.208 +AC_SUBST(MYSQL_CFLAGS)
   9.209 +
   9.210 +
   9.211 +AC_CHECK_PROG(MYSQL_LIBS,mysql_config,`mysql_config --libs`)
   9.212 +if test -z "$MYSQL_LIBS"; then 
   9.213 +        AC_MSG_ERROR([Could not find mysql_config script. Make sure the mysql client libraries are installed])
   9.214 +fi
   9.215 +AC_SUBST(MYSQL_LIBS)
   9.216 +
   9.217 +#dnl Enable gtk-doc
   9.218 +#GTK_DOC_CHECK(1.4)
   9.219 +
   9.220 +
   9.221 +AC_CONFIG_FILES([Makefile
   9.222 +                pixmaps/Makefile
   9.223 +                src/Makefile
   9.224 +                src/libgmyth/Makefile
   9.225 +                src/gui/Makefile
   9.226 +		gmyth.pc])
   9.227 +AC_OUTPUT
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/gmyth/data/settings/history.dat	Wed Sep 20 23:45:35 2006 +0100
    10.3 @@ -0,0 +1,3 @@
    10.4 +# MIPTV history file
    10.5 +# Stores the last network frequency used
    10.6 +602000000
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/gmyth/debian/changelog	Wed Sep 20 23:45:35 2006 +0100
    11.3 @@ -0,0 +1,6 @@
    11.4 +mmyth (0.1-indt1) unstable; urgency=low
    11.5 +
    11.6 +  * Initial Maemo Package.
    11.7 +
    11.8 + -- Hallyson Melo <hallyson.melo@indt.org.br>  Fri, 15 Sep 2006 10:26:16 -0300
    11.9 +
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/gmyth/debian/compat	Wed Sep 20 23:45:35 2006 +0100
    12.3 @@ -0,0 +1,1 @@
    12.4 +4
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/gmyth/debian/control	Wed Sep 20 23:45:35 2006 +0100
    13.3 @@ -0,0 +1,17 @@
    13.4 +Source: mmyth 
    13.5 +Section: user/accessories
    13.6 +Priority: optional
    13.7 +Maintainer: Hallyson Melo <hallyson.melo@indt.org.br> 
    13.8 +Build-Depends: debhelper, libgtk2.0-dev (>= 2.4.0),
    13.9 + libosso-dev, hildon-libs-dev, hildon-fm-dev
   13.10 +Standards-Version: 3.6.2
   13.11 +
   13.12 +Package: mmyth
   13.13 +Architecture: any
   13.14 +Depends: ${shlibs:Depends}, ${misc:Depends}, maemo-select-menu-location
   13.15 +Provides: MythTV
   13.16 +Description: MythTV frontend
   13.17 + NONONONONONONONONONONONONONONONONO
   13.18 + NONONONONONONONONONONo
   13.19 + .
   13.20 + NONNONONONON
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/gmyth/debian/control.in	Wed Sep 20 23:45:35 2006 +0100
    14.3 @@ -0,0 +1,17 @@
    14.4 +Source: mmyth 
    14.5 +Section: user/accessories
    14.6 +Priority: optional
    14.7 +Maintainer: Hallyson Melo <hallyson.melo@indt.org.br> 
    14.8 +Build-Depends: debhelper, libgtk2.0-dev (>= 2.4.0),
    14.9 + libosso-dev, hildon-libs-dev, hildon-fm-dev
   14.10 +Standards-Version: 3.6.2
   14.11 +
   14.12 +Package: mmyth
   14.13 +Architecture: any
   14.14 +Depends: ${shlibs:Depends}, ${misc:Depends}, maemo-select-menu-location
   14.15 +Provides: MythTV
   14.16 +Description: MythTV frontend
   14.17 + NONONONONONONONONONONONONONONONONO
   14.18 + NONONONONONONONONONONo
   14.19 + .
   14.20 + NONNONONONON
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/gmyth/debian/mmyth.desktop	Wed Sep 20 23:45:35 2006 +0100
    15.3 @@ -0,0 +1,10 @@
    15.4 +[Desktop Entry]
    15.5 +Encoding=UTF-8
    15.6 +Version=0.1
    15.7 +Type=Application
    15.8 +Name=Maemo Myth
    15.9 +Exec=/usr/bin/mmyth
   15.10 +Terminal=false
   15.11 +X-HildonDesk-ShowInToolbar=true
   15.12 +X-Osso-Type=application/x-executable
   15.13 +StartupWMClass=mmyth
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/gmyth/debian/mmyth.dirs	Wed Sep 20 23:45:35 2006 +0100
    16.3 @@ -0,0 +1,3 @@
    16.4 +usr/share/pixmaps
    16.5 +usr/share/applications/hildon
    16.6 +usr/share/dbus-1/services
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/gmyth/debian/mmyth.postinst	Wed Sep 20 23:45:35 2006 +0100
    17.3 @@ -0,0 +1,5 @@
    17.4 +#! /bin/sh
    17.5 +
    17.6 +maemo-select-menu-location mmyth.desktop tana_fi_extras
    17.7 +
    17.8 +exit 0
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/gmyth/debian/mmyth.service	Wed Sep 20 23:45:35 2006 +0100
    18.3 @@ -0,0 +1,3 @@
    18.4 +[D-BUS Service]
    18.5 +Name=com.nokia.xournal
    18.6 +Exec=/usr/bin/xournal
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/gmyth/debian/rules	Wed Sep 20 23:45:35 2006 +0100
    19.3 @@ -0,0 +1,15 @@
    19.4 +#!/usr/bin/make -f
    19.5 +# -*- mode: makefile; coding: utf-8 -*-
    19.6 +
    19.7 +include /usr/share/cdbs/1/rules/debhelper.mk
    19.8 +include /usr/share/cdbs/1/class/gnome.mk
    19.9 +include /usr/share/cdbs/1/rules/simple-patchsys.mk
   19.10 +include /usr/share/gnome-pkg-tools/1/rules/uploaders.mk
   19.11 +
   19.12 +DEB_CONFIGURE_EXTRA_FLAGS := --prefix=/usr
   19.13 +
   19.14 +binary-install/mmyth::
   19.15 +#	/usr/bin/install -p -m 644 debian/mmyth.png `pwd`/debian/mmyth/usr/share/pixmaps
   19.16 +	/usr/bin/install -p -m 644 debian/mmyth.desktop `pwd`/debian/mmyth/usr/share/applications/hildon
   19.17 +#	/usr/bin/install -p -m 644 debian/mmyth.service `pwd`/debian/mmyth/usr/share/dbus-1/services
   19.18 +
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/gmyth/doxygen.cfg	Wed Sep 20 23:45:35 2006 +0100
    20.3 @@ -0,0 +1,212 @@
    20.4 +# Doxyfile 1.4.2
    20.5 +
    20.6 +#---------------------------------------------------------------------------
    20.7 +# Project related configuration options
    20.8 +#---------------------------------------------------------------------------
    20.9 +PROJECT_NAME           = $(PROJECT)-$(VERSION)
   20.10 +PROJECT_NUMBER         = 
   20.11 +OUTPUT_DIRECTORY       = $(DOCDIR)
   20.12 +CREATE_SUBDIRS         = NO
   20.13 +OUTPUT_LANGUAGE        = English
   20.14 +USE_WINDOWS_ENCODING   = NO
   20.15 +BRIEF_MEMBER_DESC      = YES
   20.16 +REPEAT_BRIEF           = YES
   20.17 +ABBREVIATE_BRIEF       = YES
   20.18 +ALWAYS_DETAILED_SEC    = NO
   20.19 +INLINE_INHERITED_MEMB  = NO
   20.20 +STRIP_FROM_INC_PATH    = $(SRCDIR)/src/libgmyth
   20.21 +FULL_PATH_NAMES        = YES
   20.22 +STRIP_FROM_PATH        = $(SRCDIR)/src/libgmyth
   20.23 +SHORT_NAMES            = YES
   20.24 +JAVADOC_AUTOBRIEF      = YES
   20.25 +MULTILINE_CPP_IS_BRIEF = NO
   20.26 +DETAILS_AT_TOP         = YES
   20.27 +INHERIT_DOCS           = YES
   20.28 +DISTRIBUTE_GROUP_DOC   = NO
   20.29 +TAB_SIZE               = 8
   20.30 +ALIASES                = 
   20.31 +OPTIMIZE_OUTPUT_FOR_C  = YES
   20.32 +OPTIMIZE_OUTPUT_JAVA   = NO
   20.33 +SUBGROUPING            = YES
   20.34 +#---------------------------------------------------------------------------
   20.35 +# Build related configuration options
   20.36 +#---------------------------------------------------------------------------
   20.37 +EXTRACT_ALL            = YES
   20.38 +EXTRACT_PRIVATE        = NO
   20.39 +EXTRACT_STATIC         = NO
   20.40 +EXTRACT_LOCAL_CLASSES  = YES
   20.41 +EXTRACT_LOCAL_METHODS  = YES
   20.42 +HIDE_UNDOC_MEMBERS     = NO
   20.43 +HIDE_UNDOC_CLASSES     = NO
   20.44 +HIDE_FRIEND_COMPOUNDS  = NO
   20.45 +HIDE_IN_BODY_DOCS      = NO
   20.46 +INTERNAL_DOCS          = NO
   20.47 +CASE_SENSE_NAMES       = NO
   20.48 +HIDE_SCOPE_NAMES       = NO
   20.49 +SHOW_INCLUDE_FILES     = YES
   20.50 +INLINE_INFO            = YES
   20.51 +SORT_MEMBER_DOCS       = YES
   20.52 +SORT_BRIEF_DOCS        = NO
   20.53 +SORT_BY_SCOPE_NAME     = NO
   20.54 +GENERATE_TODOLIST      = YES
   20.55 +GENERATE_TESTLIST      = YES
   20.56 +GENERATE_BUGLIST       = YES
   20.57 +GENERATE_DEPRECATEDLIST= YES
   20.58 +ENABLED_SECTIONS       = 
   20.59 +MAX_INITIALIZER_LINES  = 30
   20.60 +SHOW_USED_FILES        = YES
   20.61 +#---------------------------------------------------------------------------
   20.62 +# configuration options related to warning and progress messages
   20.63 +#---------------------------------------------------------------------------
   20.64 +QUIET                  = YES
   20.65 +WARNINGS               = YES
   20.66 +WARN_IF_UNDOCUMENTED   = YES
   20.67 +WARN_IF_DOC_ERROR      = YES
   20.68 +WARN_FORMAT            = "$file:$line: $text"
   20.69 +WARN_LOGFILE           = 
   20.70 +#---------------------------------------------------------------------------
   20.71 +# configuration options related to the input files
   20.72 +#---------------------------------------------------------------------------
   20.73 +INPUT                  = $(SRCDIR)/src/libgmyth
   20.74 +FILE_PATTERNS          = *.c *.h
   20.75 +RECURSIVE              = YES
   20.76 +EXCLUDE                = 
   20.77 +EXCLUDE_SYMLINKS       = NO
   20.78 +EXCLUDE_PATTERNS       = 
   20.79 +EXAMPLE_PATH           = $(SRCDIR)/src/gui
   20.80 +EXAMPLE_PATTERNS       = 
   20.81 +EXAMPLE_RECURSIVE      = NO
   20.82 +IMAGE_PATH             = 
   20.83 +INPUT_FILTER           = 
   20.84 +FILTER_SOURCE_FILES    = NO
   20.85 +#---------------------------------------------------------------------------
   20.86 +# configuration options related to source browsing
   20.87 +#---------------------------------------------------------------------------
   20.88 +SOURCE_BROWSER         = YES
   20.89 +INLINE_SOURCES         = NO
   20.90 +STRIP_CODE_COMMENTS    = YES
   20.91 +REFERENCED_BY_RELATION = YES
   20.92 +REFERENCES_RELATION    = YES
   20.93 +VERBATIM_HEADERS       = YES
   20.94 +#---------------------------------------------------------------------------
   20.95 +# configuration options related to the alphabetical class index
   20.96 +#---------------------------------------------------------------------------
   20.97 +ALPHABETICAL_INDEX     = NO
   20.98 +COLS_IN_ALPHA_INDEX    = 5
   20.99 +IGNORE_PREFIX          = 
  20.100 +#---------------------------------------------------------------------------
  20.101 +# configuration options related to the HTML output
  20.102 +#---------------------------------------------------------------------------
  20.103 +GENERATE_HTML          = $(GENERATE_HTML)
  20.104 +HTML_OUTPUT            = html
  20.105 +HTML_FILE_EXTENSION    = .html
  20.106 +HTML_HEADER            = 
  20.107 +HTML_FOOTER            = 
  20.108 +HTML_STYLESHEET        = 
  20.109 +HTML_ALIGN_MEMBERS     = YES
  20.110 +GENERATE_HTMLHELP      = $(GENERATE_CHM)
  20.111 +CHM_FILE               = ../$(PROJECT).chm
  20.112 +HHC_LOCATION           = $(HHC_PATH)
  20.113 +GENERATE_CHI           = $(GENERATE_CHI)
  20.114 +BINARY_TOC             = YES
  20.115 +TOC_EXPAND             = YES
  20.116 +DISABLE_INDEX          = NO
  20.117 +ENUM_VALUES_PER_LINE   = 4
  20.118 +GENERATE_TREEVIEW      = YES
  20.119 +TREEVIEW_WIDTH         = 250
  20.120 +#---------------------------------------------------------------------------
  20.121 +# configuration options related to the LaTeX output
  20.122 +#---------------------------------------------------------------------------
  20.123 +GENERATE_LATEX         = $(GENERATE_LATEX)
  20.124 +LATEX_OUTPUT           = latex
  20.125 +LATEX_CMD_NAME         = latex
  20.126 +MAKEINDEX_CMD_NAME     = makeindex
  20.127 +COMPACT_LATEX          = NO
  20.128 +PAPER_TYPE             = $(PAPER_SIZE)
  20.129 +EXTRA_PACKAGES         = 
  20.130 +LATEX_HEADER           = 
  20.131 +PDF_HYPERLINKS         = NO
  20.132 +USE_PDFLATEX           = NO
  20.133 +LATEX_BATCHMODE        = YES
  20.134 +LATEX_HIDE_INDICES     = NO
  20.135 +#---------------------------------------------------------------------------
  20.136 +# configuration options related to the RTF output
  20.137 +#---------------------------------------------------------------------------
  20.138 +GENERATE_RTF           = $(GENERATE_RTF)
  20.139 +RTF_OUTPUT             = rtf
  20.140 +COMPACT_RTF            = NO
  20.141 +RTF_HYPERLINKS         = NO
  20.142 +RTF_STYLESHEET_FILE    = 
  20.143 +RTF_EXTENSIONS_FILE    = 
  20.144 +#---------------------------------------------------------------------------
  20.145 +# configuration options related to the man page output
  20.146 +#---------------------------------------------------------------------------
  20.147 +GENERATE_MAN           = $(GENERATE_MAN)
  20.148 +MAN_OUTPUT             = man
  20.149 +MAN_EXTENSION          = .1
  20.150 +MAN_LINKS              = NO
  20.151 +#---------------------------------------------------------------------------
  20.152 +# configuration options related to the XML output
  20.153 +#---------------------------------------------------------------------------
  20.154 +GENERATE_XML           = $(GENERATE_XML)
  20.155 +XML_OUTPUT             = xml
  20.156 +XML_SCHEMA             = 
  20.157 +XML_DTD                = 
  20.158 +XML_PROGRAMLISTING     = YES
  20.159 +#---------------------------------------------------------------------------
  20.160 +# configuration options for the AutoGen Definitions output
  20.161 +#---------------------------------------------------------------------------
  20.162 +GENERATE_AUTOGEN_DEF   = NO
  20.163 +#---------------------------------------------------------------------------
  20.164 +# configuration options related to the Perl module output
  20.165 +#---------------------------------------------------------------------------
  20.166 +GENERATE_PERLMOD       = NO
  20.167 +PERLMOD_LATEX          = NO
  20.168 +PERLMOD_PRETTY         = YES
  20.169 +PERLMOD_MAKEVAR_PREFIX = 
  20.170 +#---------------------------------------------------------------------------
  20.171 +# Configuration options related to the preprocessor   
  20.172 +#---------------------------------------------------------------------------
  20.173 +ENABLE_PREPROCESSING   = YES
  20.174 +MACRO_EXPANSION        = NO
  20.175 +EXPAND_ONLY_PREDEF     = NO
  20.176 +SEARCH_INCLUDES        = YES
  20.177 +INCLUDE_PATH           = 
  20.178 +INCLUDE_FILE_PATTERNS  = 
  20.179 +PREDEFINED             = 
  20.180 +EXPAND_AS_DEFINED      = 
  20.181 +SKIP_FUNCTION_MACROS   = YES
  20.182 +#---------------------------------------------------------------------------
  20.183 +# Configuration::additions related to external references   
  20.184 +#---------------------------------------------------------------------------
  20.185 +TAGFILES               = 
  20.186 +GENERATE_TAGFILE       = $(DOCDIR)/$(PROJECT).tag
  20.187 +ALLEXTERNALS           = NO
  20.188 +EXTERNAL_GROUPS        = YES
  20.189 +PERL_PATH              = $(PERL_PATH)
  20.190 +#---------------------------------------------------------------------------
  20.191 +# Configuration options related to the dot tool   
  20.192 +#---------------------------------------------------------------------------
  20.193 +CLASS_DIAGRAMS         = YES
  20.194 +HIDE_UNDOC_RELATIONS   = YES
  20.195 +HAVE_DOT               = $(HAVE_DOT)
  20.196 +CLASS_GRAPH            = YES
  20.197 +COLLABORATION_GRAPH    = YES
  20.198 +UML_LOOK               = NO
  20.199 +TEMPLATE_RELATIONS     = NO
  20.200 +INCLUDE_GRAPH          = YES
  20.201 +INCLUDED_BY_GRAPH      = YES
  20.202 +CALL_GRAPH             = NO
  20.203 +GRAPHICAL_HIERARCHY    = YES
  20.204 +DOT_IMAGE_FORMAT       = png
  20.205 +DOT_PATH               = $(DOT_PATH)
  20.206 +DOTFILE_DIRS           = 
  20.207 +MAX_DOT_GRAPH_WIDTH    = 1024
  20.208 +MAX_DOT_GRAPH_HEIGHT   = 1024
  20.209 +MAX_DOT_GRAPH_DEPTH    = 0
  20.210 +GENERATE_LEGEND        = YES
  20.211 +DOT_CLEANUP            = YES
  20.212 +#---------------------------------------------------------------------------
  20.213 +# Configuration::additions related to the search engine   
  20.214 +#---------------------------------------------------------------------------
  20.215 +SEARCHENGINE           = NO
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/gmyth/gmyth.pc.in	Wed Sep 20 23:45:35 2006 +0100
    21.3 @@ -0,0 +1,12 @@
    21.4 +prefix=@prefix@
    21.5 +exec_prefix=@exec_prefix@
    21.6 +libdir=@libdir@
    21.7 +includedir=@includedir@
    21.8 +
    21.9 +Name: gmyth
   21.10 +Description: Myth TV library based upon GLib/GObject paradigm
   21.11 +Version: @VERSION@
   21.12 +Requires: gobject-2.0 glib-2.0 gtk+-2.0 
   21.13 +
   21.14 +Libs: @MYSQL_LIBS@ -L${libdir} -lgmyth
   21.15 +Cflags: @MYSQL_CFLAGS@ -I${includedir}/gmyth
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/gmyth/m4/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
    22.3 @@ -0,0 +1,7 @@
    22.4 +EXTRA_DIST = \
    22.5 +        ac_doxygen.m4 \
    22.6 +        as-compiler-flag.m4 \
    22.7 +        as-expand.m4 \
    22.8 +        as-version.m4 \
    22.9 +        as-gtk-doc.m4
   22.10 +
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/gmyth/m4/ac_doxygen.m4	Wed Sep 20 23:45:35 2006 +0100
    23.3 @@ -0,0 +1,312 @@
    23.4 +# This file is part of Autoconf.                       -*- Autoconf -*-
    23.5 +
    23.6 +# Copyright (C) 2004 Oren Ben-Kiki
    23.7 +# This file is distributed under the same terms as the Autoconf macro files.
    23.8 +
    23.9 +# Generate automatic documentation using Doxygen. Works in concert with the
   23.10 +# aminclude.m4 file and a compatible doxygen configuration file. Defines the
   23.11 +# following public macros:
   23.12 +#
   23.13 +# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
   23.14 +# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
   23.15 +# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
   23.16 +# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
   23.17 +# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
   23.18 +# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
   23.19 +# paper size.
   23.20 +#
   23.21 +# By default, HTML, PDF and PS documentation is generated as this seems to be
   23.22 +# the most popular and portable combination. MAN pages created by Doxygen are
   23.23 +# usually problematic, though by picking an appropriate subset and doing some
   23.24 +# massaging they might be better than nothing. CHM and RTF are specific for MS
   23.25 +# (note that you can't generate both HTML and CHM at the same time). The XML is
   23.26 +# rather useless unless you apply specialized post-processing to it.
   23.27 +#
   23.28 +# The macro mainly controls the default state of the feature. The use can
   23.29 +# override the default by specifying --enable or --disable. The macros ensure
   23.30 +# that contradictory flags are not given (e.g., --enable-doxygen-html and
   23.31 +# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
   23.32 +# Finally, each feature will be automatically disabled (with a warning) if the
   23.33 +# required programs are missing.
   23.34 +#
   23.35 +# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
   23.36 +# the following parameters: a one-word name for the project for use as a
   23.37 +# filename base etc., an optional configuration file name (the default is
   23.38 +# 'Doxyfile', the same as Doxygen's default), and an optional output directory
   23.39 +# name (the default is 'doxygen-doc').
   23.40 +
   23.41 +## ----------##
   23.42 +## Defaults. ##
   23.43 +## ----------##
   23.44 +
   23.45 +DX_ENV=""
   23.46 +AC_DEFUN([DX_FEATURE_doc],  ON)
   23.47 +AC_DEFUN([DX_FEATURE_dot],  ON)
   23.48 +AC_DEFUN([DX_FEATURE_man],  OFF)
   23.49 +AC_DEFUN([DX_FEATURE_html], ON)
   23.50 +AC_DEFUN([DX_FEATURE_chm],  OFF)
   23.51 +AC_DEFUN([DX_FEATURE_chi],  OFF)
   23.52 +AC_DEFUN([DX_FEATURE_rtf],  OFF)
   23.53 +AC_DEFUN([DX_FEATURE_xml],  OFF)
   23.54 +AC_DEFUN([DX_FEATURE_pdf],  ON)
   23.55 +AC_DEFUN([DX_FEATURE_ps],   ON)
   23.56 +
   23.57 +## --------------- ##
   23.58 +## Private macros. ##
   23.59 +## --------------- ##
   23.60 +
   23.61 +# DX_ENV_APPEND(VARIABLE, VALUE)
   23.62 +# ------------------------------
   23.63 +# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
   23.64 +AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
   23.65 +
   23.66 +# DX_DIRNAME_EXPR
   23.67 +# ---------------
   23.68 +# Expand into a shell expression prints the directory part of a path.
   23.69 +AC_DEFUN([DX_DIRNAME_EXPR],
   23.70 +         [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
   23.71 +
   23.72 +# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
   23.73 +# -------------------------------------
   23.74 +# Expands according to the M4 (static) status of the feature.
   23.75 +AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
   23.76 +
   23.77 +# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
   23.78 +# ----------------------------------
   23.79 +# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
   23.80 +AC_DEFUN([DX_REQUIRE_PROG], [
   23.81 +AC_PATH_TOOL([$1], [$2])
   23.82 +if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
   23.83 +    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
   23.84 +    AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
   23.85 +fi
   23.86 +])
   23.87 +
   23.88 +# DX_TEST_FEATURE(FEATURE)
   23.89 +# ------------------------
   23.90 +# Expand to a shell expression testing whether the feature is active.
   23.91 +AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
   23.92 +
   23.93 +# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
   23.94 +# -------------------------------------------------
   23.95 +# Verify that a required features has the right state before trying to turn on
   23.96 +# the DX_CURRENT_FEATURE.
   23.97 +AC_DEFUN([DX_CHECK_DEPEND], [
   23.98 +test "$DX_FLAG_$1" = "$2" \
   23.99 +|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
  23.100 +                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])
  23.101 +])
  23.102 +
  23.103 +# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
  23.104 +# ----------------------------------------------------------
  23.105 +# Turn off the DX_CURRENT_FEATURE if the required feature is off.
  23.106 +AC_DEFUN([DX_CLEAR_DEPEND], [
  23.107 +test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
  23.108 +])
  23.109 +
  23.110 +# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
  23.111 +#                CHECK_DEPEND, CLEAR_DEPEND,
  23.112 +#                REQUIRE, DO-IF-ON, DO-IF-OFF)
  23.113 +# --------------------------------------------
  23.114 +# Parse the command-line option controlling a feature. CHECK_DEPEND is called
  23.115 +# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
  23.116 +# otherwise CLEAR_DEPEND is called to turn off the default state if a required
  23.117 +# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
  23.118 +# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
  23.119 +# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
  23.120 +AC_DEFUN([DX_ARG_ABLE], [
  23.121 +    AC_DEFUN([DX_CURRENT_FEATURE], [$1])
  23.122 +    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
  23.123 +    AC_ARG_ENABLE(doxygen-$1,
  23.124 +                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
  23.125 +                                                      [--enable-doxygen-$1]),
  23.126 +                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],
  23.127 +                  [
  23.128 +case "$enableval" in
  23.129 +#(
  23.130 +y|Y|yes|Yes|YES)
  23.131 +    AC_SUBST([DX_FLAG_$1], 1)
  23.132 +    $3
  23.133 +;; #(
  23.134 +n|N|no|No|NO)
  23.135 +    AC_SUBST([DX_FLAG_$1], 0)
  23.136 +;; #(
  23.137 +*)
  23.138 +    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
  23.139 +;;
  23.140 +esac
  23.141 +], [
  23.142 +AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
  23.143 +$4
  23.144 +])
  23.145 +if DX_TEST_FEATURE([$1]); then
  23.146 +    $5
  23.147 +    :
  23.148 +fi
  23.149 +if DX_TEST_FEATURE([$1]); then
  23.150 +    AM_CONDITIONAL(DX_COND_$1, :)
  23.151 +    $6
  23.152 +    :
  23.153 +else
  23.154 +    AM_CONDITIONAL(DX_COND_$1, false)
  23.155 +    $7
  23.156 +    :
  23.157 +fi
  23.158 +])
  23.159 +
  23.160 +## -------------- ##
  23.161 +## Public macros. ##
  23.162 +## -------------- ##
  23.163 +
  23.164 +# DX_XXX_FEATURE(DEFAULT_STATE)
  23.165 +# -----------------------------
  23.166 +AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
  23.167 +AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
  23.168 +AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
  23.169 +AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
  23.170 +AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
  23.171 +AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
  23.172 +AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
  23.173 +AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
  23.174 +AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
  23.175 +AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
  23.176 +
  23.177 +# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
  23.178 +# ---------------------------------------------------------
  23.179 +# PROJECT also serves as the base name for the documentation files.
  23.180 +# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
  23.181 +AC_DEFUN([DX_INIT_DOXYGEN], [
  23.182 +
  23.183 +# Files:
  23.184 +AC_SUBST([DX_PROJECT], [$1])
  23.185 +AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
  23.186 +AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
  23.187 +
  23.188 +# Environment variables used inside doxygen.cfg:
  23.189 +DX_ENV_APPEND(SRCDIR, $srcdir)
  23.190 +DX_ENV_APPEND(PROJECT, $DX_PROJECT)
  23.191 +DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
  23.192 +DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
  23.193 +
  23.194 +# Doxygen itself:
  23.195 +DX_ARG_ABLE(doc, [generate any doxygen documentation],
  23.196 +            [],
  23.197 +            [],
  23.198 +            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
  23.199 +             DX_REQUIRE_PROG([DX_PERL], perl)],
  23.200 +            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
  23.201 +
  23.202 +# Dot for graphics:
  23.203 +DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
  23.204 +            [DX_CHECK_DEPEND(doc, 1)],
  23.205 +            [DX_CLEAR_DEPEND(doc, 1)],
  23.206 +            [DX_REQUIRE_PROG([DX_DOT], dot)],
  23.207 +            [DX_ENV_APPEND(HAVE_DOT, YES)
  23.208 +             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
  23.209 +            [DX_ENV_APPEND(HAVE_DOT, NO)])
  23.210 +
  23.211 +# Man pages generation:
  23.212 +DX_ARG_ABLE(man, [generate doxygen manual pages],
  23.213 +            [DX_CHECK_DEPEND(doc, 1)],
  23.214 +            [DX_CLEAR_DEPEND(doc, 1)],
  23.215 +            [],
  23.216 +            [DX_ENV_APPEND(GENERATE_MAN, YES)],
  23.217 +            [DX_ENV_APPEND(GENERATE_MAN, NO)])
  23.218 +
  23.219 +# RTF file generation:
  23.220 +DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
  23.221 +            [DX_CHECK_DEPEND(doc, 1)],
  23.222 +            [DX_CLEAR_DEPEND(doc, 1)],
  23.223 +            [],
  23.224 +            [DX_ENV_APPEND(GENERATE_RTF, YES)],
  23.225 +            [DX_ENV_APPEND(GENERATE_RTF, NO)])
  23.226 +
  23.227 +# XML file generation:
  23.228 +DX_ARG_ABLE(xml, [generate doxygen XML documentation],
  23.229 +            [DX_CHECK_DEPEND(doc, 1)],
  23.230 +            [DX_CLEAR_DEPEND(doc, 1)],
  23.231 +            [],
  23.232 +            [DX_ENV_APPEND(GENERATE_XML, YES)],
  23.233 +            [DX_ENV_APPEND(GENERATE_XML, NO)])
  23.234 +
  23.235 +# (Compressed) HTML help generation:
  23.236 +DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
  23.237 +            [DX_CHECK_DEPEND(doc, 1)],
  23.238 +            [DX_CLEAR_DEPEND(doc, 1)],
  23.239 +            [DX_REQUIRE_PROG([DX_HHC], hhc)],
  23.240 +            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
  23.241 +             DX_ENV_APPEND(GENERATE_HTML, YES)
  23.242 +             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
  23.243 +            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
  23.244 +
  23.245 +# Seperate CHI file generation.
  23.246 +DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
  23.247 +            [DX_CHECK_DEPEND(chm, 1)],
  23.248 +            [DX_CLEAR_DEPEND(chm, 1)],
  23.249 +            [],
  23.250 +            [DX_ENV_APPEND(GENERATE_CHI, YES)],
  23.251 +            [DX_ENV_APPEND(GENERATE_CHI, NO)])
  23.252 +
  23.253 +# Plain HTML pages generation:
  23.254 +DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
  23.255 +            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
  23.256 +            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
  23.257 +            [],
  23.258 +            [DX_ENV_APPEND(GENERATE_HTML, YES)],
  23.259 +            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
  23.260 +
  23.261 +# PostScript file generation:
  23.262 +DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
  23.263 +            [DX_CHECK_DEPEND(doc, 1)],
  23.264 +            [DX_CLEAR_DEPEND(doc, 1)],
  23.265 +            [DX_REQUIRE_PROG([DX_LATEX], latex)
  23.266 +             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
  23.267 +             DX_REQUIRE_PROG([DX_DVIPS], dvips)
  23.268 +             DX_REQUIRE_PROG([DX_EGREP], egrep)])
  23.269 +
  23.270 +# PDF file generation:
  23.271 +DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
  23.272 +            [DX_CHECK_DEPEND(doc, 1)],
  23.273 +            [DX_CLEAR_DEPEND(doc, 1)],
  23.274 +            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
  23.275 +             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
  23.276 +             DX_REQUIRE_PROG([DX_EGREP], egrep)])
  23.277 +
  23.278 +# LaTeX generation for PS and/or PDF:
  23.279 +if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
  23.280 +    AM_CONDITIONAL(DX_COND_latex, :)
  23.281 +    DX_ENV_APPEND(GENERATE_LATEX, YES)
  23.282 +else
  23.283 +    AM_CONDITIONAL(DX_COND_latex, false)
  23.284 +    DX_ENV_APPEND(GENERATE_LATEX, NO)
  23.285 +fi
  23.286 +
  23.287 +# Paper size for PS and/or PDF:
  23.288 +AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
  23.289 +           [a4wide (default), a4, letter, legal or executive])
  23.290 +case "$DOXYGEN_PAPER_SIZE" in
  23.291 +#(
  23.292 +"")
  23.293 +    AC_SUBST(DOXYGEN_PAPER_SIZE, "")
  23.294 +;; #(
  23.295 +a4wide|a4|letter|legal|executive)
  23.296 +    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
  23.297 +;; #(
  23.298 +*)
  23.299 +    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
  23.300 +;;
  23.301 +esac
  23.302 +
  23.303 +#For debugging:
  23.304 +#echo DX_FLAG_doc=$DX_FLAG_doc
  23.305 +#echo DX_FLAG_dot=$DX_FLAG_dot
  23.306 +#echo DX_FLAG_man=$DX_FLAG_man
  23.307 +#echo DX_FLAG_html=$DX_FLAG_html
  23.308 +#echo DX_FLAG_chm=$DX_FLAG_chm
  23.309 +#echo DX_FLAG_chi=$DX_FLAG_chi
  23.310 +#echo DX_FLAG_rtf=$DX_FLAG_rtf
  23.311 +#echo DX_FLAG_xml=$DX_FLAG_xml
  23.312 +#echo DX_FLAG_pdf=$DX_FLAG_pdf
  23.313 +#echo DX_FLAG_ps=$DX_FLAG_ps
  23.314 +#echo DX_ENV=$DX_ENV
  23.315 +])
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/gmyth/m4/as-compiler-flag.m4	Wed Sep 20 23:45:35 2006 +0100
    24.3 @@ -0,0 +1,33 @@
    24.4 +dnl as-compiler-flag.m4 0.1.0
    24.5 +
    24.6 +dnl autostars m4 macro for detection of compiler flags
    24.7 +
    24.8 +dnl David Schleef <ds@schleef.org>
    24.9 +
   24.10 +dnl $Id: as-compiler-flag.m4,v 1.1.1.1 2005/08/26 00:42:44 andrunko Exp $
   24.11 +
   24.12 +dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])
   24.13 +dnl Tries to compile with the given CFLAGS.
   24.14 +dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,
   24.15 +dnl and ACTION-IF-NOT-ACCEPTED otherwise.
   24.16 +
   24.17 +AC_DEFUN([AS_COMPILER_FLAG],
   24.18 +[
   24.19 +  AC_MSG_CHECKING([to see if compiler understands $1])
   24.20 +
   24.21 +  save_CFLAGS="$CFLAGS"
   24.22 +  CFLAGS="$CFLAGS $1"
   24.23 +
   24.24 +  AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
   24.25 +  CFLAGS="$save_CFLAGS"
   24.26 +
   24.27 +  if test "X$flag_ok" = Xyes ; then
   24.28 +    $2
   24.29 +    true
   24.30 +  else
   24.31 +    $3
   24.32 +    true
   24.33 +  fi
   24.34 +  AC_MSG_RESULT([$flag_ok])
   24.35 +])
   24.36 +
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/gmyth/m4/as-expand.m4	Wed Sep 20 23:45:35 2006 +0100
    25.3 @@ -0,0 +1,40 @@
    25.4 +dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR)
    25.5 +dnl
    25.6 +dnl example
    25.7 +dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
    25.8 +dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local
    25.9 +
   25.10 +AC_DEFUN([AS_AC_EXPAND],
   25.11 +[
   25.12 +  EXP_VAR=[$1]
   25.13 +  FROM_VAR=[$2]
   25.14 +
   25.15 +  dnl first expand prefix and exec_prefix if necessary
   25.16 +  prefix_save=$prefix
   25.17 +  exec_prefix_save=$exec_prefix
   25.18 +
   25.19 +  dnl if no prefix given, then use /usr/local, the default prefix
   25.20 +  if test "x$prefix" = "xNONE"; then
   25.21 +    prefix=$ac_default_prefix
   25.22 +  fi
   25.23 +  dnl if no exec_prefix given, then use prefix
   25.24 +  if test "x$exec_prefix" = "xNONE"; then
   25.25 +    exec_prefix=$prefix
   25.26 +  fi
   25.27 +
   25.28 +  full_var="$FROM_VAR"
   25.29 +  dnl loop until it doesn't change anymore
   25.30 +  while true; do
   25.31 +    new_full_var="`eval echo $full_var`"
   25.32 +    if test "x$new_full_var"="x$full_var"; then break; fi
   25.33 +    full_var=$new_full_var
   25.34 +  done
   25.35 +
   25.36 +  dnl clean up
   25.37 +  full_var=$new_full_var
   25.38 +  AC_SUBST([$1], "$full_var")
   25.39 +
   25.40 +  dnl restore prefix and exec_prefix
   25.41 +  prefix=$prefix_save
   25.42 +  exec_prefix=$exec_prefix_save
   25.43 +])
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/gmyth/m4/as-version.m4	Wed Sep 20 23:45:35 2006 +0100
    26.3 @@ -0,0 +1,59 @@
    26.4 +dnl version.m4 0.0.5
    26.5 +dnl autostars m4 macro for versioning
    26.6 +dnl thomas@apestaart.org
    26.7 +dnl
    26.8 +dnl AS_VERSION(PACKAGE, PREFIX, MAJOR, MINOR, MICRO, NANO, ACTION_IF_NO_NANO, ACTION_IF_NANO)
    26.9 +dnl example
   26.10 +dnl AS_VERSION(gstreamer, GST_VERSION, 0, 3, 2,)
   26.11 +dnl for a 0.3.2 release version
   26.12 +dnl
   26.13 +dnl this macro
   26.14 +dnl - defines [$PREFIX]_MAJOR, MINOR and MICRO
   26.15 +dnl - if NANO is empty, then we're in release mode, else in cvs/dev mode
   26.16 +dnl - defines [$PREFIX], VERSION, and [$PREFIX]_RELEASE
   26.17 +dnl - executes the relevant action
   26.18 +dnl - AC_SUBST's PACKAGE, VERSION, [$PREFIX] and [$PREFIX]_RELEASE
   26.19 +dnl   as well as the little ones
   26.20 +dnl - doesn't call AM_INIT_AUTOMAKE anymore because it prevents
   26.21 +dnl   maintainer mode from running ok
   26.22 +dnl
   26.23 +dnl don't forget to put #undef [$2] and [$2]_RELEASE in acconfig.h
   26.24 +
   26.25 +AC_DEFUN([AS_VERSION],
   26.26 +[
   26.27 +  PACKAGE=[$1]
   26.28 +  [$2]_MAJOR_VERSION=[$3]
   26.29 +  [$2]_MINOR_VERSION=[$4]
   26.30 +  [$2]_MICRO_VERSION=[$5]
   26.31 +  NANO=[$6]
   26.32 +  [$2]_NANO_VERSION=$NANO
   26.33 +  if test "x$NANO" = "x" || test "x$NANO" = "x0";
   26.34 +  then
   26.35 +      AC_MSG_NOTICE(configuring [$1] for release)
   26.36 +      VERSION=[$3].[$4].[$5]
   26.37 +      [$2]_RELEASE=1
   26.38 +      dnl execute action
   26.39 +      ifelse([$7], , :, [$7])
   26.40 +  else
   26.41 +      AC_MSG_NOTICE(configuring [$1] for development with nano $NANO)
   26.42 +      VERSION=[$3].[$4].[$5].$NANO
   26.43 +      [$2]_RELEASE=`date +%Y%m%d_%H%M%S`
   26.44 +      dnl execute action
   26.45 +      ifelse([$8], , :, [$8])
   26.46 +  fi
   26.47 +
   26.48 +  [$2]_VERSION=$VERSION
   26.49 +  AC_DEFINE_UNQUOTED([$2]_VERSION, "$[$2]_VERSION", [Define the version])
   26.50 +  AC_SUBST([$2]_VERSION)
   26.51 +  
   26.52 +  AC_SUBST([$2]_RELEASE)
   26.53 +
   26.54 +  AC_SUBST([$2]_MAJOR_VERSION)
   26.55 +  AC_SUBST([$2]_MINOR_VERSION)
   26.56 +  AC_SUBST([$2]_MICRO_VERSION)
   26.57 +  AC_SUBST([$2]_NANO_VERSION)
   26.58 +  AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Define the package name])
   26.59 +  AC_SUBST(PACKAGE)
   26.60 +  AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Define the version])
   26.61 +  AC_SUBST(VERSION)
   26.62 +])
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/gmyth/pixmaps/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
    27.3 @@ -0,0 +1,11 @@
    27.4 +# Adding the application icon
    27.5 +#icondir = $(datadir)/miptv/pixmaps
    27.6 +#icon_DATA = \
    27.7 +#	miptv.png
    27.8 +
    27.9 +
   27.10 +# Adding the application resources
   27.11 +pixmapdir = $(pkgdatadir)/pixmaps
   27.12 +pixmap_DATA = mmyth_logo.png
   27.13 +
   27.14 +EXTRA_DIST = $(pixmap_DATA)
    28.1 Binary file gmyth/pixmaps/main_logo.gif has changed
    29.1 Binary file gmyth/pixmaps/mmyth_logo.png has changed
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/gmyth/src/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
    30.3 @@ -0,0 +1,29 @@
    30.4 +SUBDIRS = libgmyth gui .
    30.5 +
    30.6 +bin_PROGRAMS = mmyth
    30.7 +
    30.8 +mmyth_SOURCES = mmyth_main.c
    30.9 +
   30.10 +mmyth_CFLAGS = 								\
   30.11 +	$(GTK_CFLAGS) 							\
   30.12 +	$(GLIB_CFLAGS) 							\
   30.13 +	$(GST_CFLAGS) 							\
   30.14 +	$(MYSQL_CFLAGS) 						\
   30.15 +	-g3 -O0 								\
   30.16 +	-I$(top_srcdir)/src/libgmyth 			\
   30.17 +	-I$(top_srcdir)/src/gui 				\
   30.18 +	-DDATA_DIR=\""$(pkgdatadir)"\" 			\
   30.19 +	-DPIX_DIR=\""$(pkgdatadir)/pixmaps/"\" 	\
   30.20 +	-DESG_DIR=\""$(pkgdatadir)/pixmaps/"\" 	\
   30.21 +	-DICON_DIR=\""$(pkgdatadir)/pixmaps/"\"
   30.22 +
   30.23 +mmyth_LDFLAGS = 
   30.24 +
   30.25 +mmyth_LDADD = 								\
   30.26 +	$(GTK_LIBS) 							\
   30.27 +	$(GLIB_LIBS) 							\
   30.28 +	$(GST_LIBS) 							\
   30.29 +	$(GSTBASE_LIBS) 						\
   30.30 +	$(HILDON_LIBS)							\
   30.31 +	$(top_srcdir)/src/libgmyth/libgmyth.la	\
   30.32 +	$(top_srcdir)/src/gui/libmmythgui.la
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/gmyth/src/gui/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
    31.3 @@ -0,0 +1,29 @@
    31.4 +noinst_LTLIBRARIES = libmmythgui.la
    31.5 +
    31.6 +libmmythgui_la_SOURCES =		\
    31.7 +		mmyth_ui.c				\
    31.8 +		mmyth_uicommon.c		\
    31.9 +		mmyth_epg_grid_view.c	\
   31.10 +		mmyth_epg_grid_widget.c	\
   31.11 +		mmyth_recordui.c		\
   31.12 +		mmyth_uisettings.c		\
   31.13 +		mmyth_schedulerui.c
   31.14 +
   31.15 +libmmythgui_la_CFLAGS = \
   31.16 +		$(GTK_CFLAGS) \
   31.17 +		$(GLIB_CFLAGS) \
   31.18 +		$(GST_CFLAGS) \
   31.19 +		$(MYSQL_CFLAGS) \
   31.20 +		-I$(top_srcdir)/src/libgmyth \
   31.21 +		-I$(top_srcdir)/src \
   31.22 +		-DDATA_DIR=\""$(pkgdatadir)"\" \
   31.23 +		-DPIX_DIR=\""$(pkgdatadir)/pixmaps/"\" \
   31.24 +		-DICON_DIR=\""$(datadir)/pixmaps/"\" \
   31.25 +		-g3 -O0
   31.26 +
   31.27 +libmmythgui_la_LIBADD = 	\
   31.28 +	      $(top_srcdir)/src/libgmyth/libgmyth.la
   31.29 +
   31.30 +libmmythgui_la_LDFLAGS = -export-dynamic		
   31.31 +
   31.32 +
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/gmyth/src/gui/mmyth_epg_grid_view.c	Wed Sep 20 23:45:35 2006 +0100
    32.3 @@ -0,0 +1,213 @@
    32.4 +#include <string.h>
    32.5 +#include <stdlib.h>
    32.6 +#include <gtk/gtk.h>
    32.7 +#include <gdk/gdkkeysyms.h>
    32.8 +#include <time.h>
    32.9 +
   32.10 +#include "mmyth_epg_grid_view.h"
   32.11 +#include "mmyth_epg_grid_widget.h"
   32.12 +
   32.13 +/* Service genre */
   32.14 +#define GENRE_MIN               0
   32.15 +#define GENRE_MAX               10
   32.16 +#define GENRE_UNDEFINED         0
   32.17 +#define GENRE_MOVIE             1
   32.18 +#define GENRE_NEWS              2
   32.19 +#define GENRE_SHOW              3
   32.20 +#define GENRE_SPORTS            4
   32.21 +#define GENRE_CHILDREN          5
   32.22 +#define GENRE_MUSIC             6
   32.23 +#define GENRE_CULTURE           7
   32.24 +#define GENRE_SOCIAL            8
   32.25 +#define GENRE_EDUCATION         9
   32.26 +#define GENRE_LEISURE           10
   32.27 +
   32.28 +#define NRO_HOURS 3
   32.29 +
   32.30 +/* Function prototypes*/
   32.31 +static void update_service_details(MMythEpgGridWidget *object, 
   32.32 +                                   gpointer arg1, gpointer user_data);
   32.33 +static gboolean key_press_epg_grid_view(GtkWidget * widget, 
   32.34 +                                        GdkEventKey * event, 
   32.35 +                                        gpointer user_data);
   32.36 +
   32.37 +static GtkWidget *mmyth_epg_grid_widget = NULL;
   32.38 +
   32.39 +/* is a GtkEventBox */
   32.40 +static GtkWidget *program_details_area = NULL;
   32.41 +static GtkWidget *details_main_hbox = NULL;
   32.42 +static GtkWidget *details_vbox = NULL;
   32.43 +static GtkWidget *details_logo_vbox = NULL;
   32.44 +
   32.45 +/* update signal callback from MMythEpgGridWidget */
   32.46 +static void
   32.47 +update_service_details(MMythEpgGridWidget *object, gpointer arg1, gpointer user_data) 
   32.48 +{
   32.49 +	g_return_if_fail(arg1 != NULL);
   32.50 +
   32.51 +	EpgGridItem *epg_grid_item = (EpgGridItem *) arg1;
   32.52 +	
   32.53 +	gchar sel_prog_desc[100] = "<big><b>";
   32.54 +	gchar time_buffer[50];
   32.55 +
   32.56 +    /* FIXME: get first content from content_list*/
   32.57 +    GMythProgramInfo *proginfo = (GMythProgramInfo *) epg_grid_item->proginfo;
   32.58 +
   32.59 +    if(proginfo) {
   32.60 +        GString *prog_name = proginfo->title;    
   32.61 +        GString *service_name = proginfo->chanid;
   32.62 +           
   32.63 +    	if(details_vbox != NULL)
   32.64 +  	        gtk_container_remove (GTK_CONTAINER (details_main_hbox), details_vbox);	
   32.65 +    
   32.66 +        /* update service description */
   32.67 +        strcat(sel_prog_desc, service_name->str);
   32.68 +        strcat(sel_prog_desc, "</b></big>");
   32.69 +    
   32.70 +        GtkWidget *fst_line_lbl = gtk_label_new(NULL);
   32.71 +        gtk_misc_set_alignment (GTK_MISC(fst_line_lbl), 0.0, 0.0); 
   32.72 +        gtk_label_set_markup(GTK_LABEL(fst_line_lbl), sel_prog_desc);     
   32.73 +
   32.74 +        /* freeing char[] */
   32.75 +        sel_prog_desc[0] = 0;
   32.76 +        strcat(sel_prog_desc, "\t");
   32.77 +        strcat(sel_prog_desc, prog_name->str);    
   32.78 +            	        		
   32.79 +        struct tm loctime_start, loctime_end;
   32.80 +    
   32.81 +        // Convert it to local time representation. 
   32.82 +        /* FIXME: conversion from time to localtime is different
   32.83 +        in different machines */
   32.84 +        long int schedule_start_time = proginfo->startts;
   32.85 +        long int schedule_end_time   = proginfo->endts;
   32.86 +    
   32.87 +        if (localtime_r(&schedule_start_time, &loctime_start) == NULL) {
   32.88 +            g_warning ("localtime_r error in mmyth_epg_grid_view!\n");
   32.89 +        }
   32.90 +    
   32.91 +        #if 0 
   32.92 +            fprintf (stderr, asctime (loctime_start)); 
   32.93 +        #endif
   32.94 +    
   32.95 +        strftime (time_buffer, 100, "  %H:%M - ", &loctime_start);
   32.96 +        strcat(sel_prog_desc, time_buffer );
   32.97 +    
   32.98 +        if (localtime_r(&schedule_end_time, &loctime_end) == NULL) {
   32.99 +            g_warning ("localtime_r error in mmyth_epg_grid_view!\n");
  32.100 +        }
  32.101 +
  32.102 +        #if 0
  32.103 +            fprintf (stderr, asctime (loctime_end));     		    
  32.104 +        #endif
  32.105 +    
  32.106 +        strftime (time_buffer, 100, "%H:%M\n", &loctime_end);
  32.107 +        strcat(sel_prog_desc, time_buffer );
  32.108 +    
  32.109 +        GtkWidget *snd_line_lbl = gtk_label_new(NULL);
  32.110 +        gtk_misc_set_alignment (GTK_MISC(snd_line_lbl), 0.0, 0.0); 
  32.111 +        gtk_label_set_markup(GTK_LABEL(snd_line_lbl), sel_prog_desc);     
  32.112 +    
  32.113 +        // add the current selected program description to the label
  32.114 +        details_vbox = gtk_vbox_new(FALSE, 0);
  32.115 +        GtkWidget *fst_line_hbox = gtk_hbox_new(FALSE, 0);        
  32.116 +        
  32.117 +        gtk_box_pack_start (GTK_BOX (fst_line_hbox),
  32.118 +                            fst_line_lbl, FALSE, FALSE, 6);
  32.119 +        gtk_box_pack_start (GTK_BOX (details_vbox),
  32.120 +                            fst_line_hbox, FALSE, FALSE, 0);
  32.121 +        gtk_box_pack_start (GTK_BOX (details_vbox),
  32.122 +                            snd_line_lbl, FALSE, FALSE, 0);
  32.123 +        gtk_box_pack_start (GTK_BOX (details_main_hbox),
  32.124 +                            details_vbox, FALSE, FALSE, 0);
  32.125 +        
  32.126 +        gtk_widget_show_all(details_main_hbox);
  32.127 +    }        
  32.128 +}
  32.129 +
  32.130 +/* Callback for hardware keys */
  32.131 +static gboolean
  32.132 +key_press_epg_grid_view(GtkWidget * widget, 
  32.133 +                        GdkEventKey * event, gpointer user_data)
  32.134 +{
  32.135 +    MMythEpgGridWidget *mmyth_epg_grid_widget = (MMythEpgGridWidget *) user_data;
  32.136 +
  32.137 +    return mmyth_epg_grid_widget_key_press(mmyth_epg_grid_widget, widget, event); 
  32.138 +}
  32.139 +
  32.140 +GtkWidget *
  32.141 +epg_grid_view_new (MMythUi* mmyth_ui) 
  32.142 +{
  32.143 +    GtkWidget *scrolled_window;
  32.144 +    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  32.145 +    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
  32.146 +                                    GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);                   
  32.147 +    
  32.148 +    gtk_widget_modify_bg(scrolled_window, GTK_STATE_NORMAL, &main_bg_color);  
  32.149 +    
  32.150 +    GtkWidget *main_vbox = gtk_vbox_new (FALSE, 0);      
  32.151 +    //gtk_container_set_border_width(main_vbox, 4);        
  32.152 +    
  32.153 +    GtkWidget *details_event_box = gtk_event_box_new();               
  32.154 +    gtk_widget_modify_bg(details_event_box, GTK_STATE_NORMAL, &main_bg_color);  
  32.155 +    
  32.156 +    program_details_area = gtk_vbox_new (FALSE, 0);
  32.157 +    gtk_container_add (GTK_CONTAINER (details_event_box),
  32.158 +                       program_details_area);   
  32.159 +    gtk_container_set_border_width(GTK_CONTAINER (program_details_area), 4);        
  32.160 +
  32.161 +	details_main_hbox = gtk_hbox_new (FALSE, 10);    
  32.162 +
  32.163 +	gtk_box_pack_start (GTK_BOX (program_details_area),
  32.164 +	                    details_main_hbox, FALSE, FALSE, 0);                    
  32.165 +	                    
  32.166 +	details_logo_vbox = gtk_vbox_new (FALSE, 0);      	 
  32.167 +    
  32.168 +	GtkWidget *details_desc_vbox = gtk_vbox_new (FALSE, 0);      
  32.169 +
  32.170 +    gtk_box_pack_start (GTK_BOX (details_main_hbox),
  32.171 +	                    details_desc_vbox, FALSE, FALSE, 0);                    
  32.172 +    gtk_box_pack_start (GTK_BOX (details_main_hbox),
  32.173 +	                    details_logo_vbox, FALSE, FALSE, 0);                    	
  32.174 +	
  32.175 +    gtk_widget_set_size_request (program_details_area, -1, 120);          
  32.176 +    
  32.177 +    mmyth_epg_grid_widget = mmyth_epg_grid_widget_new();
  32.178 +    g_signal_connect(mmyth_epg_grid_widget, "selection_updated", 
  32.179 +                     G_CALLBACK (update_service_details), NULL);    
  32.180 +
  32.181 +    /* select by default the first service */
  32.182 +    /* depends on mount services */
  32.183 +    if (MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget)->epg_view_model) {
  32.184 +	    GList *fst_service = (GList *) 
  32.185 +	    	MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget)->epg_view_model->data;
  32.186 +    	mmyth_epg_grid_widget_update_service(MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget),
  32.187 +                                         fst_service);
  32.188 +    }
  32.189 +    
  32.190 +    gtk_box_pack_start (GTK_BOX (main_vbox),
  32.191 +                        details_event_box, FALSE, FALSE, 0); 
  32.192 +    gtk_box_pack_start (GTK_BOX (main_vbox),
  32.193 +                        gtk_hseparator_new(), FALSE, FALSE, 0);         
  32.194 +    gtk_box_pack_start (GTK_BOX (main_vbox),
  32.195 +                        mmyth_epg_grid_widget, FALSE, FALSE, 0);                    
  32.196 +
  32.197 +    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window),
  32.198 +                                           main_vbox);    
  32.199 +    
  32.200 +    /* Add hardware button listener to application */
  32.201 +    g_signal_connect(mmyth_ui->main_window, "key_press_event", 
  32.202 +                     G_CALLBACK (key_press_epg_grid_view), mmyth_epg_grid_widget);    
  32.203 +
  32.204 +    gtk_widget_show_all (scrolled_window);
  32.205 +    
  32.206 +    return scrolled_window;
  32.207 +}
  32.208 +
  32.209 +/*
  32.210 +DVBHScheduleEvent * 
  32.211 +mmyth_epg_grid_view_get_selected_schedule()
  32.212 +{
  32.213 +    return mmyth_epg_grid_get_selected_schedule
  32.214 +            (MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget));
  32.215 +}
  32.216 +*/
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/gmyth/src/gui/mmyth_epg_grid_view.h	Wed Sep 20 23:45:35 2006 +0100
    33.3 @@ -0,0 +1,8 @@
    33.4 +#ifndef MMYTH_ESG_GRID_VIEW_H_
    33.5 +#define MMYTH_ESG_GRID_VIEW_H_
    33.6 +
    33.7 +#include "mmyth_ui.h"
    33.8 +
    33.9 +GtkWidget *epg_grid_view_new(MMythUi * mmyth_ui);
   33.10 +
   33.11 +#endif /* MMYTH_ESG_GRID_VIEW_H_ */
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/gmyth/src/gui/mmyth_epg_grid_widget.c	Wed Sep 20 23:45:35 2006 +0100
    34.3 @@ -0,0 +1,622 @@
    34.4 +#include <gtk/gtksignal.h>
    34.5 +#include <gdk/gdkevents.h>
    34.6 +#include <gdk/gdkkeysyms.h>
    34.7 +
    34.8 +#include "mmyth_uicommon.h"
    34.9 +#include "mmyth_epg_grid_widget.h"
   34.10 +
   34.11 +#include "gmyth_util.h" 
   34.12 +#include "gmyth_epg.h"
   34.13 +
   34.14 +#define PIXELS_HOUR 105
   34.15 +#define PROGRAM_SEPARATION 2
   34.16 +
   34.17 +enum {
   34.18 +  SELECTION_UPDATED_SIGNAL,
   34.19 +  LAST_SIGNAL
   34.20 +};
   34.21 +
   34.22 +struct _MMythEpgGridWidgetPrivate {
   34.23 +    /* private widget components */
   34.24 +    GtkWidget *epg_channels_vbox;
   34.25 +    GtkWidget *epg_programs_vbox;
   34.26 + 
   34.27 +    GHashTable *service_model_hash;
   34.28 +    
   34.29 +    /* guidegrid attributes */
   34.30 +    gboolean show_favorites;
   34.31 +    gint current_start_channel_id;
   34.32 +    
   34.33 +    time_t current_start_time;
   34.34 +    time_t current_end_time;
   34.35 +
   34.36 +    guint selected_channel_index;
   34.37 +    
   34.38 +    /* GList of ProgramInfo for each Channel */
   34.39 +    GList * program_list[MAX_DISPLAY_CHANS];
   34.40 +    GList * channel_list;
   34.41 +    
   34.42 +    GMythEPG *mmyth_epg;
   34.43 +    
   34.44 +    gint DISPLAY_CHANS;
   34.45 +};
   34.46 +
   34.47 +static void mmyth_epg_grid_widget_class_init          (MMythEpgGridWidgetClass *klass);
   34.48 +static void mmyth_epg_grid_widget_init                (MMythEpgGridWidget *object);
   34.49 +static void mmyth_epg_grid_widget_private_init        (MMythEpgGridWidgetPrivate *private);
   34.50 +static void mmyth_epg_grid_widget_mount_services      (MMythEpgGridWidget *object, 
   34.51 +                                                       int start_time, int end_time);
   34.52 +static void mmyth_epg_grid_widget_mount_header        (MMythEpgGridWidget *object);
   34.53 +static void mmyth_epg_grid_widget_clicked             (GtkWidget* widget, 
   34.54 +                                                       GdkEventExpose *event, 
   34.55 +                                                       gpointer data);
   34.56 +static GtkWidget *create_event_box_lbl                (gchar *str, int width, 
   34.57 +                                                       const GdkColor *bg_color, 
   34.58 +                                                       const GdkColor *fg_color);
   34.59 +
   34.60 +static void mmyth_epg_grid_widget_fill_programinfos(MMythEpgGridWidgetPrivate *private);
   34.61 +static void mmyth_epg_grid_widget_fill_program_row_infos(
   34.62 +                    MMythEpgGridWidgetPrivate *private, 
   34.63 +                    unsigned int chanNum, unsigned int row);
   34.64 +
   34.65 +static gint mmyth_epg_grid_widget_signals[LAST_SIGNAL] = { 0 };
   34.66 +
   34.67 +G_DEFINE_TYPE(MMythEpgGridWidget, mmyth_epg_grid_widget, GTK_TYPE_EVENT_BOX)
   34.68 +    
   34.69 +static void
   34.70 +mmyth_epg_grid_widget_class_init (MMythEpgGridWidgetClass *klass)
   34.71 +{
   34.72 +  g_type_class_add_private (klass, sizeof (MMythEpgGridWidgetPrivate));
   34.73 +  
   34.74 +  mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL] = g_signal_new (
   34.75 +                     "selection_updated",
   34.76 +					 G_TYPE_FROM_CLASS(klass), 
   34.77 +					 G_SIGNAL_RUN_FIRST,
   34.78 +					 0,
   34.79 +                     NULL,
   34.80 +                     NULL,
   34.81 +					 g_cclosure_marshal_VOID__POINTER, 
   34.82 +                     G_TYPE_NONE, 
   34.83 +                     1,
   34.84 +                     G_TYPE_POINTER);
   34.85 +}
   34.86 +
   34.87 +static void 
   34.88 +mmyth_epg_grid_widget_private_init (MMythEpgGridWidgetPrivate *private)
   34.89 +{
   34.90 +    time_t cur_time;
   34.91 +    
   34.92 +    g_return_if_fail(private != NULL);     
   34.93 +
   34.94 +    private->epg_channels_vbox   = NULL;
   34.95 +    private->epg_programs_vbox   = NULL;
   34.96 +    private->service_model_hash  = NULL;
   34.97 +
   34.98 +    private->show_favorites = FALSE;
   34.99 +    private->current_start_channel_id = -1;
  34.100 +
  34.101 +    /* Selected the first diplayable channel initially */
  34.102 +    private->selected_channel_index = 0;
  34.103 +        
  34.104 +    /* TODO fix the current start/end time */
  34.105 +    private->current_start_time = time(&cur_time);
  34.106 +    private->current_end_time = time(&cur_time) + 10800;   
  34.107 +    
  34.108 +    private->DISPLAY_CHANS = MAX_DISPLAY_CHANS;
  34.109 +    
  34.110 +    // TODO: Close the epg and unref it in dispose call
  34.111 +    private->mmyth_epg = gmyth_epg_new ();
  34.112 +    if (!gmyth_epg_connect (private->mmyth_epg)) {
  34.113 +    	g_warning ("[%s] Could not connect mysql handler to db", __FUNCTION__);
  34.114 +    	g_object_unref (private->mmyth_epg);
  34.115 +    	private->mmyth_epg = NULL;
  34.116 +    }
  34.117 +}
  34.118 +
  34.119 +static void
  34.120 +mmyth_epg_grid_widget_init (MMythEpgGridWidget *mmyth_epg_grid_widget)
  34.121 +{
  34.122 +    MMythEpgGridWidgetPrivate *private = 
  34.123 +        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
  34.124 +    
  34.125 +    /* init private fields */
  34.126 +    mmyth_epg_grid_widget_private_init(private);
  34.127 +
  34.128 +    mmyth_epg_grid_widget->epg_view_model      = NULL;
  34.129 +    mmyth_epg_grid_widget->selected_grid_item  = NULL;
  34.130 +
  34.131 +    GtkWidget *epg_event_box = GTK_WIDGET(mmyth_epg_grid_widget);
  34.132 +    gtk_widget_modify_bg(epg_event_box, GTK_STATE_NORMAL, &main_bg_color);
  34.133 +    gtk_widget_set_size_request (epg_event_box, 0, 125);
  34.134 +    
  34.135 +    GtkWidget *epg_main_hbox = gtk_hbox_new (FALSE, 10);
  34.136 +    gtk_container_set_border_width(GTK_CONTAINER (epg_main_hbox), 10);
  34.137 +    
  34.138 +    gtk_container_add (GTK_CONTAINER (epg_event_box),
  34.139 +                       epg_main_hbox);
  34.140 +		        
  34.141 +    /* channels vbox */
  34.142 +    GtkWidget *epg_channels_vbox = gtk_vbox_new (FALSE, 3); 
  34.143 +    private->epg_channels_vbox = epg_channels_vbox; 
  34.144 +
  34.145 +    /* programs vbox */
  34.146 +    GtkWidget *epg_programs_vbox = gtk_vbox_new (FALSE, 3);
  34.147 +    private->epg_programs_vbox = epg_programs_vbox;
  34.148 +    
  34.149 +    /* packing start */
  34.150 +    gtk_box_pack_start (GTK_BOX (epg_main_hbox),
  34.151 +	                epg_channels_vbox, FALSE, FALSE, 0);
  34.152 +    gtk_box_pack_start (GTK_BOX (epg_main_hbox),
  34.153 +                        epg_programs_vbox, FALSE, FALSE, 0);
  34.154 +
  34.155 +    /* table header (first line) */  
  34.156 +    mmyth_epg_grid_widget_mount_header(mmyth_epg_grid_widget);                 
  34.157 +    
  34.158 +    /* service programs */ 
  34.159 +    /* mount service programs with current time */
  34.160 +    mmyth_epg_grid_widget_mount_services(mmyth_epg_grid_widget, 
  34.161 +                                         private->current_start_time,
  34.162 +                                         private->current_end_time);                                           
  34.163 +}
  34.164 +
  34.165 +GtkWidget*
  34.166 +mmyth_epg_grid_widget_new ()
  34.167 +{
  34.168 +  return GTK_WIDGET ( gtk_type_new (mmyth_epg_grid_widget_get_type ()));
  34.169 +}
  34.170 +
  34.171 +static void
  34.172 +mmyth_epg_grid_widget_mount_services(MMythEpgGridWidget *mmyth_epg_grid_widget, 
  34.173 +                                     int start_time, int end_time)
  34.174 +{
  34.175 +    GList *proglist;
  34.176 +    GList *channel_list = NULL;
  34.177 +    GMythChannelInfo *channel_info;
  34.178 +
  34.179 +    int chanid;
  34.180 +    MMythEpgGridWidgetPrivate *private = 
  34.181 +        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
  34.182 +	
  34.183 +	// update view_model
  34.184 +	/* FIXME shallow free or recursive? */
  34.185 +	if(mmyth_epg_grid_widget->epg_view_model != NULL) {
  34.186 +		g_list_free(mmyth_epg_grid_widget->epg_view_model);
  34.187 +		mmyth_epg_grid_widget->epg_view_model = NULL;
  34.188 +	}
  34.189 +	
  34.190 +	if(private->service_model_hash != NULL) {
  34.191 +		g_hash_table_destroy(private->service_model_hash);
  34.192 +	}
  34.193 +
  34.194 +	private->service_model_hash = g_hash_table_new(NULL, NULL);
  34.195 +
  34.196 +    /* fill program infos from db */
  34.197 +    mmyth_epg_grid_widget_fill_programinfos(private);
  34.198 +    
  34.199 +    channel_list = private->channel_list;
  34.200 + 
  34.201 +    /* for each channel get_programs() */
  34.202 +    for (chanid=0; channel_list &&
  34.203 +                   chanid < private->DISPLAY_CHANS; chanid++) {
  34.204 +        proglist = (GList *) private->program_list[chanid];        
  34.205 +    
  34.206 +        channel_info = (GMythChannelInfo *) channel_list->data;
  34.207 +        channel_list = g_list_next(channel_list);        
  34.208 +
  34.209 +        /* Service Title*/
  34.210 +        GString *name = NULL;
  34.211 +        if (channel_info->channel_name)
  34.212 +        	name = g_string_new (channel_info->channel_name->str);
  34.213 +		
  34.214 +		GdkColor title_bg_color;
  34.215 +		title_bg_color.red = 5000;
  34.216 +		title_bg_color.green = 9000;
  34.217 +		title_bg_color.blue = 40000;        
  34.218 +		
  34.219 +		GdkColor title_fg_color;
  34.220 +		title_fg_color.red = 60000;
  34.221 +		title_fg_color.green = 60000;
  34.222 +		title_fg_color.blue = 60000;        
  34.223 +		
  34.224 +		GtkWidget *event_box_channel = create_event_box_lbl(
  34.225 +                                                        name->str, 90, 
  34.226 +									                    &title_bg_color, 
  34.227 +									                    &title_fg_color);
  34.228 +
  34.229 +        gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
  34.230 +		                    event_box_channel, FALSE, FALSE, 0);
  34.231 +
  34.232 +  		GtkWidget *epg_line_hbox = gtk_hbox_new (FALSE, 0);      
  34.233 +
  34.234 +	    GdkColor bg_color;
  34.235 +	    bg_color.red = 5000;
  34.236 +	    bg_color.green = 30000;
  34.237 +	    bg_color.blue = 60000;        
  34.238 +	
  34.239 +	    GdkColor fg_color;
  34.240 +	    fg_color.red = 60000;
  34.241 +	    fg_color.green = 60000;
  34.242 +	    fg_color.blue = 60000;        
  34.243 +		
  34.244 +		/* Content parsing */
  34.245 +        GList *epg_grid_list = NULL;
  34.246 +
  34.247 +        GMythProgramInfo *proginfo;
  34.248 +        int pixel_count = 0;
  34.249 +        for (; proglist; proglist = proglist->next) {
  34.250 +            proginfo = (GMythProgramInfo *) proglist->data;
  34.251 +            
  34.252 +            GString *content_name = proginfo->title;
  34.253 +                    
  34.254 +       	    int initial_time, last_time, duration;
  34.255 +
  34.256 +            int schedule_start_time = proginfo->startts;
  34.257 +            int schedule_end_time   = proginfo->endts;
  34.258 +
  34.259 +	        initial_time = 
  34.260 +                (schedule_start_time < start_time) ? start_time : schedule_start_time;
  34.261 +            last_time = (schedule_end_time > end_time) ? end_time : schedule_end_time;
  34.262 +	        duration = last_time - initial_time;
  34.263 +		    
  34.264 +            // Verify program time 
  34.265 +            #if 0
  34.266 +			    g_debug ("ServiceID: %d, ScheduleID: %d\n", service->id, schedule->id);
  34.267 +                fprintf (stderr, "program time\nfrom = %d, to = %d\n", 
  34.268 +                         schedule->validFrom, schedule->validTo); 
  34.269 +                
  34.270 +                struct tm loctime;
  34.271 +    
  34.272 +                /* Convert it to local time representation. */
  34.273 +                if (localtime_r((time_t *)&schedule->validFrom, &loctime) == NULL) {
  34.274 +                    g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
  34.275 +                    return NULL;
  34.276 +                }            
  34.277 +                fprintf (stderr, asctime (&loctime)); 
  34.278 +                
  34.279 +                if (localtime_r((time_t *)&schedule->validTo, &loctime) == NULL) {
  34.280 +                    g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
  34.281 +                    return NULL;
  34.282 +                } 
  34.283 +                fprintf (stderr, asctime (&loctime)); 
  34.284 +            #endif
  34.285 +    		
  34.286 +    	    /* fprintf(stderr, "duration = %d\n", duration); */
  34.287 +    	    double duration_hour = duration / (double) 3600.0;
  34.288 +    	    /* fprintf(stderr, "duration_hour = %lf\n", duration_hour); */
  34.289 +    		
  34.290 +            int size = PIXELS_HOUR * duration_hour;
  34.291 +                
  34.292 +            /* complete hour */
  34.293 +            /* FIXME: UGLY WRONG HACK TO ALIGN PROGRAM TIME!!!*/
  34.294 +            if(last_time%3600 != 0) {
  34.295 +                size -= PROGRAM_SEPARATION;                
  34.296 +            }
  34.297 +            if(initial_time%3600 != 0) {
  34.298 +                size -= PROGRAM_SEPARATION;                
  34.299 +            }
  34.300 +
  34.301 +            pixel_count += size + PROGRAM_SEPARATION;
  34.302 +	        GtkWidget *event_box = create_event_box_lbl(content_name->str, 
  34.303 +							  size, &bg_color, 
  34.304 +							  &fg_color);
  34.305 +							  gtk_widget_add_events(event_box, 
  34.306 +							  GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  34.307 +            
  34.308 +            /* create EpgGridItem */
  34.309 +            EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
  34.310 +            epg_grid_item->proginfo  = proginfo;
  34.311 +            epg_grid_item->event_box = event_box;
  34.312 +            epg_grid_item->object    = mmyth_epg_grid_widget;
  34.313 +            
  34.314 +            epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);                                   		                        
  34.315 +
  34.316 +     	    gtk_box_pack_start (GTK_BOX (epg_line_hbox),
  34.317 +	                            event_box, FALSE, FALSE, PROGRAM_SEPARATION);
  34.318 +	                                 
  34.319 +   	        g_signal_connect (G_OBJECT (event_box), "button-press-event",
  34.320 +		                      G_CALLBACK (mmyth_epg_grid_widget_clicked), 
  34.321 +                              (gpointer*) epg_grid_list);
  34.322 +        }
  34.323 +#if 0
  34.324 +        printf("chaind = %d!!!!" chanid);fflush(stdout);
  34.325 +#endif        
  34.326 +
  34.327 +        if(!epg_grid_list) {
  34.328 +            /* No programs for current channel */
  34.329 +            /* FIXME: size HARDCODED */
  34.330 +            GtkWidget *event_box = create_event_box_lbl("No program list available",
  34.331 +                              PIXELS_HOUR * 3, &bg_color,
  34.332 +                              &fg_color);
  34.333 +                              gtk_widget_add_events(event_box,
  34.334 +                              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
  34.335 +
  34.336 +            /* create EpgGridItem */
  34.337 +            EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
  34.338 +            epg_grid_item->proginfo  = NULL;
  34.339 +            epg_grid_item->event_box = event_box;
  34.340 +            epg_grid_item->object    = mmyth_epg_grid_widget;
  34.341 +
  34.342 +            epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);
  34.343 +            
  34.344 +            gtk_box_pack_start (GTK_BOX (epg_line_hbox),
  34.345 +	                            event_box, FALSE, FALSE, PROGRAM_SEPARATION);            	
  34.346 +	                                 
  34.347 +   	        g_signal_connect (G_OBJECT (event_box), "button-press-event",
  34.348 +		                      G_CALLBACK (mmyth_epg_grid_widget_clicked),
  34.349 +                              (gpointer*) epg_grid_list);
  34.350 +        }
  34.351 +
  34.352 +        epg_grid_list = g_list_reverse(epg_grid_list);
  34.353 +        mmyth_epg_grid_widget->epg_view_model = 
  34.354 +              g_list_append(mmyth_epg_grid_widget->epg_view_model, epg_grid_list);
  34.355 +        
  34.356 +	    gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
  34.357 +	                        epg_line_hbox, FALSE, FALSE,  0);                    		    		
  34.358 +    }
  34.359 +}
  34.360 +
  34.361 +static void
  34.362 +mmyth_epg_grid_widget_mount_header(MMythEpgGridWidget *mmyth_epg_grid_widget)
  34.363 +{	          	    
  34.364 +    MMythEpgGridWidgetPrivate *private = 
  34.365 +        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
  34.366 +    
  34.367 +    struct tm hour_tm;
  34.368 +    const gchar name_title[] = "Today";    
  34.369 +    GtkWidget * lbl_title = gtk_label_new(name_title);
  34.370 +
  34.371 +    gtk_misc_set_alignment (GTK_MISC(lbl_title), 0.0, 0.5);
  34.372 +    
  34.373 +    gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
  34.374 +                        lbl_title, FALSE, FALSE, 0);
  34.375 +
  34.376 +	/* hours title line */
  34.377 +    GtkWidget *epg_programs_hours_hbox = gtk_hbox_new (TRUE, 0); 
  34.378 +
  34.379 +    if (localtime_r((time_t *)&private->current_start_time, &hour_tm) == NULL) {
  34.380 +        g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
  34.381 +        return NULL;
  34.382 +    }    
  34.383 +
  34.384 +    if (hour_tm.tm_min>30) {
  34.385 +        hour_tm.tm_min = 30;
  34.386 +    } else if (hour_tm.tm_min>0) {
  34.387 +        hour_tm.tm_min = 0;
  34.388 +    }
  34.389 +        
  34.390 +    gchar hour1_str[10];
  34.391 +    strftime(hour1_str, 8, "%H:%M", &hour_tm);
  34.392 +    GtkWidget * lbl_hour1 = gtk_label_new(hour1_str);
  34.393 +    gtk_misc_set_alignment (GTK_MISC(lbl_hour1), 0.0, 0.5);    
  34.394 +	
  34.395 +    hour_tm.tm_hour++;
  34.396 +    gchar hour2_str[10];    
  34.397 +    strftime(hour2_str, 8, "%H:%M", &hour_tm);
  34.398 +    GtkWidget * lbl_hour2 = gtk_label_new(hour2_str);
  34.399 +    gtk_misc_set_alignment (GTK_MISC(lbl_hour2), 0.0, 0.5);        
  34.400 +
  34.401 +    hour_tm.tm_hour++;
  34.402 +	gchar hour3_str[10];    
  34.403 +    strftime(hour3_str, 8, "%H:%M", &hour_tm);
  34.404 +    GtkWidget * lbl_hour3 = gtk_label_new(hour3_str);
  34.405 +    gtk_misc_set_alignment (GTK_MISC(lbl_hour3), 0.0, 0.5);        
  34.406 +    
  34.407 +    gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
  34.408 +                        lbl_hour1, TRUE, TRUE, 0);                    
  34.409 +    gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
  34.410 +                        lbl_hour2, TRUE, TRUE, 0);                    
  34.411 +    gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
  34.412 +                        lbl_hour3, TRUE, TRUE, 0); 
  34.413 + 
  34.414 +    gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
  34.415 +                        epg_programs_hours_hbox, FALSE, FALSE, 0);                        
  34.416 +}
  34.417 +
  34.418 +/******************************************************************************
  34.419 + *              INTERNAL CALLBACKS FOR STATE CHANGE                           *
  34.420 + *****************************************************************************/
  34.421 +static void 
  34.422 +mmyth_epg_grid_widget_deselect_service(MMythEpgGridWidget *mmyth_epg_grid_widget)
  34.423 +{
  34.424 +	EpgGridItem *epg_grid_item;
  34.425 +	
  34.426 +  	/* deselect*/
  34.427 +    if(mmyth_epg_grid_widget->selected_grid_item != NULL) {
  34.428 +    	epg_grid_item = 
  34.429 +            (EpgGridItem*) mmyth_epg_grid_widget->selected_grid_item->data;
  34.430 +    	gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_NORMAL);
  34.431 +    }            
  34.432 +}
  34.433 +
  34.434 +static void 
  34.435 +mmyth_epg_grid_widget_clicked (GtkWidget* widget, 
  34.436 +                               GdkEventExpose *event, gpointer data)
  34.437 +{           
  34.438 +    g_return_if_fail(data != NULL);
  34.439 +
  34.440 +    GList *epg_grid_item_list = (GList *) data;
  34.441 +    EpgGridItem *epg_grid_item = (EpgGridItem *) epg_grid_item_list->data;
  34.442 +
  34.443 +    /* update the selected service */
  34.444 +    mmyth_epg_grid_widget_update_service( epg_grid_item->object, (GList*) data );       
  34.445 +}
  34.446 +
  34.447 +void
  34.448 +mmyth_epg_grid_widget_update_service(MMythEpgGridWidget * object,
  34.449 +                                     GList *selected_grid_list)
  34.450 +{
  34.451 +    g_return_if_fail(object != NULL);
  34.452 +    g_return_if_fail(selected_grid_list != NULL);
  34.453 +		
  34.454 +	EpgGridItem *epg_grid_item = (EpgGridItem *) selected_grid_list->data;
  34.455 +
  34.456 +    mmyth_epg_grid_widget_deselect_service(epg_grid_item->object);
  34.457 +
  34.458 +    /* updating current selected schedule_item and schedule_list*/
  34.459 +    object->selected_grid_item = selected_grid_list;
  34.460 +    
  34.461 +    /* set state of the event box */
  34.462 +    gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_SELECTED);
  34.463 +    /* emit update signal for listeners */
  34.464 +    g_signal_emit(object, 
  34.465 +                  mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL],
  34.466 +                  0,
  34.467 +                  (gpointer) epg_grid_item);
  34.468 +}
  34.469 +
  34.470 +static GtkWidget * 
  34.471 +create_event_box_lbl(gchar *str, int width, const GdkColor *bg_color, 
  34.472 +                     const GdkColor *fg_color) 
  34.473 +{
  34.474 +    GtkWidget *event_box = gtk_event_box_new();
  34.475 +	GtkWidget *lbl = gtk_label_new(str);
  34.476 +    gtk_label_set_ellipsize(GTK_LABEL(lbl), PANGO_ELLIPSIZE_END);
  34.477 +
  34.478 +    gtk_widget_modify_bg(event_box, GTK_STATE_NORMAL, bg_color);    
  34.479 +    gtk_widget_modify_fg(lbl, GTK_STATE_NORMAL, fg_color);    
  34.480 +    
  34.481 +    /* selected colors are const*/
  34.482 +    GdkColor selected_bg_color;
  34.483 +    selected_bg_color.red = 100;
  34.484 +    selected_bg_color.green = 40000;
  34.485 +    selected_bg_color.blue = 100;        
  34.486 +
  34.487 +    GdkColor selected_fg_color;
  34.488 +    selected_fg_color.red = 100;
  34.489 +    selected_fg_color.green = 100;
  34.490 +    selected_fg_color.blue = 100;        
  34.491 +            
  34.492 +    gtk_widget_modify_bg(event_box, GTK_STATE_SELECTED, &selected_bg_color);    
  34.493 +    gtk_widget_modify_fg(lbl, GTK_STATE_SELECTED, &selected_fg_color);    
  34.494 +    
  34.495 +    gtk_misc_set_alignment (GTK_MISC(lbl), 0.0, 0.5);    
  34.496 +	gtk_container_add (GTK_CONTAINER (event_box),
  34.497 +                       lbl);
  34.498 +	gtk_widget_set_size_request(event_box, width, -1);
  34.499 +	                       
  34.500 +    return event_box;
  34.501 +}
  34.502 +
  34.503 +/******************************************************************************
  34.504 + *                            METHODS                                         *
  34.505 + *****************************************************************************/
  34.506 +
  34.507 +/* Callback for hardware keys */
  34.508 +gboolean
  34.509 +mmyth_epg_grid_widget_key_press (MMythEpgGridWidget * object, 
  34.510 +                                 GtkWidget * widget, GdkEventKey * event)
  34.511 +{
  34.512 +    MMythEpgGridWidgetPrivate *private = 
  34.513 +        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(object);
  34.514 +  
  34.515 +    EpgGridItem *epg_grid_item;
  34.516 +    GList *tmp;
  34.517 +    
  34.518 +    /* List of selected_grid_item */
  34.519 +    GList *selected_view_model;
  34.520 +    
  34.521 +    gint channel_index;
  34.522 +    
  34.523 +	if(object->selected_grid_item == NULL) {
  34.524 +        g_warning ("No program selected");
  34.525 +	    return FALSE;
  34.526 +	} 
  34.527 +    
  34.528 +    epg_grid_item = (EpgGridItem*) object->selected_grid_item->data;    
  34.529 +    
  34.530 +    channel_index = private->selected_channel_index;
  34.531 +    
  34.532 +    switch (event->keyval) {
  34.533 +        case GDK_Up:        
  34.534 +            selected_view_model = g_list_nth( object->epg_view_model, channel_index - 1 );
  34.535 +            if(selected_view_model != NULL) {
  34.536 +                private->selected_channel_index = channel_index - 1;
  34.537 +   	            tmp = (GList *) selected_view_model->data;               
  34.538 +                /* TODO: select a better centralized item 
  34.539 +                   currently is picking the 1st or last item */
  34.540 +                if(g_list_next(object->selected_grid_item) == NULL &&
  34.541 +                   g_list_previous(object->selected_grid_item) != NULL) {
  34.542 +                    /* in this case the new selected will be the last */ 
  34.543 +                    tmp = g_list_last(tmp);
  34.544 +                }
  34.545 +
  34.546 +	            /* update the selected service */
  34.547 +                mmyth_epg_grid_widget_update_service( object, tmp );
  34.548 +            }    
  34.549 +        return TRUE;         
  34.550 +        case GDK_Down:
  34.551 +            selected_view_model = g_list_nth( object->epg_view_model, channel_index + 1 );            
  34.552 +            if(selected_view_model != NULL) {   	            
  34.553 +                private->selected_channel_index = channel_index + 1;
  34.554 +   	            tmp = (GList *) selected_view_model->data;
  34.555 +                /* TODO: select a better centralized item 
  34.556 +                   currently is picking the 1st or last item */
  34.557 +                if(g_list_next(object->selected_grid_item) == NULL &&
  34.558 +                   g_list_previous(object->selected_grid_item) != NULL) {
  34.559 +                    /* in this case the new selected will be the last */ 
  34.560 +                    tmp = g_list_last(tmp);
  34.561 +                }
  34.562 +
  34.563 +	            /* update the selected service */
  34.564 +                mmyth_epg_grid_widget_update_service( object, tmp );
  34.565 +            }
  34.566 +        return TRUE;        
  34.567 +        case GDK_Left:    
  34.568 +            tmp = g_list_previous( object->selected_grid_item );
  34.569 +            if(tmp != NULL) {
  34.570 +	            /* update the selected service */
  34.571 +                mmyth_epg_grid_widget_update_service( object, tmp );
  34.572 +            }
  34.573 +        return TRUE;        
  34.574 +        case GDK_Right:
  34.575 +            tmp = g_list_next( object->selected_grid_item );
  34.576 +            if(tmp != NULL) {
  34.577 +	            /* update the selected service */
  34.578 +                mmyth_epg_grid_widget_update_service( object, tmp );
  34.579 +            }
  34.580 +        return TRUE;        
  34.581 +	    default:
  34.582 +	    return TRUE;
  34.583 +    }
  34.584 +    
  34.585 +    return FALSE;
  34.586 +}
  34.587 +
  34.588 +static void 
  34.589 +mmyth_epg_grid_widget_fill_programinfos (MMythEpgGridWidgetPrivate *private)
  34.590 +{
  34.591 +    GList *channels_list = NULL;
  34.592 +    int y;
  34.593 +
  34.594 +    if ((private->mmyth_epg != NULL) &&
  34.595 +	   	(gmyth_epg_get_channel_list (private->mmyth_epg, &channels_list) < 0 )) {
  34.596 +			private->channel_list = NULL;
  34.597 +			return;
  34.598 +    }
  34.599 +    
  34.600 +    private->channel_list = channels_list;
  34.601 +    
  34.602 +    for (y = 0; y < private->DISPLAY_CHANS && channels_list; y++) {
  34.603 +        GMythChannelInfo *channel_info = (GMythChannelInfo *) channels_list->data;
  34.604 +
  34.605 +        mmyth_epg_grid_widget_fill_program_row_infos(
  34.606 +                            private, channel_info->channel_ID, y);
  34.607 +
  34.608 +        channels_list = g_list_next (channels_list);
  34.609 +    }
  34.610 +}
  34.611 +
  34.612 +static void 
  34.613 +mmyth_epg_grid_widget_fill_program_row_infos(MMythEpgGridWidgetPrivate *private,
  34.614 +                                             guint chanNum, guint row)
  34.615 +{    
  34.616 +    gint res =  gmyth_epg_get_program_list (private->mmyth_epg,
  34.617 +    					&(private->program_list[row]),
  34.618 +                        chanNum, private->current_start_time, 
  34.619 +                        private->current_end_time);
  34.620 +                        
  34.621 +    if (res < 0) {
  34.622 +    	g_warning ("[%s] Error while retrieving epg programs", __FUNCTION__);
  34.623 +    }
  34.624 +}
  34.625 +    
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/gmyth/src/gui/mmyth_epg_grid_widget.h	Wed Sep 20 23:45:35 2006 +0100
    35.3 @@ -0,0 +1,74 @@
    35.4 +#ifndef __MMYTH_EPG_GRID_WIDGET_H__
    35.5 +#define __MMYTH_EPG_GRID_WIDGET_H__
    35.6 +
    35.7 +#include <glib-object.h>
    35.8 +#include <gdk/gdk.h>
    35.9 +#include <gtk/gtkvbox.h>
   35.10 +#include <gtk/gtkeventbox.h>
   35.11 +
   35.12 +#include "gmyth_common.h"
   35.13 +
   35.14 +#define MAX_DISPLAY_CHANS 4
   35.15 +
   35.16 +#define G_BEGIN_DECLS
   35.17 +
   35.18 +#define MMYTH_EPG_GRID_WIDGET_TYPE               (mmyth_epg_grid_widget_get_type ())
   35.19 +#define MMYTH_EPG_GRID_WIDGET(obj)               (GTK_CHECK_CAST ((obj), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidget))
   35.20 +#define MMYTH_EPG_GRID_WIDGET_CLASS(klass)       (GTK_CHECK_CLASS_CAST ((klass), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidgetClass))
   35.21 +#define IS_MMYTH_EPG_GRID_WIDGET(obj)            (GTK_CHECK_TYPE ((obj), MMYTH_EPG_GRID_WIDGET_TYPE))
   35.22 +#define IS_MMYTH_EPG_GRID_WIDGET_CLASS(klass)    (GTK_CHECK_CLASS_TYPE ((klass), MMYTH_EPG_GRID_WIDGET_TYPE))
   35.23 +#define MMYTH_EPG_GRID_WIDGET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidgetClass))
   35.24 +#define MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(obj)   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MMYTH_EPG_GRID_WIDGET_TYPE, MMythEpgGridWidgetPrivate))
   35.25 +
   35.26 +
   35.27 +typedef struct _MMythEpgGridWidget         MMythEpgGridWidget;
   35.28 +typedef struct _MMythEpgGridWidgetClass    MMythEpgGridWidgetClass;
   35.29 +typedef struct _MMythEpgGridWidgetPrivate  MMythEpgGridWidgetPrivate;
   35.30 +
   35.31 +struct _MMythEpgGridWidgetClass
   35.32 +{
   35.33 +  GtkEventBoxClass parent_class;
   35.34 +
   35.35 +  /* callbacks */
   35.36 +  /* no one for now */
   35.37 +};
   35.38 +
   35.39 +struct _MMythEpgGridWidget
   35.40 +{
   35.41 +    GtkEventBox event_box;
   35.42 +
   35.43 +    /* Selected Widgets Logic*/
   35.44 +    /* List os Service Model in the current view
   35.45 +     * the data of this list are GList for the programs
   35.46 +     * of each service */
   35.47 +    GList *epg_view_model;
   35.48 +
   35.49 +    /* Selected Schedule Item*/
   35.50 +    GList *selected_grid_item;  
   35.51 +};
   35.52 +
   35.53 +
   35.54 +GType          mmyth_epg_grid_widget_get_type        (void);
   35.55 +GtkWidget*     mmyth_epg_grid_widget_new             (void);
   35.56 +/*DVBHScheduleEvent*    mmyth_epg_grid_get_selected_schedule  (MMythEpgGridWidget * object);*/
   35.57 +void           mmyth_epg_grid_widget_update_service  (MMythEpgGridWidget * object, 
   35.58 +                                                      GList *epg_grid_item_node);
   35.59 +gboolean       mmyth_epg_grid_widget_key_press       (MMythEpgGridWidget * object, 
   35.60 +                                                      GtkWidget * widget, 
   35.61 +                                                      GdkEventKey * event);
   35.62 +
   35.63 +typedef struct _EpgGridItem EpgGridItem;
   35.64 +
   35.65 +/* FIXME: auxiliary struct */
   35.66 +struct _EpgGridItem {
   35.67 +
   35.68 +    GMythProgramInfo *proginfo;
   35.69 +    GtkWidget *event_box;
   35.70 +
   35.71 +    /* for callback purposes */
   35.72 +    MMythEpgGridWidget *object;
   35.73 +};
   35.74 +
   35.75 +#define G_END_DECLS
   35.76 +
   35.77 +#endif /* __MMYTH_EPG_GRID_WIDGET_H__ */
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/gmyth/src/gui/mmyth_recordui.c	Wed Sep 20 23:45:35 2006 +0100
    36.3 @@ -0,0 +1,332 @@
    36.4 +#include<gtk/gtk.h>
    36.5 +#include<glib.h>
    36.6 +#include <sys/types.h>
    36.7 +#include <sys/stat.h>
    36.8 +#include <unistd.h>
    36.9 +#include <string.h>
   36.10 +#include <stdio.h>
   36.11 +#include <stdlib.h>
   36.12 +
   36.13 +#include "mmyth_ui.h"
   36.14 +#include "mmyth_recordui.h"
   36.15 +
   36.16 +/* GMyth library includes */
   36.17 +#include "gmyth_scheduler.h"
   36.18 +#include "gmyth_util.h"
   36.19 +
   36.20 +enum {
   36.21 +	START_DATE_COLUMN = 0,
   36.22 +	TITLE_COLUMN,
   36.23 +	CHAN_ID_COLUMN,
   36.24 +	END_TIME_COLUMN,
   36.25 +	RECORD_ID_COLUMN,
   36.26 +	BASENAME_COLUMN,
   36.27 +	N_COLUMNS
   36.28 +};
   36.29 +
   36.30 +gboolean
   36.31 +mmyth_recordui_reload_all (MMythRecordUI *recordui)
   36.32 +{
   36.33 +	gboolean res = FALSE;
   36.34 +
   36.35 +	res = mmyth_recordui_reload_schedule (recordui);
   36.36 +		
   36.37 +	res = res & mmyth_recordui_reload_record (recordui);
   36.38 +	
   36.39 +	
   36.40 +	if (!res)
   36.41 +		g_warning ("[%s] Error while reloading schedule and recording content", __FUNCTION__);
   36.42 +		
   36.43 +	return res;
   36.44 +}
   36.45 +
   36.46 +gboolean
   36.47 +mmyth_recordui_reload_schedule (MMythRecordUI *recordui)
   36.48 +{
   36.49 +	gint new_row = 0;
   36.50 +	ScheduleInfo *schedule_info;
   36.51 +	GList *schedule_list;
   36.52 +	GtkTreeIter iter;
   36.53 +    GString *start_date_time = NULL;
   36.54 +    GString *end_date_time = NULL;
   36.55 +    GString *str_aux = g_string_new("");
   36.56 +	gint res;
   36.57 +
   36.58 +	gtk_tree_store_clear(recordui->sch_tree_store);	
   36.59 +
   36.60 +	res = gmyth_scheduler_get_schedule_list(recordui->scheduler, &(schedule_list));
   36.61 +	if (res < 0) {
   36.62 +		g_warning ("[%s] Retrieved NULL list of scheduled data from database", 
   36.63 +                   __FUNCTION__);
   36.64 +		return FALSE;
   36.65 +	}
   36.66 +
   36.67 +	for ( ; schedule_list; schedule_list = schedule_list->next) {
   36.68 + 	  	schedule_info = (ScheduleInfo*) schedule_list->data;
   36.69 +
   36.70 +  	  	gtk_tree_store_insert(recordui->sch_tree_store, &iter, NULL, new_row++);
   36.71 +        
   36.72 +        start_date_time = gmyth_util_time_to_string(schedule_info->start_time);
   36.73 +        end_date_time = gmyth_util_time_to_string(schedule_info->end_time);
   36.74 +        
   36.75 +        g_string_printf(str_aux, "%d", schedule_info->channel_id);
   36.76 +        
   36.77 +	  	gtk_tree_store_set(recordui->sch_tree_store, &iter,
   36.78 +	  		START_DATE_COLUMN, start_date_time->str, 
   36.79 +	  		TITLE_COLUMN, schedule_info->title->str,
   36.80 +	  		CHAN_ID_COLUMN, str_aux->str,
   36.81 +	  		END_TIME_COLUMN, end_date_time->str, //It doesn't appear
   36.82 +	  		RECORD_ID_COLUMN, schedule_info->record_id, 
   36.83 +			-1); //the last line is a hidden item to be used in searching tasks
   36.84 + 	}
   36.85 +  	
   36.86 +  	g_debug ("[%s] %d lines added to schedule list UI", __FUNCTION__, new_row);
   36.87 +  	
   36.88 +    /* free allocated memory */
   36.89 +    if(!start_date_time)
   36.90 +        g_string_free(start_date_time, FALSE);
   36.91 +    if(!end_date_time)
   36.92 +        g_string_free(end_date_time, FALSE);
   36.93 +    g_string_free(str_aux,  FALSE);
   36.94 +    
   36.95 +  	return TRUE;
   36.96 +}
   36.97 +
   36.98 +gboolean
   36.99 +mmyth_recordui_reload_record (MMythRecordUI *recordui)
  36.100 +{
  36.101 +	gint new_row = 0;
  36.102 +	RecordedInfo *recorded_info;
  36.103 +	GList *record_list = NULL;
  36.104 +	GtkTreeIter iter;
  36.105 +    GString *start_date_time = NULL;
  36.106 +    GString *end_date_time = NULL;
  36.107 +    GString *str_aux = g_string_new("");
  36.108 +	gint res;
  36.109 +	
  36.110 +	gtk_tree_store_clear(recordui->rec_tree_store);		
  36.111 +
  36.112 +	res = gmyth_scheduler_get_recorded_list(recordui->scheduler, &record_list);
  36.113 +	if (res < 0) {
  36.114 +		g_warning ("[%s] Retrieved NULL list of recorded data from database", __FUNCTION__);
  36.115 +		return FALSE;
  36.116 +	}
  36.117 +	
  36.118 +	for (; record_list; record_list = record_list->next) {
  36.119 + 	  	recorded_info = (RecordedInfo*) record_list->data;
  36.120 +
  36.121 +  	  	gtk_tree_store_insert(recordui->rec_tree_store, &iter, NULL, new_row++);
  36.122 +
  36.123 +        start_date_time = gmyth_util_time_to_string(recorded_info->start_time);
  36.124 +        end_date_time = gmyth_util_time_to_string(recorded_info->end_time);
  36.125 +
  36.126 +        g_string_printf(str_aux, "%d", recorded_info->channel_id);
  36.127 +
  36.128 +	  	gtk_tree_store_set(recordui->rec_tree_store, &iter,
  36.129 +	  		START_DATE_COLUMN, start_date_time->str, 
  36.130 +	  		TITLE_COLUMN, recorded_info->title->str,
  36.131 +	  		CHAN_ID_COLUMN, str_aux->str,
  36.132 +	  		END_TIME_COLUMN, end_date_time->str, //It doesn't appear
  36.133 +	  		RECORD_ID_COLUMN, recorded_info->record_id,
  36.134 +			BASENAME_COLUMN, recorded_info->basename->str, -1); 
  36.135 +            //the last line is a hidden item to be used in searching tasks	  		
  36.136 +  	}
  36.137 +  	
  36.138 +  	g_debug ("[%s] %d lines added to record list UI", __FUNCTION__, new_row);
  36.139 +  	  	
  36.140 +  	return TRUE;
  36.141 +}
  36.142 +
  36.143 +
  36.144 +MMythRecordUI*
  36.145 +mmyth_recordui_new(void)
  36.146 +{
  36.147 +	MMythRecordUI *recordui = g_new0 (MMythRecordUI, 1);
  36.148 +	
  36.149 +	recordui->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  36.150 +	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (recordui->scrolled_window),
  36.151 +			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  36.152 +
  36.153 +	recordui->viewport = gtk_viewport_new (NULL, NULL);
  36.154 +  	gtk_container_add (GTK_CONTAINER (recordui->scrolled_window), recordui->viewport);
  36.155 +
  36.156 +  	recordui->notebook = gtk_notebook_new ();
  36.157 +  	gtk_container_set_border_width (GTK_CONTAINER (recordui->notebook), 1);
  36.158 +  	gtk_notebook_set_scrollable (GTK_NOTEBOOK (recordui->notebook), TRUE);
  36.159 +  	gtk_notebook_popup_enable (GTK_NOTEBOOK (recordui->notebook));
  36.160 +  	gtk_container_add (GTK_CONTAINER (recordui->viewport), recordui->notebook);
  36.161 +  	gtk_notebook_popup_disable(GTK_NOTEBOOK (recordui->notebook));
  36.162 +
  36.163 +	/* Schedule tab */
  36.164 +  	recordui->sch_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  36.165 +  	gtk_container_add (GTK_CONTAINER (recordui->notebook), recordui->sch_scrolled_window);
  36.166 +  	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (recordui->sch_scrolled_window), 
  36.167 +                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  36.168 +  	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (recordui->sch_scrolled_window), 
  36.169 +                                         GTK_SHADOW_IN);
  36.170 +
  36.171 +    /* The basename column in the sched_tree_store is not being used*/
  36.172 +  	recordui->sch_tree_store = 
  36.173 +        gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
  36.174 +  		                    G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING );
  36.175 +    
  36.176 +  	recordui->sch_treeview = 
  36.177 +        gtk_tree_view_new_with_model(GTK_TREE_MODEL(recordui->sch_tree_store));
  36.178 +  	gtk_container_add (GTK_CONTAINER (recordui->sch_scrolled_window), 
  36.179 +                       recordui->sch_treeview);
  36.180 +  	recordui->sch_renderer = gtk_cell_renderer_text_new();
  36.181 +  	//g_object_set(G_OBJECT(renderer1), "foreground", "green", "background", "black", NULL);
  36.182 +  	recordui->sch_column1 = 
  36.183 +        gtk_tree_view_column_new_with_attributes("Start time", recordui->sch_renderer, 
  36.184 +                                                 "text", START_DATE_COLUMN, NULL);
  36.185 +  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview), 
  36.186 +                                recordui->sch_column1); 
  36.187 +  	recordui->sch_column2 = 
  36.188 +        gtk_tree_view_column_new_with_attributes("Title", recordui->sch_renderer, 
  36.189 +                                                 "text", TITLE_COLUMN, NULL);
  36.190 +  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview), 
  36.191 +                                recordui->sch_column2);
  36.192 +  	recordui->sch_column3 = 
  36.193 +        gtk_tree_view_column_new_with_attributes("Channel", recordui->sch_renderer, 
  36.194 +                                                 "text", CHAN_ID_COLUMN, NULL);
  36.195 +  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview), 
  36.196 +                                recordui->sch_column3);
  36.197 +  	gtk_tree_view_column_set_resizable(recordui->sch_column1, TRUE);
  36.198 +  	gtk_tree_view_column_set_resizable(recordui->sch_column2, TRUE);
  36.199 +  	gtk_tree_view_column_set_resizable(recordui->sch_column3, TRUE);
  36.200 +  	gtk_tree_view_column_set_reorderable(recordui->sch_column1, TRUE);
  36.201 +  	gtk_tree_view_column_set_reorderable(recordui->sch_column2, TRUE);
  36.202 +  	gtk_tree_view_column_set_reorderable(recordui->sch_column3, TRUE);  	  	  	  	
  36.203 +//  recordui->sch_column4 = 
  36.204 +//      gtk_tree_view_column_new_with_attributes("", recordui->sch_renderer, "text", END_TIME_COLUMN, NULL);
  36.205 +//  gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->sch_treeview), 
  36.206 +//                                            recordui->sch_column4);
  36.207 +
  36.208 +  	recordui->sch_label = gtk_label_new (("Schedule"));
  36.209 +  	gtk_notebook_set_tab_label (GTK_NOTEBOOK (recordui->notebook), 
  36.210 +                                gtk_notebook_get_nth_page (
  36.211 +                                               GTK_NOTEBOOK (recordui->notebook), 0), 
  36.212 +                                recordui->sch_label);
  36.213 +
  36.214 +  // Record items  tab
  36.215 +  //   g_object_set(G_OBJECT(renderer2), "foreground", "blue", NULL);
  36.216 +  	recordui->rec_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  36.217 +  	gtk_container_add (GTK_CONTAINER (recordui->notebook), 
  36.218 +                       recordui->rec_scrolled_window);
  36.219 +  	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (recordui->rec_scrolled_window), 
  36.220 +                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  36.221 +  	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (recordui->rec_scrolled_window), 
  36.222 +                                         GTK_SHADOW_IN);
  36.223 +
  36.224 +  	recordui->rec_tree_store = 
  36.225 +        gtk_tree_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
  36.226 +                	        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
  36.227 +  	recordui->rec_treeview = 
  36.228 +        gtk_tree_view_new_with_model(GTK_TREE_MODEL(recordui->rec_tree_store));
  36.229 +  	gtk_container_add (GTK_CONTAINER (recordui->rec_scrolled_window), 
  36.230 +                       recordui->rec_treeview);
  36.231 +  	recordui->rec_renderer = gtk_cell_renderer_text_new();
  36.232 +  	//g_object_set(G_OBJECT(renderer1), "foreground", "green", "background", "black", NULL);
  36.233 + 
  36.234 +  	recordui->rec_column1 = 
  36.235 +        gtk_tree_view_column_new_with_attributes("Start time", recordui->rec_renderer, 
  36.236 +                                                 "text", START_DATE_COLUMN, NULL);
  36.237 +  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview), 
  36.238 +                                recordui->rec_column1);
  36.239 +  	recordui->rec_column2 = 
  36.240 +        gtk_tree_view_column_new_with_attributes("Title", recordui->rec_renderer, 
  36.241 +                                                 "text", TITLE_COLUMN, NULL);
  36.242 +  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview), 
  36.243 +                                recordui->rec_column2);
  36.244 +  	recordui->rec_column3 = 
  36.245 +        gtk_tree_view_column_new_with_attributes("Channel", recordui->rec_renderer, 
  36.246 +                                                 "text", CHAN_ID_COLUMN, NULL);
  36.247 +  	gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview), 
  36.248 +                                recordui->rec_column3);
  36.249 +  	gtk_tree_view_column_set_resizable(recordui->rec_column1, TRUE);
  36.250 +  	gtk_tree_view_column_set_resizable(recordui->rec_column2, TRUE);
  36.251 +  	gtk_tree_view_column_set_resizable(recordui->rec_column3, TRUE);
  36.252 +  	gtk_tree_view_column_set_reorderable(recordui->rec_column1, TRUE);
  36.253 +  	gtk_tree_view_column_set_reorderable(recordui->rec_column2, TRUE);
  36.254 +  	gtk_tree_view_column_set_reorderable(recordui->rec_column3, TRUE);
  36.255 +//  recordui->rec_column4 = gtk_tree_view_column_new_with_attributes("", recordui->rec_renderer, "text", END_TIME_COLUMN, NULL);
  36.256 +//  gtk_tree_view_append_column(GTK_TREE_VIEW(recordui->rec_treeview), recordui->rec_column4);
  36.257 +
  36.258 +  	recordui->rec_label = gtk_label_new (("Recorded"));
  36.259 +  	gtk_notebook_set_tab_label (GTK_NOTEBOOK (recordui->notebook), 
  36.260 +                                gtk_notebook_get_nth_page (
  36.261 +                                      GTK_NOTEBOOK (recordui->notebook), 1), 
  36.262 +                                recordui->rec_label);
  36.263 +  
  36.264 +  	// Gets the mmyth scheduler manager
  36.265 +  	recordui->scheduler = gmyth_scheduler_new ();
  36.266 +    
  36.267 +    /* init connection to the backend */
  36.268 +    gmyth_scheduler_connect (recordui->scheduler);
  36.269 +    
  36.270 +	return recordui;
  36.271 +}
  36.272 +
  36.273 +void
  36.274 +mmyth_recordui_free (MMythRecordUI *recordui)
  36.275 +{
  36.276 +	// FIXME: Release memory here!
  36.277 +    /* close connection to the backend */
  36.278 +    gmyth_scheduler_disconnect (recordui->scheduler);
  36.279 +}
  36.280 +
  36.281 +void
  36.282 +mmyth_recordui_delete_selected (GtkButton *button, MMythRecordUI *recordui)
  36.283 +{
  36.284 +	GtkTreeSelection *selection;
  36.285 +	GtkTreeModel *list_store;
  36.286 +	GtkTreeIter iter;
  36.287 +	int index;
  36.288 +	int curr_page = 0;
  36.289 +	
  36.290 +	curr_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(recordui->notebook));
  36.291 +
  36.292 +	if ( curr_page == 0) {
  36.293 +		selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(recordui->sch_treeview));
  36.294 +		if (selection != NULL) {
  36.295 +			gtk_tree_selection_get_selected(selection, &list_store, &iter);
  36.296 +			gtk_tree_model_get(list_store, &iter, RECORD_ID_COLUMN, &index, -1);
  36.297 +			gmyth_scheduler_delete_schedule(recordui->scheduler, index);
  36.298 +			mmyth_recordui_reload_schedule (recordui);
  36.299 +			return;
  36.300 +		}
  36.301 +			
  36.302 +	} else if (curr_page == 1) {
  36.303 +		selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(recordui->rec_treeview));
  36.304 +		if (selection != NULL) {
  36.305 +			gtk_tree_selection_get_selected(selection, &list_store, &iter);
  36.306 +			gtk_tree_model_get(list_store, &iter, RECORD_ID_COLUMN, &index, -1);
  36.307 +			gmyth_scheduler_delete_recorded(recordui->scheduler, index);
  36.308 +			mmyth_recordui_reload_record (recordui);
  36.309 +			return;
  36.310 +		}
  36.311 +	}
  36.312 +	
  36.313 +	g_warning ("[%s] None element was removed from the list", __FUNCTION__);
  36.314 +}
  36.315 +
  36.316 +/* FIXME: change this function name, it is returning the 
  36.317 + * basename_column that represents the nuv filename of 
  36.318 + * the recorded content */
  36.319 +gchar*
  36.320 +mmyth_recordui_get_selected_recorded (MMythRecordUI *recordui)
  36.321 +{
  36.322 +	GtkTreeSelection *selection = NULL;
  36.323 +	GtkTreeModel *list_store = NULL;
  36.324 +	GtkTreeIter iter;
  36.325 +	gchar *path = NULL;
  36.326 +
  36.327 +	/* returning nuv filename, basename_column */
  36.328 +	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(recordui->rec_treeview));
  36.329 +	if (gtk_tree_selection_get_selected (selection, &list_store, &iter)) {
  36.330 +		gtk_tree_model_get(list_store, &iter, BASENAME_COLUMN, &path, -1);
  36.331 +	}
  36.332 +
  36.333 +	// FIXME: MOVE THIS TO OTHER PLACE
  36.334 +	return path;
  36.335 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/gmyth/src/gui/mmyth_recordui.h	Wed Sep 20 23:45:35 2006 +0100
    37.3 @@ -0,0 +1,48 @@
    37.4 +#ifndef MMYTH_RECORD_H_
    37.5 +#define MMYTH_RECORD_H_
    37.6 +
    37.7 +#include "gmyth_scheduler.h"
    37.8 +
    37.9 +typedef struct _MMythRecordUI
   37.10 +{
   37.11 +	GtkWidget *scrolled_window;
   37.12 +	GtkWidget *viewport;
   37.13 +	GtkWidget *notebook;
   37.14 +	
   37.15 +	GtkWidget *rec_scrolled_window;
   37.16 +	GtkWidget *sch_scrolled_window;
   37.17 +	GtkWidget *rec_treeview;
   37.18 +	GtkWidget *sch_treeview;
   37.19 +	GtkWidget *rec_label;
   37.20 +	GtkWidget *sch_label;
   37.21 +	
   37.22 +	GtkTreeViewColumn *rec_column1;
   37.23 +	GtkTreeViewColumn *rec_column2;
   37.24 +	GtkTreeViewColumn *rec_column3;
   37.25 +	GtkTreeViewColumn *rec_column4;
   37.26 +	GtkTreeViewColumn *sch_column1;
   37.27 +	GtkTreeViewColumn *sch_column2;
   37.28 +	GtkTreeViewColumn *sch_column3;
   37.29 +	GtkTreeViewColumn *sch_column4;
   37.30 +	
   37.31 +	GtkCellRenderer *rec_renderer;
   37.32 +	GtkCellRenderer *sch_renderer;
   37.33 +
   37.34 +	GtkTreeStore *sch_tree_store;
   37.35 +	GtkTreeStore *rec_tree_store;
   37.36 +	
   37.37 +	GMythScheduler *scheduler;
   37.38 +	
   37.39 +} MMythRecordUI;
   37.40 +
   37.41 +MMythRecordUI* mmyth_recordui_new(void);
   37.42 +void mmyth_recordui_free (MMythRecordUI *recordui);
   37.43 +
   37.44 +void mmyth_recordui_delete_selected (GtkButton *button, MMythRecordUI *recordui);
   37.45 +gboolean mmyth_recordui_reload_all (MMythRecordUI *recordui);
   37.46 +gboolean mmyth_recordui_reload_schedule (MMythRecordUI *recordui);
   37.47 +gboolean mmyth_recordui_reload_record (MMythRecordUI *recordui);
   37.48 +
   37.49 +gchar* mmyth_recordui_get_selected_recorded (MMythRecordUI *recordui);
   37.50 +
   37.51 +#endif /*MMYTH_RECORD_H_*/
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/gmyth/src/gui/mmyth_schedulerui.c	Wed Sep 20 23:45:35 2006 +0100
    38.3 @@ -0,0 +1,368 @@
    38.4 +#include <gtk/gtk.h>
    38.5 +#include <glib.h>
    38.6 +#include <glib/gprintf.h>
    38.7 +#include <sys/types.h>
    38.8 +#include <sys/stat.h>
    38.9 +#include <unistd.h>
   38.10 +#include <string.h>
   38.11 +#include <stdio.h>
   38.12 +
   38.13 +#include "mmyth_ui.h"
   38.14 +#include "mmyth_uicommon.h"
   38.15 +#include "mmyth_recordui.h"
   38.16 +#include "mmyth_schedulerui.h"
   38.17 +
   38.18 +/* GMyth library includes */
   38.19 +#include "gmyth_scheduler.h"
   38.20 +#include "gmyth_common.h"
   38.21 +#include "gmyth_epg.h"
   38.22 +
   38.23 +static void run_calendar_dialog (GtkButton *button, gpointer data);
   38.24 +
   38.25 +static void add_channel_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
   38.26 +static void add_time_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
   38.27 +static void add_date_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
   38.28 +static void add_duration_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
   38.29 +static void add_frequency_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
   38.30 +static void add_title_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox);
   38.31 +
   38.32 +MMythSchedulerUI*
   38.33 +mmyth_schedulerui_new (void)
   38.34 +{
   38.35 +	GtkWidget *scrolledwindow;	
   38.36 +	GtkWidget *viewport;	
   38.37 +	GtkWidget *head_hbox;
   38.38 +	GtkWidget *fields_vbox;
   38.39 +	GtkWidget *hseparator;
   38.40 +	GtkWidget *label;
   38.41 +
   38.42 +	MMythSchedulerUI *scheduler_ui = g_new0 (MMythSchedulerUI, 1);
   38.43 +	
   38.44 +	scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
   38.45 +	scheduler_ui->main_widget = scrolledwindow;
   38.46 +	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
   38.47 +  			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
   38.48 +
   38.49 +	//Is this needed?  
   38.50 +	viewport = gtk_viewport_new (NULL, NULL);
   38.51 +	gtk_container_add (GTK_CONTAINER (scrolledwindow), viewport);
   38.52 +
   38.53 +	//Is this needed?
   38.54 +	head_hbox = gtk_hbox_new (FALSE, 0);
   38.55 +	gtk_container_add (GTK_CONTAINER (viewport), head_hbox);
   38.56 +
   38.57 +	fields_vbox = gtk_vbox_new (FALSE, 0);
   38.58 +	gtk_box_pack_start (GTK_BOX (head_hbox), fields_vbox, TRUE, TRUE, 0);
   38.59 +	gtk_container_set_border_width (GTK_CONTAINER (fields_vbox), 10);
   38.60 +
   38.61 +	label = gtk_label_new_with_mnemonic (("Manual Schedule Recording"));
   38.62 +	gtk_box_pack_start (GTK_BOX (fields_vbox), label, FALSE, FALSE, 0);
   38.63 +	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
   38.64 +
   38.65 +	hseparator = gtk_hseparator_new ();
   38.66 +	gtk_box_pack_start (GTK_BOX (fields_vbox), hseparator, FALSE, TRUE, 0);
   38.67 +
   38.68 +	add_channel_field (scheduler_ui, fields_vbox);
   38.69 +	add_time_field (scheduler_ui, fields_vbox);
   38.70 +	add_date_field (scheduler_ui, fields_vbox);
   38.71 +	add_duration_field (scheduler_ui, fields_vbox);
   38.72 +	add_frequency_field (scheduler_ui, fields_vbox);
   38.73 +	add_title_field (scheduler_ui, fields_vbox);
   38.74 +	
   38.75 +	return scheduler_ui;
   38.76 +}
   38.77 +
   38.78 +static void
   38.79 +set_date_from_calendar (GtkCalendar *calendar, gpointer data)
   38.80 +{
   38.81 +	char sched_date[24];
   38.82 +
   38.83 +	MMythSchedulerUI *scheduler_ui = (MMythSchedulerUI*) data;
   38.84 +
   38.85 +	// FIXME: Change this, save another value instead of month_temp, day_temp, ...	
   38.86 +	gtk_calendar_get_date(GTK_CALENDAR(calendar), 
   38.87 +		&(scheduler_ui->year_temp), &(scheduler_ui->month_temp), &(scheduler_ui->day_temp));
   38.88 +
   38.89 +	sched_date[23]='\0';
   38.90 +	g_sprintf(sched_date, "%04d %02d %02d (yyyy mm dd)",
   38.91 +		scheduler_ui->year_temp, scheduler_ui->month_temp+1, scheduler_ui->day_temp);
   38.92 +
   38.93 +	gtk_button_set_label(GTK_BUTTON(scheduler_ui->date_button), sched_date);
   38.94 +
   38.95 +	gtk_widget_destroy(scheduler_ui->calendar_dialog);
   38.96 +	scheduler_ui->calendar_dialog = NULL;
   38.97 +	scheduler_ui->calendar = NULL;
   38.98 +}
   38.99 +
  38.100 +//calendar
  38.101 +static void
  38.102 +run_calendar_dialog (GtkButton *button, gpointer data)
  38.103 +{
  38.104 +
  38.105 +	GtkWidget *dialog_vbox;
  38.106 +	MMythSchedulerUI *scheduler_ui = (MMythSchedulerUI*) data;
  38.107 +
  38.108 +	// calendar_dialog and calendar are been released at set_date_from_calendar ()
  38.109 +	scheduler_ui->calendar_dialog = gtk_dialog_new ();
  38.110 +	gtk_container_set_border_width (GTK_CONTAINER (scheduler_ui->calendar_dialog), 1);
  38.111 +  	gtk_window_set_title (GTK_WINDOW (scheduler_ui->calendar_dialog), "Select starting date");
  38.112 +  	gtk_window_set_position (GTK_WINDOW (scheduler_ui->calendar_dialog), GTK_WIN_POS_CENTER);
  38.113 +	gtk_window_set_decorated (GTK_WINDOW (scheduler_ui->calendar_dialog), FALSE);
  38.114 +
  38.115 +	dialog_vbox = GTK_DIALOG (scheduler_ui->calendar_dialog)->vbox;
  38.116 +
  38.117 +	scheduler_ui->calendar = gtk_calendar_new ();
  38.118 +
  38.119 +	gtk_box_pack_start (GTK_BOX (dialog_vbox), scheduler_ui->calendar, TRUE, TRUE, 0);
  38.120 +	gtk_calendar_display_options (GTK_CALENDAR (scheduler_ui->calendar),
  38.121 +        GTK_CALENDAR_SHOW_HEADING | GTK_CALENDAR_SHOW_DAY_NAMES);
  38.122 +
  38.123 +	gtk_widget_show_all (scheduler_ui->calendar_dialog);
  38.124 +
  38.125 +	g_signal_connect (G_OBJECT (scheduler_ui->calendar), "day-selected-double-click",
  38.126 +                      G_CALLBACK (set_date_from_calendar), data);
  38.127 +}
  38.128 +
  38.129 +
  38.130 +gboolean
  38.131 +mmyth_schedulerui_save (MMythSchedulerUI *scheduler_ui)
  38.132 +{
  38.133 +    GMythScheduler *scheduler;
  38.134 +	ScheduleInfo *schedule_info;
  38.135 +	GMythChannelInfo *channel_info;
  38.136 +
  38.137 +	GList *clist;
  38.138 +	gint index, duration;
  38.139 +    gint frequency;
  38.140 +    struct tm start_tm;
  38.141 +	
  38.142 +	schedule_info = g_new0(ScheduleInfo, 1);
  38.143 +    if(schedule_info == NULL) {
  38.144 +        g_warning ("Error allocating memory");
  38.145 +        return FALSE;
  38.146 +    }
  38.147 +        
  38.148 +    clist = scheduler_ui->channel_list;
  38.149 +      
  38.150 +    index = gtk_combo_box_get_active(GTK_COMBO_BOX(scheduler_ui->channel_combobox));
  38.151 +
  38.152 +    if (clist != NULL)
  38.153 +		clist = g_list_nth(clist, index);
  38.154 +    
  38.155 +    if (clist) {
  38.156 +	    g_debug ("[%s] New schedule: %d", __FUNCTION__, index);
  38.157 +    } else {
  38.158 +	    g_warning ("[%s] Error when adding new schedule", __FUNCTION__);
  38.159 +	    return FALSE;
  38.160 +    }
  38.161 +    
  38.162 +    channel_info = clist->data;
  38.163 +    
  38.164 +    /* initialize schedule_info */
  38.165 +    schedule_info->channel_id = channel_info->channel_ID;
  38.166 +    
  38.167 +    start_tm.tm_hour = 
  38.168 +        (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(scheduler_ui->hour_spinbutton));
  38.169 +	start_tm.tm_min = 
  38.170 +        (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(scheduler_ui->min_spinbutton));
  38.171 +    start_tm.tm_sec = 0;
  38.172 +
  38.173 +	start_tm.tm_mday = (gint)scheduler_ui->day_temp;
  38.174 +	start_tm.tm_mon =  (gint)scheduler_ui->month_temp;
  38.175 +	start_tm.tm_year = (gint)scheduler_ui->year_temp - 1900; //years since 1900
  38.176 +
  38.177 +    schedule_info->start_time = timelocal(&start_tm);
  38.178 +    if (schedule_info->start_time == (time_t)(-1)) {
  38.179 +        g_warning ("timelocal error!\n");
  38.180 +        return FALSE;
  38.181 +    }
  38.182 +
  38.183 +	duration = (gint) gtk_spin_button_get_value(
  38.184 +                        GTK_SPIN_BUTTON(scheduler_ui->duration_spinbutton));
  38.185 +    schedule_info->end_time = schedule_info->start_time + (duration*60);
  38.186 +
  38.187 +    /* TODO: frequency is not implemented yet */
  38.188 +	frequency = gtk_combo_box_get_active(GTK_COMBO_BOX(scheduler_ui->freq_combobox));
  38.189 +
  38.190 +	schedule_info->title = g_string_new("");
  38.191 +	g_string_printf(schedule_info->title, "%s", 
  38.192 +                    gtk_entry_get_text(GTK_ENTRY(scheduler_ui->title_entry)));
  38.193 +	
  38.194 +    /* FIXME: Architecture change to reuse the scheduler created in the recordui! */
  38.195 +    scheduler = gmyth_scheduler_new ();
  38.196 +
  38.197 +    gmyth_scheduler_connect(scheduler);
  38.198 +
  38.199 +    /* FIXME: set record_id = -1 to add a new schedule */
  38.200 +    schedule_info->record_id = -1;
  38.201 +    gmyth_scheduler_add_schedule (scheduler, schedule_info);
  38.202 +
  38.203 +    gmyth_scheduler_disconnect(scheduler);
  38.204 +    
  38.205 +    /* free allocated memory */
  38.206 +    g_object_unref (scheduler);
  38.207 +    g_free (schedule_info);
  38.208 +	
  38.209 +    return TRUE;
  38.210 +} 
  38.211 +
  38.212 +static GtkWidget*
  38.213 +add_line (GtkWidget *vbox, const gchar *str)
  38.214 +{
  38.215 +	GtkWidget *label;
  38.216 +	GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
  38.217 +
  38.218 +	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  38.219 +	gtk_container_set_border_width (GTK_CONTAINER (hbox), 3);
  38.220 +	
  38.221 +	label = gtk_label_new (str);
  38.222 +	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  38.223 +	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);	
  38.224 +
  38.225 +	return hbox;
  38.226 +}
  38.227 +
  38.228 +static void
  38.229 +add_channel_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
  38.230 +{
  38.231 +	GtkWidget *combobox;
  38.232 +	
  38.233 +	GtkWidget *hbox = add_line (vbox, "Channel:    ");
  38.234 +	
  38.235 +	combobox = gtk_combo_box_new_text ();
  38.236 +
  38.237 +	scheduler_ui->channel_combobox = combobox;
  38.238 +	gtk_box_pack_start (GTK_BOX (hbox), combobox, FALSE, FALSE, 0);
  38.239 +			
  38.240 +	GMythEPG *mmyth_epg = gmyth_epg_new ();
  38.241 +	if (!gmyth_epg_connect (mmyth_epg)) {
  38.242 +		// FIXME: Without this list the scheduler UI should not be shown!
  38.243 +		g_warning ("[%s] Error when getting list of channels", __FUNCTION__);
  38.244 +	}
  38.245 +  	
  38.246 +	if (gmyth_epg_get_channel_list (mmyth_epg, &(scheduler_ui->channel_list)) < 0) {
  38.247 +		g_debug ("[%s] Error while trying to retrieve channel list", __FUNCTION__);
  38.248 +	} else {
  38.249 + 		GList *clist =  scheduler_ui->channel_list;
  38.250 +		GMythChannelInfo *channel_info;
  38.251 +
  38.252 +		while (clist != NULL) {
  38.253 +  	  		channel_info = clist->data;
  38.254 +  	  		clist = clist->next;
  38.255 +  	  		gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->channel_combobox), 
  38.256 +                                       (channel_info->channel_name->str));
  38.257 +  		}
  38.258 +
  38.259 +       gtk_combo_box_set_active(GTK_COMBO_BOX (scheduler_ui->channel_combobox), 0);
  38.260 +  	}
  38.261 +}
  38.262 +
  38.263 +static void
  38.264 +add_time_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
  38.265 +{
  38.266 +	GtkWidget *label;
  38.267 +	GtkObject *spinbutton_adj;
  38.268 +	GtkWidget *hbox = add_line (vbox, "Time:         ");
  38.269 +
  38.270 +	time_t real_time;
  38.271 +	struct tm sched_time;
  38.272 +
  38.273 +	time(&real_time);
  38.274 +
  38.275 +    if (localtime_r((time_t *)&real_time, &sched_time) == NULL) {
  38.276 +        g_warning ("localtime_r error in mmyth_epg_grid_view!\n");
  38.277 +        return NULL;
  38.278 +    }
  38.279 + 
  38.280 +	if (sched_time.tm_min>30){
  38.281 +  		sched_time.tm_hour = sched_time.tm_hour+1;
  38.282 +  		sched_time.tm_min = 0;
  38.283 +	} else if (sched_time.tm_min>0) {
  38.284 +  		sched_time.tm_min = 30;
  38.285 +	}
  38.286 +
  38.287 +  	scheduler_ui->year_temp = (guint)sched_time.tm_year + 1900;
  38.288 +  	scheduler_ui->month_temp = (guint)sched_time.tm_mon;
  38.289 +  	scheduler_ui->day_temp = (guint)sched_time.tm_mday;
  38.290 +   
  38.291 +	//hour entry
  38.292 +	spinbutton_adj = gtk_adjustment_new (sched_time.tm_hour, 00, 23, 1, 10, 10);
  38.293 +	scheduler_ui->hour_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adj), 1, 0);
  38.294 +	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->hour_spinbutton, FALSE, FALSE, 0);
  38.295 +
  38.296 +	label = gtk_label_new ((" : "));
  38.297 +	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  38.298 +	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
  38.299 +	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
  38.300 +
  38.301 +	//minute entry
  38.302 +	spinbutton_adj = gtk_adjustment_new (sched_time.tm_min, 0, 59, 1, 10, 10);
  38.303 +	scheduler_ui->min_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adj), 1, 0);
  38.304 +	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->min_spinbutton, FALSE, FALSE, 0);
  38.305 +
  38.306 +	label = gtk_label_new ((" (hh:mm)"));
  38.307 +
  38.308 +	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  38.309 +
  38.310 +}	
  38.311 +
  38.312 +static void
  38.313 +add_date_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
  38.314 +{
  38.315 +	char sched_date[24];
  38.316 +	GtkWidget *hbox = add_line (vbox, "Date:        ");
  38.317 +		
  38.318 +	//sched_date = ctime(&real_time);
  38.319 +  	g_sprintf (sched_date, "%04d %02d %02d (yyyy mm dd)", scheduler_ui->year_temp, scheduler_ui->month_temp+1, scheduler_ui->day_temp);
  38.320 +  	sched_date[23]='\0';
  38.321 +  
  38.322 +  	scheduler_ui->date_button = gtk_button_new_with_label (sched_date);
  38.323 +  	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->date_button, FALSE, FALSE, 0);
  38.324 +  	gtk_button_set_relief (GTK_BUTTON (scheduler_ui->date_button), GTK_RELIEF_NONE);
  38.325 +
  38.326 +	g_signal_connect (G_OBJECT (scheduler_ui->date_button), "clicked",
  38.327 +                      G_CALLBACK (run_calendar_dialog), scheduler_ui);
  38.328 +
  38.329 +}
  38.330 +
  38.331 +static void
  38.332 +add_duration_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
  38.333 +{
  38.334 +	GtkWidget *hbox = add_line (vbox, "Duration:   ");
  38.335 +	GtkWidget *label;
  38.336 +	GtkObject *spinbutton_adj;
  38.337 +	
  38.338 +	spinbutton_adj = gtk_adjustment_new (60, 5, 360, 5, 60, 60);
  38.339 +  	scheduler_ui->duration_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adj), 1, 0);
  38.340 +  	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->duration_spinbutton, FALSE, TRUE, 0);
  38.341 +  	gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (scheduler_ui->duration_spinbutton), TRUE);
  38.342 +
  38.343 +	label = gtk_label_new ((" (minutes)     "));
  38.344 +  	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  38.345 +}
  38.346 +
  38.347 +static void
  38.348 +add_frequency_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
  38.349 +{
  38.350 +	
  38.351 +	GtkWidget *hbox = add_line (vbox, "Frequency: ");	
  38.352 +	
  38.353 +	scheduler_ui->freq_combobox = gtk_combo_box_new_text ();
  38.354 +	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->freq_combobox, FALSE, FALSE, 0);
  38.355 +	gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->freq_combobox), ("Only this day               "));
  38.356 +	gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->freq_combobox), ("Daily                            "));
  38.357 +	gtk_combo_box_append_text (GTK_COMBO_BOX (scheduler_ui->freq_combobox), ("Weekly                         "));
  38.358 +	gtk_combo_box_set_active(GTK_COMBO_BOX (scheduler_ui->freq_combobox), 0);
  38.359 +
  38.360 +}
  38.361 +
  38.362 +static void
  38.363 +add_title_field (MMythSchedulerUI *scheduler_ui, GtkWidget *vbox)
  38.364 +{
  38.365 +	GtkWidget *hbox = add_line (vbox, "Title:           ");
  38.366 +	
  38.367 +  	scheduler_ui->title_entry = gtk_entry_new ();
  38.368 +  	gtk_box_pack_start (GTK_BOX (hbox), scheduler_ui->title_entry, FALSE, FALSE, 0);
  38.369 +  	gtk_entry_set_text (GTK_ENTRY (scheduler_ui->title_entry), "(Optional)");
  38.370 +	
  38.371 +}
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/gmyth/src/gui/mmyth_schedulerui.h	Wed Sep 20 23:45:35 2006 +0100
    39.3 @@ -0,0 +1,45 @@
    39.4 +#ifndef MMYTH_SCHEDULERECORDING_H_
    39.5 +#define MMYTH_SCHEDULERECORDING_H_
    39.6 +
    39.7 +#include <glib.h>
    39.8 +
    39.9 +typedef struct _MMythSchedulerUI {
   39.10 +	
   39.11 +	GList *channel_list;
   39.12 +	
   39.13 +	GtkWidget *main_widget;
   39.14 +
   39.15 +	GtkWidget *channel_combobox;
   39.16 +	GtkWidget *freq_combobox;
   39.17 +	GtkWidget *hour_spinbutton;
   39.18 +	GtkWidget *min_spinbutton;
   39.19 +	GtkWidget *duration_spinbutton;
   39.20 +	GtkWidget *title_entry;
   39.21 +	GtkWidget *date_button;
   39.22 +
   39.23 +	GtkWidget *calendar_dialog;
   39.24 +	GtkWidget *calendar;
   39.25 +	
   39.26 +	guint year_temp, month_temp, day_temp;
   39.27 +} MMythSchedulerUI;
   39.28 +
   39.29 +typedef struct {
   39.30 +    long int channel_id;
   39.31 +
   39.32 +    struct tm start_tm;
   39.33 +
   39.34 +    int duration;
   39.35 +    int frequency;
   39.36 +
   39.37 +    GString *title;
   39.38 +
   39.39 +} ScheduleEntry;
   39.40 +
   39.41 +MMythSchedulerUI* mmyth_schedulerui_new (void);
   39.42 +
   39.43 +gboolean mmyth_schedulerui_save (MMythSchedulerUI *scheduler_ui);
   39.44 +
   39.45 +void mmyth_schedulerui_cb_schedule_button (GtkButton * button, gpointer user_data);
   39.46 +
   39.47 +
   39.48 +#endif /*MMYTH_SCHEDULERECORDING_H_*/
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/gmyth/src/gui/mmyth_ui.c	Wed Sep 20 23:45:35 2006 +0100
    40.3 @@ -0,0 +1,814 @@
    40.4 +
    40.5 +#include <glib-object.h>
    40.6 +#include <sys/types.h>
    40.7 +#include <sys/stat.h>
    40.8 +#include <unistd.h>
    40.9 +#include <string.h>
   40.10 +#include <stdio.h>
   40.11 +#include <gtk/gtk.h>
   40.12 +#include <gdk/gdkx.h>
   40.13 +#include <gst/interfaces/xoverlay.h>
   40.14 +#include <assert.h>
   40.15 +
   40.16 +#include "mmyth_ui.h"
   40.17 +#include "mmyth_uicommon.h"
   40.18 +#include "mmyth_schedulerui.h"
   40.19 +#include "mmyth_recordui.h"
   40.20 +#include "mmyth_uisettings.h"
   40.21 +#include "mmyth_epg_grid_view.h"
   40.22 +
   40.23 +/* GMyth library includes */
   40.24 +#include "gmyth_context.h"
   40.25 +#include "gmyth_tvplayer.h"
   40.26 +
   40.27 +#ifndef MAEMO_PLATFORM
   40.28 +static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
   40.29 +#endif
   40.30 +
   40.31 +static MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
   40.32 +static MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
   40.33 +static MMythUiCommon *create_epg_grid_view (MMythUi * mmyth_ui);
   40.34 +static MMythUiCommon *create_record_view (MMythUi * mmyth_ui);
   40.35 +static MMythUiCommon *create_schedule_view (MMythUi * mmyth_ui);
   40.36 +
   40.37 +static void cb_video_close_button (GtkButton * button, gpointer user_data);
   40.38 +static void cb_record_button (GtkButton * button, gpointer user_data);
   40.39 +static void cb_menu_item_settings (GtkMenuItem *menuitem, gpointer user_data);
   40.40 +
   40.41 +/* main box from button box separator*/
   40.42 +static GtkWidget *main_vseparator = NULL;
   40.43 +
   40.44 +GdkPixbuf *icon_sports, *icon_news, 
   40.45 +          *icon_movies, *icon_shows, *icon_default;
   40.46 +
   40.47 +#ifndef MAEMO_PLATFORM
   40.48 +/* FIXME: */
   40.49 +static MMythUi *popup_mmyth_ui;
   40.50 +#endif
   40.51 +
   40.52 +MMythUi *
   40.53 +mmyth_ui_initialize (
   40.54 +#ifdef MAEMO_PLATFORM
   40.55 +	HildonProgram *program,
   40.56 +#endif
   40.57 +	GtkWidget * main_window)
   40.58 +{
   40.59 +    MMythUi *mmyth_ui;
   40.60 +
   40.61 +    mmyth_ui = g_new0 (MMythUi, 1);
   40.62 +
   40.63 +    mmyth_ui->main_window = main_window;    
   40.64 +    mmyth_ui->videow = NULL;
   40.65 +    mmyth_ui->mmyth_recordui = NULL;
   40.66 +    mmyth_ui->mmyth_schedulerui = NULL;
   40.67 +	
   40.68 +    /* Horizontal box that divides the view into control and video area */
   40.69 +    mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
   40.70 +    gtk_widget_show (mmyth_ui->main_hbox);
   40.71 +    g_object_ref (mmyth_ui->main_hbox);
   40.72 +
   40.73 +    main_bg_color.red   = 65000;
   40.74 +    main_bg_color.green = 65000;
   40.75 +    main_bg_color.blue  = 65000;
   40.76 +    
   40.77 +    
   40.78 +#ifndef MAEMO_PLATFORM
   40.79 +    /* Popup menu */
   40.80 +    popup_mmyth_ui = mmyth_ui;
   40.81 +    g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
   40.82 +                      G_CALLBACK (button_press_handler),
   40.83 +                      G_OBJECT (mmyth_ui->main_hbox));    
   40.84 +
   40.85 +#else // #ifdef MAEMO
   40.86 +
   40.87 +    mmyth_ui->main_menu = GTK_MENU(gtk_menu_new());
   40.88 +    hildon_program_set_common_menu(program, mmyth_ui->main_menu);
   40.89 +
   40.90 +    mmyth_ui->menu_setup = gtk_menu_item_new_with_label("Setup");
   40.91 +    gtk_widget_set_size_request (GTK_WIDGET (mmyth_ui->menu_setup), 150, 40);
   40.92 +    gtk_menu_append(mmyth_ui->main_menu, mmyth_ui->menu_setup);
   40.93 +
   40.94 +    g_signal_connect(G_OBJECT(mmyth_ui->menu_setup), "activate", G_CALLBACK(cb_menu_item_settings), mmyth_ui);
   40.95 +
   40.96 +    gtk_widget_show_all (GTK_WIDGET (mmyth_ui->main_menu));
   40.97 +#endif
   40.98 +    
   40.99 +    // Main widget is mmyth_ui->main_hbox
  40.100 +    mmyth_ui->main_uicommon       = create_main_view (mmyth_ui);
  40.101 +
  40.102 +    gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
  40.103 +                       mmyth_ui->main_hbox);
  40.104 +
  40.105 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  40.106 +
  40.107 +    return mmyth_ui;
  40.108 +}
  40.109 +
  40.110 +void
  40.111 +mmyth_ui_finalize (MMythUi * mmyth_ui)
  40.112 +{
  40.113 +    if (mmyth_ui != NULL) {
  40.114 +    	if (mmyth_ui->main_uicommon)
  40.115 +	    	mmyth_uicommon_free (mmyth_ui->main_uicommon);
  40.116 +    	if (mmyth_ui->video_uicommon)
  40.117 +		    mmyth_uicommon_free (mmyth_ui->video_uicommon);
  40.118 +		if (mmyth_ui->epg_grid_uicommon)
  40.119 +		    mmyth_uicommon_free (mmyth_ui->epg_grid_uicommon);
  40.120 +		if (mmyth_ui->record_uicommon)
  40.121 +		    mmyth_uicommon_free (mmyth_ui->record_uicommon);	    
  40.122 +		if (mmyth_ui->schedule_uicommon)
  40.123 +		    mmyth_uicommon_free (mmyth_ui->schedule_uicommon);
  40.124 +
  40.125 +	    g_free (mmyth_ui);
  40.126 +    }
  40.127 +}
  40.128 +
  40.129 +void
  40.130 +mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
  40.131 +{
  40.132 +	if (new_uicommon == NULL) {
  40.133 +		g_warning ("MMythUI setting a NULL UI_Common as current display\n");
  40.134 +		return;
  40.135 +	}
  40.136 +		
  40.137 +    if (mmyth_ui->current_uicommon) {
  40.138 +        if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
  40.139 +            gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
  40.140 +            gtk_widget_hide (mmyth_ui->videow);
  40.141 +        }
  40.142 +        else {
  40.143 +            gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  40.144 +                                  mmyth_ui->current_uicommon->main_widget);
  40.145 +        }
  40.146 +
  40.147 +        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  40.148 +                              mmyth_ui->current_uicommon->event_box);
  40.149 +        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  40.150 +                              main_vseparator);        
  40.151 +
  40.152 +    }
  40.153 +
  40.154 +    if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
  40.155 +        //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
  40.156 +        gtk_widget_show (mmyth_ui->video_alignment);
  40.157 +        gtk_widget_show (mmyth_ui->videow);
  40.158 +    }
  40.159 +    else {
  40.160 +        /* FIXME: Fst call is NULL when mmyth_player_init fails */
  40.161 +        if(mmyth_ui->video_alignment != NULL)
  40.162 +            gtk_widget_hide (mmyth_ui->video_alignment);
  40.163 +        /* FIXME: Fst call is NULL when mmyth_player_init fails */
  40.164 +        if(mmyth_ui->videow != NULL)
  40.165 +            gtk_widget_hide (mmyth_ui->videow);
  40.166 +
  40.167 +        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  40.168 +                            new_uicommon->main_widget, TRUE, TRUE, 0);
  40.169 +    }
  40.170 +
  40.171 +    if(main_vseparator == NULL) {
  40.172 +        /* FIXME: should free this variable*/
  40.173 +        main_vseparator = gtk_vseparator_new();
  40.174 +        g_object_ref (main_vseparator);                   
  40.175 +    }  
  40.176 +    gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  40.177 +                        main_vseparator, FALSE, FALSE, 0);    
  40.178 +    gtk_widget_show (main_vseparator);
  40.179 +
  40.180 +    gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
  40.181 +                      FALSE, 0);         
  40.182 +
  40.183 +    mmyth_ui->current_uicommon = new_uicommon;
  40.184 +
  40.185 +}
  40.186 +
  40.187 +/* The close callback is the same for all windows*/
  40.188 +static void
  40.189 +cb_not_impl_button (GtkButton * button, gpointer user_data)
  40.190 +{
  40.191 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.192 +
  40.193 +    GtkWidget *msg_dialog = gtk_message_dialog_new (
  40.194 +                                           GTK_WINDOW(mmyth_ui->main_window),
  40.195 +                                           GTK_DIALOG_MODAL |
  40.196 +                                           GTK_DIALOG_DESTROY_WITH_PARENT,
  40.197 +                                           GTK_MESSAGE_INFO,
  40.198 +                                           GTK_BUTTONS_OK,
  40.199 +                                           "Feature not implemented");
  40.200 +    gtk_widget_set_size_request (msg_dialog, 350, 120);
  40.201 +
  40.202 +    gtk_dialog_run (GTK_DIALOG (msg_dialog));
  40.203 +
  40.204 +    gtk_widget_destroy(GTK_WIDGET(msg_dialog)); 
  40.205 +}
  40.206 +
  40.207 +/******************************************************************************
  40.208 + *                        POPUP MENU WIDGET METHODS                           *
  40.209 + *****************************************************************************/
  40.210 +
  40.211 +static void 
  40.212 +cb_menu_item_settings (GtkMenuItem *menuitem,
  40.213 +                            gpointer user_data)
  40.214 +{
  40.215 +    
  40.216 +    MMythUi *mmyth_ui = (MMythUi*) user_data;
  40.217 +   
  40.218 +    if (mmyth_uisettings_run (GTK_WINDOW (mmyth_ui->main_window))) {
  40.219 +    	// If user changes the settings, we restart the context
  40.220 +    	g_debug ("[%s] Restarting mmyth_context to new settings", __FUNCTION__);
  40.221 +    	gmyth_context_initialize();
  40.222 +    }
  40.223 +}
  40.224 +
  40.225 +#ifndef MAEMO_PLATFORM
  40.226 +
  40.227 +static void 
  40.228 +detacher (GtkWidget *attach_widget,GtkMenu *menu) 
  40.229 +{
  40.230 +	
  40.231 +}
  40.232 +
  40.233 +static void
  40.234 +do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
  40.235 +{
  40.236 +    GtkWidget *popup;
  40.237 +
  40.238 +  int button, event_time;
  40.239 +
  40.240 +  GtkWidget *item_general;
  40.241 +  GtkWidget *image;
  40.242 +
  40.243 +  popup = gtk_menu_new ();
  40.244 +
  40.245 +  item_general = gtk_image_menu_item_new_with_mnemonic ("Setup");
  40.246 +  gtk_widget_show (item_general);
  40.247 +  gtk_container_add (GTK_CONTAINER (popup), item_general);
  40.248 +
  40.249 +  image = gtk_image_new_from_stock ("gtk-edit", GTK_ICON_SIZE_MENU);
  40.250 +  gtk_widget_show (image);
  40.251 +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item_general), image);
  40.252 +
  40.253 +  g_signal_connect (G_OBJECT(item_general), "activate", G_CALLBACK (cb_menu_item_settings), popup_mmyth_ui);
  40.254 +
  40.255 +    if (event) {
  40.256 +      button = event->button;
  40.257 +      event_time = event->time;
  40.258 +    } else {
  40.259 +      button = 0;
  40.260 +      event_time = gtk_get_current_event_time ();
  40.261 +    }
  40.262 +    
  40.263 +    gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
  40.264 +    gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
  40.265 +                  button, event_time);
  40.266 +    gtk_widget_show_all(popup);
  40.267 +}
  40.268 +
  40.269 +/* Respond to a button-press by posting a menu passed in as widget.
  40.270 + *
  40.271 + * Note that the "widget" argument is the menu being posted, NOT
  40.272 + * the button that was pressed.
  40.273 + */
  40.274 +static gint 
  40.275 +button_press_handler (GtkWidget *widget, GdkEvent *event)
  40.276 +{
  40.277 +
  40.278 +    if (event->type == GDK_BUTTON_PRESS) {
  40.279 +      GdkEventButton *bevent = (GdkEventButton *) event; 
  40.280 +          /* Ignore double-clicks and triple-clicks */
  40.281 +      if (bevent->button == 3)
  40.282 +        {
  40.283 +          do_popup_menu (widget, bevent);
  40.284 +          return TRUE;
  40.285 +        }
  40.286 +    }
  40.287 +
  40.288 +    /* Tell calling code that we have not handled this event; pass it on. */
  40.289 +    return FALSE;
  40.290 +}
  40.291 +#endif
  40.292 +
  40.293 +/******************************************************************************
  40.294 + *                          MAIN APP VIEW METHODS                             *
  40.295 + *****************************************************************************/
  40.296 +
  40.297 +static void
  40.298 +cb_close_button (GtkButton * button, gpointer user_data)
  40.299 +{
  40.300 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.301 +
  40.302 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  40.303 +}
  40.304 +
  40.305 +static void
  40.306 +cb_watch_tv_button (GtkButton * button, gpointer user_data)
  40.307 +{
  40.308 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.309 +	gboolean res = FALSE;
  40.310 +	
  40.311 +	if (!(mmyth_ui->video_uicommon))
  40.312 +		mmyth_ui->video_uicommon = create_video_view (mmyth_ui);
  40.313 +	
  40.314 +	// Creates the tv player that will retrieve the mythtv content, decode and show it
  40.315 +	mmyth_ui->tvplayer = gmyth_tvplayer_new ();
  40.316 +	/* choose here if this is a LiveTV session */
  40.317 +	mmyth_ui->tvplayer->is_livetv = TRUE;
  40.318 +
  40.319 +	res = gmyth_tvplayer_initialize (mmyth_ui->tvplayer);
  40.320 +
  40.321 +	if (!res) {
  40.322 +		g_warning ("[%s] Could not initialize tvplayer", __FUNCTION__);
  40.323 +
  40.324 +		g_object_unref (mmyth_ui->tvplayer);
  40.325 +		mmyth_ui->tvplayer = NULL;
  40.326 +
  40.327 +		GtkWidget *dialog = gtk_message_dialog_new (
  40.328 +				GTK_WINDOW(mmyth_ui->main_window),
  40.329 +				GTK_DIALOG_DESTROY_WITH_PARENT,
  40.330 +                GTK_MESSAGE_ERROR,
  40.331 +                GTK_BUTTONS_CLOSE,
  40.332 +			 	"MMyth found errors while starting TV Player, please check "
  40.333 +			 	"the GStreamer installation");
  40.334 +
  40.335 +		gtk_dialog_run (GTK_DIALOG (dialog));
  40.336 +		gtk_widget_destroy (dialog);
  40.337 +		
  40.338 +		return;
  40.339 +	}
  40.340 +	//res = mmyth_tvplayer_livetv_setup (mmyth_ui->tvplayer);
  40.341 +	//
  40.342 +	if (mmyth_ui && mmyth_ui->tvplayer && res) {
  40.343 +		gmyth_tvplayer_set_widget (mmyth_ui->tvplayer, mmyth_ui->videow);
  40.344 +		gmyth_tvplayer_start_playing (mmyth_ui->tvplayer);
  40.345 +	} else {
  40.346 +		// TODO: Show Alert with error description!
  40.347 +		g_warning ("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
  40.348 +		g_object_unref (mmyth_ui->tvplayer);
  40.349 +		mmyth_ui->tvplayer = NULL;
  40.350 +		// FIXME: Show the exact error that happened
  40.351 +		GtkWidget *dialog = gtk_message_dialog_new (
  40.352 +				GTK_WINDOW(mmyth_ui->main_window),
  40.353 +				GTK_DIALOG_DESTROY_WITH_PARENT,
  40.354 +                GTK_MESSAGE_ERROR,
  40.355 +                GTK_BUTTONS_CLOSE,
  40.356 +                "Error while starting TV Player, please check if the backend"
  40.357 +                " is running properly and a tv card is available!");
  40.358 +		gtk_dialog_run (GTK_DIALOG (dialog));
  40.359 +		gtk_widget_destroy (dialog);		
  40.360 +		return;
  40.361 +	}
  40.362 +	mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);
  40.363 +	
  40.364 +}
  40.365 +
  40.366 +static void 
  40.367 +cb_epg_button (GtkButton * button, gpointer user_data)
  40.368 +{
  40.369 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.370 +    
  40.371 +    if (!(mmyth_ui->epg_grid_uicommon))
  40.372 +    	mmyth_ui->epg_grid_uicommon = create_epg_grid_view(mmyth_ui);
  40.373 +    	
  40.374 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->epg_grid_uicommon);
  40.375 +}
  40.376 +
  40.377 +static MMythUiCommon *
  40.378 +create_main_view (MMythUi * mmyth_ui)
  40.379 +{
  40.380 +    MMythUiCommon *ui_common;
  40.381 +    GtkWidget *main_widget;
  40.382 +    GtkWidget *image;
  40.383 +
  40.384 +	g_debug ("Creating Main UI Common");
  40.385 +	
  40.386 +    // FIXME: file path
  40.387 +#ifdef MMYTH_DEV
  40.388 +    image = gtk_image_new_from_file ("../pixmaps/mmyth_logo.png");
  40.389 +#else
  40.390 +    image = gtk_image_new_from_file ( PIX_DIR "mmyth_logo.png");
  40.391 +#endif
  40.392 +    
  40.393 +    main_widget = gtk_event_box_new();
  40.394 +    
  40.395 +    gtk_container_add (GTK_CONTAINER (main_widget),
  40.396 +                       image);
  40.397 +
  40.398 +
  40.399 +    gtk_widget_show_all (main_widget);
  40.400 +    g_object_ref (main_widget);
  40.401 +
  40.402 +    ui_common = mmyth_uicommon_new (main_widget,
  40.403 +                                    "Watch TV", "EPG", "Recording");
  40.404 +
  40.405 +    /* Button signals */
  40.406 +    // FIXME
  40.407 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  40.408 +                      G_CALLBACK (cb_watch_tv_button), mmyth_ui);
  40.409 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  40.410 +                      G_CALLBACK (cb_epg_button), mmyth_ui);
  40.411 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  40.412 +                      G_CALLBACK (cb_record_button), mmyth_ui);
  40.413 +
  40.414 +    return ui_common;
  40.415 +
  40.416 +}
  40.417 +
  40.418 +/******************************************************************************
  40.419 + *                         epg GRID VIEW METHODS                              *
  40.420 + *****************************************************************************/
  40.421 +
  40.422 +static MMythUiCommon *
  40.423 +create_epg_grid_view (MMythUi * mmyth_ui)
  40.424 +{
  40.425 +    MMythUiCommon *ui_common;        
  40.426 +
  40.427 +	g_debug ("Creating EPG Grid UI Common");
  40.428 +	
  40.429 +    GtkWidget *epg_grid_view = GTK_WIDGET (epg_grid_view_new (mmyth_ui));
  40.430 +    
  40.431 +    ui_common = mmyth_uicommon_new (epg_grid_view,
  40.432 +                                    "Play", "Record",
  40.433 +                                    "Close");    
  40.434 +    
  40.435 +    /* Button signals */
  40.436 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  40.437 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  40.438 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  40.439 +                      G_CALLBACK (cb_record_button), mmyth_ui);
  40.440 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  40.441 +                      G_CALLBACK (cb_close_button), mmyth_ui);
  40.442 +    
  40.443 +    return ui_common;
  40.444 +}
  40.445 +/******************************************************************************
  40.446 + *                         SCHEDULE VIEW METHODS                                *
  40.447 + ******************************************************************************/
  40.448 +
  40.449 +static void
  40.450 +cb_save_new_schedule (GtkButton *button, gpointer user_data)
  40.451 +{
  40.452 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.453 +
  40.454 +	if (!(mmyth_ui->schedule_uicommon))
  40.455 +		mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
  40.456 +		
  40.457 +    mmyth_schedulerui_save (mmyth_ui->mmyth_schedulerui);
  40.458 +    
  40.459 +    mmyth_recordui_reload_schedule (mmyth_ui->mmyth_recordui);
  40.460 +    
  40.461 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
  40.462 +    
  40.463 +}
  40.464 +
  40.465 +static void
  40.466 +cb_edit_scheduled (GtkTreeView * tree_view, GtkTreePath *path, 
  40.467 +		           GtkTreeViewColumn *column, gpointer user_data)
  40.468 +{
  40.469 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.470 +    GtkTreeSelection *selection;
  40.471 +	GtkTreeModel *list_store;
  40.472 +	GtkTreeIter iter;
  40.473 +	int index;
  40.474 +    //gint new_row = 0, record_id = 0;
  40.475 +	ScheduleInfo *schedule_info;
  40.476 +	GList *schedule_list;
  40.477 +	//GtkTreeIter iter;
  40.478 +	gint res;
  40.479 +
  40.480 +	//gtk_tree_store_clear(recordui->sch_tree_store);	
  40.481 +
  40.482 +	res = gmyth_scheduler_get_schedule_list(mmyth_ui->mmyth_recordui->scheduler, &(schedule_list));
  40.483 +	if (res < 0) {
  40.484 +		g_warning ("[%s] Retrieved NULL list of scheduled data from database", __FUNCTION__);
  40.485 +		//return FALSE;
  40.486 +	}
  40.487 +	printf("\nX %d", res); fflush(stdout);
  40.488 +    
  40.489 +   	selection = 
  40.490 +        gtk_tree_view_get_selection(GTK_TREE_VIEW(mmyth_ui->mmyth_recordui->sch_treeview));
  40.491 +    
  40.492 +    gtk_tree_selection_get_selected(selection, &list_store, &iter);
  40.493 +	gtk_tree_model_get(list_store, &iter, 4, &index, -1);
  40.494 +    
  40.495 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
  40.496 +    
  40.497 +	if (!(mmyth_ui->schedule_uicommon))
  40.498 +		mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
  40.499 +		
  40.500 +	schedule_list = g_list_nth(schedule_list, atoi(gtk_tree_path_to_string(path)));
  40.501 +	schedule_info = (ScheduleInfo*) schedule_list->data;
  40.502 +
  40.503 +    printf("\nstarttime: %ld", schedule_info->start_time); fflush(stdout);		
  40.504 +}
  40.505 +
  40.506 +static MMythUiCommon *
  40.507 +create_schedule_view (MMythUi * mmyth_ui)
  40.508 +{
  40.509 +    MMythUiCommon *ui_common;        
  40.510 +    GtkWidget *schedule_widget;
  40.511 +    
  40.512 +    g_debug ("Creating Schedule UI Common");
  40.513 +
  40.514 +	mmyth_ui->mmyth_schedulerui = mmyth_schedulerui_new ();
  40.515 +	if (mmyth_ui->mmyth_schedulerui == NULL) {
  40.516 +		g_warning ("[%s] Error while creating scheduler ui", __FUNCTION__);
  40.517 +		return NULL;
  40.518 +	}
  40.519 +	
  40.520 +	schedule_widget = mmyth_ui->mmyth_schedulerui->main_widget;
  40.521 +
  40.522 +    gtk_widget_show_all (schedule_widget);
  40.523 +    g_object_ref (schedule_widget);
  40.524 +    
  40.525 +    ui_common = mmyth_uicommon_new (schedule_widget,
  40.526 +                                    "Save", "Clear",
  40.527 +                                    "Cancel");    
  40.528 +
  40.529 +    /* Button signals */
  40.530 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  40.531 +                      G_CALLBACK (cb_save_new_schedule), mmyth_ui);
  40.532 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  40.533 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  40.534 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  40.535 +                      G_CALLBACK (cb_record_button), mmyth_ui);
  40.536 +    
  40.537 +    return ui_common;
  40.538 +}
  40.539 +/******************************************************************************
  40.540 + *                         RECORD VIEW METHODS                                *
  40.541 + ******************************************************************************/
  40.542 +static void
  40.543 +cb_record_button (GtkButton * button, gpointer user_data)
  40.544 +{
  40.545 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.546 +
  40.547 +	if (!(mmyth_ui->record_uicommon)) {
  40.548 +		mmyth_ui->record_uicommon = create_record_view (mmyth_ui);
  40.549 +		mmyth_ui->schedule_uicommon = create_schedule_view (mmyth_ui);
  40.550 +	}
  40.551 +	
  40.552 +	mmyth_recordui_reload_all (mmyth_ui->mmyth_recordui);
  40.553 +	
  40.554 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
  40.555 +
  40.556 +} 
  40.557 +
  40.558 +static void
  40.559 +cb_record_close_button (GtkButton * button, gpointer user_data)
  40.560 +{
  40.561 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.562 +
  40.563 +	mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
  40.564 +
  40.565 +	mmyth_recordui_free(mmyth_ui->mmyth_recordui);
  40.566 +	
  40.567 +	if (mmyth_ui->record_uicommon) {
  40.568 +		gtk_widget_destroy (mmyth_ui->record_uicommon->main_widget);
  40.569 +		mmyth_uicommon_free(mmyth_ui->record_uicommon);
  40.570 +		mmyth_ui->record_uicommon = NULL;
  40.571 +	}
  40.572 +
  40.573 +	if (mmyth_ui->schedule_uicommon) {
  40.574 +	//	mmyth_uicommon_free(mmyth_ui->schedule_uicommon);
  40.575 +	}	
  40.576 +} 
  40.577 +
  40.578 +
  40.579 +
  40.580 +
  40.581 +static void
  40.582 +play_selected_recorded (gpointer user_data)
  40.583 +{
  40.584 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.585 +    gboolean res = FALSE;
  40.586 +
  40.587 +    gchar *path = mmyth_recordui_get_selected_recorded (mmyth_ui->mmyth_recordui);
  40.588 +    
  40.589 +    if (path == NULL) {
  40.590 +    	// This should never happens. Play button is just activated when
  40.591 +    	// a recording is selected.
  40.592 +    	g_warning ("[%s] Play button pressed while none recorded is selected", __FUNCTION__);
  40.593 +    	return;
  40.594 +    }
  40.595 +
  40.596 +	if (!(mmyth_ui->video_uicommon))
  40.597 +		mmyth_ui->video_uicommon = create_video_view (mmyth_ui);
  40.598 +	
  40.599 +	// Creates the tv player that will retrieve the mythtv content, decode and show it
  40.600 +	mmyth_ui->tvplayer = gmyth_tvplayer_new ();
  40.601 +	g_debug ("[%s] New TV Player created: %d\n", __FUNCTION__, (int) (mmyth_ui->tvplayer));
  40.602 +	res = gmyth_tvplayer_initialize (mmyth_ui->tvplayer);
  40.603 +	if (!res) {
  40.604 +		g_warning ("[%s] Could not initialize tvplayer", __FUNCTION__);
  40.605 +
  40.606 +		g_object_unref (mmyth_ui->tvplayer);
  40.607 +		mmyth_ui->tvplayer = NULL;
  40.608 +
  40.609 +		GtkWidget *dialog = gtk_message_dialog_new (
  40.610 +				GTK_WINDOW(mmyth_ui->main_window),
  40.611 +				GTK_DIALOG_DESTROY_WITH_PARENT,
  40.612 +                GTK_MESSAGE_ERROR,
  40.613 +                GTK_BUTTONS_CLOSE,
  40.614 +			 	"MMyth found errors while starting TV Player, please check "
  40.615 +			 	"the GStreamer installation");
  40.616 +
  40.617 +		gtk_dialog_run (GTK_DIALOG (dialog));
  40.618 +		gtk_widget_destroy (dialog);
  40.619 +		
  40.620 +		return;
  40.621 +	}		
  40.622 +
  40.623 +	res = gmyth_tvplayer_record_setup (mmyth_ui->tvplayer, path);
  40.624 +	
  40.625 +	if (mmyth_ui && mmyth_ui->tvplayer && res) {
  40.626 +		gmyth_tvplayer_set_widget (mmyth_ui->tvplayer, mmyth_ui->videow);
  40.627 +		gmyth_tvplayer_start_playing (mmyth_ui->tvplayer);
  40.628 +	} else {
  40.629 +		// TODO: Show Alert with error description!
  40.630 +		g_warning ("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
  40.631 +		g_object_unref (mmyth_ui->tvplayer);
  40.632 +		mmyth_ui->tvplayer = NULL;
  40.633 +		// FIXME: Show the exact error that happened
  40.634 +		GtkWidget *dialog = gtk_message_dialog_new (
  40.635 +				GTK_WINDOW(mmyth_ui->main_window),
  40.636 +				GTK_DIALOG_DESTROY_WITH_PARENT,
  40.637 +                GTK_MESSAGE_ERROR,
  40.638 +                GTK_BUTTONS_CLOSE,
  40.639 +                "Error while starting TV Player, please check if the backend"
  40.640 +                " is running properly and a tv card is available!");
  40.641 +		gtk_dialog_run (GTK_DIALOG (dialog));
  40.642 +		gtk_widget_destroy (dialog);		
  40.643 +		return;
  40.644 +	}
  40.645 +	
  40.646 +	mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);    
  40.647 +}
  40.648 +
  40.649 +static void
  40.650 +cb_play_clicked_recorded (GtkTreeView * tree_view, GtkTreePath *path, 
  40.651 +		GtkTreeViewColumn *column, gpointer user_data)
  40.652 +{
  40.653 +	play_selected_recorded (user_data);
  40.654 +}
  40.655 +
  40.656 +static void
  40.657 +cb_play_selected (GtkButton * button, gpointer user_data)
  40.658 +{
  40.659 +	play_selected_recorded (user_data);
  40.660 +}
  40.661 +
  40.662 +static void
  40.663 +cb_schedule_button (GtkButton * button, gpointer user_data)
  40.664 +{
  40.665 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.666 +
  40.667 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
  40.668 +}
  40.669 +
  40.670 +void
  40.671 +cb_switch_page (GtkNotebook *notebook, GtkNotebookPage *page,
  40.672 +		guint page_num, gpointer user_data)
  40.673 +{
  40.674 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.675 +    MMythUiCommon *ui_common; 
  40.676 +    
  40.677 +	assert (mmyth_ui);
  40.678 +	assert (mmyth_ui->record_uicommon);
  40.679 +	
  40.680 +    ui_common = mmyth_ui->record_uicommon;
  40.681 +    
  40.682 +    if (page_num == 0) { // Switched to Schedule list
  40.683 +    	gtk_button_set_label (GTK_BUTTON (ui_common->button1), "New");
  40.684 +		g_signal_handlers_disconnect_by_func (
  40.685 +			G_OBJECT (ui_common->button1), G_CALLBACK (cb_play_selected), mmyth_ui);
  40.686 +	    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  40.687 +            G_CALLBACK (cb_schedule_button), mmyth_ui);
  40.688 +    } else if (page_num == 1) {
  40.689 +    	gtk_button_set_label (GTK_BUTTON (ui_common->button1), "Play");
  40.690 +		g_signal_handlers_disconnect_by_func (
  40.691 +			G_OBJECT (ui_common->button1), G_CALLBACK (cb_schedule_button), mmyth_ui);
  40.692 +	    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  40.693 +            G_CALLBACK (cb_play_selected), mmyth_ui);
  40.694 +    }
  40.695 +}
  40.696 +                                            
  40.697 +                                            
  40.698 +static MMythUiCommon *
  40.699 +create_record_view (MMythUi * mmyth_ui)
  40.700 +{
  40.701 +    MMythUiCommon *ui_common;        
  40.702 +    
  40.703 +   	g_debug ("Creating Record UI Common");
  40.704 +   	
  40.705 +	mmyth_ui->mmyth_recordui = mmyth_recordui_new ();
  40.706 +
  40.707 +	// FIXME: Change MMythRecordUI to a GtkWidget child and avoid this call!
  40.708 +    gtk_widget_show_all (mmyth_ui->mmyth_recordui->scrolled_window);
  40.709 +    
  40.710 +    ui_common = mmyth_uicommon_new (mmyth_ui->mmyth_recordui->scrolled_window, "New", "Delete", "<<Back");    
  40.711 +    g_object_ref (mmyth_ui->mmyth_recordui->scrolled_window);
  40.712 +        
  40.713 +    /* Button signals */
  40.714 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  40.715 +                      G_CALLBACK (cb_schedule_button), mmyth_ui);
  40.716 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  40.717 +                      G_CALLBACK (mmyth_recordui_delete_selected), mmyth_ui->mmyth_recordui);
  40.718 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  40.719 +                      G_CALLBACK (cb_record_close_button), mmyth_ui);
  40.720 +    g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->notebook),
  40.721 +		      "switch-page", G_CALLBACK (cb_switch_page), mmyth_ui);
  40.722 +    g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->rec_treeview),
  40.723 +		      "row-activated", G_CALLBACK (cb_play_clicked_recorded), mmyth_ui);
  40.724 +    g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->sch_treeview),
  40.725 +		      "row-activated", G_CALLBACK (cb_edit_scheduled), mmyth_ui);
  40.726 +    return ui_common;
  40.727 +}
  40.728 +
  40.729 +
  40.730 +/******************************************************************************
  40.731 + *                         GST VIDEO WIDGET METHODS                           *
  40.732 + *****************************************************************************/
  40.733 +
  40.734 +static void
  40.735 +cb_video_close_button (GtkButton * button, gpointer user_data)
  40.736 +{
  40.737 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  40.738 +	
  40.739 +	g_debug ("MMythUI video close button pressed");
  40.740 +	
  40.741 +	if (mmyth_ui && mmyth_ui->tvplayer) {
  40.742 +	    gmyth_tvplayer_stop_playing (mmyth_ui->tvplayer);
  40.743 +
  40.744 +		g_object_unref (mmyth_ui->tvplayer);
  40.745 +		mmyth_ui->tvplayer = NULL;	    
  40.746 +	} else {
  40.747 +		g_warning ("cb_video_close_button called with NULL pointer\n");
  40.748 +	}
  40.749 +	
  40.750 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  40.751 +}
  40.752 +
  40.753 +
  40.754 +static MMythUiCommon *
  40.755 +create_video_view (MMythUi * mmyth_ui)
  40.756 +{
  40.757 +
  40.758 +    MMythUiCommon *ui_common;
  40.759 +
  40.760 +	g_debug ("Creating Video UI Common");
  40.761 +	
  40.762 +	/* Creates widget to be user by MMythTVPlayer to draw the video */
  40.763 +    mmyth_ui->videow = gtk_drawing_area_new ();
  40.764 +    // FIXME: Get the widget size from settings
  40.765 +    gtk_widget_set_size_request (mmyth_ui->videow, 300, 240);
  40.766 +
  40.767 +    //mmiptv_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
  40.768 +
  40.769 +	// Creates an alignment to place the video widget inside
  40.770 +    mmyth_ui->video_alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
  40.771 +    gtk_widget_hide (mmyth_ui->video_alignment);
  40.772 +
  40.773 +    gtk_container_add (GTK_CONTAINER (mmyth_ui->video_alignment),
  40.774 +                       mmyth_ui->videow);
  40.775 +
  40.776 +    /* Add the gst video widget to hbox. It should never be removed. */    
  40.777 +    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
  40.778 +    if((mmyth_ui->main_hbox != NULL) && (mmyth_ui->video_alignment != NULL)) {
  40.779 +        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  40.780 +                            mmyth_ui->video_alignment, TRUE, TRUE, 0);    
  40.781 +	} else {
  40.782 +		g_warning ("[%s] Error while adding video_alignment to main widget", __FUNCTION__);	
  40.783 +    }
  40.784 +
  40.785 +    g_object_ref (mmyth_ui->videow);
  40.786 +    g_object_ref (mmyth_ui->video_alignment);
  40.787 +
  40.788 +    ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
  40.789 +                                    "  Full\nScreen", "Other\nServices",
  40.790 +                                    "Close");
  40.791 +                                    
  40.792 +    
  40.793 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  40.794 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  40.795 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  40.796 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);    
  40.797 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  40.798 +                      G_CALLBACK (cb_video_close_button), mmyth_ui);
  40.799 +
  40.800 +	if (ui_common)
  40.801 +		g_debug ("Video UI_Common sucessfull created");
  40.802 +		
  40.803 +    return ui_common;
  40.804 +}
  40.805 +
  40.806 +
  40.807 +
  40.808 +GtkWidget*
  40.809 +mmyth_ui_get_video_widget (MMythUi *mmyth_ui) {
  40.810 +	
  40.811 +	if (mmyth_ui && mmyth_ui->videow) {
  40.812 +	
  40.813 +		return mmyth_ui->videow;
  40.814 +	}
  40.815 +	
  40.816 +	return NULL;	
  40.817 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/gmyth/src/gui/mmyth_ui.c.mine	Wed Sep 20 23:45:35 2006 +0100
    41.3 @@ -0,0 +1,451 @@
    41.4 +
    41.5 +#include <gtk/gtk.h>
    41.6 +#include <gdk/gdkx.h>
    41.7 +#include <gst/interfaces/xoverlay.h>
    41.8 +
    41.9 +#include "mmyth_ui.h"
   41.10 +#include "mmyth_uicommon.h"
   41.11 +/* FIXME
   41.12 +#include "mmyth_videoplayer.h"
   41.13 +*/
   41.14 +#include "mmyth_esg_grid_view.h"
   41.15 +
   41.16 +static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
   41.17 +
   41.18 +MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
   41.19 +MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
   41.20 +MMythUiCommon *create_esg_grid_view (MMythUi * mmyth_ui);
   41.21 +static void cb_video_close_button (GtkButton * button, gpointer user_data);
   41.22 +
   41.23 +/* main box from button box separator*/
   41.24 +static GtkWidget *main_vseparator = NULL;
   41.25 +
   41.26 +GdkPixbuf *icon_sports, *icon_news, 
   41.27 +          *icon_movies, *icon_shows, *icon_default;
   41.28 +
   41.29 +/* FIXME: UGLY HACK */
   41.30 +MMythUi *popup_mmyth_ui;
   41.31 +
   41.32 +void
   41.33 +mmyth_ui_initialize_icons ()
   41.34 +{
   41.35 +    GError *error = NULL;
   41.36 +
   41.37 +#ifdef MMYTH_DEVEL
   41.38 +    icon_sports =
   41.39 +        gdk_pixbuf_new_from_file ("../pixmaps/ico_sports.png", &error);
   41.40 +#else
   41.41 +    icon_sports = gdk_pixbuf_new_from_file (PIX_DIR "ico_sports.png", &error);
   41.42 +#endif
   41.43 +
   41.44 +    if (error) {
   41.45 +        g_warning ("Could not load icon sports: %s\n", error->message);
   41.46 +        g_error_free (error);
   41.47 +        error = NULL;
   41.48 +    }
   41.49 +
   41.50 +#ifdef MMYTH_DEVEL
   41.51 +    icon_news = gdk_pixbuf_new_from_file ("../pixmaps/ico_news.png", &error);
   41.52 +#else
   41.53 +    icon_news = gdk_pixbuf_new_from_file (PIX_DIR "ico_news.png", &error);
   41.54 +#endif
   41.55 +
   41.56 +    if (error) {
   41.57 +        g_warning ("Could not load icon news: %s\n", error->message);
   41.58 +        g_error_free (error);
   41.59 +        error = NULL;
   41.60 +    }
   41.61 +
   41.62 +#ifdef MMYTH_DEVEL
   41.63 +    icon_movies =
   41.64 +        gdk_pixbuf_new_from_file ("../pixmaps/ico_movies.png", &error);
   41.65 +#else
   41.66 +    icon_movies = gdk_pixbuf_new_from_file (PIX_DIR "ico_movies.png", &error);
   41.67 +#endif
   41.68 +    if (error) {
   41.69 +        g_warning ("Could not load icon movies: %s\n", error->message);
   41.70 +        g_error_free (error);
   41.71 +        error = NULL;
   41.72 +    }
   41.73 +
   41.74 +#ifdef MMYTH_DEVEL
   41.75 +    icon_shows = gdk_pixbuf_new_from_file ("../pixmaps/ico_shows.png", &error);
   41.76 +#else
   41.77 +    icon_shows = gdk_pixbuf_new_from_file (PIX_DIR "ico_shows.png", &error);
   41.78 +#endif
   41.79 +    if (error) {
   41.80 +        g_warning ("Could not load icon shows: %s\n", error->message);
   41.81 +        g_error_free (error);
   41.82 +        error = NULL;
   41.83 +    }
   41.84 +
   41.85 +#ifdef MMYTH_DEVEL
   41.86 +    icon_default =
   41.87 +        gdk_pixbuf_new_from_file ("../pixmaps/ico_default.png", &error);
   41.88 +#else
   41.89 +    icon_default = gdk_pixbuf_new_from_file (PIX_DIR "ico_default.png", &error);
   41.90 +#endif
   41.91 +
   41.92 +    if (error) {
   41.93 +        g_warning ("Could not load icon default: %s\n", error->message);
   41.94 +        g_error_free (error);
   41.95 +        error = NULL;
   41.96 +    }
   41.97 +
   41.98 +}
   41.99 +
  41.100 +MMythUi *
  41.101 +mmyth_ui_initialize (GtkWidget * main_window)
  41.102 +{
  41.103 +    MMythUi *mmyth_ui;
  41.104 +
  41.105 +	// FIXME: REMOVE ME
  41.106 +	//mmyth_settings_load ( );
  41.107 +    
  41.108 +    mmyth_ui = g_new0 (MMythUi, 1);
  41.109 +
  41.110 +    mmyth_ui->main_window = main_window;    
  41.111 +
  41.112 +    /* Horizontal box that divides the view into control and video area */
  41.113 +    mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
  41.114 +    gtk_widget_show (mmyth_ui->main_hbox);
  41.115 +    g_object_ref (mmyth_ui->main_hbox);
  41.116 +
  41.117 +    mmyth_ui_initialize_icons ();
  41.118 +    
  41.119 +    main_bg_color.red   = 65000;
  41.120 +    main_bg_color.green = 65000;
  41.121 +    main_bg_color.blue  = 65000;
  41.122 +    
  41.123 +    // Main widget is mmyth_ui->main_hbox
  41.124 +    mmyth_ui->main_uicommon       = create_main_view (mmyth_ui);
  41.125 +    mmyth_ui->video_uicommon      = create_video_view (mmyth_ui);
  41.126 +    mmyth_ui->esg_grid_uicommon   = create_esg_grid_view (mmyth_ui);
  41.127 +
  41.128 +    /* Popup menu */
  41.129 +    /* FIXME: URGENT ugly, ugly hack */
  41.130 +    popup_mmyth_ui = mmyth_ui;
  41.131 +    g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
  41.132 +                      G_CALLBACK (button_press_handler),
  41.133 +                      G_OBJECT (mmyth_ui->main_hbox));    
  41.134 +    
  41.135 +    gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
  41.136 +                       mmyth_ui->main_hbox);
  41.137 +
  41.138 +    /* Add the gst video widget to hbox. It should never be removed. */    
  41.139 +    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
  41.140 +    if(mmyth_ui->video_alignment != NULL)
  41.141 +        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  41.142 +                            mmyth_ui->video_alignment, TRUE, TRUE, 0);    
  41.143 +
  41.144 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  41.145 +
  41.146 +    return mmyth_ui;
  41.147 +}
  41.148 +
  41.149 +void
  41.150 +mmyth_ui_finalize (MMythUi * mmyth_ui)
  41.151 +{
  41.152 +    if (mmyth_ui != NULL)
  41.153 +        g_free (mmyth_ui);
  41.154 +
  41.155 +    mmyth_uicommon_unref_all (mmyth_ui->main_uicommon);
  41.156 +    mmyth_uicommon_unref_all (mmyth_ui->video_uicommon);
  41.157 +    mmyth_uicommon_unref_all (mmyth_ui->esgcurrent_uicommon);
  41.158 +}
  41.159 +
  41.160 +void
  41.161 +mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
  41.162 +{
  41.163 +    if (mmyth_ui->current_uicommon) {
  41.164 +        if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
  41.165 +            gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
  41.166 +            gtk_widget_hide (mmyth_ui->videow);
  41.167 +        }
  41.168 +        else {
  41.169 +            gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  41.170 +                                  mmyth_ui->current_uicommon->main_widget);
  41.171 +        }
  41.172 +
  41.173 +        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  41.174 +                              mmyth_ui->current_uicommon->event_box);
  41.175 +        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  41.176 +                              main_vseparator);        
  41.177 +
  41.178 +    }
  41.179 +
  41.180 +    if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
  41.181 +        //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
  41.182 +        gtk_widget_show (mmyth_ui->video_alignment);
  41.183 +        gtk_widget_show (mmyth_ui->videow);
  41.184 +    }
  41.185 +    else {
  41.186 +        /* FIXME: Fst call is NULL when mmyth_player_init fails */
  41.187 +        if(mmyth_ui->video_alignment != NULL)
  41.188 +            gtk_widget_hide (mmyth_ui->video_alignment);
  41.189 +        /* FIXME: Fst call is NULL when mmyth_player_init fails */
  41.190 +        if(mmyth_ui->videow != NULL)
  41.191 +            gtk_widget_hide (mmyth_ui->videow);
  41.192 +
  41.193 +        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  41.194 +                            new_uicommon->main_widget, TRUE, TRUE, 0);
  41.195 +    }
  41.196 +
  41.197 +    if(main_vseparator == NULL) {
  41.198 +        /* FIXME: should free this variable*/
  41.199 +        main_vseparator = gtk_vseparator_new();
  41.200 +        g_object_ref (main_vseparator);                   
  41.201 +    }  
  41.202 +    gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  41.203 +                        main_vseparator, FALSE, FALSE, 0);    
  41.204 +    gtk_widget_show (main_vseparator);
  41.205 +
  41.206 +    gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
  41.207 +                      FALSE, 0);         
  41.208 +
  41.209 +    mmyth_ui->current_uicommon = new_uicommon;
  41.210 +
  41.211 +}
  41.212 +
  41.213 +/* The close callback is the same for all windows*/
  41.214 +static void
  41.215 +cb_not_impl_button (GtkButton * button, gpointer user_data)
  41.216 +{
  41.217 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  41.218 +
  41.219 +    GtkWidget *msg_dialog = gtk_message_dialog_new (
  41.220 +                                           GTK_WINDOW(mmyth_ui->main_window),
  41.221 +                                           GTK_DIALOG_MODAL |
  41.222 +                                           GTK_DIALOG_DESTROY_WITH_PARENT,
  41.223 +                                           GTK_MESSAGE_INFO,
  41.224 +                                           GTK_BUTTONS_OK,
  41.225 +                                           "Feature not implemented yet");
  41.226 +    gtk_widget_set_size_request (msg_dialog, 300, 120);
  41.227 +
  41.228 +    gtk_dialog_run (GTK_DIALOG (msg_dialog));
  41.229 +
  41.230 +    gtk_widget_destroy(GTK_WIDGET(msg_dialog)); 
  41.231 +}
  41.232 +
  41.233 +/******************************************************************************
  41.234 + *                        POPUP MENU WIDGET METHODS                           *
  41.235 + *****************************************************************************/
  41.236 +
  41.237 +void 
  41.238 +detacher (GtkWidget *attach_widget,GtkMenu *menu) 
  41.239 +{
  41.240 +}
  41.241 +
  41.242 +void 
  41.243 +menu_item_settings_cb (GtkMenuItem *menuitem,
  41.244 +                            gpointer user_data)
  41.245 +{
  41.246 +    /* MMythUi *mmyth_ui = (MMythUi *) user_data; */
  41.247 +
  41.248 +    /* FIXME
  41.249 +    MMythUi *mmyth_ui = popup_mmyth_ui;
  41.250 +    
  41.251 +    settings_show_dialog (GTK_WINDOW (mmyth_ui->main_window));    
  41.252 +    */
  41.253 +}
  41.254 +
  41.255 +static void
  41.256 +do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
  41.257 +{
  41.258 +    GtkWidget *popup;
  41.259 +    int button, event_time;
  41.260 +    
  41.261 +    popup = gtk_menu_new ();
  41.262 +    
  41.263 +    /* ... add menu items ... */
  41.264 +    GtkWidget *menu_item = gtk_menu_item_new_with_label("Settings");
  41.265 +    gtk_menu_append(popup, menu_item);
  41.266 +    
  41.267 +    g_signal_connect (G_OBJECT(menu_item), "activate", 
  41.268 +                      G_CALLBACK (menu_item_settings_cb), NULL);
  41.269 +    
  41.270 +    if (event)
  41.271 +    {
  41.272 +      button = event->button;
  41.273 +      event_time = event->time;
  41.274 +    }
  41.275 +    else
  41.276 +    {
  41.277 +      button = 0;
  41.278 +      event_time = gtk_get_current_event_time ();
  41.279 +    }
  41.280 +    
  41.281 +    //gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
  41.282 +    gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
  41.283 +                  button, event_time);
  41.284 +    gtk_widget_show_all(popup);
  41.285 +}
  41.286 +
  41.287 +/* Respond to a button-press by posting a menu passed in as widget.
  41.288 + *
  41.289 + * Note that the "widget" argument is the menu being posted, NOT
  41.290 + * the button that was pressed.
  41.291 + */
  41.292 +
  41.293 +static gint 
  41.294 +button_press_handler (GtkWidget *widget, GdkEvent *event)
  41.295 +{
  41.296 +
  41.297 +    if (event->type == GDK_BUTTON_PRESS) {
  41.298 +      GdkEventButton *bevent = (GdkEventButton *) event; 
  41.299 +          /* Ignore double-clicks and triple-clicks */
  41.300 +      if (bevent->button == 3)
  41.301 +        {
  41.302 +          do_popup_menu (widget, bevent);
  41.303 +          return TRUE;
  41.304 +        }
  41.305 +    }
  41.306 +
  41.307 +    /* Tell calling code that we have not handled this event; pass it on. */
  41.308 +    return FALSE;
  41.309 +}
  41.310 +
  41.311 +
  41.312 +/******************************************************************************
  41.313 + *                          MAIN APP VIEW METHODS                             *
  41.314 + *****************************************************************************/
  41.315 +
  41.316 +/* The close callback is the same for all windows*/
  41.317 +static void
  41.318 +cb_close_button (GtkButton * button, gpointer user_data)
  41.319 +{
  41.320 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  41.321 +
  41.322 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  41.323 +}
  41.324 +
  41.325 +static void 
  41.326 +cb_esg_today_button (GtkButton * button, gpointer user_data)
  41.327 +{
  41.328 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  41.329 +
  41.330 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->esg_grid_uicommon);
  41.331 +}
  41.332 +
  41.333 +MMythUiCommon *
  41.334 +create_main_view (MMythUi * mmyth_ui)
  41.335 +{
  41.336 +    MMythUiCommon *ui_common;
  41.337 +    GtkWidget *main_widget;
  41.338 +    GtkWidget *image;
  41.339 +
  41.340 +    // FIXME: file path
  41.341 +#ifdef MMYTH_DEV
  41.342 +    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
  41.343 +#else
  41.344 +    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
  41.345 +#endif
  41.346 +    
  41.347 +    main_widget = gtk_event_box_new();
  41.348 +    
  41.349 +    gtk_container_add (GTK_CONTAINER (main_widget),
  41.350 +                       image);
  41.351 +    
  41.352 +
  41.353 +    gtk_widget_show_all (main_widget);
  41.354 +    g_object_ref (main_widget);
  41.355 +
  41.356 +    ui_common = mmyth_uicommon_new (main_widget,
  41.357 +                                    "Channels", "Current", "Today");
  41.358 +
  41.359 +    /* Button signals */
  41.360 +    /* FIXME
  41.361 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  41.362 +                      G_CALLBACK (cb_channels_button), mmyth_ui);
  41.363 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  41.364 +                      G_CALLBACK (cb_esg_current_button), mmyth_ui);
  41.365 +    */
  41.366 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  41.367 +                      G_CALLBACK (cb_esg_today_button), mmyth_ui);
  41.368 +
  41.369 +    return ui_common;
  41.370 +
  41.371 +}
  41.372 +
  41.373 +/******************************************************************************
  41.374 + *                         ESG GRID VIEW METHODS                              *
  41.375 + *****************************************************************************/
  41.376 +
  41.377 +static void
  41.378 +cb_esg_grid_view_button (GtkButton * button, gpointer user_data)
  41.379 +{
  41.380 +    /* FIXME 
  41.381 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  41.382 +    guint32 service_id = -1;
  41.383 +
  41.384 +    // Retrieves the user selected service ID 
  41.385 +    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
  41.386 +    
  41.387 +    if(schedule != NULL) {
  41.388 +        service_id = schedule->service->number;
  41.389 +        mmyth_play_channel (mmyth_ui, service_id);    
  41.390 +    }
  41.391 +    */
  41.392 +}
  41.393 +
  41.394 +MMythUiCommon *
  41.395 +create_esg_grid_view (MMythUi * mmyth_ui)
  41.396 +{
  41.397 +    MMythUiCommon *ui_common;        
  41.398 +    GtkWidget *esg_grid_view = GTK_WIDGET (esg_grid_view_new (mmyth_ui));
  41.399 +    
  41.400 +    
  41.401 +    ui_common = mmyth_uicommon_new (esg_grid_view,
  41.402 +                                    "View", "Remind",
  41.403 +                                    "Close");    
  41.404 +    
  41.405 +    /* Button signals */
  41.406 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  41.407 +                      G_CALLBACK (cb_esg_grid_view_button), mmyth_ui);
  41.408 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  41.409 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  41.410 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  41.411 +                      G_CALLBACK (cb_close_button), mmyth_ui);
  41.412 +    
  41.413 +    return ui_common;
  41.414 +}
  41.415 +
  41.416 +/******************************************************************************
  41.417 + *                         GST VIDEO WIDGET METHODS                           *
  41.418 + *****************************************************************************/
  41.419 +
  41.420 +static void
  41.421 +cb_video_close_button (GtkButton * button, gpointer user_data)
  41.422 +{
  41.423 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  41.424 +
  41.425 +    /* FIXME
  41.426 +    mmyth_player_stop (mmyth_ui);
  41.427 +    */
  41.428 +
  41.429 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  41.430 +}
  41.431 +
  41.432 +MMythUiCommon *
  41.433 +create_video_view (MMythUi * mmyth_ui)
  41.434 +{
  41.435 +
  41.436 +    MMythUiCommon *ui_common;
  41.437 +
  41.438 +    /* FIXME
  41.439 +    mmyth_player_init (mmyth_ui);
  41.440 +    */
  41.441 +
  41.442 +    ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
  41.443 +                                    "  Full\nScreen", "Other\nServices",
  41.444 +                                    "Close");
  41.445 +
  41.446 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  41.447 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  41.448 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  41.449 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);    
  41.450 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  41.451 +                      G_CALLBACK (cb_video_close_button), mmyth_ui);
  41.452 +
  41.453 +    return ui_common;
  41.454 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/gmyth/src/gui/mmyth_ui.c.r2518	Wed Sep 20 23:45:35 2006 +0100
    42.3 @@ -0,0 +1,456 @@
    42.4 +
    42.5 +#include <gtk/gtk.h>
    42.6 +#include <gdk/gdkx.h>
    42.7 +#include <gst/interfaces/xoverlay.h>
    42.8 +
    42.9 +#include "mmyth_ui.h"
   42.10 +#include "mmyth_uicommon.h"
   42.11 +/* FIXME
   42.12 +#include "mmyth_videoplayer.h"
   42.13 +#include "mmyth_esg_grid_view.h"
   42.14 +#include "mmyth_common.h"
   42.15 +*/
   42.16 +
   42.17 +static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
   42.18 +
   42.19 +MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
   42.20 +MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
   42.21 +MMythUiCommon *create_esg_grid_view (MMythUi * mmyth_ui);
   42.22 +static void cb_video_close_button (GtkButton * button, gpointer user_data);
   42.23 +
   42.24 +/* main box from button box separator*/
   42.25 +static GtkWidget *main_vseparator = NULL;
   42.26 +
   42.27 +GdkPixbuf *icon_sports, *icon_news, 
   42.28 +          *icon_movies, *icon_shows, *icon_default;
   42.29 +
   42.30 +/* FIXME: UGLY HACK */
   42.31 +MMythUi *popup_mmyth_ui;
   42.32 +
   42.33 +void
   42.34 +mmyth_ui_initialize_icons ()
   42.35 +{
   42.36 +    GError *error = NULL;
   42.37 +
   42.38 +#ifdef MMYTH_DEVEL
   42.39 +    icon_sports =
   42.40 +        gdk_pixbuf_new_from_file ("../pixmaps/ico_sports.png", &error);
   42.41 +#else
   42.42 +    icon_sports = gdk_pixbuf_new_from_file (PIX_DIR "ico_sports.png", &error);
   42.43 +#endif
   42.44 +
   42.45 +    if (error) {
   42.46 +        g_warning ("Could not load icon sports: %s\n", error->message);
   42.47 +        g_error_free (error);
   42.48 +        error = NULL;
   42.49 +    }
   42.50 +
   42.51 +#ifdef MMYTH_DEVEL
   42.52 +    icon_news = gdk_pixbuf_new_from_file ("../pixmaps/ico_news.png", &error);
   42.53 +#else
   42.54 +    icon_news = gdk_pixbuf_new_from_file (PIX_DIR "ico_news.png", &error);
   42.55 +#endif
   42.56 +
   42.57 +    if (error) {
   42.58 +        g_warning ("Could not load icon news: %s\n", error->message);
   42.59 +        g_error_free (error);
   42.60 +        error = NULL;
   42.61 +    }
   42.62 +
   42.63 +#ifdef MMYTH_DEVEL
   42.64 +    icon_movies =
   42.65 +        gdk_pixbuf_new_from_file ("../pixmaps/ico_movies.png", &error);
   42.66 +#else
   42.67 +    icon_movies = gdk_pixbuf_new_from_file (PIX_DIR "ico_movies.png", &error);
   42.68 +#endif
   42.69 +    if (error) {
   42.70 +        g_warning ("Could not load icon movies: %s\n", error->message);
   42.71 +        g_error_free (error);
   42.72 +        error = NULL;
   42.73 +    }
   42.74 +
   42.75 +#ifdef MMYTH_DEVEL
   42.76 +    icon_shows = gdk_pixbuf_new_from_file ("../pixmaps/ico_shows.png", &error);
   42.77 +#else
   42.78 +    icon_shows = gdk_pixbuf_new_from_file (PIX_DIR "ico_shows.png", &error);
   42.79 +#endif
   42.80 +    if (error) {
   42.81 +        g_warning ("Could not load icon shows: %s\n", error->message);
   42.82 +        g_error_free (error);
   42.83 +        error = NULL;
   42.84 +    }
   42.85 +
   42.86 +#ifdef MMYTH_DEVEL
   42.87 +    icon_default =
   42.88 +        gdk_pixbuf_new_from_file ("../pixmaps/ico_default.png", &error);
   42.89 +#else
   42.90 +    icon_default = gdk_pixbuf_new_from_file (PIX_DIR "ico_default.png", &error);
   42.91 +#endif
   42.92 +
   42.93 +    if (error) {
   42.94 +        g_warning ("Could not load icon default: %s\n", error->message);
   42.95 +        g_error_free (error);
   42.96 +        error = NULL;
   42.97 +    }
   42.98 +
   42.99 +}
  42.100 +
  42.101 +MMythUi *
  42.102 +mmyth_ui_initialize (GtkWidget * main_window)
  42.103 +{
  42.104 +    MMythUi *mmyth_ui;
  42.105 +
  42.106 +	// FIXME: REMOVE ME
  42.107 +	//mmyth_settings_load ( );
  42.108 +    
  42.109 +    mmyth_ui = g_new0 (MMythUi, 1);
  42.110 +
  42.111 +    mmyth_ui->main_window = main_window;    
  42.112 +
  42.113 +    /* Horizontal box that divides the view into control and video area */
  42.114 +    mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
  42.115 +    gtk_widget_show (mmyth_ui->main_hbox);
  42.116 +    g_object_ref (mmyth_ui->main_hbox);
  42.117 +
  42.118 +    mmyth_ui_initialize_icons ();
  42.119 +    
  42.120 +    main_bg_color.red   = 65000;
  42.121 +    main_bg_color.green = 65000;
  42.122 +    main_bg_color.blue  = 65000;
  42.123 +    
  42.124 +    // Main widget is mmyth_ui->main_hbox
  42.125 +    mmyth_ui->main_uicommon       = create_main_view (mmyth_ui);
  42.126 +    mmyth_ui->video_uicommon      = create_video_view (mmyth_ui);
  42.127 +    mmyth_ui->esg_grid_uicommon   = create_esg_grid_view (mmyth_ui);
  42.128 +
  42.129 +    /* Popup menu */
  42.130 +    /* FIXME: URGENT ugly, ugly hack */
  42.131 +    popup_mmyth_ui = mmyth_ui;
  42.132 +    g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
  42.133 +                      G_CALLBACK (button_press_handler),
  42.134 +                      G_OBJECT (mmyth_ui->main_hbox));    
  42.135 +    
  42.136 +    gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
  42.137 +                       mmyth_ui->main_hbox);
  42.138 +
  42.139 +    /* Add the gst video widget to hbox. It should never be removed. */    
  42.140 +    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
  42.141 +    if(mmyth_ui->video_alignment != NULL)
  42.142 +        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  42.143 +                            mmyth_ui->video_alignment, TRUE, TRUE, 0);    
  42.144 +
  42.145 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  42.146 +
  42.147 +    return mmyth_ui;
  42.148 +}
  42.149 +
  42.150 +void
  42.151 +mmyth_ui_finalize (MMythUi * mmyth_ui)
  42.152 +{
  42.153 +    if (mmyth_ui != NULL)
  42.154 +        g_free (mmyth_ui);
  42.155 +
  42.156 +    mmyth_uicommon_unref_all (mmyth_ui->main_uicommon);
  42.157 +    mmyth_uicommon_unref_all (mmyth_ui->video_uicommon);
  42.158 +    mmyth_uicommon_unref_all (mmyth_ui->esgcurrent_uicommon);
  42.159 +}
  42.160 +
  42.161 +void
  42.162 +mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
  42.163 +{
  42.164 +    if (mmyth_ui->current_uicommon) {
  42.165 +        if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
  42.166 +            gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
  42.167 +            gtk_widget_hide (mmyth_ui->videow);
  42.168 +        }
  42.169 +        else {
  42.170 +            gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  42.171 +                                  mmyth_ui->current_uicommon->main_widget);
  42.172 +        }
  42.173 +
  42.174 +        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  42.175 +                              mmyth_ui->current_uicommon->event_box);
  42.176 +        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  42.177 +                              main_vseparator);        
  42.178 +
  42.179 +    }
  42.180 +
  42.181 +    if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
  42.182 +        //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
  42.183 +        gtk_widget_show (mmyth_ui->video_alignment);
  42.184 +        gtk_widget_show (mmyth_ui->videow);
  42.185 +    }
  42.186 +    else {
  42.187 +        /* FIXME: Fst call is NULL when mmyth_player_init fails */
  42.188 +        if(mmyth_ui->video_alignment != NULL)
  42.189 +            gtk_widget_hide (mmyth_ui->video_alignment);
  42.190 +        /* FIXME: Fst call is NULL when mmyth_player_init fails */
  42.191 +        if(mmyth_ui->videow != NULL)
  42.192 +            gtk_widget_hide (mmyth_ui->videow);
  42.193 +
  42.194 +        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  42.195 +                            new_uicommon->main_widget, TRUE, TRUE, 0);
  42.196 +    }
  42.197 +
  42.198 +    if(main_vseparator == NULL) {
  42.199 +        /* FIXME: should free this variable*/
  42.200 +        main_vseparator = gtk_vseparator_new();
  42.201 +        g_object_ref (main_vseparator);                   
  42.202 +    }  
  42.203 +    gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  42.204 +                        main_vseparator, FALSE, FALSE, 0);    
  42.205 +    gtk_widget_show (main_vseparator);
  42.206 +
  42.207 +    gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
  42.208 +                      FALSE, 0);         
  42.209 +
  42.210 +    mmyth_ui->current_uicommon = new_uicommon;
  42.211 +
  42.212 +}
  42.213 +
  42.214 +/* The close callback is the same for all windows*/
  42.215 +static void
  42.216 +cb_not_impl_button (GtkButton * button, gpointer user_data)
  42.217 +{
  42.218 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  42.219 +
  42.220 +    GtkWidget *msg_dialog = gtk_message_dialog_new (
  42.221 +                                           GTK_WINDOW(mmyth_ui->main_window),
  42.222 +                                           GTK_DIALOG_MODAL |
  42.223 +                                           GTK_DIALOG_DESTROY_WITH_PARENT,
  42.224 +                                           GTK_MESSAGE_INFO,
  42.225 +                                           GTK_BUTTONS_OK,
  42.226 +                                           "Feature not implemented yet");
  42.227 +    gtk_widget_set_size_request (msg_dialog, 300, 120);
  42.228 +
  42.229 +    gtk_dialog_run (GTK_DIALOG (msg_dialog));
  42.230 +
  42.231 +    gtk_widget_destroy(GTK_WIDGET(msg_dialog)); 
  42.232 +}
  42.233 +
  42.234 +/******************************************************************************
  42.235 + *                        POPUP MENU WIDGET METHODS                           *
  42.236 + *****************************************************************************/
  42.237 +
  42.238 +void 
  42.239 +detacher (GtkWidget *attach_widget,GtkMenu *menu) 
  42.240 +{
  42.241 +}
  42.242 +
  42.243 +void 
  42.244 +menu_item_settings_cb (GtkMenuItem *menuitem,
  42.245 +                            gpointer user_data)
  42.246 +{
  42.247 +    /* MMythUi *mmyth_ui = (MMythUi *) user_data; */
  42.248 +
  42.249 +    /* FIXME
  42.250 +    MMythUi *mmyth_ui = popup_mmyth_ui;
  42.251 +    
  42.252 +    settings_show_dialog (GTK_WINDOW (mmyth_ui->main_window));    
  42.253 +    */
  42.254 +}
  42.255 +
  42.256 +static void
  42.257 +do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
  42.258 +{
  42.259 +    GtkWidget *popup;
  42.260 +    int button, event_time;
  42.261 +    
  42.262 +    popup = gtk_menu_new ();
  42.263 +    
  42.264 +    /* ... add menu items ... */
  42.265 +    GtkWidget *menu_item = gtk_menu_item_new_with_label("Settings");
  42.266 +    gtk_menu_append(popup, menu_item);
  42.267 +    
  42.268 +    g_signal_connect (G_OBJECT(menu_item), "activate", 
  42.269 +                      G_CALLBACK (menu_item_settings_cb), NULL);
  42.270 +    
  42.271 +    if (event)
  42.272 +    {
  42.273 +      button = event->button;
  42.274 +      event_time = event->time;
  42.275 +    }
  42.276 +    else
  42.277 +    {
  42.278 +      button = 0;
  42.279 +      event_time = gtk_get_current_event_time ();
  42.280 +    }
  42.281 +    
  42.282 +    //gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
  42.283 +    gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
  42.284 +                  button, event_time);
  42.285 +    gtk_widget_show_all(popup);
  42.286 +}
  42.287 +
  42.288 +/* Respond to a button-press by posting a menu passed in as widget.
  42.289 + *
  42.290 + * Note that the "widget" argument is the menu being posted, NOT
  42.291 + * the button that was pressed.
  42.292 + */
  42.293 +
  42.294 +static gint 
  42.295 +button_press_handler (GtkWidget *widget, GdkEvent *event)
  42.296 +{
  42.297 +
  42.298 +    if (event->type == GDK_BUTTON_PRESS) {
  42.299 +      GdkEventButton *bevent = (GdkEventButton *) event; 
  42.300 +          /* Ignore double-clicks and triple-clicks */
  42.301 +      if (bevent->button == 3)
  42.302 +        {
  42.303 +          do_popup_menu (widget, bevent);
  42.304 +          return TRUE;
  42.305 +        }
  42.306 +    }
  42.307 +
  42.308 +    /* Tell calling code that we have not handled this event; pass it on. */
  42.309 +    return FALSE;
  42.310 +}
  42.311 +
  42.312 +
  42.313 +/******************************************************************************
  42.314 + *                          MAIN APP VIEW METHODS                             *
  42.315 + *****************************************************************************/
  42.316 +
  42.317 +/* The close callback is the same for all windows*/
  42.318 +static void
  42.319 +cb_close_button (GtkButton * button, gpointer user_data)
  42.320 +{
  42.321 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  42.322 +
  42.323 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  42.324 +}
  42.325 +
  42.326 +/* FIXME
  42.327 +static void 
  42.328 +cb_esg_today_button (GtkButton * button, gpointer user_data)
  42.329 +{
  42.330 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  42.331 +
  42.332 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->esg_grid_uicommon);
  42.333 +}
  42.334 +*/
  42.335 +
  42.336 +MMythUiCommon *
  42.337 +create_main_view (MMythUi * mmyth_ui)
  42.338 +{
  42.339 +    MMythUiCommon *ui_common;
  42.340 +    GtkWidget *main_widget;
  42.341 +    GtkWidget *image;
  42.342 +
  42.343 +    // FIXME: file path
  42.344 +#ifdef MMYTH_DEV
  42.345 +    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
  42.346 +#else
  42.347 +    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
  42.348 +#endif
  42.349 +    
  42.350 +    main_widget = gtk_event_box_new();
  42.351 +    
  42.352 +    gtk_container_add (GTK_CONTAINER (main_widget),
  42.353 +                       image);
  42.354 +    
  42.355 +
  42.356 +    gtk_widget_show_all (main_widget);
  42.357 +    g_object_ref (main_widget);
  42.358 +
  42.359 +    ui_common = mmyth_uicommon_new (main_widget,
  42.360 +                                    "Channels", "Current", "Today");
  42.361 +
  42.362 +    /* Button signals */
  42.363 +    /* FIXME
  42.364 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  42.365 +                      G_CALLBACK (cb_channels_button), mmyth_ui);
  42.366 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  42.367 +                      G_CALLBACK (cb_esg_current_button), mmyth_ui);
  42.368 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  42.369 +                      G_CALLBACK (cb_esg_today_button), mmyth_ui);
  42.370 +    */
  42.371 +
  42.372 +    return ui_common;
  42.373 +
  42.374 +}
  42.375 +
  42.376 +/******************************************************************************
  42.377 + *                         ESG GRID VIEW METHODS                              *
  42.378 + *****************************************************************************/
  42.379 +
  42.380 +static void
  42.381 +cb_esg_grid_view_button (GtkButton * button, gpointer user_data)
  42.382 +{
  42.383 +    /* FIXME 
  42.384 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  42.385 +    guint32 service_id = -1;
  42.386 +
  42.387 +    // Retrieves the user selected service ID 
  42.388 +    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
  42.389 +    
  42.390 +    if(schedule != NULL) {
  42.391 +        service_id = schedule->service->number;
  42.392 +        mmyth_play_channel (mmyth_ui, service_id);    
  42.393 +    }
  42.394 +    */
  42.395 +}
  42.396 +
  42.397 +MMythUiCommon *
  42.398 +create_esg_grid_view (MMythUi * mmyth_ui)
  42.399 +{
  42.400 +    MMythUiCommon *ui_common;        
  42.401 +    /* FIXME
  42.402 +    GtkWidget *esg_grid_view = GTK_WIDGET (esg_grid_view_new (mmyth_ui));
  42.403 +    
  42.404 +    
  42.405 +    ui_common = mmyth_uicommon_new (esg_grid_view,
  42.406 +                                    "View", "Remind",
  42.407 +                                    "Close");    
  42.408 +    */
  42.409 +    
  42.410 +    /* Button signals */
  42.411 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  42.412 +                      G_CALLBACK (cb_esg_grid_view_button), mmyth_ui);
  42.413 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  42.414 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  42.415 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  42.416 +                      G_CALLBACK (cb_close_button), mmyth_ui);
  42.417 +    
  42.418 +    return ui_common;
  42.419 +}
  42.420 +
  42.421 +/******************************************************************************
  42.422 + *                         GST VIDEO WIDGET METHODS                           *
  42.423 + *****************************************************************************/
  42.424 +
  42.425 +static void
  42.426 +cb_video_close_button (GtkButton * button, gpointer user_data)
  42.427 +{
  42.428 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  42.429 +
  42.430 +    /* FIXME
  42.431 +    mmyth_player_stop (mmyth_ui);
  42.432 +    */
  42.433 +
  42.434 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  42.435 +}
  42.436 +
  42.437 +MMythUiCommon *
  42.438 +create_video_view (MMythUi * mmyth_ui)
  42.439 +{
  42.440 +
  42.441 +    MMythUiCommon *ui_common;
  42.442 +
  42.443 +    /* FIXME
  42.444 +    mmyth_player_init (mmyth_ui);
  42.445 +    */
  42.446 +
  42.447 +    ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
  42.448 +                                    "  Full\nScreen", "Other\nServices",
  42.449 +                                    "Close");
  42.450 +
  42.451 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  42.452 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  42.453 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  42.454 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);    
  42.455 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  42.456 +                      G_CALLBACK (cb_video_close_button), mmyth_ui);
  42.457 +
  42.458 +    return ui_common;
  42.459 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/gmyth/src/gui/mmyth_ui.c.r2535	Wed Sep 20 23:45:35 2006 +0100
    43.3 @@ -0,0 +1,567 @@
    43.4 +#include <gtk/gtk.h>
    43.5 +#include <gdk/gdkx.h>
    43.6 +#include <gst/interfaces/xoverlay.h>
    43.7 +
    43.8 +#include "mmyth_ui.h"
    43.9 +#include "mmyth_uicommon.h"
   43.10 +#include "mmyth_uischedulerecording.h"
   43.11 +#include "mmyth_uirecord.h"
   43.12 +/* FIXME
   43.13 +#include "mmyth_videoplayer.h"
   43.14 +#include "mmyth_esg_grid_view.h"
   43.15 +#include "mmyth_common.h"
   43.16 +*/
   43.17 +
   43.18 +static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
   43.19 +
   43.20 +MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
   43.21 +MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
   43.22 +MMythUiCommon *create_esg_grid_view (MMythUi * mmyth_ui);
   43.23 +MMythUiCommon *create_record_view (MMythUi * mmyth_ui);
   43.24 +MMythUiCommon *create_schedule_view (MMythUi * mmyth_ui);
   43.25 +static void cb_video_close_button (GtkButton * button, gpointer user_data);
   43.26 +static void cb_record_button (GtkButton * button, gpointer user_data);
   43.27 +
   43.28 +/* main box from button box separator*/
   43.29 +static GtkWidget *main_vseparator = NULL;
   43.30 +
   43.31 +GdkPixbuf *icon_sports, *icon_news, 
   43.32 +          *icon_movies, *icon_shows, *icon_default;
   43.33 +
   43.34 +/* FIXME: UGLY HACK */
   43.35 +MMythUi *popup_mmyth_ui;
   43.36 +
   43.37 +void
   43.38 +mmyth_ui_initialize_icons ()
   43.39 +{
   43.40 +    GError *error = NULL;
   43.41 +
   43.42 +#ifdef MMYTH_DEVEL
   43.43 +    icon_sports =
   43.44 +        gdk_pixbuf_new_from_file ("../pixmaps/ico_sports.png", &error);
   43.45 +#else
   43.46 +    icon_sports = gdk_pixbuf_new_from_file (PIX_DIR "ico_sports.png", &error);
   43.47 +#endif
   43.48 +
   43.49 +    if (error) {
   43.50 +        g_warning ("Could not load icon sports: %s\n", error->message);
   43.51 +        g_error_free (error);
   43.52 +        error = NULL;
   43.53 +    }
   43.54 +
   43.55 +#ifdef MMYTH_DEVEL
   43.56 +    icon_news = gdk_pixbuf_new_from_file ("../pixmaps/ico_news.png", &error);
   43.57 +#else
   43.58 +    icon_news = gdk_pixbuf_new_from_file (PIX_DIR "ico_news.png", &error);
   43.59 +#endif
   43.60 +
   43.61 +    if (error) {
   43.62 +        g_warning ("Could not load icon news: %s\n", error->message);
   43.63 +        g_error_free (error);
   43.64 +        error = NULL;
   43.65 +    }
   43.66 +
   43.67 +#ifdef MMYTH_DEVEL
   43.68 +    icon_movies =
   43.69 +        gdk_pixbuf_new_from_file ("../pixmaps/ico_movies.png", &error);
   43.70 +#else
   43.71 +    icon_movies = gdk_pixbuf_new_from_file (PIX_DIR "ico_movies.png", &error);
   43.72 +#endif
   43.73 +    if (error) {
   43.74 +        g_warning ("Could not load icon movies: %s\n", error->message);
   43.75 +        g_error_free (error);
   43.76 +        error = NULL;
   43.77 +    }
   43.78 +
   43.79 +#ifdef MMYTH_DEVEL
   43.80 +    icon_shows = gdk_pixbuf_new_from_file ("../pixmaps/ico_shows.png", &error);
   43.81 +#else
   43.82 +    icon_shows = gdk_pixbuf_new_from_file (PIX_DIR "ico_shows.png", &error);
   43.83 +#endif
   43.84 +    if (error) {
   43.85 +        g_warning ("Could not load icon shows: %s\n", error->message);
   43.86 +        g_error_free (error);
   43.87 +        error = NULL;
   43.88 +    }
   43.89 +
   43.90 +#ifdef MMYTH_DEVEL
   43.91 +    icon_default =
   43.92 +        gdk_pixbuf_new_from_file ("../pixmaps/ico_default.png", &error);
   43.93 +#else
   43.94 +    icon_default = gdk_pixbuf_new_from_file (PIX_DIR "ico_default.png", &error);
   43.95 +#endif
   43.96 +
   43.97 +    if (error) {
   43.98 +        g_warning ("Could not load icon default: %s\n", error->message);
   43.99 +        g_error_free (error);
  43.100 +        error = NULL;
  43.101 +    }
  43.102 +
  43.103 +}
  43.104 +
  43.105 +MMythUi *
  43.106 +mmyth_ui_initialize (GtkWidget * main_window)
  43.107 +{
  43.108 +    MMythUi *mmyth_ui;
  43.109 +
  43.110 +	// FIXME: REMOVE ME
  43.111 +	//mmyth_settings_load ( );
  43.112 +    
  43.113 +    mmyth_ui = g_new0 (MMythUi, 1);
  43.114 +
  43.115 +    mmyth_ui->main_window = main_window;    
  43.116 +
  43.117 +    /* Horizontal box that divides the view into control and video area */
  43.118 +    mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
  43.119 +    gtk_widget_show (mmyth_ui->main_hbox);
  43.120 +    g_object_ref (mmyth_ui->main_hbox);
  43.121 +
  43.122 +    mmyth_ui_initialize_icons ();
  43.123 +    
  43.124 +    main_bg_color.red   = 65000;
  43.125 +    main_bg_color.green = 65000;
  43.126 +    main_bg_color.blue  = 65000;
  43.127 +    
  43.128 +    // Main widget is mmyth_ui->main_hbox
  43.129 +    mmyth_ui->main_uicommon       = create_main_view (mmyth_ui);
  43.130 +    mmyth_ui->video_uicommon      = create_video_view (mmyth_ui);
  43.131 +    mmyth_ui->esg_grid_uicommon   = create_esg_grid_view (mmyth_ui);
  43.132 +    mmyth_ui->record_uicommon     = create_record_view (mmyth_ui);    
  43.133 +    mmyth_ui->schedule_uicommon   = create_schedule_view (mmyth_ui);
  43.134 +    /* Popup menu */
  43.135 +    /* FIXME: URGENT ugly, ugly hack */
  43.136 +    popup_mmyth_ui = mmyth_ui;
  43.137 +    g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
  43.138 +                      G_CALLBACK (button_press_handler),
  43.139 +                      G_OBJECT (mmyth_ui->main_hbox));    
  43.140 +    
  43.141 +    gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
  43.142 +                       mmyth_ui->main_hbox);
  43.143 +
  43.144 +    /* Add the gst video widget to hbox. It should never be removed. */    
  43.145 +    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
  43.146 +    if(mmyth_ui->video_alignment != NULL)
  43.147 +        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  43.148 +                            mmyth_ui->video_alignment, TRUE, TRUE, 0);    
  43.149 +
  43.150 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  43.151 +
  43.152 +    return mmyth_ui;
  43.153 +}
  43.154 +
  43.155 +void
  43.156 +mmyth_ui_finalize (MMythUi * mmyth_ui)
  43.157 +{
  43.158 +    if (mmyth_ui != NULL)
  43.159 +        g_free (mmyth_ui);
  43.160 +
  43.161 +    mmyth_uicommon_unref_all (mmyth_ui->main_uicommon);
  43.162 +    mmyth_uicommon_unref_all (mmyth_ui->video_uicommon);
  43.163 +    mmyth_uicommon_unref_all (mmyth_ui->esgcurrent_uicommon);
  43.164 +}
  43.165 +
  43.166 +void
  43.167 +mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
  43.168 +{
  43.169 +    if (mmyth_ui->current_uicommon) {
  43.170 +        if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
  43.171 +            gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
  43.172 +            gtk_widget_hide (mmyth_ui->videow);
  43.173 +        }
  43.174 +        else {
  43.175 +            gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  43.176 +                                  mmyth_ui->current_uicommon->main_widget);
  43.177 +        }
  43.178 +
  43.179 +        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  43.180 +                              mmyth_ui->current_uicommon->event_box);
  43.181 +        gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
  43.182 +                              main_vseparator);        
  43.183 +
  43.184 +    }
  43.185 +
  43.186 +    if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
  43.187 +        //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
  43.188 +        gtk_widget_show (mmyth_ui->video_alignment);
  43.189 +        gtk_widget_show (mmyth_ui->videow);
  43.190 +    }
  43.191 +    else {
  43.192 +        /* FIXME: Fst call is NULL when mmyth_player_init fails */
  43.193 +        if(mmyth_ui->video_alignment != NULL)
  43.194 +            gtk_widget_hide (mmyth_ui->video_alignment);
  43.195 +        /* FIXME: Fst call is NULL when mmyth_player_init fails */
  43.196 +        if(mmyth_ui->videow != NULL)
  43.197 +            gtk_widget_hide (mmyth_ui->videow);
  43.198 +
  43.199 +        gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  43.200 +                            new_uicommon->main_widget, TRUE, TRUE, 0);
  43.201 +    }
  43.202 +
  43.203 +    if(main_vseparator == NULL) {
  43.204 +        /* FIXME: should free this variable*/
  43.205 +        main_vseparator = gtk_vseparator_new();
  43.206 +        g_object_ref (main_vseparator);                   
  43.207 +    }  
  43.208 +    gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
  43.209 +                        main_vseparator, FALSE, FALSE, 0);    
  43.210 +    gtk_widget_show (main_vseparator);
  43.211 +
  43.212 +    gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
  43.213 +                      FALSE, 0);         
  43.214 +
  43.215 +    mmyth_ui->current_uicommon = new_uicommon;
  43.216 +
  43.217 +}
  43.218 +
  43.219 +/* The close callback is the same for all windows*/
  43.220 +static void
  43.221 +cb_not_impl_button (GtkButton * button, gpointer user_data)
  43.222 +{
  43.223 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  43.224 +
  43.225 +    GtkWidget *msg_dialog = gtk_message_dialog_new (
  43.226 +                                           GTK_WINDOW(mmyth_ui->main_window),
  43.227 +                                           GTK_DIALOG_MODAL |
  43.228 +                                           GTK_DIALOG_DESTROY_WITH_PARENT,
  43.229 +                                           GTK_MESSAGE_INFO,
  43.230 +                                           GTK_BUTTONS_OK,
  43.231 +                                           "Feature not implemented yet");
  43.232 +    gtk_widget_set_size_request (msg_dialog, 300, 120);
  43.233 +
  43.234 +    gtk_dialog_run (GTK_DIALOG (msg_dialog));
  43.235 +
  43.236 +    gtk_widget_destroy(GTK_WIDGET(msg_dialog)); 
  43.237 +}
  43.238 +
  43.239 +/******************************************************************************
  43.240 + *                        POPUP MENU WIDGET METHODS                           *
  43.241 + *****************************************************************************/
  43.242 +
  43.243 +void 
  43.244 +detacher (GtkWidget *attach_widget,GtkMenu *menu) 
  43.245 +{
  43.246 +}
  43.247 +
  43.248 +void 
  43.249 +menu_item_settings_cb (GtkMenuItem *menuitem,
  43.250 +                            gpointer user_data)
  43.251 +{
  43.252 +    /* MMythUi *mmyth_ui = (MMythUi *) user_data; */
  43.253 +
  43.254 +    /* FIXME
  43.255 +    MMythUi *mmyth_ui = popup_mmyth_ui;
  43.256 +    
  43.257 +    settings_show_dialog (GTK_WINDOW (mmyth_ui->main_window));    
  43.258 +    */
  43.259 +}
  43.260 +
  43.261 +static void
  43.262 +do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
  43.263 +{
  43.264 +    GtkWidget *popup;
  43.265 +    int button, event_time;
  43.266 +    
  43.267 +    popup = gtk_menu_new ();
  43.268 +    
  43.269 +    /* ... add menu items ... */
  43.270 +    GtkWidget *menu_item = gtk_menu_item_new_with_label("Settings");
  43.271 +    gtk_menu_append(popup, menu_item);
  43.272 +    
  43.273 +    g_signal_connect (G_OBJECT(menu_item), "activate", 
  43.274 +                      G_CALLBACK (menu_item_settings_cb), NULL);
  43.275 +    
  43.276 +    if (event)
  43.277 +    {
  43.278 +      button = event->button;
  43.279 +      event_time = event->time;
  43.280 +    }
  43.281 +    else
  43.282 +    {
  43.283 +      button = 0;
  43.284 +      event_time = gtk_get_current_event_time ();
  43.285 +    }
  43.286 +    
  43.287 +    //gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
  43.288 +    gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
  43.289 +                  button, event_time);
  43.290 +    gtk_widget_show_all(popup);
  43.291 +}
  43.292 +
  43.293 +/* Respond to a button-press by posting a menu passed in as widget.
  43.294 + *
  43.295 + * Note that the "widget" argument is the menu being posted, NOT
  43.296 + * the button that was pressed.
  43.297 + */
  43.298 +
  43.299 +static gint 
  43.300 +button_press_handler (GtkWidget *widget, GdkEvent *event)
  43.301 +{
  43.302 +
  43.303 +    if (event->type == GDK_BUTTON_PRESS) {
  43.304 +      GdkEventButton *bevent = (GdkEventButton *) event; 
  43.305 +          /* Ignore double-clicks and triple-clicks */
  43.306 +      if (bevent->button == 3)
  43.307 +        {
  43.308 +          do_popup_menu (widget, bevent);
  43.309 +          return TRUE;
  43.310 +        }
  43.311 +    }
  43.312 +
  43.313 +    /* Tell calling code that we have not handled this event; pass it on. */
  43.314 +    return FALSE;
  43.315 +}
  43.316 +
  43.317 +
  43.318 +/******************************************************************************
  43.319 + *                          MAIN APP VIEW METHODS                             *
  43.320 + *****************************************************************************/
  43.321 +
  43.322 +/* The close callback is the same for all windows*/
  43.323 +static void
  43.324 +cb_close_button (GtkButton * button, gpointer user_data)
  43.325 +{
  43.326 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  43.327 +
  43.328 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  43.329 +}
  43.330 +
  43.331 +// FIXME
  43.332 +//static void 
  43.333 +//cb_record_button (GtkButton * button, gpointer user_data)
  43.334 +//{
  43.335 +//    MMythUi *mmyth_ui = (MMythUi *) user_data;
  43.336 +//
  43.337 +//    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
  43.338 +//}
  43.339 +
  43.340 +
  43.341 +MMythUiCommon *
  43.342 +create_main_view (MMythUi * mmyth_ui)
  43.343 +{
  43.344 +    MMythUiCommon *ui_common;
  43.345 +    GtkWidget *main_widget;
  43.346 +    GtkWidget *image;
  43.347 +
  43.348 +    // FIXME: file path
  43.349 +#ifdef MMYTH_DEV
  43.350 +    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
  43.351 +#else
  43.352 +    image = gtk_image_new_from_file ("../pixmaps/main_logo.gif");
  43.353 +#endif
  43.354 +    
  43.355 +    main_widget = gtk_event_box_new();
  43.356 +    
  43.357 +    gtk_container_add (GTK_CONTAINER (main_widget),
  43.358 +                       image);
  43.359 +    
  43.360 +
  43.361 +    gtk_widget_show_all (main_widget);
  43.362 +    g_object_ref (main_widget);
  43.363 +
  43.364 +    ui_common = mmyth_uicommon_new (main_widget,
  43.365 +                                    "Channels", "Current", "Recording");
  43.366 +
  43.367 +    /* Button signals */
  43.368 +    // FIXME
  43.369 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  43.370 +                      G_CALLBACK (cb_record_button), mmyth_ui);
  43.371 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  43.372 +                      G_CALLBACK (cb_record_button), mmyth_ui);
  43.373 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  43.374 +                      G_CALLBACK (cb_record_button), mmyth_ui);
  43.375 +    
  43.376 +
  43.377 +    return ui_common;
  43.378 +
  43.379 +}
  43.380 +
  43.381 +/******************************************************************************
  43.382 + *                         ESG GRID VIEW METHODS                              *
  43.383 + *****************************************************************************/
  43.384 +
  43.385 +static void
  43.386 +cb_esg_grid_view_button (GtkButton * button, gpointer user_data)
  43.387 +{
  43.388 +    /* FIXME 
  43.389 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  43.390 +    guint32 service_id = -1;
  43.391 +
  43.392 +    // Retrieves the user selected service ID 
  43.393 +    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
  43.394 +    
  43.395 +    if(schedule != NULL) {
  43.396 +        service_id = schedule->service->number;
  43.397 +        mmyth_play_channel (mmyth_ui, service_id);    
  43.398 +    }
  43.399 +    */
  43.400 +}
  43.401 +
  43.402 +MMythUiCommon *
  43.403 +create_esg_grid_view (MMythUi * mmyth_ui)
  43.404 +{
  43.405 +    MMythUiCommon *ui_common;        
  43.406 +    /* FIXME
  43.407 +    GtkWidget *esg_grid_view = GTK_WIDGET (esg_grid_view_new (mmyth_ui));
  43.408 +    
  43.409 +    
  43.410 +    ui_common = mmyth_uicommon_new (esg_grid_view,
  43.411 +                                    "View", "Remind",
  43.412 +                                    "Close");    
  43.413 +    */
  43.414 +    
  43.415 +    /* Button signals */
  43.416 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  43.417 +                      G_CALLBACK (cb_esg_grid_view_button), mmyth_ui);
  43.418 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  43.419 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  43.420 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  43.421 +                      G_CALLBACK (cb_close_button), mmyth_ui);
  43.422 +    
  43.423 +    return ui_common;
  43.424 +}
  43.425 +/******************************************************************************
  43.426 + *                         SCHEDULE VIEW METHODS                                *
  43.427 + ******************************************************************************/
  43.428 + 
  43.429 +static void
  43.430 +cb_schedule_button (GtkButton * button, gpointer user_data)
  43.431 +{
  43.432 +	    MMythUi *mmyth_ui = (MMythUi *) user_data;
  43.433 +
  43.434 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
  43.435 +    /* FIXME 
  43.436 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  43.437 +    guint32 service_id = -1;
  43.438 +
  43.439 +    // Retrieves the user selected service ID 
  43.440 +    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
  43.441 +    
  43.442 +    if(schedule != NULL) {
  43.443 +        service_id = schedule->service->number;
  43.444 +        mmyth_play_channel (mmyth_ui, service_id);    
  43.445 +    }
  43.446 +    */
  43.447 +} 
  43.448 + 
  43.449 +MMythUiCommon *
  43.450 +create_schedule_view (MMythUi * mmyth_ui)
  43.451 +{
  43.452 +    MMythUiCommon *ui_common;        
  43.453 +    
  43.454 +    GtkWidget *schedule_view = GTK_WIDGET (schedule_view_new ());
  43.455 +        //record_view = gtk_event_box_new();
  43.456 +
  43.457 +
  43.458 +    gtk_widget_show_all (schedule_view);
  43.459 +    g_object_ref (schedule_view);
  43.460 +    
  43.461 +    ui_common = mmyth_uicommon_new (schedule_view,
  43.462 +                                    "Save", "Clear",
  43.463 +                                    "Cancel");    
  43.464 +
  43.465 +    //ui->
  43.466 +    
  43.467 +    /* Button signals */
  43.468 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  43.469 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  43.470 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  43.471 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  43.472 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  43.473 +                      G_CALLBACK (cb_close_button), mmyth_ui);
  43.474 +    
  43.475 +    return ui_common;
  43.476 +}
  43.477 +/******************************************************************************
  43.478 + *                         RECORD VIEW METHODS                                *
  43.479 + ******************************************************************************/
  43.480 + 
  43.481 +static void
  43.482 +cb_record_button (GtkButton * button, gpointer user_data)
  43.483 +{
  43.484 +	    MMythUi *mmyth_ui = (MMythUi *) user_data;
  43.485 +
  43.486 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
  43.487 +    /* FIXME 
  43.488 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  43.489 +    guint32 service_id = -1;
  43.490 +
  43.491 +    // Retrieves the user selected service ID 
  43.492 +    DVBHScheduleEvent *schedule = (DVBHScheduleEvent *) mmyth_esg_grid_view_get_selected_schedule();
  43.493 +    
  43.494 +    if(schedule != NULL) {
  43.495 +        service_id = schedule->service->number;
  43.496 +        mmyth_play_channel (mmyth_ui, service_id);    
  43.497 +    }
  43.498 +    */
  43.499 +} 
  43.500 + 
  43.501 +MMythUiCommon *
  43.502 +create_record_view (MMythUi * mmyth_ui)
  43.503 +{
  43.504 +    MMythUiCommon *ui_common;        
  43.505 +    
  43.506 +    GtkWidget *record_view = GTK_WIDGET (record_view_new ());
  43.507 +        //record_view = gtk_event_box_new();
  43.508 +    
  43.509 +
  43.510 +    
  43.511 +
  43.512 +    gtk_widget_show_all (record_view);
  43.513 +    g_object_ref (record_view);
  43.514 +    
  43.515 +    ui_common = mmyth_uicommon_new (record_view,
  43.516 +                                    "Play (!)", "Schedule",
  43.517 +                                    "Delete(!)");    
  43.518 +    
  43.519 +    //ui->
  43.520 +    
  43.521 +    
  43.522 +    /* Button signals */
  43.523 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  43.524 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  43.525 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  43.526 +                      G_CALLBACK (cb_schedule_button), mmyth_ui);
  43.527 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  43.528 +                      G_CALLBACK (cb_close_button), mmyth_ui);
  43.529 +    
  43.530 +    return ui_common;
  43.531 +}
  43.532 +/******************************************************************************
  43.533 + *                         GST VIDEO WIDGET METHODS                           *
  43.534 + *****************************************************************************/
  43.535 +
  43.536 +static void
  43.537 +cb_video_close_button (GtkButton * button, gpointer user_data)
  43.538 +{
  43.539 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  43.540 +
  43.541 +    /* FIXME
  43.542 +    mmyth_player_stop (mmyth_ui);
  43.543 +    */
  43.544 +
  43.545 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
  43.546 +}
  43.547 +
  43.548 +MMythUiCommon *
  43.549 +create_video_view (MMythUi * mmyth_ui)
  43.550 +{
  43.551 +
  43.552 +    MMythUiCommon *ui_common;
  43.553 +
  43.554 +    /* FIXME
  43.555 +    mmyth_player_init (mmyth_ui);
  43.556 +    */
  43.557 +
  43.558 +    ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
  43.559 +                                    "  Full\nScreen", "Other\nServices",
  43.560 +                                    "Close");
  43.561 +
  43.562 +    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
  43.563 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);
  43.564 +    g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
  43.565 +                      G_CALLBACK (cb_not_impl_button), mmyth_ui);    
  43.566 +    g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
  43.567 +                      G_CALLBACK (cb_video_close_button), mmyth_ui);
  43.568 +
  43.569 +    return ui_common;
  43.570 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/gmyth/src/gui/mmyth_ui.h	Wed Sep 20 23:45:35 2006 +0100
    44.3 @@ -0,0 +1,75 @@
    44.4 +#ifndef MMYTH_UI_H_
    44.5 +#define MMYTH_UI_H_
    44.6 +
    44.7 +#include <gtk/gtk.h>
    44.8 +#include <gst/gst.h>
    44.9 +
   44.10 +#include "config.h"
   44.11 +
   44.12 +#ifdef MAEMO_PLATFORM
   44.13 +#include "hildon-widgets/hildon-program.h"
   44.14 +#include "hildon-widgets/hildon-window.h"
   44.15 +#endif
   44.16 +
   44.17 +#include "mmyth_uicommon.h"
   44.18 +#include "mmyth_recordui.h"
   44.19 +#include "mmyth_schedulerui.h"
   44.20 +
   44.21 +/* GMyth library includes */
   44.22 +#include "gmyth_tvplayer.h"
   44.23 +
   44.24 +typedef struct _MMythUi
   44.25 +{
   44.26 +
   44.27 +    /* The main application window */
   44.28 +    GtkWidget *main_window;
   44.29 +    MMythUiCommon *current_uicommon;
   44.30 +
   44.31 +    /* Main widget components */
   44.32 +    GtkWidget *main_hbox;
   44.33 +    GtkWidget *video_alignment;
   44.34 +    GdkPixbuf *logo;
   44.35 +
   44.36 +    /* Main widgets grouping */
   44.37 +    MMythUiCommon *main_uicommon;
   44.38 +    MMythUiCommon *video_uicommon;
   44.39 +    MMythUiCommon *epg_grid_uicommon;
   44.40 +    MMythUiCommon *record_uicommon;
   44.41 +    MMythUiCommon *schedule_uicommon;
   44.42 +    
   44.43 +    GtkWidget *videow;
   44.44 +    int idle_id;
   44.45 +    //GstTagList *tagcache;
   44.46 +    
   44.47 +    MMythRecordUI *mmyth_recordui;
   44.48 +    MMythSchedulerUI *mmyth_schedulerui;
   44.49 +
   44.50 +#ifdef MAEMO_PLATFORM
   44.51 +    HildonProgram *program;
   44.52 +    GtkMenu *main_menu;
   44.53 +    GtkWidget *menu_setup;
   44.54 +#endif
   44.55 +
   44.56 +    GMythTVPlayer *tvplayer;
   44.57 +    
   44.58 +} MMythUi;
   44.59 +
   44.60 +GdkPixbuf *icon_sports, *icon_news, *icon_movies, *icon_shows;
   44.61 +GdkColor main_bg_color;
   44.62 +
   44.63 +void mmyth_set_main_widget (MMythUi * mmyth_ui, MMythUiCommon * new_ui);
   44.64 +//void mmyth_play_selected(GtkButton * button, gpointer user_data);
   44.65 +
   44.66 +#ifdef MAEMO_PLATFORM
   44.67 +MMythUi *mmyth_ui_initialize (HildonProgram *program, GtkWidget * main_window);
   44.68 +#else
   44.69 +MMythUi *mmyth_ui_initialize (GtkWidget * main_window);
   44.70 +#endif
   44.71 +
   44.72 +void mmyth_ui_finalize (MMythUi * mmyth_ui);
   44.73 +
   44.74 +void mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon);
   44.75 +
   44.76 +GtkWidget* mmyth_ui_get_video_widget (MMythUi *mmyth_ui);
   44.77 +
   44.78 +#endif /* MMYTH_UI_H_ */
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/gmyth/src/gui/mmyth_uicommon.c	Wed Sep 20 23:45:35 2006 +0100
    45.3 @@ -0,0 +1,134 @@
    45.4 +
    45.5 +#include <gtk/gtk.h>
    45.6 +#include <glib.h>
    45.7 +#include <glib/gprintf.h>
    45.8 +
    45.9 +#include "mmyth_uicommon.h"
   45.10 +#include "mmyth_ui.h"
   45.11 +
   45.12 +static void
   45.13 +refresh_time_on_screen (GtkWidget *label)
   45.14 +{
   45.15 +	time_t real_time;
   45.16 +  	struct tm sched_time;
   45.17 +	GString *time_showed;
   45.18 +
   45.19 +	time_showed = g_string_new("");
   45.20 +	time(&real_time);
   45.21 +
   45.22 +    if (localtime_r((time_t *)&real_time, &sched_time) == NULL) {
   45.23 +        g_error ("localtime_r error in mmyth_epg_grid_view!\n");
   45.24 +        return NULL;
   45.25 +    }
   45.26 +
   45.27 +	g_string_printf(time_showed, "%d:%02d:%02d", 
   45.28 +		sched_time.tm_hour, 
   45.29 +		sched_time.tm_min, 
   45.30 +		sched_time.tm_sec);
   45.31 +
   45.32 +	gtk_label_set_text (GTK_LABEL(label), time_showed->str);
   45.33 +}
   45.34 +
   45.35 +MMythUiCommon *
   45.36 +mmyth_uicommon_new (GtkWidget * main_widget, const gchar * label1,
   45.37 +                    const gchar * label2, const gchar * label3)
   45.38 +{
   45.39 +
   45.40 +    MMythUiCommon *ui_common = g_new0 (MMythUiCommon, 1); 
   45.41 +    
   45.42 +    if (!main_widget) {
   45.43 +    	g_warning ("MMythUICommon created with a NULL main widget\n");
   45.44 +    }
   45.45 +    
   45.46 +    ui_common->main_widget = main_widget;
   45.47 +
   45.48 +    ui_common->event_box = gtk_event_box_new();
   45.49 +    
   45.50 +    /* Vertical box that divides the control area into two (buttons + clock) */
   45.51 +    ui_common->vbox = gtk_vbox_new (FALSE, 0);  /* spacing */
   45.52 +    gtk_container_set_border_width(GTK_CONTAINER (ui_common->vbox), 4);
   45.53 +    
   45.54 +    gtk_container_add (GTK_CONTAINER (ui_common->event_box),
   45.55 +                       ui_common->vbox);
   45.56 +    gtk_widget_modify_bg(ui_common->event_box, GTK_STATE_NORMAL, &main_bg_color);  
   45.57 +    
   45.58 +    /* Vertical box that divides the control area into four */
   45.59 +    ui_common->button_vbox = gtk_vbox_new (TRUE, 0);    /* spacing */
   45.60 +
   45.61 +    gtk_container_set_border_width (GTK_CONTAINER (ui_common->button_vbox), 0);
   45.62 +
   45.63 +    /* The button 1 */
   45.64 +    ui_common->button1 = gtk_button_new_with_label (label1);
   45.65 +    gtk_widget_modify_bg(ui_common->button1, GTK_STATE_NORMAL, &main_bg_color);  
   45.66 +    gtk_widget_set_size_request (ui_common->button1, BUTTON_WIDTH,
   45.67 +                                 BUTTON_HEIGHT);
   45.68 +
   45.69 +    /* The button 2 */
   45.70 +    ui_common->button2 = gtk_button_new_with_label (label2);
   45.71 +    gtk_widget_modify_bg(ui_common->button2, GTK_STATE_NORMAL, &main_bg_color);  
   45.72 +    gtk_widget_set_size_request (ui_common->button2, BUTTON_WIDTH,
   45.73 +                                 BUTTON_HEIGHT);
   45.74 +
   45.75 +    /* The button 3 */
   45.76 +    ui_common->button3 = gtk_button_new_with_label (label3);
   45.77 +    gtk_widget_modify_bg(ui_common->button3, GTK_STATE_NORMAL, &main_bg_color);  
   45.78 +    gtk_widget_set_size_request (ui_common->button3, BUTTON_WIDTH,
   45.79 +                                 BUTTON_HEIGHT);
   45.80 +
   45.81 +    /* The clock label */
   45.82 +    ui_common->label = gtk_label_new ("Starting...");
   45.83 +    gtk_widget_show (ui_common->label);
   45.84 +    ui_common->source_id = g_timeout_add(500, (GSourceFunc) refresh_time_on_screen, ui_common->label);
   45.85 +
   45.86 +    /* Packing components */
   45.87 +    gtk_box_pack_start (GTK_BOX (ui_common->vbox),
   45.88 +                        ui_common->button_vbox, TRUE, TRUE, 0);
   45.89 +
   45.90 +    gtk_box_pack_start (GTK_BOX (ui_common->vbox),
   45.91 +                        ui_common->label, FALSE, FALSE, 0);
   45.92 +
   45.93 +    gtk_box_pack_start (GTK_BOX (ui_common->button_vbox),
   45.94 +                        ui_common->button1, FALSE, FALSE, 0);
   45.95 +
   45.96 +    gtk_box_pack_start (GTK_BOX (ui_common->button_vbox),
   45.97 +                        ui_common->button2, FALSE, FALSE, 0);
   45.98 +
   45.99 +    gtk_box_pack_start (GTK_BOX (ui_common->button_vbox),
  45.100 +                        ui_common->button3, FALSE, FALSE, 0);
  45.101 +
  45.102 +    gtk_widget_show_all (ui_common->event_box);
  45.103 +
  45.104 +    /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
  45.105 +    if(ui_common->main_widget != NULL)
  45.106 +        g_object_ref (ui_common->main_widget);
  45.107 +        
  45.108 +    g_object_ref (ui_common->vbox);
  45.109 +    g_object_ref (ui_common->button_vbox);
  45.110 +    g_object_ref (ui_common->label);
  45.111 +    g_object_ref (ui_common->button1);
  45.112 +    g_object_ref (ui_common->button2);
  45.113 +    g_object_ref (ui_common->button3);
  45.114 +    g_object_ref (ui_common->event_box);
  45.115 +    return ui_common;
  45.116 +}
  45.117 +
  45.118 +void
  45.119 +mmyth_uicommon_free (MMythUiCommon *ui_common)
  45.120 +{
  45.121 +	g_debug ("[%s] Clean uicommon used memory", __FUNCTION__);
  45.122 +
  45.123 +    g_source_remove (ui_common->source_id);
  45.124 +    	
  45.125 +    g_object_unref (ui_common->main_widget);
  45.126 +    g_object_unref (ui_common->vbox);
  45.127 +    g_object_unref (ui_common->button_vbox);
  45.128 +    g_object_unref (ui_common->label);
  45.129 +    g_object_unref (ui_common->button1);
  45.130 +    g_object_unref (ui_common->button2);
  45.131 +    g_object_unref (ui_common->button3);
  45.132 +    g_object_unref (ui_common->event_box);    
  45.133 +    
  45.134 +    g_free (ui_common);
  45.135 +}
  45.136 +
  45.137 +
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/gmyth/src/gui/mmyth_uicommon.h	Wed Sep 20 23:45:35 2006 +0100
    46.3 @@ -0,0 +1,51 @@
    46.4 +#ifndef MMYTH_UICOMMON_H_
    46.5 +#define MMYTH_UICOMMON_H_
    46.6 +
    46.7 +#include "config.h"
    46.8 +
    46.9 +#include <gtk/gtk.h>
   46.10 +#include <glib.h>
   46.11 +
   46.12 +#ifndef MAEMO_PLATFORM
   46.13 +#define BUTTON_HEIGHT        50
   46.14 +#define BUTTON_WIDTH        100
   46.15 +#else
   46.16 +#define BUTTON_HEIGHT       80
   46.17 +#define BUTTON_WIDTH        150
   46.18 +#endif
   46.19 +
   46.20 +#define MAIN_WINDOW_WIDTH	550
   46.21 +#define MAIN_WINDOW_HEIGHT	250
   46.22 +
   46.23 +#define CHANNELS_DIALOG_WIDTH	300
   46.24 +#define CHANNELS_DIALOG_HEIGHT	200
   46.25 +
   46.26 +#define SETTINGS_DIALOG_WIDTH	300
   46.27 +#define SETTINGS_DIALOG_HEIGHT	120
   46.28 +
   46.29 +extern GdkColor main_bg_color;
   46.30 +
   46.31 +typedef struct _MMythUiCommon
   46.32 +{
   46.33 +    GtkWidget *main_widget;
   46.34 +
   46.35 +    /* event box to set the background color*/
   46.36 +    GtkWidget *event_box;
   46.37 +    
   46.38 +    GtkWidget *vbox;
   46.39 +    GtkWidget *button_vbox;
   46.40 +    GtkWidget *label;
   46.41 +
   46.42 +    GtkWidget *button1;
   46.43 +    GtkWidget *button2;
   46.44 +    GtkWidget *button3;
   46.45 +    
   46.46 +    gint source_id;
   46.47 +} MMythUiCommon;
   46.48 +
   46.49 +MMythUiCommon *mmyth_uicommon_new (GtkWidget * main_widget,
   46.50 +                                   const gchar * label1, const gchar * label2,
   46.51 +                                   const gchar * label3);
   46.52 +void mmyth_uicommon_free (MMythUiCommon *ui_common);
   46.53 +
   46.54 +#endif /* MMYTH_UICOMMON_H_ */
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/gmyth/src/gui/mmyth_uisettings.c	Wed Sep 20 23:45:35 2006 +0100
    47.3 @@ -0,0 +1,169 @@
    47.4 +#include<gtk/gtk.h>
    47.5 +#include<glib.h>
    47.6 +#include <sys/types.h>
    47.7 +#include <sys/stat.h>
    47.8 +#include <unistd.h>
    47.9 +#include <string.h>
   47.10 +#include <stdio.h>
   47.11 +#include <stdlib.h>
   47.12 +
   47.13 +#include "mmyth_uisettings.h"
   47.14 +
   47.15 +#include "gmyth_context.h"
   47.16 +
   47.17 +static GtkWidget *settings_dialog;
   47.18 +static GtkWidget *entry_hostname;
   47.19 +static GtkWidget *entry_dbname;
   47.20 +static GtkWidget *entry_username;
   47.21 +static GtkWidget *entry_passwd;
   47.22 +static GtkWidget *entry_port;
   47.23 +
   47.24 +static void settings_dialog_update_data (void);
   47.25 +static GtkWidget* add_entry_to_table (GtkWidget *table, GString *init_str,
   47.26 +	guint pos_left, guint pos_right, guint pos_top, guint pos_bottom);
   47.27 +static GtkWidget* add_label_to_table (GtkWidget *table, const gchar *str, 
   47.28 +	guint pos_left, guint pos_right,  guint pos_top, guint pos_bottom);
   47.29 +	
   47.30 +	
   47.31 +gboolean
   47.32 +mmyth_uisettings_run (GtkWindow *main_window)
   47.33 +{
   47.34 +
   47.35 +	GtkWidget *settings_table;
   47.36 +	GtkWidget *label_hostname, *label_dbname;
   47.37 +	GtkWidget *label_username, *label_passwd, *label_port;
   47.38 +
   47.39 +	GMythSettings *msettings = gmyth_context_get_settings();
   47.40 +	
   47.41 +	settings_dialog = gtk_dialog_new_with_buttons ("Settings",
   47.42 +                                         main_window,
   47.43 +                                         GTK_DIALOG_DESTROY_WITH_PARENT,
   47.44 +                                         GTK_STOCK_OK,
   47.45 +                                         GTK_RESPONSE_ACCEPT,
   47.46 +                                         GTK_STOCK_CANCEL,
   47.47 +                                         GTK_RESPONSE_REJECT,
   47.48 +                                         NULL);
   47.49 +                                         
   47.50 +  gtk_widget_set_size_request (settings_dialog, 400, 244);
   47.51 +
   47.52 +/*  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
   47.53 +  gtk_widget_show (scrolledwindow1);
   47.54 +  gtk_container_add (GTK_CONTAINER (window1), scrolledwindow1);
   47.55 +  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
   47.56 +
   47.57 +  viewport1 = gtk_viewport_new (NULL, NULL);
   47.58 +  gtk_widget_show (viewport1);
   47.59 +  gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);
   47.60 +  gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport1), GTK_SHADOW_NONE);
   47.61 +*/
   47.62 +
   47.63 +	// Creates the table and attach it to the settings dialog
   47.64 +	settings_table = gtk_table_new (5, 2, FALSE);
   47.65 +	gtk_widget_show (settings_table);
   47.66 +	gtk_box_pack_start (GTK_BOX (GTK_DIALOG(settings_dialog)->vbox), settings_table, FALSE, TRUE, 0);
   47.67 +	gtk_container_set_border_width (GTK_CONTAINER (settings_table), 3);
   47.68 +	gtk_table_set_row_spacings (GTK_TABLE (settings_table), 5);
   47.69 +	gtk_table_set_col_spacings (GTK_TABLE (settings_table), 10);
   47.70 +
   47.71 +	label_hostname = add_label_to_table (settings_table, "Host Name:", 0, 1, 0, 1);
   47.72 +	label_dbname   = add_label_to_table (settings_table, "Database Name:", 0, 1, 1, 2);
   47.73 +	label_username = add_label_to_table (settings_table, "Username:", 0, 1, 2, 3);
   47.74 +	label_passwd = add_label_to_table (settings_table, "Password:", 0, 1, 3, 4);
   47.75 +	label_port = add_label_to_table (settings_table, "Server port:", 0, 1, 4, 5);
   47.76 +	
   47.77 +	entry_hostname = add_entry_to_table (settings_table,
   47.78 +		gmyth_settings_get_backend_hostname (msettings),
   47.79 +		1, 2, 0, 1);
   47.80 +	entry_dbname = add_entry_to_table (settings_table,
   47.81 +		gmyth_settings_get_dbname (msettings),
   47.82 +		1, 2, 1, 2 );
   47.83 +	entry_username = add_entry_to_table (settings_table,
   47.84 +		gmyth_settings_get_username (msettings),
   47.85 +		1, 2, 2, 3 );
   47.86 +	entry_passwd = add_entry_to_table (settings_table,
   47.87 +		gmyth_settings_get_password (msettings),
   47.88 +		1, 2, 3, 4 );
   47.89 +		
   47.90 +	GString *str_port = g_string_new ("");
   47.91 +	g_string_printf (str_port, "%d", 
   47.92 +		gmyth_settings_get_backend_port (msettings));
   47.93 +	entry_port = add_entry_to_table (settings_table, str_port,
   47.94 +		1, 2, 4, 5 );
   47.95 +	g_string_free (str_port, TRUE);
   47.96 +		
   47.97 +	if (gtk_dialog_run (GTK_DIALOG (settings_dialog)) == GTK_RESPONSE_ACCEPT) {
   47.98 +		settings_dialog_update_data ();
   47.99 +		gtk_widget_destroy (settings_dialog);
  47.100 +		return TRUE;
  47.101 +	}
  47.102 +	
  47.103 +	gtk_widget_destroy (settings_dialog);
  47.104 +	
  47.105 +	return FALSE;
  47.106 +	
  47.107 +}
  47.108 +
  47.109 +static GtkWidget*
  47.110 +add_label_to_table (GtkWidget *table, const gchar *str, guint pos_left, guint pos_right, 
  47.111 +		guint pos_top, guint pos_bottom )
  47.112 +{
  47.113 +	GtkWidget *tmp_label = gtk_label_new (str);
  47.114 +	
  47.115 +	gtk_widget_show (tmp_label);
  47.116 +	gtk_table_attach (GTK_TABLE (table), tmp_label, 
  47.117 +					pos_left, pos_right, pos_top, pos_bottom,
  47.118 +                    (GtkAttachOptions) (GTK_FILL),
  47.119 +                    (GtkAttachOptions) (0), 0, 0);
  47.120 +	gtk_misc_set_alignment (GTK_MISC (tmp_label), 0, 0.5);
  47.121 +	
  47.122 +	return tmp_label;
  47.123 +}
  47.124 +
  47.125 +static GtkWidget*
  47.126 +add_entry_to_table (GtkWidget *table, GString *init_str, guint pos_left, guint pos_right,
  47.127 +		guint pos_top, guint pos_bottom)
  47.128 +{
  47.129 +	GtkWidget *tmp_entry = gtk_entry_new ();
  47.130 +	gtk_widget_show (tmp_entry);
  47.131 +	gtk_table_attach (GTK_TABLE (table), tmp_entry, 
  47.132 +					pos_left, pos_right, pos_top, pos_bottom,
  47.133 +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
  47.134 +                    (GtkAttachOptions) (0), 0, 0);
  47.135 +    if (init_str)
  47.136 +		gtk_entry_set_text (GTK_ENTRY (tmp_entry), (init_str->str));
  47.137 +		
  47.138 +	//gtk_entry_set_invisible_char (GTK_ENTRY (entry_port), 9679);
  47.139 +	
  47.140 +	return tmp_entry;
  47.141 +}
  47.142 +
  47.143 +static void
  47.144 +settings_dialog_update_data (void) 
  47.145 +{
  47.146 +	GString *tmp_entry_text;
  47.147 +	GMythSettings *msettings = gmyth_context_get_settings();
  47.148 +	
  47.149 +	if (!msettings) {
  47.150 +		g_warning ("[%s] Could not get GMythSettings instance from context\n", __FUNCTION__);
  47.151 +		return;
  47.152 +	}
  47.153 +		
  47.154 +	tmp_entry_text = g_string_new("");
  47.155 +	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_hostname)));
  47.156 +	gmyth_settings_set_backend_hostname(msettings, tmp_entry_text);
  47.157 +	
  47.158 +	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_dbname)));
  47.159 +	gmyth_settings_set_dbname(msettings, tmp_entry_text);
  47.160 +	
  47.161 +	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_username)));
  47.162 +	gmyth_settings_set_username(msettings, tmp_entry_text);
  47.163 +	
  47.164 +	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_passwd)));
  47.165 +	gmyth_settings_set_password(msettings, tmp_entry_text);	
  47.166 +	
  47.167 +	g_string_printf(tmp_entry_text, "%s", gtk_entry_get_text( GTK_ENTRY(entry_port)));
  47.168 +	gmyth_settings_set_backend_port(msettings, atoi(tmp_entry_text->str));
  47.169 +	
  47.170 +	gmyth_settings_save (msettings);
  47.171 +	
  47.172 +}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/gmyth/src/gui/mmyth_uisettings.h	Wed Sep 20 23:45:35 2006 +0100
    48.3 @@ -0,0 +1,6 @@
    48.4 +#ifndef MMYTH_SETTINGS_H_
    48.5 +#define MMYTH_SETTINGS_H_
    48.6 +
    48.7 +gboolean mmyth_uisettings_run (GtkWindow *main_window);
    48.8 +
    48.9 +#endif /*MMYTH_SETTINGS_H_*/
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/gmyth/src/gui/mmyth_videoplayer.c	Wed Sep 20 23:45:35 2006 +0100
    49.3 @@ -0,0 +1,369 @@
    49.4 +
    49.5 +#include <gst/gst.h>
    49.6 +#include <gtk/gtk.h>
    49.7 +#include <gdk/gdkx.h>
    49.8 +#include <gst/interfaces/xoverlay.h>
    49.9 +#include <unistd.h>
   49.10 +
   49.11 +#include "mmyth_ui.h"
   49.12 +#include "mmyth_videoplayer.h"
   49.13 +#include "mmyth_sdpreader.h"
   49.14 +
   49.15 +#include "esg_database.h"
   49.16 +
   49.17 +#include "ipd_demux.h"
   49.18 +#include "ipd_network.h"
   49.19 +
   49.20 +#ifdef INDT_IP_DECAPSULATOR
   49.21 +#include <sys/types.h>
   49.22 +#include <signal.h>
   49.23 +#endif
   49.24 +
   49.25 +/* Global flag/semaphore to control IP decapsulator threads */
   49.26 +gboolean state_keep_running = 0;
   49.27 +
   49.28 +
   49.29 +typedef struct _GstPlayerWindowStateChange
   49.30 +{
   49.31 +    GstElement *play;
   49.32 +    GstState old_state, new_state;
   49.33 +    MMythUi *mmyth_ui;
   49.34 +} GstPlayerWindowStateChange;
   49.35 +
   49.36 +typedef struct _GstPlayerWindowTagFound
   49.37 +{
   49.38 +    GstElement *play;
   49.39 +    GstTagList *taglist;
   49.40 +    MMythUi *mmyth_ui;
   49.41 +} GstPlayerWindowTagFound;
   49.42 +
   49.43 +
   49.44 +GstElement *gst_pipeline, *gst_decoder, *gst_videosink;
   49.45 +
   49.46 +static gboolean idle_state (gpointer data);
   49.47 +
   49.48 +static gboolean
   49.49 +bus_call (GstBus * bus, GstMessage * msg, gpointer data)
   49.50 +{
   49.51 +    MMythUi *mmyth_ui = (MMythUi *) data;
   49.52 +    GMainLoop *loop = mmyth_ui->loop;
   49.53 +
   49.54 +    switch (GST_MESSAGE_TYPE (msg)) {
   49.55 +        case GST_MESSAGE_EOS:
   49.56 +
   49.57 +            if (mmyth_ui->idle_id != 0) {
   49.58 +                g_source_remove (mmyth_ui->idle_id);
   49.59 +                mmyth_ui->idle_id = 0;
   49.60 +            }
   49.61 +
   49.62 +            //g_idle_add ((GSourceFunc) idle_eos, data);
   49.63 +            gst_element_set_state (GST_ELEMENT (GST_MESSAGE_SRC (msg)),
   49.64 +                                   GST_STATE_READY);
   49.65 +            break;
   49.66 +        case GST_MESSAGE_ERROR:{
   49.67 +                gchar *debug;
   49.68 +                GError *err;
   49.69 +
   49.70 +                gst_message_parse_error (msg, &err, &debug);
   49.71 +                g_free (debug);
   49.72 +
   49.73 +                printf ("Error: %s\n", err->message);
   49.74 +                g_error_free (err);
   49.75 +
   49.76 +                g_main_loop_quit (loop);
   49.77 +            }
   49.78 +            break;
   49.79 +        case GST_MESSAGE_STATE_CHANGED:{
   49.80 +                GstState oldstate;
   49.81 +                GstState newstate;
   49.82 +                GstState pending;
   49.83 +                GstPlayerWindowStateChange *st =
   49.84 +                    g_new (GstPlayerWindowStateChange, 1);
   49.85 +
   49.86 +                gst_message_parse_state_changed (msg,
   49.87 +                                                 &oldstate,
   49.88 +                                                 &newstate, &pending);
   49.89 +
   49.90 +                st->play = mmyth_ui->play;
   49.91 +                gst_object_ref (GST_OBJECT (mmyth_ui->play));
   49.92 +                st->old_state = oldstate;
   49.93 +                st->new_state = newstate;
   49.94 +
   49.95 +                st->mmyth_ui = mmyth_ui;
   49.96 +
   49.97 +                /* State debug messages */
   49.98 +                printf ("oldstate = %s, newstate = %s, pendingstate = %s\n",
   49.99 +                        gst_element_state_get_name (oldstate),
  49.100 +                        gst_element_state_get_name (newstate),
  49.101 +                        gst_element_state_get_name (pending));
  49.102 +
  49.103 +                g_idle_add ((GSourceFunc) idle_state, st);
  49.104 +
  49.105 +            }
  49.106 +            break;
  49.107 +        default:
  49.108 +            printf (gst_message_type_get_name (GST_MESSAGE_TYPE (msg)));
  49.109 +            printf ("\n");
  49.110 +            break;
  49.111 +    }
  49.112 +
  49.113 +    return TRUE;
  49.114 +}
  49.115 +
  49.116 +
  49.117 +static gboolean
  49.118 +cb_iterate (gpointer data)
  49.119 +{
  49.120 +    MMythUi *mmyth_ui = (MMythUi *) data;
  49.121 +    //gboolean res;
  49.122 +
  49.123 +    g_main_loop_run (mmyth_ui->loop);
  49.124 +/*
  49.125 +	if (!GST_FLAG_IS_SET (mmyth_ui->play, GST_BIN_SELF_SCHEDULABLE)) {
  49.126 +    	res = gst_bin_iterate (GST_BIN (mmyth_ui->play));
  49.127 +	} else {
  49.128 +    	g_usleep (100);
  49.129 +		res = (gst_element_get_state (mmyth_ui->play) == GST_STATE_PLAYING);
  49.130 +	}
  49.131 +
  49.132 +	if (!res)
  49.133 +    	mmyth_ui->idle_id = 0;
  49.134 +    	
  49.135 +    return res;
  49.136 +*/
  49.137 +    return FALSE;
  49.138 +
  49.139 +}
  49.140 +
  49.141 +static gboolean
  49.142 +idle_state (gpointer data)
  49.143 +{
  49.144 +    GstPlayerWindowStateChange *st = data;
  49.145 +
  49.146 +    if (st->old_state == GST_STATE_PLAYING) {
  49.147 +        if (st->mmyth_ui->idle_id != 0) {
  49.148 +            g_source_remove (st->mmyth_ui->idle_id);
  49.149 +            st->mmyth_ui->idle_id = 0;
  49.150 +        }
  49.151 +    }
  49.152 +    else if (st->new_state == GST_STATE_PLAYING) {
  49.153 +        if (st->mmyth_ui->idle_id != 0)
  49.154 +            g_source_remove (st->mmyth_ui->idle_id);
  49.155 +
  49.156 +        st->mmyth_ui->idle_id = g_idle_add (cb_iterate, st->mmyth_ui);
  49.157 +    }
  49.158 +
  49.159 +    /* new movie loaded? */
  49.160 +    if (st->old_state == GST_STATE_READY && st->new_state > GST_STATE_READY) {
  49.161 +
  49.162 +        /* gboolean have_video = FALSE; */
  49.163 +
  49.164 +        gtk_widget_show (st->mmyth_ui->videow);
  49.165 +
  49.166 +        gtk_window_resize (GTK_WINDOW (st->mmyth_ui->main_window), 1, 1);
  49.167 +
  49.168 +    }
  49.169 +
  49.170 +    /* discarded movie? */
  49.171 +    if (st->old_state > GST_STATE_READY && st->new_state == GST_STATE_READY) {
  49.172 +
  49.173 +        if (st->mmyth_ui->tagcache) {
  49.174 +            gst_tag_list_free (st->mmyth_ui->tagcache);
  49.175 +            st->mmyth_ui->tagcache = NULL;
  49.176 +        }
  49.177 +    }
  49.178 +
  49.179 +    gst_object_unref (GST_OBJECT (st->play));
  49.180 +    //g_object_unref (G_OBJECT (st->win));
  49.181 +    g_free (st);
  49.182 +
  49.183 +    /* once */
  49.184 +    return FALSE;
  49.185 +}
  49.186 +
  49.187 +
  49.188 +
  49.189 +static gboolean
  49.190 +expose (GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
  49.191 +{
  49.192 +    MMythUi *mmyth_ui = (MMythUi *) user_data;
  49.193 +
  49.194 +    gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (mmyth_ui->videosink),
  49.195 +                                  GDK_WINDOW_XWINDOW (mmyth_ui->videow->
  49.196 +                                                      window));
  49.197 +    return TRUE;
  49.198 +}
  49.199 +
  49.200 +
  49.201 +void
  49.202 +mmyth_player_init (MMythUi * mmyth_ui)
  49.203 +{
  49.204 +    GstElement *play;
  49.205 +    GstElement *source, *parser, *decoder, *videosink;
  49.206 +
  49.207 +    play = gst_pipeline_new ("video-player");
  49.208 +    source = gst_element_factory_make ("udpsrc", "file-source");
  49.209 +    parser = gst_element_factory_make ("rtph263pdepay", "rtp-demux");
  49.210 +    decoder = gst_element_factory_make ("ffdec_h263", "mpeg-decoder");
  49.211 +    videosink = gst_element_factory_make ("xvimagesink", "image-output");
  49.212 +    gst_pipeline = play;
  49.213 +    gst_decoder = decoder;
  49.214 +    gst_videosink = videosink;
  49.215 +
  49.216 +    if (!(gst_pipeline && source && parser && decoder && videosink)) {
  49.217 +        /* FIXME: hanlde the error correctly */
  49.218 +        /* video_alignment is not being created (below) 
  49.219 +           and is causing problems to the ui */
  49.220 +        g_print ("GstElement creation error!\n");
  49.221 +        return;
  49.222 +    }
  49.223 +
  49.224 +    g_object_set (G_OBJECT (videosink), "sync", FALSE, NULL);
  49.225 +
  49.226 +    gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (gst_pipeline)),
  49.227 +                       bus_call, mmyth_ui);
  49.228 +
  49.229 +    gst_bin_add_many (GST_BIN (gst_pipeline), source, parser, decoder,
  49.230 +                      videosink, NULL);
  49.231 +
  49.232 +    {
  49.233 +        GstCaps *rtpcaps = gst_caps_new_simple ("application/x-rtp", NULL);
  49.234 +        gst_element_link_filtered(source, parser, rtpcaps);
  49.235 +    }
  49.236 +    
  49.237 +    gst_element_link_many (/*source,*/ parser, decoder, videosink, NULL);
  49.238 +
  49.239 +    /* actual window */
  49.240 +    mmyth_ui->play = play;
  49.241 +    mmyth_ui->videosink = videosink;
  49.242 +    mmyth_ui->udpsource = source;
  49.243 +
  49.244 +    g_object_ref (mmyth_ui->play);
  49.245 +    g_object_ref (mmyth_ui->videosink);
  49.246 +
  49.247 +    /* video widget */
  49.248 +    //mmyth_ui->videow = gst_player_video_new (videosink, play);
  49.249 +    mmyth_ui->videow = gtk_drawing_area_new ();
  49.250 +    gtk_widget_set_size_request (mmyth_ui->videow, 300, 240);
  49.251 +
  49.252 +    mmyth_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
  49.253 +
  49.254 +
  49.255 +    mmyth_ui->video_alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
  49.256 +    gtk_widget_hide (mmyth_ui->video_alignment);
  49.257 +
  49.258 +    gtk_container_add (GTK_CONTAINER (mmyth_ui->video_alignment),
  49.259 +                       mmyth_ui->videow);
  49.260 +
  49.261 +    g_signal_connect (mmyth_ui->videow, "expose-event", G_CALLBACK (expose),
  49.262 +                      mmyth_ui);
  49.263 +    //g_signal_connect(mmyth_ui->videow, "size_request", G_CALLBACK(cb_preferred_video_size), mmyth_ui);
  49.264 +
  49.265 +
  49.266 +    g_object_ref (mmyth_ui->videow);
  49.267 +    g_object_ref (mmyth_ui->video_alignment);
  49.268 +
  49.269 +    //gnome_app_set_contents (app, videow);
  49.270 +    //gtk_widget_show (mmyth_ui->videow);
  49.271 +
  49.272 +//fail:
  49.273 +//  gst_object_unref (GST_OBJECT (play));
  49.274 +//  return NULL;  
  49.275 +
  49.276 +}
  49.277 +
  49.278 +void
  49.279 +mmyth_player_stop (MMythUi * mmyth_ui)
  49.280 +{
  49.281 +    gst_element_set_state (mmyth_ui->play, GST_STATE_NULL);
  49.282 +
  49.283 +    if(mmyth_ui->videow != NULL)
  49.284 +        gtk_widget_hide (mmyth_ui->videow);
  49.285 +
  49.286 +    /* Disable IP Decapsulator playing threads */
  49.287 +    state_keep_running = FALSE;	
  49.288 +
  49.289 +}
  49.290 +
  49.291 +static gboolean
  49.292 +idle_play (gpointer data)
  49.293 +{
  49.294 +    MMythUi *mmyth_ui = (MMythUi *) data;
  49.295 +
  49.296 +    sleep (2);
  49.297 +
  49.298 +    gst_element_set_state (mmyth_ui->play, GST_STATE_PLAYING);
  49.299 +
  49.300 +    return FALSE;
  49.301 +}
  49.302 +
  49.303 +
  49.304 +/* Run IP decapsulator play function in a new thread. The thread is finished setting the
  49.305 + * semaphore "state_keep_running" to FALSE*/
  49.306 +gpointer
  49.307 +run_ipd(gpointer data)
  49.308 +{
  49.309 +    GString *ip_addr = (GString*) data;
  49.310 +
  49.311 +	state_keep_running = TRUE;
  49.312 +
  49.313 +	printf("Inside thread\n");
  49.314 +
  49.315 +	ipd_mpe_play_section (ip_addr->str, &state_keep_running);
  49.316 +
  49.317 +	return 0;
  49.318 +}
  49.319 +
  49.320 +void
  49.321 +mmyth_play_channel (MMythUi * mmyth_ui, gint service_number)
  49.322 +{
  49.323 +	ESGDatabase *esg_db;
  49.324 +    DVBHService *service;
  49.325 +	SDPData sdp_data;
  49.326 +	GString *service_ip_addr;
  49.327 +	
  49.328 +	/* First verifies if there is a tuned network */
  49.329 +	if ( !ipd_network_is_tuned() ) {
  49.330 +		/* FIXME: show alert and handle this error */
  49.331 +        g_warning ("Play not possible, network not tuned");
  49.332 +		return;
  49.333 +	}
  49.334 +
  49.335 +    esg_db = esg_database_get_instance();
  49.336 +    /* Gets the service structure */
  49.337 +    service = (DVBHService *) esg_database_get_service_from_number
  49.338 +                                 (esg_db, service_number);
  49.339 +
  49.340 +	/* Verifies if sdp fragment exists to this service */
  49.341 +	if ( service->sdp_file == NULL ) {
  49.342 +		/* FIXME: Implement error handling */
  49.343 +        g_warning ("SDP fragment not available to access service");
  49.344 +		return;
  49.345 +    }
  49.346 +	
  49.347 +	/* Parses the sdp to get ipv6 address and port */
  49.348 +	mmyth_sdp_parse_file (service->sdp_file->str, &sdp_data);
  49.349 +
  49.350 +    /* Sets the gstreamer properties acording to the service access address */
  49.351 +	/* FIXME: Develop sdp_bin in gstreamer to give sdp file as pipeline config */
  49.352 +    g_object_set (G_OBJECT (mmyth_ui->udpsource), "multicast_group",
  49.353 +                  sdp_data.ip_addr->str, NULL);
  49.354 +    g_object_set (G_OBJECT (mmyth_ui->udpsource), "port", sdp_data.video_port, NULL);
  49.355 +
  49.356 +    /* Shows the video widget on screen */
  49.357 +    mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);
  49.358 +
  49.359 +    gtk_widget_show (mmyth_ui->videow);
  49.360 +    gtk_widget_queue_draw (mmyth_ui->videow);
  49.361 +
  49.362 +#ifdef INDT_IP_DECAPSULATOR
  49.363 +    /* Will be dealocated in run_ipd */	
  49.364 +	service_ip_addr = g_string_new (sdp_data.ip_addr->str);
  49.365 +	
  49.366 +	/* Requests the IP decapsulator to play the channel stream*/
  49.367 +	g_thread_create (run_ipd, (gpointer) service_ip_addr, FALSE, NULL);
  49.368 +#endif
  49.369 +		
  49.370 +    //gst_element_set_state (mmyth_ui->play, GST_STATE_PLAYING);
  49.371 +    g_idle_add (idle_play, mmyth_ui);
  49.372 +}
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/gmyth/src/gui/mmyth_videoplayer.h	Wed Sep 20 23:45:35 2006 +0100
    50.3 @@ -0,0 +1,12 @@
    50.4 +#ifndef MMYTH_VIDEOPLAYER_H_
    50.5 +#define MMYTH_VIDEOPLAYER_H_
    50.6 +
    50.7 +#include "mmyth_ui.h"
    50.8 +
    50.9 +void mmyth_player_init (MMythUi * mmyth_ui);
   50.10 +void mmyth_player_stop (MMythUi * mmyth_ui);
   50.11 +
   50.12 +void mmyth_play_channel (MMythUi * mmyth_ui, gint service_id);
   50.13 +
   50.14 +
   50.15 +#endif /* MMYTH_VIDEOPLAYER_H_ */
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/gmyth/src/libgmyth/Makefile.am	Wed Sep 20 23:45:35 2006 +0100
    51.3 @@ -0,0 +1,59 @@
    51.4 +SUBDIRS = .
    51.5 +
    51.6 +lib_LTLIBRARIES = libgmyth.la
    51.7 +
    51.8 +libgmyth_la_SOURCES = 			\
    51.9 +	gmyth_common.c				\
   51.10 +	gmyth_context.c				\
   51.11 +	gmyth_epg.c 				\
   51.12 +	gmyth_remote_encoder.c		\
   51.13 +	gmyth_remote_util.c			\
   51.14 +	gmyth_settings.c			\
   51.15 +	gmyth_tvchain.c				\
   51.16 +	gmyth_tvplayer.c			\
   51.17 +	gmyth_scheduler.c 			\
   51.18 +	gmyth_util.c				\
   51.19 +	gmyth_query.c				\
   51.20 +	gmyth_socket.c				\
   51.21 +	gmyth_stringlist.c				
   51.22 +
   51.23 +libgmyth_la_CFLAGS = 			\
   51.24 +	-DDATADIR=\"$(pkgdatadir)\" \
   51.25 +	$(GLIB_CFLAGS) 				\
   51.26 +	$(GTK_CFLAGS) 				\
   51.27 +	$(GOBJECT_CFLAGS)			\
   51.28 +	$(GST_CFLAGS) 				\
   51.29 +	$(GSTBASE_CFLAGS)			\
   51.30 +	$(MYSQL_CFLAGS)				\
   51.31 +	-g3 -O0
   51.32 +
   51.33 +#libgmyth_la_LIBADD =			\
   51.34 +#	$(MYSQL_LIBS)
   51.35 +
   51.36 +libgmyth_la_LDFLAGS = 			\
   51.37 +	-export-dynamic 			\
   51.38 +	-lgstinterfaces-0.10 		\
   51.39 +	$(MYSQL_LIBS) 				\
   51.40 +	$(GST_LIBS) 				\
   51.41 +	$(GSTBASE_LIBS)
   51.42 +
   51.43 +libgmyth_includedir = 			\
   51.44 +	$(pkgincludedir)
   51.45 +
   51.46 +libgmyth_include_HEADERS =    	\
   51.47 +	gmyth_common.h	 			\
   51.48 +	gmyth_context.h 			\
   51.49 +	gmyth_epg.h 				\
   51.50 +	gmyth_remote_encoder.h 		\
   51.51 +	gmyth_scheduler.h 			\
   51.52 +	gmyth_settings.h 			\
   51.53 +	gmyth_tvchain.h 			\
   51.54 +	gmyth_tvplayer.h 			\
   51.55 +	gmyth_util.h 				\
   51.56 +	gmyth_query.h 				\
   51.57 +	gmyth_socket.h 				\
   51.58 +	gmyth_remote_util.h			\
   51.59 +	gmyth_stringlist.h 				
   51.60 +
   51.61 +CLEANFILES = $(BUILT_SOURCES)
   51.62 +
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/gmyth/src/libgmyth/gmyth_common.c	Wed Sep 20 23:45:35 2006 +0100
    52.3 @@ -0,0 +1,85 @@
    52.4 +/**
    52.5 + * GMyth Library
    52.6 + *
    52.7 + * @file gmyth/gmyth_common.c
    52.8 + * 
    52.9 + * @brief <p> This file contains basic common functions for the gmyth library.
   52.10 + *
   52.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   52.12 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   52.13 + *
   52.14 + *//*
   52.15 + * 
   52.16 + * This program is free software; you can redistribute it and/or modify
   52.17 + * it under the terms of the GNU Lesser General Public License as published by
   52.18 + * the Free Software Foundation; either version 2 of the License, or
   52.19 + * (at your option) any later version.
   52.20 + *
   52.21 + * This program is distributed in the hope that it will be useful,
   52.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   52.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   52.24 + * GNU General Public License for more details.
   52.25 + *
   52.26 + * You should have received a copy of the GNU Lesser General Public License
   52.27 + * along with this program; if not, write to the Free Software
   52.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   52.29 + */
   52.30 +
   52.31 +#include "gmyth_common.h"
   52.32 +
   52.33 +static void free_channel_data(gpointer data, gpointer user_data);
   52.34 +static void free_program_data(gpointer data, gpointer user_data);
   52.35 +
   52.36 +/** Frees the memory allocated to the GMythChannelInfo objects inside list.
   52.37 + * The list memory is also released by g_list_free(). If LIST is NULL it
   52.38 + * simply returns.
   52.39 + * 
   52.40 + * @param list the GList containing a list of GMythChannelInfo to free.
   52.41 + */
   52.42 +void 
   52.43 +gmyth_free_channel_list(GList *list) 
   52.44 +{
   52.45 +	if (list == NULL) {
   52.46 +		g_warning ("%s received null GList as parameter", __FUNCTION__);
   52.47 +		return;
   52.48 +	}
   52.49 +	
   52.50 +	g_list_foreach (list, free_channel_data, NULL);
   52.51 +	
   52.52 +	g_list_free (list);
   52.53 +}
   52.54 +
   52.55 +/** Frees the memory allocated to the GMythProgramInfo objects inside list.
   52.56 + * The list memory is also released by g_list_free(). If list is NULL it
   52.57 + * simply returns.
   52.58 + * 
   52.59 + * @param list the GList containing a list of GMythProgramInfo to free.
   52.60 + */
   52.61 +void
   52.62 +gmyth_free_program_list(GList *list)
   52.63 +{
   52.64 +	if (list == NULL) {
   52.65 +		g_warning ("%s received null GList as parameter", __FUNCTION__);
   52.66 +		return;
   52.67 +	}
   52.68 +	
   52.69 +	g_list_foreach (list, free_program_data, NULL);
   52.70 +	
   52.71 +	g_list_free (list);
   52.72 +}
   52.73 +
   52.74 +
   52.75 +static void 
   52.76 +free_channel_data(gpointer data, gpointer user_data)
   52.77 +{
   52.78 +    if(data)
   52.79 +        g_free((GMythChannelInfo*) data);
   52.80 +}
   52.81 +
   52.82 +static void
   52.83 +free_program_data(gpointer data, gpointer user_data)
   52.84 +{
   52.85 +    if(data)
   52.86 +        g_free((GMythProgramInfo*) data);
   52.87 +}
   52.88 +
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/gmyth/src/libgmyth/gmyth_common.h	Wed Sep 20 23:45:35 2006 +0100
    53.3 @@ -0,0 +1,155 @@
    53.4 +/**
    53.5 + * GMyth Library
    53.6 + * 
    53.7 + * @file gmyth/gmyth_common.h
    53.8 + * 
    53.9 + * @brief <p> This file contains basic common functions for the gmyth library.
   53.10 + *
   53.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   53.12 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   53.13 + *
   53.14 + *//*
   53.15 + * 
   53.16 + * This program is free software; you can redistribute it and/or modify
   53.17 + * it under the terms of the GNU Lesser General Public License as published by
   53.18 + * the Free Software Foundation; either version 2 of the License, or
   53.19 + * (at your option) any later version.
   53.20 + *
   53.21 + * This program is distributed in the hope that it will be useful,
   53.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   53.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   53.24 + * GNU General Public License for more details.
   53.25 + *
   53.26 + * You should have received a copy of the GNU Lesser General Public License
   53.27 + * along with this program; if not, write to the Free Software
   53.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   53.29 + */
   53.30 +
   53.31 +#ifndef GMYTH_COMMON_H_
   53.32 +#define GMYTH_COMMON_H_
   53.33 +
   53.34 +#include <glib.h>
   53.35 +#include <time.h>
   53.36 +
   53.37 +/**
   53.38 + * The GMythChannelInfo structure represents the channel information
   53.39 + * stored in the backend database.
   53.40 + */
   53.41 +typedef struct {
   53.42 +	/** The channel ID in backend database */
   53.43 +	int channel_ID;
   53.44 +	
   53.45 +	/** The channel name in backend database */
   53.46 +	GString *channel_name;
   53.47 +
   53.48 +} GMythChannelInfo;
   53.49 +
   53.50 +
   53.51 +/**
   53.52 + * The GMythProgramInfo structure represents a program information
   53.53 + * stored in the database. It could be a program from the EPG data,
   53.54 + * a program scheduled to be recorded, or a program already recorded.
   53.55 + */
   53.56 +typedef struct {
   53.57 +	
   53.58 +	/** The channel unique ID. */
   53.59 +    GString *chanid;
   53.60 +    
   53.61 +    /** The program start time. */
   53.62 +    time_t startts;
   53.63 +    /** The program end time. */
   53.64 +    time_t endts;
   53.65 +    /** The recording schedule start time. */
   53.66 +    time_t recstartts;
   53.67 +    /** The recording schedule end time */
   53.68 +    time_t recendts;
   53.69 +    
   53.70 +    /** The program title. */
   53.71 +    GString *title;
   53.72 +    /** The program subtitle. */
   53.73 +    GString *subtitle;
   53.74 +    /** The program description. */
   53.75 +    GString *description;
   53.76 +    /** The program category. */
   53.77 +    GString *category;
   53.78 +    
   53.79 +    GString *chanstr;
   53.80 +    GString *chansign;
   53.81 +    /** The associated channel name. */
   53.82 +    GString *channame;
   53.83 +    int chancommfree;
   53.84 +    GString *chanOutputFilters;
   53.85 +    
   53.86 +    GString *seriesid;
   53.87 +    /** The program unique id. */
   53.88 +    GString *programid;
   53.89 +    GString * catType;
   53.90 +
   53.91 +    GString * sortTitle;  
   53.92 +
   53.93 +	/** A flag informing if the program has video or not. */    
   53.94 +    gboolean isVideo;
   53.95 +    int lenMins;
   53.96 +    
   53.97 +    GString *year;    
   53.98 +    double stars;
   53.99 +    int repeat;
  53.100 +    
  53.101 +    time_t originalAirDate;
  53.102 +    time_t lastmodified;
  53.103 +    time_t lastInUseTime;
  53.104 +    
  53.105 +    gboolean hasAirDate;
  53.106 +
  53.107 +    int spread;
  53.108 +    int startCol;
  53.109 +
  53.110 +//    enum RecStatusType recstatus;
  53.111 +//    enum RecStatusType oldrecstatus;
  53.112 +//    enum RecStatusType savedrecstatus;
  53.113 +    int recpriority2;
  53.114 +    int reactivate;    
  53.115 +
  53.116 +    int recordid;
  53.117 +    int parentid;   
  53.118 +    //enum RecordingType rectype;
  53.119 +    //enum RecordingDupInType dupin;
  53.120 +    //enum RecordingDupMethodType dupmethod;
  53.121 +    
  53.122 +    /** The backend video source id associated to this program.*/
  53.123 +    int sourceid;
  53.124 +    /** the backend input id associated to this program.*/
  53.125 +    int inputid;
  53.126 +    /** The backend card id associated to this program.*/
  53.127 +    int cardid;
  53.128 +    gboolean shareable;
  53.129 +    gboolean duplicate;
  53.130 +  
  53.131 +    GString * schedulerid;
  53.132 +    int findid;
  53.133 +
  53.134 +    int programflags;
  53.135 +    int transcoder;
  53.136 +
  53.137 +    //proginfo->spread = -1;
  53.138 +    //proginfo->programflags = proginfo->getProgramFlags();
  53.139 +
  53.140 +    GString *recgroup;
  53.141 +    GString *playgroup;
  53.142 +    int recpriority;
  53.143 +
  53.144 +	/** The file size of the recorded program.*/
  53.145 +    long long filesize;
  53.146 +    /** The file name of the recorded program.*/
  53.147 +    GString *pathname;
  53.148 +    GString *hostname;
  53.149 +        
  53.150 +    /* AvailableStatusType availableStatus;*/
  53.151 + 
  53.152 +} GMythProgramInfo;
  53.153 +
  53.154 +
  53.155 +void gmyth_free_channel_list(GList *list);
  53.156 +void gmyth_free_program_list(GList *list);
  53.157 +
  53.158 +#endif /* GMYTH_COMMON_H_ */
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/gmyth/src/libgmyth/gmyth_context.c	Wed Sep 20 23:45:35 2006 +0100
    54.3 @@ -0,0 +1,312 @@
    54.4 +/**
    54.5 + * GMyth Library
    54.6 + *
    54.7 + * @file gmyth/gmyth_context.c
    54.8 + * 
    54.9 + * @brief <p> GMythContext class contains general attributes and functions
   54.10 + * that express the connection state of each mythtvfrontend.
   54.11 + *
   54.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   54.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   54.14 + *
   54.15 + *//*
   54.16 + * 
   54.17 + * This program is free software; you can redistribute it and/or modify
   54.18 + * it under the terms of the GNU Lesser General Public License as published by
   54.19 + * the Free Software Foundation; either version 2 of the License, or
   54.20 + * (at your option) any later version.
   54.21 + *
   54.22 + * This program is distributed in the hope that it will be useful,
   54.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   54.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   54.25 + * GNU General Public License for more details.
   54.26 + *
   54.27 + * You should have received a copy of the GNU Lesser General Public License
   54.28 + * along with this program; if not, write to the Free Software
   54.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   54.30 + */
   54.31 +
   54.32 +#include "gmyth_context.h"
   54.33 +
   54.34 +#include <arpa/inet.h>
   54.35 +#include <sys/types.h>
   54.36 +#include <sys/socket.h>
   54.37 +#include <netdb.h>
   54.38 +#include <errno.h>
   54.39 +#include <stdlib.h>
   54.40 +
   54.41 +#include "gmyth_query.h"
   54.42 +#include "gmyth_socket.h"
   54.43 +
   54.44 +static void gmyth_context_class_init          (GMythContextClass *klass);
   54.45 +static void gmyth_context_init                (GMythContext *object);
   54.46 +
   54.47 +static void gmyth_context_dispose  (GObject *object);
   54.48 +static void gmyth_context_finalize (GObject *object);
   54.49 +
   54.50 +
   54.51 +G_DEFINE_TYPE(GMythContext, gmyth_context, G_TYPE_OBJECT)
   54.52 +
   54.53 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
   54.54 +
   54.55 +static GMythContext *gcontext = NULL; 
   54.56 +
   54.57 +static void
   54.58 +gmyth_context_class_init (GMythContextClass *klass)
   54.59 +{
   54.60 +	GObjectClass *gobject_class;
   54.61 +
   54.62 +	gobject_class = (GObjectClass *) klass;
   54.63 +
   54.64 +	gobject_class->dispose  = gmyth_context_dispose;
   54.65 +	gobject_class->finalize = gmyth_context_finalize;	
   54.66 +}
   54.67 +
   54.68 +static void
   54.69 +gmyth_context_init (GMythContext *gmyth_context)
   54.70 +{
   54.71 +
   54.72 +}
   54.73 +
   54.74 +static void
   54.75 +gmyth_context_dispose  (GObject *object)
   54.76 +{
   54.77 +	GMythContext *gmyth_context = GMYTH_CONTEXT(object);
   54.78 +
   54.79 +	if ( gmyth_context->gmyth_settings != NULL ) {
   54.80 +		g_object_unref (gmyth_context->gmyth_settings);	
   54.81 +		gmyth_context->gmyth_settings = NULL;
   54.82 +	}
   54.83 +
   54.84 +	if ( gmyth_context->localhostname != NULL ) {
   54.85 +		g_string_free ( gmyth_context->localhostname, TRUE );
   54.86 +		gmyth_context->localhostname = NULL;
   54.87 +	}
   54.88 +
   54.89 +	if (gmyth_context->server_socket != NULL) {
   54.90 +		g_object_unref (gmyth_context->server_socket);
   54.91 +		gmyth_context->server_socket = NULL;
   54.92 +	}
   54.93 +
   54.94 +	G_OBJECT_CLASS (gmyth_context_parent_class)->dispose (object);
   54.95 +}
   54.96 +
   54.97 +static void
   54.98 +gmyth_context_finalize (GObject *object)
   54.99 +{
  54.100 +	g_signal_handlers_destroy (object);
  54.101 +
  54.102 +	G_OBJECT_CLASS (gmyth_context_parent_class)->finalize (object);
  54.103 +}
  54.104 +
  54.105 +/** Gets the some important address translation info, 
  54.106 + * from the client socket that will open a connection.
  54.107 + *
  54.108 + * @return gint error number
  54.109 + */
  54.110 +static gint
  54.111 +myth_context_toaddrinfo( gchar *addr, gint port, struct addrinfo **addrInfo )
  54.112 +{
  54.113 +	struct addrinfo hints;
  54.114 +	gchar *portStr = g_strnfill( 32, ' ' );
  54.115 +	gint errorn = EADDRNOTAVAIL;
  54.116 +
  54.117 +	memset( &hints, 0, sizeof(hints) );
  54.118 +	hints.ai_family = AF_INET;
  54.119 +	hints.ai_socktype = SOCK_STREAM;
  54.120 +
  54.121 +	/* hints.ai_flags = AI_NUMERICHOST; */
  54.122 +	if ( port != -1 )
  54.123 +		sprintf(portStr, "%d", port);
  54.124 +	else
  54.125 +		portStr = NULL;
  54.126 +
  54.127 +	g_debug( "[%s] Address: %s, port: %s\n", __FUNCTION__, addr, portStr );
  54.128 +	if ( ( errorn = getaddrinfo(addr, portStr, &hints, addrInfo) ) != 0 ) {
  54.129 +		g_printerr( "[%s] Socket ERROR: %s\n", __FUNCTION__, gai_strerror(errorn) );
  54.130 +	}
  54.131 +
  54.132 +	return errorn;
  54.133 +
  54.134 +}
  54.135 +
  54.136 +/** Initializes the GMythContext object. It reads local system information
  54.137 + * load gmyth user settings and start connection to the database.
  54.138 + * 
  54.139 + * @return TRUE if initialization was successfull, 
  54.140 + * FALSE if any error happens.
  54.141 + */
  54.142 +gboolean
  54.143 +gmyth_context_initialize ()
  54.144 +{
  54.145 +	GString *localhost = NULL;
  54.146 +
  54.147 +	if (gcontext == NULL) {
  54.148 +		gcontext = GMYTH_CONTEXT ( g_object_new (GMYTH_CONTEXT_TYPE, FALSE));
  54.149 +	}
  54.150 +
  54.151 +	localhost = gmyth_socket_get_local_hostname( );
  54.152 +
  54.153 +	if (localhost==NULL || localhost->len <=0 ) {
  54.154 +		g_warning ("[%s] Could not determine local hostname. Setting to 127.0.0.1", __FUNCTION__);
  54.155 +		gcontext->localhostname = g_string_new ("127.0.0.1");
  54.156 +	} else {
  54.157 +		gcontext->localhostname = localhost;
  54.158 +	}
  54.159 +
  54.160 +	if (gcontext->gmyth_settings) {
  54.161 +		g_object_unref (gcontext->gmyth_settings);	
  54.162 +		gcontext->gmyth_settings = NULL;
  54.163 +	}
  54.164 +
  54.165 +	gcontext->gmyth_settings = gmyth_settings_new ();
  54.166 +	if (!gmyth_settings_load (gcontext->gmyth_settings)) {
  54.167 +		g_warning ("GMythContext: Settings file not opened!\n");	
  54.168 +	} else {
  54.169 +		g_debug ("GMythContext: Settings file loaded");
  54.170 +	}
  54.171 +
  54.172 +	if (gcontext->server_socket != NULL) {
  54.173 +		g_object_unref (gcontext->server_socket);
  54.174 +		gcontext->server_socket = NULL;
  54.175 +	}
  54.176 +
  54.177 +	GString *server_hostname = 
  54.178 +        gmyth_settings_get_backend_hostname(gcontext->gmyth_settings);
  54.179 +	int server_port = gmyth_settings_get_backend_port(gcontext->gmyth_settings);
  54.180 +
  54.181 +	gcontext->server_socket = gmyth_socket_new ();
  54.182 +	if (!gmyth_socket_connect_to_backend (gcontext->server_socket,
  54.183 +				server_hostname->str, server_port, FALSE)) {
  54.184 +		g_warning ("[%s] Socket connection to backend error!", __FUNCTION__);
  54.185 +		g_object_unref (gcontext->server_socket);
  54.186 +		gcontext->server_socket = NULL;
  54.187 +		return FALSE;	
  54.188 +	}
  54.189 +
  54.190 +	return TRUE;
  54.191 +}
  54.192 +
  54.193 +/** Formats a Mythtv protocol command based on strlist and sends it to
  54.194 + * the connected backend. The backend response is overwritten into strlist.
  54.195 + * 
  54.196 + * @param strlist the string list to be sent, 
  54.197 + * and on which the answer will be written.
  54.198 + * @return TRUE if command was sent and an answer was received, FALSE if any
  54.199 + * error happens.
  54.200 + */
  54.201 +gboolean
  54.202 +gmyth_context_send_receive_stringlist (GMythStringList *strlist)
  54.203 +{
  54.204 +	gint ok = -1;
  54.205 +
  54.206 +	if (!gcontext || !(gcontext->server_socket)) {
  54.207 +		g_warning ("[%s] GMythContext not initialized", __FUNCTION__);
  54.208 +		return FALSE;
  54.209 +	}
  54.210 +
  54.211 +	//g_static_mutex_lock( &mutex );
  54.212 +
  54.213 +	ok = gmyth_socket_sendreceive_stringlist (gcontext->server_socket, strlist);
  54.214 +
  54.215 +	//g_static_mutex_unlock( &mutex );
  54.216 +
  54.217 +	if (!ok) {
  54.218 +		g_warning ("Connection to backend server lost");
  54.219 +	}
  54.220 +
  54.221 +	return (ok ? TRUE : FALSE);
  54.222 +}
  54.223 +
  54.224 +/** Gets the GMythSettings object associated to this context.
  54.225 + * 
  54.226 + * @return The GMythSettings object currently valid or NULL if the settings
  54.227 + * were not opened.
  54.228 + */
  54.229 +GMythSettings*
  54.230 +gmyth_context_get_settings ()
  54.231 +{
  54.232 +	if (!gcontext) {
  54.233 +		g_warning ("[%s] GMythContext not initialized\n", __FUNCTION__);
  54.234 +		return NULL;
  54.235 +	}
  54.236 +
  54.237 +	return gcontext->gmyth_settings;
  54.238 +}
  54.239 +
  54.240 +/** Gets the machine local hostname.
  54.241 + * 
  54.242 + * @param hostname a valid GString object to be overwritten with the local
  54.243 + * hostname.
  54.244 + * @return true if the hostname was read, false if any error happened.
  54.245 + */
  54.246 +gboolean
  54.247 +gmyth_context_get_local_hostname (GString *hostname)
  54.248 +{
  54.249 +	if (!hostname) {
  54.250 +		g_warning ("[%s] Received null argument", __FUNCTION__);
  54.251 +		return FALSE;
  54.252 +	}
  54.253 +
  54.254 +	g_string_assign (hostname, gcontext->localhostname->str);
  54.255 +
  54.256 +	return TRUE;
  54.257 +}
  54.258 +
  54.259 +/** Gets a setting information from the backend mysql database.
  54.260 + * 
  54.261 + * @param key The setting key to be retrieved.
  54.262 + * @param host the hostname associated to the desired setting.
  54.263 + * @param default_value the default setting value if could not query from
  54.264 + * backend database.
  54.265 + * @return The setting value loaded from database, or the given default value
  54.266 + * if the query fails.
  54.267 + */
  54.268 +GString*
  54.269 +gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value)
  54.270 +{
  54.271 +	GString *query_str;
  54.272 +
  54.273 +	// TODO: Reuse msql query in gmyth_context
  54.274 +	GMythQuery *gmyth_query = gmyth_query_new ();
  54.275 +
  54.276 +	if (gmyth_query_connect (gmyth_query)) {
  54.277 +		MYSQL_RES *msql_res;
  54.278 +		MYSQL_ROW msql_row;
  54.279 +
  54.280 +		query_str = g_string_new ("");
  54.281 +		g_string_printf (query_str, "SELECT data FROM settings WHERE value = \"%s\" "
  54.282 +				"AND hostname = \"%s\" ;", key->str, host->str);
  54.283 +
  54.284 +		msql_res = gmyth_query_process_statement (gmyth_query, query_str->str);
  54.285 +		if (msql_res) {
  54.286 +			msql_row = mysql_fetch_row (msql_res);
  54.287 +			if (msql_row != NULL) {
  54.288 +				return g_string_new (msql_row[0]);
  54.289 +			}
  54.290 +		}
  54.291 +
  54.292 +		g_object_unref (gmyth_query);
  54.293 +	} else {
  54.294 +		g_warning ("Database not open while trying to load setting: %s", key->str);
  54.295 +	}
  54.296 +
  54.297 +
  54.298 +	return default_value;
  54.299 +}
  54.300 +
  54.301 +/** Verify if the context is currently connected to a backend.
  54.302 + * 
  54.303 + * @return true if connection was opened, false if not.
  54.304 + */
  54.305 +gboolean
  54.306 +gmyth_context_check_connection ()
  54.307 +{
  54.308 +	// FIXME: Check this based on socket states
  54.309 +	if (!gcontext) {
  54.310 +		g_warning ("[%s] GMythContext not initialized", __FUNCTION__);
  54.311 +		return FALSE;
  54.312 +	}
  54.313 +
  54.314 +	return (gcontext->server_socket != NULL);
  54.315 +}
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/gmyth/src/libgmyth/gmyth_context.h	Wed Sep 20 23:45:35 2006 +0100
    55.3 @@ -0,0 +1,88 @@
    55.4 +/**
    55.5 + * GMyth Library
    55.6 + *
    55.7 + * @file gmyth/gmyth_context.h
    55.8 + * 
    55.9 + * @brief <p> GMythContext class contains general attributes and functions
   55.10 + * that express the connection state of each mythtvfrontend.
   55.11 + *
   55.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   55.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   55.14 + *
   55.15 + *//*
   55.16 + * 
   55.17 + * This program is free software; you can redistribute it and/or modify
   55.18 + * it under the terms of the GNU Lesser General Public License as published by
   55.19 + * the Free Software Foundation; either version 2 of the License, or
   55.20 + * (at your option) any later version.
   55.21 + *
   55.22 + * This program is distributed in the hope that it will be useful,
   55.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   55.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   55.25 + * GNU General Public License for more details.
   55.26 + *
   55.27 + * You should have received a copy of the GNU Lesser General Public License
   55.28 + * along with this program; if not, write to the Free Software
   55.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   55.30 + */
   55.31 +
   55.32 +#ifndef __GMYTH_CONTEXT_H__
   55.33 +#define __GMYTH_CONTEXT_H__
   55.34 +
   55.35 +#include <glib-object.h>
   55.36 +
   55.37 +#include "gmyth_settings.h"
   55.38 +#include "gmyth_socket.h"
   55.39 +#include "gmyth_stringlist.h"
   55.40 +
   55.41 +#define G_BEGIN_DECLS
   55.42 +
   55.43 +#define GMYTH_CONTEXT_TYPE               (gmyth_context_get_type ())
   55.44 +#define GMYTH_CONTEXT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_CONTEXT_TYPE, GMythContext))
   55.45 +#define GMYTH_CONTEXT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_CONTEXT_TYPE, GMythContextClass))
   55.46 +#define IS_GMYTH_CONTEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_CONTEXT_TYPE))
   55.47 +#define IS_GMYTH_CONTEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_CONTEXT_TYPE))
   55.48 +#define GMYTH_CONTEXT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_CONTEXT_TYPE, GMythContextClass))
   55.49 +
   55.50 +#define MYTHTV_VERSION_DEFAULT          30
   55.51 +
   55.52 +typedef struct _GMythContext         GMythContext;
   55.53 +typedef struct _GMythContextClass    GMythContextClass;
   55.54 +
   55.55 +struct _GMythContextClass
   55.56 +{
   55.57 +  GObjectClass parent_class;
   55.58 +
   55.59 +  /* callbacks */
   55.60 +  /* no one for now */
   55.61 +};
   55.62 +
   55.63 +struct _GMythContext
   55.64 +{
   55.65 +    GObject parent;
   55.66 +
   55.67 +	GMythSettings *gmyth_settings;
   55.68 +	GMythSocket *server_socket;  
   55.69 +	
   55.70 +	GString *localhostname;
   55.71 +};
   55.72 +
   55.73 +
   55.74 +GType           gmyth_context_get_type (void);
   55.75 +void            gmyth_context_create();
   55.76 +
   55.77 +gboolean gmyth_context_initialize ();
   55.78 +gboolean gmyth_context_check_connection ();
   55.79 +GMythSettings* gmyth_context_get_settings ();
   55.80 +
   55.81 +gboolean gmyth_context_send_receive_stringlist (GMythStringList *strlist);
   55.82 +
   55.83 +GString* gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value);
   55.84 +gboolean gmyth_context_get_local_hostname (GString *hostname);
   55.85 +
   55.86 +GString* gmyth_context_get_setting_onhost (GString *key, GString *host, GString *default_value);
   55.87 +
   55.88 +
   55.89 +#define G_END_DECLS
   55.90 +
   55.91 +#endif /* __GMYTH_CONTEXT_H__ */
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/gmyth/src/libgmyth/gmyth_epg.c	Wed Sep 20 23:45:35 2006 +0100
    56.3 @@ -0,0 +1,278 @@
    56.4 +/**
    56.5 + * GMyth Library
    56.6 + *
    56.7 + * @file gmyth/gmyth_epg.c
    56.8 + * 
    56.9 + * @brief <p> GMythEPG class provides access to the program and channel data
   56.10 + * from the Electronic Program Guide (EPG) of the Mythtv backend.
   56.11 + *
   56.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   56.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   56.14 + *
   56.15 + *//*
   56.16 + * 
   56.17 + * This program is free software; you can redistribute it and/or modify
   56.18 + * it under the terms of the GNU Lesser General Public License as published by
   56.19 + * the Free Software Foundation; either version 2 of the License, or
   56.20 + * (at your option) any later version.
   56.21 + *
   56.22 + * This program is distributed in the hope that it will be useful,
   56.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   56.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   56.25 + * GNU General Public License for more details.
   56.26 + *
   56.27 + * You should have received a copy of the GNU Lesser General Public License
   56.28 + * along with this program; if not, write to the Free Software
   56.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   56.30 + */
   56.31 +
   56.32 +#include <mysql.h>
   56.33 +#include <stdlib.h>
   56.34 +#include <string.h>
   56.35 +#include <assert.h>
   56.36 +
   56.37 +#include "gmyth_epg.h"
   56.38 +#include "gmyth_util.h"
   56.39 +
   56.40 +static void gmyth_epg_class_init          (GMythEPGClass *klass);
   56.41 +static void gmyth_epg_init                (GMythEPG *object);
   56.42 +
   56.43 +static void gmyth_epg_dispose  (GObject *object);
   56.44 +static void gmyth_epg_finalize (GObject *object);
   56.45 +
   56.46 +G_DEFINE_TYPE(GMythEPG, gmyth_epg, G_TYPE_OBJECT)
   56.47 +    
   56.48 +static void
   56.49 +gmyth_epg_class_init (GMythEPGClass *klass)
   56.50 +{
   56.51 +	GObjectClass *gobject_class;
   56.52 +
   56.53 +    gobject_class = (GObjectClass *) klass;
   56.54 +	
   56.55 +    gobject_class->dispose  = gmyth_epg_dispose;
   56.56 +    gobject_class->finalize = gmyth_epg_finalize;	
   56.57 +}
   56.58 +
   56.59 +static void
   56.60 +gmyth_epg_init (GMythEPG *gmyth_epg)
   56.61 +{
   56.62 +	gmyth_epg->sqlquery = gmyth_query_new ();
   56.63 +}
   56.64 +
   56.65 +static void
   56.66 +gmyth_epg_dispose  (GObject *object)
   56.67 +{
   56.68 +    //GMythEPG *gmyth_epg = GMYTH_EPG(object);
   56.69 +    
   56.70 +	G_OBJECT_CLASS (gmyth_epg_parent_class)->dispose (object);
   56.71 +}
   56.72 +
   56.73 +static void
   56.74 +gmyth_epg_finalize (GObject *object)
   56.75 +{
   56.76 +	g_signal_handlers_destroy (object);
   56.77 +
   56.78 +    G_OBJECT_CLASS (gmyth_epg_parent_class)->finalize (object);
   56.79 +}
   56.80 +
   56.81 +/**
   56.82 + * Creates a new instance of GMythEPG.
   56.83 + * 
   56.84 + * @return a new instance of GMythEPG.
   56.85 + */
   56.86 +GMythEPG*
   56.87 +gmyth_epg_new ()
   56.88 +{
   56.89 +    GMythEPG *epg = GMYTH_EPG (g_object_new(GMYTH_EPG_TYPE, NULL));
   56.90 +
   56.91 +    return epg;
   56.92 +}
   56.93 +
   56.94 +/** Connects to the Mysql database in the backend. The backend address
   56.95 + * is loaded from the GMythSettings instance.
   56.96 + * 
   56.97 + * @param gmyth_epg the GMythEPG instance to be connected.
   56.98 + * @return true if connection was success, false if failed.
   56.99 + */
  56.100 +gboolean
  56.101 +gmyth_epg_connect (GMythEPG *gmyth_epg)
  56.102 +{
  56.103 +	assert(gmyth_epg);
  56.104 +
  56.105 +	if (gmyth_epg->sqlquery	== NULL) {
  56.106 +		g_warning ("[%s] GMythEPG not initialized", __FUNCTION__);
  56.107 +		return FALSE;
  56.108 +	}
  56.109 +
  56.110 +    if (!gmyth_query_connect(gmyth_epg->sqlquery)) {
  56.111 +        g_warning ("[%s] Error while connecting to db", __FUNCTION__);
  56.112 +        return FALSE;
  56.113 +    }
  56.114 +
  56.115 +    return TRUE;	
  56.116 +}
  56.117 +
  56.118 +/** Disconnects from the Mysql database in the backend.
  56.119 + * 
  56.120 + * @param gmyth_epg the GMythEPG instance to be disconnected
  56.121 + * @return true if disconnection was success, false if failed.
  56.122 + */
  56.123 +gboolean
  56.124 +gmyth_epg_disconnect (GMythEPG *gmyth_epg)
  56.125 +{
  56.126 +	assert(gmyth_epg);
  56.127 +
  56.128 +	if (gmyth_epg->sqlquery	!= NULL) {	
  56.129 +		g_object_unref (gmyth_epg->sqlquery);
  56.130 +	}
  56.131 +	
  56.132 +	return TRUE;
  56.133 +}
  56.134 +
  56.135 +/** Retrieves the available list of channels from the backend Mysql database.
  56.136 + * 
  56.137 + * @param gmyth_epg the GMythEPG instance.
  56.138 + * @param glist_ptr the GList pointer to be filled with the loaded list address.
  56.139 + * @return The amount of channels retrieved from database,  or -1 if error.
  56.140 + */
  56.141 +gint
  56.142 +gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr)
  56.143 +{
  56.144 +	MYSQL_RES *msql_res;
  56.145 +
  56.146 +    assert(gmyth_epg);
  56.147 +
  56.148 +    msql_res = gmyth_query_process_statement (gmyth_epg->sqlquery, 
  56.149 +    		"SELECT chanid,name FROM channel;");
  56.150 +
  56.151 +	(*glist_ptr) = NULL;
  56.152 +	
  56.153 +    if (msql_res == NULL) {
  56.154 +        g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
  56.155 +		return -1;
  56.156 +    } else {
  56.157 +        MYSQL_ROW row;
  56.158 +		GMythChannelInfo *channel_info;        
  56.159 +
  56.160 +        while ((row = mysql_fetch_row (msql_res)) != NULL){
  56.161 +
  56.162 +        	channel_info = g_new0(GMythChannelInfo, 1);
  56.163 +            channel_info->channel_ID = atoi (row[0]);
  56.164 +            channel_info->channel_name = g_string_new (row[1]);
  56.165 +        
  56.166 +            (*glist_ptr) = g_list_append ((*glist_ptr), channel_info);
  56.167 +    	}
  56.168 +    }
  56.169 +    mysql_free_result (msql_res);
  56.170 +    return (!(*glist_ptr)) ?  0 : g_list_length (*glist_ptr);
  56.171 +}
  56.172 +
  56.173 +/** 
  56.174 + * Retrieves the available list of channels from the backend Mysql database.
  56.175 + * 
  56.176 + * @param gmyth_epg the GMythEPG instance.
  56.177 + * @param proglist the GList pointer to be filled with the loaded list.
  56.178 + * @param chan_num the channel num on which to search for program.
  56.179 + * @param starttime the start time to search for programs.
  56.180 + * @param endtime the end time to search for programs.
  56.181 + * @return The amount of channels retrieved from database, or -1 if error.
  56.182 + */
  56.183 +gint
  56.184 +gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
  56.185 +		const gint chan_num, time_t starttime, time_t endtime)
  56.186 +{
  56.187 +    GString *startts = gmyth_util_time_to_string(starttime);
  56.188 +    GString *endts = gmyth_util_time_to_string(endtime);
  56.189 +    MYSQL_ROW row;
  56.190 +    GString *querystr;
  56.191 +    
  56.192 +    assert(gmyth_epg);
  56.193 +    
  56.194 +    querystr = g_string_new(
  56.195 +        "SELECT DISTINCT program.chanid, program.starttime, program.endtime, "
  56.196 +        "    program.title, program.subtitle, program.description, "
  56.197 +        "    program.category, channel.channum, channel.callsign, "
  56.198 +        "    channel.name, program.previouslyshown, channel.commfree, "
  56.199 +        "    channel.outputfilters, program.seriesid, program.programid, "
  56.200 +        "    program.airdate, program.stars, program.originalairdate, "
  56.201 +        "    program.category_type, oldrecstatus.recordid, "
  56.202 +        "    oldrecstatus.rectype, oldrecstatus.recstatus, "
  56.203 +        "    oldrecstatus.findid "
  56.204 +        "FROM program "
  56.205 +        "LEFT JOIN channel ON program.chanid = channel.chanid "
  56.206 +        "LEFT JOIN oldrecorded AS oldrecstatus ON "
  56.207 +        "    program.title = oldrecstatus.title AND "
  56.208 +        "    channel.callsign = oldrecstatus.station AND "
  56.209 +        "    program.starttime = oldrecstatus.starttime "
  56.210 +        );
  56.211 +        
  56.212 +    g_string_append_printf (querystr, 
  56.213 +        "WHERE program.chanid = %d "
  56.214 +        "  AND program.endtime >= '%s' "
  56.215 +        "  AND program.starttime <= '%s' "
  56.216 +        "  AND program.manualid = 0 ",
  56.217 +        chan_num, startts->str, endts->str);
  56.218 +
  56.219 +    if (!g_strrstr(querystr->str, " GROUP BY "))
  56.220 +        querystr = g_string_append(querystr,
  56.221 +            " GROUP BY program.starttime, channel.channum, "
  56.222 +            "  channel.callsign, program.title ");
  56.223 +
  56.224 +    if (!g_strrstr(querystr->str, " LIMIT "))
  56.225 +        querystr = g_string_append(querystr, " LIMIT 1000 ");
  56.226 +
  56.227 +    MYSQL_RES *res_set = 
  56.228 +        gmyth_query_process_statement(gmyth_epg->sqlquery, querystr->str);
  56.229 +
  56.230 +    if (res_set == NULL) {
  56.231 +        g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
  56.232 +		return -1;
  56.233 +    }
  56.234 +
  56.235 +    (*proglist) = NULL;        
  56.236 +    while ((row = mysql_fetch_row (res_set)) != NULL) {
  56.237 +
  56.238 +        GMythProgramInfo *p = g_new0 (GMythProgramInfo, 1);
  56.239 +        p->chanid = g_string_new (row[0]);
  56.240 +
  56.241 +        p->startts = gmyth_util_string_to_time (g_string_new (row[1]));
  56.242 +        p->endts = gmyth_util_string_to_time (g_string_new (row[2]));
  56.243 +                                                     
  56.244 +        p->recstartts = p->startts;
  56.245 +        p->recendts = p->endts;
  56.246 +        p->lastmodified = p->startts;
  56.247 +    
  56.248 +        p->title = g_string_new (row[3]);
  56.249 +        p->subtitle = g_string_new (row[4]);
  56.250 +        p->description = g_string_new (row[5]);
  56.251 +        p->category = g_string_new (row[6]);
  56.252 +        p->chanstr = g_string_new (row[7]);
  56.253 +        p->chansign = g_string_new (row[8]);
  56.254 +        p->channame = g_string_new (row[9]);
  56.255 +        p->repeat = atoi(row[10]);
  56.256 +        p->chancommfree = atoi(row[11]);
  56.257 +        p->chanOutputFilters = g_string_new (row[12]);
  56.258 +        p->seriesid = g_string_new (row[13]);
  56.259 +        p->programid = g_string_new (row[14]);
  56.260 +        p->year = g_string_new (row[15]);
  56.261 +        p->stars = atof(row[16]);
  56.262 +
  56.263 +        if (!row[17] || !strcmp(row[17], "")) {
  56.264 +            p->originalAirDate = 0;
  56.265 +            p->hasAirDate = FALSE;
  56.266 +        } else {
  56.267 +            p->originalAirDate = gmyth_util_string_to_time (g_string_new (row[17]));
  56.268 +            p->hasAirDate = TRUE;
  56.269 +        }
  56.270 +        
  56.271 +        p->catType = g_string_new (row[18]);
  56.272 +
  56.273 +        *proglist = g_list_append((*proglist), p);
  56.274 +    }
  56.275 +
  56.276 +    /* deallocate */
  56.277 +    mysql_free_result (res_set);
  56.278 +    g_string_free(querystr, TRUE);
  56.279 +
  56.280 +    return TRUE;
  56.281 +}
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/gmyth/src/libgmyth/gmyth_epg.h	Wed Sep 20 23:45:35 2006 +0100
    57.3 @@ -0,0 +1,75 @@
    57.4 +/**
    57.5 + * GMyth Library
    57.6 + *
    57.7 + * @file gmyth/gmyth_epg.h
    57.8 + * 
    57.9 + * @brief <p> GMythEPG class provides access to the program and channel data
   57.10 + * from the Electronic Program Guide (EPG) of the Mythtv backend.
   57.11 + *
   57.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   57.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   57.14 + *
   57.15 + *//*
   57.16 + * 
   57.17 + * This program is free software; you can redistribute it and/or modify
   57.18 + * it under the terms of the GNU Lesser General Public License as published by
   57.19 + * the Free Software Foundation; either version 2 of the License, or
   57.20 + * (at your option) any later version.
   57.21 + *
   57.22 + * This program is distributed in the hope that it will be useful,
   57.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   57.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   57.25 + * GNU General Public License for more details.
   57.26 + *
   57.27 + * You should have received a copy of the GNU Lesser General Public License
   57.28 + * along with this program; if not, write to the Free Software
   57.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   57.30 + */
   57.31 +
   57.32 +#ifndef GMYTH_EPG_H_
   57.33 +#define GMYTH_EPG_H_
   57.34 +
   57.35 +#include <glib-object.h>
   57.36 +
   57.37 +#include "gmyth_query.h"
   57.38 +#include "gmyth_common.h"
   57.39 +
   57.40 +#define G_BEGIN_DECLS
   57.41 +
   57.42 +#define GMYTH_EPG_TYPE               (gmyth_epg_get_type ())
   57.43 +#define GMYTH_EPG(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE, GMythEPG))
   57.44 +#define GMYTH_EPG_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE, GMythEPGClass))
   57.45 +#define IS_GMYTH_EPG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE))
   57.46 +#define IS_GMYTH_EPG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE))
   57.47 +#define GMYTH_EPG_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_EPG_TYPE, GMythEPGClass))
   57.48 +
   57.49 +typedef struct _GMythEPG         GMythEPG;
   57.50 +typedef struct _GMythEPGClass    GMythEPGClass;
   57.51 +
   57.52 +struct _GMythEPGClass
   57.53 +{
   57.54 +  GObjectClass parent_class;
   57.55 +
   57.56 +  /* callbacks */
   57.57 +  /* no one for now */
   57.58 +};
   57.59 +
   57.60 +struct _GMythEPG
   57.61 +{
   57.62 +    GObject parent;
   57.63 +
   57.64 +	GMythQuery *sqlquery;
   57.65 +};
   57.66 +
   57.67 +GType          gmyth_epg_get_type (void);
   57.68 +
   57.69 +GMythEPG* gmyth_epg_new ();
   57.70 +
   57.71 +gboolean gmyth_epg_connect (GMythEPG *gmyth_epg);
   57.72 +gboolean gmyth_epg_disconnect (GMythEPG *gmyth_epg);
   57.73 +
   57.74 +gint gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr);
   57.75 +gint gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
   57.76 +		const gint chanNum, time_t  starttime, time_t  endtime);
   57.77 +
   57.78 +#endif /*GMYTH_EPG_H_*/
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/gmyth/src/libgmyth/gmyth_query.c	Wed Sep 20 23:45:35 2006 +0100
    58.3 @@ -0,0 +1,221 @@
    58.4 +/**
    58.5 + * GMyth Library
    58.6 + *
    58.7 + * @file gmyth/gmyth_query.c
    58.8 + * 
    58.9 + * @brief <p> GMythQuery class provides a wrapper for accessing
   58.10 + * the libmysqlclient funtions.
   58.11 + *
   58.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   58.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   58.14 + *
   58.15 + *//*
   58.16 + * 
   58.17 + * This program is free software; you can redistribute it and/or modify
   58.18 + * it under the terms of the GNU Lesser General Public License as published by
   58.19 + * the Free Software Foundation; either version 2 of the License, or
   58.20 + * (at your option) any later version.
   58.21 + *
   58.22 + * This program is distributed in the hope that it will be useful,
   58.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   58.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   58.25 + * GNU General Public License for more details.
   58.26 + *
   58.27 + * You should have received a copy of the GNU Lesser General Public License
   58.28 + * along with this program; if not, write to the Free Software
   58.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   58.30 + */
   58.31 +
   58.32 +#include <stdlib.h>
   58.33 +#include <stdio.h>
   58.34 +#include <assert.h>
   58.35 +
   58.36 +#include "gmyth_query.h"
   58.37 +#include "gmyth_settings.h"
   58.38 +#include "gmyth_context.h"
   58.39 +
   58.40 +static void gmyth_query_class_init          (GMythQueryClass *klass);
   58.41 +static void gmyth_query_init                (GMythQuery *object);
   58.42 +
   58.43 +static void gmyth_query_dispose  (GObject *object);
   58.44 +static void gmyth_query_finalize (GObject *object);
   58.45 +
   58.46 +static void gmyth_query_print_error (MYSQL *conn, char *message);
   58.47 +
   58.48 +G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT)
   58.49 +    
   58.50 +static void
   58.51 +gmyth_query_class_init (GMythQueryClass *klass)
   58.52 +{
   58.53 +	GObjectClass *gobject_class;
   58.54 +
   58.55 +    gobject_class = (GObjectClass *) klass;
   58.56 +	
   58.57 +    gobject_class->dispose  = gmyth_query_dispose;
   58.58 +    gobject_class->finalize = gmyth_query_finalize;	
   58.59 +}
   58.60 +
   58.61 +static void
   58.62 +gmyth_query_init (GMythQuery *gmyth_query)
   58.63 +{
   58.64 +	GMythSettings *gmyth_settings = gmyth_context_get_settings ();
   58.65 +	
   58.66 +    gmyth_query->opt_host_name = gmyth_settings_get_backend_hostname(gmyth_settings);
   58.67 +    gmyth_query->opt_user_name = gmyth_settings_get_username(gmyth_settings);
   58.68 +    gmyth_query->opt_password = gmyth_settings_get_password(gmyth_settings);
   58.69 +    gmyth_query->opt_db_name = gmyth_settings_get_dbname(gmyth_settings);
   58.70 +
   58.71 +    /* initialize connection handler */
   58.72 +    gmyth_query->conn = mysql_init (NULL);
   58.73 +    
   58.74 +    if (!(gmyth_query->conn))
   58.75 +    	g_warning ("[%s] MSQL structure not initialized", __FUNCTION__);
   58.76 +
   58.77 +}
   58.78 +
   58.79 +static void
   58.80 +gmyth_query_dispose  (GObject *object)
   58.81 +{
   58.82 +    GMythQuery *gmyth_query = GMYTH_QUERY (object);
   58.83 +    
   58.84 +    /* disconnect from server */
   58.85 +	gmyth_query_disconnect (gmyth_query);
   58.86 +	
   58.87 +	G_OBJECT_CLASS (gmyth_query_parent_class)->dispose (object);
   58.88 +}
   58.89 +
   58.90 +static void
   58.91 +gmyth_query_finalize (GObject *object)
   58.92 +{
   58.93 +	g_signal_handlers_destroy (object);
   58.94 +
   58.95 +    G_OBJECT_CLASS (gmyth_query_parent_class)->finalize (object);
   58.96 +}
   58.97 +
   58.98 +/** Creates a new instance of GMythQuery.
   58.99 + * 
  58.100 + * @return a new instance of GMythQuery.
  58.101 + */
  58.102 +GMythQuery*
  58.103 +gmyth_query_new ()
  58.104 +{
  58.105 +    GMythQuery *sql_query = GMYTH_QUERY (g_object_new(GMYTH_QUERY_TYPE, NULL));
  58.106 +
  58.107 +    return sql_query;
  58.108 +}
  58.109 +
  58.110 +/** Connects to the Mysql database in the backend. The backend address
  58.111 + * is loaded from the GMythSettings instance.
  58.112 + * 
  58.113 + * @param gmyth_query the GMythEPG instance to be connected.
  58.114 + * @return true if connection was success, false if failed.
  58.115 + */
  58.116 +gboolean
  58.117 +gmyth_query_connect (GMythQuery *gmyth_query) 
  58.118 +{
  58.119 +    char *opt_host_name;
  58.120 +    char *opt_user_name;
  58.121 +    char *opt_password;
  58.122 +    char *opt_db_name;
  58.123 +
  58.124 +    assert(gmyth_query);
  58.125 +    
  58.126 +    opt_host_name   = (gmyth_query->opt_host_name ? gmyth_query->opt_host_name->str : NULL);
  58.127 +    opt_db_name     = (gmyth_query->opt_db_name ? gmyth_query->opt_db_name->str : NULL);
  58.128 +    opt_user_name   = (gmyth_query->opt_user_name ? gmyth_query->opt_user_name->str : NULL);
  58.129 +    opt_password    = (gmyth_query->opt_password ? gmyth_query->opt_password->str : NULL);
  58.130 +
  58.131 +    
  58.132 +    if (gmyth_query->conn == NULL) {
  58.133 +        gmyth_query_print_error (NULL, "mysql_init() failed (probably out of memory)");
  58.134 +        return FALSE;
  58.135 +    }
  58.136 +    
  58.137 +    /* connect to server */
  58.138 +    if (mysql_real_connect (gmyth_query->conn, opt_host_name, 
  58.139 +            opt_user_name, opt_password, opt_db_name, 
  58.140 +            0, NULL, 0) == NULL) {
  58.141 +            	
  58.142 +        gmyth_query_print_error (gmyth_query->conn, "mysql_real_connect() failed");
  58.143 +		return FALSE;
  58.144 +    }
  58.145 +
  58.146 +    g_debug ("[%s] Connection to Mysql server succeeded!", __FUNCTION__);
  58.147 +    
  58.148 +    return TRUE;
  58.149 +}
  58.150 +
  58.151 +/** Disconnects from the Mysql database in the backend.
  58.152 + * 
  58.153 + * @param gmyth_query the GMythQuery instance to be disconnected
  58.154 + * @return true if disconnection was success, false if failed.
  58.155 + */
  58.156 +gboolean
  58.157 +gmyth_query_disconnect (GMythQuery *gmyth_query) 
  58.158 +{
  58.159 +    assert(gmyth_query);
  58.160 +    
  58.161 +    /* TODO: Check how to return error */
  58.162 +    g_debug ("[%s] Closing gmyth_query->conn", __FUNCTION__);
  58.163 +    mysql_close (gmyth_query->conn);
  58.164 +
  58.165 +	return TRUE;	
  58.166 +}
  58.167 +
  58.168 +static void
  58.169 +gmyth_query_print_error (MYSQL *conn, char *message)
  58.170 +{
  58.171 +    fprintf (stderr, "%s\n", message);
  58.172 +    
  58.173 +    if (conn != NULL) {
  58.174 +#if MYSQL_VERSION_ID >= 40101
  58.175 +        fprintf (stderr, "Error %u (%s): %s\n",
  58.176 +                mysql_errno (conn), mysql_sqlstate(conn), mysql_error (conn));
  58.177 +#else
  58.178 +        fprintf (stderr, "Error %u: %s\n",
  58.179 +               mysql_errno (conn), mysql_error (conn));
  58.180 +#endif
  58.181 +    }
  58.182 +}
  58.183 +
  58.184 +/** Sends the given query to the backend returning the query result as
  58.185 + * MYSQL_RES pointer.
  58.186 + * 
  58.187 + * FIXME: this function is returning NULL whether any error happens
  58.188 + * or no rows are returned (e.g. UPDATE or REPLACE).
  58.189 + * 
  58.190 + * @param gmyth_query the GMythQuery instance.
  58.191 + * @param stmt_str the query text.
  58.192 + * @return the MYSQL_RES result pointer or NULL if any error happens.
  58.193 + */
  58.194 +MYSQL_RES*
  58.195 +gmyth_query_process_statement (GMythQuery *gmyth_query, char *stmt_str)
  58.196 +{
  58.197 +    MYSQL_RES *res_set;
  58.198 +    
  58.199 +    assert(gmyth_query);
  58.200 +    
  58.201 +    g_debug ("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
  58.202 +
  58.203 +    if (gmyth_query == NULL)
  58.204 +    	return NULL;
  58.205 +    
  58.206 +    /* the statement failed */
  58.207 +    if (mysql_query (gmyth_query->conn, stmt_str) != 0) {
  58.208 +        gmyth_query_print_error (gmyth_query->conn, "Could not execute statement");
  58.209 +        return NULL;
  58.210 +    }
  58.211 +
  58.212 +    /* the statement succeeded; determine whether it returned data */
  58.213 +    res_set = mysql_store_result (gmyth_query->conn);
  58.214 +    if (res_set) {
  58.215 +        return res_set;
  58.216 +    } else if (mysql_field_count (gmyth_query->conn) == 0) {
  58.217 +             g_debug ("%lu rows affected\n",
  58.218 +                     (unsigned long) mysql_affected_rows (gmyth_query->conn));
  58.219 +    } else {
  58.220 +            gmyth_query_print_error (gmyth_query->conn, "Could not retrieve result set");
  58.221 +    }
  58.222 +    
  58.223 +    return NULL;
  58.224 +}
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/gmyth/src/libgmyth/gmyth_query.h	Wed Sep 20 23:45:35 2006 +0100
    59.3 @@ -0,0 +1,84 @@
    59.4 +/**
    59.5 + * GMyth Library
    59.6 + *
    59.7 + * @file gmyth/gmyth_query.h
    59.8 + * 
    59.9 + * @brief <p> GMythQuery class provides a wrapper for accessing
   59.10 + * the libmysqlclient funtions.
   59.11 + *
   59.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   59.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   59.14 + *
   59.15 + *//*
   59.16 + * 
   59.17 + * This program is free software; you can redistribute it and/or modify
   59.18 + * it under the terms of the GNU Lesser General Public License as published by
   59.19 + * the Free Software Foundation; either version 2 of the License, or
   59.20 + * (at your option) any later version.
   59.21 + *
   59.22 + * This program is distributed in the hope that it will be useful,
   59.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   59.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   59.25 + * GNU General Public License for more details.
   59.26 + *
   59.27 + * You should have received a copy of the GNU Lesser General Public License
   59.28 + * along with this program; if not, write to the Free Software
   59.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   59.30 + */
   59.31 +
   59.32 +#ifndef __GMYTH_QUERY_H__
   59.33 +#define __GMYTH_QUERY_H__
   59.34 +
   59.35 +#include <glib-object.h>
   59.36 +
   59.37 +/* MYSQL includes */
   59.38 +#include <mysql.h>
   59.39 +
   59.40 +#define G_BEGIN_DECLS
   59.41 +
   59.42 +#define GMYTH_QUERY_TYPE               (gmyth_query_get_type ())
   59.43 +#define GMYTH_QUERY(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE, GMythQuery))
   59.44 +#define GMYTH_QUERY_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE, GMythQueryClass))
   59.45 +#define IS_GMYTH_QUERY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE))
   59.46 +#define IS_GMYTH_QUERY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE))
   59.47 +#define GMYTH_QUERY_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_QUERY_TYPE, GMythQueryClass))
   59.48 +
   59.49 +
   59.50 +typedef struct _GMythQuery         GMythQuery;
   59.51 +typedef struct _GMythQueryClass    GMythQueryClass;
   59.52 +
   59.53 +struct _GMythQueryClass
   59.54 +{
   59.55 +  GObjectClass parent_class;
   59.56 +
   59.57 +  /* callbacks */
   59.58 +  /* no one for now */
   59.59 +};
   59.60 +
   59.61 +struct _GMythQuery
   59.62 +{
   59.63 +    GObject parent;
   59.64 +  
   59.65 +    GString *opt_host_name; /* server host (default=localhost) */
   59.66 +    GString *opt_user_name; /* username (default=login name) */
   59.67 +    GString *opt_password; /* password (default=none) */
   59.68 +    unsigned int opt_port_num; /* port number (use built-in value) */
   59.69 +    GString *opt_socket_name; /* socket name (use built-in value) */
   59.70 +    GString *opt_db_name; /* database name (default=none) */
   59.71 +    unsigned int opt_flags; /* connection flags (none) */
   59.72 +    MYSQL *conn; /* pointer to connection handler */  
   59.73 +};
   59.74 +
   59.75 +
   59.76 +GType gmyth_query_get_type (void);
   59.77 +
   59.78 +GMythQuery* gmyth_query_new ();
   59.79 +MYSQL_RES * gmyth_query_process_statement 
   59.80 +                (GMythQuery *gmyth_query, char *stmt_str);
   59.81 +
   59.82 +gboolean gmyth_query_connect (GMythQuery *gmyth_query);
   59.83 +gboolean gmyth_query_disconnect (GMythQuery *gmyth_query);
   59.84 +
   59.85 +#define G_END_DECLS
   59.86 +
   59.87 +#endif /* __GMYTH_QUERY_H__ */
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/gmyth/src/libgmyth/gmyth_remote_encoder.c	Wed Sep 20 23:45:35 2006 +0100
    60.3 @@ -0,0 +1,207 @@
    60.4 +/**
    60.5 + * GMyth Library
    60.6 + *
    60.7 + * @file gmyth/gmyth_remote_encoder.c
    60.8 + * 
    60.9 + * @brief <p> GMythRemoteEncoder class defines functions for playing live tv.
   60.10 + *
   60.11 + * The remote encoder is used by gmyth_tvplayer to setup livetv. 
   60.12 + *
   60.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   60.14 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   60.15 + *
   60.16 + *//*
   60.17 + * 
   60.18 + * This program is free software; you can redistribute it and/or modify
   60.19 + * it under the terms of the GNU Lesser General Public License as published by
   60.20 + * the Free Software Foundation; either version 2 of the License, or
   60.21 + * (at your option) any later version.
   60.22 + *
   60.23 + * This program is distributed in the hope that it will be useful,
   60.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   60.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   60.26 + * GNU General Public License for more details.
   60.27 + *
   60.28 + * You should have received a copy of the GNU Lesser General Public License
   60.29 + * along with this program; if not, write to the Free Software
   60.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   60.31 + */
   60.32 +
   60.33 +#include "gmyth_remote_encoder.h"
   60.34 +
   60.35 +#include <assert.h>
   60.36 +
   60.37 +#include "gmyth_stringlist.h"
   60.38 +
   60.39 +static void gmyth_remote_encoder_class_init          (GMythRemoteEncoderClass *klass);
   60.40 +static void gmyth_remote_encoder_init                (GMythRemoteEncoder *object);
   60.41 +
   60.42 +static void gmyth_remote_encoder_dispose  (GObject *object);
   60.43 +static void gmyth_remote_encoder_finalize (GObject *object);
   60.44 +
   60.45 +G_DEFINE_TYPE(GMythRemoteEncoder, gmyth_remote_encoder, G_TYPE_OBJECT)
   60.46 +    
   60.47 +static void
   60.48 +gmyth_remote_encoder_class_init (GMythRemoteEncoderClass *klass)
   60.49 +{
   60.50 +    GObjectClass *gobject_class;
   60.51 +
   60.52 +    gobject_class = (GObjectClass *) klass;
   60.53 +	
   60.54 +    gobject_class->dispose  = gmyth_remote_encoder_dispose;
   60.55 +    gobject_class->finalize = gmyth_remote_encoder_finalize;	
   60.56 +}
   60.57 +
   60.58 +static void
   60.59 +gmyth_remote_encoder_init (GMythRemoteEncoder *gmyth_remote_encoder)
   60.60 +{
   60.61 +}
   60.62 +
   60.63 +static void
   60.64 +gmyth_remote_encoder_dispose  (GObject *object)
   60.65 +{
   60.66 +    // GMythRemoteEncoder *gmyth_remote_encoder = GMYTH_REMOTE_ENCODER(object);
   60.67 +    
   60.68 +	G_OBJECT_CLASS (gmyth_remote_encoder_parent_class)->dispose (object);
   60.69 +}
   60.70 +
   60.71 +
   60.72 +static void
   60.73 +gmyth_remote_encoder_finalize (GObject *object)
   60.74 +{
   60.75 +	g_signal_handlers_destroy (object);
   60.76 +
   60.77 +    GMythRemoteEncoder *remote_encoder = GMYTH_REMOTE_ENCODER(object);
   60.78 +
   60.79 +	g_debug ("[%s] Closing control socket", __FUNCTION__);
   60.80 +	gmyth_socket_close_connection(remote_encoder->myth_socket);
   60.81 +	g_object_unref (remote_encoder->myth_socket);
   60.82 +    
   60.83 +    G_OBJECT_CLASS (gmyth_remote_encoder_parent_class)->finalize (object);
   60.84 +}
   60.85 +
   60.86 +/** Creates a new instance of GMythRemoteEncoder.
   60.87 + * 
   60.88 + * @return a new instance of GMythRemoteEncoder.
   60.89 + */
   60.90 +GMythRemoteEncoder*
   60.91 +gmyth_remote_encoder_new (int num, GString *hostname, gshort port)
   60.92 +{
   60.93 +	GMythRemoteEncoder *encoder = GMYTH_REMOTE_ENCODER ( g_object_new (
   60.94 +			GMYTH_REMOTE_ENCODER_TYPE, FALSE ));
   60.95 +			
   60.96 +	encoder->recorder_num = num;
   60.97 +	encoder->hostname = g_string_new (hostname->str);
   60.98 +	encoder->port = port;
   60.99 +	
  60.100 +	return encoder;
  60.101 +}
  60.102 +
  60.103 +/** Configures the remote encoder instance connecting it to Mythtv backend.
  60.104 + * 
  60.105 + * @param remote_encoder the GMythRemoteEncoder instance.
  60.106 + * @return TRUE if successfull, FALSE if any error happens.
  60.107 + */
  60.108 +gboolean
  60.109 +gmyth_remote_encoder_setup (GMythRemoteEncoder *remote_encoder)
  60.110 +{
  60.111 +	assert (remote_encoder);
  60.112 +	g_debug ("[%s] Creating socket and connecting to backend", __FUNCTION__);
  60.113 +
  60.114 +	if (remote_encoder->myth_socket == NULL) { 
  60.115 +		
  60.116 +		remote_encoder->myth_socket = gmyth_socket_new ();
  60.117 +		
  60.118 +		if (!gmyth_socket_connect_to_backend (remote_encoder->myth_socket, remote_encoder->hostname->str, 
  60.119 +					remote_encoder->port, TRUE) ) {
  60.120 +			g_warning ("GMythRemoteEncoder: Connection to backend failed");	
  60.121 +			return FALSE;
  60.122 +		}
  60.123 +
  60.124 +	} else {
  60.125 +		g_warning("Remote encoder socket already created\n");
  60.126 +	}
  60.127 +
  60.128 +	return TRUE;
  60.129 +}
  60.130 +
  60.131 +/** Sends the SPAWN_LIVETV command through Mythtv protocol. This command
  60.132 + * requests the backend to start capturing TV content.
  60.133 + * 
  60.134 + * @param remote_encoder The GMythRemoteEncoder instance.
  60.135 + * @param tvchain_id The tvchain unique id.
  60.136 + * @return true if success, false if any error happens.
  60.137 + */
  60.138 +gboolean
  60.139 +gmyth_remote_encoder_spawntv (GMythRemoteEncoder *remote_encoder, GString *tvchain_id)
  60.140 +{
  60.141 +	GMythStringList *str_list;
  60.142 +	GString *tmp_str;
  60.143 +	
  60.144 +	g_debug ("[%s] Spawntv with tvchain_id = %s", __FUNCTION__, tvchain_id->str);
  60.145 +	
  60.146 +	str_list = gmyth_string_list_new ();
  60.147 +	
  60.148 +	tmp_str = g_string_new ("QUERY_RECORDER ");
  60.149 +	g_string_append_printf (tmp_str, "%d", remote_encoder->recorder_num); 
  60.150 +	
  60.151 +	gmyth_string_list_append_string (str_list, tmp_str);
  60.152 +	gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
  60.153 +	gmyth_string_list_append_string (str_list, tvchain_id);
  60.154 +	gmyth_string_list_append_int (str_list, 0); // PIP = FALSE (0)
  60.155 +
  60.156 +	gmyth_socket_sendreceive_stringlist (remote_encoder->myth_socket, str_list);
  60.157 +	
  60.158 +    g_string_free (tmp_str, TRUE);
  60.159 +    
  60.160 +    tmp_str = gmyth_string_list_get_string (str_list, 0);
  60.161 +    if (tmp_str == NULL) {
  60.162 +    	g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
  60.163 +    	return FALSE;
  60.164 +	}
  60.165 +	
  60.166 +    if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
  60.167 +    	g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
  60.168 +	    g_object_unref (str_list);
  60.169 +    	return FALSE;
  60.170 +    }
  60.171 +
  60.172 +    g_object_unref (str_list);
  60.173 +    return TRUE;
  60.174 +
  60.175 +}
  60.176 +
  60.177 +/** Sends the command STOP_LIVETV to Mythtv backend.
  60.178 + * 
  60.179 + * @param remote_encoder the GMythRemoteEncoder instance.
  60.180 + * @return true if success, false if any error happens.
  60.181 + */
  60.182 +gboolean
  60.183 +gmyth_remote_encoder_stop_livetv (GMythRemoteEncoder *remote_encoder)
  60.184 +{
  60.185 +	GMythStringList *str_list;
  60.186 +	GString *tmp_str;
  60.187 +
  60.188 +	g_debug ("[%s]", __FUNCTION__);
  60.189 +
  60.190 +	str_list = gmyth_string_list_new ();
  60.191 +
  60.192 +	tmp_str = g_string_new ("QUERY_RECORDER ");
  60.193 +	g_string_append_printf (tmp_str, "%d", remote_encoder->recorder_num); 
  60.194 +	gmyth_string_list_append_string (str_list, g_string_new ("STOP_LIVETV"));
  60.195 +
  60.196 +	gmyth_socket_sendreceive_stringlist (remote_encoder->myth_socket, str_list);
  60.197 +
  60.198 +	g_string_free (tmp_str, TRUE);
  60.199 +
  60.200 +	tmp_str = gmyth_string_list_get_string (str_list, 0);
  60.201 +	if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
  60.202 +		g_warning ("[%s] Stop livetv request returned %s", __FUNCTION__, tmp_str->str);
  60.203 +		g_object_unref (str_list);
  60.204 +		return FALSE;
  60.205 +	}
  60.206 +
  60.207 +	g_object_unref (str_list);
  60.208 +	return TRUE;
  60.209 +
  60.210 +}
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/gmyth/src/libgmyth/gmyth_remote_encoder.h	Wed Sep 20 23:45:35 2006 +0100
    61.3 @@ -0,0 +1,89 @@
    61.4 +/**
    61.5 + * GMyth Library
    61.6 + *
    61.7 + * @file gmyth/gmyth_remote_encoder.h
    61.8 + * 
    61.9 + * @brief <p> GMythRemoteEncoder class defines functions for playing live tv.
   61.10 + *
   61.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   61.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   61.13 + *
   61.14 + *//*
   61.15 + * 
   61.16 + * This program is free software; you can redistribute it and/or modify
   61.17 + * it under the terms of the GNU Lesser General Public License as published by
   61.18 + * the Free Software Foundation; either version 2 of the License, or
   61.19 + * (at your option) any later version.
   61.20 + *
   61.21 + * This program is distributed in the hope that it will be useful,
   61.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   61.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   61.24 + * GNU General Public License for more details.
   61.25 + *
   61.26 + * You should have received a copy of the GNU Lesser General Public License
   61.27 + * along with this program; if not, write to the Free Software
   61.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   61.29 + */
   61.30 +
   61.31 +#ifndef __GMYTH_REMOTE_ENCODER_H__
   61.32 +#define __GMYTH_REMOTE_ENCODER_H__
   61.33 +
   61.34 +#include <glib-object.h>
   61.35 +
   61.36 +#include "gmyth_socket.h"
   61.37 +
   61.38 +#include <stdio.h>
   61.39 +#include <stdlib.h>
   61.40 +#include <string.h>
   61.41 +#include <netdb.h>
   61.42 +#include <sys/socket.h>
   61.43 +#include <unistd.h>
   61.44 +
   61.45 +#define G_BEGIN_DECLS
   61.46 +
   61.47 +#define GMYTH_REMOTE_ENCODER_TYPE               (gmyth_remote_encoder_get_type ())
   61.48 +#define GMYTH_REMOTE_ENCODER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoder))
   61.49 +#define GMYTH_REMOTE_ENCODER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoderClass))
   61.50 +#define IS_GMYTH_REMOTE_ENCODER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_REMOTE_ENCODER_TYPE))
   61.51 +#define IS_GMYTH_REMOTE_ENCODER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_REMOTE_ENCODER_TYPE))
   61.52 +#define GMYTH_REMOTE_ENCODER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_REMOTE_ENCODER_TYPE, GMythRemoteEncoderClass))
   61.53 +
   61.54 +
   61.55 +typedef struct _GMythRemoteEncoder         GMythRemoteEncoder;
   61.56 +typedef struct _GMythRemoteEncoderClass    GMythRemoteEncoderClass;
   61.57 +
   61.58 +struct _GMythRemoteEncoderClass
   61.59 +{
   61.60 +  GObjectClass parent_class;
   61.61 +
   61.62 +  /* callbacks */
   61.63 +  /* no one for now */
   61.64 +};
   61.65 +
   61.66 +struct _GMythRemoteEncoder
   61.67 +{
   61.68 +    GObject parent;
   61.69 +
   61.70 +    /* socket descriptor */
   61.71 +    GMythSocket *myth_socket;
   61.72 +    
   61.73 +    int recorder_num;
   61.74 +    GString *hostname;
   61.75 +    int port;
   61.76 +};
   61.77 +
   61.78 +
   61.79 +GType   gmyth_remote_encoder_get_type   (void);
   61.80 +
   61.81 +GMythRemoteEncoder* gmyth_remote_encoder_new    (int num,
   61.82 +                                                 GString *hostname,
   61.83 +                                                 gshort port);
   61.84 +
   61.85 +gboolean gmyth_remote_encoder_setup     (GMythRemoteEncoder *encoder);
   61.86 +gboolean gmyth_remote_encoder_spawntv   (GMythRemoteEncoder *remote_encoder,
   61.87 +                                         GString *tvchain_id);
   61.88 +gboolean gmyth_remote_encoder_stop_livetv (GMythRemoteEncoder *remote_encoder);
   61.89 +
   61.90 +#define G_END_DECLS
   61.91 +
   61.92 +#endif /* __GMYTH_REMOTE_ENCODER_H__ */
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/gmyth/src/libgmyth/gmyth_remote_util.c	Wed Sep 20 23:45:35 2006 +0100
    62.3 @@ -0,0 +1,70 @@
    62.4 +/**
    62.5 + * GMyth Library
    62.6 + *
    62.7 + * @file gmyth/gmyth_remote_util.c
    62.8 + * 
    62.9 + * @brief <p> This component provides utility functions for accessing remote data.
   62.10 + *
   62.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   62.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   62.13 + *
   62.14 + *//*
   62.15 + * 
   62.16 + * This program is free software; you can redistribute it and/or modify
   62.17 + * it under the terms of the GNU Lesser General Public License as published by
   62.18 + * the Free Software Foundation; either version 2 of the License, or
   62.19 + * (at your option) any later version.
   62.20 + *
   62.21 + * This program is distributed in the hope that it will be useful,
   62.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   62.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   62.24 + * GNU General Public License for more details.
   62.25 + *
   62.26 + * You should have received a copy of the GNU Lesser General Public License
   62.27 + * along with this program; if not, write to the Free Software
   62.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   62.29 + */
   62.30 +
   62.31 +#include "gmyth_remote_util.h"
   62.32 + 
   62.33 +#include "gmyth_context.h"
   62.34 +#include "gmyth_remote_encoder.h"
   62.35 +#include "gmyth_stringlist.h"
   62.36 +
   62.37 +/** Requests the Mythtv backend for a free remote recorder.
   62.38 + * 
   62.39 + * @param curr The recorder index, or -1 to consider the first one.
   62.40 + * @return the remote encoder instance available, or NULL if any error happens.
   62.41 + */
   62.42 +GMythRemoteEncoder*
   62.43 +remote_request_next_free_recorder (int curr)
   62.44 +{
   62.45 +	GMythRemoteEncoder *encoder;
   62.46 +	GString *hostname;
   62.47 +	int num, port;
   62.48 +	
   62.49 +	GMythStringList *strlist = gmyth_string_list_new();
   62.50 +	
   62.51 +	g_debug ("[%s] Request next free recorder in the backend", __FUNCTION__);
   62.52 +	
   62.53 +    gmyth_string_list_append_char_array (strlist, "GET_NEXT_FREE_RECORDER");
   62.54 +    gmyth_string_list_append_int (strlist, curr);
   62.55 +
   62.56 +    if (!gmyth_context_send_receive_stringlist(strlist)) {
   62.57 +    	g_warning ("GET_NEXT_FREE_RECORDER request error!\n");
   62.58 +        return NULL;
   62.59 +    }
   62.60 +
   62.61 +    num = gmyth_string_list_get_int (strlist, 0);
   62.62 +    hostname = gmyth_string_list_get_string (strlist, 1);
   62.63 +    port = gmyth_string_list_get_int (strlist, 2);
   62.64 +
   62.65 +	g_debug ("[%s] Free recorder info received: num: %d, hostname: %s, port: %d", 
   62.66 +				__FUNCTION__, num, hostname->str, port);
   62.67 +	
   62.68 +	encoder = gmyth_remote_encoder_new (num, hostname, port);
   62.69 +	
   62.70 +	g_object_unref (strlist);
   62.71 +	
   62.72 +	return encoder;
   62.73 +}
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/gmyth/src/libgmyth/gmyth_remote_util.h	Wed Sep 20 23:45:35 2006 +0100
    63.3 @@ -0,0 +1,35 @@
    63.4 +/**
    63.5 + * GMyth Library
    63.6 + *
    63.7 + * @file gmyth/gmyth_remote_util.h
    63.8 + * 
    63.9 + * @brief <p> This component provides utility functions for accessing remote data.
   63.10 + *
   63.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   63.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   63.13 + *
   63.14 + *//*
   63.15 + * 
   63.16 + * This program is free software; you can redistribute it and/or modify
   63.17 + * it under the terms of the GNU Lesser General Public License as published by
   63.18 + * the Free Software Foundation; either version 2 of the License, or
   63.19 + * (at your option) any later version.
   63.20 + *
   63.21 + * This program is distributed in the hope that it will be useful,
   63.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   63.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   63.24 + * GNU General Public License for more details.
   63.25 + *
   63.26 + * You should have received a copy of the GNU Lesser General Public License
   63.27 + * along with this program; if not, write to the Free Software
   63.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   63.29 + */
   63.30 +
   63.31 +#ifndef __REMOTE_UTIL_H__
   63.32 +#define __REMOTE_UTIL_H__
   63.33 +
   63.34 +#include "gmyth_remote_encoder.h"
   63.35 +
   63.36 +GMythRemoteEncoder* remote_request_next_free_recorder (int curr);
   63.37 +
   63.38 +#endif
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/gmyth/src/libgmyth/gmyth_scheduler.c	Wed Sep 20 23:45:35 2006 +0100
    64.3 @@ -0,0 +1,610 @@
    64.4 +/**
    64.5 + * GMyth Library
    64.6 + *
    64.7 + * @file gmyth/gmyth_scheduler.c
    64.8 + * 
    64.9 + * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
   64.10 + * and modifying the recorded content.
   64.11 + *
   64.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   64.13 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
   64.14 + *
   64.15 + *//*
   64.16 + * 
   64.17 + * This program is free software; you can redistribute it and/or modify
   64.18 + * it under the terms of the GNU Lesser General Public License as published by
   64.19 + * the Free Software Foundation; either version 2 of the License, or
   64.20 + * (at your option) any later version.
   64.21 + *
   64.22 + * This program is distributed in the hope that it will be useful,
   64.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   64.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   64.25 + * GNU General Public License for more details.
   64.26 + *
   64.27 + * You should have received a copy of the GNU Lesser General Public License
   64.28 + * along with this program; if not, write to the Free Software
   64.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   64.30 + */
   64.31 +
   64.32 +#include <assert.h>
   64.33 +
   64.34 +#include "gmyth_scheduler.h"
   64.35 +
   64.36 +#include "gmyth_context.h"
   64.37 +#include "gmyth_util.h"
   64.38 +#include "gmyth_query.h"
   64.39 +
   64.40 +static void gmyth_scheduler_class_init          (GMythSchedulerClass *klass);
   64.41 +static void gmyth_scheduler_init                (GMythScheduler *object);
   64.42 +
   64.43 +static void gmyth_scheduler_dispose  (GObject *object);
   64.44 +static void gmyth_scheduler_finalize (GObject *object);
   64.45 +
   64.46 +static gint get_record_id_from_database (GMythScheduler *scheduler);
   64.47 +static void update_backend (gint record_id);
   64.48 +
   64.49 +G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
   64.50 +    
   64.51 +static void
   64.52 +gmyth_scheduler_class_init (GMythSchedulerClass *klass)
   64.53 +{
   64.54 +	GObjectClass *gobject_class;
   64.55 +
   64.56 +    gobject_class = (GObjectClass *) klass;
   64.57 +
   64.58 +    gobject_class->dispose  = gmyth_scheduler_dispose;
   64.59 +    gobject_class->finalize = gmyth_scheduler_finalize;	
   64.60 +}
   64.61 +
   64.62 +static void
   64.63 +gmyth_scheduler_init (GMythScheduler *sched)
   64.64 +{
   64.65 +	sched->recordid =0;
   64.66 +    sched->type = 0;
   64.67 +    sched->search = 0;
   64.68 +    sched->profile =  g_string_new("");
   64.69 +    
   64.70 +    sched->dupin = 0;
   64.71 +    sched->dupmethod = 0;
   64.72 +    sched->autoexpire = 0;
   64.73 +    sched->autotranscode = 0;
   64.74 +    sched->transcoder = 0;
   64.75 +
   64.76 +    sched->autocommflag = 0;
   64.77 +    sched->autouserjob1 = 0;
   64.78 +    sched->autouserjob2 = 0;
   64.79 +    sched->autouserjob3 = 0;
   64.80 +    sched->autouserjob4 = 0;
   64.81 +    
   64.82 +    sched->startoffset = 0;
   64.83 +    sched->endoffset = 0;
   64.84 +    sched->maxepisodes = 0;
   64.85 +    sched->maxnewest = 0;
   64.86 +
   64.87 +    sched->recpriority = 0;
   64.88 +    sched->recgroup = 0;
   64.89 +    sched->playgroup = 0;
   64.90 +    
   64.91 +    sched->prefinput = 0;
   64.92 +    sched->inactive = 0;
   64.93 +    
   64.94 +    sched->searchType = g_string_new("");
   64.95 +    sched->searchForWhat = g_string_new("");
   64.96 +    
   64.97 +    sched->msqlquery = gmyth_query_new ();
   64.98 +}
   64.99 +
  64.100 +static void
  64.101 +gmyth_scheduler_dispose  (GObject *object)
  64.102 +{
  64.103 +	G_OBJECT_CLASS (gmyth_scheduler_parent_class)->dispose (object);
  64.104 +}
  64.105 +
  64.106 +static void
  64.107 +gmyth_scheduler_finalize (GObject *object)
  64.108 +{
  64.109 +	g_signal_handlers_destroy (object);
  64.110 +
  64.111 +    G_OBJECT_CLASS (gmyth_scheduler_parent_class)->finalize (object);
  64.112 +}
  64.113 +
  64.114 +/** Creates a new instance of GMythScheduler.
  64.115 + * 
  64.116 + * @return a new instance of GMythScheduler.
  64.117 + */
  64.118 +GMythScheduler*
  64.119 +gmyth_scheduler_new ()
  64.120 +{
  64.121 +    GMythScheduler *scheduler = 
  64.122 +        GMYTH_SCHEDULER (g_object_new(GMYTH_SCHEDULER_TYPE, NULL));
  64.123 +    
  64.124 +    return scheduler;
  64.125 +}
  64.126 +
  64.127 +/** Connects to the Mysql database in the backend. The backend address
  64.128 + * is loaded from the GMythSettings instance.
  64.129 + * 
  64.130 + * @param scheduler the GMythScheduler instance to be connected.
  64.131 + * @return true if connection was success, false if failed.
  64.132 + */
  64.133 +gboolean
  64.134 +gmyth_scheduler_connect (GMythScheduler *scheduler)
  64.135 +{
  64.136 +    assert(scheduler);
  64.137 +
  64.138 +    if (scheduler->msqlquery == NULL) {
  64.139 +        g_warning ("[%s] MMythScheduler not initialized", __FUNCTION__);
  64.140 +        return FALSE;
  64.141 +    }
  64.142 +
  64.143 +    if (!gmyth_query_connect(scheduler->msqlquery)) {
  64.144 +    	g_warning ("[%s] Error while connecting to db", __FUNCTION__);
  64.145 +        return FALSE;
  64.146 +    }
  64.147 +
  64.148 +    return TRUE;
  64.149 +}
  64.150 +
  64.151 +/** Disconnects from the Mysql database in the backend.
  64.152 + * 
  64.153 + * @param scheduler the GMythScheduler instance to be disconnected
  64.154 + * @return true if disconnection was success, false if failed.
  64.155 + */
  64.156 +gboolean
  64.157 +gmyth_scheduler_disconnect (GMythScheduler *scheduler)
  64.158 +{
  64.159 +    assert(scheduler);
  64.160 +
  64.161 +    if (scheduler->msqlquery != NULL) {
  64.162 +        g_object_unref (scheduler->msqlquery);
  64.163 +    }
  64.164 +
  64.165 +    return TRUE;
  64.166 +}
  64.167 +
  64.168 +/** Retrieves from the backend Mysql database the list of recording schedules.
  64.169 + * 
  64.170 + * @param scheduler The GMythScheduler instance.
  64.171 + * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
  64.172 + * @return The amount of schedules retrieved from database, or -1 if error.
  64.173 + */
  64.174 +gint
  64.175 +gmyth_scheduler_get_schedule_list ( GMythScheduler *scheduler, GList **schedule_list)
  64.176 +{
  64.177 +	ScheduleInfo *schedule;
  64.178 +	MYSQL_RES *msql_res;
  64.179 +    GString *query_str = g_string_new ("");
  64.180 +    GString *date_time = g_string_new ("");
  64.181 +    
  64.182 +    assert(scheduler);
  64.183 +    
  64.184 +    g_string_printf (query_str, 
  64.185 +    	"SELECT recordid,programid,chanid,starttime,startdate,"
  64.186 +    	"endtime,enddate,title,subtitle,description,category FROM record;");
  64.187 +
  64.188 +	if (scheduler->msqlquery == NULL) {
  64.189 +		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
  64.190 +		return -1;
  64.191 +	}
  64.192 +    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
  64.193 +
  64.194 +    if (msql_res == NULL) {
  64.195 +        g_warning ("DB retrieval of schedule list failed");
  64.196 +        return -1;
  64.197 +    } else {
  64.198 +        MYSQL_ROW row;
  64.199 +        *schedule_list = NULL;
  64.200 +        
  64.201 +        while((row = mysql_fetch_row (msql_res)) != NULL) {
  64.202 +        	schedule = g_new0(ScheduleInfo, 1);
  64.203 +        	
  64.204 +        	schedule->record_id  = atoi (row[0]);
  64.205 +        	schedule->program_id = atoi (row[1]);
  64.206 +            schedule->channel_id = atoi (row[2]);
  64.207 +            
  64.208 +            /* generate a time_t from a time and a date db field */
  64.209 +            g_string_printf (date_time, "%s %s", row[4], row[3]);
  64.210 +            
  64.211 +            schedule->start_time = gmyth_util_string_to_time (date_time);
  64.212 +            
  64.213 +            /* generate a time_t from a time and a date db field */
  64.214 +            g_string_printf (date_time, "%s %s", row[6], row[5]);
  64.215 +            
  64.216 +            schedule->end_time = gmyth_util_string_to_time (date_time);
  64.217 +
  64.218 +            schedule->title = g_string_new (row[7]);
  64.219 +            schedule->subtitle = g_string_new (row[8]);
  64.220 +            schedule->description = g_string_new (row[9]);
  64.221 +            schedule->category = g_string_new (row[10]);
  64.222 +
  64.223 +           (*schedule_list) = g_list_append (*(schedule_list), schedule);
  64.224 +    	}
  64.225 +    }
  64.226 +
  64.227 +    mysql_free_result (msql_res);
  64.228 +    g_string_free(query_str, TRUE);
  64.229 +    g_string_free(date_time, TRUE);
  64.230 +
  64.231 +    return (*schedule_list == NULL) ? 0 : g_list_length (*schedule_list);
  64.232 +}
  64.233 +
  64.234 +/** Retrieves from the backend Mysql database the list of recorded programs.
  64.235 + * 
  64.236 + * @param scheduler The GMythScheduler instance.
  64.237 + * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
  64.238 + * @return The amount of recorded retrieved from database, or -1 if error.
  64.239 + */
  64.240 +gint
  64.241 +gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler, GList **recorded_list)
  64.242 +{
  64.243 +	RecordedInfo *record;
  64.244 +	MYSQL_RES *msql_res;
  64.245 +    GString *query_str = g_string_new ("");
  64.246 +    GString *date_time = g_string_new ("");
  64.247 +	
  64.248 +    assert(scheduler);
  64.249 +    
  64.250 +    g_string_printf (query_str, 
  64.251 +    	"SELECT recordid,programid,chanid,starttime,progstart,"
  64.252 +    	"endtime,progend,title,subtitle,description,category,basename FROM recorded;");
  64.253 +
  64.254 +	if (scheduler->msqlquery == NULL) {
  64.255 +		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
  64.256 +		return -1;
  64.257 +	}
  64.258 +
  64.259 +    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
  64.260 +
  64.261 +    if (msql_res == NULL) {
  64.262 +        g_warning ("DB retrieval of recording list failed");
  64.263 +        return -1;
  64.264 +	} else {
  64.265 +        MYSQL_ROW row;
  64.266 +        *recorded_list = NULL;
  64.267 +        
  64.268 +        while((row = mysql_fetch_row (msql_res))!=NULL){
  64.269 +        	record = g_new0(RecordedInfo, 1);
  64.270 +            
  64.271 +            record->record_id  = atoi (row[0]);
  64.272 +            record->program_id = atoi (row[1]);
  64.273 +            record->channel_id = atoi (row[2]);
  64.274 +            
  64.275 +            /* the db field time already contains the date. therefore
  64.276 +             * we are not using the date field */
  64.277 +            /* generate a time_t from a time and a date db field */
  64.278 +            /* g_string_printf (date_time, "%s %s", row[4], row[3]); */
  64.279 +            g_string_printf (date_time, "%s", row[3]); 
  64.280 +            
  64.281 +            record->start_time = gmyth_util_string_to_time (date_time);
  64.282 +
  64.283 +            /* the db field time already contains the date. therefore
  64.284 +             * we are not using the date field */
  64.285 +            /* generate a time_t from a time and a date db field */
  64.286 +            /* g_string_printf (date_time, "%s %s", row[6], row[5]); */
  64.287 +            g_string_printf (date_time, "%s", row[5]); 
  64.288 +
  64.289 +            record->end_time = gmyth_util_string_to_time (date_time);
  64.290 +	
  64.291 +            record->title = g_string_new (row[7]);
  64.292 +            record->subtitle = g_string_new (row[8]);
  64.293 +            record->description = g_string_new (row[9]);
  64.294 +            record->category = g_string_new (row[10]);
  64.295 +            record->basename = g_string_new (row[11]);
  64.296 +
  64.297 +		    *recorded_list = g_list_append (*recorded_list, record);
  64.298 +    	}
  64.299 +    }
  64.300 +    
  64.301 +    mysql_free_result (msql_res);
  64.302 +    g_string_free(query_str, TRUE);
  64.303 +    g_string_free(date_time, TRUE);
  64.304 +
  64.305 +    return (*recorded_list == NULL) ? 0 : g_list_length (*recorded_list);
  64.306 +}
  64.307 +
  64.308 +/** Requests the Mysql database in the backend to add a new schedule.
  64.309 + * 
  64.310 + * @param scheduler the GMythScheduler instance.
  64.311 + * @param schedule_info the ScheduleInfo with recording schedule information
  64.312 + * to be added. record_id = -1 to add a new schedule, otherwise this
  64.313 + * function will update the schedule in the db
  64.314 + * @return gboolean returns FALSE if some error occurs, TRUE otherwise
  64.315 + */
  64.316 +gboolean
  64.317 +gmyth_scheduler_add_schedule (GMythScheduler *scheduler,
  64.318 +                        	  ScheduleInfo *schedule_info)
  64.319 +{
  64.320 +    struct tm start_tm;
  64.321 +    struct tm end_tm;
  64.322 +
  64.323 +	MYSQL_RES *msql_res;
  64.324 +    GString *query_str = g_string_new ("");
  64.325 +
  64.326 +    assert(scheduler);
  64.327 +    
  64.328 +	if (scheduler->msqlquery == NULL) {
  64.329 +		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
  64.330 +		return 0;
  64.331 +	}
  64.332 +	
  64.333 +	/* manipulating time */
  64.334 + 	if(localtime_r(&schedule_info->start_time, &start_tm) == NULL) {
  64.335 +        g_warning ("localtime_r error in libgmyth scheduler!\n");
  64.336 +        return FALSE;                 
  64.337 +    }
  64.338 +        
  64.339 + 	if(localtime_r(&schedule_info->end_time, &end_tm) == NULL) {
  64.340 +        g_warning ("localtime_r error in libgmyth scheduler!\n");
  64.341 +        return FALSE;
  64.342 +    }	
  64.343 +	
  64.344 +	//TODO: verify if this funtion realy does what it should do!
  64.345 +	g_string_printf (query_str, "REPLACE INTO record "
  64.346 +	    "(recordid, type, chanid, starttime, "
  64.347 +	    "startdate, endtime, enddate, title,"
  64.348 +	    "profile, recpriority, maxnewest, inactive, "
  64.349 +	    "maxepisodes, autoexpire, startoffset, endoffset, "
  64.350 +	    "recgroup, dupmethod, dupin, station, "
  64.351 +	    "autocommflag, findday, findtime, findid, "
  64.352 +	    "search, autotranscode, transcoder, tsdefault, "
  64.353 +	    "autouserjob1, autouserjob2, autouserjob3, autouserjob4) "
  64.354 +	    " values ( %d, 1, %d, \"%02d:%02d:00\","	//recordid, type, chanid, starttime
  64.355 +	    " \"%d-%02d-%02d\", \"%02d:%02d:00\", \"%04d-%02d-%02d\", \"%s\","
  64.356 +        //startdate, endtime, enddate, title
  64.357 +	    "DEFAULT, 0, 0, 0, "	//profile, recpriority, maxnewest, inactive
  64.358 +	    "0, 1, 0, 0, "			//maxepisodes, autoexpire, startoffset, endoffset
  64.359 +	    "DEFAULT, 6, 15, %d, " 	//recgroup, dupmethod, dupin, station
  64.360 +	    "1, %d, \"%02d:%02d:00\", %d, "	//autocommflag, findday, findtime, findid
  64.361 +	    "5, 0, 29, 1, "			//search, autotranscode, transcoder, tsdefault
  64.362 +	    "0, 0, 0, 0 );",		//autouserjob1, autouserjob2, autouserjob3, autouserjob4
  64.363 +	    schedule_info->record_id, schedule_info->channel_id,
  64.364 +        start_tm.tm_hour, start_tm.tm_min,
  64.365 +	    start_tm.tm_year+1900, start_tm.tm_mon+1, 
  64.366 +        start_tm.tm_mday,
  64.367 +        end_tm.tm_hour, end_tm.tm_min,
  64.368 +        end_tm.tm_year+1900, end_tm.tm_mon+1, 
  64.369 +        end_tm.tm_mday, schedule_info->title->str, //title
  64.370 +    	schedule_info->channel_id,//station
  64.371 +    	start_tm.tm_wday+1, //findday
  64.372 +   		start_tm.tm_hour, start_tm.tm_min, //findtime
  64.373 +   		(gint)(schedule_info->start_time/60/60/24 + 719528)//findid
  64.374 +    );
  64.375 +
  64.376 +    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
  64.377 +    
  64.378 +    /* FIXME: currently no way to detect db error in UPDATE, REPLACES!
  64.379 +    if (msql_res == NULL) {
  64.380 +        g_warning ("DB retrieval of recording list failed");
  64.381 +        return -1;
  64.382 +	}*/
  64.383 +    
  64.384 +    /* TODO: verify record_id = -1 semantics */
  64.385 +    if (schedule_info->record_id <= 0)
  64.386 +	    schedule_info->record_id = get_record_id_from_database(scheduler);
  64.387 +    
  64.388 +    /* Notify the backend of changes */
  64.389 +    update_backend(schedule_info->record_id);
  64.390 +    
  64.391 +    /* free allocated memory */
  64.392 +    mysql_free_result (msql_res);
  64.393 +    g_string_free(query_str, TRUE);
  64.394 +    
  64.395 +    return 1;
  64.396 +}
  64.397 +
  64.398 +/** Requests the Mysql database in the backend to remove an existing schedule.
  64.399 + * 
  64.400 + * @param scheduler the GMythScheduler instance.
  64.401 + * @param record_id The schedule's record id to be removed
  64.402 + * @return gboolean TRUE if success, FALSE if error
  64.403 + */
  64.404 +gboolean
  64.405 +gmyth_scheduler_delete_schedule (GMythScheduler *scheduler, gint record_id)
  64.406 +{
  64.407 +
  64.408 +	MYSQL_RES *msql_res;
  64.409 +    GString *query_str = g_string_new ("");
  64.410 +
  64.411 +    assert(scheduler);
  64.412 +    
  64.413 +	if (scheduler->msqlquery == NULL) {
  64.414 +		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
  64.415 +		return FALSE;
  64.416 +	}
  64.417 +
  64.418 +    //========================================
  64.419 +    g_string_printf (query_str, 
  64.420 +    	"DELETE FROM record WHERE recordid=%d", record_id);
  64.421 +
  64.422 +    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
  64.423 +
  64.424 +    if (msql_res == NULL) {
  64.425 +    	g_warning ("[%s] Error while trying to delete a schedule in the database", __FUNCTION__);
  64.426 +    	return FALSE;
  64.427 +    }
  64.428 +
  64.429 +	update_backend(record_id);// Notify the backend of the changes
  64.430 +    
  64.431 +    mysql_free_result (msql_res);
  64.432 +    g_string_free(query_str, TRUE);
  64.433 +
  64.434 +	return TRUE;
  64.435 +}
  64.436 +
  64.437 +/** Requests the Mysql database in the backend to remove an existing recorded item.
  64.438 + * 
  64.439 + * @param scheduler the GMythScheduler instance.
  64.440 + * @param record_id The recorded item id to be removed
  64.441 + * @return gboolean TRUE if success, FALSE if error
  64.442 + */
  64.443 +gboolean
  64.444 +gmyth_scheduler_delete_recorded (GMythScheduler *scheduler, gint record_id)
  64.445 +{
  64.446 +
  64.447 +	MYSQL_RES *msql_res;
  64.448 +    GString *query_str = g_string_new ("");
  64.449 +
  64.450 +    assert(scheduler);
  64.451 +    
  64.452 +	if (scheduler->msqlquery == NULL) {
  64.453 +		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
  64.454 +		return FALSE;
  64.455 +	}
  64.456 +
  64.457 +    //========================================
  64.458 +    g_string_printf (query_str, 
  64.459 +    	"DELETE FROM recorded WHERE recordid=%d", record_id);
  64.460 +
  64.461 +    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
  64.462 +
  64.463 +	update_backend(record_id);// Notify the backend of the changes
  64.464 +    
  64.465 +    mysql_free_result (msql_res);
  64.466 +    g_string_free(query_str, TRUE);
  64.467 +
  64.468 +	return TRUE;
  64.469 +}
  64.470 +
  64.471 +/** Retrieves an existing recorded item information from database. The information
  64.472 + * is used to fill the returned GMythProgramInfo.
  64.473 + * 
  64.474 + * @param scheduler The GMythScheduler instance.
  64.475 + * @param channel The channel associated to the record
  64.476 + * @param starttime The record start time
  64.477 + * @return A GMythProgramInfo struct with the requested record item
  64.478 + * information, or NULL if error.
  64.479 + */
  64.480 +GMythProgramInfo*
  64.481 +gmyth_scheduler_get_recorded (GMythScheduler *scheduler, 
  64.482 +                              GString *channel, time_t starttime)
  64.483 +{
  64.484 +	MYSQL_RES *msql_res;
  64.485 +	GMythProgramInfo *proginfo = NULL;
  64.486 +	GString *query_str = g_string_new("");
  64.487 +	GString *time_str = gmyth_util_time_to_string (starttime);
  64.488 +
  64.489 +    assert(scheduler);
  64.490 +    
  64.491 +	if (scheduler->msqlquery == NULL) {
  64.492 +		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
  64.493 +		return NULL;
  64.494 +	}
  64.495 +
  64.496 +	g_string_printf (query_str, "SELECT recorded.chanid,starttime,endtime,title, "
  64.497 +                  "subtitle,description,channel.channum, "
  64.498 +                  "channel.callsign,channel.name,channel.commfree, "
  64.499 +                  "channel.outputfilters,seriesid,programid,filesize, "
  64.500 +                  "lastmodified,stars,previouslyshown,originalairdate, "
  64.501 +                  "hostname,recordid,transcoder,playgroup, "
  64.502 +                  "recorded.recpriority,progstart,progend,basename,recgroup "
  64.503 +                  "FROM recorded "
  64.504 +                  "LEFT JOIN channel "
  64.505 +                  "ON recorded.chanid = channel.chanid "
  64.506 +                  "WHERE recorded.chanid = \"%s\" "
  64.507 +                  "AND starttime = \"%s\" ;",
  64.508 +                  channel->str, time_str->str);
  64.509 +
  64.510 +    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
  64.511 +
  64.512 +    if (msql_res /*&& query.size() > 0*/) {
  64.513 +    	
  64.514 +    	MYSQL_ROW msql_row = mysql_fetch_row (msql_res);
  64.515 +    	if (msql_row) {
  64.516 +
  64.517 +    		proginfo = g_new0 (GMythProgramInfo, 1);
  64.518 +    	
  64.519 +	        proginfo->chanid = g_string_new (msql_row[0]);
  64.520 +	        proginfo->startts = gmyth_util_string_to_time (g_string_new (msql_row[23]));
  64.521 +	        proginfo->endts = gmyth_util_string_to_time (g_string_new (msql_row[24]));
  64.522 +	        proginfo->recstartts = gmyth_util_string_to_time (g_string_new (msql_row[1]));
  64.523 +	        proginfo->recendts = gmyth_util_string_to_time (g_string_new (msql_row[2]));
  64.524 +	        proginfo->title = g_string_new (msql_row[3]);
  64.525 +	        proginfo->subtitle = g_string_new (msql_row[4]);
  64.526 +	        proginfo->description = g_string_new (msql_row[5]);
  64.527 +	
  64.528 +	        proginfo->chanstr = g_string_new (msql_row[6]);
  64.529 +	        proginfo->chansign = g_string_new (msql_row[7]);
  64.530 +	        proginfo->channame = g_string_new (msql_row[0]);
  64.531 +	        proginfo->chancommfree = atoi (msql_row[9]);
  64.532 +	        proginfo->chanOutputFilters = g_string_new (msql_row[10]);
  64.533 +	        proginfo->seriesid = g_string_new (msql_row[11]);
  64.534 +	        proginfo->programid = g_string_new (msql_row[12]);
  64.535 +	        proginfo->filesize = atoll (msql_row[13]);
  64.536 +	
  64.537 +	        proginfo->lastmodified = gmyth_util_string_to_time (g_string_new (msql_row[14]));
  64.538 +	        
  64.539 +	        proginfo->stars = atof (msql_row[15]);
  64.540 +	        proginfo->repeat = atoi (msql_row[16]);
  64.541 +	        
  64.542 +	        if (msql_row[17] == NULL) {
  64.543 +	            proginfo->originalAirDate = 0;
  64.544 +	            proginfo->hasAirDate = FALSE;
  64.545 +	        } else {
  64.546 +	            proginfo->originalAirDate = gmyth_util_string_to_time (g_string_new (msql_row[17]));
  64.547 +	            proginfo->hasAirDate = TRUE;
  64.548 +	        }
  64.549 +	        
  64.550 +	        proginfo->hostname = g_string_new (msql_row[18]);
  64.551 +	        proginfo->recordid = atoi (msql_row[19]);
  64.552 +	        proginfo->transcoder = atoi (msql_row[20]);
  64.553 +	
  64.554 +	        //proginfo->spread = -1;
  64.555 +			//proginfo->programflags = proginfo->getProgramFlags();
  64.556 +	
  64.557 +	        proginfo->recgroup = g_string_new (msql_row[26]);
  64.558 +	        proginfo->playgroup = g_string_new (msql_row[21]);
  64.559 +	        proginfo->recpriority = atoi (msql_row[22]);
  64.560 +	
  64.561 +	        proginfo->pathname = g_string_new (msql_row[25]);
  64.562 +
  64.563 +	        g_debug ("One program info loaded from mysql database\n");
  64.564 +    	}
  64.565 +    }
  64.566 +
  64.567 +	mysql_free_result (msql_res);
  64.568 +    g_string_free(query_str, TRUE);
  64.569 +    g_string_free(time_str, TRUE);
  64.570 +
  64.571 +    return proginfo;
  64.572 +}
  64.573 +
  64.574 +/** Retrieves the next record id.
  64.575 + * 
  64.576 + * @param scheduler The GMythScheduler instance.
  64.577 + * @return gint record_id if success, -1 otherwise 
  64.578 + */
  64.579 +static gint
  64.580 +get_record_id_from_database (GMythScheduler *scheduler)
  64.581 +{
  64.582 +    gint record_id;
  64.583 +
  64.584 +    assert(scheduler);
  64.585 +    
  64.586 +	if (scheduler->msqlquery == NULL) {
  64.587 +		g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
  64.588 +		return 0;
  64.589 +	}
  64.590 +
  64.591 +    record_id = mysql_insert_id (scheduler->msqlquery->conn);
  64.592 +
  64.593 +	return record_id;
  64.594 +}	
  64.595 +	
  64.596 +/** Notifies the backend of an update in the db.
  64.597 + * 
  64.598 + * @param record_id the id of the modified recording.
  64.599 + */
  64.600 +static void
  64.601 +update_backend(gint record_id)//fixme: put void and discovery record_id inside
  64.602 +{
  64.603 +    GMythStringList *strlist = gmyth_string_list_new ();
  64.604 +    GString *datastr = g_string_new ("RESCHEDULE_RECORDINGS ");
  64.605 +
  64.606 +    g_string_append_printf (datastr, "%d", record_id);
  64.607 +    gmyth_string_list_append_string (strlist, datastr);
  64.608 +
  64.609 +    gmyth_context_send_receive_stringlist (strlist);
  64.610 +    
  64.611 +    g_string_free(datastr, TRUE);
  64.612 +    g_object_unref(strlist);
  64.613 +}
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/gmyth/src/libgmyth/gmyth_scheduler.h	Wed Sep 20 23:45:35 2006 +0100
    65.3 @@ -0,0 +1,156 @@
    65.4 +/**
    65.5 + * GMyth Library
    65.6 + *
    65.7 + * @file gmyth/gmyth_scheduler.h
    65.8 + * 
    65.9 + * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
   65.10 + * and modifying the recorded content.
   65.11 + *
   65.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   65.13 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
   65.14 + *
   65.15 + *//*
   65.16 + * 
   65.17 + * This program is free software; you can redistribute it and/or modify
   65.18 + * it under the terms of the GNU Lesser General Public License as published by
   65.19 + * the Free Software Foundation; either version 2 of the License, or
   65.20 + * (at your option) any later version.
   65.21 + *
   65.22 + * This program is distributed in the hope that it will be useful,
   65.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   65.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   65.25 + * GNU General Public License for more details.
   65.26 + *
   65.27 + * You should have received a copy of the GNU Lesser General Public License
   65.28 + * along with this program; if not, write to the Free Software
   65.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   65.30 + */
   65.31 +
   65.32 +#ifndef __GMYTH_SCHEDULER_H__
   65.33 +#define __GMYTH_SCHEDULER_H__
   65.34 +
   65.35 +#include <glib-object.h>
   65.36 +#include <time.h>
   65.37 +
   65.38 +#include "gmyth_common.h"
   65.39 +#include "gmyth_query.h"
   65.40 +
   65.41 +#define G_BEGIN_DECLS
   65.42 +
   65.43 +#define GMYTH_SCHEDULER_TYPE               (gmyth_scheduler_get_type ())
   65.44 +#define GMYTH_SCHEDULER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE, GMythScheduler))
   65.45 +#define GMYTH_SCHEDULER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
   65.46 +#define IS_GMYTH_SCHEDULER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE))
   65.47 +#define IS_GMYTH_SCHEDULER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE))
   65.48 +#define GMYTH_SCHEDULER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
   65.49 +
   65.50 +
   65.51 +typedef struct _GMythScheduler         GMythScheduler;
   65.52 +typedef struct _GMythSchedulerClass    GMythSchedulerClass;
   65.53 +
   65.54 +struct _GMythSchedulerClass
   65.55 +{
   65.56 +  GObjectClass parent_class;
   65.57 +
   65.58 +  /* callbacks */
   65.59 +  /* no one for now */
   65.60 +};
   65.61 +
   65.62 +struct _GMythScheduler
   65.63 +{
   65.64 +    GObject parent;
   65.65 +
   65.66 +  	unsigned long recordid;
   65.67 +    unsigned long type;
   65.68 +    unsigned long search;
   65.69 +    GString *profile;
   65.70 +    
   65.71 +    long dupin;
   65.72 +    long dupmethod;
   65.73 +    long autoexpire;
   65.74 +    short int autotranscode;
   65.75 +    long transcoder;
   65.76 +    
   65.77 +    short int autocommflag;
   65.78 +    short int autouserjob1;
   65.79 +    short int autouserjob2;
   65.80 +    short int autouserjob3;
   65.81 +    short int autouserjob4;
   65.82 +    
   65.83 +    long startoffset;
   65.84 +    long endoffset;
   65.85 +    long maxepisodes;
   65.86 +    long maxnewest;
   65.87 +    
   65.88 +    long recpriority;
   65.89 +    GString *recgroup;
   65.90 +    GString *playgroup;
   65.91 +    
   65.92 +    long prefinput;
   65.93 +    short int inactive;
   65.94 +    
   65.95 +    GString *searchType;
   65.96 +    GString *searchForWhat;
   65.97 +    
   65.98 +    GMythQuery *msqlquery;
   65.99 +};
  65.100 +
  65.101 +typedef struct {
  65.102 +	gint    record_id;
  65.103 +	gint    program_id;
  65.104 +	gint    channel_id;
  65.105 +	
  65.106 +    time_t start_time;
  65.107 +	time_t end_time;
  65.108 +    
  65.109 +	GString *title;
  65.110 +	GString *subtitle;
  65.111 +	GString *description;
  65.112 +	GString *category;
  65.113 +    
  65.114 +} ScheduleInfo;
  65.115 +
  65.116 +typedef struct {
  65.117 +    gint    record_id;
  65.118 +    gint    program_id;
  65.119 +    gint    channel_id;
  65.120 +
  65.121 +    time_t start_time;
  65.122 +    time_t end_time;
  65.123 +
  65.124 +	GString *title;
  65.125 +	GString *subtitle;
  65.126 +	GString *description;
  65.127 +	GString *category;
  65.128 +    
  65.129 +	GString *basename;
  65.130 +    
  65.131 +} RecordedInfo;
  65.132 +
  65.133 +
  65.134 +GType           gmyth_scheduler_get_type (void);
  65.135 +
  65.136 +GMythScheduler* gmyth_scheduler_new ();
  65.137 +gboolean        gmyth_scheduler_connect      (GMythScheduler *scheduler);
  65.138 +gboolean        gmyth_scheduler_disconnect   (GMythScheduler *scheduler);
  65.139 +
  65.140 +gint            gmyth_scheduler_get_schedule_list (GMythScheduler *scheduler, 
  65.141 +                                                   GList **sched_list);
  65.142 +gint            gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler, 
  65.143 +                                                   GList **rec_list);
  65.144 +
  65.145 +GMythProgramInfo* gmyth_scheduler_get_recorded (GMythScheduler *scheduler, 
  65.146 +                                        		GString *channel, time_t starttime);
  65.147 +
  65.148 +gint            gmyth_scheduler_add_schedule(GMythScheduler *scheduler, 
  65.149 +                                             ScheduleInfo *schedule_info);
  65.150 +
  65.151 +gint            gmyth_scheduler_delete_schedule (GMythScheduler *scheduler, 
  65.152 +                                                 gint record_id);
  65.153 +gint            gmyth_scheduler_delete_recorded (GMythScheduler *scheduler, 
  65.154 +                                                 gint record_id);
  65.155 +
  65.156 +#define G_END_DECLS
  65.157 +
  65.158 +#endif /* __GMYTH_SCHEDULER_H__ */
  65.159 +
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/gmyth/src/libgmyth/gmyth_settings.c	Wed Sep 20 23:45:35 2006 +0100
    66.3 @@ -0,0 +1,417 @@
    66.4 +/**
    66.5 + * GMyth Library
    66.6 + *
    66.7 + * @file gmyth/gmyth_settings.c
    66.8 + * 
    66.9 + * @brief <p> This component contains functions acessing and modifying 
   66.10 + * user and program settings.
   66.11 + * 
   66.12 + * The standard settings file is created in the user home folder, in the
   66.13 + * file ~/.mmyth/settings.dat.  
   66.14 + *
   66.15 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   66.16 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
   66.17 + *
   66.18 + *//*
   66.19 + * 
   66.20 + * This program is free software; you can redistribute it and/or modify
   66.21 + * it under the terms of the GNU Lesser General Public License as published by
   66.22 + * the Free Software Foundation; either version 2 of the License, or
   66.23 + * (at your option) any later version.
   66.24 + *
   66.25 + * This program is distributed in the hope that it will be useful,
   66.26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   66.27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   66.28 + * GNU General Public License for more details.
   66.29 + *
   66.30 + * You should have received a copy of the GNU Lesser General Public License
   66.31 + * along with this program; if not, write to the Free Software
   66.32 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   66.33 + */
   66.34 +
   66.35 +#include "gmyth_settings.h"
   66.36 + 
   66.37 +#include <string.h>
   66.38 +#include <stdlib.h>
   66.39 +#include <unistd.h>
   66.40 +#include <fcntl.h>
   66.41 +
   66.42 +#include <glib.h>
   66.43 +#include <glib/gprintf.h>
   66.44 +#include <glib/gstdio.h>
   66.45 +
   66.46 +#define GMYTH_SETTINGS_FILE_NAME	"settings.dat"
   66.47 +#define GMYTH_SETTINGS_DIR		".mmyth"
   66.48 +
   66.49 +static void gmyth_settings_class_init          (GMythSettingsClass *klass);
   66.50 +static void gmyth_settings_init                (GMythSettings *object);
   66.51 +
   66.52 +static void gmyth_settings_dispose  (GObject *object);
   66.53 +static void gmyth_settings_finalize (GObject *object);
   66.54 +
   66.55 +static void fill_settings_data(GMythSettings *gmyth_settings, char* line);
   66.56 +
   66.57 +G_DEFINE_TYPE(GMythSettings, gmyth_settings, G_TYPE_OBJECT)
   66.58 +
   66.59 +static void
   66.60 +gmyth_settings_class_init (GMythSettingsClass *klass)
   66.61 +{
   66.62 +	GObjectClass *gobject_class;
   66.63 +
   66.64 +    gobject_class = (GObjectClass *) klass;
   66.65 +
   66.66 +    gobject_class->dispose  = gmyth_settings_dispose;
   66.67 +    gobject_class->finalize = gmyth_settings_finalize;	
   66.68 +}
   66.69 +
   66.70 +static void
   66.71 +gmyth_settings_init (GMythSettings *gmyth_settings)
   66.72 +{
   66.73 +
   66.74 +	gmyth_settings->settings_file = NULL;
   66.75 +	
   66.76 +    gmyth_settings->backend_hostname = g_string_new("127.0.0.1");
   66.77 +    gmyth_settings->backend_port = 6543;
   66.78 +    gmyth_settings->mysql_dbname = g_string_new("mythconverg");
   66.79 +	gmyth_settings->mysql_username = g_string_new("mythtv");
   66.80 +    gmyth_settings->mysql_password = g_string_new("mythtv");
   66.81 +    gmyth_settings->database_type = g_string_new("mysql");
   66.82 +    	
   66.83 +}
   66.84 +
   66.85 +
   66.86 +static void
   66.87 +gmyth_settings_dispose  (GObject *object)
   66.88 +{
   66.89 +	GMythSettings *gmyth_settings = GMYTH_SETTINGS(object);
   66.90 +
   66.91 +	if ( gmyth_settings->backend_hostname != NULL )
   66.92 +		g_string_free( gmyth_settings->backend_hostname, TRUE );
   66.93 +	if ( gmyth_settings->mysql_dbname != NULL )
   66.94 +		g_string_free( gmyth_settings->mysql_dbname, TRUE );
   66.95 +	if ( gmyth_settings->mysql_username != NULL )
   66.96 +		g_string_free( gmyth_settings->mysql_username, TRUE );
   66.97 +	if ( gmyth_settings->mysql_password != NULL )
   66.98 +		g_string_free( gmyth_settings->mysql_password, TRUE );
   66.99 +	if ( gmyth_settings->database_type != NULL )
  66.100 +		g_string_free( gmyth_settings->database_type, TRUE );
  66.101 +
  66.102 +	G_OBJECT_CLASS (gmyth_settings_parent_class)->dispose (object);
  66.103 +}
  66.104 +
  66.105 +static void
  66.106 +gmyth_settings_finalize (GObject *object)
  66.107 +{
  66.108 +	g_signal_handlers_destroy (object);
  66.109 +
  66.110 +    G_OBJECT_CLASS (gmyth_settings_parent_class)->finalize (object);
  66.111 +}
  66.112 +
  66.113 +/** Creates a new instance of GMythSettings.
  66.114 + * 
  66.115 + * @return a new instance of GMythSettings.
  66.116 + */
  66.117 +GMythSettings*
  66.118 +gmyth_settings_new ()
  66.119 +{
  66.120 +    GMythSettings *gmyth_settings = GMYTH_SETTINGS (g_object_new(GMYTH_SETTINGS_TYPE, NULL));
  66.121 +
  66.122 +    return gmyth_settings;
  66.123 +}
  66.124 +
  66.125 +static gboolean
  66.126 +gmyth_settings_ensure_dir_exists (const gchar *dir)
  66.127 +{
  66.128 +
  66.129 +	g_debug ("[%s] \tdir = %s\n", __FUNCTION__, dir);
  66.130 +
  66.131 +    if (g_file_test (dir, G_FILE_TEST_IS_DIR) == FALSE) {
  66.132 +	    if (g_file_test (dir, G_FILE_TEST_EXISTS) == TRUE) {
  66.133 +            g_warning ("%s exists, please move it out of the way.", dir);
  66.134 +            return FALSE;
  66.135 +	    }
  66.136 +
  66.137 +        if (mkdir (dir, 488) != 0) {
  66.138 +            g_warning ("Failed to create directory %s.", dir);
  66.139 +            return FALSE;
  66.140 +        }
  66.141 +    }
  66.142 +
  66.143 +    return TRUE;
  66.144 +}
  66.145 +
  66.146 +static gboolean
  66.147 +gmyth_settings_ensure_file_exists (const gchar *file_name) {
  66.148 +
  66.149 +	int file = 0;
  66.150 +	
  66.151 +    if ( g_file_test( file_name, G_FILE_TEST_EXISTS ) == FALSE ) {
  66.152 +        g_debug ( "\n\tCreating %s file...\n", file_name );
  66.153 +        file = creat( file_name, S_IRWXU | S_IRWXO | S_IRWXG );
  66.154 +
  66.155 +		if ( close( file ) == -1 )
  66.156 +			return FALSE;
  66.157 +    }
  66.158 +
  66.159 +	return TRUE;
  66.160 +}
  66.161 +
  66.162 +/** Loads the GMyth settings from the given file.
  66.163 + * 
  66.164 + * @param gmyth_settings the GMythSettings instance.
  66.165 + * @param filename The desired file to be opened.
  66.166 + * @return TRUE if success, FALSE if error.
  66.167 + */
  66.168 +gboolean
  66.169 +gmyth_settings_load_from_file (GMythSettings *gmyth_settings, GString *filename)
  66.170 +{
  66.171 +    FILE *file_desc;
  66.172 +    char line[100];
  66.173 +	
  66.174 +	g_debug ("[%s] Loading GMyth settings file: %s", __FUNCTION__, filename->str);
  66.175 +	
  66.176 +    file_desc = fopen(filename->str, "r");
  66.177 +    if( file_desc == NULL) {
  66.178 +        g_warning ("[%s] Settings file %s could not be opened", __FUNCTION__, filename->str);
  66.179 +        return FALSE;
  66.180 +    }
  66.181 +	
  66.182 +	gmyth_settings->settings_file = g_string_new (filename->str);
  66.183 +	
  66.184 +    while(fgets(line, 100, file_desc)) {
  66.185 +        int i;
  66.186 +
  66.187 +        /* Removes the new line characters from the end of line */
  66.188 +        for ( i = strlen(line)-1; i >= 0; i--) {
  66.189 +            if ( !g_ascii_iscntrl (line[i]) ) {
  66.190 +                line[i+1] = '\0';
  66.191 +                break;
  66.192 +            }
  66.193 +        }
  66.194 +        
  66.195 +        fill_settings_data(gmyth_settings, line);
  66.196 +    }
  66.197 +
  66.198 +    fclose (file_desc);
  66.199 +
  66.200 +    return TRUE;
  66.201 +}
  66.202 +
  66.203 +/** Loads the GMyth settings from the standard settings file
  66.204 + * (~/.mmyth/settings.dat).
  66.205 + * 
  66.206 + * @param gmyth_settings the GMythSettings instance.
  66.207 + * @return TRUE if success, FALSE if error.
  66.208 + */
  66.209 +gboolean
  66.210 +gmyth_settings_load (GMythSettings *gmyth_settings)
  66.211 +{
  66.212 +	GString* file_full_path = g_string_new( g_build_filename( g_get_home_dir(), 
  66.213 +				GMYTH_SETTINGS_DIR, GMYTH_SETTINGS_FILE_NAME, NULL ) );
  66.214 +
  66.215 +	gmyth_settings->settings_file = file_full_path;
  66.216 +		
  66.217 +	gmyth_settings_ensure_dir_exists( g_build_filename( g_get_home_dir(), GMYTH_SETTINGS_DIR, NULL ) );
  66.218 +
  66.219 +	// Verifies if the file already exist
  66.220 +	if ( g_file_test( file_full_path->str, G_FILE_TEST_EXISTS ) == FALSE ) {
  66.221 +		g_debug ("[%s] Settings file does not exist. A new one will be created.\n", __FUNCTION__);
  66.222 +
  66.223 +		if ( gmyth_settings_ensure_file_exists( file_full_path->str ) == FALSE )
  66.224 +			return FALSE;
  66.225 +
  66.226 +		// Creates the file with default values (see _init function)
  66.227 +		return gmyth_settings_save (gmyth_settings);
  66.228 +		
  66.229 +	} else {
  66.230 +		g_debug ("[%s] Opening settings from file %s", __FUNCTION__, file_full_path->str);
  66.231 +		
  66.232 +		return gmyth_settings_load_from_file (gmyth_settings, file_full_path);
  66.233 +	}	
  66.234 +}	
  66.235 +
  66.236 +/** Saves the current gmyth_settings to the settings file related to the
  66.237 + * given instance.
  66.238 + * 
  66.239 + * @param gmyth_settings the GMythSettings instance.
  66.240 + * @return TRUE if success, FALSE if error.
  66.241 + */
  66.242 +gboolean
  66.243 +gmyth_settings_save (GMythSettings *gmyth_settings)
  66.244 +{
  66.245 +    FILE *file_desc;
  66.246 +	
  66.247 +	if (gmyth_settings->settings_file == NULL) {
  66.248 +		g_warning ("[%s] Settings were not loaded from file, could not save!", __FUNCTION__);
  66.249 +	}
  66.250 +	
  66.251 +    file_desc = fopen(gmyth_settings->settings_file->str, "w");
  66.252 +    if( file_desc == NULL) {
  66.253 +        g_warning ("GMYTH_SETTINGS: settings file %s not found", gmyth_settings->settings_file->str);
  66.254 +        return FALSE;
  66.255 +    }
  66.256 +    
  66.257 +	g_fprintf(file_desc, "#Maemo-Myth Settings\n");
  66.258 +
  66.259 +	g_fprintf(file_desc, "#General settings related with mythtv database\n");
  66.260 +	g_fprintf(file_desc, "dbname=%s\n", gmyth_settings->mysql_dbname->str);
  66.261 +	g_fprintf(file_desc, "username=%s\n", gmyth_settings->mysql_username->str);
  66.262 +	g_fprintf(file_desc, "password=%s\n", gmyth_settings->mysql_password->str);
  66.263 +
  66.264 +	g_fprintf(file_desc, "\n#General settings related with mythtv backend\n");
  66.265 +	g_fprintf(file_desc, "hostname=%s\n", gmyth_settings->backend_hostname->str);
  66.266 +	g_fprintf(file_desc, "backend_port=%d\n", gmyth_settings->backend_port);
  66.267 +
  66.268 +    fclose (file_desc);
  66.269 +
  66.270 +	g_debug ("[%s] Settings file saved", __FUNCTION__);
  66.271 +    return TRUE;
  66.272 +}
  66.273 +
  66.274 +/** Gets the backend hostname from the settings.
  66.275 + * 
  66.276 + * @param gmyth_settings the GMythSettings instance.
  66.277 + * @return The loaded backend hostname, or the default value "127.0.0.1" if settings
  66.278 + * file was not opened.
  66.279 + */
  66.280 +GString*
  66.281 +gmyth_settings_get_backend_hostname (GMythSettings *gmyth_settings)
  66.282 +{
  66.283 +	return g_string_new (gmyth_settings->backend_hostname->str);
  66.284 +}
  66.285 +
  66.286 +/** Sets the backend hostname to the settings.
  66.287 + * 
  66.288 + * @param gmyth_settings the GMythSettings instance.
  66.289 + * @param new_hostname The new hostname.
  66.290 + */
  66.291 +void
  66.292 +gmyth_settings_set_backend_hostname (GMythSettings *gmyth_settings, GString *new_hostname)
  66.293 +{
  66.294 +	g_string_assign (gmyth_settings->backend_hostname, new_hostname->str);
  66.295 +}
  66.296 +
  66.297 +/** Gets the user name to connect to backend database.
  66.298 + * 
  66.299 + * @param gmyth_settings the GMythSettings instance.
  66.300 + * @return The loaded user name, or the default value "mythtv" if settings
  66.301 + * file was not opened.
  66.302 + */
  66.303 +GString*
  66.304 +gmyth_settings_get_username (GMythSettings *gmyth_settings)
  66.305 +{
  66.306 +	return g_string_new (gmyth_settings->mysql_username->str);
  66.307 +}
  66.308 +
  66.309 +/** Sets the username to connect to backend database.
  66.310 + * 
  66.311 + * @param gmyth_settings the GMythSettings instance.
  66.312 + * @param new_username The new username.
  66.313 + */
  66.314 +void
  66.315 +gmyth_settings_set_username (GMythSettings *gmyth_settings, GString *new_username)
  66.316 +{
  66.317 +	g_string_assign (gmyth_settings->mysql_username, new_username->str);
  66.318 +}
  66.319 +
  66.320 +/** Gets the database password from the settings file.
  66.321 + * 
  66.322 + * @param gmyth_settings the GMythSettings instance.
  66.323 + * @return The loaded password, or the default value "mythtv" if settings
  66.324 + * file was not opened.
  66.325 + */
  66.326 +GString*
  66.327 +gmyth_settings_get_password (GMythSettings *gmyth_settings)
  66.328 +{
  66.329 +	return g_string_new (gmyth_settings->mysql_password->str);	
  66.330 +}
  66.331 +
  66.332 +/** Sets the database password.
  66.333 + * 
  66.334 + * @param gmyth_settings the GMythSettings instance.
  66.335 + * @param new_password The new password.
  66.336 + */
  66.337 +
  66.338 +void
  66.339 +gmyth_settings_set_password (GMythSettings *gmyth_settings, GString *new_password)
  66.340 +{
  66.341 +	g_string_assign (gmyth_settings->mysql_password, new_password->str);
  66.342 +}
  66.343 +
  66.344 +/** Gets the backend database name from the settings file.
  66.345 + * 
  66.346 + * @param gmyth_settings the GMythSettings instance.
  66.347 + * @return The loaded database name, or the default value "mythconverg" if settings
  66.348 + * file was not opened.
  66.349 + */
  66.350 +GString*
  66.351 +gmyth_settings_get_dbname (GMythSettings *gmyth_settings)
  66.352 +{
  66.353 +	return g_string_new (gmyth_settings->mysql_dbname->str);
  66.354 +}
  66.355 +
  66.356 +/** Sets the Mythtv database name to the settings.
  66.357 + * 
  66.358 + * @param gmyth_settings the GMythSettings instance.
  66.359 + * @param new_dbname The new database name.
  66.360 + */
  66.361 +
  66.362 +void
  66.363 +gmyth_settings_set_dbname (GMythSettings *gmyth_settings, GString *new_dbname)
  66.364 +{
  66.365 +	g_string_assign (gmyth_settings->mysql_dbname, new_dbname->str);
  66.366 +}
  66.367 +
  66.368 +/** Gets the backend port from the settings.
  66.369 + * 
  66.370 + * @param gmyth_settings the GMythSettings instance.
  66.371 + * @return The loaded backend port, or the default value "6543" if settings
  66.372 + * file was not opened.
  66.373 + */
  66.374 +int
  66.375 +gmyth_settings_get_backend_port (GMythSettings *gmyth_settings)
  66.376 +{
  66.377 +	return gmyth_settings->backend_port;
  66.378 +}
  66.379 +
  66.380 +/** Sets the backend port.
  66.381 + * 
  66.382 + * @param gmyth_settings the GMythSettings instance.
  66.383 + * @param new_port The new port.
  66.384 + */
  66.385 +void
  66.386 +gmyth_settings_set_backend_port (GMythSettings *gmyth_settings, gint new_port)
  66.387 +{
  66.388 +	gmyth_settings->backend_port = new_port;
  66.389 +}
  66.390 +
  66.391 +
  66.392 +static void
  66.393 +fill_settings_data(GMythSettings *gmyth_settings, char* line)
  66.394 +{
  66.395 +    gchar** str_splited;
  66.396 +
  66.397 +	GString *gstr_splited;
  66.398 +	gstr_splited = g_string_new("");
  66.399 +	str_splited = g_strsplit (line, "=", -1);
  66.400 +
  66.401 +	if(!(strcmp(str_splited[0], "hostname"))){
  66.402 +		g_string_assign(gstr_splited, str_splited[1]);
  66.403 +		gmyth_settings_set_backend_hostname(gmyth_settings, gstr_splited);
  66.404 +	}
  66.405 +	else if (!(strcmp(str_splited[0], "dbname"))){
  66.406 +		g_string_assign(gstr_splited, str_splited[1]);
  66.407 +		gmyth_settings_set_dbname(gmyth_settings, gstr_splited);	
  66.408 +	}
  66.409 +	else if (!(strcmp(str_splited[0], "username"))){
  66.410 +		g_string_assign(gstr_splited, str_splited[1]);
  66.411 +		gmyth_settings_set_username(gmyth_settings, gstr_splited);
  66.412 +	}	
  66.413 +	else if (!(strcmp(str_splited[0], "password"))){
  66.414 +		g_string_assign(gstr_splited, str_splited[1]);
  66.415 +		gmyth_settings_set_password(gmyth_settings, gstr_splited);
  66.416 +	}
  66.417 +	else if (!(strcmp(str_splited[0], "backend_port"))){
  66.418 +		gmyth_settings_set_backend_port(gmyth_settings, atoi(str_splited[1]));
  66.419 +	}		
  66.420 +}
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/gmyth/src/libgmyth/gmyth_settings.h	Wed Sep 20 23:45:35 2006 +0100
    67.3 @@ -0,0 +1,103 @@
    67.4 +/**
    67.5 + * GMyth Library
    67.6 + *
    67.7 + * @file gmyth/gmyth_settings.h
    67.8 + * 
    67.9 + * @brief <p> This component contains functions acessing and modifying 
   67.10 + * user and program settings.
   67.11 + * 
   67.12 + * The standard settings file is created in the user home folder, in the
   67.13 + * file ~/.mmyth/settings.dat.  
   67.14 + *
   67.15 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   67.16 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
   67.17 + *
   67.18 + *//*
   67.19 + * 
   67.20 + * This program is free software; you can redistribute it and/or modify
   67.21 + * it under the terms of the GNU Lesser General Public License as published by
   67.22 + * the Free Software Foundation; either version 2 of the License, or
   67.23 + * (at your option) any later version.
   67.24 + *
   67.25 + * This program is distributed in the hope that it will be useful,
   67.26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   67.27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   67.28 + * GNU General Public License for more details.
   67.29 + *
   67.30 + * You should have received a copy of the GNU Lesser General Public License
   67.31 + * along with this program; if not, write to the Free Software
   67.32 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   67.33 + */
   67.34 +
   67.35 +#ifndef __GMYTH_SETTINGS_H__
   67.36 +#define __GMYTH_SETTINGS_H__
   67.37 +
   67.38 +#include <glib-object.h>
   67.39 +
   67.40 +//#include <stdio.h>
   67.41 +//#include <stdlib.h>
   67.42 +//#include <string.h>
   67.43 +//#include <netdb.h>
   67.44 +//#include <sys/socket.h>
   67.45 +//#include <unistd.h>
   67.46 +
   67.47 +#define G_BEGIN_DECLS
   67.48 +
   67.49 +#define GMYTH_SETTINGS_TYPE               (gmyth_settings_get_type ())
   67.50 +#define GMYTH_SETTINGS(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SETTINGS_TYPE, GMythSettings))
   67.51 +#define GMYTH_SETTINGS_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SETTINGS_TYPE, GMythSettingsClass))
   67.52 +#define IS_GMYTH_SETTINGS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SETTINGS_TYPE))
   67.53 +#define IS_GMYTH_SETTINGS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SETTINGS_TYPE))
   67.54 +#define GMYTH_SETTINGS_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SETTINGS_TYPE, GMythSettingsClass))
   67.55 +
   67.56 +
   67.57 +typedef struct _GMythSettings         GMythSettings;
   67.58 +typedef struct _GMythSettingsClass    GMythSettingsClass;
   67.59 +
   67.60 +struct _GMythSettingsClass
   67.61 +{
   67.62 +  GObjectClass parent_class;
   67.63 +
   67.64 +  /* callbacks */
   67.65 +  /* no one for now */
   67.66 +};
   67.67 +
   67.68 +struct _GMythSettings
   67.69 +{
   67.70 +    GObject parent;
   67.71 +
   67.72 +	GString *settings_file;
   67.73 +	
   67.74 +    GString *backend_hostname;
   67.75 +    int backend_port;
   67.76 +
   67.77 +    GString *mysql_dbname;
   67.78 +	GString *mysql_username;
   67.79 +    GString *mysql_password;
   67.80 +    // FIXME: Why do we need database_type? Do we intend to support other dbs?
   67.81 +    GString *database_type;
   67.82 +};
   67.83 +
   67.84 +
   67.85 +GType gmyth_settings_get_type (void);
   67.86 +
   67.87 +GMythSettings* gmyth_settings_new ();
   67.88 +gboolean gmyth_settings_load_from_file (GMythSettings *gmyth_settings, GString *filename);
   67.89 +gboolean gmyth_settings_load (GMythSettings *msettings);
   67.90 +gboolean gmyth_settings_save (GMythSettings *gmyth_settings);
   67.91 +
   67.92 +GString* gmyth_settings_get_backend_hostname (GMythSettings *gmyth_settings);
   67.93 +void gmyth_settings_set_backend_hostname (GMythSettings *gmyth_settings, GString *new_hostname);
   67.94 +GString* gmyth_settings_get_username (GMythSettings *gmyth_settings);
   67.95 +void gmyth_settings_set_username (GMythSettings *gmyth_settings, GString *new_username);
   67.96 +GString* gmyth_settings_get_password (GMythSettings *gmyth_settings);
   67.97 +void gmyth_settings_set_password (GMythSettings *gmyth_settings, GString *new_password);
   67.98 +GString* gmyth_settings_get_dbname (GMythSettings *gmyth_settings);
   67.99 +void gmyth_settings_set_dbname (GMythSettings *gmyth_settings, GString *new_dbname);
  67.100 +int gmyth_settings_get_backend_port (GMythSettings *gmyth_settings);
  67.101 +void gmyth_settings_set_backend_port (GMythSettings *gmyth_settings, gint new_port);
  67.102 +
  67.103 +
  67.104 +#define G_END_DECLS
  67.105 +
  67.106 +#endif /* __GMYTH_SETTINGS_H__ */
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/gmyth/src/libgmyth/gmyth_socket.c	Wed Sep 20 23:45:35 2006 +0100
    68.3 @@ -0,0 +1,708 @@
    68.4 +/**
    68.5 + * GMyth Library
    68.6 + *
    68.7 + * @file gmyth/gmyth_socket.c
    68.8 + * 
    68.9 + * @brief <p> MythTV socket implementation, according to the MythTV Project
   68.10 + * (www.mythtv.org). 
   68.11 + * 
   68.12 + * This component provides basic socket functionalities to interact with
   68.13 + * the Mythtv backend.
   68.14 + * <p>
   68.15 + *
   68.16 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   68.17 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br> 
   68.18 + *
   68.19 + *//*
   68.20 + * 
   68.21 + * This program is free software; you can redistribute it and/or modify
   68.22 + * it under the terms of the GNU Lesser General Public License as published by
   68.23 + * the Free Software Foundation; either version 2 of the License, or
   68.24 + * (at your option) any later version.
   68.25 + *
   68.26 + * This program is distributed in the hope that it will be useful,
   68.27 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   68.28 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   68.29 + * GNU General Public License for more details.
   68.30 + *
   68.31 + * You should have received a copy of the GNU Lesser General Public License
   68.32 + * along with this program; if not, write to the Free Software
   68.33 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   68.34 + */
   68.35 +
   68.36 +#include <glib.h> 
   68.37 +#include <glib/gprintf.h>
   68.38 +
   68.39 +#include <arpa/inet.h>
   68.40 +#include <sys/types.h>
   68.41 +#include <sys/socket.h>
   68.42 +#include <netdb.h>
   68.43 +#include <errno.h>
   68.44 +#include <stdlib.h>
   68.45 +
   68.46 +#include "gmyth_socket.h"
   68.47 +#include "gmyth_stringlist.h"
   68.48 +#include "gmyth_context.h"
   68.49 +
   68.50 +#define BUFLEN 				        512
   68.51 +#define MYTH_SEPARATOR 			    "[]:[]"
   68.52 +#define MYTH_PROTOCOL_FIELD_SIZE	8
   68.53 +
   68.54 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
   68.55 +
   68.56 +static void gmyth_socket_class_init          (GMythSocketClass *klass);
   68.57 +static void gmyth_socket_init                (GMythSocket *object);
   68.58 +
   68.59 +static void gmyth_socket_dispose  (GObject *object);
   68.60 +static void gmyth_socket_finalize (GObject *object);
   68.61 +
   68.62 +G_DEFINE_TYPE(GMythSocket, gmyth_socket, G_TYPE_OBJECT)
   68.63 +
   68.64 +static void
   68.65 +gmyth_socket_class_init (GMythSocketClass *klass)
   68.66 +{
   68.67 +    GObjectClass *gobject_class;
   68.68 +
   68.69 +    gobject_class = (GObjectClass *) klass;
   68.70 +
   68.71 +    gobject_class->dispose  = gmyth_socket_dispose;
   68.72 +    gobject_class->finalize = gmyth_socket_finalize;	
   68.73 +}
   68.74 +
   68.75 +static void
   68.76 +gmyth_socket_init (GMythSocket *gmyth_socket)
   68.77 +{
   68.78 +}
   68.79 +
   68.80 +/** Gets the some important address translation info, from the client socket
   68.81 + * that will open a connection.
   68.82 + * 
   68.83 + * @return gint that represents the error number from getaddrinfo(). 
   68.84 + */
   68.85 +static gint
   68.86 +gmyth_socket_toaddrinfo( gchar *addr, gint port, struct addrinfo **addrInfo )
   68.87 +{
   68.88 +    struct addrinfo hints;
   68.89 +    gchar *portStr = g_strnfill( 32, ' ' );
   68.90 +    gint errorn = EADDRNOTAVAIL;
   68.91 +
   68.92 +    memset( &hints, 0, sizeof(hints) );
   68.93 +    hints.ai_family = AF_INET;
   68.94 +    hints.ai_socktype = SOCK_STREAM;
   68.95 +    /* hints.ai_flags = AI_NUMERICHOST; */
   68.96 +    if ( port != -1 )	
   68.97 +		sprintf(portStr, "%d", port);
   68.98 +    else
   68.99 +		portStr = NULL;
  68.100 +
  68.101 +    g_debug( "[%s] Address: %s, port: %s\n", __FUNCTION__, addr, portStr );
  68.102 +    if ( ( errorn = getaddrinfo(addr, portStr, &hints, addrInfo) ) != 0 ) {
  68.103 +		g_printerr( "[%s] Socket ERROR: %s\n", __FUNCTION__, gai_strerror(errorn) );
  68.104 +    }
  68.105 +
  68.106 +    return errorn;
  68.107 +}
  68.108 +
  68.109 +/** This function retrieves the local hostname of the 
  68.110 + * client machine.
  68.111 + *
  68.112 + * @return GString* get local hostname.
  68.113 + */
  68.114 +GString *
  68.115 +gmyth_socket_get_local_hostname( )
  68.116 +{
  68.117 +    GString *str = g_string_new("");
  68.118 +
  68.119 +    gchar *localhostname = g_strnfill( 1024, ' ' );
  68.120 +    gchar *localaddr = g_strdup( "127.0.0.1" );
  68.121 +
  68.122 +    gboolean found_addr = FALSE;
  68.123 +
  68.124 +    struct addrinfo* addr_info_data = NULL, *addr_info0 = NULL;
  68.125 +
  68.126 +    struct sockaddr_in* sa = NULL;
  68.127 +
  68.128 +    g_static_mutex_lock( &mutex );
  68.129 +
  68.130 +    gethostname(localhostname, 1024);
  68.131 +
  68.132 +    gint err = gmyth_socket_toaddrinfo( localhostname, -1,  &addr_info_data );
  68.133 +
  68.134 +    addr_info0 = addr_info_data;
  68.135 +
  68.136 +    while( addr_info0 != NULL && addr_info0->ai_addr != NULL && 
  68.137 +	    ( sa = (struct sockaddr_in*)addr_info0->ai_addr ) != NULL && !found_addr ) {
  68.138 +    	localaddr = inet_ntoa( sa->sin_addr );
  68.139 +	    if ( localaddr != NULL ) 
  68.140 +            g_print( "[%s] localaddr = %s\n", __FUNCTION__, localaddr );
  68.141 +
  68.142 +	    if ( localaddr != NULL && ( g_strrstr( localaddr, "127" ) == NULL ) ) {
  68.143 +    	    g_print( "[%s] Trying the address %s (err = %d).\n", 
  68.144 +                    __FUNCTION__, localaddr, err );
  68.145 +	        g_print( "[%s] Found local address %s!\n", __FUNCTION__, localaddr );
  68.146 +	        str = g_string_assign( str, g_strdup( localaddr ) );
  68.147 +	        found_addr = TRUE;
  68.148 +	        break;
  68.149 +	    }
  68.150 +	    addr_info0 = addr_info0->ai_next;
  68.151 +    };
  68.152 +
  68.153 +    if ( found_addr == FALSE ) {
  68.154 +	    g_warning("[%s] Could not determine the local hostname address. Setting to %s\n",
  68.155 +                    __FUNCTION__, localaddr );
  68.156 +    	if ( localaddr != NULL )
  68.157 +	        str = g_string_assign( str, localaddr );
  68.158 +    	else
  68.159 +	        str = g_string_assign( str, "127.0.0.1" );
  68.160 +    }
  68.161 +
  68.162 +    g_static_mutex_unlock( &mutex );
  68.163 +
  68.164 +    if (localhostname!=NULL)
  68.165 +	g_free( localhostname );
  68.166 +
  68.167 +    return str;
  68.168 +}
  68.169 +
  68.170 +static void
  68.171 +gmyth_socket_dispose  (GObject *object)
  68.172 +{
  68.173 +    GMythSocket *gmyth_socket = GMYTH_SOCKET(object);
  68.174 +
  68.175 +    gmyth_socket_close_connection (gmyth_socket);
  68.176 +    /* disconnect socket */
  68.177 +    G_OBJECT_CLASS (gmyth_socket_parent_class)->dispose (object);
  68.178 +}
  68.179 +
  68.180 +static void
  68.181 +gmyth_socket_finalize (GObject *object)
  68.182 +{
  68.183 +    g_signal_handlers_destroy (object);
  68.184 +
  68.185 +    G_OBJECT_CLASS (gmyth_socket_parent_class)->finalize (object);
  68.186 +}
  68.187 +
  68.188 +/** Creates a new instance of GMythSocket.
  68.189 + * 
  68.190 + * @return a new instance of GMythSocket.
  68.191 + */
  68.192 +GMythSocket*
  68.193 +gmyth_socket_new ()
  68.194 +{
  68.195 +    GMythSocket *gmyth_socket = GMYTH_SOCKET (g_object_new(GMYTH_SOCKET_TYPE, NULL));
  68.196 +
  68.197 +    gmyth_socket->sd_io_ch = NULL;
  68.198 +
  68.199 +    gmyth_socket->hostname = g_strdup("");
  68.200 +
  68.201 +    gmyth_socket->port = 6543;
  68.202 +
  68.203 +    return gmyth_socket;
  68.204 +}
  68.205 +
  68.206 +/** Connects to the backend.
  68.207 + * 
  68.208 + * @param gmyth_socket The GMythSocket instance.
  68.209 + * @param hostname The backend hostname or IP address.
  68.210 + * @param port The backend port.
  68.211 + * @return TRUE if success, FALSE if error.
  68.212 + */
  68.213 +gboolean
  68.214 +gmyth_socket_connect (GMythSocket **gmyth_socket,
  68.215 +	gchar *hostname, gint port)
  68.216 +{
  68.217 +    struct addrinfo *addr_info_data = NULL, *addr_info0 = NULL;
  68.218 +    gint ret_code = -1;
  68.219 +    gint errno;
  68.220 +    gboolean ret = TRUE;
  68.221 +
  68.222 +    if ( hostname == NULL )
  68.223 +		g_printerr ( "[%s] Invalid hostname parameter!\n", __FUNCTION__ );
  68.224 +
  68.225 +    errno = gmyth_socket_toaddrinfo( hostname, port, &addr_info_data );
  68.226 +
  68.227 +    g_return_val_if_fail( addr_info_data != NULL, FALSE );
  68.228 +
  68.229 +    /* store hostname and port number */
  68.230 +    (*gmyth_socket)->hostname = g_strdup( hostname );
  68.231 +    (*gmyth_socket)->port = port;
  68.232 +
  68.233 +    for ( addr_info0 = addr_info_data; addr_info0; addr_info0 = addr_info_data->ai_next ) {
  68.234 +
  68.235 +	struct sockaddr_in *sa = (struct sockaddr_in*)addr_info0->ai_addr;
  68.236 +	/* init socket descriptor */
  68.237 +	(*gmyth_socket)->sd = socket( addr_info0->ai_family, addr_info0->ai_socktype,
  68.238 +				     addr_info0->ai_protocol );
  68.239 +
  68.240 +	if ( (*gmyth_socket)->sd < 0 )
  68.241 +	    continue;
  68.242 +
  68.243 +	g_debug( "[%s] hostname = %s, sock_fd = %d, addr = %s, addr_len = %d, \
  68.244 +		ai_family = %d, ai_protocol = %d\n",
  68.245 +		__FUNCTION__, hostname, (*gmyth_socket)->sd, inet_ntoa( sa->sin_addr ),
  68.246 +		addr_info0->ai_addrlen, addr_info0->ai_family, addr_info0->ai_protocol );
  68.247 +
  68.248 +	if ( ( ret_code = connect( (*gmyth_socket)->sd, (struct sockaddr *)addr_info0->ai_addr,
  68.249 +			addr_info0->ai_addrlen ) ) < 0 )
  68.250 +	{
  68.251 +	    g_printerr( "[%s] Error connecting to backend!\n", __FUNCTION__ );
  68.252 +	    if ( ret_code == ETIMEDOUT )
  68.253 +		g_printerr( "[%s]\tBackend host unreachable!\n", __FUNCTION__ );
  68.254 +
  68.255 +	    g_printerr( "ERROR: %s\n", gai_strerror(ret_code) );
  68.256 +	    continue;
  68.257 +	}
  68.258 +
  68.259 +	/* only will be reached if none of the error above occurred */
  68.260 +	break;
  68.261 +
  68.262 +    }
  68.263 +
  68.264 +    (*gmyth_socket)->sd_io_ch = g_io_channel_unix_new( (*gmyth_socket)->sd );
  68.265 +
  68.266 +    //if (addr_info_data != NULL )
  68.267 +    //freeaddrinfo( addr_info_data );
  68.268 +
  68.269 +    ret = ( ret_code == 0 ) ? TRUE : FALSE ;
  68.270 +
  68.271 +    return ret;
  68.272 +
  68.273 +}
  68.274 +
  68.275 +/** Gets the GIOChannel associated to the given GMythSocket.
  68.276 + * 
  68.277 + * @param gmyth_socket The GMythSocket instance.
  68.278 + */
  68.279 +GIOChannel *
  68.280 +gmyth_socket_get_io_channel( GMythSocket *gmyth_socket )
  68.281 +{
  68.282 +    g_return_val_if_fail( gmyth_socket != NULL, NULL );
  68.283 +
  68.284 +    return gmyth_socket->sd_io_ch;
  68.285 +}
  68.286 +
  68.287 +/** Verifies if the socket is able to read.
  68.288 + * 
  68.289 + * @param gmyth_socket The GMythSocket instance.
  68.290 + * @return TRUE if the socket is able to read, FALSE if not.
  68.291 + */
  68.292 +gboolean
  68.293 +gmyth_socket_is_able_to_read( GMythSocket *gmyth_socket )
  68.294 +{
  68.295 +    gboolean ret = TRUE;
  68.296 +
  68.297 +    /* verify if the input (read) buffer is ready to receive data */
  68.298 +    GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
  68.299 +
  68.300 +    if ( ( io_cond & G_IO_IN ) == 0 ) {
  68.301 +	g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
  68.302 +	ret = FALSE;
  68.303 +    }
  68.304 +
  68.305 +    return ret;
  68.306 +
  68.307 +}
  68.308 +
  68.309 +/** Verifies if the socket is able to write.
  68.310 + * 
  68.311 + * @param gmyth_socket The GMythSocket instance.
  68.312 + * @return TRUE if the socket is able to write, FALSE if not.
  68.313 + */
  68.314 +gboolean
  68.315 +gmyth_socket_is_able_to_write( GMythSocket *gmyth_socket )
  68.316 +{
  68.317 +    gboolean ret = TRUE;
  68.318 +
  68.319 +    /* verify if the input (read) buffer is ready to receive data */
  68.320 +    GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
  68.321 +
  68.322 +    if ( ( ( io_cond & G_IO_OUT ) == 0 ) || ( ( io_cond & G_IO_HUP ) == 0 ) ) {
  68.323 +	g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
  68.324 +	ret = FALSE;
  68.325 +    }
  68.326 +
  68.327 +    return ret;
  68.328 +
  68.329 +}
  68.330 +
  68.331 +/** Sends a command to the backend.
  68.332 + * 
  68.333 + * @param gmyth_socket the GMythSocket instance.
  68.334 + * @param command The string command to be sent.
  68.335 + */
  68.336 +gboolean
  68.337 +gmyth_socket_send_command(GMythSocket *gmyth_socket, GString *command) 
  68.338 +{
  68.339 +    gboolean ret = TRUE;
  68.340 +
  68.341 +    GIOStatus io_status = G_IO_STATUS_NORMAL;
  68.342 +    //GIOCondition io_cond;
  68.343 +    GError* error = NULL;
  68.344 +    gchar *buffer = NULL;
  68.345 +
  68.346 +    gsize bytes_written = 0;
  68.347 +
  68.348 +    if( command == NULL || ( command->len <= 0 ) ) {
  68.349 +		g_warning ("[%s] Invalid NULL command parameter!\n", __FUNCTION__);
  68.350 +		ret = FALSE;
  68.351 +		goto done;
  68.352 +    }
  68.353 +
  68.354 +    g_static_mutex_lock( &mutex );
  68.355 +    g_debug ("[%s] Sending command to backend: %s\n", __FUNCTION__, command->str);
  68.356 +
  68.357 +    /*
  68.358 +       io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
  68.359 +
  68.360 +       if ( ( io_cond & G_IO_IN ) == 0 ) {
  68.361 +       g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
  68.362 +       ret = FALSE;
  68.363 +       goto done;
  68.364 +       }
  68.365 +       */
  68.366 +
  68.367 +    buffer = g_strnfill( BUFLEN, ' ' );
  68.368 +    snprintf( buffer, MYTH_PROTOCOL_FIELD_SIZE+1, "%-8d", command->len);
  68.369 +    g_print( "[%s] buffer = [%s]\n", __FUNCTION__, buffer  );
  68.370 +
  68.371 +    command = g_string_prepend(command, buffer);
  68.372 +
  68.373 +    g_print( "[%s] command = [%s]\n", __FUNCTION__, command->str  );
  68.374 +
  68.375 +    /* write bytes to socket */    
  68.376 +    io_status = g_io_channel_write_chars( gmyth_socket->sd_io_ch, command->str, 
  68.377 +	    command->len, &bytes_written, &error );
  68.378 +
  68.379 +
  68.380 +    if( (io_status == G_IO_STATUS_ERROR) || ( bytes_written <= 0 ) ) {
  68.381 +		g_warning ("[%s] Error while writing to socket", __FUNCTION__);
  68.382 +		ret = FALSE;
  68.383 +    } else if ( bytes_written < command->len ) {
  68.384 +		g_warning ("[%s] Not all data was written socket", __FUNCTION__);
  68.385 +		ret = FALSE;
  68.386 +    }
  68.387 +
  68.388 +    io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
  68.389 +
  68.390 +    if ( ( bytes_written != command->len ) || ( io_status == G_IO_STATUS_ERROR ) )
  68.391 +    {
  68.392 +		g_warning ("[%s] Some problem occurred when sending data to the socket\n", __FUNCTION__);
  68.393 +	
  68.394 +		ret = TRUE;
  68.395 +    }
  68.396 +
  68.397 +    g_static_mutex_unlock( &mutex );
  68.398 +done:
  68.399 +    if ( error != NULL ) {
  68.400 +		g_printerr( "[%s] Error found reading data from IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
  68.401 +		ret = FALSE;
  68.402 +		g_error_free( error );
  68.403 +    }
  68.404 +
  68.405 +    if ( buffer!= NULL )
  68.406 +		g_free( buffer );
  68.407 +
  68.408 +    return ret;
  68.409 +}
  68.410 +
  68.411 +/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
  68.412 + * supported by the backend and send the "ANN" command.
  68.413 + * 
  68.414 + * @param gmyth_socket the GMythSocket instance.
  68.415 + * @param hostname_backend The backend hostname or IP address.
  68.416 + * @param port The backend port to connect.
  68.417 + * @param blocking_client A flag to choose between blocking and non-blocking 
  68.418 + * backend connection.
  68.419 + */
  68.420 +gboolean
  68.421 +gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket, 
  68.422 +	gchar *hostname_backend, int port, gboolean blocking_client)
  68.423 +{
  68.424 +    if (!gmyth_socket_connect (&gmyth_socket, hostname_backend, port)) {
  68.425 +		g_warning ("[%s] Could not open socket to backend machine", __FUNCTION__);
  68.426 +		return FALSE;
  68.427 +    }
  68.428 +
  68.429 +    if (gmyth_socket_check_protocol_version (gmyth_socket)) {
  68.430 +
  68.431 +	GString *result;
  68.432 +	GString *base_str = g_string_new("");
  68.433 +	GString *hostname = NULL;
  68.434 +
  68.435 +	hostname = gmyth_socket_get_local_hostname();
  68.436 +
  68.437 +	g_string_printf(base_str, "ANN %s %s 0", 
  68.438 +		(blocking_client ? "Playback" : "Monitor"),
  68.439 +		hostname->str);
  68.440 +
  68.441 +	g_debug ("[%s] Connection command sent to backend: %s", __FUNCTION__, base_str->str);
  68.442 +
  68.443 +	gmyth_socket_send_command (gmyth_socket, base_str);
  68.444 +	result = gmyth_socket_receive_response(gmyth_socket);
  68.445 +
  68.446 +	if (result != NULL) {
  68.447 +	    g_debug ("[%s] Response received from backend: %s", __FUNCTION__, result->str);
  68.448 +	    g_string_free (result, TRUE);
  68.449 +	}
  68.450 +
  68.451 +	g_string_free (hostname, TRUE);
  68.452 +	g_string_free (base_str, TRUE);
  68.453 +
  68.454 +	return TRUE;
  68.455 +    } else {
  68.456 +		g_warning ("[%s] GMythSocket could not connect to the backend", __FUNCTION__);	
  68.457 +		return FALSE;
  68.458 +	}
  68.459 +
  68.460 +}
  68.461 +
  68.462 +/** Closes the socket connection to the backend.
  68.463 + * 
  68.464 + * @param gmyth_socket The GMythSocket instance.
  68.465 + */
  68.466 +void
  68.467 +gmyth_socket_close_connection (GMythSocket *gmyth_socket)
  68.468 +{
  68.469 +    close (gmyth_socket->sd);	
  68.470 +}
  68.471 +
  68.472 +
  68.473 +/** Try the MythTV version numbers, and get the version returned by
  68.474 + * the possible REJECT message, in order to contruct a new
  68.475 + * MythTV version request.
  68.476 + * 
  68.477 + * @param gmyth_socket The GMythSocket instance.
  68.478 + * @param mythtv_version The Mythtv protocol version to be tested
  68.479 + */
  68.480 +gboolean
  68.481 +gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket, gint mythtv_version)
  68.482 +{
  68.483 +    GString *response;
  68.484 +    GString *payload;
  68.485 +    gchar *new_version = g_strdup("");
  68.486 +    gboolean res = TRUE;
  68.487 +
  68.488 +try_new_version:
  68.489 +    payload = g_string_new ("MYTH_PROTO_VERSION");
  68.490 +    g_string_append_printf( payload, " %d", mythtv_version );
  68.491 +
  68.492 +    gmyth_socket_send_command(gmyth_socket, payload);
  68.493 +    response = gmyth_socket_receive_response(gmyth_socket);
  68.494 +
  68.495 +    if (response == NULL) {
  68.496 +		g_warning ("[%s] Check protocol version error! Not answered!", __FUNCTION__);
  68.497 +		res = FALSE;	
  68.498 +		goto done;
  68.499 +    }
  68.500 +
  68.501 +    res = g_str_has_prefix (response->str, "ACCEPT");
  68.502 +    if (!res) {
  68.503 +		g_warning ("[%s] Protocol version request error: %s", __FUNCTION__, response->str);
  68.504 +	/* get the version number returned by the REJECT message */
  68.505 +	if ( ( res = g_str_has_prefix (response->str, "REJECT") ) == TRUE ) {
  68.506 +	    new_version = g_strrstr( response->str, "]" );
  68.507 +	    if (new_version!=NULL) {
  68.508 +		++new_version; /* skip ']' character */
  68.509 +		if ( new_version != NULL ) {
  68.510 +		    g_print( "[%s] got MythTV version = %s\n", __FUNCTION__, new_version );
  68.511 +		    mythtv_version = g_ascii_strtoull( g_strdup( new_version ), NULL, 10 );
  68.512 +		    /* do reconnection to the socket (socket is closed if the MythTV version was wrong) */
  68.513 +		    gmyth_socket_connect( &gmyth_socket, gmyth_socket->hostname, gmyth_socket->port );
  68.514 +		    /* g_free( new_version ); */
  68.515 +		    goto try_new_version;
  68.516 +		}
  68.517 +	    }
  68.518 +	}
  68.519 +    }
  68.520 +
  68.521 +done:
  68.522 +    if ( payload != NULL )
  68.523 +		g_string_free (payload, TRUE);
  68.524 +    if ( response != NULL )
  68.525 +		g_string_free (response, TRUE);
  68.526 +//   if (new_version!=NULL)
  68.527 +//	g_free( new_version );
  68.528 +
  68.529 +    return res;
  68.530 +}
  68.531 +
  68.532 +/** Verifies if the Mythtv backend supported the GMyth supported version.
  68.533 + * 
  68.534 + * @param gmyth_socket The GMythSocket instance.
  68.535 + * @return TRUE if supports, FALSE if not.
  68.536 + */
  68.537 +gboolean
  68.538 +gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket)
  68.539 +{
  68.540 +    return gmyth_socket_check_protocol_version_number( gmyth_socket, MYTHTV_VERSION_DEFAULT );
  68.541 +}
  68.542 +
  68.543 +/** Receives a backend answer after a gmyth_socket_send_command_call ().
  68.544 + * 
  68.545 + * @param gmyth_socket The GMythSocket instance.
  68.546 + * @return The response received, or NULL if error or nothing was received.
  68.547 + */
  68.548 +GString*
  68.549 +gmyth_socket_receive_response(GMythSocket *gmyth_socket)
  68.550 +{
  68.551 +    GIOStatus io_status = G_IO_STATUS_NORMAL;
  68.552 +    GError* error = NULL;
  68.553 +    gchar *buffer = NULL;
  68.554 +
  68.555 +    GString *str = NULL;
  68.556 +
  68.557 +    gsize bytes_read = 0;
  68.558 +    gint  len = 0;
  68.559 +    GIOCondition io_cond;
  68.560 +
  68.561 +    g_return_val_if_fail( gmyth_socket != NULL, NULL );
  68.562 +
  68.563 +    /* verify if the input (read) buffer is ready to receive data */
  68.564 +
  68.565 +    buffer = g_strnfill( BUFLEN, ' ' );
  68.566 +
  68.567 +    g_static_mutex_lock( &mutex );
  68.568 +
  68.569 +    io_status = g_io_channel_read_chars( gmyth_socket->sd_io_ch, buffer, MYTH_PROTOCOL_FIELD_SIZE, &bytes_read, &error );
  68.570 +
  68.571 +
  68.572 +    /* verify if the input (read) buffer is ready to receive data */
  68.573 +    io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
  68.574 +
  68.575 +    g_print ( "[%s] Bytes read = %d\n", __FUNCTION__, bytes_read );
  68.576 +
  68.577 +    if( (io_status == G_IO_STATUS_ERROR) || (bytes_read <= 0) ) {
  68.578 +		g_warning ("[%s] Error in mythprotocol response from backend\n", __FUNCTION__);
  68.579 +		str = NULL;
  68.580 +		//return NULL;
  68.581 +    } else {
  68.582 +
  68.583 +		io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
  68.584 +		/* verify if the input (read) buffer is ready to receive data */
  68.585 +		io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
  68.586 +	
  68.587 +		if ( ( io_cond & G_IO_IN ) != 0 ) {
  68.588 +	
  68.589 +		    snprintf( buffer, MYTH_PROTOCOL_FIELD_SIZE+1, "%-8s", g_strdup(buffer));
  68.590 +		    g_print( "[%s] buffer = [%s]\n", __FUNCTION__, buffer  );
  68.591 +	
  68.592 +		    /* removes trailing whitespace */
  68.593 +		    buffer = g_strstrip( buffer );
  68.594 +	
  68.595 +		    len = (gint)strtoull ( buffer, NULL, 10 );  
  68.596 +	
  68.597 +		    bytes_read = 0;
  68.598 +		    io_status = g_io_channel_read_chars( gmyth_socket->sd_io_ch, buffer, len, &bytes_read, &error );
  68.599 +		    buffer[bytes_read] = '\0';
  68.600 +		}
  68.601 +    }  
  68.602 +
  68.603 +    g_static_mutex_unlock( &mutex );
  68.604 +
  68.605 +    g_debug ("[%s] Response received from backend: {%s}\n", __FUNCTION__, buffer);
  68.606 +
  68.607 +    if ( ( bytes_read != len ) || ( io_status == G_IO_STATUS_ERROR ) )
  68.608 +		str = NULL;
  68.609 +    else
  68.610 +		str = g_string_new( buffer );
  68.611 +
  68.612 +    if ( buffer != NULL )
  68.613 +		g_free( buffer );
  68.614 +
  68.615 +    if ( error != NULL ) {
  68.616 +		g_printerr( "[%s] Error found receiving response from the IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
  68.617 +		str = NULL;
  68.618 +		g_error_free( error );
  68.619 +    }
  68.620 +
  68.621 +    return str;
  68.622 +}
  68.623 +
  68.624 +/** Format a Mythtv command from the str_list entries and send it to backend.
  68.625 + * 
  68.626 + * @param gmyth_socket The GMythSocket instance.
  68.627 + * @param str_list The string list to form the command
  68.628 + * @return TRUE if command was sent, FALSE if any error happens.
  68.629 + */
  68.630 +gboolean
  68.631 +gmyth_socket_write_stringlist(GMythSocket *gmyth_socket, GMythStringList* str_list)
  68.632 +{
  68.633 +
  68.634 +    GList *tmp_list;
  68.635 +    GPtrArray *ptr_array;
  68.636 +    gchar *str_array;
  68.637 +
  68.638 +    g_static_mutex_lock( &mutex );
  68.639 +
  68.640 +    ptr_array = g_ptr_array_sized_new(g_list_length(str_list->glist));
  68.641 +
  68.642 +    g_print( "[%s] Number of parameters = %d\n", __FUNCTION__, g_list_length(str_list->glist) );    
  68.643 +
  68.644 +    // FIXME: change this implementation!
  68.645 +    tmp_list = str_list->glist;
  68.646 +    for(; tmp_list; tmp_list = tmp_list->next) {
  68.647 +	if ( tmp_list->data != NULL )
  68.648 +	    g_ptr_array_add(ptr_array, ((GString*)tmp_list->data)->str);
  68.649 +    }
  68.650 +    g_ptr_array_add(ptr_array, NULL); // g_str_joinv() needs a NULL terminated string
  68.651 +
  68.652 +    str_array = g_strjoinv (MYTH_SEPARATOR, (gchar **) (ptr_array->pdata));
  68.653 +
  68.654 +    g_static_mutex_unlock( &mutex );
  68.655 +
  68.656 +    // Sends message to backend	
  68.657 +    // TODO: implement looping to send remaining data, and add timeout testing!
  68.658 +    gmyth_socket_send_command(gmyth_socket, g_string_new(str_array));
  68.659 +
  68.660 +    g_free (str_array);
  68.661 +    g_ptr_array_free (ptr_array, TRUE);
  68.662 +
  68.663 +    return TRUE;
  68.664 +}
  68.665 +
  68.666 +/* Receives a backend command response and split it into the given string list.
  68.667 + * 
  68.668 + * @param gmyth_socket The GMythSocket instance.
  68.669 + * @param str_list the string list to be filled.
  68.670 + * @return The number of received strings.
  68.671 + */
  68.672 +gint
  68.673 +gmyth_socket_read_stringlist (GMythSocket *gmyth_socket, GMythStringList* str_list)
  68.674 +{
  68.675 +    GString *response;
  68.676 +    gchar **str_array;
  68.677 +    gint i;
  68.678 +
  68.679 +    response = gmyth_socket_receive_response(gmyth_socket);
  68.680 +    g_static_mutex_lock( &mutex );
  68.681 +
  68.682 +    gmyth_string_list_clear_all (str_list);	
  68.683 +    str_array = g_strsplit (response->str, MYTH_SEPARATOR, -1);
  68.684 +
  68.685 +    for (i=0; i< g_strv_length (str_array); i++) {
  68.686 +	gmyth_string_list_append_string (str_list, g_string_new (str_array[i]));
  68.687 +    }
  68.688 +    g_static_mutex_unlock( &mutex );
  68.689 +
  68.690 +    g_string_free (response, TRUE);
  68.691 +    g_strfreev (str_array);
  68.692 +
  68.693 +    return gmyth_string_list_length (str_list);
  68.694 +}
  68.695 +
  68.696 +/** Formats a Mythtv protocol command based on str_list and sends it to
  68.697 + * the connected backend. The backend response is overwritten into str_list.
  68.698 + *
  68.699 + * @param gmyth_socket The GMythSocket instance.
  68.700 + * @param str_list The string list to be sent, and on which the answer 
  68.701 + * will be written.
  68.702 + * @return TRUE if command was sent and an answer was received, FALSE if any
  68.703 + * error happens.
  68.704 + */
  68.705 +gint
  68.706 +gmyth_socket_sendreceive_stringlist (GMythSocket *gmyth_socket, GMythStringList *str_list)
  68.707 +{
  68.708 +    gmyth_socket_write_stringlist (gmyth_socket, str_list);
  68.709 +
  68.710 +    return gmyth_socket_read_stringlist (gmyth_socket, str_list);
  68.711 +}
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/gmyth/src/libgmyth/gmyth_socket.h	Wed Sep 20 23:45:35 2006 +0100
    69.3 @@ -0,0 +1,116 @@
    69.4 +/**
    69.5 + * GMyth Library
    69.6 + *
    69.7 + * @file gmyth/gmyth_socket.h
    69.8 + * 
    69.9 + * @brief <p> MythTV socket implementation, according to the MythTV Project
   69.10 + * (www.mythtv.org). 
   69.11 + * 
   69.12 + * This component provides basic socket functionalities to interact with
   69.13 + * the Mythtv backend.
   69.14 + * <p>
   69.15 + *
   69.16 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   69.17 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br> 
   69.18 + *
   69.19 + *//*
   69.20 + * 
   69.21 + * This program is free software; you can redistribute it and/or modify
   69.22 + * it under the terms of the GNU Lesser General Public License as published by
   69.23 + * the Free Software Foundation; either version 2 of the License, or
   69.24 + * (at your option) any later version.
   69.25 + *
   69.26 + * This program is distributed in the hope that it will be useful,
   69.27 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   69.28 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   69.29 + * GNU General Public License for more details.
   69.30 + *
   69.31 + * You should have received a copy of the GNU Lesser General Public License
   69.32 + * along with this program; if not, write to the Free Software
   69.33 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   69.34 + */
   69.35 +
   69.36 +#ifndef __GMYTH_SOCKET_H__
   69.37 +#define __GMYTH_SOCKET_H__
   69.38 +
   69.39 +#include <glib-object.h>
   69.40 +
   69.41 +#include <string.h>
   69.42 +#include <netdb.h>
   69.43 +#include <sys/socket.h>
   69.44 +#include <unistd.h>
   69.45 +#include <glib.h>
   69.46 +
   69.47 +#include "gmyth_stringlist.h"
   69.48 +
   69.49 +#define G_BEGIN_DECLS
   69.50 +
   69.51 +#define GMYTH_SOCKET_TYPE               (gmyth_socket_get_type ())
   69.52 +#define GMYTH_SOCKET(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE, GMythSocket))
   69.53 +#define GMYTH_SOCKET_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE, GMythSocketClass))
   69.54 +#define IS_GMYTH_SOCKET(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE))
   69.55 +#define IS_GMYTH_SOCKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE))
   69.56 +#define GMYTH_SOCKET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SOCKET_TYPE, GMythSocketClass))
   69.57 +
   69.58 +
   69.59 +typedef struct _GMythSocket         GMythSocket;
   69.60 +typedef struct _GMythSocketClass    GMythSocketClass;
   69.61 +
   69.62 +struct _GMythSocketClass
   69.63 +{
   69.64 +	GObjectClass parent_class;
   69.65 +
   69.66 +	/* callbacks */
   69.67 +	/* no one for now */
   69.68 +};
   69.69 +
   69.70 +struct _GMythSocket
   69.71 +{
   69.72 +	GObject parent;
   69.73 +
   69.74 +	/* socket descriptor */
   69.75 +	int sd;  
   69.76 +	GIOChannel *sd_io_ch;
   69.77 +
   69.78 +	gchar *hostname;
   69.79 +	gint port;
   69.80 +};
   69.81 +
   69.82 +
   69.83 +GType           gmyth_socket_get_type (void);
   69.84 +
   69.85 +GMythSocket *   gmyth_socket_new ();
   69.86 +
   69.87 +GIOChannel *    gmyth_socket_get_io_channel (GMythSocket *gmyth_socket );
   69.88 +
   69.89 +gboolean        gmyth_socket_is_able_to_read (GMythSocket *gmyth_socket );
   69.90 +gboolean        gmyth_socket_is_able_to_write (GMythSocket *gmyth_socket );
   69.91 +
   69.92 +gboolean        gmyth_socket_send_command (GMythSocket *gmyth_socket, 
   69.93 +                                           GString *command);
   69.94 +GString *       gmyth_socket_receive_response (GMythSocket *gmyth_socket);
   69.95 +int             gmyth_socket_sendreceive_stringlist (GMythSocket * gmyth_socket, 
   69.96 +                                                     GMythStringList *str_list);
   69.97 +
   69.98 +gboolean        gmyth_socket_connect (GMythSocket **gmyth_socket,
   69.99 +                                      gchar *hostname, gint port);
  69.100 +gboolean        gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket, 
  69.101 +                                                 gchar *hostname_backend, int port,
  69.102 +                                          		 gboolean blocking_client);
  69.103 +
  69.104 +GString *       gmyth_socket_get_local_hostname ();
  69.105 +
  69.106 +void            gmyth_socket_close_connection (GMythSocket *gmyth_socket);
  69.107 +
  69.108 +gboolean		gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket);
  69.109 +gboolean		gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket, 
  69.110 +                                                            gint mythtv_version);
  69.111 +
  69.112 +gboolean		gmyth_socket_write_stringlist(GMythSocket *gmyth_socket, 
  69.113 +                                              GMythStringList* str_list);
  69.114 +int			    gmyth_socket_read_stringlist(GMythSocket *gmyth_socket, 
  69.115 +                                             GMythStringList* str_list);
  69.116 +
  69.117 +#define G_END_DECLS
  69.118 +
  69.119 +#endif /* __GMYTH_SOCKET_H__ */
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/gmyth/src/libgmyth/gmyth_stringlist.c	Wed Sep 20 23:45:35 2006 +0100
    70.3 @@ -0,0 +1,272 @@
    70.4 +/**
    70.5 + * GMyth Library
    70.6 + *
    70.7 + * @file gmyth/gmyth_stringlist.c
    70.8 + * 
    70.9 + * @brief <p> This component contains functions for dealing with the stringlist
   70.10 + * format of the mythprotocol.
   70.11 + * 
   70.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   70.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   70.14 + *
   70.15 + *//*
   70.16 + * 
   70.17 + * This program is free software; you can redistribute it and/or modify
   70.18 + * it under the terms of the GNU Lesser General Public License as published by
   70.19 + * the Free Software Foundation; either version 2 of the License, or
   70.20 + * (at your option) any later version.
   70.21 + *
   70.22 + * This program is distributed in the hope that it will be useful,
   70.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   70.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   70.25 + * GNU General Public License for more details.
   70.26 + *
   70.27 + * You should have received a copy of the GNU Lesser General Public License
   70.28 + * along with this program; if not, write to the Free Software
   70.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   70.30 + */
   70.31 +
   70.32 +#include "gmyth_stringlist.h"
   70.33 +
   70.34 +static void gmyth_string_list_class_init          (GMythStringListClass *klass);
   70.35 +static void gmyth_string_list_init                (GMythStringList *object);
   70.36 +
   70.37 +static void gmyth_string_list_dispose  (GObject *object);
   70.38 +static void gmyth_string_list_finalize (GObject *object);
   70.39 +
   70.40 +G_DEFINE_TYPE(GMythStringList, gmyth_string_list, G_TYPE_OBJECT)
   70.41 +    
   70.42 +static void
   70.43 +gmyth_string_list_class_init (GMythStringListClass *klass)
   70.44 +{
   70.45 +	GObjectClass *gobject_class;
   70.46 +
   70.47 +    gobject_class = (GObjectClass *) klass;
   70.48 +	
   70.49 +    gobject_class->dispose  = gmyth_string_list_dispose;
   70.50 +    gobject_class->finalize = gmyth_string_list_finalize;	
   70.51 +}
   70.52 +
   70.53 +static void
   70.54 +gmyth_string_list_init (GMythStringList *gmyth_string_list)
   70.55 +{
   70.56 +	gmyth_string_list->glist = NULL;
   70.57 +}
   70.58 +
   70.59 +static void
   70.60 +gmyth_string_list_dispose  (GObject *object)
   70.61 +{
   70.62 +	GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
   70.63 +
   70.64 +	if (gmyth_string_list->glist)
   70.65 +		gmyth_string_list_clear_all(gmyth_string_list);
   70.66 +
   70.67 +	G_OBJECT_CLASS (gmyth_string_list_parent_class)->dispose (object);
   70.68 +}
   70.69 +
   70.70 +static void
   70.71 +gmyth_string_list_finalize (GObject *object)
   70.72 +{
   70.73 +	//GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
   70.74 +
   70.75 +	g_signal_handlers_destroy (object);
   70.76 +
   70.77 +	G_OBJECT_CLASS (gmyth_string_list_parent_class)->finalize (object);
   70.78 +}
   70.79 +
   70.80 +/** Creates a new instance of GStringList.
   70.81 + * 
   70.82 + * @return a new instance of GStringList.
   70.83 + */
   70.84 +GMythStringList *
   70.85 +gmyth_string_list_new ()
   70.86 +{
   70.87 +    GMythStringList *gmyth_string_list = GMYTH_STRING_LIST (g_object_new(GMYTH_STRING_LIST_TYPE, NULL));
   70.88 +
   70.89 +    return gmyth_string_list;
   70.90 +}
   70.91 +
   70.92 +/** Appends a guint64 to the string list.
   70.93 + * 
   70.94 + * @param strlist The GMythStringList instance.
   70.95 + * @param value The guint64 to be appended.
   70.96 + * 
   70.97 + * @return The appended guint64 converted to a GString object.
   70.98 + */
   70.99 +GString*
  70.100 +gmyth_string_list_append_int ( GMythStringList *strlist, const gint value )
  70.101 +{
  70.102 +	GString *tmp_str = g_string_new ("");
  70.103 +
  70.104 +	g_string_printf (tmp_str, "%d", value);
  70.105 +
  70.106 +	gmyth_string_list_append_string (strlist, tmp_str);
  70.107 +
  70.108 +	return tmp_str;	
  70.109 +}
  70.110 +
  70.111 +/** Appends a guint64 to the string list.
  70.112 + * 
  70.113 + * @param strlist The GMythStringList instance.
  70.114 + * @param value The guint64 to be appended.
  70.115 + * 
  70.116 + * @return The appended guint64 converted to a GString object.
  70.117 + */
  70.118 +GString*
  70.119 +gmyth_string_list_append_uint64 ( GMythStringList *strlist, const guint64 value)
  70.120 +{
  70.121 +	GString *tmp_str = g_string_new ("");	
  70.122 +
  70.123 +	glong l2 = ( (guint64)(value) & 0xffffffffLL );
  70.124 +	glong l1 = ( ((guint64)(value) >> 32 ) & 0xffffffffLL );
  70.125 +  
  70.126 +	/* high order part of guint64 value */
  70.127 +	g_string_printf (tmp_str, "%ld", l1);
  70.128 +	
  70.129 +	g_debug( "[%s] uint64 (high) = %s\n", __FUNCTION__, tmp_str->str );
  70.130 +
  70.131 +	gmyth_string_list_append_string (strlist, tmp_str);
  70.132 +
  70.133 + 	/* low order part of guint64 value */
  70.134 +	g_string_printf (tmp_str, "%ld", l2);	
  70.135 +
  70.136 +	g_debug( "[%s] uint64 (low) = %s\n", __FUNCTION__, tmp_str->str );
  70.137 +
  70.138 +	gmyth_string_list_append_string (strlist, tmp_str);
  70.139 +
  70.140 +	return tmp_str;	
  70.141 +}
  70.142 +
  70.143 +/** Appends a char array to the string list.
  70.144 + * 
  70.145 + * @param strlist The GMythStringList instance.
  70.146 + * @param value The char array to be appended.
  70.147 + * 
  70.148 + * @return The appended char array converted to a GString object.
  70.149 + */
  70.150 +GString*
  70.151 +gmyth_string_list_append_char_array ( GMythStringList *strlist, const gchar* value )
  70.152 +{
  70.153 +	GString *tmp_str = NULL;
  70.154 +	
  70.155 +	g_return_val_if_fail( strlist != NULL, NULL );
  70.156 +	
  70.157 +	tmp_str = g_string_new (value);
  70.158 +
  70.159 +	g_return_val_if_fail( tmp_str != NULL, NULL );
  70.160 +
  70.161 +	gmyth_string_list_append_string (strlist, tmp_str);
  70.162 +
  70.163 +	return tmp_str;		
  70.164 +}
  70.165 +
  70.166 +/** Appends a string to the string list.
  70.167 + * 
  70.168 + * @param strlist The GMythStringList instance.
  70.169 + * @param value The string to be appended.
  70.170 + * 
  70.171 + * @return The appended string itself. 
  70.172 + */
  70.173 +GString*
  70.174 +gmyth_string_list_append_string ( GMythStringList *strlist, GString *value )
  70.175 +{
  70.176 +	g_return_val_if_fail( strlist != NULL, NULL );
  70.177 +
  70.178 +	strlist->glist = g_list_append (strlist->glist, value);
  70.179 +
  70.180 +	return value;
  70.181 +}
  70.182 +
  70.183 +/** Gets an integer value from the string list at the given position.
  70.184 + * 
  70.185 + * @param strlist The GMythStringList instance.
  70.186 + * @param index the integer position in the list, starting with zero.
  70.187 + * @return The integer value.
  70.188 + */
  70.189 +gint
  70.190 +gmyth_string_list_get_int ( GMythStringList *strlist, const gint index )
  70.191 +{
  70.192 +	//TODO: Create static method check_index()
  70.193 +	GString *tmp_str = NULL;
  70.194 +	
  70.195 +	g_return_val_if_fail( strlist != NULL, 0 );
  70.196 +
  70.197 +	tmp_str = (GString *) g_list_nth_data (strlist->glist, index);
  70.198 +
  70.199 +	g_return_val_if_fail( tmp_str != NULL && tmp_str->str != NULL, 0 );
  70.200 +	
  70.201 +	return (int) ( 0x00000000ffffffffL & g_ascii_strtoull ( tmp_str->str, NULL, 0 ) );
  70.202 +}
  70.203 +
  70.204 +/** Gets a guint64 value from the string list at the given position.
  70.205 + * According to the Mythtv protocol, the 64 bits value is formed by
  70.206 + * two strings.
  70.207 + * 
  70.208 + * @param strlist The GMythStringList instance.
  70.209 + * @param index the index of the first string forming the 64 bits value. 
  70.210 + * Index starts with zero.
  70.211 + * @return The guint64 value.
  70.212 + */
  70.213 +guint64
  70.214 +gmyth_string_list_get_uint64 ( GMythStringList *strlist, const gint index )
  70.215 +{
  70.216 +	//TODO: Create static method check_index()
  70.217 +	guint64 ret_value = 0;
  70.218 +
  70.219 +	g_return_val_if_fail( strlist != NULL, 0 );
  70.220 +  
  70.221 +	const GString *tmp_str1 = (GString *) g_list_nth_data (strlist->glist, index);
  70.222 +	const GString *tmp_str2 = (GString *) g_list_nth_data (strlist->glist, index+1);
  70.223 +	
  70.224 +	glong l1 = (glong)g_ascii_strtoull (tmp_str1->str, NULL, 10);
  70.225 +	glong l2 = (glong)g_ascii_strtoull (tmp_str2->str, NULL, 10);
  70.226 +	
  70.227 +	ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
  70.228 +  
  70.229 +	g_debug( "[%s] returning uint64 value = %llu\n", __FUNCTION__, ret_value );	
  70.230 +	
  70.231 +	return ret_value;
  70.232 +}
  70.233 +
  70.234 +/** Gets a string from the string list at the given position.
  70.235 + * 
  70.236 + * @param strlist The GMythStringList instance.
  70.237 + * @param index the string position in the list, starting with zero.
  70.238 + * @return A pointer to the string data.
  70.239 + */
  70.240 +GString*
  70.241 +gmyth_string_list_get_string ( GMythStringList *strlist, const gint index )
  70.242 +{
  70.243 +	if (!strlist || !(strlist->glist)) {
  70.244 +		g_warning ("%s received Null arguments", __FUNCTION__);
  70.245 +		return NULL;
  70.246 +	}
  70.247 +
  70.248 +	return (GString *) g_list_nth_data (strlist->glist, index);
  70.249 +}
  70.250 +
  70.251 +/** Removes all strings from the string list.
  70.252 + * 
  70.253 + * @param strlist The GMythStringList instance.
  70.254 + */
  70.255 +void
  70.256 +gmyth_string_list_clear_all ( GMythStringList *strlist )
  70.257 +{
  70.258 +	if ( strlist != NULL && strlist->glist ) {
  70.259 +		g_list_free (strlist->glist);
  70.260 +		strlist->glist = NULL;
  70.261 +	}
  70.262 +}
  70.263 +
  70.264 +/** Retrieves the number of elements in the string list.
  70.265 + * 
  70.266 + * @param strlist The GMythStringList instance.
  70.267 + * @return the string list length.
  70.268 + */
  70.269 +gint
  70.270 +gmyth_string_list_length ( GMythStringList *strlist )
  70.271 +{
  70.272 +	g_return_val_if_fail( strlist != NULL && strlist->glist != NULL, 0 );
  70.273 +
  70.274 +	return g_list_length (strlist->glist);
  70.275 +}
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/gmyth/src/libgmyth/gmyth_stringlist.h	Wed Sep 20 23:45:35 2006 +0100
    71.3 @@ -0,0 +1,97 @@
    71.4 +/**
    71.5 + * GMyth Library
    71.6 + *
    71.7 + * @file gmyth/gmyth_stringlist.h
    71.8 + * 
    71.9 + * @brief <p> This component contains functions for dealing with the stringlist
   71.10 + * format of the mythprotocol.
   71.11 + * 
   71.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   71.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   71.14 + *
   71.15 + *//*
   71.16 + * 
   71.17 + * This program is free software; you can redistribute it and/or modify
   71.18 + * it under the terms of the GNU Lesser General Public License as published by
   71.19 + * the Free Software Foundation; either version 2 of the License, or
   71.20 + * (at your option) any later version.
   71.21 + *
   71.22 + * This program is distributed in the hope that it will be useful,
   71.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   71.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   71.25 + * GNU General Public License for more details.
   71.26 + *
   71.27 + * You should have received a copy of the GNU Lesser General Public License
   71.28 + * along with this program; if not, write to the Free Software
   71.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   71.30 + */
   71.31 +
   71.32 +#ifndef GMYTH_STRING_LIST_H_
   71.33 +#define GMYTH_STRING_LIST_H_
   71.34 +
   71.35 +#include <glib-object.h>
   71.36 +
   71.37 +#include <stdio.h>
   71.38 +#include <stdlib.h>
   71.39 +#include <string.h>
   71.40 +#include <netdb.h>
   71.41 +#include <sys/socket.h>
   71.42 +#include <unistd.h>
   71.43 +
   71.44 +#define G_BEGIN_DECLS
   71.45 +
   71.46 +#define GMYTH_STRING_LIST_TYPE               (gmyth_string_list_get_type ())
   71.47 +#define GMYTH_STRING_LIST(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE, GMythStringList))
   71.48 +#define GMYTH_STRING_LIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
   71.49 +#define IS_GMYTH_STRING_LIST(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE))
   71.50 +#define IS_GMYTH_STRING_LIST_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE))
   71.51 +#define GMYTH_STRING_LIST_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
   71.52 +
   71.53 +
   71.54 +typedef struct _GMythStringList         GMythStringList;
   71.55 +typedef struct _GMythStringListClass    GMythStringListClass;
   71.56 +
   71.57 +struct _GMythStringListClass
   71.58 +{
   71.59 +  GObjectClass parent_class;
   71.60 +
   71.61 +  /* callbacks */
   71.62 +  /* no one for now */
   71.63 +};
   71.64 +
   71.65 +struct _GMythStringList
   71.66 +{
   71.67 +    GObject parent;
   71.68 +
   71.69 +    /* string list */
   71.70 +    GList *glist;  
   71.71 +};
   71.72 +
   71.73 +
   71.74 +GType               gmyth_string_list_get_type (void);
   71.75 +
   71.76 +GMythStringList *   gmyth_string_list_new ();
   71.77 +
   71.78 +void                gmyth_string_list_clear_all (GMythStringList *strlist);
   71.79 +int                 gmyth_string_list_length (GMythStringList *strlist);
   71.80 +
   71.81 +GString *           gmyth_string_list_append_int (GMythStringList *strlist, 
   71.82 +                                                  const gint value);
   71.83 +GString *           gmyth_string_list_append_uint64 (GMythStringList *strlist, 
   71.84 +                                                     const guint64 value);
   71.85 +
   71.86 +GString *           gmyth_string_list_append_char_array (GMythStringList *strlist, 
   71.87 +                                                         const char* value);
   71.88 +GString *           gmyth_string_list_append_string (GMythStringList *strlist, 
   71.89 +                                                     GString *value);
   71.90 +
   71.91 +int                 gmyth_string_list_get_int (GMythStringList *strlist, const gint index);
   71.92 +guint64             gmyth_string_list_get_uint64 (GMythStringList *strlist, const gint index);
   71.93 +GString *           gmyth_string_list_get_string (GMythStringList *strlist, const gint index);
   71.94 +
   71.95 +#define gmyth_string_list_get_char_array(strlist, index) \
   71.96 +            (gmyth_string_list_get_string(strlist, index))->str
   71.97 +
   71.98 +#define G_END_DECLS
   71.99 +
  71.100 +#endif /*GMYTH_STRING_LIST_H_*/
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/gmyth/src/libgmyth/gmyth_tvchain.c	Wed Sep 20 23:45:35 2006 +0100
    72.3 @@ -0,0 +1,324 @@
    72.4 +/**
    72.5 + * GMyth Library
    72.6 + *
    72.7 + * @file gmyth/gmyth_tvchain.c
    72.8 + * 
    72.9 + * @brief <p> This component contains functions for creating and accessing
   72.10 + * the tvchain functions for live tv playback.
   72.11 + * 
   72.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   72.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   72.14 + *
   72.15 + *//*
   72.16 + * 
   72.17 + * This program is free software; you can redistribute it and/or modify
   72.18 + * it under the terms of the GNU Lesser General Public License as published by
   72.19 + * the Free Software Foundation; either version 2 of the License, or
   72.20 + * (at your option) any later version.
   72.21 + *
   72.22 + * This program is distributed in the hope that it will be useful,
   72.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   72.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   72.25 + * GNU General Public License for more details.
   72.26 + *
   72.27 + * You should have received a copy of the GNU Lesser General Public License
   72.28 + * along with this program; if not, write to the Free Software
   72.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   72.30 + */
   72.31 +
   72.32 +#include <glib.h>
   72.33 +#include <time.h>
   72.34 +#include <stdio.h>
   72.35 +#include <stdlib.h>
   72.36 +
   72.37 +#include "gmyth_epg.h"
   72.38 +#include "gmyth_tvchain.h"
   72.39 +#include "gmyth_util.h"
   72.40 +#include "gmyth_query.h"
   72.41 +#include "gmyth_scheduler.h"
   72.42 +
   72.43 +static void gmyth_tvchain_class_init          (GMythTVChainClass *klass);
   72.44 +static void gmyth_tvchain_init                (GMythTVChain *object);
   72.45 +
   72.46 +static void gmyth_tvchain_dispose  (GObject *object);
   72.47 +static void gmyth_tvchain_finalize (GObject *object);
   72.48 +
   72.49 +G_DEFINE_TYPE(GMythTVChain, gmyth_tvchain, G_TYPE_OBJECT)
   72.50 +
   72.51 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
   72.52 +
   72.53 +static void
   72.54 +gmyth_tvchain_class_init (GMythTVChainClass *klass)
   72.55 +{
   72.56 +	GObjectClass *gobject_class;
   72.57 +
   72.58 +	gobject_class = (GObjectClass *) klass;
   72.59 +
   72.60 +	gobject_class->dispose  = gmyth_tvchain_dispose;
   72.61 +	gobject_class->finalize = gmyth_tvchain_finalize;	
   72.62 +}
   72.63 +
   72.64 +static void
   72.65 +gmyth_tvchain_init (GMythTVChain *tvchain)
   72.66 +{
   72.67 +	tvchain->tvchain_id = NULL;
   72.68 +
   72.69 +	tvchain->cur_chanid = g_string_new ("");
   72.70 +	tvchain->cur_startts = 0;
   72.71 +}
   72.72 +
   72.73 +static void
   72.74 +gmyth_tvchain_dispose  (GObject *object)
   72.75 +{
   72.76 +    //GMythTVChain *tvchain = GMYTH_TVCHAIN(object);
   72.77 +    
   72.78 +	G_OBJECT_CLASS (gmyth_tvchain_parent_class)->dispose (object);
   72.79 +}
   72.80 +
   72.81 +static void
   72.82 +gmyth_tvchain_finalize (GObject *object)
   72.83 +{
   72.84 +	g_signal_handlers_destroy (object);
   72.85 +
   72.86 +	G_OBJECT_CLASS (gmyth_tvchain_parent_class)->finalize (object);
   72.87 +}
   72.88 +
   72.89 +/** Initializes the tvchain and generates the tvchain id.
   72.90 + * 
   72.91 + * @param tvchain The GMythTVChain instance.
   72.92 + * @param hostname The local hostname used to generate the tvchain id.
   72.93 + */
   72.94 +void
   72.95 +gmyth_tvchain_initialize (GMythTVChain *tvchain, GString *hostname)
   72.96 +{
   72.97 +	if (tvchain->tvchain_id == NULL) {
   72.98 +		GString *isodate;
   72.99 +		time_t cur_time;
  72.100 +
  72.101 +		time(&cur_time);
  72.102 +		isodate = gmyth_util_time_to_isoformat (cur_time);
  72.103 +
  72.104 +		tvchain->tvchain_id = g_string_sized_new(7 + hostname->len + isodate->len);
  72.105 +		g_string_printf(tvchain->tvchain_id, 
  72.106 +				"live-%s-%s", hostname->str, isodate->str);
  72.107 +
  72.108 +		g_print("tv_chain_id: %s\n", tvchain->tvchain_id->str);
  72.109 +
  72.110 +		g_string_free(isodate, TRUE);
  72.111 +
  72.112 +	} else {
  72.113 +		g_warning ("[%s] TVchain already initialized", __FUNCTION__);
  72.114 +	}
  72.115 +}
  72.116 +
  72.117 +/** Gets the tvchain id.
  72.118 + * 
  72.119 + * @param tvchain The GMythTVChain instance.
  72.120 + * @return The tvchain id.
  72.121 + */
  72.122 +GString*
  72.123 +gmyth_tvchain_get_id (GMythTVChain *tvchain)
  72.124 +{
  72.125 +	return g_string_new (tvchain->tvchain_id->str);
  72.126 +}
  72.127 +
  72.128 +/** Reloads all tvchain entries in the database.
  72.129 + * 
  72.130 + * @param tvchain The GMythTVChain instance.
  72.131 + * @return  TRUE if success, or FALSE if error.
  72.132 + */
  72.133 +gboolean
  72.134 +gmyth_tvchain_reload_all (GMythTVChain *tvchain)
  72.135 +{
  72.136 +	MYSQL_ROW msql_row;
  72.137 +	MYSQL_RES *msql_res;
  72.138 +	GMythQuery *gmyth_query;
  72.139 +
  72.140 +	GString *stmt_str;
  72.141 +
  72.142 +	g_static_mutex_lock( &mutex );
  72.143 +
  72.144 +	guint prev_size = g_list_length (tvchain->tvchain_list);
  72.145 +
  72.146 +	g_debug ("[%s] chainid: %s", __FUNCTION__, tvchain->tvchain_id->str);
  72.147 +
  72.148 +	g_list_free (tvchain->tvchain_list);
  72.149 +	tvchain->tvchain_list = NULL;
  72.150 +
  72.151 +	// TODO: Reuse gmyth_query already connected from context
  72.152 +	gmyth_query = gmyth_query_new ();
  72.153 +	if (!gmyth_query_connect (gmyth_query)) {
  72.154 +		g_warning ("[%s] Could not connect to db", __FUNCTION__);
  72.155 +		g_static_mutex_unlock( &mutex );
  72.156 +
  72.157 +		return FALSE;	
  72.158 +	}
  72.159 +
  72.160 +	stmt_str = g_string_new ("");
  72.161 +	g_string_printf (stmt_str, 
  72.162 +			"SELECT chanid, starttime, endtime, discontinuity, "
  72.163 +			"chainpos, hostprefix, cardtype, channame, input "
  72.164 +			"FROM tvchain "
  72.165 +			"WHERE chainid = \"%s\" ORDER BY chainpos;",
  72.166 +			tvchain->tvchain_id->str);
  72.167 +
  72.168 +	msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
  72.169 +	if (msql_res != NULL) {
  72.170 +
  72.171 +		while ((msql_row = mysql_fetch_row (msql_res)) != NULL) {
  72.172 +			struct LiveTVChainEntry *entry = g_new0 (struct LiveTVChainEntry, 1);
  72.173 +			entry->chanid = g_string_new (msql_row[0]);
  72.174 +			entry->starttime = gmyth_util_string_to_time (g_string_new ((gchar*)msql_row[1]));
  72.175 +			entry->endtime = gmyth_util_string_to_time (g_string_new (msql_row[2]));
  72.176 +			entry->discontinuity = atoi (msql_row[3]) != 0;
  72.177 +			entry->hostprefix = g_string_new (msql_row[5]);
  72.178 +			entry->cardtype = g_string_new (msql_row[6]);
  72.179 +			entry->channum = g_string_new (msql_row[7]);
  72.180 +			entry->inputname = g_string_new (msql_row[8]);
  72.181 +
  72.182 +			//m_maxpos = query.value(4).toInt() + 1;
  72.183 +
  72.184 +			tvchain->tvchain_list = g_list_append (tvchain->tvchain_list, entry);			
  72.185 +		}
  72.186 +	} else {
  72.187 +		g_warning ("gmyth_tvchain_reload_all query error!\n");
  72.188 +		g_static_mutex_unlock( &mutex );
  72.189 +
  72.190 +		return FALSE;
  72.191 +	}
  72.192 +
  72.193 +	g_static_mutex_unlock( &mutex );
  72.194 +	
  72.195 +	tvchain->cur_pos = gmyth_tvchain_program_is_at (tvchain, tvchain->cur_chanid, tvchain->cur_startts);
  72.196 +
  72.197 +	if (tvchain->cur_pos < 0)
  72.198 +		tvchain->cur_pos = 0;
  72.199 +
  72.200 +	//    if (m_switchid >= 0)
  72.201 +	//        m_switchid = ProgramIsAt(m_switchentry.chanid,m_switchentry.starttime);
  72.202 +
  72.203 +	if (prev_size != g_list_length (tvchain->tvchain_list)) {
  72.204 +		g_debug ("[%s] Added new recording", __FUNCTION__);
  72.205 +	}	
  72.206 +
  72.207 +	g_string_free (stmt_str, TRUE);
  72.208 +
  72.209 +	mysql_free_result (msql_res);
  72.210 +
  72.211 +	g_object_unref (gmyth_query);
  72.212 +
  72.213 +	return TRUE;
  72.214 +}
  72.215 +
  72.216 +/** Returns the internal index for the TV chain related to the given
  72.217 + * channel and start time.
  72.218 + * 
  72.219 + * @param tvchain The GMythTVChain instance.
  72.220 + * @param chanid The channel id.
  72.221 + * @param startts The program start time.
  72.222 + */
  72.223 +int
  72.224 +gmyth_tvchain_program_is_at (GMythTVChain *tvchain, GString *chanid, time_t startts)
  72.225 +{
  72.226 +	int count = 0;
  72.227 +	struct LiveTVChainEntry *entry;
  72.228 +	GList *tmp_list = tvchain->tvchain_list;
  72.229 +
  72.230 +	g_static_mutex_lock( &mutex );
  72.231 +	
  72.232 +	for (; tmp_list; tmp_list = tvchain->tvchain_list->next, ++count)
  72.233 +	{
  72.234 +		entry = (struct LiveTVChainEntry*) tmp_list->data;
  72.235 +		if (!g_strncasecmp (entry->chanid->str, chanid->str, chanid->len)
  72.236 +				&& entry->starttime == startts)
  72.237 +		{
  72.238 +			g_static_mutex_unlock( &mutex );
  72.239 +			return count;
  72.240 +		}
  72.241 +	}
  72.242 +	g_static_mutex_unlock( &mutex );
  72.243 +
  72.244 +	return -1;	
  72.245 +}
  72.246 +
  72.247 +/** Get the program info associated to the tvchain.
  72.248 + * 
  72.249 + * @param tvchain The GMythTVChain instance.
  72.250 + * @param index The tvchain index.
  72.251 + * @return The program info structure.
  72.252 + */
  72.253 +GMythProgramInfo*
  72.254 +gmyth_tvchain_get_program_at (GMythTVChain *tvchain, int index)
  72.255 +{
  72.256 +	struct LiveTVChainEntry *entry;
  72.257 +
  72.258 +	entry = gmyth_tvchain_get_entry_at (tvchain, index);
  72.259 +
  72.260 +	if (entry)
  72.261 +		return gmyth_tvchain_entry_to_program (tvchain, entry);	
  72.262 +
  72.263 +	return NULL;
  72.264 +}
  72.265 +
  72.266 +/** Gets a LiveTVChainEntry associated to the tvchain by its index.
  72.267 + * 
  72.268 + * @param tvchain The GMythTVChain instance.
  72.269 + * @param index The tvchain entry index
  72.270 + * @return The LiveTVchainEntry structure.
  72.271 + */
  72.272 +struct LiveTVChainEntry*
  72.273 +gmyth_tvchain_get_entry_at (GMythTVChain *tvchain, int index)
  72.274 +{
  72.275 +	struct LiveTVChainEntry* chain_entry = NULL;
  72.276 +	
  72.277 +	g_static_mutex_lock( &mutex );
  72.278 +	
  72.279 +	int size = g_list_length (tvchain->tvchain_list);
  72.280 +	int new_index = (index < 0 || index >= size) ? size - 1 : index;
  72.281 +
  72.282 +	if (new_index >= 0) 
  72.283 +		chain_entry = (struct LiveTVChainEntry*) g_list_nth_data (tvchain->tvchain_list, new_index);
  72.284 +
  72.285 +	g_static_mutex_unlock( &mutex );
  72.286 +	
  72.287 +	if ( chain_entry != NULL ) {
  72.288 +		g_debug ("[%s] Got TV Chain entry at %d.\n", __FUNCTION__, new_index );
  72.289 +
  72.290 +	} else {
  72.291 +		g_warning ("[%s] failed to get entry at index %d", __FUNCTION__, index);
  72.292 +	}
  72.293 +
  72.294 +	return chain_entry;
  72.295 +}
  72.296 +
  72.297 +/** Gets the program info from backend database associated to the tv chain entry.
  72.298 + * 
  72.299 + * @param tvchain The GMythTVChain instance.
  72.300 + * @param entry the LiveTVChainEntry to be converted.
  72.301 + * @return The progrma info.
  72.302 + */
  72.303 +GMythProgramInfo*
  72.304 +gmyth_tvchain_entry_to_program (GMythTVChain *tvchain, struct LiveTVChainEntry *entry)
  72.305 +{
  72.306 +	GMythProgramInfo *proginfo = NULL;
  72.307 +
  72.308 +	if (!entry || !tvchain) {
  72.309 +		g_warning ("gmyth_tvchain_entry_to_program() received NULL argument");
  72.310 +		return NULL;
  72.311 +	}
  72.312 +
  72.313 +	GMythScheduler *scheduler = gmyth_scheduler_new ();
  72.314 +
  72.315 +	gmyth_scheduler_connect( scheduler );
  72.316 +	proginfo = gmyth_scheduler_get_recorded (scheduler, 
  72.317 +			entry->chanid, entry->starttime);
  72.318 +	gmyth_scheduler_disconnect( scheduler );
  72.319 +
  72.320 +	if (proginfo) {
  72.321 +		proginfo->pathname = g_string_prepend (proginfo->pathname, entry->hostprefix->str);
  72.322 +	} else {
  72.323 +		g_warning ("tvchain_entry_to_program(%s, %ld) failed!", entry->chanid->str, entry->starttime);
  72.324 +	}
  72.325 +
  72.326 +	return proginfo;
  72.327 +}
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/gmyth/src/libgmyth/gmyth_tvchain.h	Wed Sep 20 23:45:35 2006 +0100
    73.3 @@ -0,0 +1,105 @@
    73.4 +/**
    73.5 + * GMyth Library
    73.6 + *
    73.7 + * @file gmyth/gmyth_tvchain.h
    73.8 + * 
    73.9 + * @brief <p> This component contains functions for creating and accessing
   73.10 + * the tvchain functions for live tv playback.
   73.11 + * 
   73.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   73.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   73.14 + *
   73.15 + *//*
   73.16 + * 
   73.17 + * This program is free software; you can redistribute it and/or modify
   73.18 + * it under the terms of the GNU Lesser General Public License as published by
   73.19 + * the Free Software Foundation; either version 2 of the License, or
   73.20 + * (at your option) any later version.
   73.21 + *
   73.22 + * This program is distributed in the hope that it will be useful,
   73.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   73.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   73.25 + * GNU General Public License for more details.
   73.26 + *
   73.27 + * You should have received a copy of the GNU Lesser General Public License
   73.28 + * along with this program; if not, write to the Free Software
   73.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   73.30 + */
   73.31 +
   73.32 +#ifndef LIVETVCHAIN_H_
   73.33 +#define LIVETVCHAIN_H_
   73.34 +
   73.35 +#include <glib-object.h>
   73.36 +#include <time.h>
   73.37 +
   73.38 +#include "gmyth_common.h"
   73.39 +
   73.40 +#define G_BEGIN_DECLS
   73.41 +
   73.42 +#define GMYTH_TVCHAIN_TYPE               (gmyth_tvchain_get_type ())
   73.43 +#define GMYTH_TVCHAIN(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChain))
   73.44 +#define GMYTH_TVCHAIN_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
   73.45 +#define IS_GMYTH_TVCHAIN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE))
   73.46 +#define IS_GMYTH_TVCHAIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE))
   73.47 +#define GMYTH_TVCHAIN_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
   73.48 +
   73.49 +
   73.50 +typedef struct _GMythTVChain         GMythTVChain;
   73.51 +typedef struct _GMythTVChainClass    GMythTVChainClass;
   73.52 +
   73.53 +
   73.54 +struct LiveTVChainEntry
   73.55 +{
   73.56 +    GString *chanid;
   73.57 +
   73.58 +    time_t starttime;
   73.59 +    time_t endtime;
   73.60 +    
   73.61 +    gboolean discontinuity; // if true, can't play smooth from last entry
   73.62 +    GString *hostprefix;
   73.63 +    GString *cardtype;
   73.64 +    GString *channum;
   73.65 +    GString *inputname;
   73.66 +};
   73.67 +
   73.68 +
   73.69 +struct _GMythTVChainClass
   73.70 +{
   73.71 +    GObjectClass parent_class;
   73.72 +
   73.73 +    /* callbacks */
   73.74 +    /* no one for now */
   73.75 +};
   73.76 +
   73.77 +struct _GMythTVChain
   73.78 +{
   73.79 +    GObject parent;
   73.80 +
   73.81 +	GString *tvchain_id;
   73.82 +	GList   *tvchain_list;
   73.83 +	
   73.84 +	time_t  cur_startts;
   73.85 +	GString *cur_chanid;
   73.86 +	int     cur_pos;
   73.87 +};
   73.88 +
   73.89 +
   73.90 +GType       gmyth_tvchain_get_type (void);
   73.91 +
   73.92 +void        gmyth_tvchain_initialize    (GMythTVChain *tvchain, 
   73.93 +                                         GString *hostname);
   73.94 +gboolean    gmyth_tvchain_reload_all    (GMythTVChain *tvchain);
   73.95 +GString*    gmyth_tvchain_get_id        (GMythTVChain *tvchain);
   73.96 +int         gmyth_tvchain_program_is_at (GMythTVChain *tvchain, 
   73.97 +                                         GString *chanid, time_t startts);
   73.98 +
   73.99 +struct LiveTVChainEntry* gmyth_tvchain_get_entry_at (GMythTVChain *tvchain, 
  73.100 +                                                     gint index);
  73.101 +
  73.102 +GMythProgramInfo*   gmyth_tvchain_entry_to_program (GMythTVChain *tvchain, 
  73.103 +                                                    struct LiveTVChainEntry *entry);
  73.104 +GMythProgramInfo*   gmyth_tvchain_get_program_at (GMythTVChain *tvchain, gint index);
  73.105 +
  73.106 +#define G_END_DECLS
  73.107 +
  73.108 +#endif /*LIVETVCHAIN_H_*/
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/gmyth/src/libgmyth/gmyth_tvplayer.c	Wed Sep 20 23:45:35 2006 +0100
    74.3 @@ -0,0 +1,719 @@
    74.4 +/**
    74.5 + * GMyth Library
    74.6 + *
    74.7 + * @file gmyth/gmyth_tvplayer.c
    74.8 + * 
    74.9 + * @brief <p> This component provides playback of the remote A/V using
   74.10 + * GStreamer.
   74.11 + * 
   74.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   74.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   74.14 + *
   74.15 + *//*
   74.16 + * 
   74.17 + * This program is free software; you can redistribute it and/or modify
   74.18 + * it under the terms of the GNU Lesser General Public License as published by
   74.19 + * the Free Software Foundation; either version 2 of the License, or
   74.20 + * (at your option) any later version.
   74.21 + *
   74.22 + * This program is distributed in the hope that it will be useful,
   74.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   74.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   74.25 + * GNU General Public License for more details.
   74.26 + *
   74.27 + * You should have received a copy of the GNU Lesser General Public License
   74.28 + * along with this program; if not, write to the Free Software
   74.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   74.30 + */
   74.31 +
   74.32 +#include "gmyth_tvplayer.h"
   74.33 + 
   74.34 +#include <gdk/gdkx.h>
   74.35 +
   74.36 +#include "gmyth_context.h"
   74.37 +#include "gmyth_remote_util.h"
   74.38 +
   74.39 +typedef struct _GstPlayerWindowStateChange
   74.40 +{
   74.41 +    GstElement *play;
   74.42 +    GstState old_state, new_state;
   74.43 +    GMythTVPlayer *tvplayer;
   74.44 +} GstPlayerWindowStateChange;
   74.45 +
   74.46 +typedef struct _GstPlayerWindowTagFound
   74.47 +{
   74.48 +    GstElement *play;
   74.49 +    GstTagList *taglist;
   74.50 +    GMythTVPlayer *tvplayer;
   74.51 +} GstPlayerWindowTagFound;
   74.52 +
   74.53 +/*
   74.54 +static gboolean idle_state (gpointer data);
   74.55 +static gboolean bus_call (GstBus * bus, GstMessage * msg, gpointer data);
   74.56 +*/
   74.57 +
   74.58 +static void gmyth_tvplayer_class_init          (GMythTVPlayerClass *klass);
   74.59 +static void gmyth_tvplayer_init                (GMythTVPlayer *object);
   74.60 +
   74.61 +static void gmyth_tvplayer_dispose  (GObject *object);
   74.62 +static void gmyth_tvplayer_finalize (GObject *object);
   74.63 +
   74.64 +G_DEFINE_TYPE(GMythTVPlayer, gmyth_tvplayer, G_TYPE_OBJECT)
   74.65 +
   74.66 +static gboolean gmyth_tvplayer_create_pipeline (GMythTVPlayer* tvplayer);
   74.67 +static void     new_pad_cb (GstElement *element, 
   74.68 +                            GstPad *pad, gpointer data);
   74.69 +
   74.70 +static gboolean expose_cb (GtkWidget * widget, 
   74.71 +                           GdkEventExpose * event, 
   74.72 +                           gpointer user_data);
   74.73 +
   74.74 +static void
   74.75 +gmyth_tvplayer_class_init (GMythTVPlayerClass *klass)
   74.76 +{
   74.77 +	GObjectClass *gobject_class;
   74.78 +
   74.79 +    gobject_class = (GObjectClass *) klass;
   74.80 +	
   74.81 +    gobject_class->dispose  = gmyth_tvplayer_dispose;
   74.82 +    gobject_class->finalize = gmyth_tvplayer_finalize;	
   74.83 +}
   74.84 +
   74.85 +static void
   74.86 +new_pad_cb (GstElement *element, GstPad *pad, gpointer data)
   74.87 +{
   74.88 +	GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (data);
   74.89 +	GstPadLinkReturn ret;
   74.90 +	char *s;
   74.91 +	
   74.92 +	s = gst_caps_to_string (pad->caps);
   74.93 +
   74.94 +	if ( s[0] == 'a') {
   74.95 +		ret = gst_pad_link (pad, gst_element_get_pad (tvplayer->audioqueue, "sink"));
   74.96 +	} else {
   74.97 +		ret = gst_pad_link (pad, gst_element_get_pad (tvplayer->videoqueue, "sink")); 
   74.98 +	}
   74.99 +	
  74.100 +	g_free(s);
  74.101 +}
  74.102 +
  74.103 +static gboolean
  74.104 +expose_cb (GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
  74.105 +{
  74.106 +    GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (user_data);
  74.107 +
  74.108 +	if (tvplayer && tvplayer->videow) {
  74.109 +	    gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (tvplayer->gst_videosink),
  74.110 +                                  GDK_WINDOW_XWINDOW (widget->window));
  74.111 +		return TRUE;
  74.112 +	}
  74.113 +	
  74.114 +	g_warning ("GMythTVPlayer expose called before setting video window\n");
  74.115 +	
  74.116 +    return FALSE;
  74.117 +}
  74.118 +
  74.119 +static void
  74.120 +gmyth_tvplayer_init (GMythTVPlayer *tvplayer)
  74.121 +{
  74.122 +    tvplayer->gst_pipeline = NULL;
  74.123 +    tvplayer->gst_source = NULL;
  74.124 +    tvplayer->gst_videodec = NULL;
  74.125 +    tvplayer->gst_videosink = NULL;
  74.126 +    tvplayer->videoqueue = NULL;
  74.127 +    tvplayer->audioqueue = NULL;
  74.128 +    
  74.129 +    /* GTKWidget for rendering the video */
  74.130 +    tvplayer->videow = NULL;
  74.131 +	tvplayer->expose_handler = 0;
  74.132 +	    
  74.133 +	tvplayer->backend_hostname = NULL;
  74.134 +	tvplayer->backend_port = 0;
  74.135 +	tvplayer->local_hostname = NULL;
  74.136 +
  74.137 +	tvplayer->remote_encoder = NULL;
  74.138 +	tvplayer->tvchain = NULL;
  74.139 +	tvplayer->proginfo = NULL;
  74.140 +}
  74.141 +
  74.142 +static void
  74.143 +gmyth_tvplayer_dispose (GObject *object)
  74.144 +{
  74.145 +
  74.146 +	G_OBJECT_CLASS (gmyth_tvplayer_parent_class)->dispose (object);
  74.147 +}
  74.148 +
  74.149 +static void
  74.150 +gmyth_tvplayer_finalize (GObject *object)
  74.151 +{
  74.152 +	g_signal_handlers_destroy (object);
  74.153 +
  74.154 +	GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (object);
  74.155 +
  74.156 +	g_debug ("[%s] Finalizing tvplayer", __FUNCTION__);
  74.157 +	
  74.158 +	if (tvplayer->videow != NULL) {
  74.159 +		if (g_signal_handler_is_connected (tvplayer->videow, 
  74.160 +						tvplayer->expose_handler)) {
  74.161 +			g_signal_handler_disconnect (tvplayer->videow,
  74.162 +				tvplayer->expose_handler);
  74.163 +		}
  74.164 +		g_object_unref (tvplayer->videow);
  74.165 +	}
  74.166 +	
  74.167 +	if ( tvplayer->remote_encoder != NULL )
  74.168 +		g_object_unref (tvplayer->remote_encoder);
  74.169 +	if ( tvplayer->tvchain != NULL )
  74.170 +		g_object_unref (tvplayer->tvchain);
  74.171 +	if ( tvplayer->proginfo != NULL )
  74.172 +		g_object_unref (tvplayer->proginfo);	
  74.173 +
  74.174 +	// Release Gstreamer elements
  74.175 +	if ( tvplayer->gst_pipeline != NULL )
  74.176 +		g_object_unref (tvplayer->gst_pipeline);	
  74.177 +	if ( tvplayer->gst_source != NULL )
  74.178 +		g_object_unref (tvplayer->gst_source);	
  74.179 +	if ( tvplayer->gst_videodec != NULL )
  74.180 +		g_object_unref (tvplayer->gst_videodec);	
  74.181 +	if ( tvplayer->gst_videosink != NULL )
  74.182 +		g_object_unref (tvplayer->gst_videosink);	
  74.183 +	if ( tvplayer->videoqueue != NULL )
  74.184 +		g_object_unref (tvplayer->videoqueue);	
  74.185 +	if ( tvplayer->audioqueue != NULL )
  74.186 +		g_object_unref (tvplayer->audioqueue);	
  74.187 +
  74.188 +	G_OBJECT_CLASS (gmyth_tvplayer_parent_class)->finalize (object);
  74.189 +}
  74.190 +
  74.191 +/** Creates a new instance of GMythTVPlayer. 
  74.192 + * 
  74.193 + * @return a new instance of GMythTVPlayer.
  74.194 + */
  74.195 +GMythTVPlayer *
  74.196 +gmyth_tvplayer_new ()
  74.197 +{
  74.198 +    GMythTVPlayer *tvplayer = 
  74.199 +        GMYTH_TVPLAYER (g_object_new(GMYTH_TVPLAYER_TYPE, NULL));
  74.200 +    
  74.201 +    return tvplayer;
  74.202 +}
  74.203 +
  74.204 +/** Initializes the tv player.
  74.205 + *
  74.206 + * @param tvplayer the object instance.
  74.207 + * @return gboolean TRUE if the pipeline was created 
  74.208 + * successfully, FALSE otherwise.
  74.209 + */
  74.210 +gboolean
  74.211 +gmyth_tvplayer_initialize (GMythTVPlayer *tvplayer)
  74.212 +{
  74.213 +	
  74.214 +    if (!gmyth_tvplayer_create_pipeline (tvplayer)) {
  74.215 +    	g_warning ("[%s] Error while creating pipeline. TV Player not initialized", __FUNCTION__);
  74.216 +		return FALSE;
  74.217 +	} else {
  74.218 +		g_debug ("[%s] GStreamer pipeline created", __FUNCTION__);	
  74.219 +    }
  74.220 +
  74.221 +	return TRUE;
  74.222 +}
  74.223 +
  74.224 +/** Creates the GStreamer pipeline used by the player.
  74.225 + *
  74.226 + * @param tvplayer the object instance.
  74.227 + * @return gboolean TRUE if the pipeline was created 
  74.228 + * successfully, FALSE otherwise.
  74.229 + */
  74.230 +static gboolean
  74.231 +gmyth_tvplayer_create_pipeline (GMythTVPlayer* tvplayer)
  74.232 +{
  74.233 +    GstElement *pipeline;
  74.234 +    GstElement *source, *parser;
  74.235 +    GstElement *videodec, *videosink;
  74.236 +#ifndef MAEMO_PLATFORM    
  74.237 +    GstElement *audiodec, *audioconv;
  74.238 +#endif
  74.239 +    GstElement *audiosink;
  74.240 +    GstElement *videoqueue, *audioqueue;
  74.241 +
  74.242 +    g_debug ("GMythTVPlayer: Setting the Gstreamer pipeline\n");
  74.243 +	
  74.244 +    pipeline = gst_pipeline_new ("video-player");
  74.245 +    source = gst_element_factory_make ("mythtvsrc", "myth-source");
  74.246 +    parser = gst_element_factory_make ("ffdemux_nuv", "nuv-demux");
  74.247 +
  74.248 +    /* Gstreamer Video elements */
  74.249 +    videoqueue = gst_element_factory_make ("queue", "video-queue");
  74.250 +    videodec = gst_element_factory_make ("ffdec_mpeg4", "video-decoder");
  74.251 +#ifdef MAEMO_PLATFORM
  74.252 +    videosink = gst_element_factory_make ("sdlvideosink", "image-output");
  74.253 +#else
  74.254 +    videosink = gst_element_factory_make ("xvimagesink", "image-output");
  74.255 +#endif
  74.256 +    
  74.257 +    /* Gstreamer Audio elements */
  74.258 +    audioqueue = gst_element_factory_make ("queue", "audio-queue");    
  74.259 +#ifdef MAEMO_PLATFORM    
  74.260 +    audiosink = gst_element_factory_make ("dspmp3sink", "audio-output");
  74.261 +#else    
  74.262 +    audiodec = gst_element_factory_make ("ffdec_mp3", "audio-decoder");
  74.263 +    audioconv = gst_element_factory_make ("audioconvert", "audio-converter");
  74.264 +    audiosink = gst_element_factory_make ("alsasink", "audio-output");
  74.265 +#endif    
  74.266 +    
  74.267 +    if (!(pipeline && source && parser && videodec && videosink) ||
  74.268 +    	!(videoqueue && audioqueue && audiosink)) {
  74.269 +        /* FIXME: hanlde the error correctly */
  74.270 +        /* video_alignment is not being created (below) 
  74.271 +           and is causing problems to the ui */
  74.272 +
  74.273 +	    tvplayer->gst_pipeline = NULL;
  74.274 +	    tvplayer->gst_videodec = NULL;
  74.275 +	    tvplayer->gst_videosink = NULL;
  74.276 +           
  74.277 +        g_warning ("GstElement creation error!\n");
  74.278 +        return FALSE;
  74.279 +    }
  74.280 +
  74.281 +#ifndef MAEMO_PLATFORM    
  74.282 +    if (!(audiodec && audioconv)) {
  74.283 +        g_warning ("GstElement for audio stream creation error!");
  74.284 +        return FALSE;
  74.285 +    }
  74.286 +#endif    
  74.287 +    
  74.288 +    
  74.289 +    tvplayer->gst_pipeline = pipeline;
  74.290 +    tvplayer->gst_source = source;
  74.291 +    tvplayer->gst_videodec = videodec;
  74.292 +    tvplayer->gst_videosink = videosink;
  74.293 +    g_object_ref (tvplayer->gst_pipeline);
  74.294 +    g_object_ref (tvplayer->gst_source);
  74.295 +    g_object_ref (tvplayer->gst_videodec);
  74.296 +    g_object_ref (tvplayer->gst_videosink);
  74.297 +
  74.298 +    tvplayer->videoqueue = videoqueue;
  74.299 +    tvplayer->audioqueue = audioqueue;
  74.300 +    g_object_ref (tvplayer->videoqueue);
  74.301 +    g_object_ref (tvplayer->audioqueue);
  74.302 +   	
  74.303 +    g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
  74.304 +    g_object_set (G_OBJECT (audiosink), "sync", FALSE, NULL);
  74.305 +
  74.306 +//    gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (tvplayer->gst_pipeline)),
  74.307 +//                       bus_call, tvplayer);
  74.308 +
  74.309 +    gst_bin_add_many (GST_BIN (pipeline), source, parser, videoqueue,
  74.310 +    			videodec, videosink, audioqueue, audiodec, audioconv, audiosink, NULL);
  74.311 +
  74.312 +    {
  74.313 +//        GstCaps *rtpcaps = gst_caps_new_simple ("application/x-rtp", NULL);
  74.314 +//        gst_element_link_filtered(source, parser, rtpcaps);
  74.315 +    }
  74.316 +    
  74.317 +    gst_element_link (source, parser);
  74.318 +    gst_element_link_many (videoqueue, videodec, videosink, NULL);
  74.319 +    gst_element_link_many (audioqueue, audiodec, audioconv, audiosink, NULL);
  74.320 +    
  74.321 +    g_signal_connect (parser, "pad-added", G_CALLBACK (new_pad_cb), tvplayer);
  74.322 +    
  74.323 +    return TRUE;
  74.324 +}
  74.325 +
  74.326 +/** Configures the backend and the tv player 
  74.327 + * for playing the recorded content A/V.
  74.328 + *
  74.329 + * FIXME: Change filename to program info or other structure about the recorded
  74.330 + *
  74.331 + * @param tvplayer the object instance.
  74.332 + * @param filename the file uri of the recorded content to be played.
  74.333 + * @return TRUE if successfull, FALSE if any error happens.
  74.334 + */
  74.335 +gboolean
  74.336 +gmyth_tvplayer_record_setup (GMythTVPlayer *tvplayer, gchar *filename)
  74.337 +{
  74.338 +	GMythSettings *msettings = gmyth_context_get_settings();
  74.339 +	
  74.340 +	// FIXME: we should receive the uri instead of filename
  74.341 +	GString *hostname = gmyth_settings_get_backend_hostname (msettings);
  74.342 +	int port = gmyth_settings_get_backend_port(msettings);
  74.343 +	
  74.344 +	GString *fullpath = g_string_new ("myth://");
  74.345 +	g_string_append_printf (fullpath, "%s:%d/%s", hostname->str, port, filename);
  74.346 +	
  74.347 +	tvplayer->is_livetv = FALSE;
  74.348 +
  74.349 +	g_debug ("[%s] Setting record uri to gstreamer pipeline to %s", __FUNCTION__, fullpath->str);
  74.350 +		
  74.351 +    g_object_set (G_OBJECT (tvplayer->gst_source), "location",
  74.352 +          fullpath->str, NULL);
  74.353 +          
  74.354 +    return TRUE;
  74.355 +}
  74.356 +
  74.357 +/** Configures the backend and the tv player 
  74.358 + * for playing the live tv.
  74.359 + *
  74.360 + * @param tvplayer the object instance.
  74.361 + * @return TRUE if successfull, FALSE if any error happens.
  74.362 + */
  74.363 +gboolean
  74.364 +gmyth_tvplayer_livetv_setup (GMythTVPlayer *tvplayer)
  74.365 +{
  74.366 +	GMythSettings *msettings = gmyth_context_get_settings ();
  74.367 +	gboolean res = TRUE;
  74.368 +
  74.369 +	res = gmyth_context_check_connection();
  74.370 +	if (!res) {
  74.371 +		g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);	
  74.372 +		res = FALSE;
  74.373 +		goto error;
  74.374 +	}
  74.375 +
  74.376 +	tvplayer->backend_hostname = gmyth_settings_get_backend_hostname(msettings);
  74.377 +	tvplayer->backend_port = gmyth_settings_get_backend_port (msettings);
  74.378 +
  74.379 +	tvplayer->local_hostname  = g_string_new("");    
  74.380 +	gmyth_context_get_local_hostname (tvplayer->local_hostname);
  74.381 +
  74.382 +	if ( tvplayer->local_hostname == NULL ) {
  74.383 +		res = FALSE;
  74.384 +		goto error;
  74.385 +	}
  74.386 +
  74.387 +	// Gets the remote encoder num
  74.388 +	tvplayer->remote_encoder = remote_request_next_free_recorder (-1);
  74.389 +
  74.390 +	if ( tvplayer->remote_encoder == NULL ) {
  74.391 +		g_warning ("[%s] None remote encoder available", __FUNCTION__);
  74.392 +		res = FALSE;
  74.393 +		goto error;
  74.394 +	}
  74.395 +
  74.396 +	// Creates livetv chain handler
  74.397 +	tvplayer->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
  74.398 +	gmyth_tvchain_initialize ( tvplayer->tvchain, tvplayer->local_hostname );
  74.399 +
  74.400 +	if ( tvplayer->tvchain == NULL || tvplayer->tvchain->tvchain_id == NULL ) {
  74.401 +		res = FALSE;
  74.402 +		goto error;
  74.403 +	}
  74.404 +
  74.405 +	// Init remote encoder. Opens its control socket.
  74.406 +	res = gmyth_remote_encoder_setup(tvplayer->remote_encoder);
  74.407 +	if ( !res ) {
  74.408 +		g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
  74.409 +		res = FALSE;
  74.410 +		goto error;
  74.411 +	}
  74.412 +	// Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
  74.413 +	res = gmyth_remote_encoder_spawntv ( tvplayer->remote_encoder,
  74.414 +			gmyth_tvchain_get_id(tvplayer->tvchain) );
  74.415 +	if (!res) {
  74.416 +		g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
  74.417 +		res = FALSE;
  74.418 +		goto error;
  74.419 +	}
  74.420 +
  74.421 +	// Reload all TV chain from Mysql database.
  74.422 +	gmyth_tvchain_reload_all (tvplayer->tvchain);
  74.423 +
  74.424 +	if ( tvplayer->tvchain == NULL ) {
  74.425 +		res = FALSE;
  74.426 +		goto error;
  74.427 +	}
  74.428 +
  74.429 +	// Get program info from database using chanid and starttime
  74.430 +	tvplayer->proginfo = gmyth_tvchain_get_program_at (tvplayer->tvchain, -1);
  74.431 +	if ( tvplayer->proginfo == NULL ) {
  74.432 +		g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
  74.433 +		res = FALSE;
  74.434 +		goto error;
  74.435 +	} else {
  74.436 +		g_debug ("[%s] MythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ );
  74.437 +	}
  74.438 +
  74.439 +	return res;
  74.440 +
  74.441 +error:
  74.442 +	if ( tvplayer->backend_hostname != NULL ) {
  74.443 +		g_string_free( tvplayer->backend_hostname, TRUE );
  74.444 +		res = FALSE;
  74.445 +	}
  74.446 +
  74.447 +	if ( tvplayer->local_hostname != NULL ) {
  74.448 +		g_string_free( tvplayer->local_hostname, TRUE );
  74.449 +		res = FALSE;
  74.450 +	}
  74.451 +
  74.452 +	if ( tvplayer->remote_encoder != NULL ) {
  74.453 +		g_object_unref (tvplayer->remote_encoder);
  74.454 +		tvplayer->remote_encoder = NULL;
  74.455 +	}
  74.456 +
  74.457 +	if ( tvplayer->tvchain != NULL ) {
  74.458 +		g_object_unref (tvplayer->tvchain);
  74.459 +		tvplayer->tvchain = NULL;
  74.460 +	}
  74.461 +
  74.462 +	if ( tvplayer->proginfo != NULL ) {
  74.463 +		g_object_unref (tvplayer->proginfo);
  74.464 +		tvplayer->proginfo = NULL;
  74.465 +	}
  74.466 +
  74.467 +	return res;
  74.468 +
  74.469 +}
  74.470 +
  74.471 +/** Sets the GTK video widget for the tv player. 
  74.472 + *
  74.473 + * @param tvplayer the object instance.
  74.474 + * @param videow the GTK video window.
  74.475 + * @return TRUE if successfull, FALSE if any error happens.
  74.476 + */
  74.477 +gboolean
  74.478 +gmyth_tvplayer_set_widget (GMythTVPlayer *tvplayer, GtkWidget *videow)
  74.479 +{
  74.480 +	tvplayer->videow = videow;
  74.481 +	g_object_ref (videow);
  74.482 +	
  74.483 +	g_debug ("[%s] Setting widget for tv player render", __FUNCTION__);
  74.484 +	
  74.485 +    tvplayer->expose_handler = g_signal_connect (tvplayer->videow, "expose-event", 
  74.486 +                                                 G_CALLBACK (expose_cb), tvplayer);
  74.487 +
  74.488 +    //g_signal_connect(miptv_ui->videow, "size_request", G_CALLBACK(cb_preferred_video_size), miptv_ui);
  74.489 +
  74.490 +    return TRUE;
  74.491 +}
  74.492 +
  74.493 +#if 0
  74.494 +static gboolean
  74.495 +bus_call (GstBus * bus, GstMessage * msg, gpointer data)
  74.496 +{
  74.497 +    GMythTVPlayer *tvplayer = GMYTH_TVPLAYER ( data );
  74.498 +    GMainLoop *loop = tvplayer->loop;
  74.499 +
  74.500 +    switch (GST_MESSAGE_TYPE (msg)) {
  74.501 +        case GST_MESSAGE_EOS:
  74.502 +			printf ("End of stream\n");
  74.503 +/*            if (miptv_ui->idle_id != 0) {
  74.504 +                g_source_remove (miptv_ui->idle_id);
  74.505 +                miptv_ui->idle_id = 0;
  74.506 +            }*/
  74.507 +
  74.508 +            //g_idle_add ((GSourceFunc) idle_eos, data);
  74.509 +            gst_element_set_state (GST_ELEMENT (GST_MESSAGE_SRC (msg)),
  74.510 +                                   GST_STATE_READY);
  74.511 +            break;
  74.512 +        case GST_MESSAGE_ERROR:
  74.513 +        {
  74.514 +                gchar *debug;
  74.515 +                GError *err;
  74.516 +
  74.517 +                gst_message_parse_error (msg, &err, &debug);
  74.518 +                g_free (debug);
  74.519 +
  74.520 +                printf ("Error: %s\n", err->message);
  74.521 +                g_error_free (err);
  74.522 +
  74.523 +                g_main_loop_quit (loop);
  74.524 +        }
  74.525 +            break;
  74.526 +        case GST_MESSAGE_STATE_CHANGED:{
  74.527 +                GstState oldstate;
  74.528 +                GstState newstate;
  74.529 +                GstState pending;
  74.530 +                GstPlayerWindowStateChange *st =
  74.531 +                    g_new (GstPlayerWindowStateChange, 1);
  74.532 +
  74.533 +                gst_message_parse_state_changed (msg,
  74.534 +                                                 &oldstate,
  74.535 +                                                 &newstate, &pending);
  74.536 +
  74.537 +                st->play = tvplayer->gst_pipeline;
  74.538 +                gst_object_ref (GST_OBJECT (tvplayer->gst_pipeline));
  74.539 +                st->old_state = oldstate;
  74.540 +                st->new_state = newstate;
  74.541 +
  74.542 +                st->tvplayer = tvplayer;
  74.543 +
  74.544 +                /* State debug messages */
  74.545 +                printf ("oldstate = %s, newstate = %s, pendingstate = %s\n",
  74.546 +                        gst_element_state_get_name (oldstate),
  74.547 +                        gst_element_state_get_name (newstate),
  74.548 +                        gst_element_state_get_name (pending));
  74.549 +
  74.550 +                //g_idle_add ((GSourceFunc) idle_state, st);
  74.551 +
  74.552 +            }
  74.553 +            break;
  74.554 +        default:
  74.555 +            printf (gst_message_type_get_name (GST_MESSAGE_TYPE (msg)));
  74.556 +            printf ("\n");
  74.557 +            break;
  74.558 +    }
  74.559 +
  74.560 +    return TRUE;
  74.561 +}
  74.562 +#endif
  74.563 +
  74.564 +
  74.565 +#if 0
  74.566 +static gboolean
  74.567 +idle_state (gpointer data)
  74.568 +{
  74.569 +    GstPlayerWindowStateChange *st = data;
  74.570 +
  74.571 +    if (st->old_state == GST_STATE_PLAYING) {
  74.572 +        if (st->miptv_ui->idle_id != 0) {
  74.573 +            g_source_remove (st->miptv_ui->idle_id);
  74.574 +            st->miptv_ui->idle_id = 0;
  74.575 +        }
  74.576 +    }
  74.577 +    else if (st->new_state == GST_STATE_PLAYING) {
  74.578 +        if (st->miptv_ui->idle_id != 0)
  74.579 +            g_source_remove (st->miptv_ui->idle_id);
  74.580 +
  74.581 +        st->miptv_ui->idle_id = g_idle_add (cb_iterate, st->miptv_ui);
  74.582 +    }
  74.583 +
  74.584 +    /* new movie loaded? */
  74.585 +    if (st->old_state == GST_STATE_READY && st->new_state > GST_STATE_READY) {
  74.586 +
  74.587 +        /* gboolean have_video = FALSE; */
  74.588 +
  74.589 +        gtk_widget_show (st->miptv_ui->videow);
  74.590 +
  74.591 +        gtk_window_resize (GTK_WINDOW (st->miptv_ui->main_window), 1, 1);
  74.592 +
  74.593 +    }
  74.594 +
  74.595 +    /* discarded movie? */
  74.596 +    if (st->old_state > GST_STATE_READY && st->new_state == GST_STATE_READY) {
  74.597 +
  74.598 +        if (st->miptv_ui->tagcache) {
  74.599 +            gst_tag_list_free (st->miptv_ui->tagcache);
  74.600 +            st->miptv_ui->tagcache = NULL;
  74.601 +        }
  74.602 +    }
  74.603 +
  74.604 +    gst_object_unref (GST_OBJECT (st->play));
  74.605 +    //g_object_unref (G_OBJECT (st->win));
  74.606 +    g_free (st);
  74.607 +
  74.608 +    /* once */
  74.609 +    return FALSE;
  74.610 +}
  74.611 +
  74.612 +#endif
  74.613 +
  74.614 +/** Stops playing the current A/V.
  74.615 + *
  74.616 + * FIXME: How to proceed differently between livetv 
  74.617 + * and recorded content?
  74.618 + *
  74.619 + * @param tvplayer the object instance.
  74.620 + * @return void 
  74.621 + */
  74.622 +void
  74.623 +gmyth_tvplayer_stop_playing (GMythTVPlayer *tvplayer) 
  74.624 +{
  74.625 +    g_debug ("[%s] Setting gstreamer pipeline state to NULL", __FUNCTION__);
  74.626 +
  74.627 +    gst_element_set_state (tvplayer->gst_pipeline, GST_STATE_NULL);
  74.628 +    
  74.629 +    if (tvplayer->is_livetv) {
  74.630 +	    if (!gmyth_remote_encoder_stop_livetv (tvplayer->remote_encoder)) {
  74.631 +	    	g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);	
  74.632 +	    }
  74.633 +    }
  74.634 +}
  74.635 +
  74.636 +/** Queries if the tvplayer is active playing A/V content.
  74.637 + *
  74.638 + * @param tvplayer the object instance.
  74.639 + * @return TRUE if the tvplayer is active, FALSE otherwise.
  74.640 + */
  74.641 +gboolean
  74.642 +gmyth_tvplayer_is_playing (GMythTVPlayer *tvplayer)
  74.643 +{
  74.644 +	return (GST_STATE (tvplayer->gst_pipeline) == GST_STATE_PLAYING);
  74.645 +}
  74.646 +
  74.647 +/** Static function that sets the tvplayer state to PLAYING.
  74.648 + *
  74.649 + * @param tvplayer the object instance.
  74.650 + * @return TRUE if the tvplayer is active, FALSE otherwise.
  74.651 + */
  74.652 +static gboolean
  74.653 +idle_play (gpointer data)
  74.654 +{
  74.655 +    GMythTVPlayer *tvplayer = GMYTH_TVPLAYER (data);
  74.656 +
  74.657 +	g_debug ("GMythTVPlayer: Setting pipeline state to PLAYING\n");
  74.658 +
  74.659 +    gst_element_set_state (tvplayer->gst_pipeline, GST_STATE_PLAYING);
  74.660 +
  74.661 +    return FALSE;
  74.662 +}
  74.663 +
  74.664 +/** Start playing A/V with the tvplayer attributes.
  74.665 + *
  74.666 + * @param tvplayer the object instance.
  74.667 + */
  74.668 +void
  74.669 +gmyth_tvplayer_start_playing (GMythTVPlayer *tvplayer)
  74.670 +{
  74.671 +
  74.672 +	// FIXME: Move this to livetv_setup??
  74.673 +	if (tvplayer->is_livetv) {
  74.674 +
  74.675 +	#if 0
  74.676 +		if (!tvplayer || !(tvplayer->proginfo) || !(tvplayer->local_hostname)
  74.677 +				|| !(tvplayer->gst_source)) {
  74.678 +			g_warning ("GMythtvPlayer not ready to start playing\n");		
  74.679 +		}
  74.680 +
  74.681 +		if (!(tvplayer->proginfo->pathname)) {
  74.682 +			g_warning ("[%s] Playback url is null, could not play the myth content", __FUNCTION__);
  74.683 +			return;
  74.684 +		}
  74.685 +
  74.686 +		g_debug ("GMythTVPlayer: Start playing %s", tvplayer->proginfo->pathname->str);
  74.687 +#endif
  74.688 +		g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live",
  74.689 +				TRUE, NULL);
  74.690 +#if 0
  74.691 +		if ( tvplayer->tvchain != NULL ) {
  74.692 +			GString *str_chainid = gmyth_tvchain_get_id(tvplayer->tvchain);
  74.693 +			g_print( "[%s]\tCHAIN ID: %s\n", __FUNCTION__, str_chainid->str );
  74.694 +
  74.695 +			g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live-chainid", 
  74.696 +					g_strdup( str_chainid->str ), NULL);      
  74.697 +			if ( str_chainid!=NULL)
  74.698 +				g_string_free( str_chainid, FALSE );
  74.699 +		}
  74.700 +
  74.701 +		if ( tvplayer->remote_encoder != NULL )	
  74.702 +			g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-live-id",
  74.703 +					tvplayer->remote_encoder->recorder_num, NULL );
  74.704 +		g_debug ("[%s] Setting location to %s", __FUNCTION__, 
  74.705 +				tvplayer->proginfo->pathname->str);
  74.706 +
  74.707 +		/* Sets the gstreamer properties acording to the service access address */
  74.708 +		g_object_set (G_OBJECT (tvplayer->gst_source), "location",
  74.709 +				tvplayer->proginfo->pathname->str, NULL);              
  74.710 +#endif
  74.711 +	}
  74.712 +
  74.713 +	g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-version",
  74.714 +              MYTHTV_VERSION_DEFAULT, NULL);
  74.715 +
  74.716 +    g_object_set (G_OBJECT (tvplayer->gst_source), "mythtv-debug",
  74.717 +              TRUE, NULL);
  74.718 +
  74.719 +    g_idle_add (idle_play, tvplayer);
  74.720 +
  74.721 +}
  74.722 +
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/gmyth/src/libgmyth/gmyth_tvplayer.h	Wed Sep 20 23:45:35 2006 +0100
    75.3 @@ -0,0 +1,112 @@
    75.4 +/**
    75.5 + * GMyth Library
    75.6 + *
    75.7 + * @file gmyth/gmyth_tvplayer.h
    75.8 + * 
    75.9 + * @brief <p> This component provides playback of the remote A/V using
   75.10 + * GStreamer.
   75.11 + * 
   75.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   75.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   75.14 + *
   75.15 + *//*
   75.16 + * 
   75.17 + * This program is free software; you can redistribute it and/or modify
   75.18 + * it under the terms of the GNU Lesser General Public License as published by
   75.19 + * the Free Software Foundation; either version 2 of the License, or
   75.20 + * (at your option) any later version.
   75.21 + *
   75.22 + * This program is distributed in the hope that it will be useful,
   75.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   75.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   75.25 + * GNU General Public License for more details.
   75.26 + *
   75.27 + * You should have received a copy of the GNU Lesser General Public License
   75.28 + * along with this program; if not, write to the Free Software
   75.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   75.30 + */
   75.31 +
   75.32 +#ifndef GMYTH_TVPLAYER_H_
   75.33 +#define GMYTH_TVPLAYER_H_
   75.34 +
   75.35 +#include <glib-object.h>
   75.36 +#include <gtk/gtk.h>
   75.37 +
   75.38 +/* GStreamer includes */
   75.39 +#include <gst/gst.h>
   75.40 +#include <gst/interfaces/xoverlay.h>
   75.41 +
   75.42 +#include "gmyth_remote_encoder.h"
   75.43 +#include "gmyth_tvchain.h"
   75.44 +#include "gmyth_common.h"
   75.45 +
   75.46 +#define G_BEGIN_DECLS
   75.47 +
   75.48 +#define GMYTH_TVPLAYER_TYPE               (gmyth_tvplayer_get_type ())
   75.49 +#define GMYTH_TVPLAYER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVPLAYER_TYPE, GMythTVPlayer))
   75.50 +#define GMYTH_TVPLAYER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVPLAYER_TYPE, GMythTVPlayerClass))
   75.51 +#define IS_GMYTH_TVPLAYER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVPLAYER_TYPE))
   75.52 +#define IS_GMYTH_TVPLAYER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVPLAYER_TYPE))
   75.53 +#define GMYTH_TVPLAYER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVPLAYER_TYPE, GMythTVPlayerClass))
   75.54 +
   75.55 +
   75.56 +typedef struct _GMythTVPlayer         GMythTVPlayer;
   75.57 +typedef struct _GMythTVPlayerClass    GMythTVPlayerClass;
   75.58 +
   75.59 +struct _GMythTVPlayerClass
   75.60 +{
   75.61 +    GObjectClass parent_class;
   75.62 +
   75.63 +      /* callbacks */
   75.64 +      /*  no one for now */
   75.65 +};
   75.66 +
   75.67 +struct _GMythTVPlayer
   75.68 +{
   75.69 +    GObject parent;
   75.70 +    
   75.71 +    GstElement *gst_pipeline;
   75.72 +    GstElement *gst_source;
   75.73 +    GstElement *gst_videodec;
   75.74 +    GstElement *gst_videosink;
   75.75 +    GstElement *videoqueue;
   75.76 +    GstElement *audioqueue;
   75.77 +    
   75.78 +    gulong expose_handler;
   75.79 +//    GMainLoop *loop;
   75.80 +    
   75.81 +    GtkWidget *videow;
   75.82 +
   75.83 +	/* Backend connection related variables */
   75.84 +	GString *backend_hostname;
   75.85 +	gint backend_port;
   75.86 +	GString *local_hostname;
   75.87 +
   75.88 +	GMythRemoteEncoder *remote_encoder;
   75.89 +	GMythTVChain *tvchain;
   75.90 +	GMythProgramInfo *proginfo;
   75.91 +	
   75.92 +	gboolean is_livetv;
   75.93 +};
   75.94 +
   75.95 +
   75.96 +GType          gmyth_tvplayer_get_type (void);
   75.97 +
   75.98 +GMythTVPlayer* gmyth_tvplayer_new ();
   75.99 +gboolean       gmyth_tvplayer_initialize (GMythTVPlayer *tvplayer);
  75.100 +
  75.101 +void           gmyth_tvplayer_start_playing   (GMythTVPlayer *tvplayer);
  75.102 +void           gmyth_tvplayer_stop_playing    (GMythTVPlayer *tvplayer);
  75.103 +
  75.104 +gboolean       gmyth_tvplayer_set_widget   (GMythTVPlayer *tvplayer, 
  75.105 +                                            GtkWidget *videow);
  75.106 +
  75.107 +gboolean       gmyth_tvplayer_is_playing   (GMythTVPlayer *tvplayer);
  75.108 +
  75.109 +gboolean       gmyth_tvplayer_record_setup (GMythTVPlayer *tvplayer, 
  75.110 +                                            gchar *filename);
  75.111 +gboolean       gmyth_tvplayer_livetv_setup (GMythTVPlayer *tvplayer);
  75.112 +
  75.113 +#define G_END_DECLS
  75.114 +
  75.115 +#endif /*GMYTH_TVPLAYER_H_*/
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/gmyth/src/libgmyth/gmyth_util.c	Wed Sep 20 23:45:35 2006 +0100
    76.3 @@ -0,0 +1,138 @@
    76.4 +/**
    76.5 +* GMyth Library
    76.6 +*
    76.7 +* @file gmyth/gmyth_util.c
    76.8 +* 
    76.9 +* @brief <p> This component provides utility functions.
   76.10 +* 
   76.11 +* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   76.12 +* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   76.13 +*
   76.14 +*//*
   76.15 +* 
   76.16 +* This program is free software; you can redistribute it and/or modify
   76.17 +* it under the terms of the GNU Lesser General Public License as published by
   76.18 +* the Free Software Foundation; either version 2 of the License, or
   76.19 +* (at your option) any later version.
   76.20 +*
   76.21 +* This program is distributed in the hope that it will be useful,
   76.22 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
   76.23 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   76.24 +* GNU General Public License for more details.
   76.25 +*
   76.26 +* You should have received a copy of the GNU Lesser General Public License
   76.27 +* along with this program; if not, write to the Free Software
   76.28 +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   76.29 +*/
   76.30 +
   76.31 +#include "gmyth_util.h"
   76.32 +
   76.33 +#include <glib.h>
   76.34 +#include <glib/gprintf.h>
   76.35 +
   76.36 +/** Converts a time_t struct in a GString at ISO standard format 
   76.37 + * (e.g. 2006-07-20T09:56:41).
   76.38 + * 
   76.39 + * The returned GString memory should be deallocated from 
   76.40 + * the calling function.
   76.41 + *
   76.42 + * @param time_value the time value to be converted
   76.43 + * @return GString* the converted isoformat string 
   76.44 + */
   76.45 +GString*
   76.46 +gmyth_util_time_to_isoformat (time_t time_value)
   76.47 +{
   76.48 +	struct tm tm_time;
   76.49 +	GString *result;
   76.50 +	
   76.51 +	if (localtime_r(&time_value, &tm_time) == NULL) {
   76.52 +		g_warning ("gmyth_util_time_to_isoformat convertion error!\n");
   76.53 +        return NULL;
   76.54 +	}
   76.55 +	
   76.56 +	result = g_string_sized_new(20);
   76.57 +	g_string_printf(result, "%04d-%02d-%02dT%02d:%02d:%02d",
   76.58 +		tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
   76.59 +		tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);
   76.60 +	
   76.61 +	return result;
   76.62 +}
   76.63 +
   76.64 +/** Converts a time_t struct in a GString to the following 
   76.65 + * format (e.g. 2006-07-20 09:56:41).
   76.66 + * 
   76.67 + * The returned GString memory should be deallocated from 
   76.68 + * the calling function.
   76.69 + *
   76.70 + * @param time_value the time value to be converted
   76.71 + * @return GString* the converted string 
   76.72 + */
   76.73 +GString*
   76.74 +gmyth_util_time_to_string (time_t time_value)
   76.75 +{
   76.76 +	GString *result = gmyth_util_time_to_isoformat (time_value);
   76.77 +	result->str[10] = ' ';	
   76.78 +
   76.79 +	return result;
   76.80 +}
   76.81 +
   76.82 +/** Converts a GString in the following format 
   76.83 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
   76.84 + * 
   76.85 + * @param time_str the string to be converted
   76.86 + * @return time_t the time converted value
   76.87 + */
   76.88 +time_t
   76.89 +gmyth_util_string_to_time (GString* time_str)
   76.90 +{
   76.91 +	int year, month, day, hour, min, sec;
   76.92 +
   76.93 +	g_debug( "[%s] time_str = %s.\n", __FUNCTION__, time_str != NULL ? time_str->str : "[time string is NULL!]" );
   76.94 +
   76.95 +	if (sscanf (time_str->str, "%04d-%02d-%02d %02d:%02d:%02d",
   76.96 +			&year, &month, &day, &hour, &min, &sec) < 3) { /* At least date */
   76.97 +		g_warning ("GMythUtil: isoformat_to_time converter error!\n");
   76.98 +		return 0;
   76.99 +	} else {
  76.100 +		struct tm tm_time;
  76.101 +		tm_time.tm_year = year - 1900;
  76.102 +		tm_time.tm_mon = month - 1;
  76.103 +		tm_time.tm_mday = day;
  76.104 +		tm_time.tm_hour = hour;
  76.105 +		tm_time.tm_min = min;
  76.106 +		tm_time.tm_sec = sec;
  76.107 +		
  76.108 +		return mktime (&tm_time);
  76.109 +	}
  76.110 +}
  76.111 +
  76.112 +/** Decodes a long long variable from the string list
  76.113 + * format of the myhtprotocol.
  76.114 + * 
  76.115 + * @param strlist the string list of mythprotocol values
  76.116 + * @param offset  the list node offset of the long long variable
  76.117 + * @return guint64  the long long converted value
  76.118 + */
  76.119 +guint64
  76.120 +gmyth_util_decode_long_long(GMythStringList *strlist, guint offset) 
  76.121 +{
  76.122 +
  76.123 +	guint64 ret_value = 0LL;
  76.124 +
  76.125 +	g_return_val_if_fail( strlist != NULL, ret_value );
  76.126 +
  76.127 +	if ( offset < gmyth_string_list_length( strlist ))
  76.128 +		g_printerr( "[%s] Offset is lower than the Stringlist (offset = %d)!\n", 
  76.129 +                    __FUNCTION__, offset );
  76.130 +    
  76.131 +	g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value );
  76.132 +
  76.133 +	gint l1 = gmyth_string_list_get_int( strlist, offset );
  76.134 +	gint l2 = gmyth_string_list_get_int( strlist, offset + 1 );
  76.135 +
  76.136 +	ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
  76.137 +
  76.138 +	return ret_value;
  76.139 +
  76.140 +}
  76.141 +
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/gmyth/src/libgmyth/gmyth_util.h	Wed Sep 20 23:45:35 2006 +0100
    77.3 @@ -0,0 +1,42 @@
    77.4 +/**
    77.5 +* GMyth Library
    77.6 +*
    77.7 +* @file gmyth/gmyth_util.h
    77.8 +* 
    77.9 +* @brief <p> This component provides utility functions.
   77.10 +* 
   77.11 +* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   77.12 +* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   77.13 +*
   77.14 +*//*
   77.15 +* 
   77.16 +* This program is free software; you can redistribute it and/or modify
   77.17 +* it under the terms of the GNU Lesser General Public License as published by
   77.18 +* the Free Software Foundation; either version 2 of the License, or
   77.19 +* (at your option) any later version.
   77.20 +*
   77.21 +* This program is distributed in the hope that it will be useful,
   77.22 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
   77.23 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   77.24 +* GNU General Public License for more details.
   77.25 +*
   77.26 +* You should have received a copy of the GNU Lesser General Public License
   77.27 +* along with this program; if not, write to the Free Software
   77.28 +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   77.29 +*/
   77.30 +
   77.31 +#ifndef GMYTH_UTIL_H_
   77.32 +#define GMYTH_UTIL_H_
   77.33 +
   77.34 +#include <time.h>
   77.35 +#include <glib.h>
   77.36 +
   77.37 +#include "gmyth_stringlist.h"
   77.38 +
   77.39 +GString *   gmyth_util_time_to_isoformat(time_t time_value);
   77.40 +GString *   gmyth_util_time_to_string   (time_t time_value);
   77.41 +time_t      gmyth_util_string_to_time   (GString* time_str);
   77.42 +guint64     gmyth_util_decode_long_long (GMythStringList *strlist, 
   77.43 +                                         guint offset);
   77.44 +	
   77.45 +#endif /*GMYTH_UTIL_H_*/
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/gmyth/src/mmyth_main.c	Wed Sep 20 23:45:35 2006 +0100
    78.3 @@ -0,0 +1,103 @@
    78.4 +
    78.5 +#include <gtk/gtk.h>
    78.6 +
    78.7 +#include "config.h"
    78.8 +
    78.9 +#ifdef MAEMO_PLATFORM
   78.10 +#include "hildon-widgets/hildon-program.h"
   78.11 +#include "hildon-widgets/hildon-window.h"
   78.12 +#endif
   78.13 +
   78.14 +#include "gmyth_remote_encoder.h"
   78.15 +#include "gmyth_settings.h"
   78.16 +#include "gmyth_context.h"
   78.17 +#include "gmyth_tvchain.h"
   78.18 +#include "gmyth_tvplayer.h"
   78.19 +#include "gmyth_remote_util.h"
   78.20 +
   78.21 +#include "mmyth_ui.h"
   78.22 +
   78.23 +static void
   78.24 +cb_destroy (GtkWidget * widget, gpointer data)
   78.25 +{
   78.26 +    MMythUi *mmyth_ui = (MMythUi *) data;
   78.27 +
   78.28 +    if (mmyth_ui->tvplayer != NULL) {
   78.29 +    	if (gmyth_tvplayer_is_playing (mmyth_ui->tvplayer) )
   78.30 +    		gmyth_tvplayer_stop_playing (mmyth_ui->tvplayer);
   78.31 +    }
   78.32 +
   78.33 +	mmyth_ui_finalize (mmyth_ui);
   78.34 +	
   78.35 +    gtk_main_quit ();
   78.36 +}
   78.37 +
   78.38 +#ifdef NDEBUG
   78.39 +static void
   78.40 +debug_error_func( const gchar*log_domain, GLogLevelFlags log_level, const gchar *message,
   78.41 +	gpointer user_data )
   78.42 +
   78.43 +{
   78.44 +	/* leave this with NO print out messages, once you need to disable debug messages! */
   78.45 +	//g_print ( "[%s] DEBUG messages disabled!\n", __FUNCTION__ );
   78.46 +}
   78.47 +#endif
   78.48 +
   78.49 +gint
   78.50 +main (gint argc, gchar * argv[])
   78.51 +{
   78.52 +    GtkWidget *window;
   78.53 +    MMythUi *mmyth_ui;
   78.54 +#ifdef MAEMO_PLATFORM
   78.55 +    HildonProgram *program = NULL;
   78.56 +#endif
   78.57 +
   78.58 +    /* init threads */
   78.59 +    g_thread_init (NULL);
   78.60 +
   78.61 +    /* Initializes GTK */
   78.62 +    gtk_init (&argc, &argv);
   78.63 +    gst_init (&argc, &argv);
   78.64 +#ifdef NDEBUG
   78.65 + g_log_set_default_handler( debug_error_func, NULL );
   78.66 +#endif
   78.67 +
   78.68 +    /* Init libmmyth context */
   78.69 +    gmyth_context_initialize ();
   78.70 +	
   78.71 +#ifndef MAEMO_PLATFORM
   78.72 +    /* create the main window */
   78.73 +    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   78.74 +    gtk_widget_set_size_request (window, MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT);
   78.75 +    gtk_window_set_title (GTK_WINDOW (window), "Mythtv Frontend");
   78.76 +#else
   78.77 +    /* Creating Hildonized main view */
   78.78 +    program = HILDON_PROGRAM(hildon_program_get_instance());
   78.79 +    window = hildon_window_new();
   78.80 +
   78.81 +    //g_signal_connect(G_OBJECT(window), "delete_event", gtk_main_quit, NULL);
   78.82 +
   78.83 +    hildon_program_add_window(program, HILDON_WINDOW (window));
   78.84 +    g_set_application_name("Maemo Mythtv"); 
   78.85 +#endif
   78.86 +   
   78.87 +    /* Initializes MMyth Widgets */
   78.88 +#ifdef MAEMO_PLATFORM
   78.89 +    mmyth_ui = mmyth_ui_initialize (program, window);
   78.90 +#else    
   78.91 +    mmyth_ui = mmyth_ui_initialize (window);
   78.92 +#endif
   78.93 +    
   78.94 +    //mmyth_ui->loop = g_main_loop_new (NULL, FALSE);
   78.95 +
   78.96 +    /* Connect destroy signal handling */
   78.97 +    g_signal_connect (window, "destroy", G_CALLBACK (cb_destroy), mmyth_ui);
   78.98 +
   78.99 +    /* Shows main window and start gtk loop */
  78.100 +    gtk_widget_show (window);
  78.101 +
  78.102 +    gtk_main ();
  78.103 +
  78.104 +    return 0;
  78.105 +}
  78.106 +