[svn r322] created branch gmyth-0.1b trunk
authorrenatofilho
Thu Feb 01 18:42:01 2007 +0000 (2007-02-01)
branchtrunk
changeset 32022a17127789e
parent 319 69382cca242e
child 321 1c020e9ef06d
[svn r322] created branch gmyth-0.1b
branches/gmyth-0.1b/AUTHORS
branches/gmyth-0.1b/COPYING
branches/gmyth-0.1b/ChangeLog
branches/gmyth-0.1b/INSTALL
branches/gmyth-0.1b/Makefile.am
branches/gmyth-0.1b/NEWS
branches/gmyth-0.1b/README
branches/gmyth-0.1b/aminclude.am
branches/gmyth-0.1b/autogen.sh
branches/gmyth-0.1b/common/Makefile.am
branches/gmyth-0.1b/common/autogen-helper.sh
branches/gmyth-0.1b/configure.ac
branches/gmyth-0.1b/data/settings/history.dat
branches/gmyth-0.1b/debian/changelog
branches/gmyth-0.1b/debian/compat
branches/gmyth-0.1b/debian/control
branches/gmyth-0.1b/debian/gmyth-dev.install
branches/gmyth-0.1b/debian/gmyth.install
branches/gmyth-0.1b/debian/rules
branches/gmyth-0.1b/doxygen.cfg
branches/gmyth-0.1b/gmyth.pc.in
branches/gmyth-0.1b/m4/AUTHORS
branches/gmyth-0.1b/m4/COPYING
branches/gmyth-0.1b/m4/ChangeLog
branches/gmyth-0.1b/m4/INSTALL
branches/gmyth-0.1b/m4/Makefile.am
branches/gmyth-0.1b/m4/NEWS
branches/gmyth-0.1b/m4/README
branches/gmyth-0.1b/m4/ac_doxygen.m4
branches/gmyth-0.1b/m4/as-compiler-flag.m4
branches/gmyth-0.1b/m4/as-expand.m4
branches/gmyth-0.1b/m4/as-version.m4
branches/gmyth-0.1b/m4/configure.ac
branches/gmyth-0.1b/src/Makefile.am
branches/gmyth-0.1b/src/gmyth.h
branches/gmyth-0.1b/src/gmyth_backendinfo.c
branches/gmyth-0.1b/src/gmyth_backendinfo.h
branches/gmyth-0.1b/src/gmyth_common.c
branches/gmyth-0.1b/src/gmyth_common.h
branches/gmyth-0.1b/src/gmyth_debug.c
branches/gmyth-0.1b/src/gmyth_debug.h
branches/gmyth-0.1b/src/gmyth_epg.c
branches/gmyth-0.1b/src/gmyth_epg.h
branches/gmyth-0.1b/src/gmyth_file_transfer.c
branches/gmyth-0.1b/src/gmyth_file_transfer.h
branches/gmyth-0.1b/src/gmyth_http.c
branches/gmyth-0.1b/src/gmyth_http.h
branches/gmyth-0.1b/src/gmyth_livetv.c
branches/gmyth-0.1b/src/gmyth_livetv.h
branches/gmyth-0.1b/src/gmyth_marshal.list
branches/gmyth-0.1b/src/gmyth_monitor_handler.c
branches/gmyth-0.1b/src/gmyth_monitor_handler.h
branches/gmyth-0.1b/src/gmyth_programinfo.c
branches/gmyth-0.1b/src/gmyth_programinfo.h
branches/gmyth-0.1b/src/gmyth_query.c
branches/gmyth-0.1b/src/gmyth_query.h
branches/gmyth-0.1b/src/gmyth_recorder.c
branches/gmyth-0.1b/src/gmyth_recorder.h
branches/gmyth-0.1b/src/gmyth_remote_util.c
branches/gmyth-0.1b/src/gmyth_remote_util.h
branches/gmyth-0.1b/src/gmyth_scheduler.c
branches/gmyth-0.1b/src/gmyth_scheduler.h
branches/gmyth-0.1b/src/gmyth_socket.c
branches/gmyth-0.1b/src/gmyth_socket.h
branches/gmyth-0.1b/src/gmyth_stringlist.c
branches/gmyth-0.1b/src/gmyth_stringlist.h
branches/gmyth-0.1b/src/gmyth_tvchain.c
branches/gmyth-0.1b/src/gmyth_tvchain.h
branches/gmyth-0.1b/src/gmyth_uri.c
branches/gmyth-0.1b/src/gmyth_uri.h
branches/gmyth-0.1b/src/gmyth_util.c
branches/gmyth-0.1b/src/gmyth_util.h
branches/gmyth-0.1b/tests/Makefile.am
branches/gmyth-0.1b/tests/compile_file_exists
branches/gmyth-0.1b/tests/compile_test_connection
branches/gmyth-0.1b/tests/compile_test_recorder
branches/gmyth-0.1b/tests/compile_test_recordings
branches/gmyth-0.1b/tests/gmyth_test_connection.c
branches/gmyth-0.1b/tests/gmyth_test_epg.c
branches/gmyth-0.1b/tests/gmyth_test_recorder.c
branches/gmyth-0.1b/tests/gmyth_test_recordings.c
branches/gmyth-0.1b/tests/http.c
branches/gmyth-0.1b/tests/main.c
     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 +}