1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/branches/gmyth-0.1b/AUTHORS Thu Feb 01 18:42:01 2007 +0000
1.3 @@ -0,0 +1,4 @@
1.4 +Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
1.5 +Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
1.6 +Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
1.7 +Rosfran Lins Borges <rosfran.borges@indt.org.br>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/branches/gmyth-0.1b/COPYING Thu Feb 01 18:42:01 2007 +0000
2.3 @@ -0,0 +1,340 @@
2.4 + GNU GENERAL PUBLIC LICENSE
2.5 + Version 2, June 1991
2.6 +
2.7 + Copyright (C) 1989, 1991 Free Software Foundation, Inc.
2.8 + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.9 + Everyone is permitted to copy and distribute verbatim copies
2.10 + of this license document, but changing it is not allowed.
2.11 +
2.12 + Preamble
2.13 +
2.14 + The licenses for most software are designed to take away your
2.15 +freedom to share and change it. By contrast, the GNU General Public
2.16 +License is intended to guarantee your freedom to share and change free
2.17 +software--to make sure the software is free for all its users. This
2.18 +General Public License applies to most of the Free Software
2.19 +Foundation's software and to any other program whose authors commit to
2.20 +using it. (Some other Free Software Foundation software is covered by
2.21 +the GNU Library General Public License instead.) You can apply it to
2.22 +your programs, too.
2.23 +
2.24 + When we speak of free software, we are referring to freedom, not
2.25 +price. Our General Public Licenses are designed to make sure that you
2.26 +have the freedom to distribute copies of free software (and charge for
2.27 +this service if you wish), that you receive source code or can get it
2.28 +if you want it, that you can change the software or use pieces of it
2.29 +in new free programs; and that you know you can do these things.
2.30 +
2.31 + To protect your rights, we need to make restrictions that forbid
2.32 +anyone to deny you these rights or to ask you to surrender the rights.
2.33 +These restrictions translate to certain responsibilities for you if you
2.34 +distribute copies of the software, or if you modify it.
2.35 +
2.36 + For example, if you distribute copies of such a program, whether
2.37 +gratis or for a fee, you must give the recipients all the rights that
2.38 +you have. You must make sure that they, too, receive or can get the
2.39 +source code. And you must show them these terms so they know their
2.40 +rights.
2.41 +
2.42 + We protect your rights with two steps: (1) copyright the software, and
2.43 +(2) offer you this license which gives you legal permission to copy,
2.44 +distribute and/or modify the software.
2.45 +
2.46 + Also, for each author's protection and ours, we want to make certain
2.47 +that everyone understands that there is no warranty for this free
2.48 +software. If the software is modified by someone else and passed on, we
2.49 +want its recipients to know that what they have is not the original, so
2.50 +that any problems introduced by others will not reflect on the original
2.51 +authors' reputations.
2.52 +
2.53 + Finally, any free program is threatened constantly by software
2.54 +patents. We wish to avoid the danger that redistributors of a free
2.55 +program will individually obtain patent licenses, in effect making the
2.56 +program proprietary. To prevent this, we have made it clear that any
2.57 +patent must be licensed for everyone's free use or not licensed at all.
2.58 +
2.59 + The precise terms and conditions for copying, distribution and
2.60 +modification follow.
2.61 +
2.62 + GNU GENERAL PUBLIC LICENSE
2.63 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
2.64 +
2.65 + 0. This License applies to any program or other work which contains
2.66 +a notice placed by the copyright holder saying it may be distributed
2.67 +under the terms of this General Public License. The "Program", below,
2.68 +refers to any such program or work, and a "work based on the Program"
2.69 +means either the Program or any derivative work under copyright law:
2.70 +that is to say, a work containing the Program or a portion of it,
2.71 +either verbatim or with modifications and/or translated into another
2.72 +language. (Hereinafter, translation is included without limitation in
2.73 +the term "modification".) Each licensee is addressed as "you".
2.74 +
2.75 +Activities other than copying, distribution and modification are not
2.76 +covered by this License; they are outside its scope. The act of
2.77 +running the Program is not restricted, and the output from the Program
2.78 +is covered only if its contents constitute a work based on the
2.79 +Program (independent of having been made by running the Program).
2.80 +Whether that is true depends on what the Program does.
2.81 +
2.82 + 1. You may copy and distribute verbatim copies of the Program's
2.83 +source code as you receive it, in any medium, provided that you
2.84 +conspicuously and appropriately publish on each copy an appropriate
2.85 +copyright notice and disclaimer of warranty; keep intact all the
2.86 +notices that refer to this License and to the absence of any warranty;
2.87 +and give any other recipients of the Program a copy of this License
2.88 +along with the Program.
2.89 +
2.90 +You may charge a fee for the physical act of transferring a copy, and
2.91 +you may at your option offer warranty protection in exchange for a fee.
2.92 +
2.93 + 2. You may modify your copy or copies of the Program or any portion
2.94 +of it, thus forming a work based on the Program, and copy and
2.95 +distribute such modifications or work under the terms of Section 1
2.96 +above, provided that you also meet all of these conditions:
2.97 +
2.98 + a) You must cause the modified files to carry prominent notices
2.99 + stating that you changed the files and the date of any change.
2.100 +
2.101 + b) You must cause any work that you distribute or publish, that in
2.102 + whole or in part contains or is derived from the Program or any
2.103 + part thereof, to be licensed as a whole at no charge to all third
2.104 + parties under the terms of this License.
2.105 +
2.106 + c) If the modified program normally reads commands interactively
2.107 + when run, you must cause it, when started running for such
2.108 + interactive use in the most ordinary way, to print or display an
2.109 + announcement including an appropriate copyright notice and a
2.110 + notice that there is no warranty (or else, saying that you provide
2.111 + a warranty) and that users may redistribute the program under
2.112 + these conditions, and telling the user how to view a copy of this
2.113 + License. (Exception: if the Program itself is interactive but
2.114 + does not normally print such an announcement, your work based on
2.115 + the Program is not required to print an announcement.)
2.116 +
2.117 +These requirements apply to the modified work as a whole. If
2.118 +identifiable sections of that work are not derived from the Program,
2.119 +and can be reasonably considered independent and separate works in
2.120 +themselves, then this License, and its terms, do not apply to those
2.121 +sections when you distribute them as separate works. But when you
2.122 +distribute the same sections as part of a whole which is a work based
2.123 +on the Program, the distribution of the whole must be on the terms of
2.124 +this License, whose permissions for other licensees extend to the
2.125 +entire whole, and thus to each and every part regardless of who wrote it.
2.126 +
2.127 +Thus, it is not the intent of this section to claim rights or contest
2.128 +your rights to work written entirely by you; rather, the intent is to
2.129 +exercise the right to control the distribution of derivative or
2.130 +collective works based on the Program.
2.131 +
2.132 +In addition, mere aggregation of another work not based on the Program
2.133 +with the Program (or with a work based on the Program) on a volume of
2.134 +a storage or distribution medium does not bring the other work under
2.135 +the scope of this License.
2.136 +
2.137 + 3. You may copy and distribute the Program (or a work based on it,
2.138 +under Section 2) in object code or executable form under the terms of
2.139 +Sections 1 and 2 above provided that you also do one of the following:
2.140 +
2.141 + a) Accompany it with the complete corresponding machine-readable
2.142 + source code, which must be distributed under the terms of Sections
2.143 + 1 and 2 above on a medium customarily used for software interchange; or,
2.144 +
2.145 + b) Accompany it with a written offer, valid for at least three
2.146 + years, to give any third party, for a charge no more than your
2.147 + cost of physically performing source distribution, a complete
2.148 + machine-readable copy of the corresponding source code, to be
2.149 + distributed under the terms of Sections 1 and 2 above on a medium
2.150 + customarily used for software interchange; or,
2.151 +
2.152 + c) Accompany it with the information you received as to the offer
2.153 + to distribute corresponding source code. (This alternative is
2.154 + allowed only for noncommercial distribution and only if you
2.155 + received the program in object code or executable form with such
2.156 + an offer, in accord with Subsection b above.)
2.157 +
2.158 +The source code for a work means the preferred form of the work for
2.159 +making modifications to it. For an executable work, complete source
2.160 +code means all the source code for all modules it contains, plus any
2.161 +associated interface definition files, plus the scripts used to
2.162 +control compilation and installation of the executable. However, as a
2.163 +special exception, the source code distributed need not include
2.164 +anything that is normally distributed (in either source or binary
2.165 +form) with the major components (compiler, kernel, and so on) of the
2.166 +operating system on which the executable runs, unless that component
2.167 +itself accompanies the executable.
2.168 +
2.169 +If distribution of executable or object code is made by offering
2.170 +access to copy from a designated place, then offering equivalent
2.171 +access to copy the source code from the same place counts as
2.172 +distribution of the source code, even though third parties are not
2.173 +compelled to copy the source along with the object code.
2.174 +
2.175 + 4. You may not copy, modify, sublicense, or distribute the Program
2.176 +except as expressly provided under this License. Any attempt
2.177 +otherwise to copy, modify, sublicense or distribute the Program is
2.178 +void, and will automatically terminate your rights under this License.
2.179 +However, parties who have received copies, or rights, from you under
2.180 +this License will not have their licenses terminated so long as such
2.181 +parties remain in full compliance.
2.182 +
2.183 + 5. You are not required to accept this License, since you have not
2.184 +signed it. However, nothing else grants you permission to modify or
2.185 +distribute the Program or its derivative works. These actions are
2.186 +prohibited by law if you do not accept this License. Therefore, by
2.187 +modifying or distributing the Program (or any work based on the
2.188 +Program), you indicate your acceptance of this License to do so, and
2.189 +all its terms and conditions for copying, distributing or modifying
2.190 +the Program or works based on it.
2.191 +
2.192 + 6. Each time you redistribute the Program (or any work based on the
2.193 +Program), the recipient automatically receives a license from the
2.194 +original licensor to copy, distribute or modify the Program subject to
2.195 +these terms and conditions. You may not impose any further
2.196 +restrictions on the recipients' exercise of the rights granted herein.
2.197 +You are not responsible for enforcing compliance by third parties to
2.198 +this License.
2.199 +
2.200 + 7. If, as a consequence of a court judgment or allegation of patent
2.201 +infringement or for any other reason (not limited to patent issues),
2.202 +conditions are imposed on you (whether by court order, agreement or
2.203 +otherwise) that contradict the conditions of this License, they do not
2.204 +excuse you from the conditions of this License. If you cannot
2.205 +distribute so as to satisfy simultaneously your obligations under this
2.206 +License and any other pertinent obligations, then as a consequence you
2.207 +may not distribute the Program at all. For example, if a patent
2.208 +license would not permit royalty-free redistribution of the Program by
2.209 +all those who receive copies directly or indirectly through you, then
2.210 +the only way you could satisfy both it and this License would be to
2.211 +refrain entirely from distribution of the Program.
2.212 +
2.213 +If any portion of this section is held invalid or unenforceable under
2.214 +any particular circumstance, the balance of the section is intended to
2.215 +apply and the section as a whole is intended to apply in other
2.216 +circumstances.
2.217 +
2.218 +It is not the purpose of this section to induce you to infringe any
2.219 +patents or other property right claims or to contest validity of any
2.220 +such claims; this section has the sole purpose of protecting the
2.221 +integrity of the free software distribution system, which is
2.222 +implemented by public license practices. Many people have made
2.223 +generous contributions to the wide range of software distributed
2.224 +through that system in reliance on consistent application of that
2.225 +system; it is up to the author/donor to decide if he or she is willing
2.226 +to distribute software through any other system and a licensee cannot
2.227 +impose that choice.
2.228 +
2.229 +This section is intended to make thoroughly clear what is believed to
2.230 +be a consequence of the rest of this License.
2.231 +
2.232 + 8. If the distribution and/or use of the Program is restricted in
2.233 +certain countries either by patents or by copyrighted interfaces, the
2.234 +original copyright holder who places the Program under this License
2.235 +may add an explicit geographical distribution limitation excluding
2.236 +those countries, so that distribution is permitted only in or among
2.237 +countries not thus excluded. In such case, this License incorporates
2.238 +the limitation as if written in the body of this License.
2.239 +
2.240 + 9. The Free Software Foundation may publish revised and/or new versions
2.241 +of the General Public License from time to time. Such new versions will
2.242 +be similar in spirit to the present version, but may differ in detail to
2.243 +address new problems or concerns.
2.244 +
2.245 +Each version is given a distinguishing version number. If the Program
2.246 +specifies a version number of this License which applies to it and "any
2.247 +later version", you have the option of following the terms and conditions
2.248 +either of that version or of any later version published by the Free
2.249 +Software Foundation. If the Program does not specify a version number of
2.250 +this License, you may choose any version ever published by the Free Software
2.251 +Foundation.
2.252 +
2.253 + 10. If you wish to incorporate parts of the Program into other free
2.254 +programs whose distribution conditions are different, write to the author
2.255 +to ask for permission. For software which is copyrighted by the Free
2.256 +Software Foundation, write to the Free Software Foundation; we sometimes
2.257 +make exceptions for this. Our decision will be guided by the two goals
2.258 +of preserving the free status of all derivatives of our free software and
2.259 +of promoting the sharing and reuse of software generally.
2.260 +
2.261 + NO WARRANTY
2.262 +
2.263 + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
2.264 +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
2.265 +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
2.266 +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
2.267 +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2.268 +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
2.269 +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
2.270 +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
2.271 +REPAIR OR CORRECTION.
2.272 +
2.273 + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
2.274 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
2.275 +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
2.276 +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
2.277 +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
2.278 +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
2.279 +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
2.280 +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
2.281 +POSSIBILITY OF SUCH DAMAGES.
2.282 +
2.283 + END OF TERMS AND CONDITIONS
2.284 +
2.285 + How to Apply These Terms to Your New Programs
2.286 +
2.287 + If you develop a new program, and you want it to be of the greatest
2.288 +possible use to the public, the best way to achieve this is to make it
2.289 +free software which everyone can redistribute and change under these terms.
2.290 +
2.291 + To do so, attach the following notices to the program. It is safest
2.292 +to attach them to the start of each source file to most effectively
2.293 +convey the exclusion of warranty; and each file should have at least
2.294 +the "copyright" line and a pointer to where the full notice is found.
2.295 +
2.296 + <one line to give the program's name and a brief idea of what it does.>
2.297 + Copyright (C) <year> <name of author>
2.298 +
2.299 + This program is free software; you can redistribute it and/or modify
2.300 + it under the terms of the GNU General Public License as published by
2.301 + the Free Software Foundation; either version 2 of the License, or
2.302 + (at your option) any later version.
2.303 +
2.304 + This program is distributed in the hope that it will be useful,
2.305 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2.306 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.307 + GNU General Public License for more details.
2.308 +
2.309 + You should have received a copy of the GNU General Public License
2.310 + along with this program; if not, write to the Free Software
2.311 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.312 +
2.313 +
2.314 +Also add information on how to contact you by electronic and paper mail.
2.315 +
2.316 +If the program is interactive, make it output a short notice like this
2.317 +when it starts in an interactive mode:
2.318 +
2.319 + Gnomovision version 69, Copyright (C) year name of author
2.320 + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
2.321 + This is free software, and you are welcome to redistribute it
2.322 + under certain conditions; type `show c' for details.
2.323 +
2.324 +The hypothetical commands `show w' and `show c' should show the appropriate
2.325 +parts of the General Public License. Of course, the commands you use may
2.326 +be called something other than `show w' and `show c'; they could even be
2.327 +mouse-clicks or menu items--whatever suits your program.
2.328 +
2.329 +You should also get your employer (if you work as a programmer) or your
2.330 +school, if any, to sign a "copyright disclaimer" for the program, if
2.331 +necessary. Here is a sample; alter the names:
2.332 +
2.333 + Yoyodyne, Inc., hereby disclaims all copyright interest in the program
2.334 + `Gnomovision' (which makes passes at compilers) written by James Hacker.
2.335 +
2.336 + <signature of Ty Coon>, 1 April 1989
2.337 + Ty Coon, President of Vice
2.338 +
2.339 +This General Public License does not permit incorporating your program into
2.340 +proprietary programs. If your program is a subroutine library, you may
2.341 +consider it more useful to permit linking proprietary applications with the
2.342 +library. If this is what you want to do, use the GNU Library General
2.343 +Public License instead of this License.
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/branches/gmyth-0.1b/ChangeLog Thu Feb 01 18:42:01 2007 +0000
3.3 @@ -0,0 +1,24 @@
3.4 +2006-08-17 Rosfran Borges <rosfran.borges@indt.org.br>
3.5 + * Added the correct gstreamer-base package (GSTBASE) at the configure.ac;
3.6 + GSTBASE_CFLAGS and GSTBASE_LIBS variables had the same values from
3.7 + the GST_CFLAGS/GST_LIBS.
3.8 +
3.9 +2006-08-16 Rosfran Borges <rosfran.borges@indt.org.br>
3.10 + * Fixed some installation issues, regarding lib-installing to the
3.11 + correct directory, and copying the header files to the destination
3.12 + dir (make install).
3.13 + * Put 'pkg-config' resource to the Maemo Myth library. The name of the
3.14 + PKG-CONFIG resource is 'maemo-myth', plus the minor and major version.
3.15 + Actually, the version is '0.1', so the library config file is:
3.16 + 'maemo-myth-0.1.pc'. You can type: 'pkg-config --cflags --libs
3.17 + maemo-myth-0.1'.
3.18 + * Many adjustments in the automake/autoconf configuration files
3.19 + (configure.ac, Makefile.am) - some autotools misusage fixed.
3.20 + * Added the MythURI structure, and the URI parsing utility functions
3.21 + (missing in the GLib).
3.22 + * Some functions were exported (myth_socket, gmyth_context), that's
3.23 + why many ther modules need to use them.
3.24 + * Fixed some library dependencies.
3.25 + * Prepared to be used inside the GStreamer (linking with the MythTV
3.26 + plug-in).
3.27 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/branches/gmyth-0.1b/INSTALL Thu Feb 01 18:42:01 2007 +0000
4.3 @@ -0,0 +1,229 @@
4.4 +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
4.5 +Foundation, Inc.
4.6 +
4.7 + This file is free documentation; the Free Software Foundation gives
4.8 +unlimited permission to copy, distribute and modify it.
4.9 +
4.10 +Basic Installation
4.11 +==================
4.12 +
4.13 + These are generic installation instructions.
4.14 +
4.15 + The `configure' shell script attempts to guess correct values for
4.16 +various system-dependent variables used during compilation. It uses
4.17 +those values to create a `Makefile' in each directory of the package.
4.18 +It may also create one or more `.h' files containing system-dependent
4.19 +definitions. Finally, it creates a shell script `config.status' that
4.20 +you can run in the future to recreate the current configuration, and a
4.21 +file `config.log' containing compiler output (useful mainly for
4.22 +debugging `configure').
4.23 +
4.24 + It can also use an optional file (typically called `config.cache'
4.25 +and enabled with `--cache-file=config.cache' or simply `-C') that saves
4.26 +the results of its tests to speed up reconfiguring. (Caching is
4.27 +disabled by default to prevent problems with accidental use of stale
4.28 +cache files.)
4.29 +
4.30 + If you need to do unusual things to compile the package, please try
4.31 +to figure out how `configure' could check whether to do them, and mail
4.32 +diffs or instructions to the address given in the `README' so they can
4.33 +be considered for the next release. If you are using the cache, and at
4.34 +some point `config.cache' contains results you don't want to keep, you
4.35 +may remove or edit it.
4.36 +
4.37 + The file `configure.ac' (or `configure.in') is used to create
4.38 +`configure' by a program called `autoconf'. You only need
4.39 +`configure.ac' if you want to change it or regenerate `configure' using
4.40 +a newer version of `autoconf'.
4.41 +
4.42 +The simplest way to compile this package is:
4.43 +
4.44 + 1. `cd' to the directory containing the package's source code and type
4.45 + `./configure' to configure the package for your system. If you're
4.46 + using `csh' on an old version of System V, you might need to type
4.47 + `sh ./configure' instead to prevent `csh' from trying to execute
4.48 + `configure' itself.
4.49 +
4.50 + Running `configure' takes awhile. While running, it prints some
4.51 + messages telling which features it is checking for.
4.52 +
4.53 + 2. Type `make' to compile the package.
4.54 +
4.55 + 3. Optionally, type `make check' to run any self-tests that come with
4.56 + the package.
4.57 +
4.58 + 4. Type `make install' to install the programs and any data files and
4.59 + documentation.
4.60 +
4.61 + 5. You can remove the program binaries and object files from the
4.62 + source code directory by typing `make clean'. To also remove the
4.63 + files that `configure' created (so you can compile the package for
4.64 + a different kind of computer), type `make distclean'. There is
4.65 + also a `make maintainer-clean' target, but that is intended mainly
4.66 + for the package's developers. If you use it, you may have to get
4.67 + all sorts of other programs in order to regenerate files that came
4.68 + with the distribution.
4.69 +
4.70 +Compilers and Options
4.71 +=====================
4.72 +
4.73 + Some systems require unusual options for compilation or linking that
4.74 +the `configure' script does not know about. Run `./configure --help'
4.75 +for details on some of the pertinent environment variables.
4.76 +
4.77 + You can give `configure' initial values for configuration parameters
4.78 +by setting variables in the command line or in the environment. Here
4.79 +is an example:
4.80 +
4.81 + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
4.82 +
4.83 + *Note Defining Variables::, for more details.
4.84 +
4.85 +Compiling For Multiple Architectures
4.86 +====================================
4.87 +
4.88 + You can compile the package for more than one kind of computer at the
4.89 +same time, by placing the object files for each architecture in their
4.90 +own directory. To do this, you must use a version of `make' that
4.91 +supports the `VPATH' variable, such as GNU `make'. `cd' to the
4.92 +directory where you want the object files and executables to go and run
4.93 +the `configure' script. `configure' automatically checks for the
4.94 +source code in the directory that `configure' is in and in `..'.
4.95 +
4.96 + If you have to use a `make' that does not support the `VPATH'
4.97 +variable, you have to compile the package for one architecture at a
4.98 +time in the source code directory. After you have installed the
4.99 +package for one architecture, use `make distclean' before reconfiguring
4.100 +for another architecture.
4.101 +
4.102 +Installation Names
4.103 +==================
4.104 +
4.105 + By default, `make install' will install the package's files in
4.106 +`/usr/local/bin', `/usr/local/man', etc. You can specify an
4.107 +installation prefix other than `/usr/local' by giving `configure' the
4.108 +option `--prefix=PATH'.
4.109 +
4.110 + You can specify separate installation prefixes for
4.111 +architecture-specific files and architecture-independent files. If you
4.112 +give `configure' the option `--exec-prefix=PATH', the package will use
4.113 +PATH as the prefix for installing programs and libraries.
4.114 +Documentation and other data files will still use the regular prefix.
4.115 +
4.116 + In addition, if you use an unusual directory layout you can give
4.117 +options like `--bindir=PATH' to specify different values for particular
4.118 +kinds of files. Run `configure --help' for a list of the directories
4.119 +you can set and what kinds of files go in them.
4.120 +
4.121 + If the package supports it, you can cause programs to be installed
4.122 +with an extra prefix or suffix on their names by giving `configure' the
4.123 +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
4.124 +
4.125 +Optional Features
4.126 +=================
4.127 +
4.128 + Some packages pay attention to `--enable-FEATURE' options to
4.129 +`configure', where FEATURE indicates an optional part of the package.
4.130 +They may also pay attention to `--with-PACKAGE' options, where PACKAGE
4.131 +is something like `gnu-as' or `x' (for the X Window System). The
4.132 +`README' should mention any `--enable-' and `--with-' options that the
4.133 +package recognizes.
4.134 +
4.135 + For packages that use the X Window System, `configure' can usually
4.136 +find the X include and library files automatically, but if it doesn't,
4.137 +you can use the `configure' options `--x-includes=DIR' and
4.138 +`--x-libraries=DIR' to specify their locations.
4.139 +
4.140 +Specifying the System Type
4.141 +==========================
4.142 +
4.143 + There may be some features `configure' cannot figure out
4.144 +automatically, but needs to determine by the type of machine the package
4.145 +will run on. Usually, assuming the package is built to be run on the
4.146 +_same_ architectures, `configure' can figure that out, but if it prints
4.147 +a message saying it cannot guess the machine type, give it the
4.148 +`--build=TYPE' option. TYPE can either be a short name for the system
4.149 +type, such as `sun4', or a canonical name which has the form:
4.150 +
4.151 + CPU-COMPANY-SYSTEM
4.152 +
4.153 +where SYSTEM can have one of these forms:
4.154 +
4.155 + OS KERNEL-OS
4.156 +
4.157 + See the file `config.sub' for the possible values of each field. If
4.158 +`config.sub' isn't included in this package, then this package doesn't
4.159 +need to know the machine type.
4.160 +
4.161 + If you are _building_ compiler tools for cross-compiling, you should
4.162 +use the `--target=TYPE' option to select the type of system they will
4.163 +produce code for.
4.164 +
4.165 + If you want to _use_ a cross compiler, that generates code for a
4.166 +platform different from the build platform, you should specify the
4.167 +"host" platform (i.e., that on which the generated programs will
4.168 +eventually be run) with `--host=TYPE'.
4.169 +
4.170 +Sharing Defaults
4.171 +================
4.172 +
4.173 + If you want to set default values for `configure' scripts to share,
4.174 +you can create a site shell script called `config.site' that gives
4.175 +default values for variables like `CC', `cache_file', and `prefix'.
4.176 +`configure' looks for `PREFIX/share/config.site' if it exists, then
4.177 +`PREFIX/etc/config.site' if it exists. Or, you can set the
4.178 +`CONFIG_SITE' environment variable to the location of the site script.
4.179 +A warning: not all `configure' scripts look for a site script.
4.180 +
4.181 +Defining Variables
4.182 +==================
4.183 +
4.184 + Variables not defined in a site shell script can be set in the
4.185 +environment passed to `configure'. However, some packages may run
4.186 +configure again during the build, and the customized values of these
4.187 +variables may be lost. In order to avoid this problem, you should set
4.188 +them in the `configure' command line, using `VAR=value'. For example:
4.189 +
4.190 + ./configure CC=/usr/local2/bin/gcc
4.191 +
4.192 +will cause the specified gcc to be used as the C compiler (unless it is
4.193 +overridden in the site shell script).
4.194 +
4.195 +`configure' Invocation
4.196 +======================
4.197 +
4.198 + `configure' recognizes the following options to control how it
4.199 +operates.
4.200 +
4.201 +`--help'
4.202 +`-h'
4.203 + Print a summary of the options to `configure', and exit.
4.204 +
4.205 +`--version'
4.206 +`-V'
4.207 + Print the version of Autoconf used to generate the `configure'
4.208 + script, and exit.
4.209 +
4.210 +`--cache-file=FILE'
4.211 + Enable the cache: use and save the results of the tests in FILE,
4.212 + traditionally `config.cache'. FILE defaults to `/dev/null' to
4.213 + disable caching.
4.214 +
4.215 +`--config-cache'
4.216 +`-C'
4.217 + Alias for `--cache-file=config.cache'.
4.218 +
4.219 +`--quiet'
4.220 +`--silent'
4.221 +`-q'
4.222 + Do not print messages saying which checks are being made. To
4.223 + suppress all normal output, redirect it to `/dev/null' (any error
4.224 + messages will still be shown).
4.225 +
4.226 +`--srcdir=DIR'
4.227 + Look for the package's source code in directory DIR. Usually
4.228 + `configure' can determine that directory automatically.
4.229 +
4.230 +`configure' also accepts some other, not widely useful, options. Run
4.231 +`configure --help' for more details.
4.232 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/branches/gmyth-0.1b/Makefile.am Thu Feb 01 18:42:01 2007 +0000
5.3 @@ -0,0 +1,23 @@
5.4 +SUBDIRS= src
5.5 +
5.6 +### all of the standard pc files we need to generate
5.7 +pcfiles = gmyth-@GMYTH_MAJORMINOR@.pc
5.8 +
5.9 +all-local: $(pcfiles)
5.10 +
5.11 +### how to generate pc files
5.12 +%-@GMYTH_MAJORMINOR@.pc: %.pc
5.13 + cp $< $@
5.14 +
5.15 +pkgconfigdir = $(libdir)/pkgconfig
5.16 +pkgconfig_DATA = $(pcfiles)
5.17 +
5.18 +include aminclude.am
5.19 +
5.20 +EXTRA_DIST = \
5.21 + autogen.sh \
5.22 + gmyth.pc.in \
5.23 + AUTHORS \
5.24 + COPYING \
5.25 + README
5.26 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/branches/gmyth-0.1b/aminclude.am Thu Feb 01 18:42:01 2007 +0000
6.3 @@ -0,0 +1,186 @@
6.4 +# Copyright (C) 2004 Oren Ben-Kiki
6.5 +# This file is distributed under the same terms as the Automake macro files.
6.6 +
6.7 +# Generate automatic documentation using Doxygen. Goals and variables values
6.8 +# are controlled by the various DX_COND_??? conditionals set by autoconf.
6.9 +#
6.10 +# The provided goals are:
6.11 +# doxygen-doc: Generate all doxygen documentation.
6.12 +# doxygen-run: Run doxygen, which will generate some of the documentation
6.13 +# (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post
6.14 +# processing required for the rest of it (PS, PDF, and some MAN).
6.15 +# doxygen-man: Rename some doxygen generated man pages.
6.16 +# doxygen-ps: Generate doxygen PostScript documentation.
6.17 +# doxygen-pdf: Generate doxygen PDF documentation.
6.18 +#
6.19 +# Note that by default these are not integrated into the automake goals. If
6.20 +# doxygen is used to generate man pages, you can achieve this integration by
6.21 +# setting man3_MANS to the list of man pages generated and then adding the
6.22 +# dependency:
6.23 +#
6.24 +# $(man3_MANS): doxygen-doc
6.25 +#
6.26 +# This will cause make to run doxygen and generate all the documentation.
6.27 +#
6.28 +# The following variable is intended for use in Makefile.am:
6.29 +#
6.30 +# DX_CLEANFILES = everything to clean.
6.31 +#
6.32 +# This is usually added to MOSTLYCLEANFILES.
6.33 +
6.34 +## --------------------------------- ##
6.35 +## Format-independent Doxygen rules. ##
6.36 +## --------------------------------- ##
6.37 +
6.38 +if DX_COND_doc
6.39 +
6.40 +## ------------------------------- ##
6.41 +## Rules specific for HTML output. ##
6.42 +## ------------------------------- ##
6.43 +
6.44 +if DX_COND_html
6.45 +
6.46 +DX_CLEAN_HTML = @DX_DOCDIR@/html
6.47 +
6.48 +endif DX_COND_html
6.49 +
6.50 +## ------------------------------ ##
6.51 +## Rules specific for CHM output. ##
6.52 +## ------------------------------ ##
6.53 +
6.54 +if DX_COND_chm
6.55 +
6.56 +DX_CLEAN_CHM = @DX_DOCDIR@/chm
6.57 +
6.58 +if DX_COND_chi
6.59 +
6.60 +DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
6.61 +
6.62 +endif DX_COND_chi
6.63 +
6.64 +endif DX_COND_chm
6.65 +
6.66 +## ------------------------------ ##
6.67 +## Rules specific for MAN output. ##
6.68 +## ------------------------------ ##
6.69 +
6.70 +if DX_COND_man
6.71 +
6.72 +DX_CLEAN_MAN = @DX_DOCDIR@/man
6.73 +
6.74 +endif DX_COND_man
6.75 +
6.76 +## ------------------------------ ##
6.77 +## Rules specific for RTF output. ##
6.78 +## ------------------------------ ##
6.79 +
6.80 +if DX_COND_rtf
6.81 +
6.82 +DX_CLEAN_RTF = @DX_DOCDIR@/rtf
6.83 +
6.84 +endif DX_COND_rtf
6.85 +
6.86 +## ------------------------------ ##
6.87 +## Rules specific for XML output. ##
6.88 +## ------------------------------ ##
6.89 +
6.90 +if DX_COND_xml
6.91 +
6.92 +DX_CLEAN_XML = @DX_DOCDIR@/xml
6.93 +
6.94 +endif DX_COND_xml
6.95 +
6.96 +## ----------------------------- ##
6.97 +## Rules specific for PS output. ##
6.98 +## ----------------------------- ##
6.99 +
6.100 +if DX_COND_ps
6.101 +
6.102 +DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
6.103 +
6.104 +DX_PS_GOAL = doxygen-ps
6.105 +
6.106 +doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
6.107 +
6.108 +@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
6.109 + cd @DX_DOCDIR@/latex; \
6.110 + rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
6.111 + $(DX_LATEX) refman.tex; \
6.112 + $(MAKEINDEX_PATH) refman.idx; \
6.113 + $(DX_LATEX) refman.tex; \
6.114 + countdown=5; \
6.115 + while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
6.116 + refman.log > /dev/null 2>&1 \
6.117 + && test $$countdown -gt 0; do \
6.118 + $(DX_LATEX) refman.tex; \
6.119 + countdown=`expr $$countdown - 1`; \
6.120 + done; \
6.121 + $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
6.122 +
6.123 +endif DX_COND_ps
6.124 +
6.125 +## ------------------------------ ##
6.126 +## Rules specific for PDF output. ##
6.127 +## ------------------------------ ##
6.128 +
6.129 +if DX_COND_pdf
6.130 +
6.131 +DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
6.132 +
6.133 +DX_PDF_GOAL = doxygen-pdf
6.134 +
6.135 +doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
6.136 +
6.137 +@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
6.138 + cd @DX_DOCDIR@/latex; \
6.139 + rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
6.140 + $(DX_PDFLATEX) refman.tex; \
6.141 + $(DX_MAKEINDEX) refman.idx; \
6.142 + $(DX_PDFLATEX) refman.tex; \
6.143 + countdown=5; \
6.144 + while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
6.145 + refman.log > /dev/null 2>&1 \
6.146 + && test $$countdown -gt 0; do \
6.147 + $(DX_PDFLATEX) refman.tex; \
6.148 + countdown=`expr $$countdown - 1`; \
6.149 + done; \
6.150 + mv refman.pdf ../@PACKAGE@.pdf
6.151 +
6.152 +endif DX_COND_pdf
6.153 +
6.154 +## ------------------------------------------------- ##
6.155 +## Rules specific for LaTeX (shared for PS and PDF). ##
6.156 +## ------------------------------------------------- ##
6.157 +
6.158 +if DX_COND_latex
6.159 +
6.160 +DX_CLEAN_LATEX = @DX_DOCDIR@/latex
6.161 +
6.162 +endif DX_COND_latex
6.163 +
6.164 +.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
6.165 +
6.166 +.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
6.167 +
6.168 +doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
6.169 +
6.170 +doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
6.171 +
6.172 +@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
6.173 + rm -rf @DX_DOCDIR@
6.174 + $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
6.175 +
6.176 +DX_CLEANFILES = \
6.177 + @DX_DOCDIR@/@PACKAGE@.tag \
6.178 + -r \
6.179 + $(DX_CLEAN_HTML) \
6.180 + $(DX_CLEAN_CHM) \
6.181 + $(DX_CLEAN_CHI) \
6.182 + $(DX_CLEAN_MAN) \
6.183 + $(DX_CLEAN_RTF) \
6.184 + $(DX_CLEAN_XML) \
6.185 + $(DX_CLEAN_PS) \
6.186 + $(DX_CLEAN_PDF) \
6.187 + $(DX_CLEAN_LATEX)
6.188 +
6.189 +endif DX_COND_doc
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/branches/gmyth-0.1b/autogen.sh Thu Feb 01 18:42:01 2007 +0000
7.3 @@ -0,0 +1,102 @@
7.4 +#!/bin/sh
7.5 +# Run this to generate all the initial makefiles, etc.
7.6 +
7.7 +DIE=0
7.8 +package=gmyth
7.9 +srcfile=configure.ac
7.10 +
7.11 +# a quick cvs co if necessary to alleviate the pain - may remove this
7.12 +# when developers get a clue ;)
7.13 +if test ! -d common;
7.14 +then
7.15 + echo "+ getting common/ from svn"
7.16 + svn co common
7.17 +fi
7.18 +
7.19 +# source helper functions
7.20 +if test ! -f common/autogen-helper.sh;
7.21 +then
7.22 + echo There is something wrong with your source tree.
7.23 + echo You are missing common/autogen-helper.sh
7.24 + exit 1
7.25 +fi
7.26 +. common/autogen-helper.sh
7.27 +
7.28 +CONFIGURE_DEF_OPT='--enable-maintainer-mode'
7.29 +# uncomment below to disable the UPnP features
7.30 +CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --disable-upnp"
7.31 +CONFIGURE_EXT_OPT="$@"
7.32 +
7.33 +autogen_options
7.34 +
7.35 +echo -n "+ check for build tools"
7.36 +if test ! -z "$NOCHECK"; then echo " skipped"; else echo; fi
7.37 +version_check "autoconf" "$AUTOCONF autoconf autoconf-2.54 autoconf-2.53" \
7.38 + "ftp://ftp.gnu.org/pub/gnu/autoconf/" 2 53 || DIE=1
7.39 +version_check "automake" "$AUTOMAKE automake automake-1.9 automake-1.8 automake-1.7 automake-1.6" \
7.40 + "ftp://ftp.gnu.org/pub/gnu/automake/" 1 6 || DIE=1
7.41 +version_check "libtoolize" "$LIBTOOLIZE libtoolize" \
7.42 + "ftp://ftp.gnu.org/pub/gnu/libtool/" 1 5 0 || DIE=1
7.43 +version_check "pkg-config" "" \
7.44 + "http://www.freedesktop.org/software/pkgconfig" 0 8 0 || DIE=1
7.45 +
7.46 +die_check $DIE
7.47 +
7.48 +aclocal_check || DIE=1
7.49 +autoheader_check || DIE=1
7.50 +
7.51 +die_check $DIE
7.52 +
7.53 +# if no arguments specified then this will be printed
7.54 +if test -z "$*"; then
7.55 + echo "+ checking for autogen.sh options"
7.56 + echo " This autogen script will automatically run ./configure as:"
7.57 + echo " ./configure $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT"
7.58 + echo " To pass any additional options, please specify them on the $0"
7.59 + echo " command line."
7.60 +fi
7.61 +
7.62 +toplevel_check $srcfile
7.63 +
7.64 +tool_run "$aclocal" "-I m4 $ACLOCAL_FLAGS"
7.65 +tool_run "$libtoolize" "--copy --force"
7.66 +tool_run "$autoheader"
7.67 +
7.68 +# touch the stamp-h.in build stamp so we don't re-run autoheader in maintainer mode -- wingo
7.69 +echo timestamp > stamp-h.in 2> /dev/null
7.70 +
7.71 +tool_run "$autoconf"
7.72 +tool_run "$automake" "-a -c"
7.73 +
7.74 +# if enable exists, add an -enable option for each of the lines in that file
7.75 +if test -f enable; then
7.76 + for a in `cat enable`; do
7.77 + CONFIGURE_FILE_OPT="--enable-$a"
7.78 + done
7.79 +fi
7.80 +
7.81 +# if disable exists, add an -disable option for each of the lines in that file
7.82 +if test -f disable; then
7.83 + for a in `cat disable`; do
7.84 + CONFIGURE_FILE_OPT="$CONFIGURE_FILE_OPT --disable-$a"
7.85 + done
7.86 +fi
7.87 +
7.88 +test -n "$NOCONFIGURE" && {
7.89 + echo "+ skipping configure stage for package $package, as requested."
7.90 + echo "+ autogen.sh done."
7.91 + exit 0
7.92 +}
7.93 +
7.94 +echo "+ running configure ... "
7.95 +test ! -z "$CONFIGURE_DEF_OPT" && echo " ./configure default flags: $CONFIGURE_DEF_OPT"
7.96 +test ! -z "$CONFIGURE_EXT_OPT" && echo " ./configure external flags: $CONFIGURE_EXT_OPT"
7.97 +test ! -z "$CONFIGURE_FILE_OPT" && echo " ./configure enable/disable flags: $CONFIGURE_FILE_OPT"
7.98 +echo
7.99 +
7.100 +./configure $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT $CONFIGURE_FILE_OPT || {
7.101 + echo " configure failed"
7.102 + exit 1
7.103 +}
7.104 +
7.105 +echo "Now type 'make' to compile $package."
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/branches/gmyth-0.1b/common/Makefile.am Thu Feb 01 18:42:01 2007 +0000
8.3 @@ -0,0 +1,1 @@
8.4 +EXTRA_DIST = autogen-helper.sh
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/branches/gmyth-0.1b/common/autogen-helper.sh Thu Feb 01 18:42:01 2007 +0000
9.3 @@ -0,0 +1,302 @@
9.4 +# a silly hack that generates autoregen.sh but it's handy
9.5 +echo "#!/bin/sh" > autoregen.sh
9.6 +echo "./autogen.sh $@ \$@" >> autoregen.sh
9.7 +chmod +x autoregen.sh
9.8 +
9.9 +# helper functions for autogen.sh
9.10 +
9.11 +debug ()
9.12 +# print out a debug message if DEBUG is a defined variable
9.13 +{
9.14 + if test ! -z "$DEBUG"
9.15 + then
9.16 + echo "DEBUG: $1"
9.17 + fi
9.18 +}
9.19 +
9.20 +version_check ()
9.21 +# check the version of a package
9.22 +# first argument : package name (executable)
9.23 +# second argument : optional path where to look for it instead
9.24 +# third argument : source download url
9.25 +# rest of arguments : major, minor, micro version
9.26 +# all consecutive ones : suggestions for binaries to use
9.27 +# (if not specified in second argument)
9.28 +{
9.29 + PACKAGE=$1
9.30 + PKG_PATH=$2
9.31 + URL=$3
9.32 + MAJOR=$4
9.33 + MINOR=$5
9.34 + MICRO=$6
9.35 +
9.36 + # for backwards compatibility, we let PKG_PATH=PACKAGE when PKG_PATH null
9.37 + if test -z "$PKG_PATH"; then PKG_PATH=$PACKAGE; fi
9.38 + debug "major $MAJOR minor $MINOR micro $MICRO"
9.39 + VERSION=$MAJOR
9.40 + if test ! -z "$MINOR"; then VERSION=$VERSION.$MINOR; else MINOR=0; fi
9.41 + if test ! -z "$MICRO"; then VERSION=$VERSION.$MICRO; else MICRO=0; fi
9.42 +
9.43 + debug "major $MAJOR minor $MINOR micro $MICRO"
9.44 +
9.45 + for SUGGESTION in $PKG_PATH; do
9.46 + COMMAND="$SUGGESTION"
9.47 +
9.48 + # don't check if asked not to
9.49 + test -z "$NOCHECK" && {
9.50 + echo -n " checking for $COMMAND >= $VERSION ... "
9.51 + } || {
9.52 + # we set a var with the same name as the package, but stripped of
9.53 + # unwanted chars
9.54 + VAR=`echo $PACKAGE | sed 's/-//g'`
9.55 + debug "setting $VAR"
9.56 + eval $VAR="$COMMAND"
9.57 + return 0
9.58 + }
9.59 +
9.60 + debug "checking version with $COMMAND"
9.61 + ($COMMAND --version) < /dev/null > /dev/null 2>&1 ||
9.62 + {
9.63 + echo "not found."
9.64 + continue
9.65 + }
9.66 + # strip everything that's not a digit, then use cut to get the first field
9.67 + pkg_version=`$COMMAND --version|head -n 1|sed 's/^[^0-9]*//'|cut -d' ' -f1`
9.68 + debug "pkg_version $pkg_version"
9.69 + # remove any non-digit characters from the version numbers to permit numeric
9.70 + # comparison
9.71 + pkg_major=`echo $pkg_version | cut -d. -f1 | sed s/[a-zA-Z\-].*//g`
9.72 + pkg_minor=`echo $pkg_version | cut -d. -f2 | sed s/[a-zA-Z\-].*//g`
9.73 + pkg_micro=`echo $pkg_version | cut -d. -f3 | sed s/[a-zA-Z\-].*//g`
9.74 + test -z "$pkg_major" && pkg_major=0
9.75 + test -z "$pkg_minor" && pkg_minor=0
9.76 + test -z "$pkg_micro" && pkg_micro=0
9.77 + debug "found major $pkg_major minor $pkg_minor micro $pkg_micro"
9.78 +
9.79 + #start checking the version
9.80 + debug "version check"
9.81 +
9.82 + # reset check
9.83 + WRONG=
9.84 +
9.85 + if [ ! "$pkg_major" -gt "$MAJOR" ]; then
9.86 + debug "major: $pkg_major <= $MAJOR"
9.87 + if [ "$pkg_major" -lt "$MAJOR" ]; then
9.88 + debug "major: $pkg_major < $MAJOR"
9.89 + WRONG=1
9.90 + elif [ ! "$pkg_minor" -gt "$MINOR" ]; then
9.91 + debug "minor: $pkg_minor <= $MINOR"
9.92 + if [ "$pkg_minor" -lt "$MINOR" ]; then
9.93 + debug "minor: $pkg_minor < $MINOR"
9.94 + WRONG=1
9.95 + elif [ "$pkg_micro" -lt "$MICRO" ]; then
9.96 + debug "micro: $pkg_micro < $MICRO"
9.97 + WRONG=1
9.98 + fi
9.99 + fi
9.100 + fi
9.101 +
9.102 + if test ! -z "$WRONG"; then
9.103 + echo "found $pkg_version, not ok !"
9.104 + continue
9.105 + else
9.106 + echo "found $pkg_version, ok."
9.107 + # we set a var with the same name as the package, but stripped of
9.108 + # unwanted chars
9.109 + VAR=`echo $PACKAGE | sed 's/-//g'`
9.110 + debug "setting $VAR"
9.111 + eval $VAR="$COMMAND"
9.112 + return 0
9.113 + fi
9.114 + done
9.115 +
9.116 + echo "not found !"
9.117 + echo "You must have $PACKAGE installed to compile $package."
9.118 + echo "Download the appropriate package for your distribution,"
9.119 + echo "or get the source tarball at $URL"
9.120 + return 1;
9.121 +}
9.122 +
9.123 +aclocal_check ()
9.124 +{
9.125 + # normally aclocal is part of automake
9.126 + # so we expect it to be in the same place as automake
9.127 + # so if a different automake is supplied, we need to adapt as well
9.128 + # so how's about replacing automake with aclocal in the set var,
9.129 + # and saving that in $aclocal ?
9.130 + # note, this will fail if the actual automake isn't called automake*
9.131 + # or if part of the path before it contains it
9.132 + if [ -z "$automake" ]; then
9.133 + echo "Error: no automake variable set !"
9.134 + return 1
9.135 + else
9.136 + aclocal=`echo $automake | sed s/automake/aclocal/`
9.137 + debug "aclocal: $aclocal"
9.138 + if [ "$aclocal" != "aclocal" ];
9.139 + then
9.140 + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-aclocal=$aclocal"
9.141 + fi
9.142 + if [ ! -x `which $aclocal` ]; then
9.143 + echo "Error: cannot execute $aclocal !"
9.144 + return 1
9.145 + fi
9.146 + fi
9.147 +}
9.148 +
9.149 +autoheader_check ()
9.150 +{
9.151 + # same here - autoheader is part of autoconf
9.152 + # use the same voodoo
9.153 + if [ -z "$autoconf" ]; then
9.154 + echo "Error: no autoconf variable set !"
9.155 + return 1
9.156 + else
9.157 + autoheader=`echo $autoconf | sed s/autoconf/autoheader/`
9.158 + debug "autoheader: $autoheader"
9.159 + if [ "$autoheader" != "autoheader" ];
9.160 + then
9.161 + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoheader=$autoheader"
9.162 + fi
9.163 + if [ ! -x `which $autoheader` ]; then
9.164 + echo "Error: cannot execute $autoheader !"
9.165 + return 1
9.166 + fi
9.167 + fi
9.168 +
9.169 +}
9.170 +
9.171 +autoconf_2_52d_check ()
9.172 +{
9.173 + # autoconf 2.52d has a weird issue involving a yes:no error
9.174 + # so don't allow it's use
9.175 + test -z "$NOCHECK" && {
9.176 + ac_version=`$autoconf --version|head -n 1|sed 's/^[a-zA-Z\.\ ()]*//;s/ .*$//'`
9.177 + if test "$ac_version" = "2.52d"; then
9.178 + echo "autoconf 2.52d has an issue with our current build."
9.179 + echo "We don't know who's to blame however. So until we do, get a"
9.180 + echo "regular version. RPM's of a working version are on the gstreamer site."
9.181 + exit 1
9.182 + fi
9.183 + }
9.184 + return 0
9.185 +}
9.186 +
9.187 +die_check ()
9.188 +{
9.189 + # call with $DIE
9.190 + # if set to 1, we need to print something helpful then die
9.191 + DIE=$1
9.192 + if test "x$DIE" = "x1";
9.193 + then
9.194 + echo
9.195 + echo "- Please get the right tools before proceeding."
9.196 + echo "- Alternatively, if you're sure we're wrong, run with --nocheck."
9.197 + exit 1
9.198 + fi
9.199 +}
9.200 +
9.201 +autogen_options ()
9.202 +{
9.203 + if test "x$1" = "x"; then
9.204 + return 0
9.205 + fi
9.206 +
9.207 + while test "x$1" != "x" ; do
9.208 + optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
9.209 + case "$1" in
9.210 + --noconfigure)
9.211 + NOCONFIGURE=defined
9.212 + AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --noconfigure"
9.213 + echo "+ configure run disabled"
9.214 + shift
9.215 + ;;
9.216 + --nocheck)
9.217 + AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --nocheck"
9.218 + NOCHECK=defined
9.219 + echo "+ autotools version check disabled"
9.220 + shift
9.221 + ;;
9.222 + --debug)
9.223 + DEBUG=defined
9.224 + AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --debug"
9.225 + echo "+ debug output enabled"
9.226 + shift
9.227 + ;;
9.228 + --prefix=*)
9.229 + CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$optarg"
9.230 + echo "+ passing --prefix=$optarg to configure"
9.231 + shift
9.232 + ;;
9.233 + --prefix)
9.234 + shift
9.235 + echo "DEBUG: $1"
9.236 + CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$1"
9.237 + echo "+ passing --prefix=$1 to configure"
9.238 + shift
9.239 + ;;
9.240 + -h|--help)
9.241 + echo "autogen.sh (autogen options) -- (configure options)"
9.242 + echo "autogen.sh help options: "
9.243 + echo " --noconfigure don't run the configure script"
9.244 + echo " --nocheck don't do version checks"
9.245 + echo " --debug debug the autogen process"
9.246 + echo " --prefix will be passed on to configure"
9.247 + echo
9.248 + echo " --with-autoconf PATH use autoconf in PATH"
9.249 + echo " --with-automake PATH use automake in PATH"
9.250 + echo
9.251 + echo "to pass options to configure, put them as arguments after -- "
9.252 + exit 1
9.253 + ;;
9.254 + --with-automake=*)
9.255 + AUTOMAKE=$optarg
9.256 + echo "+ using alternate automake in $optarg"
9.257 + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-automake=$AUTOMAKE"
9.258 + shift
9.259 + ;;
9.260 + --with-autoconf=*)
9.261 + AUTOCONF=$optarg
9.262 + echo "+ using alternate autoconf in $optarg"
9.263 + CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoconf=$AUTOCONF"
9.264 + shift
9.265 + ;;
9.266 + --disable*|--enable*|--with*)
9.267 + echo "+ passing option $1 to configure"
9.268 + CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $1"
9.269 + shift
9.270 + ;;
9.271 + --) shift ; break ;;
9.272 + *) echo "- ignoring unknown autogen.sh argument $1"; shift ;;
9.273 + esac
9.274 + done
9.275 +
9.276 + for arg do CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $arg"; done
9.277 + if test ! -z "$CONFIGURE_EXT_OPT"
9.278 + then
9.279 + echo "+ options passed to configure: $CONFIGURE_EXT_OPT"
9.280 + fi
9.281 +}
9.282 +
9.283 +toplevel_check ()
9.284 +{
9.285 + srcfile=$1
9.286 + test -f $srcfile || {
9.287 + echo "You must run this script in the top-level $package directory"
9.288 + exit 1
9.289 + }
9.290 +}
9.291 +
9.292 +
9.293 +tool_run ()
9.294 +{
9.295 + tool=$1
9.296 + options=$2
9.297 + run_if_fail=$3
9.298 + echo "+ running $tool $options..."
9.299 + $tool $options || {
9.300 + echo
9.301 + echo $tool failed
9.302 + eval $run_if_fail
9.303 + exit 1
9.304 + }
9.305 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/branches/gmyth-0.1b/configure.ac Thu Feb 01 18:42:01 2007 +0000
10.3 @@ -0,0 +1,182 @@
10.4 +# -*- Autoconf -*-
10.5 +# Process this file with autoconf to produce a configure script.
10.6 +
10.7 +AC_PREREQ(2.50)
10.8 +
10.9 +AC_INIT([gmyth],[0.1])
10.10 +
10.11 +dnl AC_CONFIG_SRCDIR([src/mmyth_main.c])
10.12 +AC_CONFIG_HEADER(config.h)
10.13 +
10.14 +dnl when going to/from release please set the nano (fourth number) right !
10.15 +dnl releases only do Wall, SVN and prerelease does Werror too
10.16 +AS_VERSION(gmyth, GMYTH, 0, 1, 0, 3, GMYTH_SVN="no", GMYTH_SVN="yes")
10.17 +GMYTH_MAJORMINOR=$GMYTH_MAJOR_VERSION.$GMYTH_MINOR_VERSION
10.18 +AC_SUBST(GMYTH_MAJORMINOR)
10.19 +
10.20 +dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode
10.21 +AM_MAINTAINER_MODE
10.22 +dnl make aclocal work in maintainer mode
10.23 +AC_SUBST(ACLOCAL_AMFLAGS, "-I m4")
10.24 +
10.25 +# Checks for programs.
10.26 +# check for tools
10.27 +# Make sure CFLAGS is defined to stop AC_PROC_CC adding -g
10.28 +CFLAGS="$CFLAGS -Wall"
10.29 +AC_PROG_CC
10.30 +AC_PROG_LIBTOOL
10.31 +
10.32 +dnl Generate doxygen documentation
10.33 +DX_HTML_FEATURE(ON)
10.34 +DX_CHM_FEATURE(OFF)
10.35 +DX_CHI_FEATURE(OFF)
10.36 +DX_MAN_FEATURE(OFF)
10.37 +DX_RTF_FEATURE(OFF)
10.38 +DX_XML_FEATURE(OFF)
10.39 +DX_PDF_FEATURE(OFF)
10.40 +DX_PS_FEATURE(OFF)
10.41 +DX_INIT_DOXYGEN(gmyth, doxygen.cfg, docs)
10.42 +
10.43 +# Checks for libraries.
10.44 +
10.45 +# Checks for header files.
10.46 +AC_HEADER_STDC
10.47 +AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h unistd.h])
10.48 +
10.49 +# Checks for typedefs, structures, and compiler characteristics.
10.50 +AC_C_CONST
10.51 +AC_TYPE_PID_T
10.52 +AC_STRUCT_TM
10.53 +AC_HEADER_TIME
10.54 +AC_HEADER_STDBOOL
10.55 +
10.56 +# Checks for library functions.
10.57 +AC_FUNC_FORK
10.58 +AC_FUNC_STRFTIME
10.59 +AC_FUNC_SELECT_ARGTYPES
10.60 +AC_PROG_GCC_TRADITIONAL
10.61 +AC_FUNC_MALLOC
10.62 +AC_FUNC_MKTIME
10.63 +AC_FUNC_STRFTIME
10.64 +AC_FUNC_VPRINTF
10.65 +AC_CHECK_FUNCS([memset socket stime strstr strtoul gethostname inet_ntoa localtime_r select strrchr localtime strptime])
10.66 +
10.67 +##############################
10.68 +# Checks for Network functions
10.69 +##############################
10.70 +
10.71 +AC_CHECK_FUNCS([socket])
10.72 +AC_CHECK_FUNCS([inet_ntoa])
10.73 +AC_CHECK_HEADERS([ifaddrs.h])
10.74 +AC_CHECK_FUNCS([getifaddrs])
10.75 +AC_CHECK_FUNCS([time])
10.76 +
10.77 +AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
10.78 +
10.79 +CFLAGS="$CFLAGS -I/usr/include"
10.80 +LDFLAGS="$LDFLAGS -L/usr/lib"
10.81 +
10.82 +# Checks required packages
10.83 +
10.84 +dnl Test if --disable-debug given
10.85 +AC_ARG_ENABLE(debug,
10.86 + AC_HELP_STRING([--disable-debug], [enable debugging mode]))
10.87 +if test x"$enable_debug" != xno; then
10.88 + CFLAGS="$CFLAGS -g -DGMYTH_USE_DEBUG"
10.89 +else
10.90 + CFLAGS="$CFLAGS -O2 -DG_DISABLE_CHECKS"
10.91 +fi
10.92 +
10.93 +# Check for pkgconfig
10.94 +AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, yes, no)
10.95 +# Give error and exit if we don't have pkgconfig
10.96 +if test "x$HAVE_PKGCONFIG" = "xno"; then
10.97 + AC_MSG_ERROR(you need to have pkgconfig installed !)
10.98 +fi
10.99 +
10.100 +# Check for Glib2.0
10.101 +PKG_CHECK_MODULES(GLIB, glib-2.0, HAVE_GLIB=yes,HAVE_GLIB=no)
10.102 +
10.103 +# Give error and exit if we don't have glib
10.104 +if test "x$HAVE_GLIB" = "xno"; then
10.105 + AC_MSG_ERROR(you need glib-2.0 installed)
10.106 +fi
10.107 +
10.108 +# make GLIB_CFLAGS and GLIB_LIBS available
10.109 +AC_SUBST(GLIB_CFLAGS)
10.110 +AC_SUBST(GLIB_LIBS)
10.111 +
10.112 +# Check for GObject2.0
10.113 +PKG_CHECK_MODULES(GOBJECT,
10.114 + gobject-2.0,
10.115 + HAVE_GOBJECT=yes, HAVE_GOBJECT=no)
10.116 +
10.117 +# Give error and exit if we don't have gobject
10.118 +if test "x$HAVE_GOBJECT" = "xno"; then
10.119 + AC_MSG_ERROR(you need gobject-2.0 installed)
10.120 +fi
10.121 +
10.122 +# make GOBJECT_CFLAGS and GOBJECT_LIBS available
10.123 +AC_SUBST(GOBJECT_CFLAGS)
10.124 +AC_SUBST(GOBJECT_LIBS)
10.125 +
10.126 +# Check for libxml-2.0
10.127 +PKG_CHECK_MODULES(LIBXML, libxml-2.0, HAVE_LIBXML=yes,HAVE_LIBXML=no)
10.128 +
10.129 +# Give error and exit if we don't have libxml
10.130 +if test "x$HAVE_LIBXML" = "xno"; then
10.131 + AC_MSG_ERROR(you need libxml-2.0 installed)
10.132 +fi
10.133 +
10.134 +# make LIBXML_CFLAGS and LIBXML_LIBS available
10.135 +AC_SUBST(LIBXML_CFLAGS)
10.136 +AC_SUBST(LIBXML_LIBS)
10.137 +
10.138 +# Check for libcurl
10.139 +PKG_CHECK_MODULES(LIBCURL, libcurl, HAVE_LIBCRUL=yes, HAVE_LIBCURL=no)
10.140 +
10.141 +# Give error and exit if we don't have libcurl
10.142 +if test "x$HAVE_LIBCURL" = "xno"; then
10.143 + AC_MSG_ERROR(you need libcurl installed)
10.144 +fi
10.145 +
10.146 +# make LIBCURL_CFLAGS and LIBCURL_LIBS available
10.147 +AC_SUBST(LIBCURL_CFLAGS)
10.148 +AC_SUBST(LIBCURL_LIBS)
10.149 +
10.150 +
10.151 +#
10.152 +# mysql libraries
10.153 +#
10.154 +AC_CHECK_PROG(MYSQL_CFLAGS,mysql_config,`mysql_config --cflags`)
10.155 +if test -z "$MYSQL_CFLAGS"; then
10.156 + AC_MSG_ERROR([Could not find mysql_config script. Make sure the mysql client libraries are installed])
10.157 +fi
10.158 +AC_SUBST(MYSQL_CFLAGS)
10.159 +
10.160 +
10.161 +AC_CHECK_PROG(MYSQL_LIBS,mysql_config,`mysql_config --libs`)
10.162 +if test -z "$MYSQL_LIBS"; then
10.163 + AC_MSG_ERROR([Could not find mysql_config script. Make sure the mysql client libraries are installed])
10.164 +fi
10.165 +AC_SUBST(MYSQL_LIBS)
10.166 +
10.167 +#dnl Enable gtk-doc
10.168 +#GTK_DOC_CHECK(1.4)
10.169 +
10.170 +AC_SUBST(CFLAGS)
10.171 +AC_SUBST(LDFLAGS)
10.172 +AC_SUBST(LIBS)
10.173 +
10.174 +AC_OUTPUT([
10.175 +Makefile
10.176 +src/Makefile
10.177 +tests/Makefile
10.178 +gmyth.pc])
10.179 +
10.180 +if test "x$enable_debug" != "xno"; then
10.181 + AC_MSG_NOTICE([Debug: Enabled])
10.182 +else
10.183 + AC_MSG_NOTICE([Debug: Disabled])
10.184 +fi
10.185 +
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/branches/gmyth-0.1b/data/settings/history.dat Thu Feb 01 18:42:01 2007 +0000
11.3 @@ -0,0 +1,3 @@
11.4 +# MIPTV history file
11.5 +# Stores the last network frequency used
11.6 +602000000
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/branches/gmyth-0.1b/debian/changelog Thu Feb 01 18:42:01 2007 +0000
12.3 @@ -0,0 +1,6 @@
12.4 +gmyth (0.1-indt1) unstable; urgency=low
12.5 +
12.6 + * Initial Maemo Package.
12.7 +
12.8 + -- Hallyson Melo <hallyson.melo@indt.org.br> Fri, 15 Sep 2006 10:26:16 -0300
12.9 +
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/branches/gmyth-0.1b/debian/compat Thu Feb 01 18:42:01 2007 +0000
13.3 @@ -0,0 +1,1 @@
13.4 +4
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/branches/gmyth-0.1b/debian/control Thu Feb 01 18:42:01 2007 +0000
14.3 @@ -0,0 +1,19 @@
14.4 +Source: gmyth
14.5 +Priority: optional
14.6 +Maintainer: Hallyson Melo <hallyson.melo@indt.org.br>
14.7 +Build-Depends: debhelper (>= 4.0.0)
14.8 +Standards-Version: 3.6.2
14.9 +Section: libs
14.10 +
14.11 +Package: gmyth
14.12 +Section: libs
14.13 +Architecture: any
14.14 +Depends: ${shlibs:Depends}, ${misc:Depends}, libcurl3
14.15 +Description: The gmyth library binary files. GMyth is a library intended to access mythtv backend functionalities from a glib/gobject perspective. It includes access to the program guide, recorded programs, scheduling, etc.
14.16 +
14.17 +Package: gmyth-dev
14.18 +Section: libdevel
14.19 +Architecture: any
14.20 +Depends: gmyth (= ${Source-Version}), libcurl3, libcurl3-openssl-dev
14.21 +Description: The gmyth library development files. GMyth is a library intended to access mythtv backend functionalities from a glib/gobject perspective. It includes access to the program guide, recorded programs, scheduling, etc.
14.22 +
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/branches/gmyth-0.1b/debian/gmyth-dev.install Thu Feb 01 18:42:01 2007 +0000
15.3 @@ -0,0 +1,6 @@
15.4 +debian/tmp/usr/include/*
15.5 +debian/tmp/usr/lib/lib*.a
15.6 +debian/tmp/usr/lib/lib*.so
15.7 +debian/tmp/usr/lib/pkgconfig/*
15.8 +debian/tmp/usr/lib/*.la
15.9 +debian/tmp/usr/share/pkgconfig/*
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/branches/gmyth-0.1b/debian/gmyth.install Thu Feb 01 18:42:01 2007 +0000
16.3 @@ -0,0 +1,1 @@
16.4 +debian/tmp/usr/lib/lib*.so.*
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/branches/gmyth-0.1b/debian/rules Thu Feb 01 18:42:01 2007 +0000
17.3 @@ -0,0 +1,20 @@
17.4 +#!/usr/bin/make -f
17.5 +
17.6 +include /usr/share/cdbs/1/rules/debhelper.mk
17.7 +include /usr/share/cdbs/1/class/autotools.mk
17.8 +include /usr/share/cdbs/1/rules/simple-patchsys.mk
17.9 +include /usr/share/cdbs/1/rules/utils.mk
17.10 +
17.11 +# debian package version
17.12 +version=$(shell dpkg-parsechangelog | grep ^Version: | cut -d ' ' -f 2)
17.13 +
17.14 +maint: debian/control
17.15 +
17.16 +common_conf_flags = \
17.17 + --disable-debug
17.18 +
17.19 +# FIXME: should disable docs for arch only builds
17.20 +DEB_CONFIGURE_EXTRA_FLAGS := $(common_conf_flags)
17.21 +
17.22 +
17.23 +.PHONY: maint
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/branches/gmyth-0.1b/doxygen.cfg Thu Feb 01 18:42:01 2007 +0000
18.3 @@ -0,0 +1,212 @@
18.4 +# Doxyfile 1.4.2
18.5 +
18.6 +#---------------------------------------------------------------------------
18.7 +# Project related configuration options
18.8 +#---------------------------------------------------------------------------
18.9 +PROJECT_NAME = $(PROJECT)-$(VERSION)
18.10 +PROJECT_NUMBER =
18.11 +OUTPUT_DIRECTORY = $(DOCDIR)
18.12 +CREATE_SUBDIRS = NO
18.13 +OUTPUT_LANGUAGE = English
18.14 +USE_WINDOWS_ENCODING = NO
18.15 +BRIEF_MEMBER_DESC = YES
18.16 +REPEAT_BRIEF = YES
18.17 +ABBREVIATE_BRIEF = YES
18.18 +ALWAYS_DETAILED_SEC = NO
18.19 +INLINE_INHERITED_MEMB = NO
18.20 +STRIP_FROM_INC_PATH = $(SRCDIR)/src/libgmyth
18.21 +FULL_PATH_NAMES = YES
18.22 +STRIP_FROM_PATH = $(SRCDIR)/src/libgmyth
18.23 +SHORT_NAMES = YES
18.24 +JAVADOC_AUTOBRIEF = YES
18.25 +MULTILINE_CPP_IS_BRIEF = NO
18.26 +DETAILS_AT_TOP = YES
18.27 +INHERIT_DOCS = YES
18.28 +DISTRIBUTE_GROUP_DOC = NO
18.29 +TAB_SIZE = 8
18.30 +ALIASES =
18.31 +OPTIMIZE_OUTPUT_FOR_C = YES
18.32 +OPTIMIZE_OUTPUT_JAVA = NO
18.33 +SUBGROUPING = YES
18.34 +#---------------------------------------------------------------------------
18.35 +# Build related configuration options
18.36 +#---------------------------------------------------------------------------
18.37 +EXTRACT_ALL = YES
18.38 +EXTRACT_PRIVATE = NO
18.39 +EXTRACT_STATIC = NO
18.40 +EXTRACT_LOCAL_CLASSES = YES
18.41 +EXTRACT_LOCAL_METHODS = YES
18.42 +HIDE_UNDOC_MEMBERS = NO
18.43 +HIDE_UNDOC_CLASSES = NO
18.44 +HIDE_FRIEND_COMPOUNDS = NO
18.45 +HIDE_IN_BODY_DOCS = NO
18.46 +INTERNAL_DOCS = NO
18.47 +CASE_SENSE_NAMES = NO
18.48 +HIDE_SCOPE_NAMES = NO
18.49 +SHOW_INCLUDE_FILES = YES
18.50 +INLINE_INFO = YES
18.51 +SORT_MEMBER_DOCS = YES
18.52 +SORT_BRIEF_DOCS = NO
18.53 +SORT_BY_SCOPE_NAME = NO
18.54 +GENERATE_TODOLIST = YES
18.55 +GENERATE_TESTLIST = YES
18.56 +GENERATE_BUGLIST = YES
18.57 +GENERATE_DEPRECATEDLIST= YES
18.58 +ENABLED_SECTIONS =
18.59 +MAX_INITIALIZER_LINES = 30
18.60 +SHOW_USED_FILES = YES
18.61 +#---------------------------------------------------------------------------
18.62 +# configuration options related to warning and progress messages
18.63 +#---------------------------------------------------------------------------
18.64 +QUIET = YES
18.65 +WARNINGS = YES
18.66 +WARN_IF_UNDOCUMENTED = YES
18.67 +WARN_IF_DOC_ERROR = YES
18.68 +WARN_FORMAT = "$file:$line: $text"
18.69 +WARN_LOGFILE =
18.70 +#---------------------------------------------------------------------------
18.71 +# configuration options related to the input files
18.72 +#---------------------------------------------------------------------------
18.73 +INPUT = $(SRCDIR)/src/libgmyth
18.74 +FILE_PATTERNS = *.c *.h
18.75 +RECURSIVE = YES
18.76 +EXCLUDE =
18.77 +EXCLUDE_SYMLINKS = NO
18.78 +EXCLUDE_PATTERNS =
18.79 +EXAMPLE_PATH = $(SRCDIR)/src/gui
18.80 +EXAMPLE_PATTERNS =
18.81 +EXAMPLE_RECURSIVE = NO
18.82 +IMAGE_PATH =
18.83 +INPUT_FILTER =
18.84 +FILTER_SOURCE_FILES = NO
18.85 +#---------------------------------------------------------------------------
18.86 +# configuration options related to source browsing
18.87 +#---------------------------------------------------------------------------
18.88 +SOURCE_BROWSER = YES
18.89 +INLINE_SOURCES = NO
18.90 +STRIP_CODE_COMMENTS = YES
18.91 +REFERENCED_BY_RELATION = YES
18.92 +REFERENCES_RELATION = YES
18.93 +VERBATIM_HEADERS = YES
18.94 +#---------------------------------------------------------------------------
18.95 +# configuration options related to the alphabetical class index
18.96 +#---------------------------------------------------------------------------
18.97 +ALPHABETICAL_INDEX = NO
18.98 +COLS_IN_ALPHA_INDEX = 5
18.99 +IGNORE_PREFIX =
18.100 +#---------------------------------------------------------------------------
18.101 +# configuration options related to the HTML output
18.102 +#---------------------------------------------------------------------------
18.103 +GENERATE_HTML = $(GENERATE_HTML)
18.104 +HTML_OUTPUT = html
18.105 +HTML_FILE_EXTENSION = .html
18.106 +HTML_HEADER =
18.107 +HTML_FOOTER =
18.108 +HTML_STYLESHEET =
18.109 +HTML_ALIGN_MEMBERS = YES
18.110 +GENERATE_HTMLHELP = $(GENERATE_CHM)
18.111 +CHM_FILE = ../$(PROJECT).chm
18.112 +HHC_LOCATION = $(HHC_PATH)
18.113 +GENERATE_CHI = $(GENERATE_CHI)
18.114 +BINARY_TOC = YES
18.115 +TOC_EXPAND = YES
18.116 +DISABLE_INDEX = NO
18.117 +ENUM_VALUES_PER_LINE = 4
18.118 +GENERATE_TREEVIEW = YES
18.119 +TREEVIEW_WIDTH = 250
18.120 +#---------------------------------------------------------------------------
18.121 +# configuration options related to the LaTeX output
18.122 +#---------------------------------------------------------------------------
18.123 +GENERATE_LATEX = $(GENERATE_LATEX)
18.124 +LATEX_OUTPUT = latex
18.125 +LATEX_CMD_NAME = latex
18.126 +MAKEINDEX_CMD_NAME = makeindex
18.127 +COMPACT_LATEX = NO
18.128 +PAPER_TYPE = $(PAPER_SIZE)
18.129 +EXTRA_PACKAGES =
18.130 +LATEX_HEADER =
18.131 +PDF_HYPERLINKS = NO
18.132 +USE_PDFLATEX = NO
18.133 +LATEX_BATCHMODE = YES
18.134 +LATEX_HIDE_INDICES = NO
18.135 +#---------------------------------------------------------------------------
18.136 +# configuration options related to the RTF output
18.137 +#---------------------------------------------------------------------------
18.138 +GENERATE_RTF = $(GENERATE_RTF)
18.139 +RTF_OUTPUT = rtf
18.140 +COMPACT_RTF = NO
18.141 +RTF_HYPERLINKS = NO
18.142 +RTF_STYLESHEET_FILE =
18.143 +RTF_EXTENSIONS_FILE =
18.144 +#---------------------------------------------------------------------------
18.145 +# configuration options related to the man page output
18.146 +#---------------------------------------------------------------------------
18.147 +GENERATE_MAN = $(GENERATE_MAN)
18.148 +MAN_OUTPUT = man
18.149 +MAN_EXTENSION = .1
18.150 +MAN_LINKS = NO
18.151 +#---------------------------------------------------------------------------
18.152 +# configuration options related to the XML output
18.153 +#---------------------------------------------------------------------------
18.154 +GENERATE_XML = $(GENERATE_XML)
18.155 +XML_OUTPUT = xml
18.156 +XML_SCHEMA =
18.157 +XML_DTD =
18.158 +XML_PROGRAMLISTING = YES
18.159 +#---------------------------------------------------------------------------
18.160 +# configuration options for the AutoGen Definitions output
18.161 +#---------------------------------------------------------------------------
18.162 +GENERATE_AUTOGEN_DEF = NO
18.163 +#---------------------------------------------------------------------------
18.164 +# configuration options related to the Perl module output
18.165 +#---------------------------------------------------------------------------
18.166 +GENERATE_PERLMOD = NO
18.167 +PERLMOD_LATEX = NO
18.168 +PERLMOD_PRETTY = YES
18.169 +PERLMOD_MAKEVAR_PREFIX =
18.170 +#---------------------------------------------------------------------------
18.171 +# Configuration options related to the preprocessor
18.172 +#---------------------------------------------------------------------------
18.173 +ENABLE_PREPROCESSING = YES
18.174 +MACRO_EXPANSION = NO
18.175 +EXPAND_ONLY_PREDEF = NO
18.176 +SEARCH_INCLUDES = YES
18.177 +INCLUDE_PATH =
18.178 +INCLUDE_FILE_PATTERNS =
18.179 +PREDEFINED =
18.180 +EXPAND_AS_DEFINED =
18.181 +SKIP_FUNCTION_MACROS = YES
18.182 +#---------------------------------------------------------------------------
18.183 +# Configuration::additions related to external references
18.184 +#---------------------------------------------------------------------------
18.185 +TAGFILES =
18.186 +GENERATE_TAGFILE = $(DOCDIR)/$(PROJECT).tag
18.187 +ALLEXTERNALS = NO
18.188 +EXTERNAL_GROUPS = YES
18.189 +PERL_PATH = $(PERL_PATH)
18.190 +#---------------------------------------------------------------------------
18.191 +# Configuration options related to the dot tool
18.192 +#---------------------------------------------------------------------------
18.193 +CLASS_DIAGRAMS = YES
18.194 +HIDE_UNDOC_RELATIONS = YES
18.195 +HAVE_DOT = $(HAVE_DOT)
18.196 +CLASS_GRAPH = YES
18.197 +COLLABORATION_GRAPH = YES
18.198 +UML_LOOK = NO
18.199 +TEMPLATE_RELATIONS = NO
18.200 +INCLUDE_GRAPH = YES
18.201 +INCLUDED_BY_GRAPH = YES
18.202 +CALL_GRAPH = NO
18.203 +GRAPHICAL_HIERARCHY = YES
18.204 +DOT_IMAGE_FORMAT = png
18.205 +DOT_PATH = $(DOT_PATH)
18.206 +DOTFILE_DIRS =
18.207 +MAX_DOT_GRAPH_WIDTH = 1024
18.208 +MAX_DOT_GRAPH_HEIGHT = 1024
18.209 +MAX_DOT_GRAPH_DEPTH = 0
18.210 +GENERATE_LEGEND = YES
18.211 +DOT_CLEANUP = YES
18.212 +#---------------------------------------------------------------------------
18.213 +# Configuration::additions related to the search engine
18.214 +#---------------------------------------------------------------------------
18.215 +SEARCHENGINE = NO
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/branches/gmyth-0.1b/gmyth.pc.in Thu Feb 01 18:42:01 2007 +0000
19.3 @@ -0,0 +1,12 @@
19.4 +prefix=@prefix@
19.5 +exec_prefix=@exec_prefix@
19.6 +libdir=@libdir@
19.7 +includedir=@includedir@
19.8 +
19.9 +Name: gmyth
19.10 +Description: Myth TV library based upon GLib/GObject paradigm
19.11 +Version: @VERSION@
19.12 +Requires: gobject-2.0 glib-2.0 libcurl
19.13 +
19.14 +Libs: @MYSQL_LIBS@ -L${libdir} -lgmyth -lcurl
19.15 +Cflags: -I${includedir}/gmyth
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/branches/gmyth-0.1b/m4/AUTHORS Thu Feb 01 18:42:01 2007 +0000
20.3 @@ -0,0 +1,4 @@
20.4 +Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
20.5 +Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
20.6 +Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
20.7 +Rosfran Lins Borges <rosfran.borges@indt.org.br>
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/branches/gmyth-0.1b/m4/COPYING Thu Feb 01 18:42:01 2007 +0000
21.3 @@ -0,0 +1,504 @@
21.4 + GNU LESSER GENERAL PUBLIC LICENSE
21.5 + Version 2.1, February 1999
21.6 +
21.7 + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
21.8 + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21.9 + Everyone is permitted to copy and distribute verbatim copies
21.10 + of this license document, but changing it is not allowed.
21.11 +
21.12 +[This is the first released version of the Lesser GPL. It also counts
21.13 + as the successor of the GNU Library Public License, version 2, hence
21.14 + the version number 2.1.]
21.15 +
21.16 + Preamble
21.17 +
21.18 + The licenses for most software are designed to take away your
21.19 +freedom to share and change it. By contrast, the GNU General Public
21.20 +Licenses are intended to guarantee your freedom to share and change
21.21 +free software--to make sure the software is free for all its users.
21.22 +
21.23 + This license, the Lesser General Public License, applies to some
21.24 +specially designated software packages--typically libraries--of the
21.25 +Free Software Foundation and other authors who decide to use it. You
21.26 +can use it too, but we suggest you first think carefully about whether
21.27 +this license or the ordinary General Public License is the better
21.28 +strategy to use in any particular case, based on the explanations below.
21.29 +
21.30 + When we speak of free software, we are referring to freedom of use,
21.31 +not price. Our General Public Licenses are designed to make sure that
21.32 +you have the freedom to distribute copies of free software (and charge
21.33 +for this service if you wish); that you receive source code or can get
21.34 +it if you want it; that you can change the software and use pieces of
21.35 +it in new free programs; and that you are informed that you can do
21.36 +these things.
21.37 +
21.38 + To protect your rights, we need to make restrictions that forbid
21.39 +distributors to deny you these rights or to ask you to surrender these
21.40 +rights. These restrictions translate to certain responsibilities for
21.41 +you if you distribute copies of the library or if you modify it.
21.42 +
21.43 + For example, if you distribute copies of the library, whether gratis
21.44 +or for a fee, you must give the recipients all the rights that we gave
21.45 +you. You must make sure that they, too, receive or can get the source
21.46 +code. If you link other code with the library, you must provide
21.47 +complete object files to the recipients, so that they can relink them
21.48 +with the library after making changes to the library and recompiling
21.49 +it. And you must show them these terms so they know their rights.
21.50 +
21.51 + We protect your rights with a two-step method: (1) we copyright the
21.52 +library, and (2) we offer you this license, which gives you legal
21.53 +permission to copy, distribute and/or modify the library.
21.54 +
21.55 + To protect each distributor, we want to make it very clear that
21.56 +there is no warranty for the free library. Also, if the library is
21.57 +modified by someone else and passed on, the recipients should know
21.58 +that what they have is not the original version, so that the original
21.59 +author's reputation will not be affected by problems that might be
21.60 +introduced by others.
21.61 +
21.62 + Finally, software patents pose a constant threat to the existence of
21.63 +any free program. We wish to make sure that a company cannot
21.64 +effectively restrict the users of a free program by obtaining a
21.65 +restrictive license from a patent holder. Therefore, we insist that
21.66 +any patent license obtained for a version of the library must be
21.67 +consistent with the full freedom of use specified in this license.
21.68 +
21.69 + Most GNU software, including some libraries, is covered by the
21.70 +ordinary GNU General Public License. This license, the GNU Lesser
21.71 +General Public License, applies to certain designated libraries, and
21.72 +is quite different from the ordinary General Public License. We use
21.73 +this license for certain libraries in order to permit linking those
21.74 +libraries into non-free programs.
21.75 +
21.76 + When a program is linked with a library, whether statically or using
21.77 +a shared library, the combination of the two is legally speaking a
21.78 +combined work, a derivative of the original library. The ordinary
21.79 +General Public License therefore permits such linking only if the
21.80 +entire combination fits its criteria of freedom. The Lesser General
21.81 +Public License permits more lax criteria for linking other code with
21.82 +the library.
21.83 +
21.84 + We call this license the "Lesser" General Public License because it
21.85 +does Less to protect the user's freedom than the ordinary General
21.86 +Public License. It also provides other free software developers Less
21.87 +of an advantage over competing non-free programs. These disadvantages
21.88 +are the reason we use the ordinary General Public License for many
21.89 +libraries. However, the Lesser license provides advantages in certain
21.90 +special circumstances.
21.91 +
21.92 + For example, on rare occasions, there may be a special need to
21.93 +encourage the widest possible use of a certain library, so that it becomes
21.94 +a de-facto standard. To achieve this, non-free programs must be
21.95 +allowed to use the library. A more frequent case is that a free
21.96 +library does the same job as widely used non-free libraries. In this
21.97 +case, there is little to gain by limiting the free library to free
21.98 +software only, so we use the Lesser General Public License.
21.99 +
21.100 + In other cases, permission to use a particular library in non-free
21.101 +programs enables a greater number of people to use a large body of
21.102 +free software. For example, permission to use the GNU C Library in
21.103 +non-free programs enables many more people to use the whole GNU
21.104 +operating system, as well as its variant, the GNU/Linux operating
21.105 +system.
21.106 +
21.107 + Although the Lesser General Public License is Less protective of the
21.108 +users' freedom, it does ensure that the user of a program that is
21.109 +linked with the Library has the freedom and the wherewithal to run
21.110 +that program using a modified version of the Library.
21.111 +
21.112 + The precise terms and conditions for copying, distribution and
21.113 +modification follow. Pay close attention to the difference between a
21.114 +"work based on the library" and a "work that uses the library". The
21.115 +former contains code derived from the library, whereas the latter must
21.116 +be combined with the library in order to run.
21.117 +
21.118 + GNU LESSER GENERAL PUBLIC LICENSE
21.119 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
21.120 +
21.121 + 0. This License Agreement applies to any software library or other
21.122 +program which contains a notice placed by the copyright holder or
21.123 +other authorized party saying it may be distributed under the terms of
21.124 +this Lesser General Public License (also called "this License").
21.125 +Each licensee is addressed as "you".
21.126 +
21.127 + A "library" means a collection of software functions and/or data
21.128 +prepared so as to be conveniently linked with application programs
21.129 +(which use some of those functions and data) to form executables.
21.130 +
21.131 + The "Library", below, refers to any such software library or work
21.132 +which has been distributed under these terms. A "work based on the
21.133 +Library" means either the Library or any derivative work under
21.134 +copyright law: that is to say, a work containing the Library or a
21.135 +portion of it, either verbatim or with modifications and/or translated
21.136 +straightforwardly into another language. (Hereinafter, translation is
21.137 +included without limitation in the term "modification".)
21.138 +
21.139 + "Source code" for a work means the preferred form of the work for
21.140 +making modifications to it. For a library, complete source code means
21.141 +all the source code for all modules it contains, plus any associated
21.142 +interface definition files, plus the scripts used to control compilation
21.143 +and installation of the library.
21.144 +
21.145 + Activities other than copying, distribution and modification are not
21.146 +covered by this License; they are outside its scope. The act of
21.147 +running a program using the Library is not restricted, and output from
21.148 +such a program is covered only if its contents constitute a work based
21.149 +on the Library (independent of the use of the Library in a tool for
21.150 +writing it). Whether that is true depends on what the Library does
21.151 +and what the program that uses the Library does.
21.152 +
21.153 + 1. You may copy and distribute verbatim copies of the Library's
21.154 +complete source code as you receive it, in any medium, provided that
21.155 +you conspicuously and appropriately publish on each copy an
21.156 +appropriate copyright notice and disclaimer of warranty; keep intact
21.157 +all the notices that refer to this License and to the absence of any
21.158 +warranty; and distribute a copy of this License along with the
21.159 +Library.
21.160 +
21.161 + You may charge a fee for the physical act of transferring a copy,
21.162 +and you may at your option offer warranty protection in exchange for a
21.163 +fee.
21.164 +
21.165 + 2. You may modify your copy or copies of the Library or any portion
21.166 +of it, thus forming a work based on the Library, and copy and
21.167 +distribute such modifications or work under the terms of Section 1
21.168 +above, provided that you also meet all of these conditions:
21.169 +
21.170 + a) The modified work must itself be a software library.
21.171 +
21.172 + b) You must cause the files modified to carry prominent notices
21.173 + stating that you changed the files and the date of any change.
21.174 +
21.175 + c) You must cause the whole of the work to be licensed at no
21.176 + charge to all third parties under the terms of this License.
21.177 +
21.178 + d) If a facility in the modified Library refers to a function or a
21.179 + table of data to be supplied by an application program that uses
21.180 + the facility, other than as an argument passed when the facility
21.181 + is invoked, then you must make a good faith effort to ensure that,
21.182 + in the event an application does not supply such function or
21.183 + table, the facility still operates, and performs whatever part of
21.184 + its purpose remains meaningful.
21.185 +
21.186 + (For example, a function in a library to compute square roots has
21.187 + a purpose that is entirely well-defined independent of the
21.188 + application. Therefore, Subsection 2d requires that any
21.189 + application-supplied function or table used by this function must
21.190 + be optional: if the application does not supply it, the square
21.191 + root function must still compute square roots.)
21.192 +
21.193 +These requirements apply to the modified work as a whole. If
21.194 +identifiable sections of that work are not derived from the Library,
21.195 +and can be reasonably considered independent and separate works in
21.196 +themselves, then this License, and its terms, do not apply to those
21.197 +sections when you distribute them as separate works. But when you
21.198 +distribute the same sections as part of a whole which is a work based
21.199 +on the Library, the distribution of the whole must be on the terms of
21.200 +this License, whose permissions for other licensees extend to the
21.201 +entire whole, and thus to each and every part regardless of who wrote
21.202 +it.
21.203 +
21.204 +Thus, it is not the intent of this section to claim rights or contest
21.205 +your rights to work written entirely by you; rather, the intent is to
21.206 +exercise the right to control the distribution of derivative or
21.207 +collective works based on the Library.
21.208 +
21.209 +In addition, mere aggregation of another work not based on the Library
21.210 +with the Library (or with a work based on the Library) on a volume of
21.211 +a storage or distribution medium does not bring the other work under
21.212 +the scope of this License.
21.213 +
21.214 + 3. You may opt to apply the terms of the ordinary GNU General Public
21.215 +License instead of this License to a given copy of the Library. To do
21.216 +this, you must alter all the notices that refer to this License, so
21.217 +that they refer to the ordinary GNU General Public License, version 2,
21.218 +instead of to this License. (If a newer version than version 2 of the
21.219 +ordinary GNU General Public License has appeared, then you can specify
21.220 +that version instead if you wish.) Do not make any other change in
21.221 +these notices.
21.222 +
21.223 + Once this change is made in a given copy, it is irreversible for
21.224 +that copy, so the ordinary GNU General Public License applies to all
21.225 +subsequent copies and derivative works made from that copy.
21.226 +
21.227 + This option is useful when you wish to copy part of the code of
21.228 +the Library into a program that is not a library.
21.229 +
21.230 + 4. You may copy and distribute the Library (or a portion or
21.231 +derivative of it, under Section 2) in object code or executable form
21.232 +under the terms of Sections 1 and 2 above provided that you accompany
21.233 +it with the complete corresponding machine-readable source code, which
21.234 +must be distributed under the terms of Sections 1 and 2 above on a
21.235 +medium customarily used for software interchange.
21.236 +
21.237 + If distribution of object code is made by offering access to copy
21.238 +from a designated place, then offering equivalent access to copy the
21.239 +source code from the same place satisfies the requirement to
21.240 +distribute the source code, even though third parties are not
21.241 +compelled to copy the source along with the object code.
21.242 +
21.243 + 5. A program that contains no derivative of any portion of the
21.244 +Library, but is designed to work with the Library by being compiled or
21.245 +linked with it, is called a "work that uses the Library". Such a
21.246 +work, in isolation, is not a derivative work of the Library, and
21.247 +therefore falls outside the scope of this License.
21.248 +
21.249 + However, linking a "work that uses the Library" with the Library
21.250 +creates an executable that is a derivative of the Library (because it
21.251 +contains portions of the Library), rather than a "work that uses the
21.252 +library". The executable is therefore covered by this License.
21.253 +Section 6 states terms for distribution of such executables.
21.254 +
21.255 + When a "work that uses the Library" uses material from a header file
21.256 +that is part of the Library, the object code for the work may be a
21.257 +derivative work of the Library even though the source code is not.
21.258 +Whether this is true is especially significant if the work can be
21.259 +linked without the Library, or if the work is itself a library. The
21.260 +threshold for this to be true is not precisely defined by law.
21.261 +
21.262 + If such an object file uses only numerical parameters, data
21.263 +structure layouts and accessors, and small macros and small inline
21.264 +functions (ten lines or less in length), then the use of the object
21.265 +file is unrestricted, regardless of whether it is legally a derivative
21.266 +work. (Executables containing this object code plus portions of the
21.267 +Library will still fall under Section 6.)
21.268 +
21.269 + Otherwise, if the work is a derivative of the Library, you may
21.270 +distribute the object code for the work under the terms of Section 6.
21.271 +Any executables containing that work also fall under Section 6,
21.272 +whether or not they are linked directly with the Library itself.
21.273 +
21.274 + 6. As an exception to the Sections above, you may also combine or
21.275 +link a "work that uses the Library" with the Library to produce a
21.276 +work containing portions of the Library, and distribute that work
21.277 +under terms of your choice, provided that the terms permit
21.278 +modification of the work for the customer's own use and reverse
21.279 +engineering for debugging such modifications.
21.280 +
21.281 + You must give prominent notice with each copy of the work that the
21.282 +Library is used in it and that the Library and its use are covered by
21.283 +this License. You must supply a copy of this License. If the work
21.284 +during execution displays copyright notices, you must include the
21.285 +copyright notice for the Library among them, as well as a reference
21.286 +directing the user to the copy of this License. Also, you must do one
21.287 +of these things:
21.288 +
21.289 + a) Accompany the work with the complete corresponding
21.290 + machine-readable source code for the Library including whatever
21.291 + changes were used in the work (which must be distributed under
21.292 + Sections 1 and 2 above); and, if the work is an executable linked
21.293 + with the Library, with the complete machine-readable "work that
21.294 + uses the Library", as object code and/or source code, so that the
21.295 + user can modify the Library and then relink to produce a modified
21.296 + executable containing the modified Library. (It is understood
21.297 + that the user who changes the contents of definitions files in the
21.298 + Library will not necessarily be able to recompile the application
21.299 + to use the modified definitions.)
21.300 +
21.301 + b) Use a suitable shared library mechanism for linking with the
21.302 + Library. A suitable mechanism is one that (1) uses at run time a
21.303 + copy of the library already present on the user's computer system,
21.304 + rather than copying library functions into the executable, and (2)
21.305 + will operate properly with a modified version of the library, if
21.306 + the user installs one, as long as the modified version is
21.307 + interface-compatible with the version that the work was made with.
21.308 +
21.309 + c) Accompany the work with a written offer, valid for at
21.310 + least three years, to give the same user the materials
21.311 + specified in Subsection 6a, above, for a charge no more
21.312 + than the cost of performing this distribution.
21.313 +
21.314 + d) If distribution of the work is made by offering access to copy
21.315 + from a designated place, offer equivalent access to copy the above
21.316 + specified materials from the same place.
21.317 +
21.318 + e) Verify that the user has already received a copy of these
21.319 + materials or that you have already sent this user a copy.
21.320 +
21.321 + For an executable, the required form of the "work that uses the
21.322 +Library" must include any data and utility programs needed for
21.323 +reproducing the executable from it. However, as a special exception,
21.324 +the materials to be distributed need not include anything that is
21.325 +normally distributed (in either source or binary form) with the major
21.326 +components (compiler, kernel, and so on) of the operating system on
21.327 +which the executable runs, unless that component itself accompanies
21.328 +the executable.
21.329 +
21.330 + It may happen that this requirement contradicts the license
21.331 +restrictions of other proprietary libraries that do not normally
21.332 +accompany the operating system. Such a contradiction means you cannot
21.333 +use both them and the Library together in an executable that you
21.334 +distribute.
21.335 +
21.336 + 7. You may place library facilities that are a work based on the
21.337 +Library side-by-side in a single library together with other library
21.338 +facilities not covered by this License, and distribute such a combined
21.339 +library, provided that the separate distribution of the work based on
21.340 +the Library and of the other library facilities is otherwise
21.341 +permitted, and provided that you do these two things:
21.342 +
21.343 + a) Accompany the combined library with a copy of the same work
21.344 + based on the Library, uncombined with any other library
21.345 + facilities. This must be distributed under the terms of the
21.346 + Sections above.
21.347 +
21.348 + b) Give prominent notice with the combined library of the fact
21.349 + that part of it is a work based on the Library, and explaining
21.350 + where to find the accompanying uncombined form of the same work.
21.351 +
21.352 + 8. You may not copy, modify, sublicense, link with, or distribute
21.353 +the Library except as expressly provided under this License. Any
21.354 +attempt otherwise to copy, modify, sublicense, link with, or
21.355 +distribute the Library is void, and will automatically terminate your
21.356 +rights under this License. However, parties who have received copies,
21.357 +or rights, from you under this License will not have their licenses
21.358 +terminated so long as such parties remain in full compliance.
21.359 +
21.360 + 9. You are not required to accept this License, since you have not
21.361 +signed it. However, nothing else grants you permission to modify or
21.362 +distribute the Library or its derivative works. These actions are
21.363 +prohibited by law if you do not accept this License. Therefore, by
21.364 +modifying or distributing the Library (or any work based on the
21.365 +Library), you indicate your acceptance of this License to do so, and
21.366 +all its terms and conditions for copying, distributing or modifying
21.367 +the Library or works based on it.
21.368 +
21.369 + 10. Each time you redistribute the Library (or any work based on the
21.370 +Library), the recipient automatically receives a license from the
21.371 +original licensor to copy, distribute, link with or modify the Library
21.372 +subject to these terms and conditions. You may not impose any further
21.373 +restrictions on the recipients' exercise of the rights granted herein.
21.374 +You are not responsible for enforcing compliance by third parties with
21.375 +this License.
21.376 +
21.377 + 11. If, as a consequence of a court judgment or allegation of patent
21.378 +infringement or for any other reason (not limited to patent issues),
21.379 +conditions are imposed on you (whether by court order, agreement or
21.380 +otherwise) that contradict the conditions of this License, they do not
21.381 +excuse you from the conditions of this License. If you cannot
21.382 +distribute so as to satisfy simultaneously your obligations under this
21.383 +License and any other pertinent obligations, then as a consequence you
21.384 +may not distribute the Library at all. For example, if a patent
21.385 +license would not permit royalty-free redistribution of the Library by
21.386 +all those who receive copies directly or indirectly through you, then
21.387 +the only way you could satisfy both it and this License would be to
21.388 +refrain entirely from distribution of the Library.
21.389 +
21.390 +If any portion of this section is held invalid or unenforceable under any
21.391 +particular circumstance, the balance of the section is intended to apply,
21.392 +and the section as a whole is intended to apply in other circumstances.
21.393 +
21.394 +It is not the purpose of this section to induce you to infringe any
21.395 +patents or other property right claims or to contest validity of any
21.396 +such claims; this section has the sole purpose of protecting the
21.397 +integrity of the free software distribution system which is
21.398 +implemented by public license practices. Many people have made
21.399 +generous contributions to the wide range of software distributed
21.400 +through that system in reliance on consistent application of that
21.401 +system; it is up to the author/donor to decide if he or she is willing
21.402 +to distribute software through any other system and a licensee cannot
21.403 +impose that choice.
21.404 +
21.405 +This section is intended to make thoroughly clear what is believed to
21.406 +be a consequence of the rest of this License.
21.407 +
21.408 + 12. If the distribution and/or use of the Library is restricted in
21.409 +certain countries either by patents or by copyrighted interfaces, the
21.410 +original copyright holder who places the Library under this License may add
21.411 +an explicit geographical distribution limitation excluding those countries,
21.412 +so that distribution is permitted only in or among countries not thus
21.413 +excluded. In such case, this License incorporates the limitation as if
21.414 +written in the body of this License.
21.415 +
21.416 + 13. The Free Software Foundation may publish revised and/or new
21.417 +versions of the Lesser General Public License from time to time.
21.418 +Such new versions will be similar in spirit to the present version,
21.419 +but may differ in detail to address new problems or concerns.
21.420 +
21.421 +Each version is given a distinguishing version number. If the Library
21.422 +specifies a version number of this License which applies to it and
21.423 +"any later version", you have the option of following the terms and
21.424 +conditions either of that version or of any later version published by
21.425 +the Free Software Foundation. If the Library does not specify a
21.426 +license version number, you may choose any version ever published by
21.427 +the Free Software Foundation.
21.428 +
21.429 + 14. If you wish to incorporate parts of the Library into other free
21.430 +programs whose distribution conditions are incompatible with these,
21.431 +write to the author to ask for permission. For software which is
21.432 +copyrighted by the Free Software Foundation, write to the Free
21.433 +Software Foundation; we sometimes make exceptions for this. Our
21.434 +decision will be guided by the two goals of preserving the free status
21.435 +of all derivatives of our free software and of promoting the sharing
21.436 +and reuse of software generally.
21.437 +
21.438 + NO WARRANTY
21.439 +
21.440 + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
21.441 +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
21.442 +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
21.443 +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
21.444 +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
21.445 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.446 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
21.447 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
21.448 +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
21.449 +
21.450 + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
21.451 +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
21.452 +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
21.453 +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
21.454 +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
21.455 +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
21.456 +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
21.457 +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
21.458 +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
21.459 +DAMAGES.
21.460 +
21.461 + END OF TERMS AND CONDITIONS
21.462 +
21.463 + How to Apply These Terms to Your New Libraries
21.464 +
21.465 + If you develop a new library, and you want it to be of the greatest
21.466 +possible use to the public, we recommend making it free software that
21.467 +everyone can redistribute and change. You can do so by permitting
21.468 +redistribution under these terms (or, alternatively, under the terms of the
21.469 +ordinary General Public License).
21.470 +
21.471 + To apply these terms, attach the following notices to the library. It is
21.472 +safest to attach them to the start of each source file to most effectively
21.473 +convey the exclusion of warranty; and each file should have at least the
21.474 +"copyright" line and a pointer to where the full notice is found.
21.475 +
21.476 + <one line to give the library's name and a brief idea of what it does.>
21.477 + Copyright (C) <year> <name of author>
21.478 +
21.479 + This library is free software; you can redistribute it and/or
21.480 + modify it under the terms of the GNU Lesser General Public
21.481 + License as published by the Free Software Foundation; either
21.482 + version 2.1 of the License, or (at your option) any later version.
21.483 +
21.484 + This library is distributed in the hope that it will be useful,
21.485 + but WITHOUT ANY WARRANTY; without even the implied warranty of
21.486 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21.487 + Lesser General Public License for more details.
21.488 +
21.489 + You should have received a copy of the GNU Lesser General Public
21.490 + License along with this library; if not, write to the Free Software
21.491 + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21.492 +
21.493 +Also add information on how to contact you by electronic and paper mail.
21.494 +
21.495 +You should also get your employer (if you work as a programmer) or your
21.496 +school, if any, to sign a "copyright disclaimer" for the library, if
21.497 +necessary. Here is a sample; alter the names:
21.498 +
21.499 + Yoyodyne, Inc., hereby disclaims all copyright interest in the
21.500 + library `Frob' (a library for tweaking knobs) written by James Random Hacker.
21.501 +
21.502 + <signature of Ty Coon>, 1 April 1990
21.503 + Ty Coon, President of Vice
21.504 +
21.505 +That's all there is to it!
21.506 +
21.507 +
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/branches/gmyth-0.1b/m4/ChangeLog Thu Feb 01 18:42:01 2007 +0000
22.3 @@ -0,0 +1,24 @@
22.4 +2006-08-17 Rosfran Borges <rosfran.borges@indt.org.br>
22.5 + * Added the correct gstreamer-base package (GSTBASE) at the configure.ac;
22.6 + GSTBASE_CFLAGS and GSTBASE_LIBS variables had the same values from
22.7 + the GST_CFLAGS/GST_LIBS.
22.8 +
22.9 +2006-08-16 Rosfran Borges <rosfran.borges@indt.org.br>
22.10 + * Fixed some installation issues, regarding lib-installing to the
22.11 + correct directory, and copying the header files to the destination
22.12 + dir (make install).
22.13 + * Put 'pkg-config' resource to the Maemo Myth library. The name of the
22.14 + PKG-CONFIG resource is 'maemo-myth', plus the minor and major version.
22.15 + Actually, the version is '0.1', so the library config file is:
22.16 + 'maemo-myth-0.1.pc'. You can type: 'pkg-config --cflags --libs
22.17 + maemo-myth-0.1'.
22.18 + * Many adjustments in the automake/autoconf configuration files
22.19 + (configure.ac, Makefile.am) - some autotools misusage fixed.
22.20 + * Added the MythURI structure, and the URI parsing utility functions
22.21 + (missing in the GLib).
22.22 + * Some functions were exported (myth_socket, mmyth_context), that's
22.23 + why many ther modules need to use them.
22.24 + * Fixed some library dependencies.
22.25 + * Prepared to be used inside the GStreamer (linking with the MythTV
22.26 + plug-in).
22.27 +
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/branches/gmyth-0.1b/m4/INSTALL Thu Feb 01 18:42:01 2007 +0000
23.3 @@ -0,0 +1,236 @@
23.4 +Installation Instructions
23.5 +*************************
23.6 +
23.7 +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
23.8 +Software Foundation, Inc.
23.9 +
23.10 +This file is free documentation; the Free Software Foundation gives
23.11 +unlimited permission to copy, distribute and modify it.
23.12 +
23.13 +Basic Installation
23.14 +==================
23.15 +
23.16 +These are generic installation instructions.
23.17 +
23.18 + The `configure' shell script attempts to guess correct values for
23.19 +various system-dependent variables used during compilation. It uses
23.20 +those values to create a `Makefile' in each directory of the package.
23.21 +It may also create one or more `.h' files containing system-dependent
23.22 +definitions. Finally, it creates a shell script `config.status' that
23.23 +you can run in the future to recreate the current configuration, and a
23.24 +file `config.log' containing compiler output (useful mainly for
23.25 +debugging `configure').
23.26 +
23.27 + It can also use an optional file (typically called `config.cache'
23.28 +and enabled with `--cache-file=config.cache' or simply `-C') that saves
23.29 +the results of its tests to speed up reconfiguring. (Caching is
23.30 +disabled by default to prevent problems with accidental use of stale
23.31 +cache files.)
23.32 +
23.33 + If you need to do unusual things to compile the package, please try
23.34 +to figure out how `configure' could check whether to do them, and mail
23.35 +diffs or instructions to the address given in the `README' so they can
23.36 +be considered for the next release. If you are using the cache, and at
23.37 +some point `config.cache' contains results you don't want to keep, you
23.38 +may remove or edit it.
23.39 +
23.40 + The file `configure.ac' (or `configure.in') is used to create
23.41 +`configure' by a program called `autoconf'. You only need
23.42 +`configure.ac' if you want to change it or regenerate `configure' using
23.43 +a newer version of `autoconf'.
23.44 +
23.45 +The simplest way to compile this package is:
23.46 +
23.47 + 1. `cd' to the directory containing the package's source code and type
23.48 + `./configure' to configure the package for your system. If you're
23.49 + using `csh' on an old version of System V, you might need to type
23.50 + `sh ./configure' instead to prevent `csh' from trying to execute
23.51 + `configure' itself.
23.52 +
23.53 + Running `configure' takes awhile. While running, it prints some
23.54 + messages telling which features it is checking for.
23.55 +
23.56 + 2. Type `make' to compile the package.
23.57 +
23.58 + 3. Optionally, type `make check' to run any self-tests that come with
23.59 + the package.
23.60 +
23.61 + 4. Type `make install' to install the programs and any data files and
23.62 + documentation.
23.63 +
23.64 + 5. You can remove the program binaries and object files from the
23.65 + source code directory by typing `make clean'. To also remove the
23.66 + files that `configure' created (so you can compile the package for
23.67 + a different kind of computer), type `make distclean'. There is
23.68 + also a `make maintainer-clean' target, but that is intended mainly
23.69 + for the package's developers. If you use it, you may have to get
23.70 + all sorts of other programs in order to regenerate files that came
23.71 + with the distribution.
23.72 +
23.73 +Compilers and Options
23.74 +=====================
23.75 +
23.76 +Some systems require unusual options for compilation or linking that the
23.77 +`configure' script does not know about. Run `./configure --help' for
23.78 +details on some of the pertinent environment variables.
23.79 +
23.80 + You can give `configure' initial values for configuration parameters
23.81 +by setting variables in the command line or in the environment. Here
23.82 +is an example:
23.83 +
23.84 + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
23.85 +
23.86 + *Note Defining Variables::, for more details.
23.87 +
23.88 +Compiling For Multiple Architectures
23.89 +====================================
23.90 +
23.91 +You can compile the package for more than one kind of computer at the
23.92 +same time, by placing the object files for each architecture in their
23.93 +own directory. To do this, you must use a version of `make' that
23.94 +supports the `VPATH' variable, such as GNU `make'. `cd' to the
23.95 +directory where you want the object files and executables to go and run
23.96 +the `configure' script. `configure' automatically checks for the
23.97 +source code in the directory that `configure' is in and in `..'.
23.98 +
23.99 + If you have to use a `make' that does not support the `VPATH'
23.100 +variable, you have to compile the package for one architecture at a
23.101 +time in the source code directory. After you have installed the
23.102 +package for one architecture, use `make distclean' before reconfiguring
23.103 +for another architecture.
23.104 +
23.105 +Installation Names
23.106 +==================
23.107 +
23.108 +By default, `make install' installs the package's commands under
23.109 +`/usr/local/bin', include files under `/usr/local/include', etc. You
23.110 +can specify an installation prefix other than `/usr/local' by giving
23.111 +`configure' the option `--prefix=PREFIX'.
23.112 +
23.113 + You can specify separate installation prefixes for
23.114 +architecture-specific files and architecture-independent files. If you
23.115 +pass the option `--exec-prefix=PREFIX' to `configure', the package uses
23.116 +PREFIX as the prefix for installing programs and libraries.
23.117 +Documentation and other data files still use the regular prefix.
23.118 +
23.119 + In addition, if you use an unusual directory layout you can give
23.120 +options like `--bindir=DIR' to specify different values for particular
23.121 +kinds of files. Run `configure --help' for a list of the directories
23.122 +you can set and what kinds of files go in them.
23.123 +
23.124 + If the package supports it, you can cause programs to be installed
23.125 +with an extra prefix or suffix on their names by giving `configure' the
23.126 +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
23.127 +
23.128 +Optional Features
23.129 +=================
23.130 +
23.131 +Some packages pay attention to `--enable-FEATURE' options to
23.132 +`configure', where FEATURE indicates an optional part of the package.
23.133 +They may also pay attention to `--with-PACKAGE' options, where PACKAGE
23.134 +is something like `gnu-as' or `x' (for the X Window System). The
23.135 +`README' should mention any `--enable-' and `--with-' options that the
23.136 +package recognizes.
23.137 +
23.138 + For packages that use the X Window System, `configure' can usually
23.139 +find the X include and library files automatically, but if it doesn't,
23.140 +you can use the `configure' options `--x-includes=DIR' and
23.141 +`--x-libraries=DIR' to specify their locations.
23.142 +
23.143 +Specifying the System Type
23.144 +==========================
23.145 +
23.146 +There may be some features `configure' cannot figure out automatically,
23.147 +but needs to determine by the type of machine the package will run on.
23.148 +Usually, assuming the package is built to be run on the _same_
23.149 +architectures, `configure' can figure that out, but if it prints a
23.150 +message saying it cannot guess the machine type, give it the
23.151 +`--build=TYPE' option. TYPE can either be a short name for the system
23.152 +type, such as `sun4', or a canonical name which has the form:
23.153 +
23.154 + CPU-COMPANY-SYSTEM
23.155 +
23.156 +where SYSTEM can have one of these forms:
23.157 +
23.158 + OS KERNEL-OS
23.159 +
23.160 + See the file `config.sub' for the possible values of each field. If
23.161 +`config.sub' isn't included in this package, then this package doesn't
23.162 +need to know the machine type.
23.163 +
23.164 + If you are _building_ compiler tools for cross-compiling, you should
23.165 +use the option `--target=TYPE' to select the type of system they will
23.166 +produce code for.
23.167 +
23.168 + If you want to _use_ a cross compiler, that generates code for a
23.169 +platform different from the build platform, you should specify the
23.170 +"host" platform (i.e., that on which the generated programs will
23.171 +eventually be run) with `--host=TYPE'.
23.172 +
23.173 +Sharing Defaults
23.174 +================
23.175 +
23.176 +If you want to set default values for `configure' scripts to share, you
23.177 +can create a site shell script called `config.site' that gives default
23.178 +values for variables like `CC', `cache_file', and `prefix'.
23.179 +`configure' looks for `PREFIX/share/config.site' if it exists, then
23.180 +`PREFIX/etc/config.site' if it exists. Or, you can set the
23.181 +`CONFIG_SITE' environment variable to the location of the site script.
23.182 +A warning: not all `configure' scripts look for a site script.
23.183 +
23.184 +Defining Variables
23.185 +==================
23.186 +
23.187 +Variables not defined in a site shell script can be set in the
23.188 +environment passed to `configure'. However, some packages may run
23.189 +configure again during the build, and the customized values of these
23.190 +variables may be lost. In order to avoid this problem, you should set
23.191 +them in the `configure' command line, using `VAR=value'. For example:
23.192 +
23.193 + ./configure CC=/usr/local2/bin/gcc
23.194 +
23.195 +causes the specified `gcc' to be used as the C compiler (unless it is
23.196 +overridden in the site shell script). Here is a another example:
23.197 +
23.198 + /bin/bash ./configure CONFIG_SHELL=/bin/bash
23.199 +
23.200 +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
23.201 +configuration-related scripts to be executed by `/bin/bash'.
23.202 +
23.203 +`configure' Invocation
23.204 +======================
23.205 +
23.206 +`configure' recognizes the following options to control how it operates.
23.207 +
23.208 +`--help'
23.209 +`-h'
23.210 + Print a summary of the options to `configure', and exit.
23.211 +
23.212 +`--version'
23.213 +`-V'
23.214 + Print the version of Autoconf used to generate the `configure'
23.215 + script, and exit.
23.216 +
23.217 +`--cache-file=FILE'
23.218 + Enable the cache: use and save the results of the tests in FILE,
23.219 + traditionally `config.cache'. FILE defaults to `/dev/null' to
23.220 + disable caching.
23.221 +
23.222 +`--config-cache'
23.223 +`-C'
23.224 + Alias for `--cache-file=config.cache'.
23.225 +
23.226 +`--quiet'
23.227 +`--silent'
23.228 +`-q'
23.229 + Do not print messages saying which checks are being made. To
23.230 + suppress all normal output, redirect it to `/dev/null' (any error
23.231 + messages will still be shown).
23.232 +
23.233 +`--srcdir=DIR'
23.234 + Look for the package's source code in directory DIR. Usually
23.235 + `configure' can determine that directory automatically.
23.236 +
23.237 +`configure' also accepts some other, not widely useful, options. Run
23.238 +`configure --help' for more details.
23.239 +
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/branches/gmyth-0.1b/m4/Makefile.am Thu Feb 01 18:42:01 2007 +0000
24.3 @@ -0,0 +1,10 @@
24.4 +SUBDIRS= src pixmaps
24.5 +
24.6 +include aminclude.am
24.7 +
24.8 +EXTRA_DIST = \
24.9 + autogen.sh \
24.10 + AUTHORS \
24.11 + COPYING \
24.12 + README
24.13 +
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/branches/gmyth-0.1b/m4/ac_doxygen.m4 Thu Feb 01 18:42:01 2007 +0000
25.3 @@ -0,0 +1,312 @@
25.4 +# This file is part of Autoconf. -*- Autoconf -*-
25.5 +
25.6 +# Copyright (C) 2004 Oren Ben-Kiki
25.7 +# This file is distributed under the same terms as the Autoconf macro files.
25.8 +
25.9 +# Generate automatic documentation using Doxygen. Works in concert with the
25.10 +# aminclude.m4 file and a compatible doxygen configuration file. Defines the
25.11 +# following public macros:
25.12 +#
25.13 +# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
25.14 +# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
25.15 +# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
25.16 +# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
25.17 +# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
25.18 +# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
25.19 +# paper size.
25.20 +#
25.21 +# By default, HTML, PDF and PS documentation is generated as this seems to be
25.22 +# the most popular and portable combination. MAN pages created by Doxygen are
25.23 +# usually problematic, though by picking an appropriate subset and doing some
25.24 +# massaging they might be better than nothing. CHM and RTF are specific for MS
25.25 +# (note that you can't generate both HTML and CHM at the same time). The XML is
25.26 +# rather useless unless you apply specialized post-processing to it.
25.27 +#
25.28 +# The macro mainly controls the default state of the feature. The use can
25.29 +# override the default by specifying --enable or --disable. The macros ensure
25.30 +# that contradictory flags are not given (e.g., --enable-doxygen-html and
25.31 +# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
25.32 +# Finally, each feature will be automatically disabled (with a warning) if the
25.33 +# required programs are missing.
25.34 +#
25.35 +# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
25.36 +# the following parameters: a one-word name for the project for use as a
25.37 +# filename base etc., an optional configuration file name (the default is
25.38 +# 'Doxyfile', the same as Doxygen's default), and an optional output directory
25.39 +# name (the default is 'doxygen-doc').
25.40 +
25.41 +## ----------##
25.42 +## Defaults. ##
25.43 +## ----------##
25.44 +
25.45 +DX_ENV=""
25.46 +AC_DEFUN([DX_FEATURE_doc], ON)
25.47 +AC_DEFUN([DX_FEATURE_dot], ON)
25.48 +AC_DEFUN([DX_FEATURE_man], OFF)
25.49 +AC_DEFUN([DX_FEATURE_html], ON)
25.50 +AC_DEFUN([DX_FEATURE_chm], OFF)
25.51 +AC_DEFUN([DX_FEATURE_chi], OFF)
25.52 +AC_DEFUN([DX_FEATURE_rtf], OFF)
25.53 +AC_DEFUN([DX_FEATURE_xml], OFF)
25.54 +AC_DEFUN([DX_FEATURE_pdf], ON)
25.55 +AC_DEFUN([DX_FEATURE_ps], ON)
25.56 +
25.57 +## --------------- ##
25.58 +## Private macros. ##
25.59 +## --------------- ##
25.60 +
25.61 +# DX_ENV_APPEND(VARIABLE, VALUE)
25.62 +# ------------------------------
25.63 +# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
25.64 +AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
25.65 +
25.66 +# DX_DIRNAME_EXPR
25.67 +# ---------------
25.68 +# Expand into a shell expression prints the directory part of a path.
25.69 +AC_DEFUN([DX_DIRNAME_EXPR],
25.70 + [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
25.71 +
25.72 +# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
25.73 +# -------------------------------------
25.74 +# Expands according to the M4 (static) status of the feature.
25.75 +AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
25.76 +
25.77 +# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
25.78 +# ----------------------------------
25.79 +# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
25.80 +AC_DEFUN([DX_REQUIRE_PROG], [
25.81 +AC_PATH_TOOL([$1], [$2])
25.82 +if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
25.83 + AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
25.84 + AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
25.85 +fi
25.86 +])
25.87 +
25.88 +# DX_TEST_FEATURE(FEATURE)
25.89 +# ------------------------
25.90 +# Expand to a shell expression testing whether the feature is active.
25.91 +AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
25.92 +
25.93 +# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
25.94 +# -------------------------------------------------
25.95 +# Verify that a required features has the right state before trying to turn on
25.96 +# the DX_CURRENT_FEATURE.
25.97 +AC_DEFUN([DX_CHECK_DEPEND], [
25.98 +test "$DX_FLAG_$1" = "$2" \
25.99 +|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
25.100 + requires, contradicts) doxygen-DX_CURRENT_FEATURE])
25.101 +])
25.102 +
25.103 +# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
25.104 +# ----------------------------------------------------------
25.105 +# Turn off the DX_CURRENT_FEATURE if the required feature is off.
25.106 +AC_DEFUN([DX_CLEAR_DEPEND], [
25.107 +test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
25.108 +])
25.109 +
25.110 +# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
25.111 +# CHECK_DEPEND, CLEAR_DEPEND,
25.112 +# REQUIRE, DO-IF-ON, DO-IF-OFF)
25.113 +# --------------------------------------------
25.114 +# Parse the command-line option controlling a feature. CHECK_DEPEND is called
25.115 +# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
25.116 +# otherwise CLEAR_DEPEND is called to turn off the default state if a required
25.117 +# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
25.118 +# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
25.119 +# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
25.120 +AC_DEFUN([DX_ARG_ABLE], [
25.121 + AC_DEFUN([DX_CURRENT_FEATURE], [$1])
25.122 + AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
25.123 + AC_ARG_ENABLE(doxygen-$1,
25.124 + [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
25.125 + [--enable-doxygen-$1]),
25.126 + DX_IF_FEATURE([$1], [don't $2], [$2]))],
25.127 + [
25.128 +case "$enableval" in
25.129 +#(
25.130 +y|Y|yes|Yes|YES)
25.131 + AC_SUBST([DX_FLAG_$1], 1)
25.132 + $3
25.133 +;; #(
25.134 +n|N|no|No|NO)
25.135 + AC_SUBST([DX_FLAG_$1], 0)
25.136 +;; #(
25.137 +*)
25.138 + AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
25.139 +;;
25.140 +esac
25.141 +], [
25.142 +AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
25.143 +$4
25.144 +])
25.145 +if DX_TEST_FEATURE([$1]); then
25.146 + $5
25.147 + :
25.148 +fi
25.149 +if DX_TEST_FEATURE([$1]); then
25.150 + AM_CONDITIONAL(DX_COND_$1, :)
25.151 + $6
25.152 + :
25.153 +else
25.154 + AM_CONDITIONAL(DX_COND_$1, false)
25.155 + $7
25.156 + :
25.157 +fi
25.158 +])
25.159 +
25.160 +## -------------- ##
25.161 +## Public macros. ##
25.162 +## -------------- ##
25.163 +
25.164 +# DX_XXX_FEATURE(DEFAULT_STATE)
25.165 +# -----------------------------
25.166 +AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])])
25.167 +AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])])
25.168 +AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])])
25.169 +AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])])
25.170 +AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])])
25.171 +AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])])
25.172 +AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
25.173 +AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
25.174 +AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])])
25.175 +AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])])
25.176 +
25.177 +# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
25.178 +# ---------------------------------------------------------
25.179 +# PROJECT also serves as the base name for the documentation files.
25.180 +# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
25.181 +AC_DEFUN([DX_INIT_DOXYGEN], [
25.182 +
25.183 +# Files:
25.184 +AC_SUBST([DX_PROJECT], [$1])
25.185 +AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
25.186 +AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
25.187 +
25.188 +# Environment variables used inside doxygen.cfg:
25.189 +DX_ENV_APPEND(SRCDIR, $srcdir)
25.190 +DX_ENV_APPEND(PROJECT, $DX_PROJECT)
25.191 +DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
25.192 +DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
25.193 +
25.194 +# Doxygen itself:
25.195 +DX_ARG_ABLE(doc, [generate any doxygen documentation],
25.196 + [],
25.197 + [],
25.198 + [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
25.199 + DX_REQUIRE_PROG([DX_PERL], perl)],
25.200 + [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
25.201 +
25.202 +# Dot for graphics:
25.203 +DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
25.204 + [DX_CHECK_DEPEND(doc, 1)],
25.205 + [DX_CLEAR_DEPEND(doc, 1)],
25.206 + [DX_REQUIRE_PROG([DX_DOT], dot)],
25.207 + [DX_ENV_APPEND(HAVE_DOT, YES)
25.208 + DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
25.209 + [DX_ENV_APPEND(HAVE_DOT, NO)])
25.210 +
25.211 +# Man pages generation:
25.212 +DX_ARG_ABLE(man, [generate doxygen manual pages],
25.213 + [DX_CHECK_DEPEND(doc, 1)],
25.214 + [DX_CLEAR_DEPEND(doc, 1)],
25.215 + [],
25.216 + [DX_ENV_APPEND(GENERATE_MAN, YES)],
25.217 + [DX_ENV_APPEND(GENERATE_MAN, NO)])
25.218 +
25.219 +# RTF file generation:
25.220 +DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
25.221 + [DX_CHECK_DEPEND(doc, 1)],
25.222 + [DX_CLEAR_DEPEND(doc, 1)],
25.223 + [],
25.224 + [DX_ENV_APPEND(GENERATE_RTF, YES)],
25.225 + [DX_ENV_APPEND(GENERATE_RTF, NO)])
25.226 +
25.227 +# XML file generation:
25.228 +DX_ARG_ABLE(xml, [generate doxygen XML documentation],
25.229 + [DX_CHECK_DEPEND(doc, 1)],
25.230 + [DX_CLEAR_DEPEND(doc, 1)],
25.231 + [],
25.232 + [DX_ENV_APPEND(GENERATE_XML, YES)],
25.233 + [DX_ENV_APPEND(GENERATE_XML, NO)])
25.234 +
25.235 +# (Compressed) HTML help generation:
25.236 +DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
25.237 + [DX_CHECK_DEPEND(doc, 1)],
25.238 + [DX_CLEAR_DEPEND(doc, 1)],
25.239 + [DX_REQUIRE_PROG([DX_HHC], hhc)],
25.240 + [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
25.241 + DX_ENV_APPEND(GENERATE_HTML, YES)
25.242 + DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
25.243 + [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
25.244 +
25.245 +# Seperate CHI file generation.
25.246 +DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
25.247 + [DX_CHECK_DEPEND(chm, 1)],
25.248 + [DX_CLEAR_DEPEND(chm, 1)],
25.249 + [],
25.250 + [DX_ENV_APPEND(GENERATE_CHI, YES)],
25.251 + [DX_ENV_APPEND(GENERATE_CHI, NO)])
25.252 +
25.253 +# Plain HTML pages generation:
25.254 +DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
25.255 + [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
25.256 + [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
25.257 + [],
25.258 + [DX_ENV_APPEND(GENERATE_HTML, YES)],
25.259 + [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
25.260 +
25.261 +# PostScript file generation:
25.262 +DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
25.263 + [DX_CHECK_DEPEND(doc, 1)],
25.264 + [DX_CLEAR_DEPEND(doc, 1)],
25.265 + [DX_REQUIRE_PROG([DX_LATEX], latex)
25.266 + DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
25.267 + DX_REQUIRE_PROG([DX_DVIPS], dvips)
25.268 + DX_REQUIRE_PROG([DX_EGREP], egrep)])
25.269 +
25.270 +# PDF file generation:
25.271 +DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
25.272 + [DX_CHECK_DEPEND(doc, 1)],
25.273 + [DX_CLEAR_DEPEND(doc, 1)],
25.274 + [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
25.275 + DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
25.276 + DX_REQUIRE_PROG([DX_EGREP], egrep)])
25.277 +
25.278 +# LaTeX generation for PS and/or PDF:
25.279 +if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
25.280 + AM_CONDITIONAL(DX_COND_latex, :)
25.281 + DX_ENV_APPEND(GENERATE_LATEX, YES)
25.282 +else
25.283 + AM_CONDITIONAL(DX_COND_latex, false)
25.284 + DX_ENV_APPEND(GENERATE_LATEX, NO)
25.285 +fi
25.286 +
25.287 +# Paper size for PS and/or PDF:
25.288 +AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
25.289 + [a4wide (default), a4, letter, legal or executive])
25.290 +case "$DOXYGEN_PAPER_SIZE" in
25.291 +#(
25.292 +"")
25.293 + AC_SUBST(DOXYGEN_PAPER_SIZE, "")
25.294 +;; #(
25.295 +a4wide|a4|letter|legal|executive)
25.296 + DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
25.297 +;; #(
25.298 +*)
25.299 + AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
25.300 +;;
25.301 +esac
25.302 +
25.303 +#For debugging:
25.304 +#echo DX_FLAG_doc=$DX_FLAG_doc
25.305 +#echo DX_FLAG_dot=$DX_FLAG_dot
25.306 +#echo DX_FLAG_man=$DX_FLAG_man
25.307 +#echo DX_FLAG_html=$DX_FLAG_html
25.308 +#echo DX_FLAG_chm=$DX_FLAG_chm
25.309 +#echo DX_FLAG_chi=$DX_FLAG_chi
25.310 +#echo DX_FLAG_rtf=$DX_FLAG_rtf
25.311 +#echo DX_FLAG_xml=$DX_FLAG_xml
25.312 +#echo DX_FLAG_pdf=$DX_FLAG_pdf
25.313 +#echo DX_FLAG_ps=$DX_FLAG_ps
25.314 +#echo DX_ENV=$DX_ENV
25.315 +])
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/branches/gmyth-0.1b/m4/as-compiler-flag.m4 Thu Feb 01 18:42:01 2007 +0000
26.3 @@ -0,0 +1,33 @@
26.4 +dnl as-compiler-flag.m4 0.1.0
26.5 +
26.6 +dnl autostars m4 macro for detection of compiler flags
26.7 +
26.8 +dnl David Schleef <ds@schleef.org>
26.9 +
26.10 +dnl $Id: as-compiler-flag.m4,v 1.1.1.1 2005/08/26 00:42:44 andrunko Exp $
26.11 +
26.12 +dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])
26.13 +dnl Tries to compile with the given CFLAGS.
26.14 +dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,
26.15 +dnl and ACTION-IF-NOT-ACCEPTED otherwise.
26.16 +
26.17 +AC_DEFUN([AS_COMPILER_FLAG],
26.18 +[
26.19 + AC_MSG_CHECKING([to see if compiler understands $1])
26.20 +
26.21 + save_CFLAGS="$CFLAGS"
26.22 + CFLAGS="$CFLAGS $1"
26.23 +
26.24 + AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
26.25 + CFLAGS="$save_CFLAGS"
26.26 +
26.27 + if test "X$flag_ok" = Xyes ; then
26.28 + $2
26.29 + true
26.30 + else
26.31 + $3
26.32 + true
26.33 + fi
26.34 + AC_MSG_RESULT([$flag_ok])
26.35 +])
26.36 +
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/branches/gmyth-0.1b/m4/as-expand.m4 Thu Feb 01 18:42:01 2007 +0000
27.3 @@ -0,0 +1,40 @@
27.4 +dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR)
27.5 +dnl
27.6 +dnl example
27.7 +dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
27.8 +dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local
27.9 +
27.10 +AC_DEFUN([AS_AC_EXPAND],
27.11 +[
27.12 + EXP_VAR=[$1]
27.13 + FROM_VAR=[$2]
27.14 +
27.15 + dnl first expand prefix and exec_prefix if necessary
27.16 + prefix_save=$prefix
27.17 + exec_prefix_save=$exec_prefix
27.18 +
27.19 + dnl if no prefix given, then use /usr/local, the default prefix
27.20 + if test "x$prefix" = "xNONE"; then
27.21 + prefix=$ac_default_prefix
27.22 + fi
27.23 + dnl if no exec_prefix given, then use prefix
27.24 + if test "x$exec_prefix" = "xNONE"; then
27.25 + exec_prefix=$prefix
27.26 + fi
27.27 +
27.28 + full_var="$FROM_VAR"
27.29 + dnl loop until it doesn't change anymore
27.30 + while true; do
27.31 + new_full_var="`eval echo $full_var`"
27.32 + if test "x$new_full_var"="x$full_var"; then break; fi
27.33 + full_var=$new_full_var
27.34 + done
27.35 +
27.36 + dnl clean up
27.37 + full_var=$new_full_var
27.38 + AC_SUBST([$1], "$full_var")
27.39 +
27.40 + dnl restore prefix and exec_prefix
27.41 + prefix=$prefix_save
27.42 + exec_prefix=$exec_prefix_save
27.43 +])
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/branches/gmyth-0.1b/m4/as-version.m4 Thu Feb 01 18:42:01 2007 +0000
28.3 @@ -0,0 +1,59 @@
28.4 +dnl version.m4 0.0.5
28.5 +dnl autostars m4 macro for versioning
28.6 +dnl thomas@apestaart.org
28.7 +dnl
28.8 +dnl AS_VERSION(PACKAGE, PREFIX, MAJOR, MINOR, MICRO, NANO, ACTION_IF_NO_NANO, ACTION_IF_NANO)
28.9 +dnl example
28.10 +dnl AS_VERSION(gstreamer, GST_VERSION, 0, 3, 2,)
28.11 +dnl for a 0.3.2 release version
28.12 +dnl
28.13 +dnl this macro
28.14 +dnl - defines [$PREFIX]_MAJOR, MINOR and MICRO
28.15 +dnl - if NANO is empty, then we're in release mode, else in cvs/dev mode
28.16 +dnl - defines [$PREFIX], VERSION, and [$PREFIX]_RELEASE
28.17 +dnl - executes the relevant action
28.18 +dnl - AC_SUBST's PACKAGE, VERSION, [$PREFIX] and [$PREFIX]_RELEASE
28.19 +dnl as well as the little ones
28.20 +dnl - doesn't call AM_INIT_AUTOMAKE anymore because it prevents
28.21 +dnl maintainer mode from running ok
28.22 +dnl
28.23 +dnl don't forget to put #undef [$2] and [$2]_RELEASE in acconfig.h
28.24 +
28.25 +AC_DEFUN([AS_VERSION],
28.26 +[
28.27 + PACKAGE=[$1]
28.28 + [$2]_MAJOR_VERSION=[$3]
28.29 + [$2]_MINOR_VERSION=[$4]
28.30 + [$2]_MICRO_VERSION=[$5]
28.31 + NANO=[$6]
28.32 + [$2]_NANO_VERSION=$NANO
28.33 + if test "x$NANO" = "x" || test "x$NANO" = "x0";
28.34 + then
28.35 + AC_MSG_NOTICE(configuring [$1] for release)
28.36 + VERSION=[$3].[$4].[$5]
28.37 + [$2]_RELEASE=1
28.38 + dnl execute action
28.39 + ifelse([$7], , :, [$7])
28.40 + else
28.41 + AC_MSG_NOTICE(configuring [$1] for development with nano $NANO)
28.42 + VERSION=[$3].[$4].[$5].$NANO
28.43 + [$2]_RELEASE=`date +%Y%m%d_%H%M%S`
28.44 + dnl execute action
28.45 + ifelse([$8], , :, [$8])
28.46 + fi
28.47 +
28.48 + [$2]_VERSION=$VERSION
28.49 + AC_DEFINE_UNQUOTED([$2]_VERSION, "$[$2]_VERSION", [Define the version])
28.50 + AC_SUBST([$2]_VERSION)
28.51 +
28.52 + AC_SUBST([$2]_RELEASE)
28.53 +
28.54 + AC_SUBST([$2]_MAJOR_VERSION)
28.55 + AC_SUBST([$2]_MINOR_VERSION)
28.56 + AC_SUBST([$2]_MICRO_VERSION)
28.57 + AC_SUBST([$2]_NANO_VERSION)
28.58 + AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Define the package name])
28.59 + AC_SUBST(PACKAGE)
28.60 + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Define the version])
28.61 + AC_SUBST(VERSION)
28.62 +])
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/branches/gmyth-0.1b/m4/configure.ac Thu Feb 01 18:42:01 2007 +0000
29.3 @@ -0,0 +1,234 @@
29.4 +# -*- Autoconf -*-
29.5 +# Process this file with autoconf to produce a configure script.
29.6 +
29.7 +AC_PREREQ(2.50)
29.8 +
29.9 +AC_INIT([gmyth],[0.1])
29.10 +
29.11 +dnl AC_CONFIG_SRCDIR([src/mmyth_main.c])
29.12 +AC_CONFIG_HEADER(config.h)
29.13 +
29.14 +dnl when going to/from release please set the nano (fourth number) right !
29.15 +dnl releases only do Wall, SVN and prerelease does Werror too
29.16 +AS_VERSION(gmyth, GMYTH, 0, 1, 0, 3, GMYTH_SVN="no", GMYTH_SVN="yes")
29.17 +
29.18 +GMYTH_MAJORMINOR=$GMYTH_MAJOR_VERSION.$GMYTH_MINOR_VERSION
29.19 +
29.20 +AC_SUBST(GMYTH_MAJORMINOR)
29.21 +
29.22 +dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode
29.23 +AM_MAINTAINER_MODE
29.24 +dnl make aclocal work in maintainer mode
29.25 +AC_SUBST(ACLOCAL_AMFLAGS, "-I m4")
29.26 +
29.27 +# Checks for programs.
29.28 +# check for tools
29.29 +# Make sure CFLAGS is defined to stop AC_PROC_CC adding -g
29.30 +CFLAGS="$CFLAGS -Wall"
29.31 +AC_PROG_CC
29.32 +AC_PROG_LIBTOOL
29.33 +
29.34 +dnl Generate doxygen documentation
29.35 +DX_HTML_FEATURE(ON)
29.36 +DX_CHM_FEATURE(OFF)
29.37 +DX_CHI_FEATURE(OFF)
29.38 +DX_MAN_FEATURE(OFF)
29.39 +DX_RTF_FEATURE(OFF)
29.40 +DX_XML_FEATURE(OFF)
29.41 +DX_PDF_FEATURE(OFF)
29.42 +DX_PS_FEATURE(OFF)
29.43 +DX_INIT_DOXYGEN(gmyth, doxygen.cfg, docs)
29.44 +
29.45 +
29.46 +# Checks for libraries.
29.47 +
29.48 +# Checks for header files.
29.49 +AC_HEADER_STDC
29.50 +AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h unistd.h])
29.51 +
29.52 +# Checks for typedefs, structures, and compiler characteristics.
29.53 +AC_C_CONST
29.54 +AC_TYPE_PID_T
29.55 +AC_STRUCT_TM
29.56 +
29.57 +# Checks for library functions.
29.58 +AC_FUNC_FORK
29.59 +AC_PROG_GCC_TRADITIONAL
29.60 +AC_FUNC_MALLOC
29.61 +AC_FUNC_MKTIME
29.62 +AC_FUNC_VPRINTF
29.63 +AC_CHECK_FUNCS([memset socket stime strstr strtoul])
29.64 +
29.65 +AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
29.66 +
29.67 +# Checks required packages
29.68 +
29.69 +dnl Test if --disable-debug given
29.70 +AC_ARG_ENABLE(debug,
29.71 + [AC_HELP_STRING([--disable-debug], [disable debugging mode])],
29.72 + enable_debug="$enableval",
29.73 + enable_debug=yes)
29.74 +
29.75 +if test "x$enable_debug" = "xyes" ; then
29.76 + CFLAGS="$CFLAGS -g"
29.77 +else
29.78 + AC_DEFINE( NDEBUG, 1, [disable debug messages] )
29.79 + CFLAGS="$CFLAGS -O2 -DG_DISABLE_CHECKS -DNDEBUG"
29.80 +fi
29.81 +
29.82 +AM_CONDITIONAL( NDEBUG, test "x$enable_debug" = "xyes" )
29.83 +
29.84 +# Check for pkgconfig
29.85 +AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, yes, no)
29.86 +# Give error and exit if we don't have pkgconfig
29.87 +if test "x$HAVE_PKGCONFIG" = "xno"; then
29.88 + AC_MSG_ERROR(you need to have pkgconfig installed !)
29.89 +fi
29.90 +
29.91 +# Check for Glib2.0
29.92 +PKG_CHECK_MODULES(GLIB, glib-2.0, HAVE_GLIB=yes,HAVE_GLIB=no)
29.93 +
29.94 +# Give error and exit if we don't have glib
29.95 +if test "x$HAVE_GLIB" = "xno"; then
29.96 + AC_MSG_ERROR(you need glib-2.0 installed)
29.97 +fi
29.98 +
29.99 +# make GLIB_CFLAGS and GLIB_LIBS available
29.100 +AC_SUBST(GLIB_CFLAGS)
29.101 +AC_SUBST(GLIB_LIBS)
29.102 +
29.103 +# Check for GObject2.0
29.104 +PKG_CHECK_MODULES(GOBJECT,
29.105 + gobject-2.0,
29.106 + HAVE_GOBJECT=yes, HAVE_GOBJECT=no)
29.107 +
29.108 +# Give error and exit if we don't have gobject
29.109 +if test "x$HAVE_GOBJECT" = "xno"; then
29.110 + AC_MSG_ERROR(you need gobject-2.0 installed)
29.111 +fi
29.112 +
29.113 +# make GOBJECT_CFLAGS and GOBJECT_LIBS available
29.114 +AC_SUBST(GOBJECT_CFLAGS)
29.115 +AC_SUBST(GOBJECT_LIBS)
29.116 +
29.117 +# Check for GTK+-2.0
29.118 +PKG_CHECK_MODULES(GTK, gtk+-2.0, HAVE_GTK=yes,HAVE_GTK=no)
29.119 +
29.120 +# Give error and exit if we don't have gtk
29.121 +if test "x$HAVE_GTK" = "xyes"; then
29.122 + AC_DEFINE(WITH_GTK, 1, [build with GTK+ related stuff])
29.123 + dnl AC_MSG_ERROR(you need gtk+-2.0 installed)
29.124 +else
29.125 + AC_MSG_RESULT(no)
29.126 +fi
29.127 +
29.128 +AM_CONDITIONAL(WITH_GTK, test "x$HAVE_GTK" = "xyes" )
29.129 +
29.130 +# make GTK_CFLAGS and GTK_LIBS available
29.131 +AC_SUBST(GTK_CFLAGS)
29.132 +AC_SUBST(GTK_LIBS)
29.133 +
29.134 +dnl ========== Check for Hildon Libraries
29.135 +PKG_CHECK_MODULES(HILDON,
29.136 + hildon-lgpl libosso hildon-status-bar-lib libhildonmenu hildon-base-lib hildon-control-panel hildon-libs,
29.137 + HAVE_HILDON=yes, HAVE_HILDON=no)
29.138 +
29.139 +if test "x$HAVE_HILDON" = "xyes"; then
29.140 + AC_DEFINE(MAEMO_PLATFORM, 1, [build with hildon libs])
29.141 + HILDON_CFLAGS="$HILDON_CFLAGS -DMAEMO_PLATFORM=1"
29.142 +else
29.143 + AC_MSG_RESULT(no)
29.144 +fi
29.145 +
29.146 +AM_CONDITIONAL(MAEMO_PLATFORM, test "x$HAVE_HILDON" = "xyes")
29.147 +
29.148 +dnl make HILDON_CFLAGS and HILDON_LIBS available
29.149 +AC_SUBST(HILDON_CFLAGS)
29.150 +AC_SUBST(HILDON_LIBS)
29.151 +
29.152 +# Check for libxml-2.0
29.153 +PKG_CHECK_MODULES(LIBXML, libxml-2.0, HAVE_LIBXML=yes,HAVE_LIBXML=no)
29.154 +
29.155 +# Give error and exit if we don't have libxml
29.156 +if test "x$HAVE_LIBXML" = "xno"; then
29.157 + AC_MSG_ERROR(you need libxml-2.0 installed)
29.158 +fi
29.159 +
29.160 +# make LIBXML_CFLAGS and LIBXML_LIBS available
29.161 +AC_SUBST(LIBXML_CFLAGS)
29.162 +AC_SUBST(LIBXML_LIBS)
29.163 +
29.164 +
29.165 +# check for gstreamer development files
29.166 +GST_REQUIRED=0.10
29.167 +GST_MAJORMINOR=0.10
29.168 +PKG_CHECK_MODULES(GST, \
29.169 + gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED,
29.170 + HAVE_GST=yes, HAVE_GST=no)
29.171 +
29.172 +# Give error and exit if we don't have gstreamer
29.173 +if test "x$HAVE_GST" = "xno"; then
29.174 + AC_MSG_ERROR(you need gstreamer development packages installed !)
29.175 +fi
29.176 +
29.177 +# make GST_CFLAGS and GST_LIBS available
29.178 +AC_SUBST(GST_CFLAGS)
29.179 +AC_SUBST(GST_LIBS)
29.180 +
29.181 +# check for gstreamer-base plugins (xoverlay interface)
29.182 +GSTBASE_REQUIRED=0.10
29.183 +GSTBASE_MAJORMINOR=0.10
29.184 +PKG_CHECK_MODULES(GSTBASE, \
29.185 + gstreamer-base-$GSTBASE_MAJORMINOR >= $GSTBASE_REQUIRED,
29.186 + HAVE_GSTBASE=yes, HAVE_GSTBASE=no)
29.187 +
29.188 +# Give error and exit if we don't have gstreamer base libraries
29.189 +if test "x$HAVE_GSTBASE" = "xno"; then
29.190 + AC_MSG_ERROR(you need gstreamer base development packages installed !)
29.191 +fi
29.192 +
29.193 +# make GSTBASE_CFLAGS and GSTBASE_LIBS available
29.194 +AC_SUBST(GSTBASE_CFLAGS)
29.195 +AC_SUBST(GSTBASE_LIBS)
29.196 +
29.197 +
29.198 +# make GST_MAJORMINOR available in Makefile.am
29.199 +AC_SUBST(GST_MAJORMINOR)
29.200 +
29.201 +#
29.202 +# mysql libraries
29.203 +#
29.204 +AC_CHECK_PROG(MYSQL_CFLAGS,mysql_config,`mysql_config --cflags`)
29.205 +if test -z "$MYSQL_CFLAGS"; then
29.206 + AC_MSG_ERROR([Could not find mysql_config script. Make sure the mysql client libraries are installed])
29.207 +fi
29.208 +AC_SUBST(MYSQL_CFLAGS)
29.209 +
29.210 +
29.211 +AC_CHECK_PROG(MYSQL_LIBS,mysql_config,`mysql_config --libs`)
29.212 +if test -z "$MYSQL_LIBS"; then
29.213 + AC_MSG_ERROR([Could not find mysql_config script. Make sure the mysql client libraries are installed])
29.214 +fi
29.215 +AC_SUBST(MYSQL_LIBS)
29.216 +
29.217 +## Check for gmyth-0.1
29.218 +
29.219 +PKG_CHECK_MODULES(LIBGMYTH, gmyth-0.1, HAVE_LIBGMYTH=yes,HAVE_LIBGMYTH=no)
29.220 +
29.221 +# Give error and exit if we don't have gmyth-0.1
29.222 +if test "x$HAVE_LIBGMYTH" = "xno"; then
29.223 + AC_MSG_ERROR(you need gmyth-0.1 installed)
29.224 +fi
29.225 +
29.226 +# make LIBXML_CFLAGS and LIBXML_LIBS available
29.227 +AC_SUBST(LIBGMYTH_CFLAGS)
29.228 +AC_SUBST(LIBGMYTH_LIBS)
29.229 +
29.230 +#dnl Enable gtk-doc
29.231 +#GTK_DOC_CHECK(1.4)
29.232 +
29.233 +
29.234 +AC_CONFIG_FILES([Makefile
29.235 + src/Makefile
29.236 + pixmaps/Makefile])
29.237 +AC_OUTPUT
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/branches/gmyth-0.1b/src/Makefile.am Thu Feb 01 18:42:01 2007 +0000
30.3 @@ -0,0 +1,85 @@
30.4 +SUBDIRS = .
30.5 +
30.6 +lib_LTLIBRARIES = libgmyth.la
30.7 +
30.8 +BUILT_SOURCES = \
30.9 + gmyth_marshal.c \
30.10 + gmyth_marshal.h
30.11 +
30.12 +libgmyth_la_SOURCES = \
30.13 + gmyth_common.c \
30.14 + gmyth_debug.c \
30.15 + gmyth_epg.c \
30.16 + gmyth_recorder.c \
30.17 + gmyth_remote_util.c \
30.18 + gmyth_tvchain.c \
30.19 + gmyth_scheduler.c \
30.20 + gmyth_util.c \
30.21 + gmyth_query.c \
30.22 + gmyth_socket.c \
30.23 + gmyth_stringlist.c \
30.24 + gmyth_monitor_handler.c \
30.25 + gmyth_file_transfer.c \
30.26 + gmyth_livetv.c \
30.27 + gmyth_backendinfo.c \
30.28 + gmyth_programinfo.c \
30.29 + gmyth_uri.c \
30.30 + gmyth_http.c \
30.31 + $(BUILT_SOURCES)
30.32 +
30.33 +
30.34 +EXTRA_libgmyth_la_SOURCES = gmyth_marshal.list
30.35 +
30.36 +gmyth_marshal.h: gmyth_marshal.list
30.37 + glib-genmarshal --header --prefix=gmyth_marshal gmyth_marshal.list > gmyth_marshal.h.tmp
30.38 + mv gmyth_marshal.h.tmp gmyth_marshal.h
30.39 +
30.40 +gmyth_marshal.c: gmyth_marshal.list gmyth_marshal.h
30.41 + echo "#include \"glib-object.h\"" > gmyth_marshal.c.tmp
30.42 + echo "#include \"gmyth_marshal.h\"" >> gmyth_marshal.c.tmp
30.43 + glib-genmarshal --body --prefix=gmyth_marshal $(srcdir)/gmyth_marshal.list >> gmyth_marshal.c.tmp
30.44 + mv gmyth_marshal.c.tmp gmyth_marshal.c
30.45 +
30.46 +libgmyth_la_CFLAGS = \
30.47 + -DDATADIR=\"$(pkgdatadir)\" \
30.48 + $(GLIB_CFLAGS) \
30.49 + $(GOBJECT_CFLAGS) \
30.50 + $(GST_CFLAGS) \
30.51 + $(GSTBASE_CFLAGS) \
30.52 + $(GSTPLUGINSBASE_CFLAGS) \
30.53 + $(MYSQL_CFLAGS) \
30.54 + $(LIBXML_CFLAGS)
30.55 +
30.56 +libgmyth_la_LDFLAGS = \
30.57 + -export-dynamic \
30.58 + $(MYSQL_LIBS) \
30.59 + $(GST_LIBS) \
30.60 + $(GSTBASE_LIBS) \
30.61 + $(GSTPLUGINS_LIBS) \
30.62 + $(LIBXML_LIBS)
30.63 +
30.64 +libgmyth_includedir = \
30.65 + $(pkgincludedir)
30.66 +
30.67 +libgmyth_include_HEADERS = \
30.68 + gmyth.h \
30.69 + gmyth_common.h \
30.70 + gmyth_debug.h \
30.71 + gmyth_epg.h \
30.72 + gmyth_recorder.h \
30.73 + gmyth_scheduler.h \
30.74 + gmyth_tvchain.h \
30.75 + gmyth_util.h \
30.76 + gmyth_query.h \
30.77 + gmyth_socket.h \
30.78 + gmyth_remote_util.h \
30.79 + gmyth_stringlist.h \
30.80 + gmyth_monitor_handler.h \
30.81 + gmyth_file_transfer.h \
30.82 + gmyth_livetv.h \
30.83 + gmyth_backendinfo.h \
30.84 + gmyth_programinfo.h \
30.85 + gmyth_uri.h \
30.86 + gmyth_http.h
30.87 +
30.88 +CLEANFILES = $(BUILT_SOURCES)
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/branches/gmyth-0.1b/src/gmyth.h Thu Feb 01 18:42:01 2007 +0000
31.3 @@ -0,0 +1,51 @@
31.4 +/**
31.5 + * GMyth Library
31.6 + *
31.7 + * @file gmyth/gmyth.h
31.8 + *
31.9 + *
31.10 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
31.11 + * @author Renato Filho <renato.filho@indt.org.br>
31.12 + *
31.13 + *//*
31.14 + *
31.15 + * This program is free software; you can redistribute it and/or modify
31.16 + * it under the terms of the GNU Lesser General Public License as published by
31.17 + * the Free Software Foundation; either version 2 of the License, or
31.18 + * (at your option) any later version.
31.19 + *
31.20 + * This program is distributed in the hope that it will be useful,
31.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31.23 + * GNU General Public License for more details.
31.24 + *
31.25 + * You should have received a copy of the GNU Lesser General Public License
31.26 + * along with this program; if not, write to the Free Software
31.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31.28 + */
31.29 +
31.30 +
31.31 +
31.32 +#ifndef _GMYTH_H_
31.33 +#define _GMYTH_H_
31.34 +
31.35 +#include <gmyth_backendinfo.h>
31.36 +#include <gmyth_common.h>
31.37 +#include <gmyth_debug.h>
31.38 +#include <gmyth_epg.h>
31.39 +#include <gmyth_file_transfer.h>
31.40 +#include <gmyth_livetv.h>
31.41 +#include <gmyth_monitor_handler.h>
31.42 +#include <gmyth_programinfo.h>
31.43 +#include <gmyth_query.h>
31.44 +#include <gmyth_recorder.h>
31.45 +#include <gmyth_remote_util.h>
31.46 +#include <gmyth_scheduler.h>
31.47 +#include <gmyth_socket.h>
31.48 +#include <gmyth_stringlist.h>
31.49 +#include <gmyth_tvchain.h>
31.50 +#include <gmyth_uri.h>
31.51 +#include <gmyth_util.h>
31.52 +#include <gmyth_http.h>
31.53 +
31.54 +#endif /* _GMYTH_H_ */
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/branches/gmyth-0.1b/src/gmyth_backendinfo.c Thu Feb 01 18:42:01 2007 +0000
32.3 @@ -0,0 +1,258 @@
32.4 +
32.5 +/**
32.6 + * GMyth Library
32.7 + *
32.8 + * @file gmyth/gmyth_backend_info.c
32.9 + *
32.10 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
32.11 + * @author Hallyson Melo <hallyson.melo@indt.org.br>
32.12 + *
32.13 + *//*
32.14 + *
32.15 + * This program is free software; you can redistribute it and/or modify
32.16 + * it under the terms of the GNU Lesser General Public License as published by
32.17 + * the Free Software Foundation; either version 2 of the License, or
32.18 + * (at your option) any later version.
32.19 + *
32.20 + * This program is distributed in the hope that it will be useful,
32.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
32.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32.23 + * GNU General Public License for more details.
32.24 + *
32.25 + * You should have received a copy of the GNU Lesser General Public License
32.26 + * along with this program; if not, write to the Free Software
32.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32.28 + */
32.29 +
32.30 +#ifdef HAVE_CONFIG_H
32.31 +#include "config.h"
32.32 +#endif
32.33 +
32.34 +#include "gmyth_backendinfo.h"
32.35 +#include "gmyth_uri.h"
32.36 +#include "gmyth_debug.h"
32.37 +
32.38 +static void gmyth_backend_info_class_init (GMythBackendInfoClass *klass);
32.39 +static void gmyth_backend_info_init (GMythBackendInfo *object);
32.40 +
32.41 +static void gmyth_backend_info_dispose (GObject *object);
32.42 +static void gmyth_backend_info_finalize (GObject *object);
32.43 +
32.44 +G_DEFINE_TYPE(GMythBackendInfo, gmyth_backend_info, G_TYPE_OBJECT)
32.45 +
32.46 +static void
32.47 +gmyth_backend_info_class_init (GMythBackendInfoClass *klass)
32.48 +{
32.49 + GObjectClass *gobject_class;
32.50 +
32.51 + gobject_class = (GObjectClass *) klass;
32.52 +
32.53 + gobject_class->dispose = gmyth_backend_info_dispose;
32.54 + gobject_class->finalize = gmyth_backend_info_finalize;
32.55 +}
32.56 +
32.57 +static void
32.58 +gmyth_backend_info_init (GMythBackendInfo *backend_info)
32.59 +{
32.60 + backend_info->hostname = NULL;
32.61 + backend_info->username = NULL;
32.62 + backend_info->password = NULL;
32.63 + backend_info->db_name = NULL;
32.64 + backend_info->port = -1;
32.65 + backend_info->uri = NULL;
32.66 +}
32.67 +
32.68 +static void
32.69 +gmyth_backend_info_dispose (GObject *object)
32.70 +{
32.71 + GMythBackendInfo *backend_info = GMYTH_BACKEND_INFO (object);
32.72 +
32.73 + g_free (backend_info->hostname);
32.74 + g_free (backend_info->username);
32.75 + g_free (backend_info->password);
32.76 + g_free (backend_info->db_name);
32.77 +
32.78 + backend_info->hostname = NULL;
32.79 + backend_info->username = NULL;
32.80 + backend_info->password = NULL;
32.81 + backend_info->db_name = NULL;
32.82 + backend_info->port = -1;
32.83 +
32.84 + if ( backend_info->uri != NULL )
32.85 + {
32.86 + g_object_unref(backend_info->uri);
32.87 + backend_info->uri = NULL;
32.88 + }
32.89 +
32.90 + G_OBJECT_CLASS (gmyth_backend_info_parent_class)->dispose (object);
32.91 +}
32.92 +
32.93 +static void
32.94 +gmyth_backend_info_finalize (GObject *object)
32.95 +{
32.96 + g_signal_handlers_destroy (object);
32.97 +
32.98 + G_OBJECT_CLASS (gmyth_backend_info_parent_class)->finalize (object);
32.99 +}
32.100 +
32.101 +/** Creates a new instance of GMythBackendInfo.
32.102 + *
32.103 + * @return a new instance of GMythBackendInfo.
32.104 + */
32.105 +GMythBackendInfo*
32.106 +gmyth_backend_info_new ()
32.107 +{
32.108 + GMythBackendInfo *backend_info =
32.109 + GMYTH_BACKEND_INFO (g_object_new(GMYTH_BACKEND_INFO_TYPE, NULL));
32.110 +
32.111 + return backend_info;
32.112 +}
32.113 +
32.114 +GMythBackendInfo*
32.115 +gmyth_backend_info_new_full (const gchar *hostname, const gchar *username,
32.116 + const gchar *password, const gchar *db_name, gint port)
32.117 +{
32.118 + GMythBackendInfo *backend_info =
32.119 + GMYTH_BACKEND_INFO (g_object_new(GMYTH_BACKEND_INFO_TYPE, NULL));
32.120 +
32.121 + backend_info->uri = gmyth_uri_new_with_value(
32.122 + g_strdup_printf( "myth://%s:%s@%s:%d/?%s", username, password, hostname, port, db_name ) );
32.123 +
32.124 + gmyth_backend_info_set_hostname (backend_info, hostname);
32.125 + gmyth_backend_info_set_username (backend_info, username);
32.126 + gmyth_backend_info_set_password (backend_info, password);
32.127 + gmyth_backend_info_set_db_name (backend_info, db_name);
32.128 + gmyth_backend_info_set_port (backend_info, port);
32.129 +
32.130 + return backend_info;
32.131 +}
32.132 +
32.133 +GMythBackendInfo*
32.134 +gmyth_backend_info_new_with_uri ( const gchar *uri_str )
32.135 +{
32.136 + GMythBackendInfo *backend_info =
32.137 + GMYTH_BACKEND_INFO (g_object_new(GMYTH_BACKEND_INFO_TYPE, NULL));
32.138 +
32.139 + backend_info->uri = gmyth_uri_new_with_value( uri_str );
32.140 +
32.141 + gchar** path_parts = g_strsplit( gmyth_uri_get_path( backend_info->uri ), "&", -1 );
32.142 +
32.143 + gmyth_backend_info_set_hostname (backend_info, gmyth_uri_get_host ( backend_info->uri ) );
32.144 + gmyth_backend_info_set_username (backend_info, gmyth_uri_get_user( backend_info->uri ) );
32.145 + gmyth_backend_info_set_password (backend_info, gmyth_uri_get_password( backend_info->uri ) );
32.146 + /* gets the path info to database name, from the URI, and removes the trash chars */
32.147 + gmyth_backend_info_set_db_name (backend_info, path_parts != NULL && path_parts[0] != NULL
32.148 + && strlen( path_parts[0] ) > 0 ? g_strstrip( g_strdup( g_strdelimit( path_parts[0], "/?", ' ' ) ) )
32.149 + : gmyth_uri_get_path( backend_info->uri ) );
32.150 + gmyth_backend_info_set_port (backend_info, gmyth_uri_get_port( backend_info->uri ) );
32.151 +
32.152 + g_strfreev( path_parts );
32.153 +
32.154 + return backend_info;
32.155 +}
32.156 +
32.157 +void
32.158 +gmyth_backend_info_set_hostname (GMythBackendInfo *backend_info, const gchar *hostname)
32.159 +{
32.160 + g_return_if_fail (backend_info != NULL);
32.161 +
32.162 + if ( NULL == hostname || strlen(hostname) <= 0 )
32.163 + {
32.164 + gmyth_debug ( "Error trying to set a hostname equals to NULL." );
32.165 + } else {
32.166 + backend_info->hostname = g_strdup (hostname);
32.167 + }
32.168 +}
32.169 +
32.170 +void
32.171 +gmyth_backend_info_set_username (GMythBackendInfo *backend_info, const gchar *username)
32.172 +{
32.173 + g_return_if_fail (backend_info != NULL);
32.174 +
32.175 + backend_info->username = g_strdup (username);
32.176 +}
32.177 +
32.178 +void
32.179 +gmyth_backend_info_set_password (GMythBackendInfo *backend_info, const gchar *password)
32.180 +{
32.181 + g_return_if_fail (backend_info != NULL);
32.182 +
32.183 + backend_info->password = g_strdup (password);
32.184 +}
32.185 +
32.186 +void
32.187 +gmyth_backend_info_set_db_name (GMythBackendInfo *backend_info, const gchar *db_name)
32.188 +{
32.189 + g_return_if_fail (backend_info != NULL);
32.190 +
32.191 + backend_info->db_name = g_strdup (db_name);
32.192 +}
32.193 +
32.194 +void
32.195 +gmyth_backend_info_set_port (GMythBackendInfo *backend_info, const gint port )
32.196 +{
32.197 + g_return_if_fail (backend_info != NULL);
32.198 +
32.199 + if ( port <= 0 )
32.200 + {
32.201 + gmyth_debug ( "Error trying to set a hostname equals to NULL (it doesn't using UPnP)." );
32.202 + } else {
32.203 + backend_info->port = port;
32.204 + }
32.205 +}
32.206 +
32.207 +const gchar*
32.208 +gmyth_backend_info_get_hostname (GMythBackendInfo *backend_info)
32.209 +{
32.210 + g_return_val_if_fail (backend_info != NULL, NULL);
32.211 +
32.212 + return backend_info->hostname;
32.213 +}
32.214 +
32.215 +const gchar*
32.216 +gmyth_backend_info_get_username (GMythBackendInfo *backend_info)
32.217 +{
32.218 + g_return_val_if_fail (backend_info != NULL, NULL);
32.219 +
32.220 + return backend_info->username;
32.221 +}
32.222 +
32.223 +const gchar*
32.224 +gmyth_backend_info_get_password (GMythBackendInfo *backend_info)
32.225 +{
32.226 + g_return_val_if_fail (backend_info != NULL, NULL);
32.227 +
32.228 + return backend_info->password;
32.229 +}
32.230 +
32.231 +const gchar*
32.232 +gmyth_backend_info_get_db_name (GMythBackendInfo *backend_info)
32.233 +{
32.234 + g_return_val_if_fail (backend_info != NULL, NULL);
32.235 +
32.236 + return backend_info->db_name;
32.237 +}
32.238 +
32.239 +gint
32.240 +gmyth_backend_info_get_port (GMythBackendInfo *backend_info)
32.241 +{
32.242 + g_return_val_if_fail (backend_info != NULL, -1);
32.243 +
32.244 + return backend_info->port;
32.245 +}
32.246 +
32.247 +const GMythURI*
32.248 +gmyth_backend_info_get_uri (GMythBackendInfo *backend_info)
32.249 +{
32.250 +
32.251 + if ( NULL == backend_info->uri )
32.252 + {
32.253 + backend_info->uri = gmyth_uri_new_with_value(
32.254 + g_strdup_printf( "myth://%s:%s@%s:%d/?%s", backend_info->username, backend_info->password,
32.255 + backend_info->hostname, backend_info->port, backend_info->db_name ) );
32.256 + }
32.257 +
32.258 + return backend_info->uri;
32.259 +}
32.260 +
32.261 +
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/branches/gmyth-0.1b/src/gmyth_backendinfo.h Thu Feb 01 18:42:01 2007 +0000
33.3 @@ -0,0 +1,101 @@
33.4 +/**
33.5 + * GMyth Library
33.6 + *
33.7 + * @file gmyth/gmyth_backend_info.h
33.8 + *
33.9 + *
33.10 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
33.11 + * @author Hallyson Melo <hallyson.melo@indt.org.br>
33.12 + *
33.13 + *//*
33.14 + *
33.15 + * This program is free software; you can redistribute it and/or modify
33.16 + * it under the terms of the GNU Lesser General Public License as published by
33.17 + * the Free Software Foundation; either version 2 of the License, or
33.18 + * (at your option) any later version.
33.19 + *
33.20 + * This program is distributed in the hope that it will be useful,
33.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
33.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33.23 + * GNU General Public License for more details.
33.24 + *
33.25 + * You should have received a copy of the GNU Lesser General Public License
33.26 + * along with this program; if not, write to the Free Software
33.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33.28 + */
33.29 +
33.30 +#ifndef __GMYTH_BACKEND_INFO_H__
33.31 +#define __GMYTH_BACKEND_INFO_H__
33.32 +
33.33 +#include <glib-object.h>
33.34 +
33.35 +#include "gmyth_uri.h"
33.36 +
33.37 +G_BEGIN_DECLS
33.38 +
33.39 +#define GMYTH_BACKEND_INFO_TYPE (gmyth_backend_info_get_type ())
33.40 +#define GMYTH_BACKEND_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_BACKEND_INFO_TYPE, GMythBackendInfo))
33.41 +#define GMYTH_BACKEND_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_BACKEND_INFO_TYPE, GMythBackendInfoClass))
33.42 +#define IS_GMYTH_BACKEND_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_BACKEND_INFO_TYPE))
33.43 +#define IS_GMYTH_BACKEND_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_BACKEND_INFO_TYPE))
33.44 +#define GMYTH_BACKEND_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_BACKEND_INFO_TYPE, GMythBackendInfoClass))
33.45 +
33.46 +
33.47 +typedef struct _GMythBackendInfo GMythBackendInfo;
33.48 +typedef struct _GMythBackendInfoClass GMythBackendInfoClass;
33.49 +
33.50 +struct _GMythBackendInfoClass
33.51 +{
33.52 + GObjectClass parent_class;
33.53 +
33.54 + /* callbacks */
33.55 + /* no one for now */
33.56 +};
33.57 +
33.58 +struct _GMythBackendInfo
33.59 +{
33.60 + GObject parent;
33.61 +
33.62 + gchar *hostname;
33.63 + gchar *username;
33.64 + gchar *password;
33.65 + gchar *db_name;
33.66 + gint port;
33.67 + gchar *path;
33.68 +
33.69 + GMythURI* uri;
33.70 +};
33.71 +
33.72 +
33.73 +GType gmyth_backend_info_get_type (void);
33.74 +GMythBackendInfo* gmyth_backend_info_new (void);
33.75 +GMythBackendInfo* gmyth_backend_info_new_full (const gchar *hostname,
33.76 + const gchar *username,
33.77 + const gchar *password,
33.78 + const gchar *db_name,
33.79 + gint port);
33.80 +GMythBackendInfo* gmyth_backend_info_new_with_uri (const gchar *uri_str);
33.81 +void gmyth_backend_info_set_hostname (GMythBackendInfo *backend_info,
33.82 + const gchar *hostname);
33.83 +void gmyth_backend_info_set_username (GMythBackendInfo *backend_info,
33.84 + const gchar *username);
33.85 +void gmyth_backend_info_set_password (GMythBackendInfo *backend_info,
33.86 + const gchar *password);
33.87 +void gmyth_backend_info_set_db_name (GMythBackendInfo *backend_info,
33.88 + const gchar *db_name);
33.89 +void gmyth_backend_info_set_port (GMythBackendInfo *backend_info,
33.90 + gint port);
33.91 +const gchar* gmyth_backend_info_get_hostname (GMythBackendInfo *backend_info);
33.92 +const gchar* gmyth_backend_info_get_username (GMythBackendInfo *backend_info);
33.93 +const gchar* gmyth_backend_info_get_password (GMythBackendInfo *backend_info);
33.94 +const gchar* gmyth_backend_info_get_db_name (GMythBackendInfo *backend_info);
33.95 +gint gmyth_backend_info_get_port (GMythBackendInfo *backend_info);
33.96 +
33.97 +const GMythURI* gmyth_backend_info_get_uri (GMythBackendInfo *backend_info);
33.98 +
33.99 +/*const gchar* gmyth_backend_info_get_full_uri (GMythBackendInfo *backend_info);*/
33.100 +
33.101 +G_END_DECLS
33.102 +
33.103 +#endif /* __GMYTH_BACKEND_INFO_H__ */
33.104 +
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/branches/gmyth-0.1b/src/gmyth_common.c Thu Feb 01 18:42:01 2007 +0000
34.3 @@ -0,0 +1,124 @@
34.4 +/**
34.5 + * GMyth Library
34.6 + *
34.7 + * @file gmyth/gmyth_common.c
34.8 + *
34.9 + * @brief <p> This file contains basic common functions for the gmyth library.
34.10 + *
34.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
34.12 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
34.13 + *
34.14 + *//*
34.15 + *
34.16 + * This program is free software; you can redistribute it and/or modify
34.17 + * it under the terms of the GNU Lesser General Public License as published by
34.18 + * the Free Software Foundation; either version 2 of the License, or
34.19 + * (at your option) any later version.
34.20 + *
34.21 + * This program is distributed in the hope that it will be useful,
34.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
34.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34.24 + * GNU General Public License for more details.
34.25 + *
34.26 + * You should have received a copy of the GNU Lesser General Public License
34.27 + * along with this program; if not, write to the Free Software
34.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34.29 + */
34.30 +
34.31 +#ifdef HAVE_CONFIG_H
34.32 +#include "config.h"
34.33 +#endif
34.34 +
34.35 +#include "gmyth_common.h"
34.36 +#include "gmyth_debug.h"
34.37 +#include "gmyth_util.h"
34.38 +
34.39 +static void free_channel_data(gpointer data, gpointer user_data);
34.40 +static void free_program_data(gpointer data, gpointer user_data);
34.41 +
34.42 +/** Frees the memory allocated to the GMythChannelInfo objects inside list.
34.43 + * The list memory is also released by g_list_free(). If LIST is NULL it
34.44 + * simply returns.
34.45 + *
34.46 + * @param list the GList containing a list of GMythChannelInfo to free.
34.47 + */
34.48 +void
34.49 +gmyth_free_channel_list(GList *list)
34.50 +{
34.51 + if (list == NULL) {
34.52 + g_warning ("%s received null GList as parameter", __FUNCTION__);
34.53 + return;
34.54 + }
34.55 +
34.56 + g_list_foreach (list, free_channel_data, NULL);
34.57 +
34.58 + g_list_free (list);
34.59 +}
34.60 +
34.61 +/** Frees the memory allocated to the GMythProgramInfo objects inside list.
34.62 + * The list memory is also released by g_list_free(). If list is NULL it
34.63 + * simply returns.
34.64 + *
34.65 + * @param list the GList containing a list of GMythProgramInfo to free.
34.66 + */
34.67 +void
34.68 +gmyth_free_program_list(GList *list)
34.69 +{
34.70 + if (list == NULL) {
34.71 + g_warning ("%s received null GList as parameter", __FUNCTION__);
34.72 + return;
34.73 + }
34.74 +
34.75 + g_list_foreach (list, free_program_data, NULL);
34.76 +
34.77 + g_list_free (list);
34.78 +}
34.79 +
34.80 +void
34.81 +gmyth_channel_info_print(GMythChannelInfo *channel_info)
34.82 +{
34.83 + if ( channel_info != NULL )
34.84 + {
34.85 + gmyth_debug("ChannelInfo (Name, Num, ID) = (%s, %s, %d)\n",
34.86 + channel_info->channel_name->str, channel_info->channel_num->str,
34.87 + channel_info->channel_ID);
34.88 + }
34.89 +}
34.90 +
34.91 +void
34.92 +gmyth_program_info_print(GMythProgramInfo *program_info)
34.93 +{
34.94 +
34.95 + if ( program_info != NULL ) {
34.96 +
34.97 + gmyth_debug( "ProgramInfo\n\tTitle = %s\n\t"
34.98 + "Description = %s\n\t"
34.99 + "Start time= %s\t"
34.100 + "End time = %s\n"
34.101 + "Path name = %s\n"
34.102 + "File size = %lld\n"
34.103 + , program_info->title->str,
34.104 + program_info->description->str,
34.105 + gmyth_util_time_to_string_from_time_val(program_info->startts),
34.106 + gmyth_util_time_to_string_from_time_val(program_info->endts),
34.107 + program_info->pathname->str,
34.108 + program_info->filesize );
34.109 +
34.110 + }
34.111 +
34.112 +}
34.113 +
34.114 +static void
34.115 +free_channel_data(gpointer data, gpointer user_data)
34.116 +{
34.117 + if(data)
34.118 + g_free((GMythChannelInfo*) data);
34.119 +}
34.120 +
34.121 +static void
34.122 +free_program_data(gpointer data, gpointer user_data)
34.123 +{
34.124 + if(data)
34.125 + g_object_unref((GMythProgramInfo*) data);
34.126 +}
34.127 +
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/branches/gmyth-0.1b/src/gmyth_common.h Thu Feb 01 18:42:01 2007 +0000
35.3 @@ -0,0 +1,61 @@
35.4 +/**
35.5 + * GMyth Library
35.6 + *
35.7 + * @file gmyth/gmyth_common.h
35.8 + *
35.9 + * @brief <p> This file contains basic common functions for the gmyth library.
35.10 + *
35.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
35.12 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
35.13 + *
35.14 + *//*
35.15 + *
35.16 + * This program is free software; you can redistribute it and/or modify
35.17 + * it under the terms of the GNU Lesser General Public License as published by
35.18 + * the Free Software Foundation; either version 2 of the License, or
35.19 + * (at your option) any later version.
35.20 + *
35.21 + * This program is distributed in the hope that it will be useful,
35.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
35.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35.24 + * GNU General Public License for more details.
35.25 + *
35.26 + * You should have received a copy of the GNU Lesser General Public License
35.27 + * along with this program; if not, write to the Free Software
35.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35.29 + */
35.30 +
35.31 +#ifndef GMYTH_COMMON_H_
35.32 +#define GMYTH_COMMON_H_
35.33 +
35.34 +#include <glib.h>
35.35 +#include <time.h>
35.36 +
35.37 +#include "gmyth_programinfo.h"
35.38 +
35.39 +G_BEGIN_DECLS
35.40 +
35.41 +/**
35.42 + * The GMythChannelInfo structure represents the channel information
35.43 + * stored in the backend database.
35.44 + */
35.45 +typedef struct {
35.46 + /** The channel ID in backend database */
35.47 + gint channel_ID;
35.48 +
35.49 + GString* channel_num;
35.50 +
35.51 + /** The channel name in backend database */
35.52 + GString *channel_name;
35.53 +
35.54 +} GMythChannelInfo;
35.55 +
35.56 +void gmyth_free_channel_list(GList *list);
35.57 +void gmyth_free_program_list(GList *list);
35.58 +
35.59 +void gmyth_channel_info_print(GMythChannelInfo *channel_info);
35.60 +void gmyth_program_info_print(GMythProgramInfo *program_info);
35.61 +
35.62 +G_END_DECLS
35.63 +
35.64 +#endif /* GMYTH_COMMON_H_ */
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/branches/gmyth-0.1b/src/gmyth_debug.c Thu Feb 01 18:42:01 2007 +0000
36.3 @@ -0,0 +1,56 @@
36.4 +/**
36.5 + * GMyth Library
36.6 + *
36.7 + * @file gmyth/gmyth_debug.c
36.8 + *
36.9 + *
36.10 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
36.11 + * @author Renato Filho <renato.filho@indt.org.br>
36.12 + *
36.13 + *//*
36.14 + *
36.15 + * This program is free software; you can redistribute it and/or modify
36.16 + * it under the terms of the GNU Lesser General Public License as published by
36.17 + * the Free Software Foundation; either version 2 of the License, or
36.18 + * (at your option) any later version.
36.19 + *
36.20 + * This program is distributed in the hope that it will be useful,
36.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
36.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36.23 + * GNU General Public License for more details.
36.24 + *
36.25 + * You should have received a copy of the GNU Lesser General Public License
36.26 + * along with this program; if not, write to the Free Software
36.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36.28 + */
36.29 +
36.30 +#ifdef HAVE_CONFIG_H
36.31 +#include "config.h"
36.32 +#endif
36.33 +
36.34 +#include "gmyth_debug.h"
36.35 +
36.36 +void
36.37 +gmyth_debug_real (const char *func,
36.38 + const char *file,
36.39 + const int line,
36.40 + gboolean newline,
36.41 + const char *format, ...)
36.42 +{
36.43 + va_list args;
36.44 + char buffer[1025];
36.45 + char str_time[255];
36.46 + time_t the_time;
36.47 +
36.48 + va_start (args, format);
36.49 +
36.50 + g_vsnprintf (buffer, 1024, format, args);
36.51 +
36.52 + va_end (args);
36.53 +
36.54 + time (&the_time);
36.55 + strftime (str_time, 254, "%H:%M:%S", localtime (&the_time));
36.56 +
36.57 + g_printerr (newline ? "(%s) [%p] [%s] %s:%d: %s\n" : "(%s) [%p] [%s] %s:%d: %s",
36.58 + str_time, g_thread_self (), func, file, line, buffer);
36.59 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/branches/gmyth-0.1b/src/gmyth_debug.h Thu Feb 01 18:42:01 2007 +0000
37.3 @@ -0,0 +1,49 @@
37.4 +/**
37.5 + * GMyth Library
37.6 + *
37.7 + * @file gmyth/gmyth_debug.h
37.8 + *
37.9 + *
37.10 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
37.11 + * @author Renato Filho <renato.filho@indt.org.br>
37.12 + *
37.13 + *//*
37.14 + *
37.15 + * This program is free software; you can redistribute it and/or modify
37.16 + * it under the terms of the GNU Lesser General Public License as published by
37.17 + * the Free Software Foundation; either version 2 of the License, or
37.18 + * (at your option) any later version.
37.19 + *
37.20 + * This program is distributed in the hope that it will be useful,
37.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
37.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37.23 + * GNU General Public License for more details.
37.24 + *
37.25 + * You should have received a copy of the GNU Lesser General Public License
37.26 + * along with this program; if not, write to the Free Software
37.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37.28 + */
37.29 +
37.30 +#ifndef __GMYTH_DEBUG_H__
37.31 +#define __GMYTH_DEBUG_H__
37.32 +
37.33 +#include <stdarg.h>
37.34 +#include <glib.h>
37.35 +#include <time.h>
37.36 +
37.37 +G_BEGIN_DECLS
37.38 +
37.39 +#ifdef GMYTH_USE_DEBUG
37.40 +#define gmyth_debug(...) gmyth_debug_real (__FUNCTION__, __FILE__, __LINE__, TRUE, __VA_ARGS__)
37.41 +#else
37.42 +#define gmyth_debug(...)
37.43 +#endif
37.44 +
37.45 +void gmyth_debug_real (const char *func,
37.46 + const char *file,
37.47 + int line,
37.48 + gboolean newline,
37.49 + const char *format, ...) G_GNUC_PRINTF (5, 6);
37.50 +
37.51 +G_END_DECLS
37.52 +#endif
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/branches/gmyth-0.1b/src/gmyth_epg.c Thu Feb 01 18:42:01 2007 +0000
38.3 @@ -0,0 +1,299 @@
38.4 +/**
38.5 + * GMyth Library
38.6 + *
38.7 + * @file gmyth/gmyth_epg.c
38.8 + *
38.9 + * @brief <p> GMythEPG class provides access to the program and channel data
38.10 + * from the Electronic Program Guide (EPG) of the Mythtv backend.
38.11 + *
38.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
38.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
38.14 + *
38.15 + *//*
38.16 + *
38.17 + * This program is free software; you can redistribute it and/or modify
38.18 + * it under the terms of the GNU Lesser General Public License as published by
38.19 + * the Free Software Foundation; either version 2 of the License, or
38.20 + * (at your option) any later version.
38.21 + *
38.22 + * This program is distributed in the hope that it will be useful,
38.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
38.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38.25 + * GNU General Public License for more details.
38.26 + *
38.27 + * You should have received a copy of the GNU Lesser General Public License
38.28 + * along with this program; if not, write to the Free Software
38.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38.30 + */
38.31 +
38.32 +#ifdef HAVE_CONFIG_H
38.33 +#include "config.h"
38.34 +#endif
38.35 +
38.36 +#include <mysql/mysql.h>
38.37 +#include <stdlib.h>
38.38 +#include <string.h>
38.39 +#include <assert.h>
38.40 +
38.41 +#include "gmyth_epg.h"
38.42 +#include "gmyth_programinfo.h"
38.43 +#include "gmyth_util.h"
38.44 +#include "gmyth_debug.h"
38.45 +
38.46 +static void gmyth_epg_class_init (GMythEPGClass *klass);
38.47 +static void gmyth_epg_init (GMythEPG *object);
38.48 +
38.49 +static void gmyth_epg_dispose (GObject *object);
38.50 +static void gmyth_epg_finalize (GObject *object);
38.51 +
38.52 +G_DEFINE_TYPE(GMythEPG, gmyth_epg, G_TYPE_OBJECT)
38.53 +
38.54 +static void
38.55 +gmyth_epg_class_init (GMythEPGClass *klass)
38.56 +{
38.57 + GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
38.58 +
38.59 + gobject_class->dispose = gmyth_epg_dispose;
38.60 + gobject_class->finalize = gmyth_epg_finalize;
38.61 +}
38.62 +
38.63 +static void
38.64 +gmyth_epg_init (GMythEPG *gmyth_epg)
38.65 +{
38.66 +
38.67 +}
38.68 +
38.69 +static void
38.70 +gmyth_epg_dispose (GObject *object)
38.71 +{
38.72 + //GMythEPG *gmyth_epg = GMYTH_EPG(object);
38.73 +
38.74 + G_OBJECT_CLASS (gmyth_epg_parent_class)->dispose (object);
38.75 +}
38.76 +
38.77 +static void
38.78 +gmyth_epg_finalize (GObject *object)
38.79 +{
38.80 + g_signal_handlers_destroy (object);
38.81 +
38.82 + G_OBJECT_CLASS (gmyth_epg_parent_class)->finalize (object);
38.83 +}
38.84 +
38.85 +/**
38.86 + * Creates a new instance of GMythEPG.
38.87 + *
38.88 + * @return a new instance of GMythEPG.
38.89 + */
38.90 +GMythEPG*
38.91 +gmyth_epg_new (void)
38.92 +{
38.93 + GMythEPG *epg = GMYTH_EPG (g_object_new(GMYTH_EPG_TYPE, NULL));
38.94 +
38.95 + return epg;
38.96 +}
38.97 +
38.98 +/** Connects to the Mysql database in the backend. The backend address
38.99 + * is loaded from the GMythSettings instance.
38.100 + *
38.101 + * @param gmyth_epg the GMythEPG instance to be connected.
38.102 + * @return true if connection was success, false if failed.
38.103 + */
38.104 +gboolean
38.105 +gmyth_epg_connect (GMythEPG *gmyth_epg, GMythBackendInfo *backend_info)
38.106 +{
38.107 + assert(gmyth_epg);
38.108 +
38.109 + if (gmyth_epg->sqlquery == NULL) {
38.110 + gmyth_debug ("[%s] Creating gmyth_query", __FUNCTION__);
38.111 + gmyth_epg->sqlquery = gmyth_query_new ( );
38.112 + }
38.113 +
38.114 + if (!gmyth_query_connect(gmyth_epg->sqlquery, backend_info)) {
38.115 + g_warning ("[%s] Error while connecting to db", __FUNCTION__);
38.116 + return FALSE;
38.117 + }
38.118 +
38.119 + return TRUE;
38.120 +}
38.121 +
38.122 +/** Disconnects from the Mysql database in the backend.
38.123 + *
38.124 + * @param gmyth_epg the GMythEPG instance to be disconnected
38.125 + * @return true if disconnection was success, false if failed.
38.126 + */
38.127 +gboolean
38.128 +gmyth_epg_disconnect (GMythEPG *gmyth_epg)
38.129 +{
38.130 + assert(gmyth_epg);
38.131 +
38.132 + if (gmyth_epg->sqlquery != NULL) {
38.133 + g_object_unref (gmyth_epg->sqlquery);
38.134 + gmyth_epg->sqlquery = NULL;
38.135 + }
38.136 +
38.137 + return TRUE;
38.138 +}
38.139 +
38.140 +/** Retrieves the available list of channels from the backend Mysql database.
38.141 + *
38.142 + * @param gmyth_epg the GMythEPG instance.
38.143 + * @param glist_ptr the GList pointer to be filled with the loaded list address.
38.144 + * @return The amount of channels retrieved from database, or -1 if error.
38.145 + */
38.146 +gint
38.147 +gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr)
38.148 +{
38.149 + MYSQL_RES *msql_res;
38.150 +
38.151 + assert(gmyth_epg);
38.152 +
38.153 + msql_res = gmyth_query_process_statement (gmyth_epg->sqlquery,
38.154 + "SELECT chanid, channum, name FROM channel;");
38.155 +
38.156 + (*glist_ptr) = NULL;
38.157 +
38.158 + if (msql_res == NULL) {
38.159 + g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
38.160 + return -1;
38.161 + } else {
38.162 + MYSQL_ROW row;
38.163 + GMythChannelInfo *channel_info;
38.164 +
38.165 + while ((row = mysql_fetch_row (msql_res)) != NULL){
38.166 +
38.167 + channel_info = g_new0(GMythChannelInfo, 1);
38.168 + channel_info->channel_ID = g_ascii_strtoull (row[0], NULL, 10);
38.169 + channel_info->channel_num = g_string_new (row[1]);
38.170 + channel_info->channel_name = g_string_new (row[2]);
38.171 +
38.172 + gmyth_channel_info_print(channel_info);
38.173 +
38.174 + (*glist_ptr) = g_list_append ((*glist_ptr), channel_info);
38.175 + }
38.176 + }
38.177 + mysql_free_result (msql_res);
38.178 + return (!(*glist_ptr)) ? 0 : g_list_length (*glist_ptr);
38.179 +}
38.180 +
38.181 +/**
38.182 + * Retrieves the available list of channels from the backend Mysql database.
38.183 + *
38.184 + * @param gmyth_epg the GMythEPG instance.
38.185 + * @param proglist the GList pointer to be filled with the loaded list.
38.186 + * @param chan_num the channel num on which to search for program.
38.187 + * @param starttime the start time to search for programs.
38.188 + * @param endtime the end time to search for programs.
38.189 + * @return The amount of channels retrieved from database, or -1 if error.
38.190 + */
38.191 +gint
38.192 +gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
38.193 + const gint chan_num, GTimeVal *starttime, GTimeVal *endtime)
38.194 +{
38.195 +
38.196 + gchar *startts = gmyth_util_time_to_string_from_time_val(starttime);
38.197 + gchar *endts = gmyth_util_time_to_string_from_time_val(endtime);
38.198 + MYSQL_ROW row;
38.199 + GString *querystr;
38.200 +
38.201 + assert(gmyth_epg);
38.202 +
38.203 + querystr = g_string_new(
38.204 + "SELECT DISTINCT program.chanid, program.starttime, program.endtime, "
38.205 + " program.title, program.subtitle, program.description, "
38.206 + " program.category, channel.channum, channel.callsign, "
38.207 + " channel.name, program.previouslyshown, channel.commfree, "
38.208 + " channel.outputfilters, program.seriesid, program.programid, "
38.209 + " program.airdate, program.stars, program.originalairdate, "
38.210 + " program.category_type, oldrecstatus.recordid, "
38.211 + " oldrecstatus.rectype, oldrecstatus.recstatus, "
38.212 + " oldrecstatus.findid "
38.213 + "FROM program "
38.214 + "LEFT JOIN channel ON program.chanid = channel.chanid "
38.215 + "LEFT JOIN oldrecorded AS oldrecstatus ON "
38.216 + " program.title = oldrecstatus.title AND "
38.217 + " channel.callsign = oldrecstatus.station AND "
38.218 + " program.starttime = oldrecstatus.starttime "
38.219 + );
38.220 +
38.221 + g_string_append_printf (querystr,
38.222 + "WHERE program.chanid = %d "
38.223 + " AND program.endtime >= '%s' "
38.224 + " AND program.starttime <= '%s' "
38.225 + " AND program.manualid = 0 ",
38.226 + chan_num, startts, endts);
38.227 +
38.228 + if (!g_strrstr(querystr->str, " GROUP BY "))
38.229 + querystr = g_string_append(querystr,
38.230 + " GROUP BY program.starttime, channel.channum, "
38.231 + " channel.callsign, program.title ");
38.232 +
38.233 + if (!g_strrstr(querystr->str, " LIMIT "))
38.234 + querystr = g_string_append(querystr, " LIMIT 1000 ");
38.235 +
38.236 + MYSQL_RES *res_set =
38.237 + gmyth_query_process_statement(gmyth_epg->sqlquery, querystr->str);
38.238 +
38.239 + if (res_set == NULL) {
38.240 + g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
38.241 + return -1;
38.242 + }
38.243 +
38.244 + (*proglist) = NULL;
38.245 + while ((row = mysql_fetch_row (res_set)) != NULL) {
38.246 +
38.247 + GMythProgramInfo *p = gmyth_program_info_new ();
38.248 + p->chanid = g_string_new (row[0]);
38.249 +
38.250 + p->startts = gmyth_util_string_to_time_val (row[1]);
38.251 + p->endts = gmyth_util_string_to_time_val (row[2]);
38.252 +
38.253 + p->recstartts = g_new0 (GTimeVal, 1);
38.254 + p->recstartts->tv_sec = p->startts->tv_sec;
38.255 + p->recstartts->tv_usec = p->startts->tv_usec;
38.256 +
38.257 + p->recendts = g_new0 (GTimeVal, 1);
38.258 + p->recendts->tv_sec = p->endts->tv_sec;
38.259 + p->recendts->tv_usec = p->endts->tv_usec;
38.260 +
38.261 + p->lastmodified = g_new0 (GTimeVal, 1);
38.262 + p->lastmodified->tv_sec = p->startts->tv_sec;
38.263 + p->lastmodified->tv_usec = p->startts->tv_usec;
38.264 +
38.265 + p->title = g_string_new (row[3]);
38.266 + p->subtitle = g_string_new (row[4]);
38.267 + p->description = g_string_new (row[5]);
38.268 + p->category = g_string_new (row[6]);
38.269 + p->chanstr = g_string_new (row[7]);
38.270 + p->chansign = g_string_new (row[8]);
38.271 + p->channame = g_string_new (row[9]);
38.272 + p->repeat = g_ascii_strtoull(row[10], NULL, 10);
38.273 + p->chancommfree = g_ascii_strtoull(row[11], NULL, 10);
38.274 + p->chanOutputFilters = g_string_new (row[12]);
38.275 + p->seriesid = g_string_new (row[13]);
38.276 + p->programid = g_string_new (row[14]);
38.277 + p->year = g_string_new (row[15]);
38.278 + p->stars = g_ascii_strtod(row[16], NULL);
38.279 +
38.280 + if (!row[17] || !strcmp(row[17], "")) {
38.281 + p->originalAirDate = 0;
38.282 + p->hasAirDate = FALSE;
38.283 + } else {
38.284 + p->originalAirDate = gmyth_util_string_to_time_val (row[17]);
38.285 + p->hasAirDate = TRUE;
38.286 + }
38.287 +
38.288 + p->catType = g_string_new (row[18]);
38.289 +
38.290 + *proglist = g_list_append((*proglist), p);
38.291 +
38.292 +#if 0
38.293 + gmyth_program_info_print(p);
38.294 +#endif
38.295 + }
38.296 +
38.297 + /* deallocate */
38.298 + mysql_free_result (res_set);
38.299 + g_string_free(querystr, TRUE);
38.300 +
38.301 + return TRUE;
38.302 +}
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/branches/gmyth-0.1b/src/gmyth_epg.h Thu Feb 01 18:42:01 2007 +0000
39.3 @@ -0,0 +1,75 @@
39.4 +/**
39.5 + * GMyth Library
39.6 + *
39.7 + * @file gmyth/gmyth_epg.h
39.8 + *
39.9 + * @brief <p> GMythEPG class provides access to the program and channel data
39.10 + * from the Electronic Program Guide (EPG) of the Mythtv backend.
39.11 + *
39.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
39.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
39.14 + *
39.15 + *//*
39.16 + *
39.17 + * This program is free software; you can redistribute it and/or modify
39.18 + * it under the terms of the GNU Lesser General Public License as published by
39.19 + * the Free Software Foundation; either version 2 of the License, or
39.20 + * (at your option) any later version.
39.21 + *
39.22 + * This program is distributed in the hope that it will be useful,
39.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
39.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39.25 + * GNU General Public License for more details.
39.26 + *
39.27 + * You should have received a copy of the GNU Lesser General Public License
39.28 + * along with this program; if not, write to the Free Software
39.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39.30 + */
39.31 +
39.32 +#ifndef GMYTH_EPG_H_
39.33 +#define GMYTH_EPG_H_
39.34 +
39.35 +#include <glib-object.h>
39.36 +
39.37 +#include "gmyth_query.h"
39.38 +#include "gmyth_common.h"
39.39 +
39.40 +G_BEGIN_DECLS
39.41 +
39.42 +#define GMYTH_EPG_TYPE (gmyth_epg_get_type ())
39.43 +#define GMYTH_EPG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE, GMythEPG))
39.44 +#define GMYTH_EPG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE, GMythEPGClass))
39.45 +#define IS_GMYTH_EPG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE))
39.46 +#define IS_GMYTH_EPG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE))
39.47 +#define GMYTH_EPG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_EPG_TYPE, GMythEPGClass))
39.48 +
39.49 +typedef struct _GMythEPG GMythEPG;
39.50 +typedef struct _GMythEPGClass GMythEPGClass;
39.51 +
39.52 +struct _GMythEPGClass
39.53 +{
39.54 + GObjectClass parent_class;
39.55 +
39.56 + /* callbacks */
39.57 + /* no one for now */
39.58 +};
39.59 +
39.60 +struct _GMythEPG
39.61 +{
39.62 + GObject parent;
39.63 +
39.64 + GMythQuery *sqlquery;
39.65 +};
39.66 +
39.67 +GType gmyth_epg_get_type (void);
39.68 +
39.69 +GMythEPG* gmyth_epg_new (void);
39.70 +
39.71 +gboolean gmyth_epg_connect (GMythEPG *gmyth_epg, GMythBackendInfo *backend_info);
39.72 +gboolean gmyth_epg_disconnect (GMythEPG *gmyth_epg);
39.73 +
39.74 +gint gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr);
39.75 +gint gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
39.76 + const gint chanNum, GTimeVal *starttime, GTimeVal *endtime);
39.77 +
39.78 +#endif /*GMYTH_EPG_H_*/
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/branches/gmyth-0.1b/src/gmyth_file_transfer.c Thu Feb 01 18:42:01 2007 +0000
40.3 @@ -0,0 +1,705 @@
40.4 +/**
40.5 + * GMyth Library
40.6 + *
40.7 + * @file gmyth/gmyth_file_transfer.c
40.8 + *
40.9 + * @brief <p> GMythFileTransfer deals with the file streaming media remote/local
40.10 + * transfering to the MythTV frontend.
40.11 + *
40.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
40.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
40.14 + *
40.15 + *//*
40.16 + *
40.17 + * This program is free software; you can redistribute it and/or modify
40.18 + * it under the terms of the GNU Lesser General Public License as published by
40.19 + * the Free Software Foundation; either version 2 of the License, or
40.20 + * (at your option) any later version.
40.21 + *
40.22 + * This program is distributed in the hope that it will be useful,
40.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
40.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40.25 + * GNU General Public License for more details.
40.26 + *
40.27 + * You should have received a copy of the GNU Lesser General Public License
40.28 + * along with this program; if not, write to the Free Software
40.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40.30 + *
40.31 + * GStreamer MythTV plug-in properties:
40.32 + * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
40.33 + * - path (qurl - remote file to be opened)
40.34 + * - port number *
40.35 + */
40.36 +
40.37 +#ifdef HAVE_CONFIG_H
40.38 +#include "config.h"
40.39 +#endif
40.40 +
40.41 +#include "gmyth_file_transfer.h"
40.42 +#include "gmyth_livetv.h"
40.43 +#include "gmyth_util.h"
40.44 +#include "gmyth_socket.h"
40.45 +#include "gmyth_stringlist.h"
40.46 +#include "gmyth_debug.h"
40.47 +#include "gmyth_uri.h"
40.48 +#include "gmyth_marshal.h"
40.49 +
40.50 +#include <unistd.h>
40.51 +#include <glib.h>
40.52 +
40.53 +#include <arpa/inet.h>
40.54 +#include <sys/types.h>
40.55 +#include <sys/socket.h>
40.56 +#include <netdb.h>
40.57 +#include <errno.h>
40.58 +#include <stdlib.h>
40.59 +#include <assert.h>
40.60 +
40.61 +#define GMYTHTV_QUERY_HEADER "QUERY_FILETRANSFER "
40.62 +
40.63 +/* default values to the file transfer parameters */
40.64 +#define GMYTHTV_USER_READ_AHEAD TRUE
40.65 +#define GMYTHTV_RETRIES -1
40.66 +#define GMYTHTV_FILE_SIZE 0
40.67 +
40.68 +#define GMYTHTV_BUFFER_SIZE 64*1024
40.69 +
40.70 +#define GMYTHTV_VERSION 30
40.71 +
40.72 +#define GMYTHTV_TRANSFER_MAX_WAITS 700
40.73 +
40.74 +#ifdef GMYTHTV_ENABLE_DEBUG
40.75 +#define GMYTHTV_ENABLE_DEBUG 1
40.76 +#else
40.77 +#undef GMYTHTV_ENABLE_DEBUG
40.78 +#endif
40.79 +
40.80 +/* this NDEBUG is to maintain compatibility with GMyth library */
40.81 +#ifndef NDEBUG
40.82 +#define GMYTHTV_ENABLE_DEBUG 1
40.83 +#endif
40.84 +
40.85 +enum myth_sock_types {
40.86 + GMYTH_PLAYBACK_TYPE = 0,
40.87 + GMYTH_MONITOR_TYPE,
40.88 + GMYTH_FILETRANSFER_TYPE,
40.89 + GMYTH_RINGBUFFER_TYPE
40.90 +};
40.91 +
40.92 +#define GMYTH_FILE_TRANSFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferPrivate))
40.93 +
40.94 +struct _GMythFileTransferPrivate {
40.95 +
40.96 + GMythLiveTV *livetv;
40.97 +
40.98 + gboolean do_next_program_chain;
40.99 +
40.100 +};
40.101 +
40.102 +static void gmyth_file_transfer_class_init (GMythFileTransferClass *klass);
40.103 +static void gmyth_file_transfer_init (GMythFileTransfer *object);
40.104 +
40.105 +static void gmyth_file_transfer_dispose (GObject *object);
40.106 +static void gmyth_file_transfer_finalize (GObject *object);
40.107 +
40.108 +static void gmyth_file_transfer_program_info_changed( GMythFileTransfer *transfer,
40.109 + gint msg_code, gpointer livetv_transfer );
40.110 +
40.111 +static gboolean gmyth_connect_to_backend (GMythFileTransfer *transfer);
40.112 +
40.113 +void gmyth_file_transfer_close( GMythFileTransfer *transfer );
40.114 +
40.115 +static gboolean myth_control_acquire_context( gboolean do_wait );
40.116 +
40.117 +static gboolean myth_control_release_context( );
40.118 +
40.119 +G_DEFINE_TYPE(GMythFileTransfer, gmyth_file_transfer, G_TYPE_OBJECT)
40.120 +
40.121 +static void
40.122 +gmyth_file_transfer_class_init (GMythFileTransferClass *klass)
40.123 +{
40.124 + GObjectClass *gobject_class;
40.125 + GMythFileTransferClass *gtransfer_class;
40.126 +
40.127 + gobject_class = (GObjectClass *) klass;
40.128 + gtransfer_class = (GMythFileTransferClass *) gobject_class;
40.129 +
40.130 + gobject_class->dispose = gmyth_file_transfer_dispose;
40.131 + gobject_class->finalize = gmyth_file_transfer_finalize;
40.132 +
40.133 + g_type_class_add_private (gobject_class, sizeof (GMythFileTransferPrivate));
40.134 +
40.135 + gtransfer_class->program_info_changed_handler = gmyth_file_transfer_program_info_changed;
40.136 +
40.137 + gtransfer_class->program_info_changed_handler_signal_id =
40.138 + g_signal_new ( "program-info-changed",
40.139 + G_TYPE_FROM_CLASS (gtransfer_class),
40.140 + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
40.141 + 0,
40.142 + NULL,
40.143 + NULL,
40.144 + gmyth_marshal_VOID__INT_POINTER,
40.145 + G_TYPE_NONE,
40.146 + 2,
40.147 + G_TYPE_INT,
40.148 + G_TYPE_POINTER );
40.149 +
40.150 +}
40.151 +
40.152 +static void
40.153 +gmyth_file_transfer_init (GMythFileTransfer *transfer)
40.154 +{
40.155 + g_return_if_fail( transfer != NULL );
40.156 +
40.157 + transfer->readposition = 0;
40.158 + transfer->filesize = GMYTHTV_FILE_SIZE;
40.159 +
40.160 + transfer->priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
40.161 +
40.162 + transfer->priv->do_next_program_chain = FALSE;
40.163 + transfer->priv->livetv = NULL;
40.164 +
40.165 + transfer->control_sock = NULL;
40.166 + transfer->sock = NULL;
40.167 +
40.168 + transfer->mutex = g_mutex_new();
40.169 +
40.170 + g_signal_connect ( G_OBJECT (transfer), "program-info-changed",
40.171 + (GCallback)(GMYTH_FILE_TRANSFER_GET_CLASS(transfer)->program_info_changed_handler),
40.172 + NULL );
40.173 +
40.174 +}
40.175 +
40.176 +static void
40.177 +gmyth_file_transfer_dispose (GObject *object)
40.178 +{
40.179 + GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER (object);
40.180 +
40.181 + if ( transfer->mutex != NULL )
40.182 + {
40.183 + g_mutex_free( transfer->mutex );
40.184 + transfer->mutex = NULL;
40.185 + }
40.186 +
40.187 + if ( transfer->control_sock != NULL )
40.188 + {
40.189 + g_object_unref( transfer->control_sock );
40.190 + transfer->control_sock = NULL;
40.191 + }
40.192 +
40.193 + if ( transfer->sock != NULL )
40.194 + {
40.195 + g_object_unref( transfer->sock );
40.196 + transfer->sock = NULL;
40.197 + }
40.198 +
40.199 + if ( transfer->filename != NULL )
40.200 + {
40.201 + g_free( transfer->filename );
40.202 + transfer->filename = NULL;
40.203 + }
40.204 +
40.205 + G_OBJECT_CLASS (gmyth_file_transfer_parent_class)->dispose (object);
40.206 +}
40.207 +
40.208 +static void
40.209 +gmyth_file_transfer_finalize (GObject *object)
40.210 +{
40.211 + g_signal_handlers_destroy (object);
40.212 +
40.213 + G_OBJECT_CLASS (gmyth_file_transfer_parent_class)->finalize (object);
40.214 +}
40.215 +
40.216 +// fixme: do we need the card_id????
40.217 +GMythFileTransfer*
40.218 +gmyth_file_transfer_new ( const GMythBackendInfo *backend_info)
40.219 +{
40.220 + GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER (g_object_new (GMYTH_FILE_TRANSFER_TYPE, NULL));
40.221 +
40.222 + transfer->backend_info = (GMythBackendInfo *)backend_info;
40.223 + g_object_ref (transfer->backend_info);
40.224 +
40.225 + return transfer;
40.226 +}
40.227 +
40.228 +GMythFileTransfer*
40.229 +gmyth_file_transfer_new_with_uri (const gchar* uri_str)
40.230 +{
40.231 + GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER (g_object_new (GMYTH_FILE_TRANSFER_TYPE, NULL));
40.232 +
40.233 + transfer->backend_info = gmyth_backend_info_new_with_uri (uri_str);
40.234 +
40.235 + return transfer;
40.236 +}
40.237 +
40.238 +gboolean
40.239 +gmyth_file_transfer_open (GMythFileTransfer *transfer, const gchar* filename)
40.240 +{
40.241 + gboolean ret = TRUE;
40.242 +
40.243 + g_return_val_if_fail (transfer != NULL, FALSE);
40.244 + g_return_val_if_fail (filename != NULL, FALSE);
40.245 +
40.246 + if (transfer->filename != NULL)
40.247 + {
40.248 + g_free (transfer->filename);
40.249 + transfer->filename = NULL;
40.250 + }
40.251 +
40.252 + transfer->filename = g_strdup (filename);
40.253 +
40.254 + /* configure the control socket */
40.255 + if (transfer->control_sock == NULL) {
40.256 + if (!gmyth_connect_to_backend (transfer)) {
40.257 + gmyth_debug ("Connection to backend failed (Control Socket).\n");
40.258 + ret = FALSE;
40.259 + }
40.260 + } else {
40.261 + g_warning("Remote transfer control socket already created.\n");
40.262 + }
40.263 +
40.264 + gmyth_debug ("Got file with size = %lld.\n", transfer->filesize);
40.265 +
40.266 + return ret;
40.267 +
40.268 +}
40.269 +
40.270 +static gboolean
40.271 +gmyth_connect_to_backend (GMythFileTransfer *transfer)
40.272 +{
40.273 + GString *base_str = NULL;
40.274 + GString *hostname = NULL;
40.275 + GMythStringList *strlist = NULL;
40.276 + gboolean ret = TRUE;
40.277 +
40.278 + g_return_val_if_fail (transfer != NULL, FALSE );
40.279 +
40.280 + base_str = g_string_new ("");
40.281 +
40.282 + /* Creates the control socket */
40.283 + if (transfer->control_sock != NULL) {
40.284 + g_object_unref (transfer->control_sock);
40.285 + transfer->control_sock = NULL;
40.286 + }
40.287 +
40.288 + transfer->control_sock = gmyth_socket_new();
40.289 +
40.290 + // Connects the socket, send Mythtv ANN command and verify Mythtv protocol version
40.291 + if (!gmyth_socket_connect_to_backend (transfer->control_sock,
40.292 + transfer->backend_info->hostname, transfer->backend_info->port, TRUE)) {
40.293 +
40.294 + g_object_unref (transfer->control_sock);
40.295 + transfer->control_sock = NULL;
40.296 + return FALSE;
40.297 + }
40.298 +
40.299 + /* Creates the data socket */
40.300 + if (transfer->sock != NULL) {
40.301 + g_object_unref (transfer->sock);
40.302 + transfer->sock = NULL;
40.303 + }
40.304 +
40.305 + transfer->sock = gmyth_socket_new ();
40.306 + gmyth_socket_connect (transfer->sock, transfer->backend_info->hostname, transfer->backend_info->port);
40.307 +
40.308 + strlist = gmyth_string_list_new();
40.309 + hostname = gmyth_socket_get_local_hostname();
40.310 + gmyth_debug( "[%s] MythTV version (from backend) = %d.\n", __FUNCTION__, transfer->control_sock->mythtv_version );
40.311 + if ( transfer->control_sock->mythtv_version > 26 )
40.312 + g_string_printf( base_str, "ANN FileTransfer %s 1 -1", hostname->str);
40.313 + else
40.314 + g_string_printf( base_str, "ANN FileTransfer %s", hostname->str);
40.315 +
40.316 + gmyth_string_list_append_string (strlist, base_str );
40.317 + gmyth_string_list_append_char_array (strlist, transfer->filename);
40.318 +
40.319 + gmyth_socket_write_stringlist (transfer->sock, strlist );
40.320 + gmyth_socket_read_stringlist (transfer->sock, strlist );
40.321 +
40.322 + /* file identification used in future file transfer requests to backend */
40.323 + transfer->file_id = gmyth_string_list_get_int( strlist, 1 );
40.324 +
40.325 + /* Myth URI stream file size - decoded using two 8-bytes sequences (64 bits/long long types) */
40.326 + transfer->filesize = gmyth_util_decode_long_long( strlist, 2 );
40.327 +
40.328 + gmyth_debug ( "[%s] ***** Received: recordernum = %d, filesize = %" G_GUINT64_FORMAT "\n", __FUNCTION__,
40.329 + transfer->file_id, transfer->filesize );
40.330 +
40.331 + if (transfer->filesize < 0 ) {
40.332 + gmyth_debug ( "[%s] Got filesize equals to %llu is lesser than 0 [invalid stream file]\n", __FUNCTION__, transfer->filesize );
40.333 + g_object_unref (transfer->sock);
40.334 + transfer->sock = NULL;
40.335 + ret = FALSE;
40.336 + goto cleanup;
40.337 + }
40.338 +
40.339 +cleanup:
40.340 +
40.341 + if ( strlist != NULL )
40.342 + g_object_unref( strlist );
40.343 +
40.344 + g_string_free (base_str, TRUE);
40.345 + g_string_free (hostname, TRUE);
40.346 +
40.347 + return ret;
40.348 +}
40.349 +
40.350 +void
40.351 +gmyth_file_transfer_emit_program_info_changed_signal ( GMythFileTransfer *transfer, gint msg_code,
40.352 + gpointer live_tv )
40.353 +{
40.354 + /*
40.355 + g_signal_emit_by_name ( G_OBJECT(transfer),
40.356 + "program-info-changed",
40.357 + msg_code, live_tv );
40.358 + */
40.359 +
40.360 + gmyth_debug( "Calling signal handler... [FILE_TRANSFER]" );
40.361 +
40.362 + g_signal_emit ( transfer,
40.363 + GMYTH_FILE_TRANSFER_GET_CLASS (transfer)->program_info_changed_handler_signal_id,
40.364 + 0, /* details */
40.365 + msg_code, live_tv );
40.366 +
40.367 +}
40.368 +
40.369 +gboolean
40.370 +gmyth_file_transfer_is_open (GMythFileTransfer *transfer)
40.371 +{
40.372 + GMythStringList *strlist;
40.373 + GString *query;
40.374 +
40.375 + g_return_val_if_fail (transfer->control_sock != NULL, FALSE);
40.376 + g_return_val_if_fail (transfer->sock != NULL, FALSE);
40.377 +
40.378 + strlist = gmyth_string_list_new();
40.379 + query = g_string_new (GMYTHTV_QUERY_HEADER);
40.380 + g_string_append_printf (query, "%d", transfer->file_id );
40.381 +
40.382 + gmyth_string_list_append_string (strlist, query );
40.383 + gmyth_string_list_append_char_array( strlist, "IS_OPEN" );
40.384 +
40.385 + gmyth_socket_write_stringlist( transfer->control_sock, strlist );
40.386 + gmyth_socket_read_stringlist( transfer->control_sock, strlist );
40.387 +
40.388 + g_string_free (query, TRUE);
40.389 + g_object_unref (strlist);
40.390 +
40.391 + return ( strlist != NULL && gmyth_string_list_get_int( strlist, 0 ) == 1 );
40.392 +}
40.393 +
40.394 +void
40.395 +gmyth_file_transfer_close( GMythFileTransfer *transfer )
40.396 +{
40.397 + GMythStringList *strlist;
40.398 + GString *query;
40.399 +
40.400 + g_return_if_fail (transfer->control_sock != NULL);
40.401 +
40.402 + strlist = gmyth_string_list_new( );
40.403 + query = g_string_new (GMYTHTV_QUERY_HEADER);
40.404 + g_string_append_printf( query, "%d", transfer->file_id);
40.405 +
40.406 + gmyth_string_list_append_string( strlist, query );
40.407 + gmyth_string_list_append_char_array( strlist, "DONE" );
40.408 +
40.409 + if ( gmyth_socket_sendreceive_stringlist(transfer->control_sock, strlist) <= 0 ) {
40.410 + // fixme: time out???
40.411 + g_printerr( "Remote file timeout.\n" );
40.412 + }
40.413 +
40.414 + g_string_free (query, TRUE);
40.415 + g_object_unref (strlist);
40.416 +
40.417 + if (transfer->sock) {
40.418 + g_object_unref( transfer->sock );
40.419 + transfer->sock = NULL;
40.420 + }
40.421 +
40.422 + if (transfer->control_sock) {
40.423 + g_object_unref( transfer->control_sock );
40.424 + transfer->control_sock = NULL;
40.425 + }
40.426 +
40.427 +}
40.428 +
40.429 +gint64
40.430 +gmyth_file_transfer_seek(GMythFileTransfer *transfer, guint64 pos, gint whence)
40.431 +{
40.432 + GMythStringList *strlist = gmyth_string_list_new();
40.433 + GString *query;
40.434 +
40.435 + g_return_val_if_fail (transfer->sock != NULL, -1);
40.436 + g_return_val_if_fail (transfer->control_sock != NULL, -1);
40.437 +
40.438 + strlist = gmyth_string_list_new();
40.439 + query = g_string_new (GMYTHTV_QUERY_HEADER);
40.440 + g_string_append_printf (query, "%d", transfer->file_id);
40.441 +
40.442 + myth_control_acquire_context( TRUE );
40.443 +
40.444 + gmyth_string_list_append_string( strlist, query );
40.445 + gmyth_string_list_append_char_array( strlist, "SEEK" );
40.446 + gmyth_string_list_append_uint64( strlist, pos );
40.447 +
40.448 + gmyth_string_list_append_int( strlist, whence );
40.449 +
40.450 + if (pos > 0 )
40.451 + gmyth_string_list_append_uint64( strlist, pos );
40.452 + else
40.453 + gmyth_string_list_append_uint64( strlist, transfer->readposition );
40.454 +
40.455 + gmyth_socket_sendreceive_stringlist( transfer->control_sock, strlist );
40.456 +
40.457 + gint64 retval = gmyth_string_list_get_int64(strlist, 0);
40.458 + transfer->readposition = retval;
40.459 + gmyth_debug ( "[%s] got reading position pointer from the streaming = %lld\n",
40.460 + __FUNCTION__, retval );
40.461 +
40.462 + myth_control_release_context( );
40.463 +
40.464 + return retval;
40.465 +}
40.466 +
40.467 +static gboolean
40.468 +myth_control_acquire_context( gboolean do_wait )
40.469 +{
40.470 + gboolean ret = TRUE;
40.471 + //guint max_iter = 50;
40.472 +
40.473 + //g_mutex_lock( mutex );
40.474 +
40.475 + //while ( !has_io_access )
40.476 + // g_cond_wait( io_watcher_cond, mutex );
40.477 +
40.478 + //has_io_access = FALSE;
40.479 +
40.480 + //myth_control_acquire_context (FALSE);
40.481 +
40.482 + /*
40.483 + if ( do_wait ) {
40.484 + while ( --max_iter > 0 && !g_main_context_wait( io_watcher_context, io_watcher_cond, mutex ) )
40.485 + ret = FALSE;
40.486 + } else if ( !g_main_context_acquire( io_watcher_context ) )
40.487 + ret = FALSE;
40.488 + */
40.489 +
40.490 + //g_static_mutex_lock( &st_mutex );
40.491 +
40.492 + return ret;
40.493 +}
40.494 +
40.495 +static gboolean
40.496 +myth_control_release_context( )
40.497 +{
40.498 + gboolean ret = TRUE;
40.499 +
40.500 + //g_static_mutex_unlock( &st_mutex );
40.501 +
40.502 + //g_main_context_release( io_watcher_context );
40.503 +
40.504 + //g_main_context_wakeup( io_watcher_context );
40.505 +
40.506 + //has_io_access = TRUE;
40.507 +
40.508 + //g_cond_broadcast( io_watcher_cond );
40.509 +
40.510 + //g_mutex_unlock( mutex );
40.511 +
40.512 + return ret;
40.513 +}
40.514 +
40.515 +gint
40.516 +gmyth_file_transfer_read(GMythFileTransfer *transfer, GByteArray *data, gint size, gboolean read_unlimited)
40.517 +{
40.518 + gint bytes_sent = 0;
40.519 + gsize bytes_read = 0;
40.520 + gsize total_read = 0;
40.521 +
40.522 + GError *error = NULL;
40.523 +
40.524 + GIOChannel *io_channel;
40.525 + GIOChannel *io_channel_control;
40.526 +
40.527 + GIOCondition io_cond;
40.528 + GIOCondition io_cond_control;
40.529 + GIOStatus io_status = G_IO_STATUS_NORMAL, io_status_control = G_IO_STATUS_NORMAL;
40.530 +
40.531 + gboolean ret = TRUE;
40.532 +
40.533 + GString *query;
40.534 +
40.535 + g_return_val_if_fail ( data != NULL, -2 );
40.536 +
40.537 + io_channel = transfer->sock->sd_io_ch;
40.538 + io_channel_control = transfer->control_sock->sd_io_ch;
40.539 +
40.540 + io_status = g_io_channel_set_encoding( io_channel, NULL, &error );
40.541 + if ( io_status == G_IO_STATUS_NORMAL )
40.542 + gmyth_debug ( "[%s] Setting encoding to binary data socket).\n", __FUNCTION__ );
40.543 +
40.544 + io_cond = g_io_channel_get_buffer_condition( io_channel );
40.545 +
40.546 + io_cond_control = g_io_channel_get_buffer_condition( io_channel );
40.547 + if ( transfer->sock == NULL || ( io_status == G_IO_STATUS_ERROR ) ) {
40.548 + g_printerr( "gmyth_file_transfer_read(): Called with no raw socket.\n" );
40.549 + //exit(0); // fixme remove this
40.550 + return -1;
40.551 + }
40.552 +
40.553 + if ( transfer->control_sock == NULL || ( io_status_control == G_IO_STATUS_ERROR ) ) {
40.554 + g_printerr( "gmyth_file_transfer_read(): Called with no control socket.\n" );
40.555 + //exit(0); // fixme remove this
40.556 + return -1;
40.557 + }
40.558 +
40.559 + query = g_string_new (GMYTHTV_QUERY_HEADER);
40.560 + g_string_append_printf ( query, "%d", transfer->file_id );
40.561 + gmyth_debug ("[%s] Transfer_query = %s\n", __FUNCTION__, query->str );
40.562 +
40.563 + /* send requests to the maximum number of REQUEST_BLOCK messages */
40.564 + guint max_tries = 5;
40.565 +
40.566 + myth_control_acquire_context( TRUE );
40.567 +
40.568 + while (total_read == 0 && --max_tries > 0) {
40.569 + GMythStringList *strlist = gmyth_string_list_new();
40.570 +
40.571 + gmyth_string_list_append_char_array( strlist, query->str );
40.572 + gmyth_string_list_append_char_array( strlist, "REQUEST_BLOCK" );
40.573 + gmyth_string_list_append_int( strlist, size );
40.574 +
40.575 + // Request the block to the backend
40.576 + gmyth_socket_write_stringlist( transfer->control_sock, strlist );
40.577 +
40.578 + // Receives the backand answer
40.579 + gmyth_socket_read_stringlist( transfer->control_sock, strlist );
40.580 +
40.581 + if ( strlist != NULL && gmyth_string_list_length( strlist ) > 0 )
40.582 + {
40.583 + bytes_sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error
40.584 + gmyth_debug ( "[%s] got SENT buffer message = %d\n", __FUNCTION__, bytes_sent );
40.585 +
40.586 + if ( bytes_sent >= 0 )
40.587 + {
40.588 + gchar *data_buffer = g_new0 ( gchar, bytes_sent );
40.589 + while ( 0 != bytes_sent )
40.590 + {
40.591 + io_status = g_io_channel_read_chars( io_channel, data_buffer + total_read,
40.592 + (gsize) bytes_sent, &bytes_read, &error );
40.593 +
40.594 + total_read += bytes_read;
40.595 + bytes_sent -= bytes_read;
40.596 +
40.597 + /* append new data to the increasing byte array */
40.598 + data = g_byte_array_append (data, (const guint8*)data_buffer, bytes_read);
40.599 + gmyth_debug ("Total transfer data read: %d\n", total_read);
40.600 + }
40.601 + g_free (data_buffer);
40.602 + } /* if */
40.603 + } else if ( !(transfer->priv != NULL && transfer->priv->livetv != NULL &&
40.604 + transfer->priv->do_next_program_chain) ) {
40.605 + total_read = GMYTHTV_FILE_TRANSFER_READ_ERROR;
40.606 + g_object_unref (strlist);
40.607 + strlist = NULL;
40.608 + break;
40.609 + }
40.610 + g_object_unref (strlist);
40.611 + strlist = NULL;
40.612 + }
40.613 +
40.614 + if ( bytes_sent == 0 && max_tries == 0 )
40.615 + {
40.616 + gmyth_debug( "Trying to move to the next program chain..." );
40.617 + transfer->priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
40.618 +
40.619 + if ( transfer->priv != NULL && transfer->priv->livetv != NULL &&
40.620 + transfer->priv->do_next_program_chain )
40.621 + {
40.622 +
40.623 + total_read = GMYTHTV_FILE_TRANSFER_NEXT_PROG_CHAIN;
40.624 +
40.625 + g_mutex_lock( transfer->mutex );
40.626 +
40.627 + ret = gmyth_livetv_next_program_chain( transfer->priv->livetv );
40.628 +
40.629 + g_mutex_unlock( transfer->mutex );
40.630 +
40.631 + if ( !ret )
40.632 + gmyth_debug( "Cannot change to the next program chain!" );
40.633 + else
40.634 + gmyth_debug( "OK!!! MOVED to the next program chain [%s]!",
40.635 + (gmyth_tvchain_get_id( transfer->priv->livetv->tvchain ))->str );
40.636 + }
40.637 +
40.638 + } /* if */
40.639 +
40.640 + myth_control_release_context( );
40.641 + g_string_free (query, TRUE);
40.642 +
40.643 + if ( error != NULL ) {
40.644 + gmyth_debug ("Cleaning-up ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message,
40.645 + error->code);
40.646 + g_error_free (error);
40.647 + }
40.648 +
40.649 + if ( total_read > 0 )
40.650 + transfer->readposition += total_read;
40.651 +
40.652 + return total_read;
40.653 +}
40.654 +
40.655 +static void
40.656 +gmyth_file_transfer_program_info_changed( GMythFileTransfer *transfer,
40.657 + gint msg_code, gpointer livetv_transfer )
40.658 +{
40.659 + GMythLiveTV *livetv = GMYTH_LIVETV( livetv_transfer );
40.660 +
40.661 + gmyth_debug( "Program info changed! ( file transfer orig. = %p, ptr. = [%s], user data = [%s] )", transfer,
40.662 + livetv_transfer != NULL ? "[NOT NULL]" : "[NULL]", livetv != NULL ? "[NOT NULL]" : "[NULL]" );
40.663 +
40.664 + if ( livetv != NULL && transfer == livetv->file_transfer )
40.665 + {
40.666 + gmyth_debug( "YES, the requested program info movement on the LiveTV transfer is authentical!" );
40.667 + }
40.668 +
40.669 + transfer->priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
40.670 +
40.671 + transfer->priv->livetv = livetv;
40.672 + transfer->priv->do_next_program_chain = TRUE;
40.673 +
40.674 + //g_object_unref( transfer );
40.675 +}
40.676 +
40.677 +gboolean
40.678 +gmyth_file_transfer_settimeout( GMythFileTransfer *transfer, gboolean fast )
40.679 +{
40.680 +
40.681 + GMythStringList *strlist = NULL;
40.682 +
40.683 + g_return_val_if_fail (transfer->sock != NULL, FALSE);
40.684 + g_return_val_if_fail (transfer->control_sock != NULL, FALSE);
40.685 +
40.686 +// if ( transfer->timeoutisfast == fast )
40.687 +// return;
40.688 +
40.689 + strlist = gmyth_string_list_new();
40.690 + gmyth_string_list_append_char_array( strlist, GMYTHTV_QUERY_HEADER );
40.691 + gmyth_string_list_append_char_array( strlist, "SET_TIMEOUT" );
40.692 + gmyth_string_list_append_int( strlist, fast );
40.693 +
40.694 + gmyth_socket_write_stringlist( transfer->control_sock, strlist );
40.695 + gmyth_socket_read_stringlist( transfer->control_sock, strlist );
40.696 +
40.697 +// transfer->timeoutisfast = fast;
40.698 +
40.699 + return TRUE;
40.700 +}
40.701 +
40.702 +
40.703 +guint64
40.704 +gmyth_file_transfer_get_filesize (GMythFileTransfer *transfer)
40.705 +{
40.706 + g_return_val_if_fail (transfer != NULL, 0);
40.707 + return transfer->filesize;
40.708 +}
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/branches/gmyth-0.1b/src/gmyth_file_transfer.h Thu Feb 01 18:42:01 2007 +0000
41.3 @@ -0,0 +1,122 @@
41.4 +/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
41.5 +/**
41.6 + * GMyth Library
41.7 + *
41.8 + * @file gmyth/gmyth_file_transfer.h
41.9 + *
41.10 + * @brief <p> GMythFileTransfer deals with the file streaming media remote/local
41.11 + * transfering to the MythTV frontend.
41.12 + *
41.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
41.14 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
41.15 + *
41.16 + *//*
41.17 + *
41.18 + * This program is free software; you can redistribute it and/or modify
41.19 + * it under the terms of the GNU Lesser General Public License as published by
41.20 + * the Free Software Foundation; either version 2 of the License, or
41.21 + * (at your option) any later version.
41.22 + *
41.23 + * This program is distributed in the hope that it will be useful,
41.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
41.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41.26 + * GNU General Public License for more details.
41.27 + *
41.28 + * You should have received a copy of the GNU Lesser General Public License
41.29 + * along with this program; if not, write to the Free Software
41.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41.31 + */
41.32 +
41.33 +#ifndef __GMYTH_FILE_TRANSFER_H__
41.34 +#define __GMYTH_FILE_TRANSFER_H__
41.35 +
41.36 +#include <glib-object.h>
41.37 +#include <glib.h>
41.38 +
41.39 +#include "gmyth_socket.h"
41.40 +#include "gmyth_uri.h"
41.41 +#include "gmyth_backendinfo.h"
41.42 +
41.43 +#include <stdio.h>
41.44 +#include <stdlib.h>
41.45 +#include <string.h>
41.46 +#include <netdb.h>
41.47 +#include <sys/socket.h>
41.48 +#include <unistd.h>
41.49 +
41.50 +G_BEGIN_DECLS
41.51 +
41.52 +#define GMYTH_FILE_TRANSFER_TYPE (gmyth_file_transfer_get_type ())
41.53 +#define GMYTH_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransfer))
41.54 +#define GMYTH_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass))
41.55 +#define IS_GMYTH_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_TRANSFER_TYPE))
41.56 +#define IS_GMYTH_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE))
41.57 +#define GMYTH_FILE_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass))
41.58 +
41.59 +#define GMYTHTV_FILE_TRANSFER_READ_ERROR -314
41.60 +#define GMYTHTV_FILE_TRANSFER_NEXT_PROG_CHAIN -315
41.61 +
41.62 +typedef struct _GMythFileTransfer GMythFileTransfer;
41.63 +typedef struct _GMythFileTransferClass GMythFileTransferClass;
41.64 +typedef struct _GMythFileTransferPrivate GMythFileTransferPrivate;
41.65 +
41.66 +struct _GMythFileTransferClass
41.67 +{
41.68 + GObjectClass parent_class;
41.69 +
41.70 + /* callbacks */
41.71 + guint program_info_changed_handler_signal_id;
41.72 +
41.73 + /* signal default handlers */
41.74 + void (*program_info_changed_handler) ( GMythFileTransfer *transfer,
41.75 + gint msg_code, gpointer livetv_transfer );
41.76 +};
41.77 +
41.78 +struct _GMythFileTransfer
41.79 +{
41.80 + GObject parent;
41.81 +
41.82 + /* Myth URI structure */
41.83 + gchar *filename;
41.84 + GMythBackendInfo *backend_info;
41.85 +
41.86 + /* MythTV version number */
41.87 + gint mythtv_version;
41.88 +
41.89 + /* socket descriptors */
41.90 + GMythSocket *control_sock;
41.91 + GMythSocket *sock;
41.92 +
41.93 + GMutex *mutex;
41.94 +
41.95 + gint64 readposition;
41.96 + guint64 filesize;
41.97 + gint file_id;
41.98 +
41.99 + GMythFileTransferPrivate *priv;
41.100 +
41.101 +};
41.102 +
41.103 +GType gmyth_file_transfer_get_type (void);
41.104 +GMythFileTransfer *gmyth_file_transfer_new (const GMythBackendInfo *backend_info);
41.105 +gboolean gmyth_file_transfer_open (GMythFileTransfer *transfer,
41.106 + const gchar* filename);
41.107 +void gmyth_file_transfer_close (GMythFileTransfer *transfer);
41.108 +gboolean gmyth_file_transfer_is_open (GMythFileTransfer *transfer);
41.109 +gint gmyth_file_transfer_read (GMythFileTransfer *transfer,
41.110 + GByteArray *data,
41.111 + gint size,
41.112 + gboolean read_unlimited);
41.113 +gint64 gmyth_file_transfer_seek (GMythFileTransfer *transfer,
41.114 + guint64 pos,
41.115 + gint whence);
41.116 +gboolean gmyth_file_transfer_settimeout (GMythFileTransfer *transfer, gboolean fast);
41.117 +guint64 gmyth_file_transfer_get_filesize (GMythFileTransfer *transfer);
41.118 +
41.119 +void gmyth_file_transfer_emit_program_info_changed_signal ( GMythFileTransfer *transfer,
41.120 + gint msg_code,
41.121 + gpointer live_tv );
41.122 +
41.123 +G_END_DECLS
41.124 +
41.125 +#endif /* __GMYTH_FILE_TRANSFER_H__ */
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/branches/gmyth-0.1b/src/gmyth_http.c Thu Feb 01 18:42:01 2007 +0000
42.3 @@ -0,0 +1,343 @@
42.4 +/**
42.5 + * GMyth Library
42.6 + *
42.7 + * @file gmyth/gmyth_http.c
42.8 + *
42.9 + * @brief <p> GMythHttp class provides a wrapper to access
42.10 + * data from the database using http+xml
42.11 + *
42.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
42.13 + * @author Artur Duque de Souza <@indt.org.br>
42.14 + *
42.15 + */
42.16 +/*
42.17 + *
42.18 + * This program is free software; you can redistribute it and/or modify
42.19 + * it under the terms of the GNU Lesser General Public License as published by
42.20 + * the Free Software Foundation; either version 2 of the License, or
42.21 + * (at your option) any later version.
42.22 + *
42.23 + * This program is distributed in the hope that it will be useful,
42.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
42.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42.26 + * GNU General Public License for more details.
42.27 + *
42.28 + * You should have received a copy of the GNU Lesser General Public License
42.29 + * along with this program; if not, write to the Free Software
42.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
42.31 + */
42.32 +
42.33 +#ifdef HAVE_CONFIG_H
42.34 +#include "config.h"
42.35 +#endif
42.36 +
42.37 +#include <assert.h>
42.38 +#include <libxml/parser.h>
42.39 +#include <libxml/tree.h>
42.40 +#include <libxml/xpath.h>
42.41 +
42.42 +#include "gmyth_http.h"
42.43 +#include "gmyth_debug.h"
42.44 +#include "gmyth_socket.h"
42.45 +
42.46 +
42.47 +xmlXPathObjectPtr
42.48 +getnodeset(xmlDocPtr doc, xmlChar *xpath)
42.49 +{
42.50 +
42.51 + xmlXPathContextPtr context;
42.52 + xmlXPathObjectPtr result;
42.53 +
42.54 + context = xmlXPathNewContext(doc);
42.55 + result = xmlXPathEvalExpression(xpath, context);
42.56 +
42.57 + if(xmlXPathNodeSetIsEmpty(result->nodesetval))
42.58 + {
42.59 + g_fprintf(stderr, "Error: No result at XPath\n");
42.60 + return NULL;
42.61 + }
42.62 +
42.63 + xmlXPathFreeContext(context);
42.64 + return result;
42.65 +}
42.66 +
42.67 +
42.68 +xmlDocPtr XMLParse (const char *content, int length)
42.69 +{
42.70 + xmlDocPtr doc; /* the resulting document tree */
42.71 +
42.72 + doc = xmlReadMemory(content, length, NULL, NULL, 0);
42.73 + if (doc == NULL)
42.74 + {
42.75 + g_fprintf(stderr, "Error: Failed to parse XML document\n");
42.76 + return NULL;
42.77 + }
42.78 +
42.79 + return doc;
42.80 +}
42.81 +
42.82 +xmlXPathObjectPtr getXPath (xmlChar *xpath, xmlDocPtr doc)
42.83 +{
42.84 + xmlXPathObjectPtr result;
42.85 + result = getnodeset(doc, xpath);
42.86 + return result;
42.87 +}
42.88 +
42.89 +/** Retrieves the Progam List from the Channel
42.90 + *
42.91 + * @param nodeTab A pointer to a node inside the XML
42.92 + * @return A GSList containing a list of all the programs
42.93 + */
42.94 +GSList* get_Program_List(xmlNodePtr node)
42.95 +{
42.96 + GSList* program_list = NULL;
42.97 +
42.98 + while (node != NULL)
42.99 + {
42.100 + if (g_ascii_strcasecmp((char *)node->name, "text") != 0)
42.101 + {
42.102 + GMythProgram* program = (GMythProgram*)g_malloc(sizeof(struct _GMythProgram));
42.103 +
42.104 + program->title = g_string_new((char *)xmlGetProp(node, (xmlChar *)"title"));
42.105 + program->subtitle = g_string_new((char *)xmlGetProp(node, (xmlChar *)"subtitle"));
42.106 + program->catType = g_string_new((char *)xmlGetProp(node, (xmlChar *)"catType"));
42.107 + program->category = g_string_new((char *)xmlGetProp(node, (xmlChar *)"category"));
42.108 +
42.109 + sscanf ((char *)xmlGetProp(node, (xmlChar *)"repeat"), "%d", &(program->repeat));
42.110 +
42.111 + program->startTime = gmyth_util_string_to_time_val ((char *)xmlGetProp(node, \
42.112 + (xmlChar *)"startTime"));
42.113 + program->endTime = gmyth_util_string_to_time_val ((char *)xmlGetProp(node, \
42.114 + (xmlChar *)"endTime"));
42.115 +
42.116 + program_list = g_slist_append(program_list, program);
42.117 + }
42.118 +
42.119 + node = node->next;
42.120 + }
42.121 +
42.122 + return program_list;
42.123 +}
42.124 +
42.125 +/** Retrieves the Channel List from the ProgramGuide
42.126 + *
42.127 + * @param node A pointer to a node inside the XML
42.128 + * @param epg The struct where is the current epg
42.129 + * @return The epg from "param" updated
42.130 + */
42.131 +void get_Channel_List (xmlNodePtr node, GMythEpg* epg)
42.132 +{
42.133 + int i;
42.134 + epg->channelList = NULL;
42.135 +
42.136 + for (i=1; i <= epg->numOfChannels; i++)
42.137 + {
42.138 + GMythChannel* channel = (GMythChannel*)g_malloc(sizeof(struct _GMythChannel));
42.139 +
42.140 + channel->channelName = g_string_new((char *)xmlGetProp(node, (xmlChar *)"channelName"));
42.141 + channel->chanNum = g_string_new((char *)xmlGetProp(node, (xmlChar *)"chanNum"));
42.142 +
42.143 + sscanf ((char *)xmlGetProp(node, (xmlChar *)"chanId"), "%d", &(channel->chanId));
42.144 + sscanf ((char *)xmlGetProp(node, (xmlChar *)"callSign"), "%d", &(channel->callSign));
42.145 +
42.146 + channel->programList = get_Program_List(node->children);
42.147 +
42.148 + epg->channelList = g_slist_append(epg->channelList, channel);
42.149 + }
42.150 +}
42.151 +
42.152 +/** Retrieves the properties from the ProgramGuide
42.153 + *
42.154 + * @param nodeTab A pointer to a node inside the XML
42.155 + * @param epg The struct where is the current epg
42.156 + * @return The epg from "param" updated
42.157 + */
42.158 +void get_ProgramGuide_Properties (xmlNodePtr nodeTab, GMythEpg* epg)
42.159 +{
42.160 + sscanf ((char *)xmlGetProp(nodeTab, (xmlChar *)"startChanId"), "%d", &(epg->startChanId));
42.161 + sscanf ((char *)xmlGetProp(nodeTab, (xmlChar *)"endChanId"), "%d", &(epg->endChanId));
42.162 +
42.163 + epg->version = g_string_new((char *)xmlGetProp(nodeTab, (xmlChar *)"version"));
42.164 +
42.165 + sscanf ((char *)xmlGetProp(nodeTab, (xmlChar *)"protoVer"), "%d", &(epg->protoVer));
42.166 + sscanf ((char *)xmlGetProp(nodeTab, (xmlChar *)"totalCount"), "%d", &(epg->totalCount));
42.167 + sscanf ((char *)xmlGetProp(nodeTab, (xmlChar *)"numOfChannels"), "%d", &(epg->numOfChannels));
42.168 +
42.169 + epg->asOf = gmyth_util_string_to_time_val ((char *)xmlGetProp(nodeTab, (xmlChar *)"asOf"));
42.170 + epg->startTime = gmyth_util_string_to_time_val ((char *)xmlGetProp(nodeTab, (xmlChar *)"startTime"));
42.171 + epg->endTime = gmyth_util_string_to_time_val ((char *)xmlGetProp(nodeTab, (xmlChar *)"endTime"));
42.172 +
42.173 + sscanf ((char *)xmlGetProp(nodeTab, (xmlChar *)"details"), "%d", &(epg->details));
42.174 +
42.175 + // go to Channel section and retrieve Channels and Programs
42.176 + get_Channel_List(nodeTab->children->next->children->next, epg);
42.177 +}
42.178 +
42.179 +/** Aux function to retrieve the Eletronic Program Guide
42.180 + *
42.181 + * @param doc An XML document (xmlDocPtr)
42.182 + * @return The epg
42.183 + */
42.184 +void getEpg (xmlDocPtr doc, GMythEpg* epg)
42.185 +{
42.186 + xmlXPathObjectPtr result;
42.187 + xmlNodeSetPtr nodeset;
42.188 + xmlChar *keyword;
42.189 +
42.190 + int i;
42.191 + result = getXPath((xmlChar *)"/*", doc);
42.192 +
42.193 + if (result)
42.194 + {
42.195 + nodeset = result->nodesetval;
42.196 + for (i=0; i < nodeset->nodeNr; i++)
42.197 + {
42.198 + keyword = (xmlChar*)nodeset->nodeTab[i]->name;
42.199 + if (g_ascii_strcasecmp((char *)keyword, "ProgramGuide") == 0)
42.200 + get_ProgramGuide_Properties(nodeset->nodeTab[i], epg);
42.201 + }
42.202 + xmlXPathFreeObject (result);
42.203 + }
42.204 +
42.205 +}
42.206 +
42.207 +/** Retrieves the Eletronic Program Guide from the backend
42.208 + *
42.209 + * @param doc An XML document (xmlDocPtr)
42.210 + * @return The epg
42.211 + */
42.212 +GMythEpg retrieve_epg (GMythBackendInfo *backend_info, int port, \
42.213 + GTimeVal* StartTime, GTimeVal* EndTime, \
42.214 + gint StartChanId, gint NumOfChannels, \
42.215 + gchar* Details)
42.216 +{
42.217 + GMythEpg epg;
42.218 + MemoryStruct chunk;
42.219 +
42.220 + chunk.memory=NULL; /* we expect realloc(NULL, size) to work */
42.221 + chunk.size = 0; /* no data at this point */
42.222 +
42.223 + gchar* starttime = (gchar*)g_malloc(sizeof(gchar)*20);
42.224 + starttime = gmyth_util_time_to_mythformat_from_time_val(StartTime);
42.225 +
42.226 + gchar* endtime = (gchar*)g_malloc(sizeof(gchar)*20);
42.227 + endtime = gmyth_util_time_to_mythformat_from_time_val(EndTime);
42.228 +
42.229 + GString* command = g_string_new("");
42.230 + g_string_printf(command, "getProgramGuide?StartTime=%s&EndTime=%s&StartChanId=%d"
42.231 + "&NumOfChannels=%d&Details=%s", starttime, endtime, \
42.232 + StartChanId, NumOfChannels, Details);
42.233 +
42.234 + chunk = gmyth_http_request(backend_info, command);
42.235 + xmlDocPtr doc = XMLParse(chunk.memory, strlen(chunk.memory));
42.236 + getEpg(doc, &epg);
42.237 + free(chunk.memory);
42.238 +
42.239 + return epg;
42.240 +}
42.241 +
42.242 +/* Aux functions got from libcurl */
42.243 +void *myrealloc (void *ptr, size_t size)
42.244 +{
42.245 + /* There might be a realloc() out there that doesn't like reallocing
42.246 + NULL pointers, so we take care of it here */
42.247 + if(ptr)
42.248 + return realloc(ptr, size);
42.249 + else
42.250 + return malloc(size);
42.251 +}
42.252 +
42.253 +size_t
42.254 +WriteMemoryCallback (void *ptr, size_t size, size_t nmemb, void *data)
42.255 +{
42.256 + size_t realsize = size * nmemb;
42.257 + MemoryStruct *mem = (struct _MemoryStruct *)data;
42.258 +
42.259 + mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
42.260 + if (mem->memory)
42.261 + {
42.262 + memcpy(&(mem->memory[mem->size]), ptr, realsize);
42.263 + mem->size += realsize;
42.264 + mem->memory[mem->size] = 0;
42.265 + }
42.266 +
42.267 + return realsize;
42.268 +}
42.269 +
42.270 +/** Create a String containing the URL with the command
42.271 + *
42.272 + * @param command A string with the command
42.273 + * @param variables Vars to use with their values \
42.274 + * MUST FINISH WITH NULL!!!
42.275 + * @return The response
42.276 + */
42.277 +GString* gmyth_http_create_command (GString *command, ...)
42.278 +{
42.279 + va_list args;
42.280 + va_start(args, command);
42.281 + gchar* s = NULL;
42.282 +
42.283 + g_string_append(command, "?");
42.284 +
42.285 + /* Sintax: var, value */
42.286 + while ( (s = va_arg(args, gchar *)) != NULL )
42.287 + {
42.288 + g_string_append(command, s);
42.289 + g_string_append(command, "=");
42.290 + s = va_arg(args, gchar *);
42.291 + g_string_append(command, s);
42.292 + g_string_append(command, "&");
42.293 + }
42.294 +
42.295 + free(s);
42.296 + va_end(args);
42.297 +
42.298 + return command;
42.299 +}
42.300 +
42.301 +/** Send HTTP Command and receives the result of it
42.302 + *
42.303 + * @return A string with the response from the server
42.304 + * NULL if there is no response.
42.305 + */
42.306 +MemoryStruct gmyth_http_request (GMythBackendInfo *backend_info, GString *command)
42.307 +{
42.308 + LIBXML_TEST_VERSION
42.309 +
42.310 + size_t size = strlen(backend_info->hostname) + strlen(command->str) + 13;
42.311 + gchar *URL = (gchar *)g_malloc(sizeof(gchar)*size);
42.312 + g_snprintf(URL, size+1, "http://%s:6544/%s", backend_info->hostname, command->str);
42.313 +
42.314 + CURL *curl_handle;
42.315 +
42.316 + MemoryStruct chunk;
42.317 +
42.318 + chunk.memory=NULL; /* we expect realloc(NULL, size) to work */
42.319 + chunk.size = 0; /* no data at this point */
42.320 +
42.321 + curl_global_init(CURL_GLOBAL_ALL);
42.322 +
42.323 + /* init the curl session */
42.324 + curl_handle = curl_easy_init();
42.325 +
42.326 + /* specify URL to get */
42.327 + curl_easy_setopt(curl_handle, CURLOPT_URL, URL);
42.328 +
42.329 + /* send all data to this function */
42.330 + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
42.331 +
42.332 + /* we pass our 'chunk' struct to the callback function */
42.333 + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
42.334 +
42.335 + /* some servers don't like requests that are made without a user-agent
42.336 + field, so we provide one */
42.337 + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
42.338 +
42.339 + /* get it! */
42.340 + curl_easy_perform(curl_handle);
42.341 +
42.342 + /* cleanup curl stuff */
42.343 + curl_easy_cleanup(curl_handle);
42.344 +
42.345 + return chunk;
42.346 +}
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/branches/gmyth-0.1b/src/gmyth_http.h Thu Feb 01 18:42:01 2007 +0000
43.3 @@ -0,0 +1,110 @@
43.4 +/**
43.5 + * GMyth Library
43.6 + *
43.7 + * @file gmyth/gmyth_http.c
43.8 + *
43.9 + * @brief <p> GMythHttp class provides a wrapper to access
43.10 + * data from the database using http+xml
43.11 + *
43.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
43.13 + * @author Artur Duque de Souza <@indt.org.br>
43.14 + *
43.15 + *//*
43.16 + *
43.17 + * This program is free software; you can redistribute it and/or modify
43.18 + * it under the terms of the GNU Lesser General Public License as published by
43.19 + * the Free Software Foundation; either version 2 of the License, or
43.20 + * (at your option) any later version.
43.21 + *
43.22 + * This program is distributed in the hope that it will be useful,
43.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
43.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43.25 + * GNU General Public License for more details.
43.26 + *
43.27 + * You should have received a copy of the GNU Lesser General Public License
43.28 + * along with this program; if not, write to the Free Software
43.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
43.30 + */
43.31 +
43.32 +#ifndef __GMYTH_HTTP_H__
43.33 +#define __GMYTH_HTTP_H__
43.34 +
43.35 +#include <glib-object.h>
43.36 +
43.37 +#include <stdio.h>
43.38 +#include <stdlib.h>
43.39 +#include <string.h>
43.40 +#include <stdarg.h>
43.41 +#include <glib.h>
43.42 +#include <glib/gprintf.h>
43.43 +
43.44 +#include "gmyth_backendinfo.h"
43.45 +#include "gmyth_util.h"
43.46 +
43.47 +#include <curl/curl.h>
43.48 +#include <curl/types.h>
43.49 +#include <curl/easy.h>
43.50 +
43.51 +G_BEGIN_DECLS
43.52 +
43.53 +#define MYTH_PORT_STATUS 6544
43.54 +
43.55 +typedef struct _GMythPacket GMythPacket;
43.56 +typedef struct _GMythProgram GMythProgram;
43.57 +typedef struct _GMythChannel GMythChannel;
43.58 +typedef struct _GMythEpg GMythEpg;
43.59 +typedef struct _MemoryStruct MemoryStruct;
43.60 +
43.61 +struct _MemoryStruct
43.62 +{
43.63 + char *memory;
43.64 + size_t size;
43.65 +};
43.66 +
43.67 +struct _GMythPacket
43.68 +{
43.69 + GString *response;
43.70 + int type;
43.71 +};
43.72 +
43.73 +struct _GMythProgram
43.74 +{
43.75 + GString* title;
43.76 + GString* subtitle;
43.77 + GString* catType;
43.78 + GString* category;
43.79 + gint repeat;
43.80 + GTimeVal* startTime;
43.81 + GTimeVal* endTime;
43.82 +};
43.83 +
43.84 +struct _GMythChannel
43.85 +{
43.86 + GString* channelName;
43.87 + GString* chanNum;
43.88 + gint chanId;
43.89 + gint callSign;
43.90 + GSList* programList;
43.91 +};
43.92 +
43.93 +struct _GMythEpg
43.94 +{
43.95 + gint startChanId;
43.96 + gint endChanId;
43.97 + GString* version;
43.98 + gint protoVer;
43.99 + gint totalCount;
43.100 + gint numOfChannels;
43.101 + GTimeVal* asOf;
43.102 + GTimeVal* startTime;
43.103 + GTimeVal* endTime;
43.104 + gint details;
43.105 + GSList* channelList;
43.106 +};
43.107 +
43.108 +GMythEpg retrieve_epg(GMythBackendInfo *backend_info, int port, GTimeVal* StartTime, GTimeVal* EndTime, gint StartChanId, gint NumOfChannels, gchar* Details);
43.109 +MemoryStruct gmyth_http_request (GMythBackendInfo *backend_info, GString *command);
43.110 +
43.111 +G_END_DECLS
43.112 +
43.113 +#endif /* __GMYTH_HTTP_H__ */
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/branches/gmyth-0.1b/src/gmyth_livetv.c Thu Feb 01 18:42:01 2007 +0000
44.3 @@ -0,0 +1,668 @@
44.4 +/**
44.5 + * GMyth Library
44.6 + *
44.7 + * @file gmyth/gmyth_livetv.c
44.8 + *
44.9 + * @brief <p> GMythLiveTV starts a remote TV session with the MythTV backend.
44.10 + *
44.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
44.12 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
44.13 + *
44.14 + *//*
44.15 + *
44.16 + * This program is free software; you can redistribute it and/or modify
44.17 + * it under the terms of the GNU Lesser General Public License as published by
44.18 + * the Free Software Foundation; either version 2 of the License, or
44.19 + * (at your option) any later version.
44.20 + *
44.21 + * This program is distributed in the hope that it will be useful,
44.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
44.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44.24 + * GNU General Public License for more details.
44.25 + *
44.26 + * You should have received a copy of the GNU Lesser General Public License
44.27 + * along with this program; if not, write to the Free Software
44.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44.29 + */
44.30 +
44.31 +#ifdef HAVE_CONFIG_H
44.32 +#include "config.h"
44.33 +#endif
44.34 +
44.35 +#include "gmyth_livetv.h"
44.36 +#include "gmyth_remote_util.h"
44.37 +#include "gmyth_tvchain.h"
44.38 +#include "gmyth_socket.h"
44.39 +#include "gmyth_backendinfo.h"
44.40 +#include "gmyth_debug.h"
44.41 +
44.42 +#include "gmyth_file_transfer.h"
44.43 +#include "gmyth_monitor_handler.h"
44.44 +
44.45 +static void gmyth_livetv_class_init (GMythLiveTVClass *klass);
44.46 +static void gmyth_livetv_init (GMythLiveTV *object);
44.47 +
44.48 +static void gmyth_livetv_dispose (GObject *object);
44.49 +static void gmyth_livetv_finalize (GObject *object);
44.50 +
44.51 +static gint tvchain_curr_index = -1;
44.52 +
44.53 +static GStaticMutex lock = G_STATIC_MUTEX_INIT;
44.54 +
44.55 +#define GMYTHTV_TRANSFER_MAX_WAITS 100
44.56 +
44.57 +G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT)
44.58 +
44.59 +static void
44.60 +gmyth_livetv_class_init (GMythLiveTVClass *klass)
44.61 +{
44.62 + GObjectClass *gobject_class;
44.63 +
44.64 + gobject_class = (GObjectClass *) klass;
44.65 +
44.66 + gobject_class->dispose = gmyth_livetv_dispose;
44.67 + gobject_class->finalize = gmyth_livetv_finalize;
44.68 +}
44.69 +
44.70 +static void
44.71 +gmyth_livetv_init (GMythLiveTV *livetv)
44.72 +{
44.73 + livetv->backend_info = NULL;
44.74 + livetv->local_hostname = NULL;
44.75 + livetv->file_transfer = NULL;
44.76 + livetv->setup_done = FALSE;
44.77 +
44.78 + livetv->recorder = NULL;
44.79 + livetv->tvchain = NULL;
44.80 + livetv->proginfo = NULL;
44.81 + livetv->uri = NULL;
44.82 +
44.83 +}
44.84 +
44.85 +static void
44.86 +gmyth_livetv_dispose (GObject *object)
44.87 +{
44.88 + G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object);
44.89 +}
44.90 +
44.91 +static void
44.92 +gmyth_livetv_finalize (GObject *object)
44.93 +{
44.94 + g_signal_handlers_destroy (object);
44.95 +
44.96 + GMythLiveTV *livetv = GMYTH_LIVETV (object);
44.97 +
44.98 + gmyth_debug ("Finalizing livetv");
44.99 +
44.100 + if ( livetv->monitor != NULL ) {
44.101 + g_object_unref (livetv->monitor);
44.102 + livetv->monitor = NULL;
44.103 + }
44.104 +
44.105 + if ( livetv->recorder != NULL ) {
44.106 + g_object_unref (livetv->recorder);
44.107 + livetv->recorder = NULL;
44.108 + }
44.109 +
44.110 + if ( livetv->tvchain != NULL ) {
44.111 + g_object_unref (livetv->tvchain);
44.112 + livetv->tvchain = NULL;
44.113 + }
44.114 +
44.115 + if ( livetv->proginfo != NULL ) {
44.116 + g_object_unref (livetv->proginfo);
44.117 + livetv->proginfo = NULL;
44.118 + }
44.119 +
44.120 + if ( livetv->file_transfer != NULL ) {
44.121 + g_object_unref (livetv->file_transfer);
44.122 + livetv->file_transfer = NULL;
44.123 + }
44.124 +
44.125 + if ( livetv->backend_info != NULL ) {
44.126 + g_object_unref (livetv->backend_info);
44.127 + livetv->backend_info = NULL;
44.128 + }
44.129 +
44.130 + if ( livetv->uri != NULL )
44.131 + {
44.132 + g_object_unref (livetv->uri);
44.133 + livetv->uri = NULL;
44.134 + }
44.135 +
44.136 + G_OBJECT_CLASS ( gmyth_livetv_parent_class )->finalize ( object );
44.137 +}
44.138 +
44.139 +GMythLiveTV*
44.140 +gmyth_livetv_new ()
44.141 +{
44.142 + GMythLiveTV *livetv = GMYTH_LIVETV ( g_object_new( GMYTH_LIVETV_TYPE, NULL ) );
44.143 +
44.144 + return livetv;
44.145 +}
44.146 +
44.147 +static void
44.148 +gmyth_livetv_monitor_signal_handler( GMythMonitorHandler *monitor, gint msg_code,
44.149 + gchar* message, gpointer user_data )
44.150 +{
44.151 + GMythLiveTV *live_tv = GMYTH_LIVETV ( user_data );
44.152 + //g_object_ref( live_tv );
44.153 +
44.154 + gmyth_debug( "LIVETV Signal handler ( msg = %s, code = %d, live_tv param = %s, user_data = %s )\n", message, msg_code, live_tv != NULL ? "" :
44.155 + "NULL", user_data != NULL ? "" : "NULL" );
44.156 +
44.157 + if ( NULL == live_tv )
44.158 + {
44.159 + gmyth_debug( "LiveTV_obj is equals to NULL!!!" );
44.160 + return;
44.161 + }
44.162 +
44.163 + switch ( msg_code )
44.164 + {
44.165 +
44.166 + case GMYTH_BACKEND_PROGRAM_INFO_CHANGED:
44.167 + {
44.168 + gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
44.169 + "TV Chain ID is the same as the old one...\n", message );
44.170 + if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {
44.171 + gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!",
44.172 + (gmyth_tvchain_get_id( live_tv->tvchain ))->str );
44.173 + /* advertises the FileTransfer about the program info changed */
44.174 + if ( live_tv->file_transfer != NULL )
44.175 + {
44.176 + gmyth_debug( "Emitting signal to the FileTransfer... [ \"program-info-changed \" ]" );
44.177 +
44.178 + gmyth_file_transfer_emit_program_info_changed_signal( live_tv->file_transfer,
44.179 + msg_code, (gpointer)live_tv );
44.180 +
44.181 + //gmyth_livetv_monitor_handler_stop( live_tv );
44.182 + } else
44.183 + gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
44.184 + }
44.185 + }
44.186 + case GMYTH_BACKEND_DONE_RECORDING:
44.187 + {
44.188 + gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\
44.189 + "TV Chain ID is the same as the old one...\n", message );
44.190 + if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) {
44.191 + gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!",
44.192 + (gmyth_tvchain_get_id( live_tv->tvchain ))->str );
44.193 + /* advertises the FileTransfer about the program info changed */
44.194 + if ( live_tv->file_transfer != NULL )
44.195 + {
44.196 + gmyth_debug( "Emitting signal to the FileTransfer... [ \"program-info-changed \" ]" );
44.197 +
44.198 + gmyth_file_transfer_emit_program_info_changed_signal( live_tv->file_transfer,
44.199 + msg_code, (gpointer)live_tv );
44.200 +
44.201 + //gmyth_livetv_monitor_handler_stop( live_tv );
44.202 + } else
44.203 + gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
44.204 + }
44.205 +
44.206 + break;
44.207 + }
44.208 + default:
44.209 + break;
44.210 + } /* switch (Monitor Handler messages) */
44.211 +
44.212 +}
44.213 +
44.214 +gboolean
44.215 +gmyth_livetv_monitor_handler_start( GMythLiveTV *livetv )
44.216 +{
44.217 + gboolean res = TRUE;
44.218 +
44.219 + if ( livetv->monitor != NULL )
44.220 + {
44.221 + g_object_unref( livetv->monitor );
44.222 + livetv->monitor = NULL;
44.223 + }
44.224 +
44.225 + livetv->monitor = gmyth_monitor_handler_new ( );
44.226 +
44.227 + res = gmyth_monitor_handler_open (livetv->monitor, livetv->backend_info->hostname,
44.228 + livetv->backend_info->port );
44.229 +
44.230 + if ( res == TRUE )
44.231 + {
44.232 + gmyth_debug("Connect MythTV Monitor event socket! Trying to start the message handler...");
44.233 +
44.234 + res = gmyth_monitor_handler_start ( livetv->monitor );
44.235 +
44.236 + if (res)
44.237 + {
44.238 + gmyth_debug("MythTV Monitor event socket connected and listening!");
44.239 + g_signal_connect ( G_OBJECT (livetv->monitor), "backend-events-handler",
44.240 + (GCallback)gmyth_livetv_monitor_signal_handler,
44.241 + livetv );
44.242 + }
44.243 + else
44.244 + {
44.245 + gmyth_debug("Problems when trying to start MythTV Monitor event socket!");
44.246 + goto error;
44.247 + }
44.248 + }
44.249 +
44.250 +error:
44.251 + return res;
44.252 +
44.253 +}
44.254 +
44.255 +void
44.256 +gmyth_livetv_monitor_handler_stop( GMythLiveTV *livetv )
44.257 +{
44.258 +
44.259 + if ( livetv->monitor != NULL )
44.260 + {
44.261 + g_object_unref( livetv->monitor );
44.262 + livetv->monitor = NULL;
44.263 + }
44.264 +
44.265 +}
44.266 +
44.267 +
44.268 +/*
44.269 +static gchar*
44.270 +gmyth_livetv_create_remote_url( GMythLiveTV *livetv )
44.271 +{
44.272 + gchar *uri = g_strdup("");
44.273 + gmyth_backend_info_get_remote_h
44.274 +
44.275 + //gmyth_backend(livetv->backend_info)
44.276 +
44.277 + return uri;
44.278 +}
44.279 +*/
44.280 +
44.281 +static gboolean
44.282 +gmyth_livetv_setup_recorder_channel_name ( GMythLiveTV *livetv, gchar* channel, GMythBackendInfo *backend_info )
44.283 +{
44.284 + gboolean res = TRUE;
44.285 +
44.286 + GMythSocket *socket = gmyth_socket_new ();
44.287 +
44.288 + livetv->backend_info = backend_info;
44.289 +
44.290 + g_static_mutex_lock( &lock );
44.291 +
44.292 + // FIME: Implement this at gmyth_socket
44.293 + res = gmyth_socket_connect_to_backend (socket, livetv->backend_info->hostname,
44.294 + livetv->backend_info->port, TRUE);
44.295 + if (!res) {
44.296 + g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);
44.297 + res = FALSE;
44.298 + goto error;
44.299 + }
44.300 +
44.301 + livetv->is_livetv = TRUE;
44.302 +
44.303 + livetv->local_hostname = gmyth_socket_get_local_hostname ();
44.304 +
44.305 + if ( livetv->local_hostname == NULL ) {
44.306 + res = FALSE;
44.307 + goto error;
44.308 + }
44.309 +
44.310 + // Gets the recorder num
44.311 + livetv->recorder = remote_request_next_free_recorder (socket, -1);
44.312 + gmyth_socket_close_connection (socket);
44.313 +
44.314 + if ( livetv->recorder == NULL ) {
44.315 + g_warning ("[%s] None remote encoder available", __FUNCTION__);
44.316 + res = FALSE;
44.317 + goto error;
44.318 + }
44.319 +
44.320 + // Init remote encoder. Opens its control socket.
44.321 + res = gmyth_recorder_setup(livetv->recorder);
44.322 + if ( !res ) {
44.323 + g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
44.324 + res = FALSE;
44.325 + goto error;
44.326 + }
44.327 +
44.328 + // Creates livetv chain handler
44.329 + livetv->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
44.330 + gmyth_tvchain_initialize ( livetv->tvchain, livetv->backend_info );
44.331 +
44.332 + if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
44.333 + res = FALSE;
44.334 + goto error;
44.335 + }
44.336 +
44.337 + // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
44.338 + res = gmyth_recorder_spawntv ( livetv->recorder,
44.339 + gmyth_tvchain_get_id(livetv->tvchain) );
44.340 + if (!res) {
44.341 + g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
44.342 + res = FALSE;
44.343 + goto error;
44.344 + }
44.345 +
44.346 + if ( res == TRUE ) {
44.347 + /* loop finished, set the max tries variable to zero again... */
44.348 + gint wait_to_transfer = 0;
44.349 +
44.350 + while (wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS &&
44.351 + (gmyth_recorder_is_recording (livetv->recorder) == FALSE))
44.352 + g_usleep (500);
44.353 +
44.354 + /* IS_RECORDING again, just like the MythTV backend does... */
44.355 + gmyth_recorder_is_recording (livetv->recorder);
44.356 +
44.357 + if ( channel != NULL )
44.358 + {
44.359 + /* Pauses remote encoder. */
44.360 + res = gmyth_recorder_pause_recording(livetv->recorder);
44.361 + if ( !res ) {
44.362 + g_warning ("[%s] Fail while pausing remote encoder\n", __FUNCTION__);
44.363 + res = FALSE;
44.364 + goto error;
44.365 + }
44.366 +
44.367 + if ( gmyth_recorder_check_channel_name( livetv->recorder, channel ) )
44.368 + {
44.369 + if ( gmyth_recorder_set_channel_name( livetv->recorder, channel ) )
44.370 + {
44.371 + g_print( "[%s] Channel changed!!! [%s].\n", __FUNCTION__, channel );
44.372 + }
44.373 + }
44.374 +
44.375 + }
44.376 +
44.377 + sleep (9); /* FIXME: this is evil (tpm) */
44.378 + }
44.379 +
44.380 + /* DEBUG message */
44.381 + GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
44.382 +
44.383 + if ( NULL == prog_info )
44.384 + {
44.385 + gmyth_debug( "ProgramInfo is equals to NULL!!!" );
44.386 +
44.387 + return FALSE;
44.388 + }
44.389 + /* prints program info data text */
44.390 + gmyth_debug( "New ProgramInfo...\n" );
44.391 + gmyth_program_info_print( prog_info );
44.392 + /* DEBUG message */
44.393 + gmyth_debug( "Old ProgramInfo...\n" );
44.394 + gmyth_program_info_print( livetv->proginfo );
44.395 +
44.396 + /* check if the program chain could be obtained from the MythTV protocol message */
44.397 + if ( prog_info != NULL )
44.398 + {
44.399 + livetv->proginfo = prog_info;
44.400 + /* testing change channel */
44.401 + //gmyth_recorder_spawntv_no_tvchain( livetv->recorder );
44.402 + } else {
44.403 +
44.404 + /* check for the program info in the TV program chain could be obtained
44.405 + from the MythTV MySQL database */
44.406 +
44.407 + /* Reload all TV chain from Mysql database. */
44.408 + gmyth_tvchain_reload_all (livetv->tvchain);
44.409 +
44.410 + if ( livetv->tvchain == NULL ) {
44.411 + res = FALSE;
44.412 + goto error;
44.413 + }
44.414 +
44.415 + /* Get program info from database using chanid and starttime */
44.416 + livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ );
44.417 + if ( livetv->proginfo == NULL ) {
44.418 + g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
44.419 + res = FALSE;
44.420 + goto error;
44.421 + } else {
44.422 + res = TRUE;
44.423 + gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n", livetv->proginfo->pathname->str );
44.424 + }
44.425 +
44.426 + }
44.427 +
44.428 + livetv->uri = (GMythURI*)gmyth_backend_info_get_uri( backend_info );
44.429 +
44.430 + g_static_mutex_unlock( &lock );
44.431 +
44.432 + if ( !gmyth_livetv_monitor_handler_start( livetv ) )
44.433 + {
44.434 + res = FALSE;
44.435 + gmyth_debug( "LiveTV MONITOR handler error on setup!" );
44.436 + goto error;
44.437 + }
44.438 +
44.439 + livetv->setup_done = TRUE;
44.440 +
44.441 + return res;
44.442 +
44.443 +error:
44.444 + g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
44.445 +
44.446 + if ( livetv->local_hostname != NULL ) {
44.447 + g_string_free( livetv->local_hostname, FALSE );
44.448 + res = FALSE;
44.449 + }
44.450 +
44.451 + if ( livetv->recorder != NULL ) {
44.452 + g_object_unref (livetv->recorder);
44.453 + livetv->recorder = NULL;
44.454 + }
44.455 +
44.456 + if ( livetv->tvchain != NULL ) {
44.457 + g_object_unref (livetv->tvchain);
44.458 + livetv->tvchain = NULL;
44.459 + }
44.460 +
44.461 + if ( livetv->proginfo != NULL ) {
44.462 + g_object_unref (livetv->proginfo);
44.463 + livetv->proginfo = NULL;
44.464 + }
44.465 +
44.466 + if ( livetv->monitor != NULL ) {
44.467 + g_object_unref (livetv->monitor);
44.468 + livetv->monitor = NULL;
44.469 + }
44.470 +
44.471 + return res;
44.472 +
44.473 +}
44.474 +
44.475 +static gboolean
44.476 +gmyth_livetv_setup_recorder ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
44.477 +{
44.478 + return gmyth_livetv_setup_recorder_channel_name ( livetv, ( channel != -1 ) ?
44.479 + g_strdup_printf( "%d", channel ) : NULL, backend_info );
44.480 +}
44.481 +
44.482 +gboolean
44.483 +gmyth_livetv_channel_setup ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info )
44.484 +{
44.485 + return gmyth_livetv_setup_recorder ( livetv, channel, backend_info );
44.486 +}
44.487 +
44.488 +gboolean
44.489 +gmyth_livetv_channel_name_setup ( GMythLiveTV *livetv, gchar* channel, GMythBackendInfo *backend_info )
44.490 +{
44.491 + return gmyth_livetv_setup_recorder_channel_name ( livetv, channel, backend_info );
44.492 +}
44.493 +
44.494 +gboolean
44.495 +gmyth_livetv_setup ( GMythLiveTV *livetv, GMythBackendInfo *backend_info )
44.496 +{
44.497 + return gmyth_livetv_setup_recorder ( livetv, -1, backend_info );
44.498 +}
44.499 +
44.500 +gboolean
44.501 +gmyth_livetv_next_program_chain ( GMythLiveTV *livetv )
44.502 +{
44.503 + gboolean res = TRUE;
44.504 + GMythProgramInfo *prog_info = NULL;
44.505 +
44.506 + if ( !livetv->setup_done )
44.507 + {
44.508 + gmyth_debug ( "Call the setup function first!" );
44.509 + res= FALSE;
44.510 + goto error;
44.511 + }
44.512 +
44.513 + //if ( !gmyth_livetv_monitor_handler_start( livetv ) )
44.514 + // goto error;
44.515 + prog_info = gmyth_recorder_get_current_program_info( livetv->recorder );
44.516 +
44.517 + if ( NULL == prog_info )
44.518 + {
44.519 + gmyth_debug( "ProgramInfo is equals to NULL!!!" );
44.520 +
44.521 + return FALSE;
44.522 + }
44.523 + /* prints program info data text */
44.524 + gmyth_program_info_print( prog_info );
44.525 +
44.526 + if ( prog_info != NULL ) {
44.527 + res = TRUE;
44.528 + livetv->proginfo = prog_info;
44.529 + gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK, program info changed.");
44.530 + } else {
44.531 + g_warning ("[%s] LiveTV not successfully started on the next program chain.\n", __FUNCTION__ );
44.532 + res = FALSE;
44.533 + goto error;
44.534 + }
44.535 +
44.536 + livetv->setup_done = TRUE;
44.537 +
44.538 + return res;
44.539 +
44.540 +error:
44.541 + g_print( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ );
44.542 +
44.543 + if ( livetv->local_hostname != NULL ) {
44.544 + g_string_free( livetv->local_hostname, FALSE );
44.545 + res = FALSE;
44.546 + }
44.547 +
44.548 + if ( livetv->recorder != NULL ) {
44.549 + g_object_unref (livetv->recorder);
44.550 + livetv->recorder = NULL;
44.551 + }
44.552 +
44.553 + if ( livetv->tvchain != NULL ) {
44.554 + g_object_unref (livetv->tvchain);
44.555 + livetv->tvchain = NULL;
44.556 + }
44.557 +
44.558 + if ( livetv->proginfo != NULL ) {
44.559 + g_object_unref (livetv->proginfo);
44.560 + livetv->proginfo = NULL;
44.561 + }
44.562 +
44.563 + return res;
44.564 +
44.565 +}
44.566 +
44.567 +GMythFileTransfer *
44.568 +gmyth_livetv_create_file_transfer( GMythLiveTV *livetv )
44.569 +{
44.570 + //GMythURI* uri = NULL;
44.571 +
44.572 + if ( NULL == livetv )
44.573 + goto done;
44.574 +
44.575 + if ( !livetv->setup_done )
44.576 + {
44.577 + gmyth_debug( "Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!" );
44.578 + goto done;
44.579 + }
44.580 +
44.581 + if ( livetv->proginfo != NULL )
44.582 + gmyth_debug( "URI path = %s.\n", livetv->proginfo->pathname->str );
44.583 + else
44.584 + gmyth_debug( "URI path = %s.\n", livetv->uri->uri->str );
44.585 +
44.586 + g_static_mutex_lock( &lock );
44.587 +
44.588 + if ( livetv->file_transfer != NULL )
44.589 + {
44.590 + /*gmyth_file_transfer_close( livetv->file_transfer );*/
44.591 + g_object_unref( livetv->file_transfer );
44.592 + livetv->file_transfer = NULL;
44.593 + }
44.594 +
44.595 + livetv->file_transfer = gmyth_file_transfer_new( livetv->backend_info );
44.596 +
44.597 + if ( NULL == livetv->file_transfer )
44.598 + {
44.599 + gmyth_debug( "Error: couldn't create the FileTransfer from LiveTV source!" );
44.600 + goto done;
44.601 + }
44.602 +
44.603 + if ( livetv->uri != NULL )
44.604 + {
44.605 + if ( livetv->uri->path != NULL )
44.606 + {
44.607 + g_string_free( livetv->uri->path, FALSE );
44.608 + livetv->uri->path = NULL;
44.609 + }
44.610 + livetv->uri->path = g_string_new( g_strrstr( livetv->proginfo->pathname->str, "/" ) );
44.611 + } else {
44.612 + livetv->uri = gmyth_uri_new_with_value( livetv->proginfo->pathname->str );
44.613 + }
44.614 +
44.615 + if ( NULL == livetv->uri )
44.616 + {
44.617 + gmyth_debug( "Couldn't parse the URI to start LiveTV! [ uri = %s ]", livetv->proginfo->pathname->str );
44.618 + goto done;
44.619 + }
44.620 +
44.621 + if ( !gmyth_file_transfer_open( livetv->file_transfer, livetv->uri != NULL ? gmyth_uri_get_path(livetv->uri) :
44.622 + livetv->proginfo->pathname->str ) )
44.623 + {
44.624 + gmyth_debug( "Error: couldn't open the FileTransfer from LiveTV source!" );
44.625 + g_object_unref( livetv->file_transfer );
44.626 + livetv->file_transfer = NULL;
44.627 + goto done;
44.628 + }
44.629 +
44.630 + g_static_mutex_unlock( &lock );
44.631 +
44.632 +done:
44.633 + /*
44.634 + if ( uri != NULL )
44.635 + {
44.636 + g_object_unref( uri );
44.637 + uri = NULL;
44.638 + }
44.639 + */
44.640 +
44.641 + return livetv->file_transfer;
44.642 +
44.643 +}
44.644 +
44.645 +/* FIXME: How to proceed differently between livetv and recorded content */
44.646 +void
44.647 +gmyth_livetv_stop_playing (GMythLiveTV *livetv)
44.648 +{
44.649 + gmyth_debug ("Stopping the LiveTV...\n");
44.650 +
44.651 + if (livetv->is_livetv) {
44.652 + if ( !gmyth_recorder_stop_livetv (livetv->recorder) ) {
44.653 + g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);
44.654 + }
44.655 + }
44.656 +}
44.657 +
44.658 +gboolean
44.659 +gmyth_livetv_is_playing (GMythLiveTV *livetv)
44.660 +{
44.661 + return TRUE;
44.662 +}
44.663 +
44.664 +void
44.665 +gmyth_livetv_start_playing (GMythLiveTV *livetv)
44.666 +{
44.667 +
44.668 + // TODO
44.669 +
44.670 +}
44.671 +
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/branches/gmyth-0.1b/src/gmyth_livetv.h Thu Feb 01 18:42:01 2007 +0000
45.3 @@ -0,0 +1,101 @@
45.4 +/**
45.5 + * GMyth Library
45.6 + *
45.7 + * @file gmyth/gmyth_livetv.h
45.8 + *
45.9 + * @brief <p> GMythLiveTV starts a remote TV session with the MythTV backend.
45.10 + *
45.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
45.12 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
45.13 + *
45.14 + *//*
45.15 + *
45.16 + * This program is free software; you can redistribute it and/or modify
45.17 + * it under the terms of the GNU Lesser General Public License as published by
45.18 + * the Free Software Foundation; either version 2 of the License, or
45.19 + * (at your option) any later version.
45.20 + *
45.21 + * This program is distributed in the hope that it will be useful,
45.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
45.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45.24 + * GNU General Public License for more details.
45.25 + *
45.26 + * You should have received a copy of the GNU Lesser General Public License
45.27 + * along with this program; if not, write to the Free Software
45.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45.29 + */
45.30 +
45.31 +#ifndef GMYTH_LIVETV_H_
45.32 +#define GMYTH_LIVETV_H_
45.33 +
45.34 +#include <glib.h>
45.35 +#include <glib-object.h>
45.36 +
45.37 +#include "gmyth_recorder.h"
45.38 +#include "gmyth_tvchain.h"
45.39 +#include "gmyth_monitor_handler.h"
45.40 +#include "gmyth_file_transfer.h"
45.41 +#include "gmyth_programinfo.h"
45.42 +#include "gmyth_backendinfo.h"
45.43 +
45.44 +G_BEGIN_DECLS
45.45 +
45.46 +#define GMYTH_LIVETV_TYPE (gmyth_livetv_get_type ())
45.47 +#define GMYTH_LIVETV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_LIVETV_TYPE, GMythLiveTV))
45.48 +#define GMYTH_LIVETV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE, GMythLiveTVClass))
45.49 +#define IS_GMYTH_LIVETV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_LIVETV_TYPE))
45.50 +#define IS_GMYTH_LIVETV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE))
45.51 +#define GMYTH_LIVETV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_LIVETV_TYPE, GMythLiveTVClass))
45.52 +
45.53 +typedef struct _GMythLiveTV GMythLiveTV;
45.54 +typedef struct _GMythLiveTVClass GMythLiveTVClass;
45.55 +
45.56 +struct _GMythLiveTVClass
45.57 +{
45.58 + GObjectClass parent_class;
45.59 +
45.60 + /* callbacks */
45.61 +};
45.62 +
45.63 +struct _GMythLiveTV
45.64 +{
45.65 + GObject parent;
45.66 +
45.67 + GString *local_hostname;
45.68 +
45.69 + GMythBackendInfo *backend_info;
45.70 +
45.71 + GMythRecorder *recorder;
45.72 + GMythTVChain *tvchain;
45.73 + GMythProgramInfo *proginfo;
45.74 +
45.75 + GMythFileTransfer *file_transfer;
45.76 +
45.77 + GMythMonitorHandler *monitor;
45.78 + GMythURI *uri;
45.79 +
45.80 + gboolean is_livetv;
45.81 + gboolean setup_done;
45.82 +
45.83 +};
45.84 +
45.85 +GType gmyth_livetv_get_type (void);
45.86 +
45.87 +GMythLiveTV* gmyth_livetv_new ();
45.88 +
45.89 +void gmyth_livetv_start_playing (GMythLiveTV *livetv);
45.90 +void gmyth_livetv_stop_playing (GMythLiveTV *livetv);
45.91 +
45.92 +gboolean gmyth_livetv_setup (GMythLiveTV *livetv, GMythBackendInfo *backend_info);
45.93 +gboolean gmyth_livetv_channel_setup ( GMythLiveTV *livetv, gint channel, GMythBackendInfo *backend_info );
45.94 +gboolean gmyth_livetv_channel_name_setup ( GMythLiveTV *livetv, gchar* channel, GMythBackendInfo *backend_info );
45.95 +gboolean gmyth_livetv_next_program_chain ( GMythLiveTV *livetv );
45.96 +
45.97 +GMythFileTransfer *gmyth_livetv_create_file_transfer( GMythLiveTV *livetv );
45.98 +
45.99 +gboolean gmyth_livetv_monitor_handler_start( GMythLiveTV *livetv );
45.100 +void gmyth_livetv_monitor_handler_stop( GMythLiveTV *livetv );
45.101 +
45.102 +G_END_DECLS
45.103 +
45.104 +#endif /*GMYTH_LIVETV_H_*/
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/branches/gmyth-0.1b/src/gmyth_marshal.list Thu Feb 01 18:42:01 2007 +0000
46.3 @@ -0,0 +1,2 @@
46.4 +VOID:INT,STRING
46.5 +VOID:INT,POINTER
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/branches/gmyth-0.1b/src/gmyth_monitor_handler.c Thu Feb 01 18:42:01 2007 +0000
47.3 @@ -0,0 +1,595 @@
47.4 +/**
47.5 + * GMyth Library
47.6 + *
47.7 + * @file gmyth/gmyth_monitor_handler.c
47.8 + *
47.9 + * @brief <p> GMythMonitorHandler deals with the streaming media events remote/local
47.10 + * that are sent to the MythTV frontend.
47.11 + *
47.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
47.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
47.14 + *
47.15 + *//*
47.16 + *
47.17 + * This program is free software; you can redistribute it and/or modify
47.18 + * it under the terms of the GNU Lesser General Public License as published by
47.19 + * the Free Software Foundation; either version 2 of the License, or
47.20 + * (at your option) any later version.
47.21 + *
47.22 + * This program is distributed in the hope that it will be useful,
47.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
47.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47.25 + * GNU General Public License for more details.
47.26 + *
47.27 + * You should have received a copy of the GNU Lesser General Public License
47.28 + * along with this program; if not, write to the Free Software
47.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47.30 + *
47.31 + * GStreamer MythTV plug-in properties:
47.32 + * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
47.33 + * - path (qurl - remote file to be opened)
47.34 + * - port number *
47.35 + */
47.36 +
47.37 +#ifdef HAVE_CONFIG_H
47.38 +#include "config.h"
47.39 +#endif
47.40 +
47.41 +#include <unistd.h>
47.42 +#include <glib.h>
47.43 +#include <arpa/inet.h>
47.44 +#include <sys/types.h>
47.45 +#include <sys/socket.h>
47.46 +#include <netdb.h>
47.47 +#include <errno.h>
47.48 +#include <stdlib.h>
47.49 +#include <assert.h>
47.50 +
47.51 +#include "gmyth_marshal.h"
47.52 +
47.53 +#include "gmyth_monitor_handler.h"
47.54 +
47.55 +#include "gmyth.h"
47.56 +
47.57 +#define GMYTHTV_QUERY_HEADER "QUERY_FILETRANSFER "
47.58 +
47.59 +#define GMYTHTV_VERSION 30
47.60 +
47.61 +#define GMYTHTV_TRANSFER_MAX_WAITS 700
47.62 +
47.63 +#define GMYTHTV_BUFFER_SIZE 8*1024
47.64 +
47.65 +#ifdef GMYTHTV_ENABLE_DEBUG
47.66 +#define GMYTHTV_ENABLE_DEBUG 1
47.67 +#else
47.68 +#undef GMYTHTV_ENABLE_DEBUG
47.69 +#endif
47.70 +
47.71 +/* this NDEBUG is to maintain compatibility with GMyth library */
47.72 +#ifndef NDEBUG
47.73 +#define GMYTHTV_ENABLE_DEBUG 1
47.74 +#endif
47.75 +
47.76 +//GMainContext *io_watcher_context = NULL;
47.77 +
47.78 +//GThread *monitor_th = NULL;
47.79 +
47.80 +//static gboolean* myth_control_sock_listener( GIOChannel *io_channel );
47.81 +//static gboolean gmyth_monitor_handler_listener( GIOChannel *io_channel,
47.82 +// GIOCondition condition, gpointer data );
47.83 +
47.84 +//gboolean* gmyth_monitor_handler_listener( GMythMonitorHandler *monitor );
47.85 +
47.86 +void gmyth_monitor_handler_listener( GMythMonitorHandler *monitor, gpointer user_data );
47.87 +
47.88 +static void gmyth_monitor_handler_default_listener( GMythMonitorHandler *monitor, gint msg_code, gchar* message );
47.89 +
47.90 +static GMutex* mutex = NULL;
47.91 +
47.92 +//static GCond* io_watcher_cond = NULL;
47.93 +
47.94 +static void gmyth_monitor_handler_class_init (GMythMonitorHandlerClass *klass);
47.95 +static void gmyth_monitor_handler_init (GMythMonitorHandler *object);
47.96 +
47.97 +static void gmyth_monitor_handler_dispose (GObject *object);
47.98 +static void gmyth_monitor_handler_finalize (GObject *object);
47.99 +
47.100 +static gboolean gmyth_connect_to_backend_monitor (GMythMonitorHandler *monitor);
47.101 +
47.102 +void gmyth_monitor_handler_close( GMythMonitorHandler *monitor );
47.103 +
47.104 +G_DEFINE_TYPE(GMythMonitorHandler, gmyth_monitor_handler, G_TYPE_OBJECT)
47.105 +
47.106 +static void
47.107 +gmyth_monitor_handler_class_init (GMythMonitorHandlerClass *klass)
47.108 +{
47.109 + GObjectClass *gobject_class;
47.110 + GMythMonitorHandlerClass *gmonitor_class;
47.111 +
47.112 + gobject_class = (GObjectClass *) klass;
47.113 + gmonitor_class = (GMythMonitorHandlerClass *) gobject_class;
47.114 +
47.115 + gobject_class->dispose = gmyth_monitor_handler_dispose;
47.116 + gobject_class->finalize = gmyth_monitor_handler_finalize;
47.117 +
47.118 + gmonitor_class->backend_events_handler_signal_id =
47.119 + g_signal_new ("backend-events-handler",
47.120 + G_TYPE_FROM_CLASS (gmonitor_class),
47.121 + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
47.122 + 0,
47.123 + NULL,
47.124 + NULL,
47.125 + gmyth_marshal_VOID__INT_STRING,
47.126 + G_TYPE_NONE,
47.127 + 2,
47.128 + G_TYPE_INT,
47.129 + G_TYPE_STRING);
47.130 +
47.131 + gmonitor_class->backend_events_handler = gmyth_monitor_handler_default_listener;
47.132 +
47.133 +}
47.134 +
47.135 +static void
47.136 +gmyth_monitor_handler_init (GMythMonitorHandler *monitor)
47.137 +{
47.138 + g_return_if_fail( monitor != NULL );
47.139 +
47.140 + monitor->event_sock = NULL;
47.141 + monitor->hostname = NULL;
47.142 + monitor->port = 0;
47.143 + monitor->actual_index = 0;
47.144 +
47.145 + monitor->allow_msgs_listener = TRUE;
47.146 +
47.147 + //monitor->backend_msgs = g_hash_table_new( g_int_hash, g_int_equal );
47.148 +
47.149 + /* it is used for signalizing the event socket consumer thread */
47.150 + //io_watcher_cond = g_cond_new();
47.151 +
47.152 + /* mutex to control access to the event socket consumer thread */
47.153 + //mutex = g_mutex_new();
47.154 +
47.155 + monitor->monitor_th = NULL;
47.156 +
47.157 + monitor->gmyth_monitor_handler_listener = gmyth_monitor_handler_listener;
47.158 +}
47.159 +
47.160 +static void
47.161 +gmyth_monitor_handler_dispose (GObject *object)
47.162 +{
47.163 +
47.164 + GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER (object);
47.165 +
47.166 + monitor->allow_msgs_listener = FALSE;
47.167 +
47.168 + if ( monitor->monitor_th != NULL )
47.169 + {
47.170 + g_thread_pool_free( monitor->monitor_th, TRUE, FALSE );
47.171 + //g_thread_exit( monitor->monitor_th );
47.172 + if ( monitor->monitor_th != NULL )
47.173 + g_object_unref( monitor->monitor_th );
47.174 + monitor->monitor_th = NULL;
47.175 + }
47.176 +
47.177 + if ( monitor->event_sock != NULL )
47.178 + {
47.179 + g_object_unref( monitor->event_sock );
47.180 + monitor->event_sock = NULL;
47.181 + }
47.182 +
47.183 + if ( monitor->hostname != NULL )
47.184 + {
47.185 + g_free( monitor->hostname );
47.186 + monitor->hostname = NULL;
47.187 + }
47.188 +
47.189 + if ( monitor->backend_msgs != NULL )
47.190 + {
47.191 + g_hash_table_destroy ( monitor->backend_msgs );
47.192 + monitor->backend_msgs = NULL;
47.193 + }
47.194 +
47.195 + if ( mutex != NULL )
47.196 + {
47.197 + g_mutex_free( mutex );
47.198 + mutex = NULL;
47.199 + }
47.200 +
47.201 + /*
47.202 + if ( io_watcher_cond != NULL )
47.203 + {
47.204 + g_cond_free( io_watcher_cond );
47.205 + io_watcher_cond = NULL;
47.206 + }
47.207 + */
47.208 +
47.209 + G_OBJECT_CLASS (gmyth_monitor_handler_parent_class)->dispose (object);
47.210 +}
47.211 +
47.212 +static void
47.213 +gmyth_monitor_handler_finalize (GObject *object)
47.214 +{
47.215 + g_signal_handlers_destroy (object);
47.216 +
47.217 + G_OBJECT_CLASS (gmyth_monitor_handler_parent_class)->finalize (object);
47.218 +}
47.219 +
47.220 +// fixme: do we need the card_id????
47.221 +GMythMonitorHandler*
47.222 +gmyth_monitor_handler_new ( void )
47.223 +{
47.224 + GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER ( g_object_new ( GMYTH_MONITOR_HANDLER_TYPE,
47.225 + FALSE ) );
47.226 +
47.227 + return monitor;
47.228 +}
47.229 +
47.230 +static gboolean
47.231 +myth_control_acquire_context( gboolean do_wait )
47.232 +{
47.233 +
47.234 + gboolean ret = TRUE;
47.235 + //guint max_iter = 50;
47.236 +
47.237 + //g_mutex_lock( mutex );
47.238 +
47.239 + //while ( !has_io_access )
47.240 + // g_cond_wait( io_watcher_cond, mutex );
47.241 +
47.242 + //has_io_access = FALSE;
47.243 + /*
47.244 + if ( do_wait ) {
47.245 + while ( --max_iter > 0 && !g_main_context_wait( io_watcher_context, io_watcher_cond, mutex ) )
47.246 + ret = FALSE;
47.247 + } else if ( !g_main_context_acquire( io_watcher_context ) )
47.248 + ret = FALSE;
47.249 + */
47.250 +
47.251 + //g_static_mutex_lock( &st_mutex );
47.252 +
47.253 + return ret;
47.254 +
47.255 +}
47.256 +
47.257 +static gboolean
47.258 +myth_control_release_context( )
47.259 +{
47.260 +
47.261 + gboolean ret = TRUE;
47.262 +
47.263 + //g_static_mutex_unlock( &st_mutex );
47.264 +
47.265 + //g_main_context_release( io_watcher_context );
47.266 +
47.267 + //g_main_context_wakeup( io_watcher_context );
47.268 +
47.269 + //has_io_access = TRUE;
47.270 +
47.271 + //g_cond_broadcast( io_watcher_cond );
47.272 +
47.273 + //g_mutex_unlock( mutex );
47.274 +
47.275 + return ret;
47.276 +
47.277 +}
47.278 +
47.279 +gboolean
47.280 +gmyth_monitor_handler_open (GMythMonitorHandler *monitor, const gchar *hostname, gint port)
47.281 +{
47.282 + gboolean ret = TRUE;
47.283 +
47.284 + g_return_val_if_fail( hostname != NULL, FALSE );
47.285 +
47.286 + if (monitor->hostname != NULL) {
47.287 + g_free (monitor->hostname);
47.288 + monitor->hostname = NULL;
47.289 + }
47.290 +
47.291 + monitor->hostname = g_strdup( hostname );
47.292 + monitor->port = port;
47.293 +
47.294 + gmyth_debug ("Monitor event socket --- hostname: %s, port %d\n", monitor->hostname, monitor->port);
47.295 +
47.296 + /* configure the event socket */
47.297 + if ( NULL == monitor->event_sock ) {
47.298 + if (!gmyth_connect_to_backend_monitor (monitor)) {
47.299 + g_printerr( "Connection to backend failed (Event Socket).\n" );
47.300 + ret = FALSE;
47.301 + }
47.302 + } else {
47.303 + g_warning("Remote monitor event socket already created.\n");
47.304 + }
47.305 +
47.306 + return ret;
47.307 +
47.308 +}
47.309 +
47.310 +static gint
47.311 +gmyth_monitor_handler_is_backend_message( GMythMonitorHandler *monitor,
47.312 + GMythStringList* strlist, gchar **back_msg_action )
47.313 +{
47.314 + gint msg_type = GMYTH_BACKEND_NO_MESSAGE;
47.315 + GString *back_msg = NULL;
47.316 +
47.317 + back_msg = gmyth_string_list_get_string( strlist, 0 );
47.318 + if ( back_msg != NULL && back_msg->str != NULL &&
47.319 + strstr( back_msg->str, "BACKEND" ) != NULL )
47.320 + {
47.321 + gmyth_debug( "MONITOR HANDLER - Received backend message = %s", back_msg->str );
47.322 + *back_msg_action = gmyth_string_list_get_char_array( strlist, 1 );
47.323 +
47.324 + if ( back_msg_action != NULL )
47.325 + {
47.326 +
47.327 + if ( g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "LIVETV_CHAIN" ) ||
47.328 + g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "RECORDING_LIST_CHANGE" ) ||
47.329 + g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "SCHEDULE_CHANGE" ) ||
47.330 + g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "LIVETV_WATCH" ) )
47.331 + {
47.332 + gmyth_debug( "MONITOR: message type == GMYTH_BACKEND_PROGRAM_INFO_CHANGED, msg = %s", *back_msg_action );
47.333 + msg_type = GMYTH_BACKEND_PROGRAM_INFO_CHANGED;
47.334 + } else if ( g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "DONE_RECORDING" ) ) {
47.335 + gmyth_debug( "MONITOR: message type == GMYTH_BACKEND_DONE_RECORDING, msg = %s", *back_msg_action );
47.336 + msg_type = GMYTH_BACKEND_DONE_RECORDING;
47.337 + }
47.338 +
47.339 + //g_hash_table_insert ( monitor->backend_msgs,
47.340 + // &(monitor->actual_index), *back_msg_action );
47.341 +
47.342 + } // if
47.343 + }
47.344 +
47.345 + if ( back_msg != NULL )
47.346 + {
47.347 + g_string_free( back_msg, TRUE );
47.348 + back_msg = NULL;
47.349 + }
47.350 +
47.351 + return msg_type;
47.352 +
47.353 +}
47.354 +
47.355 +static void
47.356 +gmyth_monitor_handler_default_listener( GMythMonitorHandler *monitor, gint msg_code, gchar* message )
47.357 +{
47.358 + //assert( message!= NULL );
47.359 + gmyth_debug( "DEFAULT Signal handler ( msg = %s, code = %d )\n",
47.360 + message, msg_code );
47.361 +}
47.362 +
47.363 +static void
47.364 +gmyth_monitor_handler_print( GString *str, gpointer ptr )
47.365 +{
47.366 + gmyth_debug( "Backend message event: %s --- ", str->str );
47.367 +}
47.368 +
47.369 +//static void
47.370 +//gmyth_monitor_handler_listener (GMythMonitorHandler *monitor, gpointer user_data)
47.371 +//static gboolean
47.372 +//gmyth_monitor_handler_listener( GIOChannel *io_channel, GIOCondition condition, gpointer data )
47.373 +//gboolean* gmyth_monitor_handler_listener( GMythMonitorHandler *monitor )
47.374 +void
47.375 +gmyth_monitor_handler_listener (GMythMonitorHandler *monitor, gpointer user_data)
47.376 +{
47.377 + //GMythMonitorHandler *monitor = (GMythMonitorHandler*)data;
47.378 + GIOStatus io_status;
47.379 + GIOCondition io_cond;
47.380 + guint recv = 0;
47.381 + gboolean *ret = g_new0( gboolean, 1 );
47.382 + *ret = TRUE;
47.383 + //gboolean ret = TRUE;
47.384 + gsize len = 0;
47.385 +
47.386 + static guint count = 0;
47.387 +
47.388 + GIOChannel *io_channel = monitor->event_sock->sd_io_ch;
47.389 + //GIOCondition condition = g_io_channel_get_buffer_condition( io_channel );
47.390 +
47.391 + GMythStringList *strlist = NULL;
47.392 +
47.393 + //GMythMonitorHandler *monitor = (GMythMonitorHandler*)data;
47.394 +
47.395 + myth_control_acquire_context (TRUE);
47.396 +
47.397 + if ( io_channel == NULL ) {
47.398 + g_debug ("Monitor socket is NULL!\n");
47.399 + *ret = FALSE;
47.400 + goto clean_up;
47.401 + }
47.402 +
47.403 + while (monitor->allow_msgs_listener) {
47.404 + ++count;
47.405 +
47.406 + gmyth_debug ("%d - Listening on Monitor socket...!\n", count);
47.407 +
47.408 + do
47.409 + {
47.410 +
47.411 + gint bytes_sent = 0;
47.412 +
47.413 + strlist = gmyth_string_list_new();
47.414 +
47.415 + if ( monitor->event_sock != NULL )
47.416 + {
47.417 +
47.418 + len = gmyth_socket_read_stringlist( monitor->event_sock, strlist );
47.419 +
47.420 + if ( strlist != NULL && gmyth_string_list_length( strlist ) > 0 )
47.421 + {
47.422 + bytes_sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error
47.423 +
47.424 + gmyth_debug ( "[%s] MONITOR: received data buffer from IO event channel... %d strings gone!\n",
47.425 + __FUNCTION__, len );
47.426 +
47.427 + recv += len;
47.428 +
47.429 + /* debug purpose: prints out all the string list elements */
47.430 + g_list_foreach( strlist->glist, (GFunc)gmyth_monitor_handler_print, NULL );
47.431 +
47.432 + gchar *back_msg_action = g_new0( gchar, 1 );
47.433 + gint msg_type = gmyth_monitor_handler_is_backend_message( monitor, strlist,
47.434 + &back_msg_action );
47.435 +
47.436 + g_signal_emit ( monitor,
47.437 + GMYTH_MONITOR_HANDLER_GET_CLASS (monitor)->backend_events_handler_signal_id,
47.438 + 0, /* details */
47.439 + msg_type, back_msg_action );
47.440 +
47.441 + if (back_msg_action!= NULL)
47.442 + g_free( back_msg_action );
47.443 +
47.444 + }
47.445 +
47.446 + }
47.447 +
47.448 + if (strlist!=NULL)
47.449 + g_object_unref( strlist );
47.450 +
47.451 + io_cond = g_io_channel_get_buffer_condition( io_channel );
47.452 +
47.453 + } while ( recv <= 0 && ( io_cond & G_IO_IN ) != 0 );
47.454 +
47.455 + gmyth_debug ("[%s]\tMONITOR EVENT: Read %d bytes\n", __FUNCTION__, recv );
47.456 +
47.457 + g_usleep( 300 );
47.458 +
47.459 + } /* main GThread while */
47.460 +
47.461 + myth_control_release_context ();
47.462 +
47.463 + if ( io_status == G_IO_STATUS_ERROR ) {
47.464 + //gmyth_debug ("[%s] Error reading: %s\n", __FUNCTION__, error != NULL ? error->message : "" );
47.465 + gmyth_debug ("Error reading MONITOR event socket.\n");
47.466 + *ret = FALSE;
47.467 + goto clean_up;
47.468 + }
47.469 +
47.470 +clean_up:
47.471 +
47.472 + if (strlist!=NULL)
47.473 + g_object_unref( strlist );
47.474 +
47.475 + return;
47.476 +
47.477 +}
47.478 +
47.479 +static gboolean
47.480 +gmyth_connect_to_backend_monitor (GMythMonitorHandler *monitor)
47.481 +{
47.482 + gboolean ret = TRUE;
47.483 +
47.484 + monitor->event_sock = gmyth_socket_new();
47.485 +
47.486 + /* Connects the socket, send Mythtv ANN Monitor and verify Mythtv protocol version */
47.487 + if (!gmyth_socket_connect_to_backend_events ( monitor->event_sock,
47.488 + monitor->hostname, monitor->port, FALSE ) )
47.489 + {
47.490 + g_object_unref (monitor->event_sock);
47.491 + monitor->event_sock = NULL;
47.492 + ret = FALSE;
47.493 + }
47.494 +
47.495 + return ret;
47.496 +}
47.497 +
47.498 +static gboolean*
47.499 +gmyth_monitor_handler_setup( GMythMonitorHandler *monitor, GIOChannel *channel )
47.500 +{
47.501 + gboolean *ret = g_new0( gboolean, 1 );
47.502 + guint src_id = 0;
47.503 +
47.504 + *ret = TRUE;
47.505 +
47.506 + //io_watcher_context = g_main_context_default();
47.507 + //GMainLoop *loop = g_main_loop_new( io_watcher_context, TRUE );
47.508 +
47.509 + //GSource *source;
47.510 +
47.511 + if ( channel != NULL ) {
47.512 + //source = g_io_create_watch( channel, G_IO_IN | G_IO_HUP );
47.513 + src_id = g_io_add_watch( channel, G_IO_IN,
47.514 + (GIOFunc)gmyth_monitor_handler_listener, monitor );
47.515 + } else {
47.516 + *ret = FALSE;
47.517 + goto cleanup;
47.518 + }
47.519 +
47.520 + //g_source_set_callback ( source, (GSourceFunc)gmyth_monitor_handler_listener, NULL, NULL );
47.521 +
47.522 + //g_source_attach( source, io_watcher_context );
47.523 +
47.524 + //if (NULL == source){
47.525 + if (src_id < 0){
47.526 + gmyth_debug( "[%s] Error adding watch listener function to the IO control channel!\n", __FUNCTION__ );
47.527 + *ret = FALSE;
47.528 + goto cleanup;
47.529 + }
47.530 +
47.531 + //g_main_loop_run( loop );
47.532 +
47.533 +cleanup:
47.534 + //if ( source != NULL )
47.535 + // g_source_unref( source );
47.536 +
47.537 + //if ( io_watcher_context != NULL )
47.538 + // g_main_context_unref( io_watcher_context );
47.539 +
47.540 + //if ( loop != NULL )
47.541 + // g_main_loop_unref( loop );
47.542 +
47.543 + return ret;
47.544 +
47.545 +}
47.546 +
47.547 +gboolean
47.548 +gmyth_monitor_handler_start (GMythMonitorHandler *monitor)
47.549 +{
47.550 + gboolean *ret = g_new0( gboolean, 1 );
47.551 + *ret = TRUE;
47.552 +
47.553 + /*if (!g_thread_supported () ) g_thread_init (NULL);*/
47.554 + /*
47.555 + monitor->monitor_th = g_thread_pool_new( (GThreadFunc)gmyth_monitor_handler_listener,
47.556 + monitor, TRUE, NULL );
47.557 + */
47.558 + monitor->monitor_th = g_thread_pool_new( (GFunc)gmyth_monitor_handler_listener,
47.559 + monitor, 3, TRUE, NULL );
47.560 + g_thread_pool_push( monitor->monitor_th, monitor, NULL );
47.561 +
47.562 + //if ( ( ret = g_thread_join( monitor_th ) ) == FALSE )
47.563 + if ( monitor->monitor_th != NULL )
47.564 + //if ( gmyth_monitor_handler_setup( monitor, monitor->event_sock->sd_io_ch ) )
47.565 + {
47.566 + gmyth_debug ( "\n[%s]\tOK! Starting listener on the MONITOR event socket...[thread location = %p]\n",
47.567 + __FUNCTION__, g_thread_self( ) );
47.568 + *ret = TRUE;
47.569 + } else {
47.570 + gmyth_debug ( "\n[%s]\tERROR! Coudn't start listener on the MONITOR event socket...[thread location = %p]\n",
47.571 + __FUNCTION__, g_thread_self( ) );
47.572 + *ret = FALSE;
47.573 + }
47.574 +
47.575 +//cleanup:
47.576 +
47.577 + gmyth_debug( "[%s] Watch listener function over the IO control channel? %s!!!\n",
47.578 + __FUNCTION__, ( *ret == TRUE ? "YES" : "NO" ) );
47.579 +
47.580 + return *ret;
47.581 +}
47.582 +
47.583 +void
47.584 +gmyth_monitor_handler_close( GMythMonitorHandler *monitor )
47.585 +{
47.586 +
47.587 + if (monitor->event_sock) {
47.588 + g_object_unref( monitor->event_sock );
47.589 + monitor->event_sock = NULL;
47.590 + }
47.591 +
47.592 + if (monitor->hostname) {
47.593 + g_free( monitor->hostname );
47.594 + monitor->hostname = NULL;
47.595 + }
47.596 +
47.597 +}
47.598 +
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48.2 +++ b/branches/gmyth-0.1b/src/gmyth_monitor_handler.h Thu Feb 01 18:42:01 2007 +0000
48.3 @@ -0,0 +1,117 @@
48.4 +/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
48.5 +/**
48.6 + * GMyth Library
48.7 + *
48.8 + * @file gmyth/gmyth_monitor_handler.h
48.9 + *
48.10 + * @brief <p> GMythMonitorHandler deals with the streaming media events remote/local
48.11 + * that are sent to the MythTV frontend.
48.12 + *
48.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
48.14 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
48.15 + *
48.16 + *//*
48.17 + *
48.18 + * This program is free software; you can redistribute it and/or modify
48.19 + * it under the terms of the GNU Lesser General Public License as published by
48.20 + * the Free Software Foundation; either version 2 of the License, or
48.21 + * (at your option) any later version.
48.22 + *
48.23 + * This program is distributed in the hope that it will be useful,
48.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
48.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48.26 + * GNU General Public License for more details.
48.27 + *
48.28 + * You should have received a copy of the GNU Lesser General Public License
48.29 + * along with this program; if not, write to the Free Software
48.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
48.31 + */
48.32 +
48.33 +#ifndef __GMYTH_MONITOR_HANDLER_H__
48.34 +#define __GMYTH_MONITOR_HANDLER_H__
48.35 +
48.36 +#include <glib-object.h>
48.37 +#include <glib.h>
48.38 +#include <stdio.h>
48.39 +#include <stdlib.h>
48.40 +#include <string.h>
48.41 +
48.42 +#include <netdb.h>
48.43 +#include <sys/socket.h>
48.44 +#include <unistd.h>
48.45 +
48.46 +#include "gmyth_socket.h"
48.47 +#include "gmyth_uri.h"
48.48 +
48.49 +G_BEGIN_DECLS
48.50 +
48.51 +#define GMYTH_MONITOR_HANDLER_TYPE (gmyth_monitor_handler_get_type ())
48.52 +#define GMYTH_MONITOR_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandler))
48.53 +#define GMYTH_MONITOR_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandlerClass))
48.54 +#define IS_GMYTH_MONITOR_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_MONITOR_HANDLER_TYPE))
48.55 +#define IS_GMYTH_MONITOR_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_MONITOR_HANDLER_TYPE))
48.56 +#define GMYTH_MONITOR_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandlerClass))
48.57 +
48.58 +#define GMYTHTV_MONITOR_HANDLER_READ_ERROR -314
48.59 +
48.60 +enum {
48.61 + GMYTH_BACKEND_NO_MESSAGE = 0,
48.62 + GMYTH_BACKEND_PROGRAM_INFO_CHANGED,
48.63 + GMYTH_BACKEND_DONE_RECORDING,
48.64 + GMYTH_BACKEND_STOP_LIVETV
48.65 +};
48.66 +
48.67 +typedef struct _GMythMonitorHandler GMythMonitorHandler;
48.68 +typedef struct _GMythMonitorHandlerClass GMythMonitorHandlerClass;
48.69 +
48.70 +struct _GMythMonitorHandlerClass
48.71 +{
48.72 + GObjectClass parent_class;
48.73 +
48.74 + /* callbacks */
48.75 + guint backend_events_handler_signal_id;
48.76 +
48.77 + /* signal default handlers */
48.78 + void (*backend_events_handler) (GMythMonitorHandler *monitor, gint msg_code, gchar* message );
48.79 +};
48.80 +
48.81 +struct _GMythMonitorHandler
48.82 +{
48.83 + GObject parent;
48.84 +
48.85 + /* MythTV version number */
48.86 + gint mythtv_version;
48.87 +
48.88 + /* socket descriptors */
48.89 + GMythSocket *event_sock;
48.90 +
48.91 + GThreadPool *monitor_th;
48.92 +
48.93 + // gboolean* (*gmyth_monitor_handler_listener)( GMythMonitorHandler *monitor );
48.94 + void (*gmyth_monitor_handler_listener)( GMythMonitorHandler *monitor, gpointer user_data );
48.95 +
48.96 + gchar *hostname;
48.97 + gint port;
48.98 +
48.99 + gint64 actual_index;
48.100 +
48.101 + gboolean allow_msgs_listener;
48.102 +
48.103 + /* stores the messages coming from the backend */
48.104 + GHashTable *backend_msgs;
48.105 +
48.106 +};
48.107 +
48.108 +GType gmyth_monitor_handler_get_type (void);
48.109 +
48.110 +GMythMonitorHandler* gmyth_monitor_handler_new ( void );
48.111 +
48.112 +gboolean gmyth_monitor_handler_open (GMythMonitorHandler *monitor, const gchar *hostname, gint port);
48.113 +
48.114 +gboolean gmyth_monitor_handler_start (GMythMonitorHandler *monitor);
48.115 +
48.116 +void gmyth_monitor_handler_close (GMythMonitorHandler *monitor);
48.117 +
48.118 +G_END_DECLS
48.119 +
48.120 +#endif /* __GMYTH_MONITOR_HANDLER_H__ */
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49.2 +++ b/branches/gmyth-0.1b/src/gmyth_programinfo.c Thu Feb 01 18:42:01 2007 +0000
49.3 @@ -0,0 +1,460 @@
49.4 +/**
49.5 + * GMyth Library
49.6 + *
49.7 + * @file gmyth/gmyth_programinfo.c
49.8 + *
49.9 + * @brief <p> GMythFileTransfer deals with the file streaming media remote/local
49.10 + * transfering to the MythTV frontend.
49.11 + *
49.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
49.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
49.14 + *
49.15 + *//*
49.16 + *
49.17 + * This program is free software; you can redistribute it and/or modify
49.18 + * it under the terms of the GNU Lesser General Public License as published by
49.19 + * the Free Software Foundation; either version 2 of the License, or
49.20 + * (at your option) any later version.
49.21 + *
49.22 + * This program is distributed in the hope that it will be useful,
49.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
49.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49.25 + * GNU General Public License for more details.
49.26 + *
49.27 + * You should have received a copy of the GNU Lesser General Public License
49.28 + * along with this program; if not, write to the Free Software
49.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
49.30 + *
49.31 + */
49.32 +
49.33 +#ifdef HAVE_CONFIG_H
49.34 +#include "config.h"
49.35 +#endif
49.36 +
49.37 +#include <stdlib.h>
49.38 +#include <string.h>
49.39 +#include <assert.h>
49.40 +
49.41 +#include "gmyth_programinfo.h"
49.42 +#include "gmyth_util.h"
49.43 +#include "gmyth_debug.h"
49.44 +
49.45 +static void gmyth_program_info_class_init (GMythProgramInfoClass *klass);
49.46 +static void gmyth_program_info_init (GMythProgramInfo *object);
49.47 +
49.48 +static void gmyth_program_info_dispose (GObject *object);
49.49 +static void gmyth_program_info_finalize (GObject *object);
49.50 +
49.51 +G_DEFINE_TYPE(GMythProgramInfo, gmyth_program_info, G_TYPE_OBJECT)
49.52 +
49.53 +static void
49.54 +gmyth_program_info_class_init (GMythProgramInfoClass *klass)
49.55 +{
49.56 + GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
49.57 +
49.58 + gobject_class->dispose = gmyth_program_info_dispose;
49.59 + gobject_class->finalize = gmyth_program_info_finalize;
49.60 +}
49.61 +
49.62 +static void
49.63 +gmyth_program_info_init (GMythProgramInfo *gmyth_program_info)
49.64 +{
49.65 + gmyth_program_info->chancommfree = 0;
49.66 +
49.67 + /** A flag informing if the program has video or not. */
49.68 + gmyth_program_info->isVideo = FALSE;
49.69 + gmyth_program_info->lenMins = 0;
49.70 +
49.71 + gmyth_program_info->stars = 0.0f;
49.72 + gmyth_program_info->repeat = 0;
49.73 +
49.74 + gmyth_program_info->hasAirDate = FALSE;
49.75 +
49.76 + gmyth_program_info->spread = 0;
49.77 + gmyth_program_info->startCol = 0;
49.78 +
49.79 + gmyth_program_info->recpriority2 = 0;
49.80 + gmyth_program_info->reactivate = 0;
49.81 +
49.82 + gmyth_program_info->recordid = 0;
49.83 + gmyth_program_info->parentid = 0;
49.84 +
49.85 + /** The backend video source id associated to this program.*/
49.86 + gmyth_program_info->sourceid = 0;
49.87 + /** the backend input id associated to this program.*/
49.88 + gmyth_program_info->inputid = 0;
49.89 + /** The backend card id associated to this program.*/
49.90 + gmyth_program_info->cardid = 0;
49.91 + gmyth_program_info->shareable = FALSE;
49.92 + gmyth_program_info->duplicate = FALSE;
49.93 +
49.94 + gmyth_program_info->findid = 0;
49.95 +
49.96 + gmyth_program_info->programflags = 0;
49.97 + gmyth_program_info->transcoder = 0;
49.98 +
49.99 + gmyth_program_info->recpriority = 0;
49.100 +
49.101 + /** The file size of the recorded program.*/
49.102 + gmyth_program_info->filesize = -1;
49.103 +
49.104 +
49.105 +}
49.106 +
49.107 +static void
49.108 +gmyth_program_info_dispose (GObject *object)
49.109 +{
49.110 + GMythProgramInfo *gmyth_program_info = GMYTH_PROGRAM_INFO(object);
49.111 +
49.112 + if ( gmyth_program_info->chanid != NULL )
49.113 + {
49.114 + g_string_free( gmyth_program_info->chanid, TRUE );
49.115 + gmyth_program_info->chanid = NULL;
49.116 + }
49.117 +
49.118 + /** The program start time. */
49.119 + if ( gmyth_program_info->startts != NULL )
49.120 + {
49.121 + g_free( gmyth_program_info->startts);
49.122 + gmyth_program_info->startts = NULL;
49.123 + }
49.124 +
49.125 + /** The program end time. */
49.126 + if ( gmyth_program_info->endts != NULL )
49.127 + {
49.128 + g_free( gmyth_program_info->endts );
49.129 + gmyth_program_info->endts = NULL;
49.130 + }
49.131 +
49.132 + /** The recording schedule start time. */
49.133 + if ( gmyth_program_info->recstartts != NULL )
49.134 + {
49.135 + g_free( gmyth_program_info->recstartts );
49.136 + gmyth_program_info->recstartts = NULL;
49.137 + }
49.138 +
49.139 + /** The recording schedule end time */
49.140 + if ( gmyth_program_info->recendts != NULL )
49.141 + {
49.142 + g_free(gmyth_program_info->recendts);
49.143 + gmyth_program_info->recendts = NULL;
49.144 + }
49.145 +
49.146 + /** The program title. */
49.147 + if (gmyth_program_info->title != NULL )
49.148 + {
49.149 + g_string_free(gmyth_program_info->title, TRUE);
49.150 + gmyth_program_info->title = NULL;
49.151 + }
49.152 +
49.153 + /** The program subtitle. */
49.154 + if (gmyth_program_info->subtitle != NULL )
49.155 + {
49.156 + g_string_free(gmyth_program_info->subtitle, TRUE );
49.157 + gmyth_program_info->subtitle = NULL;
49.158 + }
49.159 + /** The program description. */
49.160 + if ( gmyth_program_info->description != NULL )
49.161 + {
49.162 + g_string_free( gmyth_program_info->description, TRUE );
49.163 + gmyth_program_info->description = NULL;
49.164 + }
49.165 +
49.166 + /** The program category. */
49.167 + if ( gmyth_program_info->category != NULL )
49.168 + {
49.169 + g_string_free( gmyth_program_info->category, TRUE );
49.170 + gmyth_program_info->category = NULL;
49.171 + }
49.172 +
49.173 + if ( gmyth_program_info->chanstr != NULL )
49.174 + {
49.175 + g_string_free( gmyth_program_info->chanstr, TRUE );
49.176 + gmyth_program_info->chanstr = NULL;
49.177 + }
49.178 + if ( gmyth_program_info->chansign != NULL )
49.179 + {
49.180 + g_string_free( gmyth_program_info->chansign, TRUE );
49.181 + gmyth_program_info->chansign = NULL;
49.182 + }
49.183 + /** The associated channel name. */
49.184 + if ( gmyth_program_info->channame != NULL )
49.185 + {
49.186 + g_string_free( gmyth_program_info->channame, TRUE );
49.187 + gmyth_program_info->channame = NULL;
49.188 + }
49.189 + if ( gmyth_program_info->chanOutputFilters != NULL )
49.190 + {
49.191 + g_string_free( gmyth_program_info->chanOutputFilters, TRUE );
49.192 + gmyth_program_info->chanOutputFilters = NULL;
49.193 + }
49.194 +
49.195 + if ( gmyth_program_info->seriesid != NULL )
49.196 + {
49.197 + g_string_free( gmyth_program_info->seriesid, TRUE );
49.198 + gmyth_program_info->chanOutputFilters = NULL;
49.199 +
49.200 + }
49.201 + /** The program unique id. */
49.202 + if ( gmyth_program_info->programid != NULL )
49.203 + {
49.204 + g_string_free( gmyth_program_info->programid, TRUE );
49.205 + gmyth_program_info->programid = NULL;
49.206 +
49.207 + }
49.208 + if ( gmyth_program_info->catType != NULL )
49.209 + {
49.210 + g_string_free( gmyth_program_info->catType, TRUE );
49.211 + gmyth_program_info->catType = NULL;
49.212 +
49.213 + }
49.214 +
49.215 + if ( gmyth_program_info->sortTitle != NULL )
49.216 + {
49.217 + g_string_free( gmyth_program_info->sortTitle, TRUE );
49.218 + gmyth_program_info->sortTitle = NULL;
49.219 +
49.220 + }
49.221 +
49.222 + if ( gmyth_program_info->year != NULL )
49.223 + {
49.224 + g_string_free( gmyth_program_info->year, TRUE );
49.225 + gmyth_program_info->year = NULL;
49.226 +
49.227 + }
49.228 +
49.229 + if ( gmyth_program_info->originalAirDate != NULL )
49.230 + {
49.231 + g_free( gmyth_program_info->originalAirDate);
49.232 + gmyth_program_info->originalAirDate = NULL;
49.233 + }
49.234 + if ( gmyth_program_info->lastmodified != NULL )
49.235 + {
49.236 + g_free( gmyth_program_info->lastmodified );
49.237 + gmyth_program_info->lastmodified = NULL;
49.238 +
49.239 + }
49.240 + if (gmyth_program_info->lastInUseTime != NULL)
49.241 + {
49.242 + g_free( gmyth_program_info->lastInUseTime );
49.243 + gmyth_program_info->lastInUseTime = NULL;
49.244 + }
49.245 +
49.246 + if ( gmyth_program_info->schedulerid != NULL )
49.247 + {
49.248 + g_string_free( gmyth_program_info->schedulerid, TRUE );
49.249 + gmyth_program_info->schedulerid = NULL;
49.250 + }
49.251 +
49.252 + if ( gmyth_program_info->recgroup != NULL )
49.253 + {
49.254 + g_string_free( gmyth_program_info->recgroup, TRUE );
49.255 + gmyth_program_info->recgroup = NULL;
49.256 + }
49.257 + if ( gmyth_program_info->playgroup != NULL )
49.258 + {
49.259 + g_string_free( gmyth_program_info->playgroup, TRUE );
49.260 + gmyth_program_info->playgroup = NULL;
49.261 + }
49.262 +
49.263 + /** The file name of the recorded program.*/
49.264 + if ( gmyth_program_info->pathname != NULL)
49.265 + {
49.266 + g_string_free( gmyth_program_info->pathname, TRUE );
49.267 + gmyth_program_info->pathname = NULL;
49.268 + }
49.269 +
49.270 + if ( gmyth_program_info->hostname != NULL )
49.271 + {
49.272 + g_string_free( gmyth_program_info->hostname, TRUE );
49.273 + gmyth_program_info->hostname = NULL;
49.274 + }
49.275 +
49.276 + G_OBJECT_CLASS (gmyth_program_info_parent_class)->dispose (object);
49.277 +}
49.278 +
49.279 +static void
49.280 +gmyth_program_info_finalize (GObject *object)
49.281 +{
49.282 + g_signal_handlers_destroy (object);
49.283 +
49.284 + G_OBJECT_CLASS (gmyth_program_info_parent_class)->finalize (object);
49.285 +}
49.286 +
49.287 +/**
49.288 + * Creates a new instance of GMythProgramInfo.
49.289 + *
49.290 + * @return a new instance of GMythProgramInfo.
49.291 + */
49.292 +GMythProgramInfo*
49.293 +gmyth_program_info_new (void)
49.294 +{
49.295 + GMythProgramInfo *program_info = GMYTH_PROGRAM_INFO (g_object_new(GMYTH_PROGRAM_INFO_TYPE, NULL));
49.296 +
49.297 + return program_info;
49.298 +}
49.299 +
49.300 +GMythStringList*
49.301 +gmyth_program_info_to_string_list (GMythProgramInfo *prog, GMythStringList *slist)
49.302 +{
49.303 + g_return_val_if_fail (prog != NULL, NULL);
49.304 + g_return_val_if_fail (slist != NULL, NULL);
49.305 +
49.306 + gmyth_string_list_append_string (slist, prog->title); /* 0 */
49.307 + gmyth_string_list_append_string (slist, prog->subtitle); /* 1 */
49.308 + gmyth_string_list_append_string (slist, prog->description); /* 2 */
49.309 + gmyth_string_list_append_string (slist, prog->category); /* 3 */
49.310 + gmyth_string_list_append_string (slist, prog->chanid); /* 4 */
49.311 + gmyth_string_list_append_string (slist, prog->chanstr); /* 5 */
49.312 + gmyth_string_list_append_string (slist, prog->chansign); /* 6 */
49.313 + gmyth_string_list_append_string (slist, prog->channame); /* 7 */
49.314 + gmyth_string_list_append_string (slist, prog->pathname); /* 8 */
49.315 +
49.316 + // fixme
49.317 + gmyth_string_list_append_int64 (slist, 100/*prog->filesize*/); /* 9 */
49.318 + gmyth_string_list_append_int64 (slist, 10); /* 11 */
49.319 +
49.320 + if (prog->startts)
49.321 + gmyth_string_list_append_int (slist, prog->startts->tv_sec); /* 11 */ //DATETIME_TO_LIST(startts)
49.322 + else
49.323 + gmyth_string_list_append_int (slist, 0);
49.324 +
49.325 + if (prog->endts)
49.326 + gmyth_string_list_append_int (slist, prog->endts->tv_sec); /* 12 */ //DATETIME_TO_LIST(endts)
49.327 + else
49.328 + gmyth_string_list_append_int (slist, 0);
49.329 +
49.330 + gmyth_string_list_append_int (slist, prog->duplicate); /* 13 */
49.331 + gmyth_string_list_append_int (slist, prog->shareable); /* 14 */
49.332 + gmyth_string_list_append_int (slist, prog->findid); /* 15 */
49.333 + gmyth_string_list_append_string (slist, prog->hostname); /* 16 */
49.334 + gmyth_string_list_append_int (slist, prog->sourceid); /* 17 */
49.335 + gmyth_string_list_append_int (slist, prog->cardid); /* 18 */
49.336 + gmyth_string_list_append_int (slist, prog->inputid); /* 19 */
49.337 + gmyth_string_list_append_int (slist, prog->recpriority); /* 20 */
49.338 + gmyth_string_list_append_int (slist, 0 /*prog->recstatus*/); /* 21 */
49.339 + gmyth_string_list_append_int (slist, prog->recordid); /* 22 */
49.340 + gmyth_string_list_append_int (slist, 0 /*prog->rectype*/); /* 23 */
49.341 + gmyth_string_list_append_int (slist, 0 /*prog->dupin*/); /* 24 */
49.342 + gmyth_string_list_append_int (slist, 0 /*prog->dupmethod*/); /* 25 */
49.343 + gmyth_string_list_append_int (slist, prog->recstartts != NULL ? prog->recstartts->tv_sec : 0); /* 26 */ //DATETIME_TO_LIST(recstartts)
49.344 + gmyth_string_list_append_int (slist, prog->recendts != NULL ? prog->recendts->tv_sec : 0); /* 27 */ //DATETIME_TO_LIST(recendts)
49.345 + gmyth_string_list_append_int (slist, prog->repeat); /* 28 */
49.346 + gmyth_string_list_append_int (slist, prog->programflags); /* 29 */
49.347 + gmyth_string_list_append_char_array (slist, "Default"); /* 30 */ //prog->(recgroup != "") ? recgroup : "Default")
49.348 + gmyth_string_list_append_int (slist, prog->chancommfree); /* 31 */
49.349 + gmyth_string_list_append_string (slist, prog->chanOutputFilters); /* 32 */
49.350 + gmyth_string_list_append_string (slist, prog->seriesid); /* 33 */
49.351 + gmyth_string_list_append_string (slist, prog->programid); /* 34 */
49.352 + gmyth_string_list_append_string (slist, ""); /* 35 */
49.353 + gmyth_string_list_append_int (slist, prog->lastmodified != NULL ? prog->lastmodified->tv_sec : 0); /* 36 */ //DATETIME_TO_LIST(lastmodified)
49.354 + gmyth_string_list_append_int (slist, 0); /* 37 */ //FLOAT_TO_LIST(stars)
49.355 + gmyth_string_list_append_int (slist, prog->originalAirDate != NULL ? prog->originalAirDate->tv_sec : 0); /* 38 */ //DATETIME_TO_LIST(QDateTime(originalAirDate))
49.356 + gmyth_string_list_append_int (slist, prog->hasAirDate); /* 39 */
49.357 + gmyth_string_list_append_char_array (slist, "Default"); /* 40 */ //prog->(playgroup != "") ? playgroup : "Default")
49.358 + gmyth_string_list_append_int (slist, prog->recpriority2); /* 41 */
49.359 +
49.360 + return slist;
49.361 +}
49.362 +
49.363 +GMythProgramInfo*
49.364 +gmyth_program_info_from_string_list ( GMythStringList *slist )
49.365 +{
49.366 + GMythProgramInfo *prog = gmyth_program_info_new();
49.367 +
49.368 + g_return_val_if_fail (slist != NULL, NULL);
49.369 + /*
49.370 + Unknown
49.371 +
49.372 +
49.373 +
49.374 + 1000
49.375 + 9
49.376 + 1000
49.377 + Band
49.378 + /mnt/store//1000_20070125110059.nuv
49.379 + 0
49.380 + 0
49.381 + 1169733659
49.382 + 1169735400
49.383 + 0
49.384 + 0
49.385 + 0
49.386 + hmelo-desktop
49.387 + 0
49.388 + 1
49.389 + 0
49.390 + 0
49.391 + -2
49.392 + 0
49.393 + 0
49.394 + 15
49.395 + 6
49.396 + 1169733659
49.397 + 1169735400
49.398 + 0
49.399 + 0
49.400 + LiveTV
49.401 + 0
49.402 +
49.403 +
49.404 +
49.405 + 1169733659
49.406 + 0.000000
49.407 + -1
49.408 + 0
49.409 + Default
49.410 + 0
49.411 + */
49.412 + prog->title = gmyth_string_list_get_string (slist, 0);
49.413 + prog->subtitle = gmyth_string_list_get_string (slist, 1);
49.414 + prog->description = gmyth_string_list_get_string (slist, 2);
49.415 + prog->category = gmyth_string_list_get_string (slist, 3);
49.416 + prog->chanid = gmyth_string_list_get_string (slist, 4);
49.417 + prog->chanstr = gmyth_string_list_get_string (slist, 5);
49.418 + prog->chansign = gmyth_string_list_get_string (slist, 6);
49.419 + prog->channame = gmyth_string_list_get_string (slist, 7);
49.420 + prog->pathname = gmyth_string_list_get_string (slist, 8);
49.421 + prog->filesize = gmyth_string_list_get_int64 (slist, 9);
49.422 + gmyth_string_list_get_int64 (slist, 10);
49.423 +
49.424 + prog->startts = gmyth_util_string_to_time_val( (gmyth_util_time_to_isoformat(
49.425 + (time_t)gmyth_string_list_get_int (slist, 11) ))->str ); //DATETIME_TO_LIST(startts)
49.426 + prog->endts = gmyth_util_string_to_time_val( (gmyth_util_time_to_isoformat(
49.427 + (time_t)gmyth_string_list_get_int (slist, 12) ))->str ); //DATETIME_TO_LIST(endts)
49.428 + prog->duplicate = gmyth_string_list_get_int (slist, 13);
49.429 + prog->shareable = gmyth_string_list_get_int (slist, 14);
49.430 + prog->findid = gmyth_string_list_get_int (slist, 15);
49.431 + prog->hostname = gmyth_string_list_get_string (slist, 16);
49.432 + prog->sourceid = gmyth_string_list_get_int (slist, 17);
49.433 + prog->cardid = gmyth_string_list_get_int (slist, 18);
49.434 + prog->inputid = gmyth_string_list_get_int (slist, 19);
49.435 + prog->recpriority = gmyth_string_list_get_int (slist, 20);
49.436 + prog->reactivate = gmyth_string_list_get_int (slist, 21);
49.437 + prog->recordid = gmyth_string_list_get_int (slist, 22);
49.438 + gmyth_string_list_get_int (slist, 23);
49.439 + gmyth_string_list_get_int (slist, 24);
49.440 + gmyth_string_list_get_int (slist, 25);
49.441 + prog->recstartts = gmyth_util_string_to_time_val( (gmyth_util_time_to_isoformat(
49.442 + (time_t)gmyth_string_list_get_int (slist, 26) ))->str ); //DATETIME_TO_LIST(recstartts)
49.443 + prog->recendts = gmyth_util_string_to_time_val( (gmyth_util_time_to_isoformat(
49.444 + (time_t)gmyth_string_list_get_int (slist, 27) ))->str ); //DATETIME_TO_LIST(recendts)
49.445 + prog->repeat = gmyth_string_list_get_int (slist, 28);
49.446 + prog->programflags = gmyth_string_list_get_int (slist, 29);
49.447 + prog->recgroup = gmyth_string_list_get_string (slist, 30); //prog->(recgroup != "") ? recgroup : "Default")
49.448 + prog->chancommfree = gmyth_string_list_get_int (slist, 31);
49.449 + prog->chanOutputFilters = gmyth_string_list_get_string (slist, 32);
49.450 + prog->seriesid = gmyth_string_list_get_string (slist, 33);
49.451 + prog->programid = gmyth_string_list_get_string (slist, 34);
49.452 + gmyth_string_list_get_string (slist, 35);
49.453 + prog->lastmodified = gmyth_util_string_to_time_val( (gmyth_util_time_to_isoformat(
49.454 + (time_t)gmyth_string_list_get_int (slist, 36) ))->str ); //DATETIME_TO_LIST(lastmodified)
49.455 + gmyth_string_list_get_int (slist, 37); //FLOAT_TO_LIST(stars)
49.456 + prog->originalAirDate = gmyth_util_string_to_time_val( (gmyth_util_time_to_isoformat(
49.457 + (time_t)gmyth_string_list_get_int (slist, 38) ))->str ); //DATETIME_TO_LIST(QDateTime(originalAirDate))
49.458 + prog->hasAirDate = gmyth_string_list_get_int (slist, 39);
49.459 + prog->playgroup = gmyth_string_list_get_string (slist, 40); //prog->(playgroup != "") ? playgroup : "Default")
49.460 + prog->recpriority2 = gmyth_string_list_get_int (slist, 41);
49.461 +
49.462 + return prog;
49.463 +}
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
50.2 +++ b/branches/gmyth-0.1b/src/gmyth_programinfo.h Thu Feb 01 18:42:01 2007 +0000
50.3 @@ -0,0 +1,161 @@
50.4 +/**
50.5 + * GMyth Library
50.6 + *
50.7 + * @file gmyth/gmyth_common.h
50.8 + *
50.9 + * @brief <p> This file contains basic common functions for the gmyth library.
50.10 + *
50.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
50.12 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
50.13 + *
50.14 + *//*
50.15 + *
50.16 + * This program is free software; you can redistribute it and/or modify
50.17 + * it under the terms of the GNU Lesser General Public License as published by
50.18 + * the Free Software Foundation; either version 2 of the License, or
50.19 + * (at your option) any later version.
50.20 + *
50.21 + * This program is distributed in the hope that it will be useful,
50.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
50.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50.24 + * GNU General Public License for more details.
50.25 + *
50.26 + * You should have received a copy of the GNU Lesser General Public License
50.27 + * along with this program; if not, write to the Free Software
50.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
50.29 + */
50.30 +
50.31 +#ifndef _GMYTH_PROGRAMINFO_H
50.32 +#define _GMYTH_PROGRAMINFO_H
50.33 +
50.34 +#include <glib.h>
50.35 +#include <glib-object.h>
50.36 +
50.37 +#include "gmyth_stringlist.h"
50.38 +
50.39 +G_BEGIN_DECLS
50.40 +
50.41 +#define GMYTH_PROGRAM_INFO_TYPE (gmyth_program_info_get_type ())
50.42 +#define GMYTH_PROGRAM_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_PROGRAM_INFO_TYPE, GMythProgramInfo))
50.43 +#define GMYTH_PROGRAM_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_PROGRAM_INFO_TYPE, GMythProgramInfoClass))
50.44 +#define IS_GMYTH_PROGRAM_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_PROGRAM_INFO_TYPE))
50.45 +#define IS_GMYTH_PROGRAM_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_PROGRAM_INFO_TYPE))
50.46 +#define GMYTH_PROGRAM_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_PROGRAM_INFO_TYPE, GMythProgramInfoClass))
50.47 +
50.48 +typedef struct _GMythProgramInfo GMythProgramInfo;
50.49 +typedef struct _GMythProgramInfoClass GMythProgramInfoClass;
50.50 +
50.51 +struct _GMythProgramInfoClass
50.52 +{
50.53 + GObjectClass parent_class;
50.54 +
50.55 + /* callbacks */
50.56 +};
50.57 +
50.58 +/**
50.59 + * The GMythProgramInfo structure represents a program information
50.60 + * stored in the database. It could be a program from the EPG data,
50.61 + * a program scheduled to be recorded, or a program already recorded.
50.62 + */
50.63 +struct _GMythProgramInfo
50.64 +{
50.65 + GObject parent;
50.66 +
50.67 + /** The channel unique ID. */
50.68 + GString *chanid;
50.69 +
50.70 + /** The program start time. */
50.71 + GTimeVal* startts;
50.72 + /** The program end time. */
50.73 + GTimeVal* endts;
50.74 + /** The recording schedule start time. */
50.75 + GTimeVal* recstartts;
50.76 + /** The recording schedule end time */
50.77 + GTimeVal* recendts;
50.78 +
50.79 + /** The program title. */
50.80 + GString *title;
50.81 + /** The program subtitle. */
50.82 + GString *subtitle;
50.83 + /** The program description. */
50.84 + GString *description;
50.85 + /** The program category. */
50.86 + GString *category;
50.87 +
50.88 + GString *chanstr;
50.89 + GString *chansign;
50.90 + /** The associated channel name. */
50.91 + GString *channame;
50.92 + gint chancommfree;
50.93 + GString *chanOutputFilters;
50.94 +
50.95 + GString *seriesid;
50.96 + /** The program unique id. */
50.97 + GString *programid;
50.98 + GString *catType;
50.99 +
50.100 + GString *sortTitle;
50.101 +
50.102 + /** A flag informing if the program has video or not. */
50.103 + gboolean isVideo;
50.104 + gint lenMins;
50.105 +
50.106 + GString *year;
50.107 + gdouble stars;
50.108 + gint repeat;
50.109 +
50.110 + GTimeVal* originalAirDate;
50.111 + GTimeVal* lastmodified;
50.112 + GTimeVal* lastInUseTime;
50.113 +
50.114 + gboolean hasAirDate;
50.115 +
50.116 + gint spread;
50.117 + gint startCol;
50.118 +
50.119 + gint recpriority2;
50.120 + gint reactivate;
50.121 +
50.122 + gint recordid;
50.123 + gint parentid;
50.124 +
50.125 + /** The backend video source id associated to this program.*/
50.126 + gint sourceid;
50.127 + /** the backend input id associated to this program.*/
50.128 + gint inputid;
50.129 + /** The backend card id associated to this program.*/
50.130 + gint cardid;
50.131 + gboolean shareable;
50.132 + gboolean duplicate;
50.133 +
50.134 + GString * schedulerid;
50.135 + gint findid;
50.136 +
50.137 + gint programflags;
50.138 + gint transcoder;
50.139 +
50.140 + GString *recgroup;
50.141 + GString *playgroup;
50.142 + gint recpriority;
50.143 +
50.144 + /** The file size of the recorded program.*/
50.145 + gint64 filesize;
50.146 +
50.147 + /** The file name of the recorded program.*/
50.148 + GString *pathname;
50.149 + GString *hostname;
50.150 +
50.151 + /* AvailableStatusType availableStatus;*/
50.152 +
50.153 +};
50.154 +
50.155 +GType gmyth_program_info_type (void);
50.156 +
50.157 +GMythProgramInfo* gmyth_program_info_new (void);
50.158 +
50.159 +GMythStringList* gmyth_program_info_to_string_list (GMythProgramInfo *prog, GMythStringList *slist);
50.160 +GMythProgramInfo* gmyth_program_info_from_string_list (GMythStringList *slist);
50.161 +
50.162 +G_END_DECLS
50.163 +
50.164 +#endif /*_GMYTH_PROGRAMINFO_H*/
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/branches/gmyth-0.1b/src/gmyth_query.c Thu Feb 01 18:42:01 2007 +0000
51.3 @@ -0,0 +1,239 @@
51.4 +/**
51.5 + * GMyth Library
51.6 + *
51.7 + * @file gmyth/gmyth_query.c
51.8 + *
51.9 + * @brief <p> GMythQuery class provides a wrapper for accessing
51.10 + * the libmysqlclient funtions.
51.11 + *
51.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
51.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
51.14 + *
51.15 + *//*
51.16 + *
51.17 + * This program is free software; you can redistribute it and/or modify
51.18 + * it under the terms of the GNU Lesser General Public License as published by
51.19 + * the Free Software Foundation; either version 2 of the License, or
51.20 + * (at your option) any later version.
51.21 + *
51.22 + * This program is distributed in the hope that it will be useful,
51.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
51.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51.25 + * GNU General Public License for more details.
51.26 + *
51.27 + * You should have received a copy of the GNU Lesser General Public License
51.28 + * along with this program; if not, write to the Free Software
51.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
51.30 + */
51.31 +
51.32 +#ifdef HAVE_CONFIG_H
51.33 +#include "config.h"
51.34 +#endif
51.35 +
51.36 +#include <stdlib.h>
51.37 +#include <stdio.h>
51.38 +#include <assert.h>
51.39 +
51.40 +#include "gmyth_query.h"
51.41 +#include "gmyth_debug.h"
51.42 +
51.43 +static void gmyth_query_class_init (GMythQueryClass *klass);
51.44 +static void gmyth_query_init (GMythQuery *object);
51.45 +
51.46 +static void gmyth_query_dispose (GObject *object);
51.47 +static void gmyth_query_finalize (GObject *object);
51.48 +
51.49 +static void gmyth_query_print_error (MYSQL *conn, char *message);
51.50 +
51.51 +G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT)
51.52 +
51.53 +static void
51.54 +gmyth_query_class_init (GMythQueryClass *klass)
51.55 +{
51.56 + GObjectClass *gobject_class;
51.57 +
51.58 + gobject_class = (GObjectClass *) klass;
51.59 +
51.60 + gobject_class->dispose = gmyth_query_dispose;
51.61 + gobject_class->finalize = gmyth_query_finalize;
51.62 +}
51.63 +
51.64 +static void
51.65 +gmyth_query_init (GMythQuery *gmyth_query)
51.66 +{
51.67 + gmyth_query->backend_info = NULL;
51.68 +
51.69 + /* initialize connection handler */
51.70 + gmyth_query->conn = mysql_init (NULL);
51.71 +
51.72 +
51.73 + if (!(gmyth_query->conn))
51.74 + g_warning ("[%s] MSQL structure not initialized", __FUNCTION__);
51.75 +
51.76 +}
51.77 +
51.78 +static void
51.79 +gmyth_query_dispose (GObject *object)
51.80 +{
51.81 + GMythQuery *gmyth_query = GMYTH_QUERY (object);
51.82 +
51.83 + if (gmyth_query->backend_info) {
51.84 + g_object_unref (gmyth_query->backend_info);
51.85 + //gmyth_query->backend_info = NULL;
51.86 + }
51.87 +
51.88 + G_OBJECT_CLASS (gmyth_query_parent_class)->dispose (object);
51.89 +}
51.90 +
51.91 +static void
51.92 +gmyth_query_finalize (GObject *object)
51.93 +{
51.94 + g_signal_handlers_destroy (object);
51.95 +
51.96 + G_OBJECT_CLASS (gmyth_query_parent_class)->finalize (object);
51.97 +}
51.98 +
51.99 +/** Creates a new instance of GMythQuery.
51.100 + *
51.101 + * @return a new instance of GMythQuery.
51.102 + */
51.103 +GMythQuery*
51.104 +gmyth_query_new ()
51.105 +{
51.106 + GMythQuery *sql_query = GMYTH_QUERY (g_object_new(GMYTH_QUERY_TYPE, NULL));
51.107 +
51.108 + return sql_query;
51.109 +}
51.110 +
51.111 +gboolean
51.112 +gmyth_query_connect_with_timeout (GMythQuery *gmyth_query,
51.113 + GMythBackendInfo *backend_info, guint timeout)
51.114 +{
51.115 + assert(gmyth_query);
51.116 + g_return_val_if_fail (gmyth_query->conn != NULL, FALSE);
51.117 + if (timeout != 0) {
51.118 + /* sets connection timeout */
51.119 + mysql_options (gmyth_query->conn, MYSQL_OPT_CONNECT_TIMEOUT, (gchar*) &timeout);
51.120 + }
51.121 +
51.122 + return gmyth_query_connect (gmyth_query, backend_info);
51.123 +}
51.124 +
51.125 +/** Connects to the Mysql database in the backend. The backend address
51.126 + * is loaded from the GMythBackendInfo instance.
51.127 + *
51.128 + * @param gmyth_query the GMythEPG instance to be connected.
51.129 + * @return true if connection was success, false if failed.
51.130 + */
51.131 +gboolean
51.132 +gmyth_query_connect (GMythQuery *gmyth_query, GMythBackendInfo *backend_info)
51.133 +{
51.134 + assert(gmyth_query);
51.135 + g_return_val_if_fail (backend_info != NULL, FALSE);
51.136 + g_return_val_if_fail (backend_info->hostname != NULL, FALSE);
51.137 + g_return_val_if_fail (backend_info->username != NULL, FALSE);
51.138 + g_return_val_if_fail (backend_info->password != NULL, FALSE);
51.139 + g_return_val_if_fail (backend_info->db_name != NULL, FALSE);
51.140 +
51.141 + g_object_ref (backend_info);
51.142 + gmyth_query->backend_info = backend_info;
51.143 +
51.144 + if (gmyth_query->conn == NULL) {
51.145 + gmyth_query_print_error (NULL, "mysql_init() failed (probably out of memory)");
51.146 + return FALSE;
51.147 + }
51.148 +
51.149 + /* connect to server */
51.150 + if (mysql_real_connect (gmyth_query->conn,
51.151 + gmyth_query->backend_info->hostname,
51.152 + gmyth_query->backend_info->username,
51.153 + gmyth_query->backend_info->password,
51.154 + gmyth_query->backend_info->db_name,
51.155 + 0, NULL, 0) == NULL) {
51.156 +
51.157 + gmyth_query_print_error (gmyth_query->conn, "mysql_real_connect() failed");
51.158 + return FALSE;
51.159 + }
51.160 +
51.161 + g_debug ("[%s] Connection to Mysql server succeeded! (host = %s, user = %s, "\
51.162 + "password = %s, db name = %s)", __FUNCTION__,
51.163 + gmyth_query->backend_info->hostname, gmyth_query->backend_info->username,
51.164 + gmyth_query->backend_info->password, gmyth_query->backend_info->db_name );
51.165 +
51.166 + return TRUE;
51.167 +}
51.168 +
51.169 +/** Disconnects from the Mysql database in the backend.
51.170 + *
51.171 + * @param gmyth_query the GMythQuery instance to be disconnected
51.172 + * @return true if disconnection was success, false if failed.
51.173 + */
51.174 +gboolean
51.175 +gmyth_query_disconnect (GMythQuery *gmyth_query)
51.176 +{
51.177 + assert(gmyth_query);
51.178 +
51.179 + /* TODO: Check how to return error */
51.180 + g_debug ("[%s] Closing gmyth_query->conn", __FUNCTION__);
51.181 + mysql_close (gmyth_query->conn);
51.182 +
51.183 + return TRUE;
51.184 +}
51.185 +
51.186 +static void
51.187 +gmyth_query_print_error (MYSQL *conn, char *message)
51.188 +{
51.189 + g_debug ("%s", message);
51.190 +
51.191 + if (conn != NULL) {
51.192 +#if MYSQL_VERSION_ID >= 40101
51.193 + g_debug ("Error %u (%s): %s\n",
51.194 + mysql_errno (conn), mysql_sqlstate(conn), mysql_error (conn));
51.195 +#else
51.196 + g_debug ("Error %u: %s\n",
51.197 + mysql_errno (conn), mysql_error (conn));
51.198 +#endif
51.199 + }
51.200 +}
51.201 +
51.202 +/** Sends the given query to the backend returning the query result as
51.203 + * MYSQL_RES pointer.
51.204 + *
51.205 + * FIXME: this function is returning NULL whether any error happens
51.206 + * or no rows are returned (e.g. UPDATE or REPLACE).
51.207 + *
51.208 + * @param gmyth_query the GMythQuery instance.
51.209 + * @param stmt_str the query text.
51.210 + * @return the MYSQL_RES result pointer or NULL if any error happens.
51.211 + */
51.212 +MYSQL_RES*
51.213 +gmyth_query_process_statement (GMythQuery *gmyth_query, char *stmt_str)
51.214 +{
51.215 + MYSQL_RES *res_set;
51.216 +
51.217 + assert(gmyth_query);
51.218 +
51.219 + g_debug ("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
51.220 +
51.221 + if (gmyth_query == NULL)
51.222 + return NULL;
51.223 +
51.224 + /* the statement failed */
51.225 + if (mysql_query (gmyth_query->conn, stmt_str) != 0) {
51.226 + gmyth_query_print_error (gmyth_query->conn, "Could not execute statement");
51.227 + return NULL;
51.228 + }
51.229 +
51.230 + /* the statement succeeded; determine whether it returned data */
51.231 + res_set = mysql_store_result (gmyth_query->conn);
51.232 + if (res_set) {
51.233 + return res_set;
51.234 + } else if (mysql_field_count (gmyth_query->conn) == 0) {
51.235 + g_debug ("%lu rows affected\n",
51.236 + (unsigned long) mysql_affected_rows (gmyth_query->conn));
51.237 + } else {
51.238 + gmyth_query_print_error (gmyth_query->conn, "Could not retrieve result set");
51.239 + }
51.240 +
51.241 + return NULL;
51.242 +}
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/branches/gmyth-0.1b/src/gmyth_query.h Thu Feb 01 18:42:01 2007 +0000
52.3 @@ -0,0 +1,86 @@
52.4 +/**
52.5 + * GMyth Library
52.6 + *
52.7 + * @file gmyth/gmyth_query.h
52.8 + *
52.9 + * @brief <p> GMythQuery class provides a wrapper for accessing
52.10 + * the libmysqlclient funtions.
52.11 + *
52.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
52.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
52.14 + *
52.15 + *//*
52.16 + *
52.17 + * This program is free software; you can redistribute it and/or modify
52.18 + * it under the terms of the GNU Lesser General Public License as published by
52.19 + * the Free Software Foundation; either version 2 of the License, or
52.20 + * (at your option) any later version.
52.21 + *
52.22 + * This program is distributed in the hope that it will be useful,
52.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
52.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52.25 + * GNU General Public License for more details.
52.26 + *
52.27 + * You should have received a copy of the GNU Lesser General Public License
52.28 + * along with this program; if not, write to the Free Software
52.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
52.30 + */
52.31 +
52.32 +#ifndef __GMYTH_QUERY_H__
52.33 +#define __GMYTH_QUERY_H__
52.34 +
52.35 +#include <glib-object.h>
52.36 +
52.37 +/* MYSQL includes */
52.38 +#include <mysql/mysql.h>
52.39 +
52.40 +#include "gmyth_backendinfo.h"
52.41 +
52.42 +G_BEGIN_DECLS
52.43 +
52.44 +#define GMYTH_QUERY_TYPE (gmyth_query_get_type ())
52.45 +#define GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE, GMythQuery))
52.46 +#define GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE, GMythQueryClass))
52.47 +#define IS_GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE))
52.48 +#define IS_GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE))
52.49 +#define GMYTH_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_QUERY_TYPE, GMythQueryClass))
52.50 +
52.51 +
52.52 +typedef struct _GMythQuery GMythQuery;
52.53 +typedef struct _GMythQueryClass GMythQueryClass;
52.54 +
52.55 +struct _GMythQueryClass
52.56 +{
52.57 + GObjectClass parent_class;
52.58 +
52.59 + /* callbacks */
52.60 + /* no one for now */
52.61 +};
52.62 +
52.63 +struct _GMythQuery
52.64 +{
52.65 + GObject parent;
52.66 +
52.67 + GMythBackendInfo *backend_info;
52.68 +
52.69 + GString *opt_socket_name; /* socket name (use built-in value) */
52.70 + unsigned int opt_flags; /* connection flags (none) */
52.71 +
52.72 + MYSQL *conn; /* pointer to connection handler */
52.73 +};
52.74 +
52.75 +
52.76 +GType gmyth_query_get_type (void);
52.77 +
52.78 +GMythQuery* gmyth_query_new ( );
52.79 +MYSQL_RES * gmyth_query_process_statement
52.80 + (GMythQuery *gmyth_query, gchar *stmt_str);
52.81 +
52.82 +gboolean gmyth_query_connect (GMythQuery *gmyth_query, GMythBackendInfo *backend_info);
52.83 +gboolean gmyth_query_connect_with_timeout (GMythQuery *gmyth_query,
52.84 + GMythBackendInfo *backend_info, guint timeout);
52.85 +gboolean gmyth_query_disconnect (GMythQuery *gmyth_query);
52.86 +
52.87 +G_END_DECLS
52.88 +
52.89 +#endif /* __GMYTH_QUERY_H__ */
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/branches/gmyth-0.1b/src/gmyth_recorder.c Thu Feb 01 18:42:01 2007 +0000
53.3 @@ -0,0 +1,654 @@
53.4 +/**
53.5 + * GMyth Library
53.6 + *
53.7 + * @file gmyth/gmyth_remote_encoder.c
53.8 + *
53.9 + * @brief <p> GMythRecorder class defines functions for playing live tv.
53.10 + *
53.11 + * The remote encoder is used by gmyth_tvplayer to setup livetv.
53.12 + *
53.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
53.14 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
53.15 + *
53.16 + *//*
53.17 + *
53.18 + * This program is free software; you can redistribute it and/or modify
53.19 + * it under the terms of the GNU Lesser General Public License as published by
53.20 + * the Free Software Foundation; either version 2 of the License, or
53.21 + * (at your option) any later version.
53.22 + *
53.23 + * This program is distributed in the hope that it will be useful,
53.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
53.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53.26 + * GNU General Public License for more details.
53.27 + *
53.28 + * You should have received a copy of the GNU Lesser General Public License
53.29 + * along with this program; if not, write to the Free Software
53.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
53.31 + */
53.32 +
53.33 +#ifdef HAVE_CONFIG_H
53.34 +#include "config.h"
53.35 +#endif
53.36 +
53.37 +#include "gmyth_recorder.h"
53.38 +
53.39 +#include <assert.h>
53.40 +
53.41 +#include "gmyth_stringlist.h"
53.42 +#include "gmyth_util.h"
53.43 +#include "gmyth_debug.h"
53.44 +
53.45 +#define GMYTHTV_RECORDER_HEADER "QUERY_RECORDER"
53.46 +
53.47 +static void gmyth_recorder_class_init (GMythRecorderClass *klass);
53.48 +static void gmyth_recorder_init (GMythRecorder *object);
53.49 +
53.50 +static void gmyth_recorder_dispose (GObject *object);
53.51 +static void gmyth_recorder_finalize (GObject *object);
53.52 +
53.53 +G_DEFINE_TYPE(GMythRecorder, gmyth_recorder, G_TYPE_OBJECT)
53.54 +
53.55 +static void
53.56 +gmyth_recorder_class_init (GMythRecorderClass *klass)
53.57 +{
53.58 + GObjectClass *gobject_class;
53.59 +
53.60 + gobject_class = (GObjectClass *) klass;
53.61 +
53.62 + gobject_class->dispose = gmyth_recorder_dispose;
53.63 + gobject_class->finalize = gmyth_recorder_finalize;
53.64 +}
53.65 +
53.66 +static void
53.67 +gmyth_recorder_init (GMythRecorder *gmyth_remote_encoder)
53.68 +{
53.69 +}
53.70 +
53.71 +static void
53.72 +gmyth_recorder_dispose (GObject *object)
53.73 +{
53.74 + // GMythRecorder *gmyth_remote_encoder = GMYTH_RECORDER(object);
53.75 +
53.76 + G_OBJECT_CLASS (gmyth_recorder_parent_class)->dispose (object);
53.77 +}
53.78 +
53.79 +
53.80 +static void
53.81 +gmyth_recorder_finalize (GObject *object)
53.82 +{
53.83 + g_signal_handlers_destroy (object);
53.84 +
53.85 + GMythRecorder *recorder = GMYTH_RECORDER(object);
53.86 +
53.87 + gmyth_debug ("[%s] Closing control socket", __FUNCTION__);
53.88 + gmyth_socket_close_connection(recorder->myth_socket);
53.89 + g_object_unref (recorder->myth_socket);
53.90 +
53.91 + G_OBJECT_CLASS (gmyth_recorder_parent_class)->finalize (object);
53.92 +}
53.93 +
53.94 +/** Creates a new instance of GMythRecorder.
53.95 + *
53.96 + * @return a new instance of GMythRecorder.
53.97 + */
53.98 +GMythRecorder*
53.99 +gmyth_recorder_new (int num, GString *hostname, gshort port)
53.100 +{
53.101 + GMythRecorder *encoder = GMYTH_RECORDER ( g_object_new (
53.102 + GMYTH_RECORDER_TYPE, FALSE ));
53.103 +
53.104 + encoder->recorder_num = num;
53.105 + encoder->hostname = g_string_new (hostname->str);
53.106 + encoder->port = port;
53.107 +
53.108 + return encoder;
53.109 +}
53.110 +
53.111 +/** Configures the remote encoder instance connecting it to Mythtv backend.
53.112 + *
53.113 + * @param recorder the GMythRecorder instance.
53.114 + * @return TRUE if successfull, FALSE if any error happens.
53.115 + */
53.116 +gboolean
53.117 +gmyth_recorder_setup (GMythRecorder *recorder)
53.118 +{
53.119 + assert (recorder);
53.120 + gmyth_debug ("[%s] Creating socket and connecting to backend", __FUNCTION__);
53.121 +
53.122 + if (recorder->myth_socket == NULL) {
53.123 +
53.124 + recorder->myth_socket = gmyth_socket_new ();
53.125 +
53.126 + if (!gmyth_socket_connect_to_backend ( recorder->myth_socket, recorder->hostname->str,
53.127 + recorder->port, TRUE ) ) {
53.128 + g_warning ("GMythRemoteEncoder: Connection to backend failed");
53.129 + return FALSE;
53.130 + }
53.131 +
53.132 + } else {
53.133 + g_warning("Remote encoder socket already created\n");
53.134 + }
53.135 +
53.136 + return TRUE;
53.137 +}
53.138 +
53.139 +/** Sends the SPAWN_LIVETV command through Mythtv protocol. This command
53.140 + * requests the backend to start capturing TV content.
53.141 + *
53.142 + * @param recorder The GMythRecorder instance.
53.143 + * @param tvchain_id The tvchain unique id.
53.144 + * @return true if success, false if any error happens.
53.145 + */
53.146 +gboolean
53.147 +gmyth_recorder_spawntv (GMythRecorder *recorder, GString *tvchain_id)
53.148 +{
53.149 + GMythStringList *str_list;
53.150 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.151 +
53.152 + gmyth_debug ("[%s] Spawntv with tvchain_id = %s", __FUNCTION__, tvchain_id->str);
53.153 +
53.154 + str_list = gmyth_string_list_new ();
53.155 +
53.156 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.157 +
53.158 + gmyth_string_list_append_string (str_list, tmp_str);
53.159 + gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
53.160 + gmyth_string_list_append_string (str_list, tvchain_id);
53.161 + gmyth_string_list_append_int (str_list, 0); // PIP = FALSE (0)
53.162 +
53.163 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.164 +
53.165 + g_string_free (tmp_str, TRUE);
53.166 +
53.167 + tmp_str = gmyth_string_list_get_string (str_list, 0);
53.168 + if (tmp_str == NULL) {
53.169 + g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
53.170 + return FALSE;
53.171 + }
53.172 +
53.173 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
53.174 + g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
53.175 + g_object_unref (str_list);
53.176 + return FALSE;
53.177 + }
53.178 +
53.179 + g_object_unref (str_list);
53.180 + return TRUE;
53.181 +
53.182 +}
53.183 +
53.184 +/**
53.185 + * Sends the SPAWN_LIVETV command through Mythtv protocol. This command
53.186 + * requests the backend to start capturing TV content, but it doesn't need
53.187 + * the TV chain ID.
53.188 + *
53.189 + * @param recorder The GMythRecorder instance.
53.190 + * @return true if success, false if any error happens.
53.191 + */
53.192 +gboolean
53.193 +gmyth_recorder_spawntv_no_tvchain (GMythRecorder *recorder)
53.194 +{
53.195 + GMythStringList *str_list;
53.196 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.197 +
53.198 + gmyth_debug ("[%s] Spawntv, no TV chain!", __FUNCTION__);
53.199 +
53.200 + str_list = gmyth_string_list_new ();
53.201 +
53.202 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.203 +
53.204 + gmyth_string_list_append_string (str_list, tmp_str);
53.205 + gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
53.206 +
53.207 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.208 +
53.209 + g_string_free (tmp_str, TRUE);
53.210 +
53.211 + tmp_str = gmyth_string_list_get_string (str_list, 0);
53.212 + if (tmp_str == NULL) {
53.213 + g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
53.214 + return FALSE;
53.215 + }
53.216 +
53.217 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
53.218 + g_warning ("[%s] Spawntv request returned %s", __FUNCTION__, tmp_str->str);
53.219 + g_object_unref (str_list);
53.220 + return FALSE;
53.221 + }
53.222 +
53.223 + g_object_unref (str_list);
53.224 + return TRUE;
53.225 +
53.226 +}
53.227 +
53.228 +/** Sends the command STOP_LIVETV to Mythtv backend.
53.229 + *
53.230 + * @param recorder the GMythRecorder instance.
53.231 + * @return true if success, false if any error happens.
53.232 + */
53.233 +gboolean
53.234 +gmyth_recorder_stop_livetv (GMythRecorder *recorder)
53.235 +{
53.236 + GMythStringList *str_list;
53.237 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.238 +
53.239 + gmyth_debug ("[%s]", __FUNCTION__);
53.240 +
53.241 + str_list = gmyth_string_list_new ();
53.242 +
53.243 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.244 + gmyth_string_list_append_char_array( str_list, "STOP_LIVETV" );
53.245 +
53.246 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.247 +
53.248 + g_string_free (tmp_str, TRUE);
53.249 +
53.250 + tmp_str = gmyth_string_list_get_string (str_list, 0);
53.251 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
53.252 + g_warning ("[%s] Stop livetv request returned %s", __FUNCTION__, tmp_str->str);
53.253 + g_object_unref (str_list);
53.254 + return FALSE;
53.255 + }
53.256 +
53.257 + g_object_unref (str_list);
53.258 + return TRUE;
53.259 +
53.260 +}
53.261 +
53.262 +/** Sends the FRONTEND_READY command through Mythtv protocol. This command
53.263 + * advertises the backend to start capturing TV content.
53.264 + *
53.265 + * @param recorder The GMythRecorder instance.
53.266 + * @return TRUE if success, FALSE if any error happens.
53.267 + */
53.268 +gboolean
53.269 +gmyth_recorder_send_frontend_ready_command (GMythRecorder *recorder)
53.270 +{
53.271 + GMythStringList *str_list;
53.272 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.273 +
53.274 + gmyth_debug ( "[%s] FRONTEND_READY with recorder id = %d", __FUNCTION__, recorder->recorder_num );
53.275 +
53.276 + str_list = gmyth_string_list_new ();
53.277 +
53.278 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.279 +
53.280 + gmyth_string_list_append_string (str_list, tmp_str);
53.281 + gmyth_string_list_append_string (str_list, g_string_new ("FRONTEND_READY"));
53.282 +
53.283 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.284 +
53.285 + g_string_free (tmp_str, TRUE);
53.286 +
53.287 + tmp_str = gmyth_string_list_get_string (str_list, 0);
53.288 + if (tmp_str == NULL) {
53.289 + g_warning ("[%s] FRONTEND_READY command request couldn't returns, reason: %s", __FUNCTION__, tmp_str->str);
53.290 + return FALSE;
53.291 + }
53.292 +
53.293 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
53.294 + g_warning ("[%s] FRONTEND_READY request returned %s", __FUNCTION__, tmp_str->str);
53.295 + g_object_unref (str_list);
53.296 + return FALSE;
53.297 + }
53.298 +
53.299 + g_object_unref (str_list);
53.300 + return TRUE;
53.301 +
53.302 +}
53.303 +
53.304 +/** Send a CHECK_CHANNEL command request to the backend, in order to find if a
53.305 + * certain channel actually exists.
53.306 + *
53.307 + * @param recorder The GMythRecorder instance.
53.308 + * @param channel The new channel to be checked (string format).
53.309 + * @return true if success, false if any error happens.
53.310 + */
53.311 +gboolean
53.312 +gmyth_recorder_check_channel_name (GMythRecorder *recorder, gchar* channel)
53.313 +{
53.314 + GMythStringList *str_list;
53.315 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.316 +
53.317 + gmyth_debug ("[%s] CHECK_CHANNEL with channel = %s", __FUNCTION__, channel);
53.318 +
53.319 + str_list = gmyth_string_list_new ();
53.320 +
53.321 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.322 +
53.323 + gmyth_string_list_append_string (str_list, tmp_str);
53.324 + gmyth_string_list_append_string (str_list, g_string_new ("CHECK_CHANNEL"));
53.325 + gmyth_string_list_append_char_array (str_list, channel);
53.326 +
53.327 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.328 +
53.329 + g_string_free (tmp_str, TRUE);
53.330 +
53.331 + tmp_str = gmyth_string_list_get_string (str_list, 0);
53.332 + if (tmp_str == NULL) {
53.333 + g_warning ("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__, tmp_str->str);
53.334 + return FALSE;
53.335 + }
53.336 +
53.337 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2) == 0 || g_ascii_strncasecmp (tmp_str->str, "0", 1) == 0 ) {
53.338 + g_warning ("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__, tmp_str->str);
53.339 + g_object_unref (str_list);
53.340 + return FALSE;
53.341 + }
53.342 +
53.343 + g_object_unref (str_list);
53.344 + return TRUE;
53.345 +
53.346 +}
53.347 +
53.348 +/** Send a CHECK_CHANNEL command request to the backend, in order to find if a
53.349 + * certain channel actually exists.
53.350 + *
53.351 + * @param recorder The GMythRecorder instance.
53.352 + * @param channel The new channel to be checked (decimal integer value).
53.353 + * @return true if success, false if any error happens.
53.354 + */
53.355 +gboolean
53.356 +gmyth_recorder_check_channel (GMythRecorder *recorder, gint channel)
53.357 +{
53.358 + return gmyth_recorder_check_channel_name( recorder, g_strdup_printf( "%d", channel ) );
53.359 +}
53.360 +
53.361 +/** Send a SET_CHANNEL command request to the backend, to start streaming on another
53.362 + * TV content channel.
53.363 + *
53.364 + * @param recorder The GMythRecorder instance.
53.365 + * @param channel The new channel to be loaded.
53.366 + * @return true if success, false if any error happens.
53.367 + */
53.368 +gboolean
53.369 +gmyth_recorder_set_channel (GMythRecorder *recorder, gint channel)
53.370 +{
53.371 + GMythStringList *str_list;
53.372 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.373 +
53.374 + gmyth_debug ("[%s] SET_CHANNEL with channel = %d", __FUNCTION__, channel);
53.375 +
53.376 + str_list = gmyth_string_list_new ();
53.377 +
53.378 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.379 +
53.380 + gmyth_string_list_append_string (str_list, tmp_str);
53.381 + gmyth_string_list_append_string (str_list, g_string_new ("SET_CHANNEL"));
53.382 + gmyth_string_list_append_int (str_list, channel);
53.383 +
53.384 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.385 +
53.386 + g_string_free (tmp_str, TRUE);
53.387 +
53.388 + tmp_str = gmyth_string_list_get_string (str_list, 0);
53.389 + if (tmp_str == NULL) {
53.390 + g_warning ("[%s] SET_CHANNEL request returned %s", __FUNCTION__, tmp_str->str);
53.391 + return FALSE;
53.392 + }
53.393 +
53.394 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
53.395 + g_warning ("[%s] SET_CHANNEL request returned %s", __FUNCTION__, tmp_str->str);
53.396 + g_object_unref (str_list);
53.397 + return FALSE;
53.398 + }
53.399 +
53.400 + g_object_unref (str_list);
53.401 + return TRUE;
53.402 +
53.403 +}
53.404 +
53.405 +/** Send a SET_CHANNEL command request to the backend, to start streaming on another
53.406 + * TV content channel.
53.407 + *
53.408 + * @param recorder The GMythRecorder instance.
53.409 + * @param channel The new channel to be loaded.
53.410 + * @return true if success, false if any error happens.
53.411 + */
53.412 +gboolean
53.413 +gmyth_recorder_set_channel_name (GMythRecorder *recorder, const gchar* channel)
53.414 +{
53.415 + GMythStringList *str_list;
53.416 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.417 +
53.418 + gmyth_debug ("[%s] SET_CHANNEL with channel name = %s", __FUNCTION__, channel);
53.419 +
53.420 + str_list = gmyth_string_list_new ();
53.421 +
53.422 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.423 +
53.424 + gmyth_string_list_append_string (str_list, tmp_str);
53.425 + gmyth_string_list_append_string (str_list, g_string_new ("SET_CHANNEL"));
53.426 + gmyth_string_list_append_char_array (str_list, channel);
53.427 +
53.428 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.429 +
53.430 + g_string_free (tmp_str, TRUE);
53.431 +
53.432 + tmp_str = gmyth_string_list_get_string (str_list, 0);
53.433 + if (tmp_str == NULL) {
53.434 + g_warning ("[%s] SET_CHANNEL name request returned %s", __FUNCTION__, tmp_str->str );
53.435 + return FALSE;
53.436 + }
53.437 +
53.438 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2) || g_ascii_strtoull( tmp_str->str, NULL, 10 ) == 0 ) {
53.439 + g_warning ("[%s] SET_CHANNEL name request returned %s", __FUNCTION__, tmp_str->str);
53.440 + g_object_unref (str_list);
53.441 + return FALSE;
53.442 + }
53.443 +
53.444 + g_object_unref (str_list);
53.445 + return TRUE;
53.446 +
53.447 +}
53.448 +
53.449 +/**
53.450 + * Changes the channel of the actual Recorder.
53.451 + *
53.452 + * CHANNEL_DIRECTION_UP - Go up one channel in the listing
53.453 + *
53.454 + * CHANNEL_DIRECTION_DOWN - Go down one channel in the listing
53.455 + *
53.456 + * CHANNEL_DIRECTION_FAVORITE - Go to the next favorite channel
53.457 + *
53.458 + * CHANNEL_DIRECTION_SAME - Stay
53.459 + *
53.460 + * @param recorder The GMythRecorder instance.
53.461 + * @param direction The new channel direction where to move to.
53.462 + * @return true if success, false if any error happens.
53.463 + */
53.464 +gboolean
53.465 +gmyth_recorder_change_channel (GMythRecorder *recorder, const GMythRecorderChannelChangeDirection direction)
53.466 +{
53.467 + GMythStringList *str_list;
53.468 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.469 +
53.470 + gmyth_debug ("[%s] CHANGE_CHANNEL to the channel direction = %u", __FUNCTION__, direction);
53.471 +
53.472 + str_list = gmyth_string_list_new ();
53.473 +
53.474 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.475 +
53.476 + gmyth_string_list_append_string (str_list, tmp_str);
53.477 + gmyth_string_list_append_string (str_list, g_string_new ("CHANGE_CHANNEL"));
53.478 + gmyth_string_list_append_int (str_list, direction);
53.479 +
53.480 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.481 +
53.482 + g_string_free (tmp_str, TRUE);
53.483 +
53.484 + tmp_str = gmyth_string_list_get_string (str_list, 0);
53.485 + if (tmp_str == NULL) {
53.486 + g_warning ("[%s] CHANGE_CHANNEL name request returned %s", __FUNCTION__, tmp_str->str );
53.487 + return FALSE;
53.488 + }
53.489 +
53.490 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2) || g_ascii_strtoull( tmp_str->str, NULL, 10 ) == 0 ) {
53.491 + g_warning ("[%s] CHANGE_CHANNEL name request returned %s", __FUNCTION__, tmp_str->str);
53.492 + g_object_unref (str_list);
53.493 + return FALSE;
53.494 + }
53.495 +
53.496 + g_object_unref (str_list);
53.497 + return TRUE;
53.498 +
53.499 +}
53.500 +
53.501 +/** Send a PAUSE command request to the backend, to pause streaming on another
53.502 + * TV content channel.
53.503 + *
53.504 + * @param recorder The GMythRecorder instance.
53.505 + * @return true if success, false if any error happens.
53.506 + */
53.507 +gboolean
53.508 +gmyth_recorder_pause_recording ( GMythRecorder *recorder )
53.509 +{
53.510 + GMythStringList *str_list;
53.511 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.512 +
53.513 + gmyth_debug ("[%s] PAUSE", __FUNCTION__);
53.514 +
53.515 + str_list = gmyth_string_list_new ();
53.516 +
53.517 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.518 +
53.519 + gmyth_string_list_append_string (str_list, tmp_str);
53.520 + gmyth_string_list_append_string (str_list, g_string_new ("PAUSE"));
53.521 +
53.522 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.523 +
53.524 + g_string_free (tmp_str, TRUE);
53.525 +
53.526 + tmp_str = gmyth_string_list_get_string (str_list, 0);
53.527 + if (tmp_str == NULL) {
53.528 + g_warning ("[%s] PAUSE name request returned %s", __FUNCTION__, tmp_str->str);
53.529 + return FALSE;
53.530 + }
53.531 +
53.532 + if (g_ascii_strncasecmp (tmp_str->str, "ok", 2)) {
53.533 + g_warning ("[%s] PAUSE name request returned %s", __FUNCTION__, tmp_str->str);
53.534 + g_object_unref (str_list);
53.535 + return FALSE;
53.536 + }
53.537 +
53.538 + g_object_unref (str_list);
53.539 + return TRUE;
53.540 +
53.541 +}
53.542 +
53.543 +/**
53.544 + * Requests the actual program info from the MythTV backend server.
53.545 + *
53.546 + * @param recorder The GMythRecorder instance.
53.547 + * @return The actual program info.
53.548 + */
53.549 +GMythProgramInfo *
53.550 +gmyth_recorder_get_current_program_info ( GMythRecorder *recorder )
53.551 +{
53.552 + GMythStringList *str_list;
53.553 + GMythProgramInfo *program_info = gmyth_program_info_new();
53.554 + GString *tmp_str = g_string_new( GMYTHTV_RECORDER_HEADER );
53.555 +
53.556 + str_list = gmyth_string_list_new ();
53.557 +
53.558 + g_string_append_printf ( tmp_str, " %d", recorder->recorder_num );
53.559 +
53.560 + gmyth_string_list_append_string (str_list, tmp_str);
53.561 +
53.562 + if ( recorder->myth_socket->mythtv_version >= 26 )
53.563 + gmyth_string_list_append_string (str_list, g_string_new ("GET_CURRENT_RECORDING"));
53.564 + else
53.565 + gmyth_string_list_append_string (str_list, g_string_new ("GET_PROGRAM_INFO"));
53.566 +
53.567 + gmyth_socket_sendreceive_stringlist (recorder->myth_socket, str_list);
53.568 +
53.569 + g_string_free (tmp_str, TRUE);
53.570 +
53.571 + if (str_list == NULL) {
53.572 + g_warning ("[%s] GET_PROGRAM_INFO request returned. Error getting program info, string list equals to NULL!", __FUNCTION__);
53.573 + return FALSE;
53.574 + }
53.575 +
53.576 + program_info = gmyth_program_info_from_string_list( str_list );
53.577 +
53.578 + if ( NULL == program_info ) {
53.579 + g_warning ("[%s] GET_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!", __FUNCTION__);
53.580 + g_object_unref (program_info);
53.581 + return NULL;
53.582 + }
53.583 +
53.584 + g_object_unref (str_list);
53.585 + return program_info;
53.586 +
53.587 +}
53.588 +
53.589 +gint64
53.590 +gmyth_recorder_get_file_position ( GMythRecorder *recorder )
53.591 +{
53.592 + gint64 pos = 0;
53.593 + GString *query = g_string_new( GMYTHTV_RECORDER_HEADER );
53.594 +
53.595 + GMythStringList *str_list = gmyth_string_list_new ();
53.596 +
53.597 + g_string_append_printf( query, " %d", recorder->recorder_num );
53.598 +
53.599 + gmyth_string_list_append_string (str_list, query);
53.600 + gmyth_string_list_append_char_array( str_list, "GET_FILE_POSITION" );
53.601 +
53.602 + gmyth_socket_sendreceive_stringlist ( recorder->myth_socket, str_list );
53.603 +
53.604 + if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 )
53.605 + {
53.606 + GString *str = NULL;
53.607 + if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strstr ( str->str, "bad" ) == NULL )
53.608 + pos = gmyth_util_decode_long_long( str_list, 0 );
53.609 + }
53.610 +
53.611 +#ifndef GMYTHTV_ENABLE_DEBUG
53.612 + g_print( "[%s] Got file position = %lld\n", __FUNCTION__, pos );
53.613 +#endif
53.614 + if (str_list!=NULL)
53.615 + g_object_unref (str_list);
53.616 +
53.617 + return pos;
53.618 +
53.619 +}
53.620 +
53.621 +gboolean
53.622 +gmyth_recorder_is_recording ( GMythRecorder *recorder )
53.623 +{
53.624 + gboolean ret = TRUE;
53.625 +
53.626 + g_return_val_if_fail( recorder != NULL, FALSE );
53.627 +
53.628 + GMythStringList *str_list = gmyth_string_list_new ();
53.629 + GString *message = g_string_new ("");
53.630 +
53.631 + g_string_printf( message, "%s %d", GMYTHTV_RECORDER_HEADER, recorder->recorder_num);
53.632 + gmyth_string_list_append_string (str_list, message);
53.633 + gmyth_string_list_append_string (str_list, g_string_new ("IS_RECORDING"));
53.634 +
53.635 + gmyth_socket_sendreceive_stringlist ( recorder->myth_socket, str_list );
53.636 +
53.637 + if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 )
53.638 + {
53.639 + GString *str = NULL;
53.640 + if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strcmp( str->str, "bad" )!= 0 )
53.641 + {
53.642 + gint is_rec = gmyth_string_list_get_int( str_list, 0 );
53.643 + if ( is_rec != 0 )
53.644 + ret = TRUE;
53.645 + else
53.646 + ret = FALSE;
53.647 + }
53.648 + }
53.649 + gmyth_debug( "%s, stream is %s being recorded!\n", ret ? "YES" : "NO", ret ? "" : "NOT" );
53.650 + //g_static_mutex_unlock (&mutex);
53.651 +
53.652 + if ( str_list != NULL )
53.653 + g_object_unref (str_list);
53.654 +
53.655 + return ret;
53.656 +
53.657 +}
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54.2 +++ b/branches/gmyth-0.1b/src/gmyth_recorder.h Thu Feb 01 18:42:01 2007 +0000
54.3 @@ -0,0 +1,122 @@
54.4 +/**
54.5 + * GMyth Library
54.6 + *
54.7 + * @file gmyth/gmyth_recorder.h
54.8 + *
54.9 + * @brief <p> GMythRecorder class defines functions for playing live tv.
54.10 + *
54.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
54.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
54.13 + *
54.14 + *//*
54.15 + *
54.16 + * This program is free software; you can redistribute it and/or modify
54.17 + * it under the terms of the GNU Lesser General Public License as published by
54.18 + * the Free Software Foundation; either version 2 of the License, or
54.19 + * (at your option) any later version.
54.20 + *
54.21 + * This program is distributed in the hope that it will be useful,
54.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
54.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54.24 + * GNU General Public License for more details.
54.25 + *
54.26 + * You should have received a copy of the GNU Lesser General Public License
54.27 + * along with this program; if not, write to the Free Software
54.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
54.29 + */
54.30 +
54.31 +#ifndef __GMYTH_RECORDER_H__
54.32 +#define __GMYTH_RECORDER_H__
54.33 +
54.34 +#include <glib-object.h>
54.35 +
54.36 +#include "gmyth_socket.h"
54.37 +#include "gmyth_programinfo.h"
54.38 +
54.39 +#include <stdio.h>
54.40 +#include <stdlib.h>
54.41 +#include <string.h>
54.42 +#include <netdb.h>
54.43 +#include <sys/socket.h>
54.44 +#include <unistd.h>
54.45 +
54.46 +G_BEGIN_DECLS
54.47 +
54.48 +#define GMYTH_RECORDER_TYPE (gmyth_recorder_get_type ())
54.49 +#define GMYTH_RECORDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_RECORDER_TYPE, GMythRecorder))
54.50 +#define GMYTH_RECORDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECORDER_TYPE, GMythRecorderClass))
54.51 +#define IS_GMYTH_RECORDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_RECORDER_TYPE))
54.52 +#define IS_GMYTH_RECORDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECORDER_TYPE))
54.53 +#define GMYTH_RECORDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_RECORDER_TYPE, GMythRecorderClass))
54.54 +
54.55 +
54.56 +typedef struct _GMythRecorder GMythRecorder;
54.57 +typedef struct _GMythRecorderClass GMythRecorderClass;
54.58 +
54.59 +struct _GMythRecorderClass
54.60 +{
54.61 + GObjectClass parent_class;
54.62 +
54.63 + /* callbacks */
54.64 + /* no one for now */
54.65 +};
54.66 +
54.67 +struct _GMythRecorder
54.68 +{
54.69 + GObject parent;
54.70 +
54.71 + /* socket descriptor */
54.72 + GMythSocket *myth_socket;
54.73 +
54.74 + gint recorder_num;
54.75 + GString *hostname;
54.76 + gint port;
54.77 +};
54.78 +
54.79 +typedef enum _GMythRecorderChannelChangeDirection {
54.80 + CHANNEL_DIRECTION_UP = 0,
54.81 + CHANNEL_DIRECTION_DOWN,
54.82 + CHANNEL_DIRECTION_FAVORITE,
54.83 + CHANNEL_DIRECTION_SAME
54.84 +} GMythRecorderChannelChangeDirection;
54.85 +
54.86 +GType gmyth_recorder_get_type (void);
54.87 +
54.88 +GMythRecorder* gmyth_recorder_new (int num,
54.89 + GString *hostname,
54.90 + gshort port);
54.91 +
54.92 +gboolean gmyth_recorder_setup (GMythRecorder *recorder);
54.93 +gboolean gmyth_recorder_spawntv (GMythRecorder *recorder,
54.94 + GString *tvchain_id);
54.95 +
54.96 +gboolean gmyth_recorder_spawntv_no_tvchain (GMythRecorder *recorder);
54.97 +
54.98 +gboolean gmyth_recorder_stop_livetv (GMythRecorder *recorder);
54.99 +
54.100 +gboolean gmyth_recorder_send_frontend_ready_command (GMythRecorder *recorder);
54.101 +
54.102 +gboolean gmyth_recorder_check_channel (GMythRecorder *recorder, gint channel);
54.103 +
54.104 +gboolean gmyth_recorder_check_channel_name (GMythRecorder *recorder, gchar* channel);
54.105 +
54.106 +gboolean gmyth_recorder_set_channel (GMythRecorder *recorder,
54.107 + gint channel);
54.108 +
54.109 +gboolean gmyth_recorder_set_channel_name (GMythRecorder *recorder,
54.110 + const gchar* channel);
54.111 +
54.112 +gboolean gmyth_recorder_change_channel (GMythRecorder *recorder,
54.113 + const GMythRecorderChannelChangeDirection direction);
54.114 +
54.115 +gboolean gmyth_recorder_pause_recording ( GMythRecorder *recorder );
54.116 +
54.117 +GMythProgramInfo *gmyth_recorder_get_current_program_info ( GMythRecorder *recorder );
54.118 +
54.119 +gint64 gmyth_recorder_get_file_position ( GMythRecorder *recorder );
54.120 +
54.121 +gboolean gmyth_recorder_is_recording ( GMythRecorder *recorder );
54.122 +
54.123 +G_END_DECLS
54.124 +
54.125 +#endif /* __GMYTH_REMOTE_ENCODER_H__ */
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/branches/gmyth-0.1b/src/gmyth_remote_util.c Thu Feb 01 18:42:01 2007 +0000
55.3 @@ -0,0 +1,79 @@
55.4 +/**
55.5 + * GMyth Library
55.6 + *
55.7 + * @file gmyth/gmyth_remote_util.c
55.8 + *
55.9 + * @brief <p> This component provides utility functions for accessing remote data.
55.10 + *
55.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
55.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
55.13 + *
55.14 + *//*
55.15 + *
55.16 + * This program is free software; you can redistribute it and/or modify
55.17 + * it under the terms of the GNU Lesser General Public License as published by
55.18 + * the Free Software Foundation; either version 2 of the License, or
55.19 + * (at your option) any later version.
55.20 + *
55.21 + * This program is distributed in the hope that it will be useful,
55.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
55.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55.24 + * GNU General Public License for more details.
55.25 + *
55.26 + * You should have received a copy of the GNU Lesser General Public License
55.27 + * along with this program; if not, write to the Free Software
55.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
55.29 + */
55.30 +
55.31 +#ifdef HAVE_CONFIG_H
55.32 +#include "config.h"
55.33 +#endif
55.34 +
55.35 +#include "gmyth_remote_util.h"
55.36 +
55.37 +#include "gmyth_recorder.h"
55.38 +#include "gmyth_stringlist.h"
55.39 +#include "gmyth_debug.h"
55.40 +
55.41 +/** Requests the Mythtv backend for a free remote recorder.
55.42 + *
55.43 + * @param curr The recorder index, or -1 to consider the first one.
55.44 + * @return the remote encoder instance available, or NULL if any error happens.
55.45 + */
55.46 +GMythRecorder*
55.47 +remote_request_next_free_recorder (GMythSocket *socket, int curr)
55.48 +{
55.49 + GMythRecorder *recorder = NULL;
55.50 + GString *hostname;
55.51 + int num, port;
55.52 +
55.53 + GMythStringList *strlist = gmyth_string_list_new();
55.54 +
55.55 + gmyth_debug ("[%s] Request next free recorder in the backend", __FUNCTION__);
55.56 +
55.57 + gmyth_string_list_append_char_array (strlist, "GET_NEXT_FREE_RECORDER");
55.58 + gmyth_string_list_append_int (strlist, curr);
55.59 +
55.60 + if (!gmyth_socket_sendreceive_stringlist(socket, strlist)) {
55.61 + g_warning ("GET_NEXT_FREE_RECORDER request error!\n");
55.62 + return NULL;
55.63 + }
55.64 +
55.65 + num = gmyth_string_list_get_int (strlist, 0);
55.66 + hostname = gmyth_string_list_get_string (strlist, 1);
55.67 + port = gmyth_string_list_get_int (strlist, 2);
55.68 +
55.69 + if ( num < 0 || port < 0 )
55.70 + goto clean_up;
55.71 +
55.72 + gmyth_debug ("[%s] Free recorder info received: num: %d, hostname: %s, port: %d",
55.73 + __FUNCTION__, num, hostname->str, port);
55.74 +
55.75 + recorder = gmyth_recorder_new (num, hostname, port);
55.76 +
55.77 +clean_up:
55.78 +
55.79 + g_object_unref (strlist);
55.80 +
55.81 + return recorder;
55.82 +}
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
56.2 +++ b/branches/gmyth-0.1b/src/gmyth_remote_util.h Thu Feb 01 18:42:01 2007 +0000
56.3 @@ -0,0 +1,41 @@
56.4 +/**
56.5 + * GMyth Library
56.6 + *
56.7 + * @file gmyth/gmyth_remote_util.h
56.8 + *
56.9 + * @brief <p> This component provides utility functions for accessing remote data.
56.10 + *
56.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
56.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
56.13 + *
56.14 + *//*
56.15 + *
56.16 + * This program is free software; you can redistribute it and/or modify
56.17 + * it under the terms of the GNU Lesser General Public License as published by
56.18 + * the Free Software Foundation; either version 2 of the License, or
56.19 + * (at your option) any later version.
56.20 + *
56.21 + * This program is distributed in the hope that it will be useful,
56.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
56.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56.24 + * GNU General Public License for more details.
56.25 + *
56.26 + * You should have received a copy of the GNU Lesser General Public License
56.27 + * along with this program; if not, write to the Free Software
56.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
56.29 + */
56.30 +
56.31 +#ifndef __REMOTE_UTIL_H__
56.32 +#define __REMOTE_UTIL_H__
56.33 +
56.34 +#include <glib.h>
56.35 +#include "gmyth_recorder.h"
56.36 +#include "gmyth_socket.h"
56.37 +
56.38 +G_BEGIN_DECLS
56.39 +
56.40 +GMythRecorder* remote_request_next_free_recorder (GMythSocket *socket, int curr);
56.41 +
56.42 +G_END_DECLS
56.43 +
56.44 +#endif
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
57.2 +++ b/branches/gmyth-0.1b/src/gmyth_scheduler.c Thu Feb 01 18:42:01 2007 +0000
57.3 @@ -0,0 +1,667 @@
57.4 +/**
57.5 + * GMyth Library
57.6 + *
57.7 + * @file gmyth/gmyth_scheduler.c
57.8 + *
57.9 + * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
57.10 + * and modifying the recorded content.
57.11 + *
57.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
57.13 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@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 +#ifdef HAVE_CONFIG_H
57.33 +#include "config.h"
57.34 +#endif
57.35 +
57.36 +#include <assert.h>
57.37 +
57.38 +#include <glib/gprintf.h>
57.39 +
57.40 +#include "gmyth_scheduler.h"
57.41 +#include "gmyth_util.h"
57.42 +#include "gmyth_query.h"
57.43 +#include "gmyth_socket.h"
57.44 +#include "gmyth_debug.h"
57.45 +
57.46 +static void gmyth_scheduler_class_init (GMythSchedulerClass *klass);
57.47 +static void gmyth_scheduler_init (GMythScheduler *object);
57.48 +
57.49 +static void gmyth_scheduler_dispose (GObject *object);
57.50 +static void gmyth_scheduler_finalize (GObject *object);
57.51 +
57.52 +static gint get_record_id_from_database (GMythScheduler *scheduler);
57.53 +static void update_backend (GMythScheduler *scheduler, gint record_id);
57.54 +
57.55 +G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
57.56 +
57.57 +static void
57.58 +gmyth_scheduler_class_init (GMythSchedulerClass *klass)
57.59 +{
57.60 + GObjectClass *gobject_class;
57.61 +
57.62 + gobject_class = (GObjectClass *) klass;
57.63 +
57.64 + gobject_class->dispose = gmyth_scheduler_dispose;
57.65 + gobject_class->finalize = gmyth_scheduler_finalize;
57.66 +}
57.67 +
57.68 +static void
57.69 +gmyth_scheduler_init (GMythScheduler *sched)
57.70 +{
57.71 + sched->recordid =0;
57.72 + sched->type = 0;
57.73 + sched->search = 0;
57.74 + sched->profile = g_string_new("");
57.75 +
57.76 + sched->dupin = 0;
57.77 + sched->dupmethod = 0;
57.78 + sched->autoexpire = 0;
57.79 + sched->autotranscode = 0;
57.80 + sched->transcoder = 0;
57.81 +
57.82 + sched->autocommflag = 0;
57.83 + sched->autouserjob1 = 0;
57.84 + sched->autouserjob2 = 0;
57.85 + sched->autouserjob3 = 0;
57.86 + sched->autouserjob4 = 0;
57.87 +
57.88 + sched->startoffset = 0;
57.89 + sched->endoffset = 0;
57.90 + sched->maxepisodes = 0;
57.91 + sched->maxnewest = 0;
57.92 +
57.93 + sched->recpriority = 0;
57.94 + sched->recgroup = 0;
57.95 + sched->playgroup = 0;
57.96 +
57.97 + sched->prefinput = 0;
57.98 + sched->inactive = 0;
57.99 +
57.100 + sched->searchType = g_string_new("");
57.101 + sched->searchForWhat = g_string_new("");
57.102 +
57.103 + sched->msqlquery = gmyth_query_new ();
57.104 +}
57.105 +
57.106 +static void
57.107 +gmyth_scheduler_dispose (GObject *object)
57.108 +{
57.109 + GMythScheduler *scheduler = GMYTH_SCHEDULER (object);
57.110 +
57.111 + if (scheduler->backend_info) {
57.112 + g_object_unref (scheduler->backend_info);
57.113 + scheduler->backend_info = NULL;
57.114 + }
57.115 +
57.116 + G_OBJECT_CLASS (gmyth_scheduler_parent_class)->dispose (object);
57.117 +}
57.118 +
57.119 +static void
57.120 +gmyth_scheduler_finalize (GObject *object)
57.121 +{
57.122 + g_signal_handlers_destroy (object);
57.123 +
57.124 + G_OBJECT_CLASS (gmyth_scheduler_parent_class)->finalize (object);
57.125 +}
57.126 +
57.127 +/** Creates a new instance of GMythScheduler.
57.128 + *
57.129 + * @return a new instance of GMythScheduler.
57.130 + */
57.131 +GMythScheduler*
57.132 +gmyth_scheduler_new ()
57.133 +{
57.134 + GMythScheduler *scheduler =
57.135 + GMYTH_SCHEDULER (g_object_new(GMYTH_SCHEDULER_TYPE, NULL));
57.136 +
57.137 + return scheduler;
57.138 +}
57.139 +
57.140 +gboolean
57.141 +gmyth_scheduler_connect (GMythScheduler *scheduler, GMythBackendInfo *backend_info)
57.142 +{
57.143 + return gmyth_scheduler_connect_with_timeout (scheduler, backend_info, 0);
57.144 +}
57.145 +
57.146 +/** Connects to the Mysql database in the backend. The backend address
57.147 + * is loaded from the GMythSettings instance.
57.148 + *
57.149 + * @param scheduler the GMythScheduler instance to be connected.
57.150 + * @return true if connection was success, false if failed.
57.151 + */
57.152 +gboolean
57.153 +gmyth_scheduler_connect_with_timeout (GMythScheduler *scheduler,
57.154 + GMythBackendInfo *backend_info, guint timeout)
57.155 +{
57.156 + assert(scheduler);
57.157 + g_return_val_if_fail (backend_info != NULL, FALSE);
57.158 +
57.159 + g_object_ref (backend_info);
57.160 + scheduler->backend_info = backend_info;
57.161 +
57.162 + if (scheduler->msqlquery == NULL) {
57.163 + g_warning ("[%s] GMythScheduler db initializing", __FUNCTION__);
57.164 + scheduler->msqlquery = gmyth_query_new ();
57.165 + }
57.166 +
57.167 + if (!gmyth_query_connect_with_timeout (scheduler->msqlquery,
57.168 + scheduler->backend_info, timeout)) {
57.169 + g_warning ("[%s] Error while connecting to db", __FUNCTION__);
57.170 + return FALSE;
57.171 + }
57.172 +
57.173 + return TRUE;
57.174 +}
57.175 +
57.176 +/** Disconnects from the Mysql database in the backend.
57.177 + *
57.178 + * @param scheduler the GMythScheduler instance to be disconnected
57.179 + * @return true if disconnection was success, false if failed.
57.180 + */
57.181 +gboolean
57.182 +gmyth_scheduler_disconnect (GMythScheduler *scheduler)
57.183 +{
57.184 + assert(scheduler);
57.185 +
57.186 + if (scheduler->msqlquery != NULL) {
57.187 + gmyth_query_disconnect (scheduler->msqlquery);
57.188 + g_object_unref (scheduler->msqlquery);
57.189 + }
57.190 +
57.191 + return TRUE;
57.192 +}
57.193 +
57.194 +/** Retrieves from the backend Mysql database the list of recording schedules.
57.195 + *
57.196 + * @param scheduler The GMythScheduler instance.
57.197 + * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
57.198 + * @return The amount of schedules retrieved from database, or -1 if error.
57.199 + */
57.200 +gint
57.201 +gmyth_scheduler_get_schedule_list ( GMythScheduler *scheduler, GList **schedule_list)
57.202 +{
57.203 + ScheduleInfo *schedule;
57.204 + MYSQL_RES *msql_res;
57.205 + GString *query_str = g_string_new ("");
57.206 + gchar *date_time = NULL;
57.207 +
57.208 + assert(scheduler);
57.209 +
57.210 + g_string_printf (query_str,
57.211 + "SELECT recordid,programid,chanid,starttime,startdate,"
57.212 + "endtime,enddate,title,subtitle,description,category FROM record;");
57.213 +
57.214 + if (scheduler->msqlquery == NULL) {
57.215 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
57.216 + return -1;
57.217 + }
57.218 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
57.219 +
57.220 + if (msql_res == NULL) {
57.221 + g_warning ("DB retrieval of schedule list failed");
57.222 + return -1;
57.223 + } else {
57.224 + MYSQL_ROW row;
57.225 + *schedule_list = NULL;
57.226 +
57.227 + while((row = mysql_fetch_row (msql_res)) != NULL) {
57.228 + schedule = g_new0(ScheduleInfo, 1);
57.229 +
57.230 + schedule->record_id = g_ascii_strtoull (row[0], NULL, 10);
57.231 + schedule->program_id = g_ascii_strtoull (row[1], NULL, 10);
57.232 + schedule->channel_id = g_ascii_strtoull (row[2], NULL, 10);
57.233 +
57.234 + /* generate a time_t from a time and a date db field */
57.235 + g_sprintf (date_time, "%sT%s", row[4], row[3]);
57.236 +
57.237 + schedule->start_time = gmyth_util_string_to_time_val (date_time);
57.238 +
57.239 + /* generate a time_t from a time and a date db field */
57.240 + g_sprintf (date_time, "%sT%s", row[6], row[5]);
57.241 +
57.242 + schedule->end_time = gmyth_util_string_to_time_val (date_time);
57.243 +
57.244 + schedule->title = g_string_new (row[7]);
57.245 + schedule->subtitle = g_string_new (row[8]);
57.246 + schedule->description = g_string_new (row[9]);
57.247 + schedule->category = g_string_new (row[10]);
57.248 +
57.249 + (*schedule_list) = g_list_append (*(schedule_list), schedule);
57.250 + }
57.251 + }
57.252 +
57.253 + mysql_free_result (msql_res);
57.254 + g_string_free(query_str, TRUE);
57.255 + g_free(date_time);
57.256 +
57.257 + return (*schedule_list == NULL) ? 0 : g_list_length (*schedule_list);
57.258 +}
57.259 +
57.260 +/** Retrieves from the backend Mysql database the list of recorded programs.
57.261 + *
57.262 + * @param scheduler The GMythScheduler instance.
57.263 + * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
57.264 + * @return The amount of recorded retrieved from database, or -1 if error.
57.265 + */
57.266 +gint
57.267 +gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler, GList **recorded_list)
57.268 +{
57.269 + RecordedInfo *record;
57.270 + MYSQL_RES *msql_res;
57.271 + GString *query_str = g_string_new ("");
57.272 +
57.273 + assert(scheduler);
57.274 +
57.275 + g_string_printf (query_str,
57.276 + "SELECT recordid,programid,chanid,starttime,progstart,"
57.277 + "endtime,progend,title,subtitle,description,category,filesize,basename FROM recorded WHERE recgroup != 'LiveTV'");
57.278 +
57.279 + if (scheduler->msqlquery == NULL) {
57.280 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
57.281 + return -1;
57.282 + }
57.283 +
57.284 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
57.285 +
57.286 + if (msql_res == NULL) {
57.287 + g_warning ("DB retrieval of recording list failed");
57.288 + return -1;
57.289 + } else {
57.290 + MYSQL_ROW row;
57.291 + *recorded_list = NULL;
57.292 +
57.293 + while((row = mysql_fetch_row (msql_res))!=NULL){
57.294 + record = g_new0(RecordedInfo, 1);
57.295 +
57.296 + record->record_id = (guint) g_ascii_strtoull (row[0], NULL, 10);
57.297 + record->program_id = (guint) g_ascii_strtoull (row[1], NULL, 10);
57.298 + record->channel_id = (guint) g_ascii_strtoull (row[2], NULL, 10);
57.299 +
57.300 + record->start_time = gmyth_util_string_to_time_val (row[3]);
57.301 + record->end_time = gmyth_util_string_to_time_val (row[5]);
57.302 +
57.303 + record->title = g_string_new (row[7]);
57.304 + record->subtitle = g_string_new (row[8]);
57.305 + record->description = g_string_new (row[9]);
57.306 + record->category = g_string_new (row[10]);
57.307 + record->filesize = g_ascii_strtoull (row[11], NULL, 10);
57.308 + record->basename = g_string_new (row[12]);
57.309 +
57.310 + *recorded_list = g_list_append (*recorded_list, record);
57.311 + }
57.312 + }
57.313 +
57.314 + mysql_free_result (msql_res);
57.315 + g_string_free(query_str, TRUE);
57.316 +
57.317 + return (*recorded_list == NULL) ? 0 : g_list_length (*recorded_list);
57.318 +}
57.319 +
57.320 +/** Requests the Mysql database in the backend to add a new schedule.
57.321 + *
57.322 + * @param scheduler the GMythScheduler instance.
57.323 + * @param schedule_info the ScheduleInfo with recording schedule information
57.324 + * to be added. record_id = -1 to add a new schedule, otherwise this
57.325 + * function will update the schedule in the db
57.326 + * @return gboolean returns FALSE if some error occurs, TRUE otherwise
57.327 + */
57.328 +gboolean
57.329 +gmyth_scheduler_add_schedule (GMythScheduler *scheduler,
57.330 + ScheduleInfo *schedule_info)
57.331 +{
57.332 + //GTimeVal *start_tm;
57.333 + //GTimeVal *end_tm;
57.334 +
57.335 + MYSQL_RES *msql_res;
57.336 + GString *query_str = g_string_new ("");
57.337 +
57.338 + gchar *date_time = NULL;
57.339 +
57.340 + assert(scheduler);
57.341 +
57.342 + if (scheduler->msqlquery == NULL) {
57.343 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
57.344 + return FALSE;
57.345 + }
57.346 +
57.347 + //TODO: verify if this funtion realy does what it should do!
57.348 + g_string_printf (query_str, "REPLACE INTO record "
57.349 + "(recordid, type, chanid, starttime, "
57.350 + "startdate, endtime, enddate, title,"
57.351 + "profile, recpriority, maxnewest, inactive, "
57.352 + "maxepisodes, autoexpire, startoffset, endoffset, "
57.353 + "recgroup, dupmethod, dupin, station, "
57.354 + "autocommflag, findday, findtime, findid, "
57.355 + "search, autotranscode, transcoder, tsdefault, "
57.356 + "autouserjob1, autouserjob2, autouserjob3, autouserjob4) "
57.357 + " values ( %d, 1, %d, \"%s\"," //recordid, type, chanid, starttime
57.358 + " \"%s\", \"%s\", \"%s\", \"%s\","
57.359 + //startdate, endtime, enddate, title
57.360 + "DEFAULT, 0, 0, 0, " //profile, recpriority, maxnewest, inactive
57.361 + "0, 1, 0, 0, " //maxepisodes, autoexpire, startoffset, endoffset
57.362 + "DEFAULT, 6, 15, %d, " //recgroup, dupmethod, dupin, station
57.363 + "1, %d, \"%s\", %d, " //autocommflag, findday, findtime, findid
57.364 + "5, 0, 29, 1, " //search, autotranscode, transcoder, tsdefault
57.365 + "0, 0, 0, 0 );", //autouserjob1, autouserjob2, autouserjob3, autouserjob4
57.366 + schedule_info->record_id, schedule_info->channel_id,
57.367 + gmyth_util_time_to_string_only_time( schedule_info->start_time ),
57.368 + gmyth_util_time_to_string_only_date( schedule_info->start_time ),
57.369 + gmyth_util_time_to_string_only_time( schedule_info->end_time ),
57.370 + gmyth_util_time_to_string_only_date( schedule_info->end_time ),
57.371 + schedule_info->title->str, //title
57.372 + schedule_info->channel_id,//station
57.373 + (gmyth_util_time_val_to_date( schedule_info->start_time ))->tm_wday, //findday
57.374 + gmyth_util_time_to_string_only_time( schedule_info->start_time ), //findtime
57.375 + (gint)(schedule_info->start_time->tv_sec/60/60/24 + 719528)//findid
57.376 + );
57.377 +
57.378 + gmyth_debug ( "Sending query to MySQL = %s.", query_str->str );
57.379 +
57.380 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
57.381 +
57.382 + /* FIXME: currently no way to detect db error in UPDATE, REPLACES!
57.383 + if (msql_res == NULL) {
57.384 + g_warning ("DB retrieval of recording list failed");
57.385 + return -1;
57.386 + }*/
57.387 +
57.388 + /* TODO: verify record_id = -1 semantics */
57.389 + if (schedule_info->record_id <= 0)
57.390 + schedule_info->record_id = get_record_id_from_database(scheduler);
57.391 +
57.392 + /* Notify the backend of changes */
57.393 + update_backend(scheduler, schedule_info->record_id);
57.394 +
57.395 + /* free allocated memory */
57.396 + mysql_free_result (msql_res);
57.397 + g_string_free(query_str, TRUE);
57.398 +
57.399 + return 1;
57.400 +}
57.401 +
57.402 +/** Requests the Mysql database in the backend to remove an existing schedule.
57.403 + *
57.404 + * @param scheduler the GMythScheduler instance.
57.405 + * @param record_id The schedule's record id to be removed
57.406 + * @return gboolean TRUE if success, FALSE if error
57.407 + */
57.408 +gboolean
57.409 +gmyth_scheduler_delete_schedule (GMythScheduler *scheduler, gint record_id)
57.410 +{
57.411 +
57.412 + MYSQL_RES *msql_res;
57.413 + GString *query_str = g_string_new ("");
57.414 +
57.415 + assert(scheduler);
57.416 +
57.417 + if (scheduler->msqlquery == NULL) {
57.418 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
57.419 + return FALSE;
57.420 + }
57.421 +
57.422 + //========================================
57.423 + g_string_printf (query_str,
57.424 + "DELETE FROM record WHERE recordid=%d", record_id);
57.425 +
57.426 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
57.427 +
57.428 + if (msql_res == NULL) {
57.429 + g_warning ("[%s] Error while trying to delete a schedule in the database", __FUNCTION__);
57.430 + return FALSE;
57.431 + }
57.432 +
57.433 + update_backend(scheduler, record_id);// Notify the backend of the changes
57.434 +
57.435 + mysql_free_result (msql_res);
57.436 + g_string_free(query_str, TRUE);
57.437 +
57.438 + return TRUE;
57.439 +}
57.440 +
57.441 +/** Requests the Mysql database in the backend to remove an existing recorded item.
57.442 + *
57.443 + * @param scheduler the GMythScheduler instance.
57.444 + * @param record_id The recorded item id to be removed
57.445 + * @return gboolean TRUE if success, FALSE if error
57.446 + */
57.447 +gboolean
57.448 +gmyth_scheduler_delete_recorded (GMythScheduler *scheduler, gint record_id)
57.449 +{
57.450 +
57.451 + MYSQL_RES *msql_res;
57.452 +
57.453 + GString *query_str = g_string_new ("");
57.454 +
57.455 + assert(scheduler);
57.456 +
57.457 + if (scheduler->msqlquery == NULL) {
57.458 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
57.459 + return FALSE;
57.460 + }
57.461 +
57.462 + //========================================
57.463 + g_string_printf (query_str,
57.464 + "DELETE FROM recorded WHERE recordid=%d", record_id);
57.465 +
57.466 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
57.467 +
57.468 + update_backend(scheduler, record_id);// Notify the backend of the changes
57.469 +
57.470 + mysql_free_result (msql_res);
57.471 + g_string_free(query_str, TRUE);
57.472 +
57.473 + return TRUE;
57.474 +}
57.475 +
57.476 +/** Retrieves an existing recorded item information from database. The information
57.477 + * is used to fill the returned GMythProgramInfo.
57.478 + *
57.479 + * @param scheduler The GMythScheduler instance.
57.480 + * @param channel The channel associated to the record
57.481 + * @param starttime The record start time
57.482 + * @return A GMythProgramInfo struct with the requested record item
57.483 + * information, or NULL if error.
57.484 + */
57.485 +GMythProgramInfo*
57.486 +gmyth_scheduler_get_recorded (GMythScheduler *scheduler,
57.487 + GString *channel, GTimeVal* starttime)
57.488 +{
57.489 + MYSQL_RES *msql_res;
57.490 + GMythProgramInfo *proginfo = NULL;
57.491 + GString *query_str = g_string_new("");
57.492 + gchar *time_str = gmyth_util_time_to_string_from_time_val (starttime);
57.493 +
57.494 + assert(scheduler);
57.495 +
57.496 + if (scheduler->msqlquery == NULL) {
57.497 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
57.498 + return NULL;
57.499 + }
57.500 +
57.501 + g_string_printf (query_str, "SELECT recorded.chanid,starttime,endtime,title, "
57.502 + "subtitle,description,channel.channum, "
57.503 + "channel.callsign,channel.name,channel.commfree, "
57.504 + "channel.outputfilters,seriesid,programid,filesize, "
57.505 + "lastmodified,stars,previouslyshown,originalairdate, "
57.506 + "hostname,recordid,transcoder,playgroup, "
57.507 + "recorded.recpriority,progstart,progend,basename,recgroup "
57.508 + "FROM recorded "
57.509 + "LEFT JOIN channel "
57.510 + "ON recorded.chanid = channel.chanid "
57.511 + "WHERE recorded.chanid = \"%s\" "
57.512 + "AND starttime = \"%s\" ;",
57.513 + channel->str, time_str);
57.514 +
57.515 + msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
57.516 +
57.517 + if (msql_res /*&& query.size() > 0*/) {
57.518 +
57.519 + MYSQL_ROW msql_row = mysql_fetch_row (msql_res);
57.520 + if (msql_row) {
57.521 +
57.522 + proginfo = gmyth_program_info_new();
57.523 +
57.524 + proginfo->chanid = g_string_new (msql_row[0]);
57.525 + proginfo->startts = gmyth_util_string_to_time_val (msql_row[23]);
57.526 + proginfo->endts = gmyth_util_string_to_time_val (msql_row[24]);
57.527 + proginfo->recstartts = gmyth_util_string_to_time_val (msql_row[1]);
57.528 + proginfo->recendts = gmyth_util_string_to_time_val (msql_row[2]);
57.529 + proginfo->title = g_string_new (msql_row[3]);
57.530 + proginfo->subtitle = g_string_new (msql_row[4]);
57.531 + proginfo->description = g_string_new (msql_row[5]);
57.532 +
57.533 + proginfo->chanstr = g_string_new (msql_row[6]);
57.534 + proginfo->chansign = g_string_new (msql_row[7]);
57.535 + proginfo->channame = g_string_new (msql_row[0]);
57.536 + proginfo->chancommfree = g_ascii_strtoull (msql_row[9], NULL, 10);
57.537 + proginfo->chanOutputFilters = g_string_new (msql_row[10]);
57.538 + proginfo->seriesid = g_string_new (msql_row[11]);
57.539 + proginfo->programid = g_string_new (msql_row[12]);
57.540 + proginfo->filesize = g_ascii_strtoull (msql_row[13], NULL, 10);
57.541 +
57.542 + proginfo->lastmodified = gmyth_util_string_to_time_val (msql_row[14]);
57.543 +
57.544 + proginfo->stars = g_ascii_strtod (msql_row[15], NULL);
57.545 + proginfo->repeat = g_ascii_strtoull (msql_row[16], NULL, 10);
57.546 +
57.547 + if (msql_row[17] == NULL) {
57.548 + proginfo->originalAirDate = 0;
57.549 + proginfo->hasAirDate = FALSE;
57.550 + } else {
57.551 + proginfo->originalAirDate = gmyth_util_string_to_time_val (msql_row[17]);
57.552 + proginfo->hasAirDate = TRUE;
57.553 + }
57.554 +
57.555 + proginfo->hostname = g_string_new (msql_row[18]);
57.556 + proginfo->recordid = g_ascii_strtoull (msql_row[19], NULL, 10);
57.557 + proginfo->transcoder = g_ascii_strtoull (msql_row[20], NULL, 10);
57.558 +
57.559 + //proginfo->spread = -1;
57.560 + //proginfo->programflags = proginfo->getProgramFlags();
57.561 +
57.562 + proginfo->recgroup = g_string_new (msql_row[26]);
57.563 + proginfo->playgroup = g_string_new (msql_row[21]);
57.564 + proginfo->recpriority = g_ascii_strtoull (msql_row[22], NULL, 10);
57.565 +
57.566 + proginfo->pathname = g_string_new (msql_row[25]);
57.567 +
57.568 + gmyth_debug ("One program info loaded from mysql database\n");
57.569 + }
57.570 + }
57.571 +
57.572 + mysql_free_result (msql_res);
57.573 + g_string_free(query_str, TRUE);
57.574 + g_free(time_str);
57.575 +
57.576 + return proginfo;
57.577 +}
57.578 +
57.579 +/** Retrieves the next record id.
57.580 + *
57.581 + * @param scheduler The GMythScheduler instance.
57.582 + * @return gint record_id if success, -1 otherwise
57.583 + */
57.584 +static gint
57.585 +get_record_id_from_database (GMythScheduler *scheduler)
57.586 +{
57.587 + gint record_id;
57.588 +
57.589 + assert(scheduler);
57.590 +
57.591 + if (scheduler->msqlquery == NULL) {
57.592 + g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__);
57.593 + return 0;
57.594 + }
57.595 +
57.596 + record_id = mysql_insert_id (scheduler->msqlquery->conn);
57.597 +
57.598 + return record_id;
57.599 +}
57.600 +
57.601 +/** Notifies the backend of an update in the db.
57.602 + *
57.603 + * @param record_id the id of the modified recording.
57.604 + */
57.605 +static void
57.606 +update_backend(GMythScheduler *scheduler, gint record_id)//fixme: put void and discovery record_id inside
57.607 +{
57.608 + GMythSocket *socket;
57.609 + GMythStringList *strlist = gmyth_string_list_new ();
57.610 + GString *datastr = g_string_new ("RESCHEDULE_RECORDINGS ");
57.611 +
57.612 + g_string_append_printf (datastr, "%d", record_id);
57.613 + gmyth_string_list_append_string (strlist, datastr);
57.614 +
57.615 + socket = gmyth_socket_new ();
57.616 + if (gmyth_socket_connect (socket, scheduler->backend_info->hostname,
57.617 + scheduler->backend_info->port)) {
57.618 + gmyth_socket_sendreceive_stringlist (socket, strlist);
57.619 + } else {
57.620 + g_warning ("[%s] Connection to backend failed!", __FUNCTION__);
57.621 + }
57.622 +
57.623 + g_string_free(datastr, TRUE);
57.624 + g_object_unref(strlist);
57.625 +}
57.626 +
57.627 +void
57.628 +gmyth_scheduler_recorded_info_get_preview (RecordedInfo *info, GByteArray* data)
57.629 +{
57.630 +}
57.631 +
57.632 +void
57.633 +gmyth_scheduler_recorded_info_free (RecordedInfo *info)
57.634 +{
57.635 + if (info->title != NULL)
57.636 + g_string_free (info->title, TRUE);
57.637 +
57.638 + if (info->subtitle != NULL)
57.639 + g_string_free (info->subtitle, TRUE);
57.640 +
57.641 + if (info->description != NULL)
57.642 + g_string_free (info->description, TRUE);
57.643 +
57.644 + if (info->category != NULL)
57.645 + g_string_free (info->category, TRUE);
57.646 +
57.647 + if (info->basename != NULL)
57.648 + g_string_free (info->basename, TRUE);
57.649 +
57.650 + g_free (info);
57.651 +}
57.652 +
57.653 +void
57.654 +gmyth_scheduler_schedule_info_free (ScheduleInfo *info)
57.655 +{
57.656 + if (info->title != NULL)
57.657 + g_string_free (info->title, TRUE);
57.658 +
57.659 + if (info->subtitle != NULL)
57.660 + g_string_free (info->subtitle, TRUE);
57.661 +
57.662 + if (info->description != NULL)
57.663 + g_string_free (info->description, TRUE);
57.664 +
57.665 + if (info->category != NULL)
57.666 + g_string_free (info->category, TRUE);
57.667 +
57.668 + g_free (info);
57.669 +}
57.670 +
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/branches/gmyth-0.1b/src/gmyth_scheduler.h Thu Feb 01 18:42:01 2007 +0000
58.3 @@ -0,0 +1,169 @@
58.4 +/**
58.5 + * GMyth Library
58.6 + *
58.7 + * @file gmyth/gmyth_scheduler.h
58.8 + *
58.9 + * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
58.10 + * and modifying the recorded content.
58.11 + *
58.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
58.13 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@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 +#ifndef __GMYTH_SCHEDULER_H__
58.33 +#define __GMYTH_SCHEDULER_H__
58.34 +
58.35 +#include <glib-object.h>
58.36 +#include <time.h>
58.37 +
58.38 +#include "gmyth_common.h"
58.39 +#include "gmyth_query.h"
58.40 +#include "gmyth_backendinfo.h"
58.41 +
58.42 +G_BEGIN_DECLS
58.43 +
58.44 +#define GMYTH_SCHEDULER_TYPE (gmyth_scheduler_get_type ())
58.45 +#define GMYTH_SCHEDULER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE, GMythScheduler))
58.46 +#define GMYTH_SCHEDULER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
58.47 +#define IS_GMYTH_SCHEDULER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE))
58.48 +#define IS_GMYTH_SCHEDULER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE))
58.49 +#define GMYTH_SCHEDULER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
58.50 +
58.51 +
58.52 +typedef struct _GMythScheduler GMythScheduler;
58.53 +typedef struct _GMythSchedulerClass GMythSchedulerClass;
58.54 +
58.55 +struct _GMythSchedulerClass
58.56 +{
58.57 + GObjectClass parent_class;
58.58 +
58.59 + /* callbacks */
58.60 + /* no one for now */
58.61 +};
58.62 +
58.63 +struct _GMythScheduler
58.64 +{
58.65 + GObject parent;
58.66 +
58.67 + unsigned long recordid;
58.68 + unsigned long type;
58.69 + unsigned long search;
58.70 + GString *profile;
58.71 +
58.72 + long dupin;
58.73 + long dupmethod;
58.74 + long autoexpire;
58.75 + short int autotranscode;
58.76 + long transcoder;
58.77 +
58.78 + short int autocommflag;
58.79 + short int autouserjob1;
58.80 + short int autouserjob2;
58.81 + short int autouserjob3;
58.82 + short int autouserjob4;
58.83 +
58.84 + long startoffset;
58.85 + long endoffset;
58.86 + long maxepisodes;
58.87 + long maxnewest;
58.88 +
58.89 + long recpriority;
58.90 + GString *recgroup;
58.91 + GString *playgroup;
58.92 +
58.93 + long prefinput;
58.94 + short int inactive;
58.95 +
58.96 + GString *searchType;
58.97 + GString *searchForWhat;
58.98 +
58.99 + GMythQuery *msqlquery;
58.100 + GMythBackendInfo *backend_info;
58.101 +};
58.102 +
58.103 +typedef struct {
58.104 + gint record_id;
58.105 + gint program_id;
58.106 + gint channel_id;
58.107 +
58.108 + GTimeVal* start_time;
58.109 + GTimeVal* end_time;
58.110 +
58.111 + GString *title;
58.112 + GString *subtitle;
58.113 + GString *description;
58.114 + GString *category;
58.115 +
58.116 +} ScheduleInfo;
58.117 +
58.118 +typedef struct {
58.119 + guint record_id;
58.120 + guint program_id;
58.121 + guint channel_id;
58.122 +
58.123 + GTimeVal* start_time;
58.124 + GTimeVal* end_time;
58.125 +
58.126 + GString *title;
58.127 + GString *subtitle;
58.128 + GString *description;
58.129 + GString *category;
58.130 +
58.131 + GString *basename;
58.132 +
58.133 + guint64 filesize;
58.134 +
58.135 +} RecordedInfo;
58.136 +
58.137 +
58.138 +GType gmyth_scheduler_get_type (void);
58.139 +
58.140 +GMythScheduler* gmyth_scheduler_new ();
58.141 +gboolean gmyth_scheduler_connect (GMythScheduler *scheduler,
58.142 + GMythBackendInfo *backend_info);
58.143 +gboolean gmyth_scheduler_connect_with_timeout (GMythScheduler *scheduler,
58.144 + GMythBackendInfo *backend_info, guint timeout);
58.145 +gboolean gmyth_scheduler_disconnect (GMythScheduler *scheduler);
58.146 +
58.147 +gint gmyth_scheduler_get_schedule_list (GMythScheduler *scheduler,
58.148 + GList **sched_list);
58.149 +gint gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler,
58.150 + GList **rec_list);
58.151 +
58.152 +GMythProgramInfo* gmyth_scheduler_get_recorded (GMythScheduler *scheduler,
58.153 + GString *channel, GTimeVal* starttime);
58.154 +
58.155 +gint gmyth_scheduler_add_schedule(GMythScheduler *scheduler,
58.156 + ScheduleInfo *schedule_info);
58.157 +
58.158 +gint gmyth_scheduler_delete_schedule (GMythScheduler *scheduler,
58.159 + gint record_id);
58.160 +gint gmyth_scheduler_delete_recorded (GMythScheduler *scheduler,
58.161 + gint record_id);
58.162 +
58.163 +void gmyth_scheduler_recorded_info_get_preview (RecordedInfo *info,
58.164 + GByteArray* data);
58.165 +
58.166 +void gmyth_scheduler_schedule_info_free (ScheduleInfo *info);
58.167 +void gmyth_scheduler_recorded_info_free (RecordedInfo *info);
58.168 +
58.169 +G_END_DECLS
58.170 +
58.171 +#endif /* __GMYTH_SCHEDULER_H__ */
58.172 +
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59.2 +++ b/branches/gmyth-0.1b/src/gmyth_socket.c Thu Feb 01 18:42:01 2007 +0000
59.3 @@ -0,0 +1,1082 @@
59.4 +/**
59.5 + * GMyth Library
59.6 + *
59.7 + * @file gmyth/gmyth_socket.c
59.8 + *
59.9 + * @brief <p> MythTV socket implementation, according to the MythTV Project
59.10 + * (www.mythtv.org).
59.11 + *
59.12 + * This component provides basic socket functionalities to interact with
59.13 + * the Mythtv backend.
59.14 + * <p>
59.15 + *
59.16 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
59.17 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
59.18 + *
59.19 + *//*
59.20 + *
59.21 + * This program is free software; you can redistribute it and/or modify
59.22 + * it under the terms of the GNU Lesser General Public License as published by
59.23 + * the Free Software Foundation; either version 2 of the License, or
59.24 + * (at your option) any later version.
59.25 + *
59.26 + * This program is distributed in the hope that it will be useful,
59.27 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
59.28 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59.29 + * GNU General Public License for more details.
59.30 + *
59.31 + * You should have received a copy of the GNU Lesser General Public License
59.32 + * along with this program; if not, write to the Free Software
59.33 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
59.34 + */
59.35 +
59.36 +#ifdef HAVE_CONFIG_H
59.37 +#include "config.h"
59.38 +#endif
59.39 +
59.40 +#include "gmyth_socket.h"
59.41 +
59.42 +#include <glib.h>
59.43 +#include <glib/gprintf.h>
59.44 +
59.45 +#include <arpa/inet.h>
59.46 +#include <sys/types.h>
59.47 +#include <sys/socket.h>
59.48 +#include <sys/param.h>
59.49 +#include <netdb.h>
59.50 +#include <net/if.h>
59.51 +#include <errno.h>
59.52 +#include <stdlib.h>
59.53 +
59.54 +#include <unistd.h>
59.55 +#include <netinet/in.h>
59.56 +#include <fcntl.h>
59.57 +#include <signal.h>
59.58 +
59.59 +#include <sys/ioctl.h>
59.60 +
59.61 +#include "gmyth_stringlist.h"
59.62 +#include "gmyth_uri.h"
59.63 +#include "gmyth_debug.h"
59.64 +
59.65 +#define BUFLEN 512
59.66 +#define MYTH_SEPARATOR "[]:[]"
59.67 +#define MYTH_PROTOCOL_FIELD_SIZE 8
59.68 +
59.69 +/* max number of iterations */
59.70 +#define MYTHTV_MAX_VERSION_CHECKS 40
59.71 +
59.72 +// FIXME: put this in the right place
59.73 +#define MYTHTV_VERSION_DEFAULT 30
59.74 +
59.75 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
59.76 +
59.77 +static gchar* local_hostname = NULL;
59.78 +
59.79 +static void gmyth_socket_class_init (GMythSocketClass *klass);
59.80 +static void gmyth_socket_init (GMythSocket *object);
59.81 +
59.82 +static void gmyth_socket_dispose (GObject *object);
59.83 +static void gmyth_socket_finalize (GObject *object);
59.84 +
59.85 +G_DEFINE_TYPE(GMythSocket, gmyth_socket, G_TYPE_OBJECT)
59.86 +
59.87 +static void
59.88 +gmyth_socket_class_init (GMythSocketClass *klass)
59.89 +{
59.90 + GObjectClass *gobject_class;
59.91 +
59.92 + gobject_class = (GObjectClass *) klass;
59.93 +
59.94 + gobject_class->dispose = gmyth_socket_dispose;
59.95 + gobject_class->finalize = gmyth_socket_finalize;
59.96 +}
59.97 +
59.98 +static void
59.99 +gmyth_socket_init (GMythSocket *gmyth_socket)
59.100 +{
59.101 +
59.102 + /* gmyth_socket->local_hostname = NULL; */
59.103 +
59.104 +}
59.105 +
59.106 +/** Gets the some important address translation info, from the client socket
59.107 + * that will open a connection.
59.108 + *
59.109 + * @return gint that represents the error number from getaddrinfo().
59.110 + */
59.111 +static gint
59.112 +gmyth_socket_toaddrinfo (const gchar *addr, gint port, struct addrinfo **addrInfo )
59.113 +{
59.114 + struct addrinfo hints;
59.115 + gchar *portStr = NULL;
59.116 + gint errorn = EADDRNOTAVAIL;
59.117 +
59.118 + g_return_val_if_fail ( addr != NULL, -1 );
59.119 + g_debug ("Calling %s\n", __FUNCTION__);
59.120 +
59.121 + /* hints = g_malloc0 ( sizeof(struct addrinfo) ); */
59.122 + memset ( &hints, 0, sizeof(struct addrinfo) );
59.123 + hints.ai_family = AF_INET;
59.124 + hints.ai_socktype = SOCK_STREAM;
59.125 + /* hints.ai_flags = AI_NUMERICHOST; */
59.126 +
59.127 + if ( port != -1 )
59.128 + portStr = g_strdup_printf ( "%d", port );
59.129 + else
59.130 + portStr = NULL;
59.131 +
59.132 + gmyth_debug ("Getting name resolution for: %s, %d\n", addr, port);
59.133 +
59.134 + if ( ( errorn = getaddrinfo(addr, portStr, &hints, addrInfo) ) != 0 ) {
59.135 + g_printerr( "[%s] Socket ERROR: %s\n", __FUNCTION__, gai_strerror(errorn) );
59.136 + }
59.137 + g_free (portStr);
59.138 + /* g_free (hints); */
59.139 + return errorn;
59.140 +}
59.141 +
59.142 +static gint
59.143 +gmyth_socket_find_match_address_uri( GMythURI* uri, gchar *address ) {
59.144 +
59.145 + if ( g_ascii_strcasecmp( gmyth_uri_get_host( uri ), address ) == 0 ) {
59.146 + //g_printerr( "Found URI: %s !!!\n", rui_uri_getvalue(uri) );
59.147 + return 0;
59.148 + } else {
59.149 + return -1;
59.150 + }
59.151 +
59.152 +}
59.153 +
59.154 +static const gchar *PATH_PROC_NET_DEV = "/proc/net/dev";
59.155 +
59.156 +/** Gets the list of all local network interfaces (using the /proc/net/dev directory).
59.157 + *
59.158 + * @param current_connections A list with all the network interfaces are valid,
59.159 + * to be applied just like a filter.
59.160 + * @return List with all the local net interfaces.
59.161 + */
59.162 +static GList *
59.163 +gmyth_socket_get_local_addrs( GList *current_connections )
59.164 +{
59.165 +
59.166 + GList *local_addrs = NULL;
59.167 + FILE *fd;
59.168 + gint s;
59.169 + gchar buffer[256+1];
59.170 + gchar ifaddr[20+1];
59.171 + gchar *ifname;
59.172 + gchar *sep;
59.173 +
59.174 + s = socket(AF_INET, SOCK_DGRAM, 0);
59.175 + if (s < 0)
59.176 + return 0;
59.177 + fd = fopen(PATH_PROC_NET_DEV, "r");
59.178 + fgets(buffer, sizeof(buffer)-1, fd);
59.179 + fgets(buffer, sizeof(buffer)-1, fd);
59.180 + while (!feof(fd)) {
59.181 + ifname = buffer;
59.182 + sep;
59.183 + if (fgets(buffer, sizeof(buffer)-1, fd) == NULL)
59.184 + break;
59.185 + sep = strrchr(buffer, ':');
59.186 + if (sep)
59.187 + *sep = 0;
59.188 + while (*ifname == ' ')
59.189 + ifname++;
59.190 + struct ifreq req;
59.191 + strcpy(req.ifr_name, ifname);
59.192 + if (ioctl(s, SIOCGIFFLAGS, &req) < 0)
59.193 + continue;
59.194 + if (!(req.ifr_flags & IFF_UP))
59.195 + continue;
59.196 + if (req.ifr_flags & IFF_LOOPBACK)
59.197 + continue;
59.198 + if (ioctl(s, SIOCGIFADDR, &req) < 0)
59.199 + continue;
59.200 + g_strlcpy( ifaddr, inet_ntoa(((struct sockaddr_in*)&req.ifr_addr)->sin_addr), sizeof(struct ifaddr)-1 );
59.201 + local_addrs = g_list_append( local_addrs, g_strdup( ifaddr ) );
59.202 +
59.203 + gmyth_debug( "( from the /proc/net/dev) Interface name: %s, address: %s\n",
59.204 + ifname, ifaddr );
59.205 + }
59.206 + fclose(fd);
59.207 + close(s);
59.208 + return local_addrs;
59.209 +
59.210 +}
59.211 +
59.212 +
59.213 +/**
59.214 + * Get only the local addresses from the primary interface
59.215 + */
59.216 +static gchar *
59.217 +gmyth_socket_get_primary_addr()
59.218 +{
59.219 +
59.220 + gchar *if_eth0 = g_new0( gchar, sizeof(struct ifaddr)-1 );
59.221 + GList *if_tmp = NULL;
59.222 +
59.223 + GList *interfs = gmyth_socket_get_local_addrs( NULL );
59.224 +
59.225 + if ( interfs != NULL && ( g_list_length( interfs ) > 0 ) )
59.226 + {
59.227 + /* get the first occurrence (primary interface) */
59.228 + if_tmp = g_list_first( interfs );
59.229 +
59.230 + if ( if_tmp != NULL )
59.231 + g_strlcpy (if_eth0, (gchar *)if_tmp->data, sizeof(struct ifaddr)-1 );
59.232 +
59.233 + }
59.234 +
59.235 + if ( interfs != NULL )
59.236 + g_list_free( interfs );
59.237 +
59.238 + return if_eth0;
59.239 +}
59.240 +
59.241 +/** This function retrieves the local hostname of the
59.242 + * client machine.
59.243 + *
59.244 + * @return GString* get local hostname.
59.245 + */
59.246 +GString *
59.247 +gmyth_socket_get_local_hostname ()
59.248 +{
59.249 +
59.250 + char hname[50];
59.251 + gint res = gethostname (hname, 50);
59.252 +
59.253 + if (res == -1) {
59.254 + g_debug ("Error while getting hostname");
59.255 + return NULL;
59.256 + }
59.257 +
59.258 + return g_string_new (hname);
59.259 +
59.260 +#if 0
59.261 + GString *str = NULL;
59.262 +
59.263 + if ( local_hostname != NULL && strlen(local_hostname) > 0 )
59.264 + return g_string_new( local_hostname );
59.265 +
59.266 + gchar *localaddr = NULL;
59.267 + gboolean found_addr = FALSE;
59.268 + struct addrinfo* addr_info_data = NULL, *addr_info0 = NULL;
59.269 + struct sockaddr_in* sa = NULL;
59.270 + gchar localhostname[MAXHOSTNAMELEN];
59.271 +
59.272 +
59.273 + if (gethostname (localhostname, MAXHOSTNAMELEN) != 0 ) {
59.274 + gmyth_debug ( "Error on gethostname" );
59.275 + }
59.276 + localhostname[MAXHOSTNAMELEN-1] = 0;
59.277 +
59.278 + gint err = gmyth_socket_toaddrinfo (localhostname, -1, &addr_info_data );
59.279 +
59.280 + if ( err == EADDRNOTAVAIL )
59.281 + {
59.282 + g_warning( "[%s] Address (%s) not available. (reason = %d)\n", __FUNCTION__, localhostname, err );
59.283 + return str;
59.284 + }
59.285 +
59.286 + g_static_mutex_lock( &mutex );
59.287 +
59.288 + addr_info0 = addr_info_data;
59.289 +
59.290 + while( addr_info0 != NULL && addr_info0->ai_addr != NULL &&
59.291 + ( sa = (struct sockaddr_in*)addr_info0->ai_addr ) != NULL && !found_addr ) {
59.292 + localaddr = inet_ntoa( sa->sin_addr );
59.293 +
59.294 + if ( localaddr != NULL && ( g_strrstr( localaddr, "127" ) == NULL ) ) {
59.295 + str = g_string_new (localaddr);
59.296 + found_addr = TRUE;
59.297 + g_free (localaddr);
59.298 + break;
59.299 + }
59.300 +/*
59.301 + if (localaddr != NULL) {
59.302 + g_free (localaddr);
59.303 + localaddr = NULL;
59.304 + }
59.305 + */
59.306 +
59.307 + addr_info0 = addr_info0->ai_next;
59.308 + };
59.309 +
59.310 + freeaddrinfo (addr_info_data);
59.311 + addr_info_data = NULL;
59.312 +
59.313 + if ( found_addr == FALSE ) {
59.314 + gchar *prim_addr = gmyth_socket_get_primary_addr();
59.315 +
59.316 + if ( prim_addr != NULL ) {
59.317 + g_warning("[%s] Could not determine the local alphanumerical hostname. Setting to %s\n",
59.318 + __FUNCTION__, prim_addr );
59.319 +
59.320 + str = g_string_new (prim_addr);
59.321 + g_free (prim_addr);
59.322 + } else {
59.323 + str = g_string_new (localhostname);
59.324 + }
59.325 + }
59.326 +
59.327 + g_static_mutex_unlock (&mutex);
59.328 +
59.329 + if ( str != NULL && str->str != NULL )
59.330 + local_hostname = g_strdup( str->str );
59.331 +
59.332 + return str;
59.333 +#endif
59.334 +}
59.335 +
59.336 +static void
59.337 +gmyth_socket_dispose (GObject *object)
59.338 +{
59.339 + GMythSocket *gmyth_socket = GMYTH_SOCKET(object);
59.340 +
59.341 + /* disconnect socket */
59.342 + gmyth_socket_close_connection (gmyth_socket);
59.343 +
59.344 + g_free (gmyth_socket->hostname);
59.345 + gmyth_socket->hostname = NULL;
59.346 +
59.347 + g_free (local_hostname);
59.348 +
59.349 + local_hostname = NULL;
59.350 +
59.351 + G_OBJECT_CLASS (gmyth_socket_parent_class)->dispose (object);
59.352 +}
59.353 +
59.354 +static void
59.355 +gmyth_socket_finalize (GObject *object)
59.356 +{
59.357 + g_signal_handlers_destroy (object);
59.358 +
59.359 + G_OBJECT_CLASS (gmyth_socket_parent_class)->finalize (object);
59.360 +}
59.361 +
59.362 +/** Creates a new instance of GMythSocket.
59.363 + *
59.364 + * @return a new instance of GMythSocket.
59.365 + */
59.366 +GMythSocket*
59.367 +gmyth_socket_new ()
59.368 +{
59.369 + GMythSocket *gmyth_socket = GMYTH_SOCKET (g_object_new(GMYTH_SOCKET_TYPE, NULL));
59.370 +
59.371 + gmyth_socket->mythtv_version = MYTHTV_VERSION_DEFAULT;
59.372 +
59.373 + return gmyth_socket;
59.374 +}
59.375 +
59.376 +/** Try to open an asynchronous connection to the MythTV backend.
59.377 + *
59.378 + * @param fd Socket descriptor.
59.379 + * @param remote Remote address.
59.380 + * @param len Newly created socket length field.
59.381 + * @param timeout Timeval argument with the time interval to timeout before closing.
59.382 + * @param err Error message number.
59.383 + * @return Any numerical value below 0, if an error had been found.
59.384 + */
59.385 +static gint
59.386 +gmyth_socket_try_connect ( gint fd, struct sockaddr *remote, gint len,
59.387 + struct timeval *timeout, gint *err)
59.388 +{
59.389 + /*g_return_val_if_fail( timeout != NULL, 0 );*/
59.390 + gint saveflags, ret, back_err;
59.391 +
59.392 + fd_set fd_w;
59.393 +
59.394 + saveflags = fcntl( fd, F_GETFL, 0 );
59.395 + if( saveflags < 0 ) {
59.396 + g_warning( "[%s] Problems when getting socket flags on fcntl.\n", __FUNCTION__ );
59.397 + *err=errno;
59.398 + return -1;
59.399 + }
59.400 +
59.401 + /* Set non blocking */
59.402 + if( fcntl( fd, F_SETFL, saveflags | O_NONBLOCK ) < 0) {
59.403 + g_warning( "[%s] Problems when setting non-blocking using fcntl.\n", __FUNCTION__ );
59.404 + *err=errno;
59.405 + return -1;
59.406 + }
59.407 +
59.408 + /* This will return immediately */
59.409 + *err= connect ( fd, remote, len );
59.410 + back_err=errno;
59.411 +
59.412 + /* restore flags */
59.413 + if( fcntl( fd, F_SETFL, saveflags ) < 0) {
59.414 + g_warning( "[%s] Problems when trying to restore flags with fcntl.\n", __FUNCTION__ );
59.415 + *err=errno;
59.416 + return -1;
59.417 + }
59.418 +
59.419 + /* return unless the connection was successful or the connect is
59.420 + still in progress. */
59.421 + if( *err < 0 && back_err != EINPROGRESS) {
59.422 + g_warning( "[%s] Connection unsucessfully (it is not in progress).\n", __FUNCTION__ );
59.423 + *err = errno;
59.424 + return -1;
59.425 + }
59.426 +
59.427 + FD_ZERO( &fd_w );
59.428 + FD_SET( fd, &fd_w );
59.429 +
59.430 + *err = select( FD_SETSIZE, NULL, &fd_w, NULL, timeout);
59.431 + if ( *err < 0 ) {
59.432 + g_warning( "[%s] Connection unsucessfull (timed out).\n", __FUNCTION__ );
59.433 + *err=errno;
59.434 + return -1;
59.435 + }
59.436 +
59.437 + /* 0 means it timeout out & no fds changed */
59.438 + if(*err==0) {
59.439 + close(fd);
59.440 + *err=ETIMEDOUT;
59.441 + return -1;
59.442 + }
59.443 +
59.444 + /* Get the return code from the connect */
59.445 + len = sizeof( ret );
59.446 + *err=getsockopt( fd, SOL_SOCKET, SO_ERROR, &ret, (socklen_t *) &len);
59.447 +
59.448 + if( *err < 0 ) {
59.449 + g_warning( "[%s] Connection usnsucessfull.\n", __FUNCTION__ );
59.450 + *err=errno;
59.451 + return -1;
59.452 + }
59.453 +
59.454 + /* ret=0 means success, otherwise it contains the errno */
59.455 + if (ret) {
59.456 + *err=ret;
59.457 + return -1;
59.458 + }
59.459 +
59.460 + *err=0;
59.461 + return 0;
59.462 +}
59.463 +
59.464 +/** Connects to the backend.
59.465 + *
59.466 + * @param gmyth_socket The GMythSocket instance.
59.467 + * @param hostname The backend hostname or IP address.
59.468 + * @param port The backend port.
59.469 + * @return TRUE if success, FALSE if error.
59.470 + */
59.471 +
59.472 +
59.473 +gboolean
59.474 +gmyth_socket_connect (GMythSocket *gmyth_socket,
59.475 + const gchar *hostname, gint port)
59.476 +{
59.477 + return gmyth_socket_connect_with_timeout (gmyth_socket,
59.478 + hostname, port, 0);
59.479 +}
59.480 +
59.481 +gboolean
59.482 +gmyth_socket_connect_with_timeout (GMythSocket *gmyth_socket,
59.483 + const gchar *hostname, gint port, guint timeout)
59.484 +{
59.485 + struct addrinfo *addr_info_data = NULL, *addr_info0 = NULL;
59.486 + gint ret_code = -1;
59.487 + gint errno;
59.488 + gboolean ret = TRUE;
59.489 +
59.490 + gmyth_debug ("CONNECTING %s:%d", hostname, port);
59.491 +
59.492 + if ( hostname == NULL )
59.493 + gmyth_debug ( "Invalid hostname parameter!\n");
59.494 +
59.495 + /* store hostname and port number */
59.496 + if (gmyth_socket->hostname != NULL) {
59.497 + //g_free (gmyth_socket->hostname);
59.498 + gmyth_socket->hostname = NULL;
59.499 + }
59.500 +
59.501 + errno = gmyth_socket_toaddrinfo ( hostname, port, &addr_info_data );
59.502 +
59.503 + g_return_val_if_fail( addr_info_data != NULL && hostname != NULL, FALSE );
59.504 +
59.505 + gmyth_socket->hostname = g_strdup( hostname );
59.506 + gmyth_socket->port = port;
59.507 +
59.508 + for ( addr_info0 = addr_info_data; addr_info0; addr_info0 = addr_info_data->ai_next ) {
59.509 + /* init socket descriptor */
59.510 + gmyth_socket->sd = socket( addr_info0->ai_family, addr_info0->ai_socktype,
59.511 + addr_info0->ai_protocol );
59.512 +
59.513 + if ( gmyth_socket->sd < 0 )
59.514 + continue;
59.515 +
59.516 + struct timeval *timeout_val = g_new0 (struct timeval, 1);
59.517 + if (timeout != 0) {
59.518 + /*timeout_val = g_new0 (struct timeval, 1);*/
59.519 +
59.520 + timeout_val->tv_sec = timeout;
59.521 + timeout_val->tv_usec = 0;
59.522 + } else {
59.523 + timeout_val->tv_sec = 5;
59.524 + timeout_val->tv_usec = 100;
59.525 + }
59.526 +
59.527 + if (gmyth_socket_try_connect (gmyth_socket->sd, (struct sockaddr *)addr_info0->ai_addr,
59.528 + addr_info0->ai_addrlen, timeout_val, &ret_code ) < 0 )
59.529 + {
59.530 + g_printerr( "[%s] Error connecting to backend!\n", __FUNCTION__ );
59.531 + if (ret_code == ETIMEDOUT)
59.532 + g_printerr( "[%s]\tBackend host unreachable!\n", __FUNCTION__ );
59.533 +
59.534 + close (gmyth_socket->sd);
59.535 + gmyth_socket->sd = -1;
59.536 + g_printerr ("ERROR: %s\n", gai_strerror(ret_code));
59.537 + g_free (timeout_val);
59.538 + continue;
59.539 + }
59.540 +
59.541 + g_free (timeout_val);
59.542 +
59.543 + /* only will be reached if none of the error above occurred */
59.544 + break;
59.545 + }
59.546 +
59.547 + freeaddrinfo (addr_info_data);
59.548 + addr_info_data = NULL;
59.549 +
59.550 + if (gmyth_socket->sd_io_ch != NULL) {
59.551 + g_io_channel_unref (gmyth_socket->sd_io_ch);
59.552 + gmyth_socket->sd_io_ch = NULL;
59.553 + }
59.554 +
59.555 + gmyth_socket->sd_io_ch = g_io_channel_unix_new (gmyth_socket->sd);
59.556 +
59.557 + //GIOFlags flags = g_io_channel_get_flags (gmyth_socket->sd_io_ch);
59.558 + /* unset the nonblock flag */
59.559 + //flags &= ~G_IO_FLAG_NONBLOCK;
59.560 + /* unset the nonblocking stuff for some time, because GNUTLS doesn't like
59.561 + * that */
59.562 + //g_io_channel_set_flags (gmyth_socket->sd_io_ch, flags, NULL);
59.563 +
59.564 + ret = ( ret_code == 0 ) ? TRUE : FALSE ;
59.565 + return ret;
59.566 +}
59.567 +
59.568 +/** Gets the GIOChannel associated to the given GMythSocket.
59.569 + *
59.570 + * @param gmyth_socket The GMythSocket instance.
59.571 + */
59.572 +GIOChannel *
59.573 +gmyth_socket_get_io_channel( GMythSocket *gmyth_socket )
59.574 +{
59.575 + g_return_val_if_fail( gmyth_socket != NULL, NULL );
59.576 +
59.577 + return gmyth_socket->sd_io_ch;
59.578 +}
59.579 +
59.580 +/** Verifies if the socket is able to read.
59.581 + *
59.582 + * @param gmyth_socket The GMythSocket instance.
59.583 + * @return TRUE if the socket is able to read, FALSE if not.
59.584 + */
59.585 +gboolean
59.586 +gmyth_socket_is_able_to_read( GMythSocket *gmyth_socket )
59.587 +{
59.588 + gboolean ret = TRUE;
59.589 +
59.590 + /* verify if the input (read) buffer is ready to receive data */
59.591 + GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
59.592 +
59.593 + if ( ( io_cond & G_IO_IN ) == 0 ) {
59.594 + g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
59.595 + ret = FALSE;
59.596 + }
59.597 +
59.598 + return ret;
59.599 +
59.600 +}
59.601 +
59.602 +/** Verifies if the socket is able to write.
59.603 + *
59.604 + * @param gmyth_socket The GMythSocket instance.
59.605 + * @return TRUE if the socket is able to write, FALSE if not.
59.606 + */
59.607 +gboolean
59.608 +gmyth_socket_is_able_to_write( GMythSocket *gmyth_socket )
59.609 +{
59.610 + gboolean ret = TRUE;
59.611 +
59.612 + /* verify if the input (read) buffer is ready to receive data */
59.613 + GIOCondition io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
59.614 +
59.615 + if ( ( ( io_cond & G_IO_OUT ) == 0 ) || ( ( io_cond & G_IO_HUP ) == 0 ) ) {
59.616 + g_warning ("[%s] IO channel is not able to send data!\n", __FUNCTION__);
59.617 + ret = FALSE;
59.618 + }
59.619 +
59.620 + return ret;
59.621 +
59.622 +}
59.623 +
59.624 +/** Sends a command to the backend.
59.625 + *
59.626 + * @param gmyth_socket the GMythSocket instance.
59.627 + * @param command The string command to be sent.
59.628 + */
59.629 +gboolean
59.630 +gmyth_socket_send_command(GMythSocket *gmyth_socket, GString *command)
59.631 +{
59.632 + gboolean ret = TRUE;
59.633 +
59.634 + GIOStatus io_status = G_IO_STATUS_NORMAL;
59.635 + //GIOCondition io_cond;
59.636 + GError* error = NULL;
59.637 +
59.638 +
59.639 + gchar *buffer = NULL;
59.640 +
59.641 + gsize bytes_written = 0;
59.642 +
59.643 + if( command == NULL || ( command->len <= 0 ) || command->str == NULL ) {
59.644 + g_warning ("[%s] Invalid NULL command parameter!\n", __FUNCTION__);
59.645 + ret = FALSE;
59.646 + goto done;
59.647 + }
59.648 +
59.649 + //g_static_mutex_lock( &mutex );
59.650 + gmyth_debug ("Sending command to backend: %s\n", command->str);
59.651 +
59.652 + buffer = g_strnfill( BUFLEN, ' ' );
59.653 + g_snprintf( buffer, MYTH_PROTOCOL_FIELD_SIZE+1, "%-8d", command->len);
59.654 +
59.655 + command = g_string_prepend(command, buffer);
59.656 +
59.657 + /* write bytes to socket */
59.658 + io_status = g_io_channel_write_chars( gmyth_socket->sd_io_ch, command->str,
59.659 + command->len, &bytes_written, &error );
59.660 +
59.661 +
59.662 + if( (io_status == G_IO_STATUS_ERROR) || ( bytes_written <= 0 ) ) {
59.663 + g_warning ("[%s] Error while writing to socket", __FUNCTION__);
59.664 + ret = FALSE;
59.665 + } else if ( bytes_written < command->len ) {
59.666 + g_warning ("[%s] Not all data was written socket", __FUNCTION__);
59.667 + ret = FALSE;
59.668 + }
59.669 +
59.670 + io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
59.671 +
59.672 + if ( ( bytes_written != command->len ) || ( io_status == G_IO_STATUS_ERROR ) )
59.673 + {
59.674 + g_warning ("[%s] Some problem occurred when sending data to the socket\n", __FUNCTION__);
59.675 +
59.676 + ret = TRUE;
59.677 + }
59.678 +
59.679 + //g_static_mutex_unlock( &mutex );
59.680 +done:
59.681 + if ( error != NULL ) {
59.682 + g_printerr( "[%s] Error found reading data from IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
59.683 + ret = FALSE;
59.684 + g_error_free( error );
59.685 + }
59.686 +
59.687 + if ( buffer!= NULL )
59.688 + g_free( buffer );
59.689 +
59.690 + return ret;
59.691 +}
59.692 +
59.693 +/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
59.694 + * supported by the backend and send the "ANN" command.
59.695 + *
59.696 + * @param gmyth_socket the GMythSocket instance.
59.697 + * @param hostname_backend The backend hostname or IP address.
59.698 + * @param port The backend port to connect.
59.699 + * @param blocking_client A flag to choose between blocking and non-blocking
59.700 + * @param with_events Sets the connection flag to receive events.
59.701 + * backend connection.
59.702 + */
59.703 +static gboolean
59.704 +gmyth_socket_connect_to_backend_and_events (GMythSocket *gmyth_socket,
59.705 + const gchar *hostname_backend, gint port, gboolean blocking_client,
59.706 + gboolean with_events)
59.707 +{
59.708 + if (!gmyth_socket_connect (gmyth_socket, hostname_backend, port)) {
59.709 + g_warning ("[%s] Could not open socket to backend machine [%s]\n", __FUNCTION__,
59.710 + hostname_backend );
59.711 + return FALSE;
59.712 + }
59.713 +
59.714 + if ( gmyth_socket_check_protocol_version (gmyth_socket) ) {
59.715 +
59.716 + GString *result;
59.717 + GString *base_str = g_string_new("");
59.718 + GString *hostname = NULL;
59.719 +
59.720 + hostname = gmyth_socket_get_local_hostname();
59.721 + if (hostname == NULL) {
59.722 + g_debug ("Hostname not available, setting to n800frontend\n");
59.723 + hostname = g_strdup ("n800frontend");
59.724 + }
59.725 +
59.726 + g_string_printf(base_str, "ANN %s %s %u",
59.727 + (blocking_client ? "Playback" : "Monitor"),
59.728 + hostname->str, with_events);
59.729 +
59.730 + gmyth_socket_send_command (gmyth_socket, base_str);
59.731 + result = gmyth_socket_receive_response (gmyth_socket);
59.732 +
59.733 + if (result != NULL) {
59.734 + gmyth_debug ("Response received from backend: %s", result->str);
59.735 + g_string_free (result, TRUE);
59.736 + }
59.737 +
59.738 + g_string_free (hostname, TRUE);
59.739 + g_string_free (base_str, TRUE);
59.740 +
59.741 + return TRUE;
59.742 + } else {
59.743 + g_warning ("[%s] GMythSocket could not connect to the backend", __FUNCTION__);
59.744 + return FALSE;
59.745 + }
59.746 +}
59.747 +
59.748 +/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
59.749 + * supported by the backend and send the "ANN" command.
59.750 + *
59.751 + * @param gmyth_socket the GMythSocket instance.
59.752 + * @param hostname_backend The backend hostname or IP address.
59.753 + * @param port The backend port to connect.
59.754 + * @param blocking_client A flag to choose between blocking and non-blocking
59.755 + */
59.756 +gboolean
59.757 +gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket,
59.758 + const gchar *hostname_backend, gint port, gboolean blocking_client)
59.759 +{
59.760 + if (!gmyth_socket_connect_to_backend_and_events ( gmyth_socket, hostname_backend, port,
59.761 + blocking_client, FALSE) ) {
59.762 + gmyth_debug ("Could not open socket to backend machine [%s]\n",
59.763 + hostname_backend );
59.764 + return FALSE;
59.765 + }
59.766 +
59.767 + return TRUE;
59.768 +
59.769 +}
59.770 +
59.771 +/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
59.772 + * supported by the backend and send the "ANN" command.
59.773 + *
59.774 + * @param gmyth_socket the GMythSocket instance.
59.775 + * @param hostname_backend The backend hostname or IP address.
59.776 + * @param port The backend port to connect.
59.777 + * @param blocking_client A flag to choose between blocking and non-blocking
59.778 + */
59.779 +gboolean
59.780 +gmyth_socket_connect_to_backend_events (GMythSocket *gmyth_socket,
59.781 + const gchar *hostname_backend, gint port, gboolean blocking_client)
59.782 +{
59.783 + if (!gmyth_socket_connect_to_backend_and_events ( gmyth_socket, hostname_backend, port,
59.784 + blocking_client, TRUE) ) {
59.785 + gmyth_debug ("Could not open socket to backend machine in order to receive events [%s]\n",
59.786 + hostname_backend );
59.787 + return FALSE;
59.788 + }
59.789 +
59.790 + return TRUE;
59.791 +}
59.792 +
59.793 +/** Closes the socket connection to the backend.
59.794 + *
59.795 + * @param gmyth_socket The GMythSocket instance.
59.796 + */
59.797 +void
59.798 +gmyth_socket_close_connection (GMythSocket *gmyth_socket)
59.799 +{
59.800 + close (gmyth_socket->sd);
59.801 + gmyth_socket->sd = -1;
59.802 +
59.803 + if (gmyth_socket->sd_io_ch != NULL) {
59.804 + g_io_channel_unref (gmyth_socket->sd_io_ch);
59.805 + gmyth_socket->sd_io_ch = NULL;
59.806 + }
59.807 +}
59.808 +
59.809 +
59.810 +/** Try the MythTV version numbers, and get the version returned by
59.811 + * the possible REJECT message, in order to contruct a new
59.812 + * MythTV version request.
59.813 + *
59.814 + * @param gmyth_socket The GMythSocket instance.
59.815 + * @param mythtv_version The Mythtv protocol version to be tested
59.816 + *
59.817 + * @return The actual MythTV the client is connected to.
59.818 + */
59.819 +gint
59.820 +gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket, gint mythtv_version)
59.821 +{
59.822 + GString *response = NULL;
59.823 + GString *payload = NULL;
59.824 + gboolean res = TRUE;
59.825 + gint mythtv_new_version = MYTHTV_CANNOT_NEGOTIATE_VERSION;
59.826 + guint max_iterations = MYTHTV_MAX_VERSION_CHECKS;
59.827 +
59.828 +try_new_version:
59.829 + payload = g_string_new ("MYTH_PROTO_VERSION");
59.830 + g_string_append_printf( payload, " %d", mythtv_version );
59.831 +
59.832 + gmyth_socket_send_command(gmyth_socket, payload);
59.833 + response = gmyth_socket_receive_response(gmyth_socket);
59.834 +
59.835 + if (response == NULL) {
59.836 + g_warning ("[%s] Check protocol version error! Not answered!", __FUNCTION__);
59.837 + res = FALSE;
59.838 + goto done;
59.839 + }
59.840 +
59.841 + res = g_str_has_prefix (response->str, "ACCEPT");
59.842 + if (!res) {
59.843 + g_warning ("[%s] Protocol version request error: %s", __FUNCTION__, response->str);
59.844 + /* get the version number returned by the REJECT message */
59.845 + if ( ( res = g_str_has_prefix (response->str, "REJECT") ) == TRUE ) {
59.846 + gchar *new_version = NULL;
59.847 + new_version = g_strrstr( response->str, "]" );
59.848 + if (new_version!=NULL) {
59.849 + ++new_version; /* skip ']' character */
59.850 + if ( new_version != NULL ) {
59.851 + gmyth_debug ( "[%s] got MythTV version = %s.\n", __FUNCTION__, new_version );
59.852 + mythtv_version = (gint)g_ascii_strtoull (new_version, NULL, 10 );
59.853 + /* do reconnection to the socket (socket is closed if the MythTV version was wrong) */
59.854 + gmyth_socket_connect( gmyth_socket, gmyth_socket->hostname, gmyth_socket->port );
59.855 + new_version =NULL;
59.856 + if ( --max_iterations > 0 )
59.857 + goto try_new_version;
59.858 + else
59.859 + goto done;
59.860 + }
59.861 + }
59.862 + }
59.863 + }
59.864 +
59.865 + /* change the return value to a valid one */
59.866 + if ( res ) {
59.867 + mythtv_new_version = mythtv_version;
59.868 + gmyth_socket->mythtv_version = mythtv_new_version;
59.869 + }
59.870 +
59.871 +done:
59.872 + if ( payload != NULL )
59.873 + g_string_free (payload, TRUE);
59.874 + if ( response != NULL )
59.875 + g_string_free (response, TRUE);
59.876 +
59.877 + return mythtv_new_version;
59.878 +}
59.879 +
59.880 +/** Verifies if the Mythtv backend supported the GMyth supported version.
59.881 + *
59.882 + * @param gmyth_socket The GMythSocket instance.
59.883 + * @return TRUE if supports, FALSE if not.
59.884 + */
59.885 +gboolean
59.886 +gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket)
59.887 +{
59.888 + return ( ( gmyth_socket->mythtv_version =
59.889 + gmyth_socket_check_protocol_version_number ( gmyth_socket,
59.890 + MYTHTV_VERSION_DEFAULT ) ) != MYTHTV_CANNOT_NEGOTIATE_VERSION );
59.891 +}
59.892 +
59.893 +/** Returns the Mythtv backend supported version.
59.894 + *
59.895 + * @param gmyth_socket The GMythSocket instance.
59.896 + * @return The actual MythTV version number.
59.897 + */
59.898 +gint
59.899 +gmyth_socket_get_protocol_version (GMythSocket *gmyth_socket)
59.900 +{
59.901 + return gmyth_socket->mythtv_version;
59.902 +}
59.903 +
59.904 +/** Receives a backend answer after a gmyth_socket_send_command_call ().
59.905 + *
59.906 + * @param gmyth_socket The GMythSocket instance.
59.907 + * @return The response received, or NULL if error or nothing was received.
59.908 + */
59.909 +GString*
59.910 +gmyth_socket_receive_response(GMythSocket *gmyth_socket)
59.911 +{
59.912 + GIOStatus io_status = G_IO_STATUS_NORMAL;
59.913 + GError* error = NULL;
59.914 + gchar *buffer;
59.915 +
59.916 + GString *str = NULL;
59.917 +
59.918 + gsize bytes_read = 0;
59.919 + gint len = 0;
59.920 + GIOCondition io_cond = g_io_channel_get_buffer_condition (gmyth_socket->sd_io_ch);
59.921 +
59.922 + g_return_val_if_fail( gmyth_socket != NULL, NULL );
59.923 +
59.924 + /* verify if the input (read) buffer is ready to receive data */
59.925 +
59.926 + //g_static_mutex_lock( &mutex );
59.927 +
59.928 + //buffer = g_new0 (gchar, MYTH_PROTOCOL_FIELD_SIZE);
59.929 + buffer = g_strnfill (MYTH_PROTOCOL_FIELD_SIZE, ' ');
59.930 + io_status = g_io_channel_read_chars (gmyth_socket->sd_io_ch, buffer, MYTH_PROTOCOL_FIELD_SIZE, &bytes_read, &error);
59.931 +
59.932 + /* verify if the input (read) buffer is ready to receive data */
59.933 + io_cond = g_io_channel_get_buffer_condition (gmyth_socket->sd_io_ch);
59.934 +
59.935 + gmyth_debug ( "[%s] Bytes read = %d\n", __FUNCTION__, bytes_read );
59.936 +
59.937 + if( (io_status == G_IO_STATUS_ERROR) || (bytes_read <= 0) ) {
59.938 + g_warning ("[%s] Error in mythprotocol response from backend\n", __FUNCTION__);
59.939 + str = NULL;
59.940 + //return NULL;
59.941 + } else {
59.942 +
59.943 + io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
59.944 + /* verify if the input (read) buffer is ready to receive data */
59.945 + io_cond = g_io_channel_get_buffer_condition( gmyth_socket->sd_io_ch );
59.946 +
59.947 + //if ( ( io_cond & G_IO_IN ) != 0 ) {
59.948 + //gchar *buffer_aux = NULL;
59.949 +
59.950 + /* removes trailing whitespace */
59.951 + //buffer_aux = g_strstrip (buffer);
59.952 + len = (gint)g_ascii_strtoull ( g_strstrip (buffer), NULL, 10 );
59.953 +
59.954 + if (buffer != NULL) {
59.955 + g_free (buffer);
59.956 + buffer = NULL;
59.957 + }
59.958 +
59.959 + /*
59.960 + if (buffer_aux != NULL) {
59.961 + g_free (buffer_aux);
59.962 + buffer_aux = NULL;
59.963 + }
59.964 + */
59.965 +
59.966 + buffer = g_new0 (gchar, len+1);
59.967 +
59.968 + bytes_read = 0;
59.969 + io_status = g_io_channel_read_chars( gmyth_socket->sd_io_ch, buffer, len, &bytes_read, &error);
59.970 + buffer[bytes_read] = '\0';
59.971 + //}
59.972 + }
59.973 +
59.974 + //g_static_mutex_unlock( &mutex );
59.975 +
59.976 + gmyth_debug ("Response received from backend: {%s}\n", buffer);
59.977 +
59.978 + if ( ( bytes_read != len ) || ( io_status == G_IO_STATUS_ERROR ) )
59.979 + str = NULL;
59.980 + else
59.981 + str = g_string_new (buffer);
59.982 +
59.983 + if ( error != NULL ) {
59.984 + g_printerr( "[%s] Error found receiving response from the IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
59.985 + str = NULL;
59.986 + g_error_free (error);
59.987 + }
59.988 +
59.989 + g_free (buffer);
59.990 + return str;
59.991 +}
59.992 +
59.993 +/** Format a Mythtv command from the str_list entries and send it to backend.
59.994 + *
59.995 + * @param gmyth_socket The GMythSocket instance.
59.996 + * @param str_list The string list to form the command
59.997 + * @return TRUE if command was sent, FALSE if any error happens.
59.998 + */
59.999 +gboolean
59.1000 +gmyth_socket_write_stringlist(GMythSocket *gmyth_socket, GMythStringList* str_list)
59.1001 +{
59.1002 +
59.1003 + GList *tmp_list = NULL;
59.1004 + GPtrArray *ptr_array = NULL;
59.1005 + gchar *str_array = NULL;
59.1006 +
59.1007 + g_static_mutex_lock( &mutex );
59.1008 +
59.1009 + ptr_array = g_ptr_array_sized_new (g_list_length(str_list->glist));
59.1010 +
59.1011 + // FIXME: change this implementation!
59.1012 + tmp_list = str_list->glist;
59.1013 + for(; tmp_list; tmp_list = tmp_list->next) {
59.1014 + if ( tmp_list->data != NULL ) {
59.1015 + g_ptr_array_add(ptr_array, ((GString*)tmp_list->data)->str);
59.1016 + } else {
59.1017 + g_ptr_array_add (ptr_array, "");
59.1018 + }
59.1019 + }
59.1020 + g_ptr_array_add(ptr_array, NULL); // g_str_joinv() needs a NULL terminated string
59.1021 +
59.1022 + str_array = g_strjoinv (MYTH_SEPARATOR, (gchar **) (ptr_array->pdata));
59.1023 +
59.1024 + g_static_mutex_unlock( &mutex );
59.1025 +
59.1026 + gmyth_debug ( "[%s] Sending socket request: %s\n", __FUNCTION__, str_array );
59.1027 +
59.1028 + // Sends message to backend
59.1029 + // TODO: implement looping to send remaining data, and add timeout testing!
59.1030 + GString *command = g_string_new(str_array);
59.1031 + gmyth_socket_send_command(gmyth_socket, command);
59.1032 + g_string_free (command, TRUE);
59.1033 +
59.1034 + g_free (str_array);
59.1035 + g_ptr_array_free (ptr_array, TRUE);
59.1036 +
59.1037 + return TRUE;
59.1038 +}
59.1039 +
59.1040 +/* Receives a backend command response and split it into the given string list.
59.1041 + *
59.1042 + * @param gmyth_socket The GMythSocket instance.
59.1043 + * @param str_list the string list to be filled.
59.1044 + * @return The number of received strings.
59.1045 + */
59.1046 +gint
59.1047 +gmyth_socket_read_stringlist (GMythSocket *gmyth_socket, GMythStringList* str_list)
59.1048 +{
59.1049 + GString *response;
59.1050 + gchar **str_array;
59.1051 + gint i;
59.1052 +
59.1053 + response = gmyth_socket_receive_response(gmyth_socket);
59.1054 + g_static_mutex_lock( &mutex );
59.1055 +
59.1056 + gmyth_string_list_clear_all (str_list);
59.1057 + str_array = g_strsplit (response->str, MYTH_SEPARATOR, -1);
59.1058 +
59.1059 + for (i=0; i< g_strv_length (str_array); i++) {
59.1060 + gmyth_string_list_append_char_array (str_list, str_array[i] );
59.1061 + }
59.1062 + g_static_mutex_unlock( &mutex );
59.1063 +
59.1064 + g_string_free (response, TRUE);
59.1065 + g_strfreev (str_array);
59.1066 +
59.1067 + return gmyth_string_list_length (str_list);
59.1068 +}
59.1069 +
59.1070 +/** Formats a Mythtv protocol command based on str_list and sends it to
59.1071 + * the connected backend. The backend response is overwritten into str_list.
59.1072 + *
59.1073 + * @param gmyth_socket The GMythSocket instance.
59.1074 + * @param str_list The string list to be sent, and on which the answer
59.1075 + * will be written.
59.1076 + * @return TRUE if command was sent and an answer was received, FALSE if any
59.1077 + * error happens.
59.1078 + */
59.1079 +gint
59.1080 +gmyth_socket_sendreceive_stringlist (GMythSocket *gmyth_socket, GMythStringList *str_list)
59.1081 +{
59.1082 + gmyth_socket_write_stringlist (gmyth_socket, str_list);
59.1083 +
59.1084 + return gmyth_socket_read_stringlist (gmyth_socket, str_list);
59.1085 +}
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/branches/gmyth-0.1b/src/gmyth_socket.h Thu Feb 01 18:42:01 2007 +0000
60.3 @@ -0,0 +1,130 @@
60.4 +/**
60.5 + * GMyth Library
60.6 + *
60.7 + * @file gmyth/gmyth_socket.h
60.8 + *
60.9 + * @brief <p> MythTV socket implementation, according to the MythTV Project
60.10 + * (www.mythtv.org).
60.11 + *
60.12 + * This component provides basic socket functionalities to interact with
60.13 + * the Mythtv backend.
60.14 + * <p>
60.15 + *
60.16 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
60.17 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
60.18 + *
60.19 + *//*
60.20 + *
60.21 + * This program is free software; you can redistribute it and/or modify
60.22 + * it under the terms of the GNU Lesser General Public License as published by
60.23 + * the Free Software Foundation; either version 2 of the License, or
60.24 + * (at your option) any later version.
60.25 + *
60.26 + * This program is distributed in the hope that it will be useful,
60.27 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
60.28 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60.29 + * GNU General Public License for more details.
60.30 + *
60.31 + * You should have received a copy of the GNU Lesser General Public License
60.32 + * along with this program; if not, write to the Free Software
60.33 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
60.34 + */
60.35 +
60.36 +#ifndef __GMYTH_SOCKET_H__
60.37 +#define __GMYTH_SOCKET_H__
60.38 +
60.39 +#include <glib-object.h>
60.40 +
60.41 +#include <string.h>
60.42 +#include <netdb.h>
60.43 +#include <sys/socket.h>
60.44 +#include <unistd.h>
60.45 +#include <glib.h>
60.46 +
60.47 +#include "gmyth_stringlist.h"
60.48 +
60.49 +G_BEGIN_DECLS
60.50 +
60.51 +#define GMYTH_SOCKET_TYPE (gmyth_socket_get_type ())
60.52 +#define GMYTH_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE, GMythSocket))
60.53 +#define GMYTH_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE, GMythSocketClass))
60.54 +#define IS_GMYTH_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE))
60.55 +#define IS_GMYTH_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE))
60.56 +#define GMYTH_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SOCKET_TYPE, GMythSocketClass))
60.57 +
60.58 +
60.59 +typedef struct _GMythSocket GMythSocket;
60.60 +typedef struct _GMythSocketClass GMythSocketClass;
60.61 +
60.62 +struct _GMythSocketClass
60.63 +{
60.64 + GObjectClass parent_class;
60.65 +
60.66 + /* callbacks */
60.67 + /* no one for now */
60.68 +};
60.69 +
60.70 +struct _GMythSocket
60.71 +{
60.72 + GObject parent;
60.73 +
60.74 + /* socket descriptor */
60.75 + gint sd;
60.76 + GIOChannel *sd_io_ch;
60.77 +
60.78 + gchar *hostname;
60.79 + gint port;
60.80 + gint mythtv_version;
60.81 +};
60.82 +
60.83 +/* used when no protocol version number was negotiated */
60.84 +#define MYTHTV_CANNOT_NEGOTIATE_VERSION 0
60.85 +
60.86 +GType gmyth_socket_get_type (void);
60.87 +
60.88 +GMythSocket * gmyth_socket_new ();
60.89 +
60.90 +gboolean gmyth_socket_connect (GMythSocket *gmyth_socket, const gchar *hostname, gint port);
60.91 +
60.92 +
60.93 +GIOChannel * gmyth_socket_get_io_channel (GMythSocket *gmyth_socket );
60.94 +
60.95 +gboolean gmyth_socket_is_able_to_read (GMythSocket *gmyth_socket );
60.96 +gboolean gmyth_socket_is_able_to_write (GMythSocket *gmyth_socket );
60.97 +
60.98 +gboolean gmyth_socket_send_command (GMythSocket *gmyth_socket,
60.99 + GString *command);
60.100 +GString * gmyth_socket_receive_response (GMythSocket *gmyth_socket);
60.101 +gint gmyth_socket_sendreceive_stringlist (GMythSocket *gmyth_socket,
60.102 + GMythStringList *str_list);
60.103 +
60.104 +gboolean gmyth_socket_connect (GMythSocket *gmyth_socket,
60.105 + const gchar *hostname, gint port);
60.106 +gboolean gmyth_socket_connect_with_timeout (GMythSocket *gmyth_socket,
60.107 + const gchar *hostname, gint port, guint timeout);
60.108 +
60.109 +gboolean gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket,
60.110 + const gchar *hostname_backend, gint port,
60.111 + gboolean blocking_client);
60.112 +
60.113 +gboolean gmyth_socket_connect_to_backend_events (GMythSocket *gmyth_socket,
60.114 + const gchar *hostname_backend, gint port,
60.115 + gboolean blocking_client);
60.116 +
60.117 +GString * gmyth_socket_get_local_hostname (void);
60.118 +
60.119 +void gmyth_socket_close_connection (GMythSocket *gmyth_socket);
60.120 +
60.121 +gboolean gmyth_socket_check_protocol_version (GMythSocket *gmyth_socket);
60.122 +gint gmyth_socket_check_protocol_version_number (GMythSocket *gmyth_socket,
60.123 + gint mythtv_version);
60.124 +
60.125 +gint gmyth_socket_get_protocol_version (GMythSocket *gmyth_socket);
60.126 +
60.127 +gboolean gmyth_socket_write_stringlist(GMythSocket *gmyth_socket,
60.128 + GMythStringList* str_list);
60.129 +gint gmyth_socket_read_stringlist(GMythSocket *gmyth_socket,
60.130 + GMythStringList* str_list);
60.131 +G_END_DECLS
60.132 +
60.133 +#endif /* __GMYTH_SOCKET_H__ */
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61.2 +++ b/branches/gmyth-0.1b/src/gmyth_stringlist.c Thu Feb 01 18:42:01 2007 +0000
61.3 @@ -0,0 +1,390 @@
61.4 +/**
61.5 + * GMyth Library
61.6 + *
61.7 + * @file gmyth/gmyth_stringlist.c
61.8 + *
61.9 + * @brief <p> This component contains functions for dealing with the stringlist
61.10 + * format of the mythprotocol.
61.11 + *
61.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
61.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
61.14 + *
61.15 + *//*
61.16 + *
61.17 + * This program is free software; you can redistribute it and/or modify
61.18 + * it under the terms of the GNU Lesser General Public License as published by
61.19 + * the Free Software Foundation; either version 2 of the License, or
61.20 + * (at your option) any later version.
61.21 + *
61.22 + * This program is distributed in the hope that it will be useful,
61.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
61.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
61.25 + * GNU General Public License for more details.
61.26 + *
61.27 + * You should have received a copy of the GNU Lesser General Public License
61.28 + * along with this program; if not, write to the Free Software
61.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
61.30 + */
61.31 +
61.32 +#ifdef HAVE_CONFIG_H
61.33 +#include "config.h"
61.34 +#endif
61.35 +
61.36 +#include "gmyth_stringlist.h"
61.37 +
61.38 +#include "gmyth_debug.h"
61.39 +
61.40 +static void gmyth_string_list_class_init (GMythStringListClass *klass);
61.41 +static void gmyth_string_list_init (GMythStringList *object);
61.42 +
61.43 +static void gmyth_string_list_dispose (GObject *object);
61.44 +static void gmyth_string_list_finalize (GObject *object);
61.45 +
61.46 +G_DEFINE_TYPE(GMythStringList, gmyth_string_list, G_TYPE_OBJECT)
61.47 +
61.48 +static void
61.49 +gmyth_string_list_class_init (GMythStringListClass *klass)
61.50 +{
61.51 + GObjectClass *gobject_class;
61.52 +
61.53 + gobject_class = (GObjectClass *) klass;
61.54 +
61.55 + gobject_class->dispose = gmyth_string_list_dispose;
61.56 + gobject_class->finalize = gmyth_string_list_finalize;
61.57 +}
61.58 +
61.59 +static void
61.60 +gmyth_string_list_init (GMythStringList *gmyth_string_list)
61.61 +{
61.62 + gmyth_string_list->glist = NULL;
61.63 +}
61.64 +
61.65 +static void
61.66 +gmyth_string_list_dispose (GObject *object)
61.67 +{
61.68 + GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
61.69 +
61.70 + if (gmyth_string_list->glist)
61.71 + gmyth_string_list_clear_all(gmyth_string_list);
61.72 +
61.73 + G_OBJECT_CLASS (gmyth_string_list_parent_class)->dispose (object);
61.74 +}
61.75 +
61.76 +static void
61.77 +gmyth_string_list_finalize (GObject *object)
61.78 +{
61.79 + //GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
61.80 +
61.81 + g_signal_handlers_destroy (object);
61.82 +
61.83 + G_OBJECT_CLASS (gmyth_string_list_parent_class)->finalize (object);
61.84 +}
61.85 +
61.86 +/** Creates a new instance of GStringList.
61.87 + *
61.88 + * @return a new instance of GStringList.
61.89 + */
61.90 +GMythStringList *
61.91 +gmyth_string_list_new ()
61.92 +{
61.93 + GMythStringList *gmyth_string_list = GMYTH_STRING_LIST (g_object_new (GMYTH_STRING_LIST_TYPE, NULL));
61.94 + return gmyth_string_list;
61.95 +}
61.96 +
61.97 +/** Appends a guint64 to the string list.
61.98 + *
61.99 + * @param strlist The GMythStringList instance.
61.100 + * @param value The guint64 to be appended.
61.101 + *
61.102 + * @return The appended guint64 converted to a GString object.
61.103 + */
61.104 +GString*
61.105 +gmyth_string_list_append_int ( GMythStringList *strlist, const gint value )
61.106 +{
61.107 + GString *tmp_str = g_string_new ("");
61.108 +
61.109 + g_string_printf (tmp_str, "%d", value);
61.110 +
61.111 + gmyth_string_list_append_string (strlist, tmp_str);
61.112 +
61.113 + return tmp_str;
61.114 +}
61.115 +
61.116 +/** Appends a guint64 to the string list.
61.117 + *
61.118 + * @param strlist The GMythStringList instance.
61.119 + * @param value The guint64 to be appended.
61.120 + *
61.121 + * @return The appended guint64 converted to a GString object.
61.122 + */
61.123 +GString*
61.124 +gmyth_string_list_append_uint64 ( GMythStringList *strlist, const guint64 value)
61.125 +{
61.126 + GString *tmp_str1 = g_string_new ("");
61.127 + GString *tmp_str2 = g_string_new ("");
61.128 + gmyth_debug ( "value = %llu.\n", value);
61.129 +
61.130 + gulong l2 = ( (guint64)value & 0xffffffff );
61.131 + gulong l1 = ( (guint64)value >> 32 );
61.132 +
61.133 + /* high order part of guint64 value */
61.134 + g_string_printf (tmp_str1, "%lu", l1);
61.135 +
61.136 + gmyth_debug( "[%s] uint64 (high) = %s\n", __FUNCTION__, tmp_str1->str );
61.137 +
61.138 + //gmyth_string_list_append_string (strlist, tmp_str1);
61.139 + strlist->glist = g_list_append( strlist->glist, tmp_str1 );
61.140 +
61.141 + /* low order part of guint64 value */
61.142 + g_string_printf (tmp_str2, "%lu", l2);
61.143 +
61.144 + gmyth_debug( "[%s] uint64 (low) = %s\n", __FUNCTION__, tmp_str2->str );
61.145 +
61.146 + strlist->glist = g_list_append( strlist->glist, tmp_str2 );
61.147 +
61.148 + //gmyth_string_list_append_string (strlist, tmp_str2);
61.149 +
61.150 + return tmp_str2;
61.151 +}
61.152 +
61.153 +/** Appends a gint64 to the string list.
61.154 + *
61.155 + * @param strlist The GMythStringList instance.
61.156 + * @param value The gint64 to be appended.
61.157 + *
61.158 + * @return The appended gint64 converted to a GString object.
61.159 + */
61.160 +GString*
61.161 +gmyth_string_list_append_int64 ( GMythStringList *strlist, const gint64 value)
61.162 +{
61.163 + GString *tmp_str1 = g_string_new ("");
61.164 + GString *tmp_str2 = g_string_new ("");
61.165 + gmyth_debug ( "value = %lld.\n", value );
61.166 +
61.167 + glong l2 = ( (gint64)value & 0xffffffff );
61.168 + glong l1 = ( (gint64)value >> 32 );
61.169 +
61.170 + /* high order part of gint64 value */
61.171 + g_string_printf (tmp_str1, "%ld", l1);
61.172 +
61.173 + gmyth_debug( "[%s] int64 (high) = %s\n", __FUNCTION__, tmp_str1->str );
61.174 +
61.175 + //gmyth_string_list_append_string (strlist, tmp_str1);
61.176 + strlist->glist = g_list_append( strlist->glist, tmp_str1 );
61.177 +
61.178 + /* low order part of gint64 value */
61.179 + g_string_printf (tmp_str2, "%ld", l2);
61.180 +
61.181 + gmyth_debug( "[%s] int64 (low) = %s\n", __FUNCTION__, tmp_str2->str );
61.182 +
61.183 + strlist->glist = g_list_append( strlist->glist, tmp_str2 );
61.184 +
61.185 + return tmp_str2;
61.186 +}
61.187 +
61.188 +/** Appends a char array to the string list.
61.189 + *
61.190 + * @param strlist The GMythStringList instance.
61.191 + * @param value The char array to be appended.
61.192 + *
61.193 + * @return The appended char array converted to a GString object.
61.194 + */
61.195 +GString*
61.196 +gmyth_string_list_append_char_array ( GMythStringList *strlist, const gchar* value )
61.197 +{
61.198 + GString *tmp_str = NULL;
61.199 +
61.200 + g_return_val_if_fail( strlist != NULL, NULL );
61.201 +
61.202 + tmp_str = g_string_new (value);
61.203 +
61.204 + g_return_val_if_fail( tmp_str != NULL, NULL );
61.205 +
61.206 + gmyth_string_list_append_string (strlist, tmp_str);
61.207 +
61.208 + return tmp_str;
61.209 +}
61.210 +
61.211 +/** Appends a string to the string list.
61.212 + *
61.213 + * @param strlist The GMythStringList instance.
61.214 + * @param value The string to be appended.
61.215 + *
61.216 + * @return The appended string itself.
61.217 + */
61.218 +GString*
61.219 +gmyth_string_list_append_string ( GMythStringList *strlist, GString *value )
61.220 +{
61.221 + g_return_val_if_fail( strlist != NULL, NULL );
61.222 +
61.223 + strlist->glist = g_list_append (strlist->glist, value);
61.224 +
61.225 + return value;
61.226 +}
61.227 +
61.228 +/** Gets an integer value from the string list at the given position.
61.229 + *
61.230 + * @param strlist The GMythStringList instance.
61.231 + * @param index the integer position in the list, starting with zero.
61.232 + * @return The integer value.
61.233 + */
61.234 +gint
61.235 +gmyth_string_list_get_int ( GMythStringList *strlist, const gint index )
61.236 +{
61.237 + //TODO: Create static method check_index()
61.238 + GString *tmp_str = NULL;
61.239 +
61.240 + g_return_val_if_fail( strlist != NULL, 0 );
61.241 +
61.242 + tmp_str = (GString *) g_list_nth_data (strlist->glist, index);
61.243 +
61.244 + g_return_val_if_fail( tmp_str != NULL && tmp_str->str != NULL, 0 );
61.245 +
61.246 + return (gint) ( /* 0x00000000ffffffffL & (gint64)*/g_ascii_strtoull ( tmp_str->str, NULL, 10 ) );
61.247 +}
61.248 +
61.249 +/** Gets a guint64 value from the string list at the given position.
61.250 + * According to the Mythtv protocol, the 64 bits value is formed by
61.251 + * two strings.
61.252 + *
61.253 + * @param strlist The GMythStringList instance.
61.254 + * @param index the index of the first string forming the 64 bits value.
61.255 + * Index starts with zero.
61.256 + * @return The guint64 value.
61.257 + */
61.258 +guint64
61.259 +gmyth_string_list_get_uint64 ( GMythStringList *strlist, const gint index )
61.260 +{
61.261 + //TODO: Create static method check_index()
61.262 + guint64 ret_value = 0;
61.263 + guint64 l2 = 0;
61.264 +
61.265 + g_return_val_if_fail( strlist != NULL, 0 );
61.266 +
61.267 + const GString *tmp_str1 = (GString *) g_list_nth_data (strlist->glist, index);
61.268 + const GString *tmp_str2 = (GString *) g_list_nth_data (strlist->glist, index+1);
61.269 +
61.270 + if ( tmp_str1 != NULL )
61.271 + gmyth_debug ( "[%s] seek high bytes = %s\n", __FUNCTION__, tmp_str1->str );
61.272 + if ( tmp_str2 == NULL || strlen( tmp_str2->str ) > 0 ) {
61.273 + } else {
61.274 + gmyth_debug ( "[%s] seek low bytes = %s\n", __FUNCTION__, tmp_str2->str );
61.275 + }
61.276 +
61.277 + guint64 l1 = ( (guint64)g_ascii_strtoull (tmp_str1->str, NULL, 10) /*& 0xffffffff*/ );
61.278 + if ( tmp_str2 != NULL && tmp_str2->str != NULL && strlen(tmp_str2->str) > 0 ) {
61.279 + l2 = ( (guint64)g_ascii_strtoull (tmp_str2->str, NULL, 10) /*& 0xffffffff*/ );
61.280 + } else {
61.281 + l2 = l1;
61.282 + l1 = 0;
61.283 + }
61.284 +
61.285 + gmyth_debug ( "[%s]\t[l1 == %llu, l2 == %llu]\n", __FUNCTION__, l1, l2 );
61.286 +
61.287 + ret_value = ((guint64)(l2) /*& 0xffffffff*/) | ((guint64)l1 << 32);
61.288 +
61.289 + gmyth_debug( "[%s] returning uint64 value = %llu\n", __FUNCTION__, ret_value );
61.290 +
61.291 + return ret_value;
61.292 +}
61.293 +
61.294 +/** Gets a gint64 value from the string list at the given position.
61.295 + * According to the Mythtv protocol, the 64 bits value is formed by
61.296 + * two strings.
61.297 + *
61.298 + * @param strlist The GMythStringList instance.
61.299 + * @param index the index of the first string forming the 64 bits value.
61.300 + * Index starts with zero.
61.301 + * @return The gint64 value.
61.302 + */
61.303 +gint64
61.304 +gmyth_string_list_get_int64 ( GMythStringList *strlist, const gint index )
61.305 +{
61.306 + //TODO: Create static method check_index()
61.307 + gint64 ret_value = 0;
61.308 + gint64 l2 = 0;
61.309 +
61.310 + g_return_val_if_fail( strlist != NULL, 0 );
61.311 +
61.312 + const GString *tmp_str1 = (GString *) g_list_nth_data (strlist->glist, index);
61.313 + const GString *tmp_str2 = (GString *) g_list_nth_data (strlist->glist, index+1);
61.314 +
61.315 + if ( tmp_str1 != NULL )
61.316 + gmyth_debug ( "[%s] seek high bytes = %s\n", __FUNCTION__, tmp_str1->str );
61.317 + if ( tmp_str2 == NULL || strlen( tmp_str2->str ) > 0 ) {
61.318 + } else {
61.319 + gmyth_debug ( "[%s] seek low bytes = %s\n", __FUNCTION__, tmp_str2->str );
61.320 + }
61.321 +
61.322 + gint64 l1 = ( (guint64)g_ascii_strtoull (tmp_str1->str, NULL, 10) /*& 0xffffffff*/ );
61.323 + if ( tmp_str2 != NULL && tmp_str2->str != NULL && strlen(tmp_str2->str) > 0 ) {
61.324 + l2 = ( (gint64)g_ascii_strtoull (tmp_str2->str, NULL, 10) /*& 0xffffffff*/ );
61.325 + } else {
61.326 + l2 = l1;
61.327 + l1 = 0;
61.328 + }
61.329 +
61.330 + gmyth_debug ( "[%s]\t[l1 == %lld, l2 == %lld]\n", __FUNCTION__, l1, l2 );
61.331 +
61.332 + ret_value = ((gint64)(l2) /*& 0xffffffff*/) | ((gint64)l1 << 32);
61.333 +
61.334 + gmyth_debug( "[%s] returning int64 value = %lld\n", __FUNCTION__, ret_value );
61.335 +
61.336 + return ret_value;
61.337 +}
61.338 +
61.339 +
61.340 +/** Gets a string from the string list at the given position.
61.341 + *
61.342 + * @param strlist The GMythStringList instance.
61.343 + * @param index the string position in the list, starting with zero.
61.344 + * @return A pointer to the string data.
61.345 + */
61.346 +GString*
61.347 +gmyth_string_list_get_string ( GMythStringList *strlist, const gint index )
61.348 +{
61.349 + if (!strlist || !(strlist->glist)) {
61.350 + g_warning ("%s received Null arguments", __FUNCTION__);
61.351 + return NULL;
61.352 + }
61.353 +
61.354 + return (GString *) g_list_nth_data (strlist->glist, index);
61.355 +}
61.356 +
61.357 +
61.358 +#if 0
61.359 +static void
61.360 +gmyth_string_list_clear_element( GString *str_elem, void *data_aux )
61.361 +{
61.362 + if ( str_elem != NULL ) {
61.363 + g_string_free( str_elem, TRUE );
61.364 + }
61.365 +}
61.366 +#endif
61.367 +
61.368 +/** Removes all strings from the string list.
61.369 + *
61.370 + * @param strlist The GMythStringList instance.
61.371 + */
61.372 +void
61.373 +gmyth_string_list_clear_all ( GMythStringList *strlist )
61.374 +{
61.375 + if ( strlist != NULL && strlist->glist ) {
61.376 + //g_list_foreach( strlist->glist, (GFunc)gmyth_string_list_clear_element, NULL );
61.377 + g_list_free (strlist->glist);
61.378 + strlist->glist = NULL;
61.379 + }
61.380 +}
61.381 +
61.382 +/** Retrieves the number of elements in the string list.
61.383 + *
61.384 + * @param strlist The GMythStringList instance.
61.385 + * @return the string list length.
61.386 + */
61.387 +gint
61.388 +gmyth_string_list_length ( GMythStringList *strlist )
61.389 +{
61.390 + g_return_val_if_fail( strlist != NULL && strlist->glist != NULL, 0 );
61.391 +
61.392 + return g_list_length (strlist->glist);
61.393 +}
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/branches/gmyth-0.1b/src/gmyth_stringlist.h Thu Feb 01 18:42:01 2007 +0000
62.3 @@ -0,0 +1,101 @@
62.4 +/**
62.5 + * GMyth Library
62.6 + *
62.7 + * @file gmyth/gmyth_stringlist.h
62.8 + *
62.9 + * @brief <p> This component contains functions for dealing with the stringlist
62.10 + * format of the mythprotocol.
62.11 + *
62.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
62.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
62.14 + *
62.15 + *//*
62.16 + *
62.17 + * This program is free software; you can redistribute it and/or modify
62.18 + * it under the terms of the GNU Lesser General Public License as published by
62.19 + * the Free Software Foundation; either version 2 of the License, or
62.20 + * (at your option) any later version.
62.21 + *
62.22 + * This program is distributed in the hope that it will be useful,
62.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
62.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
62.25 + * GNU General Public License for more details.
62.26 + *
62.27 + * You should have received a copy of the GNU Lesser General Public License
62.28 + * along with this program; if not, write to the Free Software
62.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
62.30 + */
62.31 +
62.32 +#ifndef GMYTH_STRING_LIST_H_
62.33 +#define GMYTH_STRING_LIST_H_
62.34 +
62.35 +#include <glib-object.h>
62.36 +
62.37 +#include <stdio.h>
62.38 +#include <stdlib.h>
62.39 +#include <string.h>
62.40 +#include <netdb.h>
62.41 +#include <sys/socket.h>
62.42 +#include <unistd.h>
62.43 +
62.44 +G_BEGIN_DECLS
62.45 +
62.46 +#define GMYTH_STRING_LIST_TYPE (gmyth_string_list_get_type ())
62.47 +#define GMYTH_STRING_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE, GMythStringList))
62.48 +#define GMYTH_STRING_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
62.49 +#define IS_GMYTH_STRING_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE))
62.50 +#define IS_GMYTH_STRING_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE))
62.51 +#define GMYTH_STRING_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
62.52 +
62.53 +
62.54 +typedef struct _GMythStringList GMythStringList;
62.55 +typedef struct _GMythStringListClass GMythStringListClass;
62.56 +
62.57 +struct _GMythStringListClass
62.58 +{
62.59 + GObjectClass parent_class;
62.60 +
62.61 + /* callbacks */
62.62 + /* no one for now */
62.63 +};
62.64 +
62.65 +struct _GMythStringList
62.66 +{
62.67 + GObject parent;
62.68 +
62.69 + /* string list */
62.70 + GList *glist;
62.71 +};
62.72 +
62.73 +
62.74 +GType gmyth_string_list_get_type (void);
62.75 +
62.76 +GMythStringList * gmyth_string_list_new (void);
62.77 +
62.78 +void gmyth_string_list_clear_all (GMythStringList *strlist);
62.79 +int gmyth_string_list_length (GMythStringList *strlist);
62.80 +
62.81 +GString * gmyth_string_list_append_int (GMythStringList *strlist,
62.82 + const gint value);
62.83 +GString * gmyth_string_list_append_uint64 (GMythStringList *strlist,
62.84 + const guint64 value);
62.85 +
62.86 +GString * gmyth_string_list_append_int64 (GMythStringList *strlist,
62.87 + const gint64 value);
62.88 +
62.89 +GString * gmyth_string_list_append_char_array (GMythStringList *strlist,
62.90 + const char* value);
62.91 +GString * gmyth_string_list_append_string (GMythStringList *strlist,
62.92 + GString *value);
62.93 +
62.94 +int gmyth_string_list_get_int (GMythStringList *strlist, const gint index);
62.95 +guint64 gmyth_string_list_get_uint64 (GMythStringList *strlist, const gint index);
62.96 +gint64 gmyth_string_list_get_int64 (GMythStringList *strlist, const gint index);
62.97 +GString * gmyth_string_list_get_string (GMythStringList *strlist, const gint index);
62.98 +
62.99 +#define gmyth_string_list_get_char_array(strlist, index) \
62.100 + (gmyth_string_list_get_string(strlist, index))->str
62.101 +
62.102 +G_END_DECLS
62.103 +
62.104 +#endif /*GMYTH_STRING_LIST_H_*/
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
63.2 +++ b/branches/gmyth-0.1b/src/gmyth_tvchain.c Thu Feb 01 18:42:01 2007 +0000
63.3 @@ -0,0 +1,390 @@
63.4 +/**
63.5 + * GMyth Library
63.6 + *
63.7 + * @file gmyth/gmyth_tvchain.c
63.8 + *
63.9 + * @brief <p> This component contains functions for creating and accessing
63.10 + * the tvchain functions for live tv playback.
63.11 + *
63.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
63.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
63.14 + *
63.15 + *//*
63.16 + *
63.17 + * This program is free software; you can redistribute it and/or modify
63.18 + * it under the terms of the GNU Lesser General Public License as published by
63.19 + * the Free Software Foundation; either version 2 of the License, or
63.20 + * (at your option) any later version.
63.21 + *
63.22 + * This program is distributed in the hope that it will be useful,
63.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
63.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63.25 + * GNU General Public License for more details.
63.26 + *
63.27 + * You should have received a copy of the GNU Lesser General Public License
63.28 + * along with this program; if not, write to the Free Software
63.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
63.30 + */
63.31 +
63.32 +#ifdef HAVE_CONFIG_H
63.33 +#include "config.h"
63.34 +#endif
63.35 +
63.36 +#include "gmyth_tvchain.h"
63.37 +
63.38 +#include <glib.h>
63.39 +#include <time.h>
63.40 +#include <stdio.h>
63.41 +#include <stdlib.h>
63.42 +#include <assert.h>
63.43 +
63.44 +#include "gmyth_epg.h"
63.45 +#include "gmyth_util.h"
63.46 +#include "gmyth_query.h"
63.47 +#include "gmyth_scheduler.h"
63.48 +#include "gmyth_debug.h"
63.49 +
63.50 +static void gmyth_tvchain_class_init (GMythTVChainClass *klass);
63.51 +static void gmyth_tvchain_init (GMythTVChain *object);
63.52 +
63.53 +static void gmyth_tvchain_dispose (GObject *object);
63.54 +static void gmyth_tvchain_finalize (GObject *object);
63.55 +
63.56 +G_DEFINE_TYPE(GMythTVChain, gmyth_tvchain, G_TYPE_OBJECT)
63.57 +
63.58 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
63.59 +
63.60 +static void
63.61 +gmyth_tvchain_class_init (GMythTVChainClass *klass)
63.62 +{
63.63 + GObjectClass *gobject_class;
63.64 +
63.65 + gobject_class = (GObjectClass *) klass;
63.66 +
63.67 + gobject_class->dispose = gmyth_tvchain_dispose;
63.68 + gobject_class->finalize = gmyth_tvchain_finalize;
63.69 +}
63.70 +
63.71 +static void
63.72 +gmyth_tvchain_init (GMythTVChain *tvchain)
63.73 +{
63.74 + tvchain->tvchain_id = NULL;
63.75 +
63.76 + tvchain->cur_chanid = g_string_new ("");
63.77 + tvchain->cur_startts = NULL;
63.78 +}
63.79 +
63.80 +static void
63.81 +gmyth_tvchain_dispose (GObject *object)
63.82 +{
63.83 + GMythTVChain *tvchain = GMYTH_TVCHAIN(object);
63.84 +
63.85 + if ( tvchain->tvchain_id != NULL ) {
63.86 + g_string_free( tvchain->tvchain_id, TRUE );
63.87 + tvchain->tvchain_id = NULL;
63.88 + }
63.89 +
63.90 + if ( tvchain->tvchain_list != NULL ) {
63.91 + g_list_free( tvchain->tvchain_list );
63.92 + tvchain->tvchain_list = NULL;
63.93 + }
63.94 +
63.95 + if ( tvchain->cur_chanid != NULL ) {
63.96 + g_string_free( tvchain->cur_chanid, TRUE );
63.97 + tvchain->cur_chanid = NULL;
63.98 + }
63.99 +
63.100 + if ( tvchain->backend_info) {
63.101 + g_object_unref (tvchain->backend_info);
63.102 + tvchain->backend_info = NULL;
63.103 + }
63.104 +
63.105 +
63.106 + G_OBJECT_CLASS (gmyth_tvchain_parent_class)->dispose (object);
63.107 +}
63.108 +
63.109 +static void
63.110 +gmyth_tvchain_finalize (GObject *object)
63.111 +{
63.112 + g_signal_handlers_destroy (object);
63.113 +
63.114 + G_OBJECT_CLASS (gmyth_tvchain_parent_class)->finalize (object);
63.115 +}
63.116 +
63.117 +/** Initializes the tvchain and generates the tvchain id.
63.118 + *
63.119 + * @param tvchain The GMythTVChain instance.
63.120 + * @param hostname The local hostname used to generate the tvchain id.
63.121 + */
63.122 +gboolean
63.123 +gmyth_tvchain_initialize (GMythTVChain *tvchain, GMythBackendInfo *backend_info)
63.124 +{
63.125 + const char *hostname;
63.126 +
63.127 + assert (tvchain);
63.128 + g_return_val_if_fail (backend_info != NULL, FALSE);
63.129 +
63.130 + g_object_ref (backend_info);
63.131 + tvchain->backend_info = backend_info;
63.132 +
63.133 + hostname = gmyth_backend_info_get_hostname (backend_info);
63.134 +
63.135 + if (tvchain->tvchain_id == NULL) {
63.136 + gchar *isodate = NULL;
63.137 + GTimeVal *cur_time = g_new0( GTimeVal, 1 );
63.138 + //struct tm* gmyth_util_time_val_to_date ( const GTimeVal* time )
63.139 +
63.140 + g_get_current_time(cur_time);
63.141 + isodate = gmyth_util_time_to_isoformat_from_time_val_fmt ( "%Y-%m-%dT%H:%M:%S", cur_time );
63.142 +
63.143 + tvchain->tvchain_id = g_string_sized_new (7 + strlen (hostname) + strlen(isodate));
63.144 + g_string_printf(tvchain->tvchain_id,
63.145 + "live-%s-%s", hostname, isodate);
63.146 +
63.147 + gmyth_debug ("[%s] tv_chain_id: %s", __FUNCTION__, tvchain->tvchain_id->str);
63.148 +
63.149 + if (isodate)
63.150 + g_free(isodate);
63.151 +
63.152 + if ( cur_time )
63.153 + g_free( cur_time );
63.154 + } else {
63.155 + g_warning ("[%s] TVchain already initialized", __FUNCTION__);
63.156 + }
63.157 +
63.158 + return TRUE;
63.159 +}
63.160 +
63.161 +/** Gets the tvchain id.
63.162 + *
63.163 + * @param tvchain The GMythTVChain instance.
63.164 + * @return The tvchain id.
63.165 + */
63.166 +GString*
63.167 +gmyth_tvchain_get_id (GMythTVChain *tvchain)
63.168 +{
63.169 + g_return_val_if_fail( tvchain != NULL && tvchain->tvchain_id != NULL, NULL );
63.170 +
63.171 + return g_string_new (tvchain->tvchain_id->str);
63.172 +}
63.173 +
63.174 +/** Reloads all tvchain entries in the database.
63.175 + *
63.176 + * @param tvchain The GMythTVChain instance.
63.177 + * @return TRUE if success, or FALSE if error.
63.178 + */
63.179 +gboolean
63.180 +gmyth_tvchain_reload_all (GMythTVChain *tvchain)
63.181 +{
63.182 + MYSQL_ROW msql_row;
63.183 + MYSQL_RES *msql_res = NULL;
63.184 + GMythQuery *gmyth_query = NULL;
63.185 + gboolean ret = TRUE;
63.186 + GString *stmt_str = NULL;
63.187 +
63.188 + g_static_mutex_lock( &mutex );
63.189 +
63.190 + /* gets the initial size of the TVChain entries list */
63.191 + guint prev_size = g_list_length (tvchain->tvchain_list);
63.192 +
63.193 + gmyth_debug ("[%s] chainid: %s", __FUNCTION__, tvchain->tvchain_id->str);
63.194 +
63.195 + if ( tvchain != NULL && tvchain->tvchain_list != NULL ) {
63.196 + g_list_free (tvchain->tvchain_list);
63.197 + tvchain->tvchain_list = NULL;
63.198 + }
63.199 +
63.200 + // TODO: Reuse gmyth_query already connected from context
63.201 + gmyth_query = gmyth_query_new ();
63.202 + if (!gmyth_query_connect (gmyth_query, tvchain->backend_info)) {
63.203 + g_warning ("[%s] Could not connect to db", __FUNCTION__);
63.204 + g_static_mutex_unlock( &mutex );
63.205 + ret = FALSE;
63.206 + goto done;
63.207 + }
63.208 +
63.209 + stmt_str = g_string_new ("");
63.210 + g_string_printf (stmt_str,
63.211 + "SELECT chanid, starttime, endtime, discontinuity, "
63.212 + "chainpos, hostprefix, cardtype, channame, input "
63.213 + "FROM tvchain "
63.214 + "WHERE chainid = \"%s\" ORDER BY chainpos;",
63.215 + tvchain->tvchain_id->str);
63.216 +
63.217 + msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
63.218 + if (msql_res != NULL) {
63.219 +
63.220 + while ((msql_row = mysql_fetch_row (msql_res)) != NULL) {
63.221 + struct LiveTVChainEntry *entry = g_new0 (struct LiveTVChainEntry, 1);
63.222 + entry->chanid = g_string_new (msql_row[0]);
63.223 + entry->starttime = gmyth_util_string_to_time_val ((const gchar*) msql_row[1]);
63.224 + entry->endtime = gmyth_util_string_to_time_val ((const gchar*) msql_row[2]);
63.225 + entry->discontinuity = g_ascii_strtoull (msql_row[3], NULL, 10 ) != 0;
63.226 + entry->hostprefix = g_string_new (msql_row[5]);
63.227 + entry->cardtype = g_string_new (msql_row[6]);
63.228 + entry->channum = g_string_new (msql_row[7]);
63.229 + entry->inputname = g_string_new (msql_row[8]);
63.230 +
63.231 + //m_maxpos = query.value(4).toInt() + 1;
63.232 + g_print( "[%s] Reading TV chain entry (channel %s): [%s, %s, %s]\n", __FUNCTION__, entry->channum->str, entry->chanid->str,
63.233 + (gchar*)msql_row[1], (gchar*)msql_row[2] );
63.234 +
63.235 + /* add this to get the actual start timestamp of the last recording */
63.236 + if ( tvchain->cur_startts < entry->starttime )
63.237 + tvchain->cur_startts = entry->starttime;
63.238 +
63.239 + tvchain->tvchain_list = g_list_append (tvchain->tvchain_list, entry);
63.240 + }
63.241 + } else {
63.242 + g_warning ("gmyth_tvchain_reload_all query error!\n");
63.243 + g_static_mutex_unlock( &mutex );
63.244 +
63.245 + ret = FALSE;
63.246 + goto done;
63.247 + }
63.248 +
63.249 + g_static_mutex_unlock( &mutex );
63.250 +
63.251 + tvchain->cur_pos = gmyth_tvchain_program_is_at (tvchain, tvchain->cur_chanid, tvchain->cur_startts);
63.252 + g_print( "[%s] TVChain current position = %d.\n", __FUNCTION__, tvchain->cur_pos );
63.253 +
63.254 + if (tvchain->cur_pos < 0)
63.255 + tvchain->cur_pos = 0;
63.256 +
63.257 + // if (m_switchid >= 0)
63.258 + // m_switchid = ProgramIsAt(m_switchentry.chanid,m_switchentry.starttime);
63.259 +
63.260 + if (prev_size != g_list_length (tvchain->tvchain_list)) {
63.261 + gmyth_debug ("[%s] Added new recording", __FUNCTION__);
63.262 + }
63.263 +
63.264 +done:
63.265 + if ( stmt_str != NULL )
63.266 + g_string_free (stmt_str, TRUE);
63.267 +
63.268 + if ( msql_res != NULL )
63.269 + mysql_free_result (msql_res);
63.270 +
63.271 + if ( gmyth_query != NULL )
63.272 + g_object_unref (gmyth_query);
63.273 +
63.274 + return ret;
63.275 +}
63.276 +
63.277 +/** Returns the internal index for the TV chain related to the given
63.278 + * channel and start time.
63.279 + *
63.280 + * @param tvchain The GMythTVChain instance.
63.281 + * @param chanid The channel id.
63.282 + * @param startts The program start time.
63.283 + */
63.284 +gint
63.285 +gmyth_tvchain_program_is_at (GMythTVChain *tvchain, GString *chanid, GTimeVal* startts)
63.286 +{
63.287 + gint count = 0;
63.288 + struct LiveTVChainEntry *entry;
63.289 + GList *tmp_list = tvchain->tvchain_list;
63.290 + guint list_size = g_list_length (tvchain->tvchain_list);
63.291 +
63.292 + g_static_mutex_lock( &mutex );
63.293 +
63.294 + for (; tmp_list && ( count < list_size ); tmp_list = tvchain->tvchain_list->next, count++)
63.295 + {
63.296 + entry = (struct LiveTVChainEntry*) tmp_list->data;
63.297 + if ( !g_strncasecmp (entry->chanid->str, chanid->str, chanid->len)
63.298 + && entry->starttime == startts )
63.299 + {
63.300 + g_static_mutex_unlock( &mutex );
63.301 + return count;
63.302 + }
63.303 + }
63.304 + g_static_mutex_unlock( &mutex );
63.305 +
63.306 + return -1;
63.307 +}
63.308 +
63.309 +/** Get the program info associated to the tvchain.
63.310 + *
63.311 + * @param tvchain The GMythTVChain instance.
63.312 + * @param index The tvchain index.
63.313 + * @return The program info structure.
63.314 + */
63.315 +GMythProgramInfo*
63.316 +gmyth_tvchain_get_program_at (GMythTVChain *tvchain, gint index)
63.317 +{
63.318 + struct LiveTVChainEntry *entry;
63.319 +
63.320 + entry = gmyth_tvchain_get_entry_at (tvchain, index);
63.321 +
63.322 + if (entry)
63.323 + return gmyth_tvchain_entry_to_program (tvchain, entry);
63.324 +
63.325 + return NULL;
63.326 +}
63.327 +
63.328 +/** Gets a LiveTVChainEntry associated to the tvchain by its index.
63.329 + *
63.330 + * @param tvchain The GMythTVChain instance.
63.331 + * @param index The tvchain entry index
63.332 + * @return The LiveTVchainEntry structure.
63.333 + */
63.334 +struct LiveTVChainEntry*
63.335 +gmyth_tvchain_get_entry_at (GMythTVChain *tvchain, gint index)
63.336 +{
63.337 + struct LiveTVChainEntry* chain_entry = NULL;
63.338 +
63.339 + g_return_val_if_fail( tvchain != NULL && tvchain->tvchain_list != NULL, NULL );
63.340 +
63.341 + g_static_mutex_lock( &mutex );
63.342 +
63.343 + gint size = g_list_length (tvchain->tvchain_list);
63.344 + gint new_index = (index < 0 || index >= size) ? size - 1 : index;
63.345 +
63.346 + if (new_index >= 0)
63.347 + chain_entry = (struct LiveTVChainEntry*) g_list_nth_data (tvchain->tvchain_list, new_index);
63.348 +
63.349 + g_static_mutex_unlock( &mutex );
63.350 +
63.351 + if ( chain_entry != NULL ) {
63.352 + gmyth_debug ("[%s] Got TV Chain entry at %d.\n", __FUNCTION__, new_index );
63.353 +
63.354 + } else {
63.355 + g_warning ("[%s] failed to get entry at index %d", __FUNCTION__, index);
63.356 + }
63.357 +
63.358 + return chain_entry;
63.359 +}
63.360 +
63.361 +/** Gets the program info from backend database associated to the tv chain entry.
63.362 + *
63.363 + * @param tvchain The GMythTVChain instance.
63.364 + * @param entry the LiveTVChainEntry to be converted.
63.365 + * @return The progrma info.
63.366 + */
63.367 +GMythProgramInfo*
63.368 +gmyth_tvchain_entry_to_program (GMythTVChain *tvchain, struct LiveTVChainEntry *entry)
63.369 +{
63.370 + GMythProgramInfo *proginfo = NULL;
63.371 +
63.372 + g_return_val_if_fail( tvchain != NULL, NULL );
63.373 +
63.374 + if ( !entry || !tvchain ) {
63.375 + g_warning ("gmyth_tvchain_entry_to_program() received NULL argument");
63.376 + return NULL;
63.377 + }
63.378 +
63.379 + GMythScheduler *scheduler = gmyth_scheduler_new ();
63.380 +
63.381 + gmyth_scheduler_connect( scheduler, tvchain->backend_info );
63.382 + proginfo = gmyth_scheduler_get_recorded (scheduler,
63.383 + entry->chanid, entry->starttime);
63.384 + gmyth_scheduler_disconnect( scheduler );
63.385 +
63.386 + if (proginfo) {
63.387 + proginfo->pathname = g_string_prepend (proginfo->pathname, entry->hostprefix->str);
63.388 + } else {
63.389 + g_warning ("tvchain_entry_to_program( chan id = %s, starttime = %ld) failed!", entry->chanid->str, entry->starttime->tv_sec);
63.390 + }
63.391 +
63.392 + return proginfo;
63.393 +}
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
64.2 +++ b/branches/gmyth-0.1b/src/gmyth_tvchain.h Thu Feb 01 18:42:01 2007 +0000
64.3 @@ -0,0 +1,108 @@
64.4 +/**
64.5 + * GMyth Library
64.6 + *
64.7 + * @file gmyth/gmyth_tvchain.h
64.8 + *
64.9 + * @brief <p> This component contains functions for creating and accessing
64.10 + * the tvchain functions for live tv playback.
64.11 + *
64.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
64.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@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 +#ifndef LIVETVCHAIN_H_
64.33 +#define LIVETVCHAIN_H_
64.34 +
64.35 +#include <glib-object.h>
64.36 +#include <time.h>
64.37 +
64.38 +#include "gmyth_common.h"
64.39 +#include "gmyth_backendinfo.h"
64.40 +
64.41 +G_BEGIN_DECLS
64.42 +
64.43 +#define GMYTH_TVCHAIN_TYPE (gmyth_tvchain_get_type ())
64.44 +#define GMYTH_TVCHAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChain))
64.45 +#define GMYTH_TVCHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
64.46 +#define IS_GMYTH_TVCHAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE))
64.47 +#define IS_GMYTH_TVCHAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE))
64.48 +#define GMYTH_TVCHAIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
64.49 +
64.50 +
64.51 +typedef struct _GMythTVChain GMythTVChain;
64.52 +typedef struct _GMythTVChainClass GMythTVChainClass;
64.53 +
64.54 +
64.55 +struct LiveTVChainEntry
64.56 +{
64.57 + GString *chanid;
64.58 +
64.59 + GTimeVal* starttime;
64.60 + GTimeVal* endtime;
64.61 +
64.62 + gboolean discontinuity; // if true, can't play smooth from last entry
64.63 + GString *hostprefix;
64.64 + GString *cardtype;
64.65 + GString *channum;
64.66 + GString *inputname;
64.67 +};
64.68 +
64.69 +
64.70 +struct _GMythTVChainClass
64.71 +{
64.72 + GObjectClass parent_class;
64.73 +
64.74 + /* callbacks */
64.75 + /* no one for now */
64.76 +};
64.77 +
64.78 +struct _GMythTVChain
64.79 +{
64.80 + GObject parent;
64.81 +
64.82 + GString *tvchain_id;
64.83 + GList *tvchain_list;
64.84 +
64.85 + GTimeVal* cur_startts;
64.86 + GString *cur_chanid;
64.87 + gint cur_pos;
64.88 +
64.89 + GMythBackendInfo *backend_info;
64.90 +};
64.91 +
64.92 +
64.93 +GType gmyth_tvchain_get_type (void);
64.94 +
64.95 +gboolean gmyth_tvchain_initialize (GMythTVChain *tvchain,
64.96 + GMythBackendInfo *backend_info);
64.97 +gboolean gmyth_tvchain_reload_all (GMythTVChain *tvchain);
64.98 +GString* gmyth_tvchain_get_id (GMythTVChain *tvchain);
64.99 +gint gmyth_tvchain_program_is_at (GMythTVChain *tvchain,
64.100 + GString *chanid, GTimeVal* startts);
64.101 +
64.102 +struct LiveTVChainEntry* gmyth_tvchain_get_entry_at (GMythTVChain *tvchain,
64.103 + gint index);
64.104 +
64.105 +GMythProgramInfo* gmyth_tvchain_entry_to_program (GMythTVChain *tvchain,
64.106 + struct LiveTVChainEntry *entry);
64.107 +GMythProgramInfo* gmyth_tvchain_get_program_at (GMythTVChain *tvchain, gint index);
64.108 +
64.109 +G_END_DECLS
64.110 +
64.111 +#endif /*LIVETVCHAIN_H_*/
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
65.2 +++ b/branches/gmyth-0.1b/src/gmyth_uri.c Thu Feb 01 18:42:01 2007 +0000
65.3 @@ -0,0 +1,404 @@
65.4 +/**
65.5 + * GMyth Library
65.6 + *
65.7 + * @file gmyth/gmyth_uri.c
65.8 + *
65.9 + * @brief <p> GMythURI utils
65.10 + * - Extracts and parses a URI char string, in according with the RFC 2396
65.11 + * [http://www.ietf.org/rfc/rfc2396.txt]
65.12 + *
65.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
65.14 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
65.15 + *
65.16 + *//*
65.17 + *
65.18 + * This program is free software; you can redistribute it and/or modify
65.19 + * it under the terms of the GNU Lesser General Public License as published by
65.20 + * the Free Software Foundation; either version 2 of the License, or
65.21 + * (at your option) any later version.
65.22 + *
65.23 + * This program is distributed in the hope that it will be useful,
65.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
65.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
65.26 + * GNU General Public License for more details.
65.27 + *
65.28 + * You should have received a copy of the GNU Lesser General Public License
65.29 + * along with this program; if not, write to the Free Software
65.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
65.31 + */
65.32 +
65.33 +#ifdef HAVE_CONFIG_H
65.34 +#include "config.h"
65.35 +#endif
65.36 +
65.37 +#include "gmyth_uri.h"
65.38 +
65.39 +#include <glib.h>
65.40 +#include <string.h>
65.41 +#include <stdlib.h>
65.42 +
65.43 +#include "gmyth_debug.h"
65.44 +
65.45 +static void gmyth_uri_class_init (GMythURIClass *klass);
65.46 +static void gmyth_uri_init (GMythURI *object);
65.47 +
65.48 +static void gmyth_uri_dispose (GObject *object);
65.49 +static void gmyth_uri_finalize (GObject *object);
65.50 +
65.51 +G_DEFINE_TYPE(GMythURI, gmyth_uri, G_TYPE_OBJECT)
65.52 +
65.53 +static void
65.54 +gmyth_uri_parser_setup_and_new( GMythURI *uri, const gchar *value );
65.55 +
65.56 +static void
65.57 +gmyth_uri_class_init (GMythURIClass *klass)
65.58 +{
65.59 + GObjectClass *gobject_class;
65.60 +
65.61 + gobject_class = (GObjectClass *) klass;
65.62 +
65.63 + gobject_class->dispose = gmyth_uri_dispose;
65.64 + gobject_class->finalize = gmyth_uri_finalize;
65.65 +}
65.66 +
65.67 +static void
65.68 +gmyth_uri_init (GMythURI *gmyth_uri)
65.69 +{
65.70 +}
65.71 +
65.72 +static void
65.73 +gmyth_uri_dispose (GObject *object)
65.74 +{
65.75 + GMythURI *gmyth_uri = GMYTH_URI(object);
65.76 +
65.77 + if ( gmyth_uri->host != NULL ) {
65.78 + g_string_free( gmyth_uri->host, TRUE );
65.79 + gmyth_uri->host = NULL;
65.80 + }
65.81 +
65.82 + if ( gmyth_uri->protocol != NULL ) {
65.83 + g_string_free( gmyth_uri->protocol, TRUE );
65.84 + gmyth_uri->protocol = NULL;
65.85 + }
65.86 +
65.87 + if ( gmyth_uri->path != NULL ) {
65.88 + g_string_free( gmyth_uri->path, TRUE );
65.89 + gmyth_uri->path = NULL;
65.90 + }
65.91 +
65.92 + if ( gmyth_uri->fragment != NULL ) {
65.93 + g_string_free( gmyth_uri->fragment, TRUE );
65.94 + gmyth_uri->fragment = NULL;
65.95 + }
65.96 +
65.97 + if ( gmyth_uri->user != NULL ) {
65.98 + g_string_free( gmyth_uri->user, TRUE );
65.99 + gmyth_uri->user = NULL;
65.100 + }
65.101 +
65.102 + if ( gmyth_uri->password != NULL ) {
65.103 + g_string_free( gmyth_uri->password, TRUE );
65.104 + gmyth_uri->password = NULL;
65.105 + }
65.106 +
65.107 + if ( gmyth_uri->query != NULL ) {
65.108 + g_string_free( gmyth_uri->query, TRUE );
65.109 + gmyth_uri->query = NULL;
65.110 + }
65.111 +
65.112 + G_OBJECT_CLASS (gmyth_uri_parent_class)->dispose (object);
65.113 +}
65.114 +
65.115 +static void
65.116 +gmyth_uri_finalize (GObject *object)
65.117 +{
65.118 + //GMythURI *gmyth_uri = GMYTH_URI(object);
65.119 +
65.120 + g_signal_handlers_destroy (object);
65.121 +
65.122 + G_OBJECT_CLASS (gmyth_uri_parent_class)->finalize (object);
65.123 +}
65.124 +
65.125 +/** Creates a new instance of GMythURI.
65.126 + *
65.127 + * @return a new instance of GMythURI.
65.128 + */
65.129 +GMythURI *
65.130 +gmyth_uri_new (void)
65.131 +{
65.132 + GMythURI *gmyth_uri = GMYTH_URI (g_object_new (GMYTH_URI_TYPE, NULL));
65.133 +
65.134 + return gmyth_uri;
65.135 +}
65.136 +
65.137 +/** Creates a new instance of GMythURI.
65.138 + *
65.139 + * @return a new instance of GMythURI.
65.140 + */
65.141 +GMythURI *
65.142 +gmyth_uri_new_with_value (const gchar *value)
65.143 +{
65.144 + GMythURI *gmyth_uri = GMYTH_URI (g_object_new (GMYTH_URI_TYPE, NULL));
65.145 +
65.146 + gmyth_uri_parser_setup_and_new (gmyth_uri, value);
65.147 +
65.148 + return gmyth_uri;
65.149 +}
65.150 +
65.151 +static gint
65.152 +gmyth_strstr (const gchar *haystack, const gchar *needle)
65.153 +{
65.154 +
65.155 + gchar *strPos;
65.156 +
65.157 + if (haystack == NULL || needle == NULL)
65.158 + return -1;
65.159 + strPos = strstr(haystack, needle);
65.160 + if (strPos == NULL)
65.161 + return -1;
65.162 +
65.163 + return (strPos - haystack);
65.164 +
65.165 +}
65.166 +
65.167 +static gboolean
65.168 +gmyth_uri_isabsolute (const GMythURI *uri)
65.169 +{
65.170 + gboolean ret = FALSE;
65.171 +
65.172 + g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->protocol != NULL, FALSE );
65.173 +
65.174 + if ( gmyth_strstr( uri->uri->str, GMYTH_URI_PROTOCOL_DELIM ) == 0 || strlen(uri->protocol->str) > 0 )
65.175 + ret = TRUE;
65.176 +
65.177 + return ret;
65.178 +}
65.179 +
65.180 +static gint
65.181 +gmyth_strrchr( const gchar *str, const gchar *chars, const gint nchars )
65.182 +{
65.183 +
65.184 + gint strLen;
65.185 + gint i, j;
65.186 +
65.187 + if ( str == NULL || chars == NULL )
65.188 + return -1;
65.189 +
65.190 + strLen = strlen( str );
65.191 + for ( i= (strLen-1); 0 <= i; i-- ) {
65.192 + for ( j=0; j<nchars; j++ ) {
65.193 + if ( str[i] == chars[j] )
65.194 + return i;
65.195 + }
65.196 + }
65.197 +
65.198 + return -1;
65.199 +
65.200 +}
65.201 +
65.202 +static gchar*
65.203 +gmyth_uri_print_field( const GString* field )
65.204 +{
65.205 + if ( field != NULL && field->str != NULL && strlen(field->str) > 0 )
65.206 + return field->str;
65.207 + else
65.208 + return "";
65.209 +}
65.210 +
65.211 +static void
65.212 +gmyth_uri_parser_setup_and_new( GMythURI *uri, const gchar *value )
65.213 +{
65.214 +
65.215 + gint uriLen;
65.216 + gint currIdx;
65.217 + gint protoIdx;
65.218 + gint atIdx;
65.219 + gint colonIdx;
65.220 + gint shashIdx;
65.221 + gint eIdx;
65.222 + gchar *host;
65.223 + gint eblacketIdx;
65.224 + gint hostLen;
65.225 + gint sharpIdx;
65.226 + /*
65.227 + gint questionIdx;
65.228 + gint queryLen;
65.229 + */
65.230 +
65.231 + uriLen = strlen(value);
65.232 + uri->uri = g_string_new( value );
65.233 +
65.234 + currIdx = 0;
65.235 +
65.236 + /*** Protocol ****/
65.237 + protoIdx = gmyth_strstr (value, GMYTH_URI_PROTOCOL_DELIM);
65.238 + if (0 < protoIdx) {
65.239 + uri->protocol = g_string_new_len (value, protoIdx);
65.240 + currIdx += protoIdx + strlen( GMYTH_URI_PROTOCOL_DELIM );
65.241 + }
65.242 +
65.243 + /*** User (Password) ****/
65.244 + atIdx = gmyth_strstr( value+currIdx, GMYTH_URI_USER_DELIM );
65.245 + if ( 0 < atIdx ) {
65.246 + colonIdx = gmyth_strstr( value+currIdx, GMYTH_URI_COLON_DELIM );
65.247 +
65.248 + if (0 < colonIdx && colonIdx < atIdx) {
65.249 + uri->user = g_string_new_len (value+currIdx, colonIdx);
65.250 + uri->password = g_string_new_len (value+currIdx+colonIdx+1, atIdx - (colonIdx+1));
65.251 + }
65.252 + else
65.253 + uri->user = g_string_new_len (value+currIdx, atIdx - currIdx);
65.254 + currIdx += atIdx + 1;
65.255 + }
65.256 +
65.257 + /*** Host (Port) ****/
65.258 + shashIdx = gmyth_strstr( value+currIdx, GMYTH_URI_SLASH_DELIM );
65.259 + if (0 < shashIdx)
65.260 + uri->host = g_string_new_len (value+currIdx, shashIdx);
65.261 + else if ( gmyth_uri_isabsolute(uri) == TRUE )
65.262 + uri->host = g_string_new_len (value+currIdx, strlen (value) - currIdx);
65.263 +
65.264 + host = gmyth_uri_get_host(uri);
65.265 + colonIdx = gmyth_strrchr (host, GMYTH_URI_COLON_DELIM, 1);
65.266 + eblacketIdx = gmyth_strrchr (host, GMYTH_URI_EBLACET_DELIM, 1);
65.267 + if ( ( 0 < colonIdx ) && ( eblacketIdx < colonIdx ) ) {
65.268 + GString *portStr = NULL;
65.269 + GString *hostStr = g_string_new (host != NULL ? host : "");
65.270 +
65.271 + hostLen = hostStr->len;
65.272 + /**** host ****/
65.273 + uri->host = g_string_erase (uri->host, 0, hostLen);
65.274 + uri->host = g_string_insert_len (uri->host, 0, hostStr->str, colonIdx);
65.275 + if (0 < hostLen) {
65.276 + if (host[0] == '[' && host[hostLen-1] == ']')
65.277 + uri->host = g_string_new_len (hostStr->str+1, colonIdx-2);
65.278 + }
65.279 + /**** port ****/
65.280 + portStr = g_string_new_len (hostStr->str+colonIdx+1, hostLen-colonIdx-1);
65.281 + uri->port = (gint)g_ascii_strtoull( portStr->str, NULL, 10 );
65.282 + g_string_free (portStr, TRUE);
65.283 + g_string_free (hostStr, TRUE);
65.284 + }
65.285 + else {
65.286 + const gchar* protocol = gmyth_uri_get_protocol(uri);
65.287 + uri->port = GMYTH_URI_KNKOWN_PORT;
65.288 + if ( strcmp(protocol, GMYTH_URI_PROTOCOL_HTTP) == 0 )
65.289 + uri->port = GMYTH_URI_DEFAULT_HTTP_PORT;
65.290 + if ( strcmp(protocol, GMYTH_URI_PROTOCOL_FTP) == 0 )
65.291 + uri->port = GMYTH_URI_DEFAULT_FTP_PORT;
65.292 + }
65.293 +
65.294 + if (shashIdx > 0) currIdx += shashIdx;
65.295 +
65.296 + /*
65.297 + Handle relative URL
65.298 + */
65.299 + if (gmyth_uri_isabsolute(uri) == FALSE)
65.300 + {
65.301 +
65.302 + if (shashIdx != 0)
65.303 + {
65.304 + /* Add slash delimiter at the beginning of the URL,
65.305 + if it doesn't exist
65.306 + */
65.307 + uri->path = g_string_new( GMYTH_URI_SLASH_DELIM );
65.308 + }
65.309 + uri->path = g_string_append( uri->path, value );
65.310 +
65.311 + } else {
65.312 + /* First set path simply to the rest of URI */
65.313 + uri->path = g_string_new_len (value+currIdx, uriLen-currIdx );
65.314 + }
65.315 +
65.316 + gmyth_debug( "uri value: %s", value );
65.317 + uri->query = g_string_new ( g_strstr_len( value, strlen(value), GMYTH_URI_E_DELIM ) );
65.318 +
65.319 + eIdx = gmyth_strstr( value+currIdx, GMYTH_URI_E_DELIM );
65.320 +
65.321 + if ( 0 < eIdx ) {
65.322 + uri->query = g_string_new ( g_strstr_len( value, strlen(value), GMYTH_URI_E_DELIM ) );
65.323 + gmyth_debug( "query = %s", uri->query->str );
65.324 + }
65.325 +
65.326 + /**** Path (Query/Fragment) ****/
65.327 + sharpIdx = gmyth_strstr(value+currIdx, GMYTH_URI_SHARP_DELIM);
65.328 + if (0 < sharpIdx) {
65.329 + uri->path = g_string_append_len( uri->path, value+currIdx, sharpIdx);
65.330 + uri->fragment = g_string_new_len (value+currIdx+sharpIdx+1, uriLen-(currIdx+sharpIdx+1));
65.331 + }
65.332 +
65.333 + gmyth_debug( "[%s] GMythURI: host = %s, port = %d, path = %s, query = %s, fragment = %s, "\
65.334 + "user = %s, password = %s.\n", __FUNCTION__, gmyth_uri_print_field( uri->host ), uri->port,
65.335 + gmyth_uri_print_field( uri->path ), gmyth_uri_print_field( uri->query ), gmyth_uri_print_field( uri->fragment ),
65.336 + gmyth_uri_print_field ( uri->user ), gmyth_uri_print_field( uri->password ) );
65.337 +
65.338 +}
65.339 +
65.340 +gboolean
65.341 +gmyth_uri_is_equals( GMythURI* uri1, GMythURI* uri2 )
65.342 +{
65.343 + return ( g_ascii_strcasecmp( gmyth_uri_get_host( uri1 ), gmyth_uri_get_host( uri2 ) ) == 0 &&
65.344 + gmyth_uri_get_port( uri1 ) == gmyth_uri_get_port( uri2 ) );
65.345 +}
65.346 +
65.347 +gboolean
65.348 +gmyth_uri_is_livetv( GMythURI* uri )
65.349 +{
65.350 + gboolean ret = FALSE;
65.351 +
65.352 + g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->uri->str != NULL, FALSE );
65.353 +
65.354 + ret = ( g_strstr_len( uri->uri->str, strlen( uri->uri->str ), "/?" ) != NULL );
65.355 +
65.356 + if ( ret )
65.357 + gmyth_debug( "This URI is a LiveTV recording..." );
65.358 +
65.359 + return ret;
65.360 +
65.361 +}
65.362 +
65.363 +gchar*
65.364 +gmyth_uri_get_channel_name( GMythURI* uri )
65.365 +{
65.366 + gchar* channel = NULL;
65.367 +
65.368 + g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->uri->str != NULL, FALSE );
65.369 +
65.370 + gchar *channel_query = g_strstr_len( gmyth_uri_get_query( uri ), strlen( gmyth_uri_get_query( uri ) ), "channel" );
65.371 +
65.372 + if ( channel_query != NULL )
65.373 + {
65.374 + gmyth_debug( "TV Channel is in the following URI segment: %s", channel_query );
65.375 +
65.376 + gchar **chan_key_value = g_strsplit( gmyth_uri_get_query( uri ), "=", 2 );
65.377 +
65.378 + /* gmyth_debug( "Channel tuple is [ %s, %s ]", chan_key_value[0], chan_key_value[1] ); */
65.379 +
65.380 + if ( chan_key_value[1] != NULL )
65.381 + {
65.382 + channel = g_strdup( chan_key_value[1] );
65.383 + }
65.384 +
65.385 + if ( chan_key_value != NULL )
65.386 + g_strfreev( chan_key_value );
65.387 + }
65.388 +
65.389 + gmyth_debug( "Got channel decimal value from the URI: %s", channel );
65.390 +
65.391 + return channel;
65.392 +
65.393 +}
65.394 +
65.395 +gint
65.396 +gmyth_uri_get_channel_num( GMythURI* uri )
65.397 +{
65.398 + gchar *channel_name = gmyth_uri_get_channel_name( uri );
65.399 +
65.400 + if ( channel_name != NULL )
65.401 + {
65.402 + return g_ascii_strtoull( channel_name, NULL, 10 );
65.403 + }
65.404 +
65.405 + return -1;
65.406 +
65.407 +}
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
66.2 +++ b/branches/gmyth-0.1b/src/gmyth_uri.h Thu Feb 01 18:42:01 2007 +0000
66.3 @@ -0,0 +1,125 @@
66.4 +/**
66.5 + * GMyth Library
66.6 + *
66.7 + * @file gmyth/gmyth_uri.h
66.8 + *
66.9 + * @brief <p> GMythURI utils
66.10 + * - Extracts and parses a URI char string, in according with the RFC 2396
66.11 + * [http://www.ietf.org/rfc/rfc2396.txt]
66.12 + *
66.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
66.14 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
66.15 + *
66.16 + *//*
66.17 + *
66.18 + * This program is free software; you can redistribute it and/or modify
66.19 + * it under the terms of the GNU Lesser General Public License as published by
66.20 + * the Free Software Foundation; either version 2 of the License, or
66.21 + * (at your option) any later version.
66.22 + *
66.23 + * This program is distributed in the hope that it will be useful,
66.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
66.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66.26 + * GNU General Public License for more details.
66.27 + *
66.28 + * You should have received a copy of the GNU Lesser General Public License
66.29 + * along with this program; if not, write to the Free Software
66.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
66.31 + */
66.32 +
66.33 +#ifndef _GMYTH_URI_H_
66.34 +#define _GMYTH_URI_H_
66.35 +
66.36 +#include <glib.h>
66.37 +#include <glib-object.h>
66.38 +
66.39 +#include <stdlib.h>
66.40 +#include <stdio.h>
66.41 +#include <string.h>
66.42 +
66.43 +G_BEGIN_DECLS
66.44 +
66.45 +#define GMYTH_URI_TYPE (gmyth_uri_get_type ())
66.46 +#define GMYTH_URI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_URI_TYPE, GMythURI))
66.47 +#define GMYTH_URI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_URI_TYPE, GMythURIClass))
66.48 +#define IS_GMYTH_URI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_URI_TYPE))
66.49 +#define IS_GMYTH_URI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_URI_TYPE))
66.50 +#define GMYTH_URI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_URI_TYPE, GMythURIClass))
66.51 +
66.52 +typedef struct _GMythURI GMythURI;
66.53 +typedef struct _GMythURIClass GMythURIClass;
66.54 +
66.55 +/****************************************
66.56 +* Define
66.57 +****************************************/
66.58 +
66.59 +#define GMYTH_URI_KNKOWN_PORT (-1)
66.60 +#define GMYTH_URI_DEFAULT_HTTP_PORT 80
66.61 +#define GMYTH_URI_DEFAULT_FTP_PORT 21
66.62 +#define GMYTH_URI_DEFAULT_PATH "/"
66.63 +#define GMYTH_URI_MAXLEN 256
66.64 +
66.65 +#define GMYTH_URI_PROTOCOL_DELIM "://"
66.66 +#define GMYTH_URI_USER_DELIM "@"
66.67 +#define GMYTH_URI_COLON_DELIM ":"
66.68 +#define GMYTH_URI_SLASH_DELIM "/"
66.69 +#define GMYTH_URI_SBLACET_DELIM "["
66.70 +#define GMYTH_URI_EBLACET_DELIM "]"
66.71 +#define GMYTH_URI_SHARP_DELIM "#"
66.72 +#define GMYTH_URI_QUESTION_DELIM "?"
66.73 +#define GMYTH_URI_E_DELIM "&"
66.74 +#define GMYTH_URI_ESCAPING_CHAR "%"
66.75 +
66.76 +#define GMYTH_URI_PROTOCOL_MYTH "myth"
66.77 +#define GMYTH_URI_PROTOCOL_HTTP "http"
66.78 +#define GMYTH_URI_PROTOCOL_FTP "ftp"
66.79 +
66.80 +/****************************************
66.81 +* Data Type
66.82 +****************************************/
66.83 +
66.84 +struct _GMythURIClass
66.85 +{
66.86 + GObjectClass parent_class;
66.87 +
66.88 + /* callbacks */
66.89 + /* no one for now */
66.90 +};
66.91 +
66.92 +struct _GMythURI {
66.93 +
66.94 + GObject parent;
66.95 +
66.96 + GString *uri;
66.97 + GString *host;
66.98 + gint port;
66.99 + GString *protocol;
66.100 + GString *path;
66.101 + GString *fragment;
66.102 + GString *user;
66.103 + GString *password;
66.104 + GString *query;
66.105 +
66.106 +};
66.107 +
66.108 +GType gmyth_uri_get_type (void);
66.109 +GMythURI* gmyth_uri_new (void);
66.110 +GMythURI* gmyth_uri_new_with_value (const gchar *value);
66.111 +gboolean gmyth_uri_is_equals ( GMythURI* uri1, GMythURI* uri2 );
66.112 +gboolean gmyth_uri_is_livetv ( GMythURI* uri );
66.113 +gint gmyth_uri_get_channel_num( GMythURI* uri );
66.114 +gchar* gmyth_uri_get_channel_name( GMythURI* uri );
66.115 +
66.116 +
66.117 +#define gmyth_uri_get_host(urip) ( urip->host != NULL ? urip->host->str : "" )
66.118 +#define gmyth_uri_get_port(urip) ( urip->port )
66.119 +#define gmyth_uri_get_protocol(urip) ( urip->protocol != NULL ? urip->protocol->str : "" )
66.120 +#define gmyth_uri_get_path(urip) ( urip->path != NULL ? urip->path->str : "" )
66.121 +#define gmyth_uri_get_user(urip) ( urip->user != NULL ? urip->user->str : "" )
66.122 +#define gmyth_uri_get_password(urip) ( urip->password != NULL ? urip->password->str : "" )
66.123 +#define gmyth_uri_get_fragment(urip) ( urip->fragment != NULL ? urip->fragment->str : "" )
66.124 +#define gmyth_uri_get_query(urip) ( urip->query != NULL ? urip->query->str : "" )
66.125 +
66.126 +G_END_DECLS
66.127 +
66.128 +#endif /* _GMYTH_URI_H_ */
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
67.2 +++ b/branches/gmyth-0.1b/src/gmyth_util.c Thu Feb 01 18:42:01 2007 +0000
67.3 @@ -0,0 +1,647 @@
67.4 +/**
67.5 +* GMyth Library
67.6 +*
67.7 +* @file gmyth/gmyth_util.c
67.8 +*
67.9 +* @brief <p> This component provides utility functions.
67.10 +*
67.11 +* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
67.12 +* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
67.13 +*
67.14 +*//*
67.15 +*
67.16 +* This program is free software; you can redistribute it and/or modify
67.17 +* it under the terms of the GNU Lesser General Public License as published by
67.18 +* the Free Software Foundation; either version 2 of the License, or
67.19 +* (at your option) any later version.
67.20 +*
67.21 +* This program is distributed in the hope that it will be useful,
67.22 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
67.23 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
67.24 +* GNU General Public License for more details.
67.25 +*
67.26 +* You should have received a copy of the GNU Lesser General Public License
67.27 +* along with this program; if not, write to the Free Software
67.28 +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
67.29 +*/
67.30 +
67.31 +#ifdef HAVE_CONFIG_H
67.32 +#include "config.h"
67.33 +#endif
67.34 +
67.35 +#define _XOPEN_SOURCE
67.36 +#define _XOPEN_SOURCE_EXTENDED
67.37 +#define __USE_MISC
67.38 +
67.39 +#include <glib.h>
67.40 +#include <glib/gprintf.h>
67.41 +#include <time.h>
67.42 +#include <sys/time.h>
67.43 +#include <sys/timex.h>
67.44 +
67.45 +#include "gmyth.h"
67.46 +
67.47 +#if !GLIB_CHECK_VERSION (2, 10, 0)
67.48 +gchar *
67.49 +g_time_val_to_iso8601 (GTimeVal *time_);
67.50 +gboolean
67.51 +g_time_val_from_iso8601 (const gchar *iso_date,
67.52 + GTimeVal *time_);
67.53 +void
67.54 +g_date_set_time_val (GDate *date,
67.55 + GTimeVal *timeval);
67.56 +
67.57 +#endif
67.58 +
67.59 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
67.60 +
67.61 +/** Converts a time_t struct in a GString at ISO standard format
67.62 + * (e.g. 2006-07-20T09:56:41).
67.63 + *
67.64 + * The returned GString memory should be deallocated from
67.65 + * the calling function.
67.66 + *
67.67 + * @param time_value the time value to be converted
67.68 + * @return GString* the converted isoformat string
67.69 + */
67.70 +GString*
67.71 +gmyth_util_time_to_isoformat (time_t time_value)
67.72 +{
67.73 + struct tm tm_time;
67.74 + GString *result;
67.75 +
67.76 + g_static_mutex_lock ( &mutex );
67.77 +
67.78 + if (localtime_r(&time_value, &tm_time) == NULL) {
67.79 + g_static_mutex_unlock ( &mutex );
67.80 + g_warning ("gmyth_util_time_to_isoformat convertion error!\n");
67.81 + return NULL;
67.82 + }
67.83 +
67.84 + result = g_string_sized_new(20);
67.85 + g_string_printf(result, "%04d-%02d-%02dT%02d:%02d:%02d",
67.86 + tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
67.87 + tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);
67.88 +
67.89 + gmyth_debug( "Result (ISO 8601) = %s", result->str );
67.90 +
67.91 + g_static_mutex_unlock ( &mutex );
67.92 +
67.93 + return result;
67.94 +}
67.95 +
67.96 +/** Converts a time_t struct in a GString at ISO standard format
67.97 + * (e.g. 2006-07-20T09:56:41).
67.98 + *
67.99 + * The returned GString memory should be deallocated from
67.100 + * the calling function.
67.101 + *
67.102 + * @param time_value the GTimeValue to be converted
67.103 + * @return GString* the converted isoformat string
67.104 + */
67.105 +gchar*
67.106 +gmyth_util_time_to_isoformat_from_time_val_fmt ( const gchar *fmt_string, const GTimeVal* time_val )
67.107 +{
67.108 + gchar *result = NULL;
67.109 + struct tm *tm_time = NULL;
67.110 +
67.111 + gint buffer_len = 0;
67.112 +
67.113 + g_return_val_if_fail( fmt_string != NULL, NULL );
67.114 +
67.115 + g_return_val_if_fail( time_val != NULL, NULL );
67.116 +
67.117 + time_t time = time_val->tv_sec;// + (gint)( time_val->tv_usec / G_USEC_PER_SEC );
67.118 +
67.119 + tm_time = g_malloc0( sizeof(struct tm) );
67.120 +
67.121 + g_static_mutex_lock ( &mutex );
67.122 +
67.123 + if ( NULL == localtime_r( &time, tm_time ) ) {
67.124 + g_warning ("gmyth_util_time_to_isoformat convertion error!\n");
67.125 + } else {
67.126 + // we first check the return of strftime to allocate a buffer of the correct size
67.127 + buffer_len = strftime( NULL, SSIZE_MAX, fmt_string, tm_time );
67.128 + if ( buffer_len > 0 ) {
67.129 + result = g_malloc0( buffer_len + 1 );
67.130 + if( result == NULL ){
67.131 + g_static_mutex_unlock ( &mutex );
67.132 + g_warning ("gmyth_util_time_to_isoformat convertion error!\n");
67.133 + return NULL;
67.134 + }
67.135 + strftime( result, buffer_len + 1, fmt_string, tm_time );
67.136 + gmyth_debug( "Dateline (ISO result): %s", result );
67.137 + }
67.138 +
67.139 + }
67.140 +
67.141 + gmyth_debug( "Result (strftime) = %s", result );
67.142 +
67.143 + //strptime( result, "%Y-%m-%dT%H:%M:%SZ", tm_time );
67.144 +
67.145 + //strftime( result, strlen(result), fmt_string, tm_time );
67.146 +
67.147 + g_static_mutex_unlock ( &mutex );
67.148 +
67.149 + gmyth_debug( "Result (ISO 8601) = %s", result );
67.150 +
67.151 + return result;
67.152 +
67.153 +}
67.154 +
67.155 +/** Converts a time_t struct in a GString at ISO standard format
67.156 + * (e.g. 2006-07-20 09:56:41).
67.157 + *
67.158 + * The returned GString memory should be deallocated from
67.159 + * the calling function.
67.160 + *
67.161 + * @param time_value the GTimeValue to be converted
67.162 + * @return GString* the converted isoformat string
67.163 + */
67.164 +gchar*
67.165 +gmyth_util_time_to_isoformat_from_time_val ( const GTimeVal* time )
67.166 +{
67.167 + gchar *result = gmyth_util_time_to_isoformat_from_time_val_fmt( "%Y-%m-%d %H:%M:%S", time );
67.168 + //result[10] = ' ';
67.169 + //result[ strlen(result) - 1] = '\0';
67.170 +
67.171 + return result;
67.172 +}
67.173 +
67.174 +/** Converts a time_t struct in a GString at ISO standard format 2
67.175 + * (e.g. 2006-07-20T09:56:41).
67.176 + *
67.177 + * The returned GString memory should be deallocated from
67.178 + * the calling function.
67.179 + *
67.180 + * @param time_value the GTimeValue to be converted
67.181 + * @return GString* the converted isoformat string
67.182 + */
67.183 +gchar*
67.184 +gmyth_util_time_to_mythformat_from_time_val ( const GTimeVal* time )
67.185 +{
67.186 + gchar *result = gmyth_util_time_to_isoformat_from_time_val_fmt( "%Y-%m-%dT%H:%M:%S", time );
67.187 + return result;
67.188 +}
67.189 +
67.190 +/** Converts a time_t struct in a GString at ISO standard format
67.191 + * (e.g. 2006-07-20T09:56:41).
67.192 + *
67.193 + * The returned GString memory should be deallocated from
67.194 + * the calling function.
67.195 + *
67.196 + * @param time_value the GTimeValue to be converted
67.197 + * @return GString* the converted isoformat string
67.198 + */
67.199 +gchar*
67.200 +gmyth_util_time_to_string_only_date ( const GTimeVal* time )
67.201 +{
67.202 + gchar *result = gmyth_util_time_to_isoformat_from_time_val_fmt( "%Y-%m-%d", time );
67.203 + //result[10] = ' ';
67.204 + //result[ strlen(result) - 1] = '\0';
67.205 + return result;
67.206 +}
67.207 +
67.208 +/** Converts a time_t struct in a GString at ISO standard format
67.209 + * (e.g. 2006-07-20T09:56:41).
67.210 + *
67.211 + * The returned GString memory should be deallocated from
67.212 + * the calling function.
67.213 + *
67.214 + * @param time_value the GTimeValue to be converted
67.215 + * @return GString* the converted isoformat string
67.216 + */
67.217 +gchar*
67.218 +gmyth_util_time_to_string_only_time ( const GTimeVal* time )
67.219 +{
67.220 + gchar *result = gmyth_util_time_to_isoformat_from_time_val_fmt( "%H:%M:%S", time );
67.221 + //result[10] = ' ';
67.222 + //result[ strlen(result) - 1] = '\0';
67.223 + return result;
67.224 +}
67.225 +
67.226 +/** Converts a time_t struct in a GString to the following
67.227 + * format (e.g. 2006-07-20 09:56:41).
67.228 + *
67.229 + * The returned GString memory should be deallocated from
67.230 + * the calling function.
67.231 + *
67.232 + * @param time_value the time value to be converted
67.233 + * @return GString* the converted string
67.234 + */
67.235 +GString*
67.236 +gmyth_util_time_to_string (time_t time_value)
67.237 +{
67.238 + GString *result = gmyth_util_time_to_isoformat (time_value);
67.239 + result->str[10] = ' ';
67.240 + result->str[ strlen(result->str) - 1] = '\0';
67.241 +
67.242 + return result;
67.243 +}
67.244 +
67.245 +/** Converts a time_t struct in a GString to the following
67.246 + * format (e.g. 2006-07-20 09:56:41).
67.247 + *
67.248 + * The returned GString memory should be deallocated from
67.249 + * the calling function.
67.250 + *
67.251 + * @param time_value the time value to be converted
67.252 + * @return GString* the converted string
67.253 + */
67.254 +gchar*
67.255 +gmyth_util_time_to_string_from_time_val ( const GTimeVal *time_val )
67.256 +{
67.257 + gchar *result = gmyth_util_time_to_isoformat_from_time_val_fmt ( "%Y-%m-%d %H:%M:%S", time_val );
67.258 + //result[10] = ' ';
67.259 +
67.260 + return result;
67.261 +}
67.262 +
67.263 +/** Converts a GString in the following format
67.264 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
67.265 + *
67.266 + * @param time_str the string to be converted
67.267 + * @return time_t the time converted value
67.268 + */
67.269 +time_t
67.270 +gmyth_util_string_to_time (GString* time_str)
67.271 +{
67.272 + gint year, month, day, hour, min, sec;
67.273 +
67.274 + gmyth_debug( "[%s] time_str = %s. [%s]", __FUNCTION__, time_str != NULL ?
67.275 + time_str->str : "[time string is NULL!]", time_str->str );
67.276 +
67.277 + if ( sscanf (time_str->str, "%04d-%02d-%02d %02d:%02d:%02d",
67.278 + &year, &month, &day, &hour, &min, &sec) < 3 ) {
67.279 + g_warning ("GMythUtil: isoformat_to_time converter error!\n");
67.280 + return 0;
67.281 + }
67.282 +
67.283 + g_static_mutex_lock ( &mutex );
67.284 +
67.285 + struct tm* tm_time = g_malloc0( sizeof(struct tm) );
67.286 + tm_time->tm_year = year - 1900;
67.287 + tm_time->tm_mon = month - 1;
67.288 + tm_time->tm_mday = day;
67.289 + tm_time->tm_hour = hour;
67.290 + tm_time->tm_min = min;
67.291 + tm_time->tm_sec = sec;
67.292 +
67.293 + g_static_mutex_unlock ( &mutex );
67.294 +
67.295 + return mktime( tm_time );
67.296 +}
67.297 +
67.298 +/** Converts a GString in the following format
67.299 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
67.300 + *
67.301 + * @param time_str the string to be converted
67.302 + * @return time_t the time converted value
67.303 + */
67.304 +struct tm*
67.305 +gmyth_util_time_val_to_date ( const GTimeVal* time )
67.306 +{
67.307 + struct tm *date = g_malloc0( sizeof( struct tm ) );
67.308 + time_t time_micros = time->tv_sec;// + (gint)( time->tv_usec / G_USEC_PER_SEC );
67.309 +
67.310 + if ( NULL == date ) {
67.311 + g_warning ( "GMythUtil: GDate *gmyth_util_time_val_to_date (GTimeVal* time) - converter error!\n" );
67.312 + return NULL;
67.313 + }
67.314 +
67.315 + if ( NULL == localtime_r( &time_micros, date ) ) {
67.316 + g_warning ( "gmyth_util_time_to_isoformat convertion error!\n" );
67.317 + return NULL;
67.318 + }
67.319 +
67.320 + gmyth_debug( "Converted from GTimeVal == %s to GDate", asctime( date ) );
67.321 +
67.322 + return date;
67.323 +}
67.324 +
67.325 +/** Converts a GString in the following format
67.326 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
67.327 + *
67.328 + * @param time_str the string to be converted
67.329 + * @return time_t the time converted value
67.330 + */
67.331 +GTimeVal*
67.332 +gmyth_util_string_to_time_val_fmt ( const gchar *fmt_string, const gchar* time_str )
67.333 +{
67.334 + GTimeVal *time = g_new0( GTimeVal, 1 );
67.335 + struct tm* tm_time = NULL;
67.336 + time_t time_micros;
67.337 + gint result;
67.338 +
67.339 + gmyth_debug( "[%s] time_str = %s. [%s]", time_str, time_str != NULL ?
67.340 + time_str : "[time string is NULL!]", time_str );
67.341 +
67.342 + if ( NULL == time_str )
67.343 + {
67.344 + g_warning ("GMythUtil: isoformat_to_time converter error!\n");
67.345 + return NULL;
67.346 + }
67.347 +
67.348 + g_static_mutex_lock ( &mutex );
67.349 +
67.350 + tm_time = g_malloc0( sizeof(struct tm) );
67.351 +
67.352 + /* we first check the return of strftime to allocate a buffer of the correct size */
67.353 + result = strptime( time_str, "%Y-%m-%dT%H:%M:%S", tm_time );
67.354 + if ( NULL == result ) {
67.355 + /* we first check the return of strftime to allocate a buffer of the correct size */
67.356 + result = strptime( time_str, "%Y-%m-%dT%H:%M:%SZ", tm_time );
67.357 + if ( NULL == result ) {
67.358 + /* we first check the return of strftime to allocate a buffer of the correct size */
67.359 + result = strptime( time_str, "%Y-%m-%d %H:%M:%S", tm_time );
67.360 + if ( NULL == result ) {
67.361 + g_static_mutex_unlock ( &mutex );
67.362 + gmyth_debug( "Dateline (ISO result): %s", result );
67.363 + time = NULL;
67.364 + //goto done;
67.365 + }
67.366 + }
67.367 + }
67.368 +
67.369 + time_micros = mktime( tm_time );
67.370 +
67.371 + time->tv_sec = time_micros; // + (gint)( time_val->tv_usec / G_USEC_PER_SEC );
67.372 +
67.373 + gmyth_debug( "After mktime call... = %s", asctime(tm_time) );
67.374 +
67.375 + g_static_mutex_unlock ( &mutex );
67.376 +
67.377 + return time;
67.378 +}
67.379 +
67.380 +/** Converts a GString in the following format
67.381 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
67.382 + *
67.383 + * @param time_str the string to be converted
67.384 + * @return time_t the time converted value
67.385 + */
67.386 +GTimeVal*
67.387 +gmyth_util_string_to_time_val ( const gchar* time_str )
67.388 +{
67.389 + GTimeVal *time = gmyth_util_string_to_time_val_fmt ( "%Y-%m-%d %H:%M:%S", time_str );
67.390 +
67.391 + return time;
67.392 +}
67.393 +
67.394 +/** Decodes a long long variable from the string list
67.395 + * format of the myhtprotocol.
67.396 + *
67.397 + * @param strlist the string list of mythprotocol values
67.398 + * @param offset the list node offset of the long long variable
67.399 + * @return gint64 the long long converted value
67.400 + */
67.401 +gint64
67.402 +gmyth_util_decode_long_long(GMythStringList *strlist, guint offset)
67.403 +{
67.404 +
67.405 + gint64 ret_value = 0LL;
67.406 +
67.407 + g_return_val_if_fail( strlist != NULL, ret_value );
67.408 +
67.409 + if ( offset > gmyth_string_list_length( strlist ))
67.410 + g_printerr( "[%s] Offset is greater than the Stringlist (offset = %d)!\n",
67.411 + __FUNCTION__, offset );
67.412 +
67.413 + g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value );
67.414 +
67.415 + gint l1 = gmyth_string_list_get_int( strlist, offset );
67.416 + gint l2 = gmyth_string_list_get_int( strlist, offset + 1 );
67.417 +
67.418 + ret_value = (l2 /*& 0xffffffffLL*/) | ( (gint64)l1 << 32 );
67.419 +
67.420 + return ret_value;
67.421 +
67.422 +}
67.423 +
67.424 +gboolean
67.425 +gmyth_util_file_exists (GMythBackendInfo *backend_info, const gchar* filename)
67.426 +{
67.427 + GMythSocket *socket;
67.428 + gboolean res;
67.429 +
67.430 + socket = gmyth_socket_new ();
67.431 + res = gmyth_socket_connect_to_backend (socket, backend_info->hostname,
67.432 + backend_info->port, TRUE);
67.433 +
67.434 + if (res == TRUE) {
67.435 + GMythStringList *slist;
67.436 + GMythProgramInfo *program = NULL;
67.437 +
67.438 + program = gmyth_program_info_new();
67.439 + program->pathname = g_string_new (filename);
67.440 +
67.441 + slist = gmyth_string_list_new ();
67.442 + gmyth_string_list_append_char_array (slist, "QUERY_CHECKFILE");
67.443 +
67.444 + gmyth_program_info_to_string_list (program, slist);
67.445 +
67.446 + gmyth_socket_sendreceive_stringlist (socket, slist);
67.447 +
67.448 + res = (gmyth_string_list_get_int (slist, 0) == 1);
67.449 +
67.450 + g_object_unref (program);
67.451 +
67.452 + g_object_unref (slist);
67.453 +
67.454 + gmyth_socket_close_connection (socket);
67.455 + }
67.456 + g_object_unref (socket);
67.457 + return res;
67.458 +}
67.459 +
67.460 +
67.461 +#if !GLIB_CHECK_VERSION (2, 10, 0)
67.462 +
67.463 +/* Hacked from glib 2.10 <gtime.c> */
67.464 +
67.465 +static time_t
67.466 +mktime_utc (struct tm *tm)
67.467 +{
67.468 + time_t retval;
67.469 +
67.470 +#ifndef HAVE_TIMEGM
67.471 + static const gint days_before[] =
67.472 + {
67.473 + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
67.474 + };
67.475 +#endif
67.476 +
67.477 +#ifndef HAVE_TIMEGM
67.478 + if (tm->tm_mon < 0 || tm->tm_mon > 11)
67.479 + return (time_t) -1;
67.480 +
67.481 + retval = (tm->tm_year - 70) * 365;
67.482 + retval += (tm->tm_year - 68) / 4;
67.483 + retval += days_before[tm->tm_mon] + tm->tm_mday - 1;
67.484 +
67.485 + if (tm->tm_year % 4 == 0 && tm->tm_mon < 2)
67.486 + retval -= 1;
67.487 +
67.488 + retval = ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 + tm->tm_sec;
67.489 +#else
67.490 + retval = timegm (tm);
67.491 +#endif /* !HAVE_TIMEGM */
67.492 +
67.493 + return retval;
67.494 +}
67.495 +
67.496 +gboolean
67.497 +g_time_val_from_iso8601 (const gchar *iso_date,
67.498 + GTimeVal *time_)
67.499 +{
67.500 + struct tm tm;
67.501 + long val;
67.502 +
67.503 + g_return_val_if_fail (iso_date != NULL, FALSE);
67.504 + g_return_val_if_fail (time_ != NULL, FALSE);
67.505 +
67.506 + val = strtoul (iso_date, (char **)&iso_date, 10);
67.507 + if (*iso_date == '-')
67.508 + {
67.509 + /* YYYY-MM-DD */
67.510 + tm.tm_year = val - 1900;
67.511 + iso_date++;
67.512 + tm.tm_mon = strtoul (iso_date, (char **)&iso_date, 10) - 1;
67.513 +
67.514 + if (*iso_date++ != '-')
67.515 + return FALSE;
67.516 +
67.517 + tm.tm_mday = strtoul (iso_date, (char **)&iso_date, 10);
67.518 + }
67.519 + else
67.520 + {
67.521 + /* YYYYMMDD */
67.522 + tm.tm_mday = val % 100;
67.523 + tm.tm_mon = (val % 10000) / 100 - 1;
67.524 + tm.tm_year = val / 10000 - 1900;
67.525 + }
67.526 +
67.527 + if (*iso_date++ != 'T')
67.528 + return FALSE;
67.529 +
67.530 + val = strtoul (iso_date, (char **)&iso_date, 10);
67.531 + if (*iso_date == ':')
67.532 + {
67.533 + /* hh:mm:ss */
67.534 + tm.tm_hour = val;
67.535 + iso_date++;
67.536 + tm.tm_min = strtoul (iso_date, (char **)&iso_date, 10);
67.537 +
67.538 + if (*iso_date++ != ':')
67.539 + return FALSE;
67.540 +
67.541 + tm.tm_sec = strtoul (iso_date, (char **)&iso_date, 10);
67.542 + }
67.543 + else
67.544 + {
67.545 + /* hhmmss */
67.546 + tm.tm_sec = val % 100;
67.547 + tm.tm_min = (val % 10000) / 100;
67.548 + tm.tm_hour = val / 10000;
67.549 + }
67.550 +
67.551 + time_->tv_sec = mktime_utc (&tm);
67.552 + time_->tv_usec = 1;
67.553 +
67.554 + if (*iso_date == '.')
67.555 + time_->tv_usec = strtoul (iso_date + 1, (char **)&iso_date, 10);
67.556 +
67.557 + if (*iso_date == '+' || *iso_date == '-')
67.558 + {
67.559 + gint sign = (*iso_date == '+') ? -1 : 1;
67.560 +
67.561 + val = 60 * strtoul (iso_date + 1, (char **)&iso_date, 10);
67.562 +
67.563 + if (*iso_date == ':')
67.564 + val = 60 * val + strtoul (iso_date + 1, NULL, 10);
67.565 + else
67.566 + val = 60 * (val / 100) + (val % 100);
67.567 +
67.568 + time_->tv_sec += (time_t) (val * sign);
67.569 + }
67.570 +
67.571 + return TRUE;
67.572 +}
67.573 +
67.574 +
67.575 +gchar *
67.576 +g_time_val_to_iso8601 (GTimeVal *time_)
67.577 +{
67.578 + gchar *retval;
67.579 +
67.580 + g_return_val_if_fail (time_->tv_usec >= 0 && time_->tv_usec < G_USEC_PER_SEC, NULL);
67.581 +
67.582 +#define ISO_8601_LEN 21
67.583 +#define ISO_8601_FORMAT "%Y-%m-%dT%H:%M:%SZ"
67.584 + retval = g_new0 (gchar, ISO_8601_LEN + 1);
67.585 +
67.586 + strftime (retval, ISO_8601_LEN,
67.587 + ISO_8601_FORMAT,
67.588 + gmtime (&(time_->tv_sec)));
67.589 +
67.590 + return retval;
67.591 +}
67.592 +
67.593 +
67.594 +/* Hacked from glib 2.10 <gdate.c> */
67.595 +
67.596 +void
67.597 +g_date_set_time_t (GDate *date,
67.598 + time_t timet)
67.599 +{
67.600 + struct tm tm;
67.601 +
67.602 + g_return_if_fail (date != NULL);
67.603 +
67.604 +#ifdef HAVE_LOCALTIME_R
67.605 + localtime_r (&timet, &tm);
67.606 +#else
67.607 + {
67.608 + struct tm *ptm = localtime (&timet);
67.609 +
67.610 + if (ptm == NULL)
67.611 + {
67.612 + /* Happens at least in Microsoft's C library if you pass a
67.613 + * negative time_t. Use 2000-01-01 as default date.
67.614 + */
67.615 +#ifndef G_DISABLE_CHECKS
67.616 + g_return_if_fail_warning (G_LOG_DOMAIN, "g_date_set_time", "ptm != NULL");
67.617 +#endif
67.618 +
67.619 + tm.tm_mon = 0;
67.620 + tm.tm_mday = 1;
67.621 + tm.tm_year = 100;
67.622 + }
67.623 + else
67.624 + memcpy ((void *) &tm, (void *) ptm, sizeof(struct tm));
67.625 + }
67.626 +#endif
67.627 +
67.628 + date->julian = FALSE;
67.629 +
67.630 + date->month = tm.tm_mon + 1;
67.631 + date->day = tm.tm_mday;
67.632 + date->year = tm.tm_year + 1900;
67.633 +
67.634 + g_return_if_fail (g_date_valid_dmy (date->day, date->month, date->year));
67.635 +
67.636 + date->dmy = TRUE;
67.637 +}
67.638 +
67.639 +
67.640 +void
67.641 +g_date_set_time_val (GDate *date,
67.642 + GTimeVal *timeval)
67.643 +{
67.644 + g_date_set_time_t (date, (time_t) timeval->tv_sec);
67.645 +}
67.646 +
67.647 +
67.648 +
67.649 +
67.650 +#endif
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
68.2 +++ b/branches/gmyth-0.1b/src/gmyth_util.h Thu Feb 01 18:42:01 2007 +0000
68.3 @@ -0,0 +1,66 @@
68.4 +/**
68.5 +* GMyth Library
68.6 +*
68.7 +* @file gmyth/gmyth_util.h
68.8 +*
68.9 +* @brief <p> This component provides utility functions.
68.10 +*
68.11 +* Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
68.12 +* @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
68.13 +*
68.14 +*//*
68.15 +*
68.16 +* This program is free software; you can redistribute it and/or modify
68.17 +* it under the terms of the GNU Lesser General Public License as published by
68.18 +* the Free Software Foundation; either version 2 of the License, or
68.19 +* (at your option) any later version.
68.20 +*
68.21 +* This program is distributed in the hope that it will be useful,
68.22 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
68.23 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
68.24 +* GNU General Public License for more details.
68.25 +*
68.26 +* You should have received a copy of the GNU Lesser General Public License
68.27 +* along with this program; if not, write to the Free Software
68.28 +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
68.29 +*/
68.30 +
68.31 +#ifndef GMYTH_UTIL_H_
68.32 +#define GMYTH_UTIL_H_
68.33 +
68.34 +#include <time.h>
68.35 +#include <glib.h>
68.36 +
68.37 +#include "gmyth_stringlist.h"
68.38 +#include "gmyth_backendinfo.h"
68.39 +
68.40 +G_BEGIN_DECLS
68.41 +
68.42 +GString *gmyth_util_time_to_isoformat(time_t time_value);
68.43 +GString *gmyth_util_time_to_string (time_t time_value);
68.44 +time_t gmyth_util_string_to_time (GString* time_str);
68.45 +gint64 gmyth_util_decode_long_long (GMythStringList *strlist,
68.46 + guint offset);
68.47 +
68.48 +gchar* gmyth_util_time_to_isoformat_from_time_val_fmt ( const gchar *fmt_string, const GTimeVal* time_val );
68.49 +
68.50 +GTimeVal *gmyth_util_string_to_time_val_fmt ( const gchar *fmt_string, const gchar* time_str );
68.51 +
68.52 +GTimeVal *gmyth_util_string_to_time_val ( const gchar* time_str );
68.53 +
68.54 +gchar *gmyth_util_time_to_isoformat_from_time_val( const GTimeVal *time);
68.55 +gchar *gmyth_util_time_to_mythformat_from_time_val ( const GTimeVal* time );
68.56 +
68.57 +gchar *gmyth_util_time_to_string_only_date ( const GTimeVal* time );
68.58 +
68.59 +gchar *gmyth_util_time_to_string_only_time ( const GTimeVal* time );
68.60 +
68.61 +gchar *gmyth_util_time_to_string_from_time_val ( const GTimeVal *time_val );
68.62 +
68.63 +struct tm *gmyth_util_time_val_to_date ( const GTimeVal* time );
68.64 +
68.65 +gboolean gmyth_util_file_exists (GMythBackendInfo *backend_info, const gchar* filename);
68.66 +
68.67 +G_END_DECLS
68.68 +
68.69 +#endif /*GMYTH_UTIL_H_*/
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
69.2 +++ b/branches/gmyth-0.1b/tests/Makefile.am Thu Feb 01 18:42:01 2007 +0000
69.3 @@ -0,0 +1,18 @@
69.4 +noinst_PROGRAMS = \
69.5 + test
69.6 +
69.7 +TESTS = \
69.8 + test
69.9 +
69.10 +test_SOURCES = \
69.11 + main.c
69.12 +
69.13 +test_LDADD = \
69.14 + $(MYSQL_LIBS) \
69.15 + $(top_builddir)/src/libgmyth.la
69.16 +
69.17 +AM_CPPFLAGS = \
69.18 + -I$(top_srcdir) \
69.19 + -I$(top_srcdir)/src \
69.20 + $(MYSQL_CFLAGS) \
69.21 + $(GLIB_CFLAGS)
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
70.2 +++ b/branches/gmyth-0.1b/tests/compile_file_exists Thu Feb 01 18:42:01 2007 +0000
70.3 @@ -0,0 +1,1 @@
70.4 +gcc -o test_file_exists test_file_exists.c -DBIG_JOINS=1 -I/usr/include/mysql -I/usr/local/include/gmyth -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -L/usr/local/lib -lmysqlclient -lz -lcrypt -lnsl -lm -lgmyth -lgobject-2.0 -lglib-2.0
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
71.2 +++ b/branches/gmyth-0.1b/tests/compile_test_connection Thu Feb 01 18:42:01 2007 +0000
71.3 @@ -0,0 +1,1 @@
71.4 +gcc -o gmyth_test_connection gmyth_test_connection.c `pkg-config --cflags --libs gmyth-0.1 glib-2.0`
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
72.2 +++ b/branches/gmyth-0.1b/tests/compile_test_recorder Thu Feb 01 18:42:01 2007 +0000
72.3 @@ -0,0 +1,1 @@
72.4 +gcc -o gmyth_test_recorder gmyth_test_recorder.c `pkg-config --cflags --libs gmyth-0.1`
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
73.2 +++ b/branches/gmyth-0.1b/tests/compile_test_recordings Thu Feb 01 18:42:01 2007 +0000
73.3 @@ -0,0 +1,1 @@
73.4 +gcc -o gmyth_test_recordings gmyth_test_recordings.c `pkg-config --cflags --libs gmyth-0.1 glib-2.0`
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
74.2 +++ b/branches/gmyth-0.1b/tests/gmyth_test_connection.c Thu Feb 01 18:42:01 2007 +0000
74.3 @@ -0,0 +1,74 @@
74.4 +#include <glib-object.h>
74.5 +
74.6 +#include "gmyth_uri.h"
74.7 +#include "gmyth_backendinfo.h"
74.8 +#include "gmyth_socket.h"
74.9 +#include "gmyth_query.h"
74.10 +
74.11 +static gboolean
74.12 +test_backend_connection1 (GMythBackendInfo *backend_info)
74.13 +{
74.14 + GMythSocket *socket = gmyth_socket_new ();
74.15 + if (gmyth_socket_connect_with_timeout (socket,
74.16 + gmyth_backend_info_get_hostname (backend_info),
74.17 + gmyth_backend_info_get_port (backend_info), 4) == TRUE) {
74.18 + g_debug ("Socket connection success");
74.19 + return TRUE;
74.20 + } else {
74.21 + g_debug ("Connection failed");
74.22 + return FALSE;
74.23 + }
74.24 +}
74.25 +
74.26 +static gboolean
74.27 +test_backend_connection2 (GMythBackendInfo *backend_info)
74.28 +{
74.29 + GMythSocket *socket = gmyth_socket_new ();
74.30 + if (gmyth_socket_connect_to_backend (socket,
74.31 + gmyth_backend_info_get_hostname (backend_info),
74.32 + gmyth_backend_info_get_port (backend_info), TRUE) == TRUE) {
74.33 +
74.34 +
74.35 + g_debug ("Backend socket connection success");
74.36 + return TRUE;
74.37 + } else {
74.38 + g_debug ("Connection failed");
74.39 + return FALSE;
74.40 + }
74.41 +}
74.42 +
74.43 +static gboolean
74.44 +test_mysql_connection1 (GMythBackendInfo *backend_info)
74.45 +{
74.46 + GMythQuery *query = gmyth_query_new ();
74.47 +
74.48 + if (gmyth_query_connect_with_timeout (query, backend_info, 3) == TRUE) {
74.49 + g_debug ("Mysql connection success");
74.50 + return TRUE;
74.51 + } else {
74.52 + g_debug ("Mysql connection failed");
74.53 + return FALSE;
74.54 + }
74.55 +
74.56 +}
74.57 +
74.58 +
74.59 +int
74.60 +main (int args, const char **argv)
74.61 +{
74.62 + const char* uri = argv[1];
74.63 +
74.64 + GMythBackendInfo *backend_info;
74.65 + g_type_init ();
74.66 + //g_thread_init (NULL);
74.67 +
74.68 + backend_info = gmyth_backend_info_new_with_uri (argv[1]);
74.69 +
74.70 + test_backend_connection1 (backend_info);
74.71 + test_backend_connection2 (backend_info);
74.72 + test_mysql_connection1 (backend_info);
74.73 +}
74.74 +
74.75 +
74.76 +
74.77 +
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
75.2 +++ b/branches/gmyth-0.1b/tests/gmyth_test_epg.c Thu Feb 01 18:42:01 2007 +0000
75.3 @@ -0,0 +1,60 @@
75.4 +
75.5 +#include "gmyth_backendinfo.h"
75.6 +#include "gmyth_epg.h"
75.7 +
75.8 +static gboolean
75.9 +test_epg_connection (GMythBackendInfo *backend_info)
75.10 +{
75.11 + GMythEPG *epg = gmyth_epg_new ();
75.12 + gboolean res = FALSE;
75.13 +
75.14 + res = gmyth_epg_connect (epg, backend_info);
75.15 +
75.16 + gmyth_epg_disconnect (epg);
75.17 + g_object_unref (epg);
75.18 +
75.19 + return res;
75.20 +}
75.21 +
75.22 +
75.23 +static gboolean
75.24 +test_epg_get_channels (GMythBackendInfo *backend_info)
75.25 +{
75.26 + GMythEPG *epg = gmyth_epg_new ();
75.27 + GList *clist;
75.28 + gint i, length;
75.29 +
75.30 + if (!gmyth_epg_connect (epg, backend_info)) {
75.31 + return FALSE;
75.32 + }
75.33 +
75.34 + length = gmyth_epg_get_channel_list (epg, &clist);
75.35 + g_print ("==== %d channels found in the EPG ====\n", length);
75.36 + for (i=0; i<length; i++) {
75.37 + GMythChannelInfo *channel_info = (GMythChannelInfo*) g_list_nth_data (clist, i);
75.38 +
75.39 + gmyth_channel_info_print(channel_info);
75.40 + }
75.41 +
75.42 + g_list_free (clist);
75.43 + gmyth_epg_disconnect (epg);
75.44 + g_object_unref (epg);
75.45 +}
75.46 +
75.47 +int
75.48 +main (int args, const char **argv)
75.49 +{
75.50 + const char* uri = argv[1];
75.51 +
75.52 + GMythBackendInfo *backend_info;
75.53 + g_type_init ();
75.54 + g_thread_init (NULL);
75.55 +
75.56 + backend_info = gmyth_backend_info_new_with_uri (argv[1]);
75.57 +
75.58 + test_epg_connection (backend_info);
75.59 + test_epg_get_channels (backend_info);
75.60 +
75.61 + return 0;
75.62 +}
75.63 +
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
76.2 +++ b/branches/gmyth-0.1b/tests/gmyth_test_recorder.c Thu Feb 01 18:42:01 2007 +0000
76.3 @@ -0,0 +1,123 @@
76.4 +#include <glib-object.h>
76.5 +
76.6 +#include "gmyth_backendinfo.h"
76.7 +#include "gmyth_remote_util.h"
76.8 +#include "gmyth_query.h"
76.9 +#include "gmyth_epg.h"
76.10 +#include "gmyth_common.h"
76.11 +
76.12 +
76.13 +static gboolean
76.14 +test_recorder_availability (GMythBackendInfo *backend_info)
76.15 +{
76.16 + GMythRecorder* recorder;
76.17 + GMythSocket *socket = gmyth_socket_new ();
76.18 +
76.19 + if (gmyth_socket_connect_to_backend (socket,
76.20 + gmyth_backend_info_get_hostname (backend_info),
76.21 + gmyth_backend_info_get_port (backend_info), TRUE) == FALSE) {
76.22 + g_debug ("Test recorder failed: Connection failed");
76.23 + return FALSE;
76.24 + }
76.25 +
76.26 + recorder = remote_request_next_free_recorder (socket, -1);
76.27 + gmyth_socket_close_connection (socket);
76.28 + if (recorder == NULL) {
76.29 + g_debug ("Recorder not available\n");
76.30 + return FALSE;
76.31 + }
76.32 +
76.33 + g_debug ("Recorder found (num): %d", recorder->recorder_num);
76.34 +
76.35 + return TRUE;
76.36 +}
76.37 +
76.38 +static gboolean
76.39 +test_recorder_setup (GMythBackendInfo *backend_info)
76.40 +{
76.41 + GMythQuery *query = gmyth_query_new ();
76.42 +
76.43 + if (gmyth_query_connect_with_timeout (query, backend_info, 3) == TRUE) {
76.44 + g_debug ("Mysql connection success");
76.45 + return TRUE;
76.46 + } else {
76.47 + g_debug ("Mysql connection failed");
76.48 + return FALSE;
76.49 + }
76.50 +
76.51 +}
76.52 +
76.53 +static gboolean
76.54 +test_recorder_check_channels (GMythBackendInfo *backend_info)
76.55 +{
76.56 + GMythRecorder* recorder;
76.57 + GMythSocket *socket = gmyth_socket_new ();
76.58 + GMythEPG *epg = gmyth_epg_new ();
76.59 + GList *clist;
76.60 + gint i, length;
76.61 +
76.62 + // Gets the free recorder
76.63 + if (gmyth_socket_connect_to_backend (socket,
76.64 + gmyth_backend_info_get_hostname (backend_info),
76.65 + gmyth_backend_info_get_port (backend_info), TRUE) == FALSE) {
76.66 + g_debug ("Test recorder failed: Connection failed");
76.67 + return FALSE;
76.68 + }
76.69 +
76.70 + recorder = remote_request_next_free_recorder (socket, -1);
76.71 + gmyth_socket_close_connection (socket);
76.72 + if (recorder == NULL) {
76.73 + g_debug ("[%s] Recorder not available", __FUNCTION__);
76.74 + return FALSE;
76.75 + }
76.76 +
76.77 + // Connects the recorder socket
76.78 + gmyth_recorder_setup (recorder);
76.79 +
76.80 + // Gets the list of channels
76.81 + if (!gmyth_epg_connect (epg, backend_info)) {
76.82 + g_debug ("%s: Not connected\n", __FUNCTION__);
76.83 + return FALSE;
76.84 + }
76.85 +
76.86 + length = gmyth_epg_get_channel_list (epg, &clist);
76.87 + gmyth_epg_disconnect (epg);
76.88 + g_object_unref (epg);
76.89 +
76.90 + g_print ("==== Verifying the %d channels found in the EPG ====\n", length);
76.91 + for (i=0; i<length; i++) {
76.92 + GMythChannelInfo *channel_info = (GMythChannelInfo*) g_list_nth_data (clist, i);
76.93 + gboolean res;
76.94 +
76.95 + // Checks the channels
76.96 + res = gmyth_recorder_check_channel (recorder, channel_info->channel_ID);
76.97 + g_debug ("Channel %d %s", channel_info->channel_ID, res ? "Found" : "Not found");
76.98 + }
76.99 +
76.100 + g_list_free (clist);
76.101 +
76.102 +}
76.103 +
76.104 +
76.105 +int
76.106 +main (int args, const char **argv)
76.107 +{
76.108 + const char* uri = argv[1];
76.109 +
76.110 + GMythBackendInfo *backend_info;
76.111 + g_type_init ();
76.112 + g_thread_init (NULL);
76.113 +
76.114 + backend_info = gmyth_backend_info_new_with_uri (argv[1]);
76.115 +
76.116 + printf ("******** Testing recorder availability ***********\n");
76.117 + test_recorder_availability (backend_info);
76.118 +
76.119 + printf ("******** Testing recorder check channels function ***********\n");
76.120 + test_recorder_check_channels (backend_info);
76.121 +}
76.122 +
76.123 +
76.124 +
76.125 +
76.126 +
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
77.2 +++ b/branches/gmyth-0.1b/tests/gmyth_test_recordings.c Thu Feb 01 18:42:01 2007 +0000
77.3 @@ -0,0 +1,59 @@
77.4 +#include <glib-object.h>
77.5 +
77.6 +#include "gmyth_uri.h"
77.7 +#include "gmyth_backendinfo.h"
77.8 +#include "gmyth_scheduler.h"
77.9 +#include "gmyth_epg.h"
77.10 +#include "gmyth_common.h"
77.11 +
77.12 +static gboolean
77.13 +test_recording_list (GMythBackendInfo *backend_info)
77.14 +{
77.15 + GList *list = NULL;
77.16 + gint length = 0;
77.17 + GMythScheduler *scheduler = gmyth_scheduler_new ();
77.18 +
77.19 + if (gmyth_scheduler_connect_with_timeout (scheduler,
77.20 + backend_info, 10) == TRUE) {
77.21 + g_debug ("===== Scheduler connection success =====");
77.22 + } else {
77.23 + g_debug ("===== Scheduler connection failed =====");
77.24 + return FALSE;
77.25 + }
77.26 +
77.27 + length = gmyth_scheduler_get_recorded_list (scheduler, &list);
77.28 +
77.29 + g_debug ("===== %d Recordings found =====\n", length);
77.30 + length--;
77.31 + while (length >= 0) {
77.32 + RecordedInfo *record = (RecordedInfo*) g_list_nth_data (list, length);
77.33 + if (record == 0) {
77.34 + g_debug ("===== Recorded list returned NULL pointer =====\n");
77.35 + length--;
77.36 + continue;
77.37 + }
77.38 + g_debug ("===== Record id = %d =====\n", record->record_id);
77.39 + g_debug ("===== Record name = %s =====\n", (record ? record->basename->str : "NULL"));
77.40 + length--;
77.41 + }
77.42 +
77.43 + gmyth_scheduler_disconnect (scheduler);
77.44 +
77.45 +}
77.46 +
77.47 +int
77.48 +main (int args, const char **argv)
77.49 +{
77.50 + const char* uri = argv[1];
77.51 +
77.52 + GMythBackendInfo *backend_info;
77.53 + g_type_init ();
77.54 +
77.55 + backend_info = gmyth_backend_info_new_with_uri (argv[1]);
77.56 +
77.57 + test_recording_list (backend_info);
77.58 +}
77.59 +
77.60 +
77.61 +
77.62 +
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
78.2 +++ b/branches/gmyth-0.1b/tests/http.c Thu Feb 01 18:42:01 2007 +0000
78.3 @@ -0,0 +1,24 @@
78.4 +#include <glib-object.h>
78.5 +#include "gmyth.h"
78.6 +#include <glib.h>
78.7 +
78.8 +int
78.9 +main (int args, const char **argv)
78.10 +{
78.11 + GMythBackendInfo *backend_info;
78.12 + g_type_init();
78.13 + //g_thread_init(NULL);
78.14 +
78.15 + backend_info = gmyth_backend_info_new ();
78.16 +
78.17 + gmyth_backend_info_set_hostname (backend_info, "localhost");
78.18 + gmyth_backend_info_set_port (backend_info, 6543);
78.19 +
78.20 + GTimeVal* start = gmyth_util_string_to_time_val("2006-01-01T00:00");
78.21 + GTimeVal* end = gmyth_util_string_to_time_val("2007-01-01T00:00");
78.22 + GMythEpg epg;
78.23 + epg = retrieve_epg(backend_info, 6544, start, end, 0, 2, "True");
78.24 +
78.25 +
78.26 + return 0;
78.27 +}
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
79.2 +++ b/branches/gmyth-0.1b/tests/main.c Thu Feb 01 18:42:01 2007 +0000
79.3 @@ -0,0 +1,49 @@
79.4 +#include <glib-object.h>
79.5 +#include "gmyth.h"
79.6 +
79.7 +int
79.8 +main (int args, const char **argv)
79.9 +{
79.10 + const char *uri = argv[1];
79.11 + GMythURI *gmyth_uri = NULL;
79.12 + gboolean res;
79.13 + GMythBackendInfo *backend_info;
79.14 + g_type_init ();
79.15 + g_thread_init (NULL);
79.16 +
79.17 + backend_info = gmyth_backend_info_new ();
79.18 + gmyth_uri = gmyth_uri_new_with_value (uri);
79.19 +
79.20 + gmyth_backend_info_set_hostname (backend_info, gmyth_uri_get_host (gmyth_uri));
79.21 + gmyth_backend_info_set_port (backend_info, gmyth_uri_get_port (gmyth_uri));
79.22 +
79.23 + res = gmyth_util_file_exists (backend_info, uri);
79.24 + if (res == FALSE) {
79.25 + g_debug ("file not exists");
79.26 + return -1;
79.27 + }
79.28 + GMythFileTransfer *file_transfer = gmyth_file_transfer_new ();
79.29 + GString *hostname = g_string_new (uri);
79.30 + res = gmyth_file_transfer_open (file_transfer, hostname);
79.31 + if (res == FALSE) {
79.32 + g_debug ("Fail to open server");
79.33 + return -1;
79.34 + }
79.35 +
79.36 + guint64 filesize = gmyth_file_transfer_get_filesize (file_transfer);
79.37 + if (filesize <= 0) {
79.38 + g_debug ("filesize is 0");
79.39 + return -1;
79.40 + }
79.41 +
79.42 + GByteArray *data = g_byte_array_new ();
79.43 + guint num = gmyth_file_transfer_read (file_transfer, data, filesize, FALSE);
79.44 + g_debug ("read %d bytes", num);
79.45 +
79.46 + g_byte_array_free (data, TRUE);
79.47 + g_object_unref (file_transfer);
79.48 + g_object_unref (gmyth_uri);
79.49 + g_string_free (hostname, TRUE);
79.50 +
79.51 + return 0;
79.52 +}