initial commit
commit
9e9a590bd8
|
@ -0,0 +1,20 @@
|
|||
Main Authors:
|
||||
|
||||
Sven Neumann <sven@gimp.org>
|
||||
Michael Natterer <mitch@gimp.org>
|
||||
Daniel Mack <daniel@yoobay.net>
|
||||
|
||||
|
||||
Blinkenproxy code was originally done by Hannes Mehnert. The Win32 port
|
||||
wouldn't have been possible without the help from Michael Schumacher.
|
||||
|
||||
|
||||
Modules contributed by:
|
||||
|
||||
1stein <1stein@1stein.no-ip.com> (Pacman, Breakout, Retris, Snake, Xxo)
|
||||
Simon Budig <simon@gimp.org> (Matrix)
|
||||
|
||||
|
||||
Views contributed by:
|
||||
|
||||
pix <pix@test.at> (BView-AA)
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,229 @@
|
|||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
will cause the specified gcc to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
## Makefile.am for blib
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = blib gfx modules test data docs
|
||||
|
||||
if HAVE_AA
|
||||
AA_PC = blib-aa.pc
|
||||
endif
|
||||
|
||||
if HAVE_DIRECTFB
|
||||
DIRECTFB_PC = blib-directfb.pc
|
||||
endif
|
||||
|
||||
if HAVE_GTK
|
||||
GTK_PC = blib-gtk.pc
|
||||
endif
|
||||
|
||||
if HAVE_PIXBUF
|
||||
PIXBUF_PC = blib-pixbuf.pc
|
||||
endif
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = \
|
||||
blib.pc \
|
||||
$(AA_PC) \
|
||||
$(DIRECTFB_PC) \
|
||||
$(GTK_PC) \
|
||||
$(PIXBUF_PC)
|
||||
|
||||
EXTRA_DIST = \
|
||||
autogen.sh \
|
||||
debian/changelog \
|
||||
debian/control \
|
||||
debian/copyright \
|
||||
debian/dirs \
|
||||
debian/docs \
|
||||
debian/files \
|
||||
debian/libblib-dev.files \
|
||||
debian/libblib-directfb-dev.files\
|
||||
debian/libblib-directfb.files \
|
||||
debian/libblib-gtk-dev.files \
|
||||
debian/libblib-gtk.files \
|
||||
debian/libblib.files \
|
||||
debian/rules
|
|
@ -0,0 +1,676 @@
|
|||
# Makefile.in generated by automake 1.7.9 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
# Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = .
|
||||
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_triplet = @host@
|
||||
AA_LIBS = @AA_LIBS@
|
||||
AA_VIEW_TYPE = @AA_VIEW_TYPE@
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BLIB_BINARY_AGE = @BLIB_BINARY_AGE@
|
||||
BLIB_INTERFACE_AGE = @BLIB_INTERFACE_AGE@
|
||||
BLIB_MAJOR_VERSION = @BLIB_MAJOR_VERSION@
|
||||
BLIB_MICRO_VERSION = @BLIB_MICRO_VERSION@
|
||||
BLIB_MINOR_VERSION = @BLIB_MINOR_VERSION@
|
||||
BLIB_VERSION = @BLIB_VERSION@
|
||||
BUILD_MODULES_FALSE = @BUILD_MODULES_FALSE@
|
||||
BUILD_MODULES_TRUE = @BUILD_MODULES_TRUE@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DATADIR = @DATADIR@
|
||||
DB2HTML = @DB2HTML@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@
|
||||
DIRECTFB_LIBS = @DIRECTFB_LIBS@
|
||||
DIRECTFB_VIEW_TYPE = @DIRECTFB_VIEW_TYPE@
|
||||
ECHO = @ECHO@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ENABLE_GTK_DOC_FALSE = @ENABLE_GTK_DOC_FALSE@
|
||||
ENABLE_GTK_DOC_TRUE = @ENABLE_GTK_DOC_TRUE@
|
||||
EXEEXT = @EXEEXT@
|
||||
F77 = @F77@
|
||||
FFLAGS = @FFLAGS@
|
||||
GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@
|
||||
GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@
|
||||
GLIB_CFLAGS = @GLIB_CFLAGS@
|
||||
GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
|
||||
GLIB_LIBS = @GLIB_LIBS@
|
||||
GLIB_MKENUMS = @GLIB_MKENUMS@
|
||||
GOBJECT_QUERY = @GOBJECT_QUERY@
|
||||
GTKDOC = @GTKDOC@
|
||||
GTK_CFLAGS = @GTK_CFLAGS@
|
||||
GTK_LIBS = @GTK_LIBS@
|
||||
GTK_VIEW_TYPE = @GTK_VIEW_TYPE@
|
||||
HAVE_AA_FALSE = @HAVE_AA_FALSE@
|
||||
HAVE_AA_TRUE = @HAVE_AA_TRUE@
|
||||
HAVE_DIRECTFB_FALSE = @HAVE_DIRECTFB_FALSE@
|
||||
HAVE_DIRECTFB_TRUE = @HAVE_DIRECTFB_TRUE@
|
||||
HAVE_DOCBOOK_FALSE = @HAVE_DOCBOOK_FALSE@
|
||||
HAVE_DOCBOOK_TRUE = @HAVE_DOCBOOK_TRUE@
|
||||
HAVE_GTK_DOC = @HAVE_GTK_DOC@
|
||||
HAVE_GTK_DOC_FALSE = @HAVE_GTK_DOC_FALSE@
|
||||
HAVE_GTK_DOC_TRUE = @HAVE_GTK_DOC_TRUE@
|
||||
HAVE_GTK_FALSE = @HAVE_GTK_FALSE@
|
||||
HAVE_GTK_TRUE = @HAVE_GTK_TRUE@
|
||||
HAVE_PIXBUF_FALSE = @HAVE_PIXBUF_FALSE@
|
||||
HAVE_PIXBUF_TRUE = @HAVE_PIXBUF_TRUE@
|
||||
HTML_DIR = @HTML_DIR@
|
||||
INCLUDEDIR = @INCLUDEDIR@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_AGE = @LT_AGE@
|
||||
LT_CURRENT = @LT_CURRENT@
|
||||
LT_RELEASE = @LT_RELEASE@
|
||||
LT_REVISION = @LT_REVISION@
|
||||
MAINT = @MAINT@
|
||||
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
|
||||
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MODULEPATH = @MODULEPATH@
|
||||
OBJEXT = @OBJEXT@
|
||||
OS_WIN32_FALSE = @OS_WIN32_FALSE@
|
||||
OS_WIN32_TRUE = @OS_WIN32_TRUE@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PIXBUF_VIEW_TYPE = @PIXBUF_VIEW_TYPE@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
RANLIB = @RANLIB@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
THEMEPATH = @THEMEPATH@
|
||||
VERSION = @VERSION@
|
||||
WIN32_CFLAGS = @WIN32_CFLAGS@
|
||||
WIN32_LIBS = @WIN32_LIBS@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_F77 = @ac_ct_F77@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
|
||||
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
oldincludedir = @oldincludedir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
|
||||
SUBDIRS = blib gfx modules test data docs
|
||||
|
||||
@HAVE_AA_TRUE@AA_PC = blib-aa.pc
|
||||
|
||||
@HAVE_DIRECTFB_TRUE@DIRECTFB_PC = blib-directfb.pc
|
||||
|
||||
@HAVE_GTK_TRUE@GTK_PC = blib-gtk.pc
|
||||
|
||||
@HAVE_PIXBUF_TRUE@PIXBUF_PC = blib-pixbuf.pc
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = \
|
||||
blib.pc \
|
||||
$(AA_PC) \
|
||||
$(DIRECTFB_PC) \
|
||||
$(GTK_PC) \
|
||||
$(PIXBUF_PC)
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
autogen.sh \
|
||||
debian/changelog \
|
||||
debian/control \
|
||||
debian/copyright \
|
||||
debian/dirs \
|
||||
debian/docs \
|
||||
debian/files \
|
||||
debian/libblib-dev.files \
|
||||
debian/libblib-directfb-dev.files\
|
||||
debian/libblib-directfb.files \
|
||||
debian/libblib-gtk-dev.files \
|
||||
debian/libblib-gtk.files \
|
||||
debian/libblib.files \
|
||||
debian/rules
|
||||
|
||||
subdir = .
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = config.h
|
||||
CONFIG_CLEAN_FILES = blib.pc blib-aa.pc blib-directfb.pc blib-gtk.pc \
|
||||
blib-pixbuf.pc
|
||||
DIST_SOURCES =
|
||||
DATA = $(pkgconfig_DATA)
|
||||
|
||||
|
||||
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
|
||||
ps-recursive install-info-recursive uninstall-info-recursive \
|
||||
all-recursive install-data-recursive install-exec-recursive \
|
||||
installdirs-recursive install-recursive uninstall-recursive \
|
||||
check-recursive installcheck-recursive
|
||||
DIST_COMMON = README $(srcdir)/Makefile.in $(srcdir)/configure AUTHORS \
|
||||
COPYING ChangeLog INSTALL Makefile.am NEWS aclocal.m4 \
|
||||
blib-aa.pc.in blib-directfb.pc.in blib-gtk.pc.in \
|
||||
blib-pixbuf.pc.in blib.pc.in config.guess config.h.in \
|
||||
config.sub configure configure.in depcomp install-sh ltmain.sh \
|
||||
missing mkinstalldirs
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
all: config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||
configure.lineno
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu Makefile
|
||||
Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
|
||||
|
||||
$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
$(SHELL) ./config.status --recheck
|
||||
$(srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
|
||||
cd $(srcdir) && $(AUTOCONF)
|
||||
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in
|
||||
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||
|
||||
config.h: stamp-h1
|
||||
@if test ! -f $@; then \
|
||||
rm -f stamp-h1; \
|
||||
$(MAKE) stamp-h1; \
|
||||
else :; fi
|
||||
|
||||
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
|
||||
@rm -f stamp-h1
|
||||
cd $(top_builddir) && $(SHELL) ./config.status config.h
|
||||
|
||||
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOHEADER)
|
||||
touch $(srcdir)/config.h.in
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f config.h stamp-h1
|
||||
blib.pc: $(top_builddir)/config.status blib.pc.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
blib-aa.pc: $(top_builddir)/config.status blib-aa.pc.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
blib-directfb.pc: $(top_builddir)/config.status blib-directfb.pc.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
blib-gtk.pc: $(top_builddir)/config.status blib-gtk.pc.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
blib-pixbuf.pc: $(top_builddir)/config.status blib-pixbuf.pc.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool
|
||||
uninstall-info-am:
|
||||
pkgconfigDATA_INSTALL = $(INSTALL_DATA)
|
||||
install-pkgconfigDATA: $(pkgconfig_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(pkgconfigdir)
|
||||
@list='$(pkgconfig_DATA)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(pkgconfigDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgconfigdir)/$$f"; \
|
||||
$(pkgconfigDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgconfigdir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-pkgconfigDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(pkgconfig_DATA)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(pkgconfigdir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(pkgconfigdir)/$$f; \
|
||||
done
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run `make' without going through this Makefile.
|
||||
# To change the values of `make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in `config.status', edit `config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||
# (2) otherwise, pass the desired values on the `make' command line.
|
||||
$(RECURSIVE_TARGETS):
|
||||
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||
maintainer-clean-recursive:
|
||||
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||
dot_seen=no; \
|
||||
case "$@" in \
|
||||
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||
*) list='$(SUBDIRS)' ;; \
|
||||
esac; \
|
||||
rev=''; for subdir in $$list; do \
|
||||
if test "$$subdir" = "."; then :; else \
|
||||
rev="$$subdir $$rev"; \
|
||||
fi; \
|
||||
done; \
|
||||
rev="$$rev ."; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
for subdir in $$rev; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done && test -z "$$fail"
|
||||
tags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||
done
|
||||
ctags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
|
||||
done
|
||||
|
||||
ETAGS = etags
|
||||
ETAGSFLAGS =
|
||||
|
||||
CTAGS = ctags
|
||||
CTAGSFLAGS =
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
|
||||
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
if (etags --etags-include --version) >/dev/null 2>&1; then \
|
||||
include_option=--etags-include; \
|
||||
else \
|
||||
include_option=--include; \
|
||||
fi; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -f $$subdir/TAGS && \
|
||||
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
ctags: CTAGS
|
||||
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
top_distdir = .
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
|
||||
am__remove_distdir = \
|
||||
{ test ! -d $(distdir) \
|
||||
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
|
||||
&& rm -fr $(distdir); }; }
|
||||
|
||||
GZIP_ENV = --best
|
||||
distuninstallcheck_listfiles = find . -type f -print
|
||||
distcleancheck_listfiles = find . -type f -print
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
$(am__remove_distdir)
|
||||
mkdir $(distdir)
|
||||
$(mkinstalldirs) $(distdir)/. $(distdir)/debian $(distdir)/docs/reference
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkinstalldirs) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -d $(distdir)/$$subdir \
|
||||
|| mkdir $(distdir)/$$subdir \
|
||||
|| exit 1; \
|
||||
(cd $$subdir && \
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$(top_distdir)" \
|
||||
distdir=../$(distdir)/$$subdir \
|
||||
distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
|
||||
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|
||||
|| chmod -R a+r $(distdir)
|
||||
dist-gzip: distdir
|
||||
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist dist-all: distdir
|
||||
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
# This target untars the dist file and tries a VPATH configuration. Then
|
||||
# it guarantees that the distribution is self-contained by making another
|
||||
# tarfile.
|
||||
distcheck: dist
|
||||
$(am__remove_distdir)
|
||||
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
|
||||
chmod -R a-w $(distdir); chmod a+w $(distdir)
|
||||
mkdir $(distdir)/_build
|
||||
mkdir $(distdir)/_inst
|
||||
chmod a-w $(distdir)
|
||||
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
|
||||
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
|
||||
&& cd $(distdir)/_build \
|
||||
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
|
||||
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
|
||||
distuninstallcheck \
|
||||
&& chmod -R a-w "$$dc_install_base" \
|
||||
&& ({ \
|
||||
(cd ../.. && $(mkinstalldirs) "$$dc_destdir") \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
|
||||
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
|
||||
} || { rm -rf "$$dc_destdir"; exit 1; }) \
|
||||
&& rm -rf "$$dc_destdir" \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
|
||||
&& rm -f $(distdir).tar.gz \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
|
||||
$(am__remove_distdir)
|
||||
@echo "$(distdir).tar.gz is ready for distribution" | \
|
||||
sed 'h;s/./=/g;p;x;p;x'
|
||||
distuninstallcheck:
|
||||
@cd $(distuninstallcheck_dir) \
|
||||
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|
||||
|| { echo "ERROR: files left after uninstall:" ; \
|
||||
if test -n "$(DESTDIR)"; then \
|
||||
echo " (check DESTDIR support)"; \
|
||||
fi ; \
|
||||
$(distuninstallcheck_listfiles) ; \
|
||||
exit 1; } >&2
|
||||
distcleancheck: distclean
|
||||
@if test '$(srcdir)' = . ; then \
|
||||
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|
||||
|| { echo "ERROR: files left in build directory after distclean:" ; \
|
||||
$(distcleancheck_listfiles) ; \
|
||||
exit 1; } >&2
|
||||
check-am: all-am
|
||||
check: check-recursive
|
||||
all-am: Makefile $(DATA) config.h
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
$(mkinstalldirs) $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
install: install-recursive
|
||||
install-exec: install-exec-recursive
|
||||
install-data: install-data-recursive
|
||||
uninstall: uninstall-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-recursive
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-recursive
|
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-hdr distclean-libtool \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-recursive
|
||||
|
||||
dvi-am:
|
||||
|
||||
info: info-recursive
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-pkgconfigDATA
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-info: install-info-recursive
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
pdf: pdf-recursive
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-recursive
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-info-am uninstall-pkgconfigDATA
|
||||
|
||||
uninstall-info: uninstall-info-recursive
|
||||
|
||||
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
|
||||
clean-generic clean-libtool clean-recursive ctags \
|
||||
ctags-recursive dist dist-all dist-gzip distcheck distclean \
|
||||
distclean-generic distclean-hdr distclean-libtool \
|
||||
distclean-recursive distclean-tags distcleancheck distdir \
|
||||
distuninstallcheck dvi dvi-am dvi-recursive info info-am \
|
||||
info-recursive install install-am install-data install-data-am \
|
||||
install-data-recursive install-exec install-exec-am \
|
||||
install-exec-recursive install-info install-info-am \
|
||||
install-info-recursive install-man install-pkgconfigDATA \
|
||||
install-recursive install-strip installcheck installcheck-am \
|
||||
installdirs installdirs-am installdirs-recursive \
|
||||
maintainer-clean maintainer-clean-generic \
|
||||
maintainer-clean-recursive mostlyclean mostlyclean-generic \
|
||||
mostlyclean-libtool mostlyclean-recursive pdf pdf-am \
|
||||
pdf-recursive ps ps-am ps-recursive tags tags-recursive \
|
||||
uninstall uninstall-am uninstall-info-am \
|
||||
uninstall-info-recursive uninstall-pkgconfigDATA \
|
||||
uninstall-recursive
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
|
@ -0,0 +1,120 @@
|
|||
blib 1.1.7 (development release)
|
||||
----------
|
||||
- added BViewPixbuf, renders still frames
|
||||
- let BViewGtk use BViewPixbuf
|
||||
- added BProxyServer, implementing the server side of the
|
||||
blinkenproxy protocol
|
||||
|
||||
blib 1.1.6 (development release)
|
||||
----------
|
||||
- optimizations to BViewGtk; makes blinkensim-gtk perform a lot better
|
||||
- bug-fixes in the XML loader
|
||||
- module fixes for multi-player
|
||||
|
||||
blib 1.1.5 (development release)
|
||||
----------
|
||||
- added Win32 port
|
||||
|
||||
blib 1.1.4 (development release)
|
||||
----------
|
||||
- added an aalib based BView
|
||||
- improved some modules, most namely BCountdown
|
||||
- bug-fixes in the GIF loader
|
||||
|
||||
blib 1.1.3 (development release)
|
||||
----------
|
||||
- bug-fixes in the GIF loader
|
||||
- minor optimizations in the GTK+ view
|
||||
|
||||
blib 1.1.2 (development release)
|
||||
----------
|
||||
- added BProxyClient to be used from blinkensim
|
||||
|
||||
blib 1.1.1 (development release)
|
||||
----------
|
||||
- fixed use of network sockets on FreeBSD
|
||||
- added files to build debian packages
|
||||
- some minor bugfixes
|
||||
|
||||
blib 1.1.0 (development release)
|
||||
----------
|
||||
- added new modules BRetris, BSnake, Bxxo
|
||||
- added hooks to allow implementation of blinkenproxy (in blinkentools)
|
||||
- added compatibility with the old-style blinken network protocol
|
||||
|
||||
blib 1.0.1
|
||||
----------
|
||||
- added new module BCountdown
|
||||
- added a new large digits font
|
||||
- fixed some bugs
|
||||
|
||||
blib 1.0.0
|
||||
----------
|
||||
- added new modules BClock, BDropout, BMatrix, BPushLine and BText
|
||||
- extended themes framework to allow to specify overlay images for
|
||||
the different intensity values
|
||||
- added b_movie_apply_colormap()
|
||||
- documented the API
|
||||
- fixed some bugs
|
||||
|
||||
blib 0.9
|
||||
--------
|
||||
- more changes to BModule, added describe and relax methods
|
||||
- added module properties to allow customization of modules
|
||||
- added value transform functions so we can deserialize property values
|
||||
- allow to register filename properties
|
||||
- added lots of new modules: BPacman, BPong, BBreakout, BProxy and BDebug
|
||||
- improved the existing module implementations
|
||||
- added a first draft of the multiplayer API (still subject to changes)
|
||||
|
||||
blib 0.8
|
||||
--------
|
||||
- improved BModule API
|
||||
- teached the BModule base class how to run a module
|
||||
- added new modules BQix and BFire
|
||||
- improved BMoviePlayer
|
||||
- added simple graphics functions to be used by modules
|
||||
- added optimized blending functions to the GTK+ view
|
||||
|
||||
blib 0.7
|
||||
--------
|
||||
- added BTetris, the tetris game as a BModule
|
||||
- added BMoviePlayer, a builtin BModule that plays movies
|
||||
- cleaned up bprotocol header file
|
||||
- improved BThemes, the file format is more flexible but still simpler
|
||||
- optimized the GTK+ view so that it is actually useable
|
||||
- moved themes into their own package: blinkenthemes
|
||||
- misc bug fixes and enhancements
|
||||
|
||||
blib 0.6
|
||||
--------
|
||||
- BModule improvements, the API looks reasonably well now
|
||||
- reworked BTheme once again
|
||||
- added a preliminary BNF and Gondwana themes
|
||||
- added BViewGtk and BViewDirectFB that implement views using BTheme
|
||||
- improved documentation of the file formats
|
||||
|
||||
blib 0.5
|
||||
--------
|
||||
- added BSender
|
||||
- fixed various bugs
|
||||
- more BTheme improvements, started to add more themes
|
||||
- improved BModule a lot, added a simple game for testing
|
||||
- fixed various bugs
|
||||
|
||||
blib 0.4
|
||||
--------
|
||||
- added BReceiver
|
||||
- added BModule, the parent class of all game modules
|
||||
- cleaned up the BML DTD
|
||||
- cleaned up BTheme API
|
||||
- fixed various bugs
|
||||
|
||||
blib 0.3
|
||||
--------
|
||||
- added simple frame and movie effects
|
||||
- added BModule framework that we'll need for the games API
|
||||
|
||||
blib 0.2
|
||||
--------
|
||||
- initial public release
|
|
@ -0,0 +1,102 @@
|
|||
BLib - Library of useful things to hack the Blinkenlights
|
||||
---------------------------------------------------------
|
||||
|
||||
This version (1.1.7) is a development release that adds a number of
|
||||
new features that haven't seen much testing yet. Future 1.1.x releases
|
||||
might change the newly added API. When the new API has settled and all
|
||||
new features are tested, we will do a stable blib-1.2 release.
|
||||
|
||||
This library contains some code that you will find useful if
|
||||
you want to create any kind of software related to Blinkenlights.
|
||||
If you have never heard about Blinkenlights, you want to check
|
||||
http://www.blinkenlights.de/ first.
|
||||
|
||||
There is code to read and write the old-style BLM movie format
|
||||
as well as code to handle GIF files and the new Blinkenlights
|
||||
Markup Language. Actually you don't have to care much since this
|
||||
is all hidden in the BMovie object.
|
||||
|
||||
Both sides of the Blinkenlights network protocol are implemented
|
||||
so that you don't have to care about the details.
|
||||
|
||||
The BModule object defines an API for games and the like. The
|
||||
modules directory contains some BModule implementations.
|
||||
|
||||
Last but not least there is code that reads Blinkenthemes. Based on
|
||||
these themes, there are views for DirectFB, GTK+-2.0, GdkPixbuf and
|
||||
aalib that you can use to implement graphical viewers and editors.
|
||||
You will want to download the blinkenthemes package.
|
||||
|
||||
We suggest you also download blinkentools and blinkensim. Both
|
||||
packages make heavy use of BLib.
|
||||
|
||||
|
||||
Requirements:
|
||||
-------------
|
||||
|
||||
BLib requires glib-2.0. You'll also need pkg-config to build BLib.
|
||||
The configure script should detect whether you have DirectFB, GTK+-2.0
|
||||
and/or aalib installed and will skip building some parts of BLib if
|
||||
you don't have these libraries.
|
||||
|
||||
This software is known to compile and work on Linux, FreeBSD, MacOS X
|
||||
and Win32 (using the MinGW environment; see http://www.mingw.org/).
|
||||
|
||||
|
||||
Installation:
|
||||
-------------
|
||||
|
||||
BLib is configured, built and installed the usual way. Read the file
|
||||
INSTALL or simply try to run
|
||||
|
||||
./configure; make; make install
|
||||
|
||||
BLib will install a couple of pkg-config files into the prefix. These
|
||||
are used by application to detect your blib installation. If BLib is
|
||||
installed into a different prefix than the pkg-config utility, you
|
||||
will want to adapt your PKG_CONFIG_PATH accordingly. See the man-page
|
||||
for pkg-config(1).
|
||||
|
||||
|
||||
Legal Disclaimer:
|
||||
-----------------
|
||||
|
||||
(c) Copyright 2002-2004 The Blinkenlights Crew All rights reversed.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The complete text of the license is found in the file COPYING.
|
||||
|
||||
A list of authors is included with this package in the file AUTHORS.
|
||||
|
||||
|
||||
The BFire module contains code taken from aafire which is distributed
|
||||
with aalib. AAlib rules, nuff respect to the AA crew!
|
||||
|
||||
|
||||
BQix was inspired by the qix hack from the xscreensaver distribution.
|
||||
I haven't copied from the code but since I had a look at the
|
||||
implementation, let's credit Jamie Zawinski as well.
|
||||
|
||||
|
||||
BMatrix is based on the Matrix hack from the xscreensaver package which
|
||||
comes with the following copyright notice:
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and
|
||||
its documentation for any purpose is hereby granted without fee, provided
|
||||
that the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation. No representations are made about the suitability of this
|
||||
software for any purpose. It is provided "as is" without express or
|
||||
implied warranty.
|
||||
|
||||
|
||||
The code to load and save GIF images contained in this package is
|
||||
loosely based on the GIF plug-in for The GIMP which appears to have
|
||||
had this copyright notices at one point in time:
|
||||
|
||||
GIMP plug-in written by Adam D. Moss <adam@gimp.org> <adam@foxbox.org>
|
||||
Based around original GIF code by David Koblas.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,159 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This script does all the magic calls to automake/autoconf and
|
||||
# friends that are needed to configure a cvs checkout. You need a
|
||||
# couple of extra development tools to run this script successfully.
|
||||
#
|
||||
# If you are compiling from a released tarball you don't need these
|
||||
# tools and you shouldn't use this script. Just call ./configure
|
||||
# directly.
|
||||
|
||||
|
||||
PROJECT="blib"
|
||||
TEST_TYPE=-f
|
||||
FILE=blib/blib.h
|
||||
|
||||
LIBTOOL_REQUIRED_VERSION=1.3.4
|
||||
AUTOCONF_REQUIRED_VERSION=2.13
|
||||
AUTOMAKE_REQUIRED_VERSION=1.4
|
||||
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
ORIGDIR=`pwd`
|
||||
cd $srcdir
|
||||
|
||||
|
||||
check_version ()
|
||||
{
|
||||
if expr $1 \>= $2 > /dev/null; then
|
||||
echo "yes (version $1)"
|
||||
else
|
||||
echo "Too old (found version $1)!"
|
||||
DIE=1
|
||||
fi
|
||||
}
|
||||
|
||||
echo
|
||||
echo "I am testing that you have the required versions of libtool, autoconf,"
|
||||
echo "and automake."
|
||||
echo
|
||||
|
||||
DIE=0
|
||||
|
||||
|
||||
# check if libtool is called libtool or glibtool for Mac OS X compatibility
|
||||
|
||||
if (libtoolize --version) < /dev/null > /dev/null 2>&1; then
|
||||
LIBTOOLIZE=libtoolize
|
||||
else
|
||||
if (glibtoolize --version) < /dev/null > /dev/null 2>&1; then
|
||||
LIBTOOLIZE=glibtoolize
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -n "checking for libtool >= $LIBTOOL_REQUIRED_VERSION ... "
|
||||
if ($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1; then
|
||||
VER=`$LIBTOOLIZE --version \
|
||||
| grep libtool | sed "s/.* \([0-9.]*\)[-a-z0-9]*$/\1/"`
|
||||
check_version $VER $LIBTOOL_REQUIRED_VERSION
|
||||
else
|
||||
echo
|
||||
echo " You must have libtool installed to compile $PROJECT."
|
||||
echo " Install the appropriate package for your distribution,"
|
||||
echo " or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1;
|
||||
fi
|
||||
|
||||
echo -n "checking for autoconf >= $AUTOCONF_REQUIRED_VERSION ... "
|
||||
if (autoconf --version) < /dev/null > /dev/null 2>&1; then
|
||||
VER=`autoconf --version \
|
||||
| grep -iw autoconf | sed "s/.* \([0-9.]*\)[-a-z0-9]*$/\1/"`
|
||||
check_version $VER $AUTOCONF_REQUIRED_VERSION
|
||||
else
|
||||
echo
|
||||
echo " You must have autoconf installed to compile $PROJECT."
|
||||
echo " Download the appropriate package for your distribution,"
|
||||
echo " or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1;
|
||||
fi
|
||||
|
||||
echo -n "checking for automake >= $AUTOMAKE_REQUIRED_VERSION ... "
|
||||
if (automake --version) < /dev/null > /dev/null 2>&1; then
|
||||
VER=`automake --version \
|
||||
| grep automake | sed "s/.* \([0-9.]*\)[-a-z0-9]*$/\1/"`
|
||||
check_version $VER $AUTOMAKE_REQUIRED_VERSION
|
||||
else
|
||||
echo
|
||||
echo " You must have automake installed to compile $PROJECT."
|
||||
echo " Get ftp://ftp.cygnus.com/pub/home/tromey/automake-1.4p1.tar.gz"
|
||||
echo " (or a newer version if it is available)"
|
||||
DIE=1
|
||||
fi
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
echo
|
||||
echo "Please install/upgrade the missing tools and call me again."
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
test $TEST_TYPE $FILE || {
|
||||
echo
|
||||
echo "You must run this script in the top-level $PROJECT directory."
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
if test -z "$*"; then
|
||||
echo
|
||||
echo "I am going to run ./configure with no arguments - if you wish "
|
||||
echo "to pass any to it, please specify them on the $0 command line."
|
||||
echo
|
||||
fi
|
||||
|
||||
|
||||
case $CC in
|
||||
*xlc | *xlc\ * | *lcc | *lcc\ *)
|
||||
am_opt=--include-deps
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$ACLOCAL_FLAGS"; then
|
||||
|
||||
acdir=`aclocal --print-ac-dir`
|
||||
m4list="glib-2.0.m4"
|
||||
|
||||
for file in $m4list
|
||||
do
|
||||
if [ ! -f "$acdir/$file" ]; then
|
||||
echo
|
||||
echo "WARNING: aclocal's directory is $acdir, but..."
|
||||
echo " no file $acdir/$file"
|
||||
echo " You may see fatal macro warnings below."
|
||||
echo " If these files are installed in /some/dir, set the ACLOCAL_FLAGS "
|
||||
echo " environment variable to \"-I /some/dir\", or install"
|
||||
echo " $acdir/$file."
|
||||
echo
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
aclocal $ACLOCAL_FLAGS
|
||||
|
||||
# optionally feature autoheader
|
||||
(autoheader --version) < /dev/null > /dev/null 2>&1 && autoheader
|
||||
|
||||
automake --add-missing $am_opt
|
||||
autoconf
|
||||
|
||||
$LIBTOOLIZE --copy --force
|
||||
|
||||
cd $ORIGDIR
|
||||
|
||||
$srcdir/configure --enable-maintainer-mode "$@"
|
||||
|
||||
echo
|
||||
echo "Now type 'make' to compile $PROJECT."
|
|
@ -0,0 +1,11 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: blib-aa
|
||||
Description: Library to display the Blinkenlights using AA-lib
|
||||
Version: @VERSION@
|
||||
Requires: blib = @VERSION@
|
||||
Libs: -L${libdir} -lb-aa @AA_LIBS@
|
||||
Cflags: -I@INCLUDEDIR@
|
|
@ -0,0 +1,11 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: blib-directfb
|
||||
Description: Library to display the Blinkenlights on DirectFB
|
||||
Version: @VERSION@
|
||||
Requires: blib = @VERSION@, directfb >= 0.9.11
|
||||
Libs: -L${libdir} -lb-directfb
|
||||
Cflags: -I@INCLUDEDIR@
|
|
@ -0,0 +1,11 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: blib-gtk
|
||||
Description: Library to display the Blinkenlights on GTK+
|
||||
Version: @VERSION@
|
||||
Requires: blib-pixbuf = @VERSION@, gtk+-2.0 >= 2.0.3
|
||||
Libs: -L${libdir} -lb-gtk
|
||||
Cflags: -I@INCLUDEDIR@
|
|
@ -0,0 +1,11 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: blib-pixbuf
|
||||
Description: Library to render the Blinkenlights on a GdkPixbuf
|
||||
Version: @VERSION@
|
||||
Requires: blib = @VERSION@, gdk-pixbuf-2.0 >= 2.0.0
|
||||
Libs: -L${libdir} -lb-pixbuf
|
||||
Cflags: -I@INCLUDEDIR@
|
|
@ -0,0 +1,14 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
datadir=@DATADIR@
|
||||
modulepath=@MODULEPATH@
|
||||
themepath=@THEMEPATH@
|
||||
|
||||
Name: blib
|
||||
Description: Library of useful things to hack the Blinkenlights
|
||||
Version: @VERSION@
|
||||
Requires: gobject-2.0 >= 2.0.1
|
||||
Libs: -L${libdir} -lb @WIN32_LIBS@
|
||||
Cflags: -I@INCLUDEDIR@ @WIN32_CFLAGS@
|
|
@ -0,0 +1,127 @@
|
|||
## Makefile.am for blib/blib
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
$(CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DTHEMEPATH=\"$(THEMEPATH)\" \
|
||||
-DMODULEPATH=\"$(MODULEPATH)\"
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
@GLIB_CFLAGS@
|
||||
|
||||
lib_LTLIBRARIES = libb.la
|
||||
|
||||
libb_la_includedir = $(INCLUDEDIR)/blib
|
||||
|
||||
libb_gif_public_headers = \
|
||||
gif-load.h \
|
||||
gif-save.h \
|
||||
gif-types.h
|
||||
|
||||
libb_gif_sources = \
|
||||
gif-load.c \
|
||||
gif-save.c
|
||||
|
||||
libb_la_include_HEADERS = \
|
||||
blib.h \
|
||||
btypes.h \
|
||||
beffects.h \
|
||||
bmovie.h \
|
||||
bmovie-blm.h \
|
||||
bmovie-bml.h \
|
||||
bmovie-gif.h \
|
||||
bmovie-effects.h \
|
||||
bobject.h \
|
||||
bparams.h \
|
||||
bpacket.h \
|
||||
bparser.h \
|
||||
btheme.h \
|
||||
bthemes.h \
|
||||
bproxyclient.h \
|
||||
bproxyserver.h \
|
||||
breceiver.h \
|
||||
bsender.h \
|
||||
bsocket.h \
|
||||
butils.h \
|
||||
bwriter.h \
|
||||
bprotocol.h \
|
||||
bmodule.h \
|
||||
bmodule-internal.h \
|
||||
bmodule-utils.h \
|
||||
bmoduleinfo.h \
|
||||
bmovieplayer.h \
|
||||
$(libb_gif_public_headers)
|
||||
|
||||
libb_la_sources = \
|
||||
blib.c \
|
||||
beffects.c \
|
||||
bmodule.c \
|
||||
bmodule-utils.c \
|
||||
bmoduleinfo.c \
|
||||
bmovieplayer.c \
|
||||
bmovie.c \
|
||||
bmovie-blm.c \
|
||||
bmovie-bml.c \
|
||||
bmovie-bml-parser.c \
|
||||
bmovie-bml-parser.h \
|
||||
bmovie-gif.c \
|
||||
bmovie-gif-parser.c \
|
||||
bmovie-gif-parser.h \
|
||||
bmovie-effects.c \
|
||||
bobject.c \
|
||||
bpacket.c \
|
||||
bparams.c \
|
||||
bparser.c \
|
||||
bproxyclient.c \
|
||||
bproxyserver.c \
|
||||
breceiver.c \
|
||||
bsender.c \
|
||||
bsocket.c \
|
||||
btheme.c \
|
||||
bthemes.c \
|
||||
btheme-parser.c \
|
||||
btheme-parser.h \
|
||||
btypes.c \
|
||||
butils.c \
|
||||
bwriter.c \
|
||||
$(libb_gif_sources)
|
||||
|
||||
libb_la_built_sources = \
|
||||
bmarshal.c \
|
||||
bmarshal.h
|
||||
|
||||
libb_la_extra_sources = \
|
||||
bmarshal.list
|
||||
|
||||
libb_la_SOURCES = $(libb_la_built_sources) $(libb_la_sources)
|
||||
|
||||
|
||||
libb_la_LDFLAGS = \
|
||||
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
|
||||
-release $(LT_RELEASE) -export-dynamic
|
||||
|
||||
libb_la_LIBADD = @GLIB_LIBS@ @WIN32_LIBS@
|
||||
|
||||
|
||||
EXTRA_DIST = $(libb_la_extra_sources)
|
||||
|
||||
|
||||
#
|
||||
# rules to generate built sources
|
||||
#
|
||||
# setup autogeneration dependencies
|
||||
gen_sources = xgen-bmh xgen-bmc
|
||||
CLEANFILES = $(gen_sources)
|
||||
|
||||
$(srcdir)/bmarshal.h: $(srcdir)/bmarshal.list
|
||||
$(GLIB_GENMARSHAL) --prefix=b_marshal $(srcdir)/bmarshal.list --header >> xgen-bmh \
|
||||
&& (cmp -s xgen-bmh $(@F) || cp xgen-bmh $(@F)) \
|
||||
&& rm -f xgen-bmh xgen-bmh~
|
||||
|
||||
$(srcdir)/bmarshal.c: $(srcdir)/bmarshal.h
|
||||
echo "#include \"bmarshal.h\"" >> xgen-bmc \
|
||||
&& $(GLIB_GENMARSHAL) --prefix=b_marshal $(srcdir)/bmarshal.list --body >> xgen-bmc \
|
||||
&& cp xgen-bmc $(@F) \
|
||||
&& rm -f xgen-bmc xgen-bmc~
|
|
@ -0,0 +1,702 @@
|
|||
# Makefile.in generated by automake 1.7.9 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
# Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_triplet = @host@
|
||||
AA_LIBS = @AA_LIBS@
|
||||
AA_VIEW_TYPE = @AA_VIEW_TYPE@
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BLIB_BINARY_AGE = @BLIB_BINARY_AGE@
|
||||
BLIB_INTERFACE_AGE = @BLIB_INTERFACE_AGE@
|
||||
BLIB_MAJOR_VERSION = @BLIB_MAJOR_VERSION@
|
||||
BLIB_MICRO_VERSION = @BLIB_MICRO_VERSION@
|
||||
BLIB_MINOR_VERSION = @BLIB_MINOR_VERSION@
|
||||
BLIB_VERSION = @BLIB_VERSION@
|
||||
BUILD_MODULES_FALSE = @BUILD_MODULES_FALSE@
|
||||
BUILD_MODULES_TRUE = @BUILD_MODULES_TRUE@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DATADIR = @DATADIR@
|
||||
DB2HTML = @DB2HTML@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@
|
||||
DIRECTFB_LIBS = @DIRECTFB_LIBS@
|
||||
DIRECTFB_VIEW_TYPE = @DIRECTFB_VIEW_TYPE@
|
||||
ECHO = @ECHO@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ENABLE_GTK_DOC_FALSE = @ENABLE_GTK_DOC_FALSE@
|
||||
ENABLE_GTK_DOC_TRUE = @ENABLE_GTK_DOC_TRUE@
|
||||
EXEEXT = @EXEEXT@
|
||||
F77 = @F77@
|
||||
FFLAGS = @FFLAGS@
|
||||
GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@
|
||||
GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@
|
||||
GLIB_CFLAGS = @GLIB_CFLAGS@
|
||||
GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
|
||||
GLIB_LIBS = @GLIB_LIBS@
|
||||
GLIB_MKENUMS = @GLIB_MKENUMS@
|
||||
GOBJECT_QUERY = @GOBJECT_QUERY@
|
||||
GTKDOC = @GTKDOC@
|
||||
GTK_CFLAGS = @GTK_CFLAGS@
|
||||
GTK_LIBS = @GTK_LIBS@
|
||||
GTK_VIEW_TYPE = @GTK_VIEW_TYPE@
|
||||
HAVE_AA_FALSE = @HAVE_AA_FALSE@
|
||||
HAVE_AA_TRUE = @HAVE_AA_TRUE@
|
||||
HAVE_DIRECTFB_FALSE = @HAVE_DIRECTFB_FALSE@
|
||||
HAVE_DIRECTFB_TRUE = @HAVE_DIRECTFB_TRUE@
|
||||
HAVE_DOCBOOK_FALSE = @HAVE_DOCBOOK_FALSE@
|
||||
HAVE_DOCBOOK_TRUE = @HAVE_DOCBOOK_TRUE@
|
||||
HAVE_GTK_DOC = @HAVE_GTK_DOC@
|
||||
HAVE_GTK_DOC_FALSE = @HAVE_GTK_DOC_FALSE@
|
||||
HAVE_GTK_DOC_TRUE = @HAVE_GTK_DOC_TRUE@
|
||||
HAVE_GTK_FALSE = @HAVE_GTK_FALSE@
|
||||
HAVE_GTK_TRUE = @HAVE_GTK_TRUE@
|
||||
HAVE_PIXBUF_FALSE = @HAVE_PIXBUF_FALSE@
|
||||
HAVE_PIXBUF_TRUE = @HAVE_PIXBUF_TRUE@
|
||||
HTML_DIR = @HTML_DIR@
|
||||
INCLUDEDIR = @INCLUDEDIR@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_AGE = @LT_AGE@
|
||||
LT_CURRENT = @LT_CURRENT@
|
||||
LT_RELEASE = @LT_RELEASE@
|
||||
LT_REVISION = @LT_REVISION@
|
||||
MAINT = @MAINT@
|
||||
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
|
||||
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MODULEPATH = @MODULEPATH@
|
||||
OBJEXT = @OBJEXT@
|
||||
OS_WIN32_FALSE = @OS_WIN32_FALSE@
|
||||
OS_WIN32_TRUE = @OS_WIN32_TRUE@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PIXBUF_VIEW_TYPE = @PIXBUF_VIEW_TYPE@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
RANLIB = @RANLIB@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
THEMEPATH = @THEMEPATH@
|
||||
VERSION = @VERSION@
|
||||
WIN32_CFLAGS = @WIN32_CFLAGS@
|
||||
WIN32_LIBS = @WIN32_LIBS@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_F77 = @ac_ct_F77@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
|
||||
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
oldincludedir = @oldincludedir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
$(CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DTHEMEPATH=\"$(THEMEPATH)\" \
|
||||
-DMODULEPATH=\"$(MODULEPATH)\"
|
||||
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
@GLIB_CFLAGS@
|
||||
|
||||
|
||||
lib_LTLIBRARIES = libb.la
|
||||
|
||||
libb_la_includedir = $(INCLUDEDIR)/blib
|
||||
|
||||
libb_gif_public_headers = \
|
||||
gif-load.h \
|
||||
gif-save.h \
|
||||
gif-types.h
|
||||
|
||||
|
||||
libb_gif_sources = \
|
||||
gif-load.c \
|
||||
gif-save.c
|
||||
|
||||
|
||||
libb_la_include_HEADERS = \
|
||||
blib.h \
|
||||
btypes.h \
|
||||
beffects.h \
|
||||
bmovie.h \
|
||||
bmovie-blm.h \
|
||||
bmovie-bml.h \
|
||||
bmovie-gif.h \
|
||||
bmovie-effects.h \
|
||||
bobject.h \
|
||||
bparams.h \
|
||||
bpacket.h \
|
||||
bparser.h \
|
||||
btheme.h \
|
||||
bthemes.h \
|
||||
bproxyclient.h \
|
||||
bproxyserver.h \
|
||||
breceiver.h \
|
||||
bsender.h \
|
||||
bsocket.h \
|
||||
butils.h \
|
||||
bwriter.h \
|
||||
bprotocol.h \
|
||||
bmodule.h \
|
||||
bmodule-internal.h \
|
||||
bmodule-utils.h \
|
||||
bmoduleinfo.h \
|
||||
bmovieplayer.h \
|
||||
$(libb_gif_public_headers)
|
||||
|
||||
|
||||
libb_la_sources = \
|
||||
blib.c \
|
||||
beffects.c \
|
||||
bmodule.c \
|
||||
bmodule-utils.c \
|
||||
bmoduleinfo.c \
|
||||
bmovieplayer.c \
|
||||
bmovie.c \
|
||||
bmovie-blm.c \
|
||||
bmovie-bml.c \
|
||||
bmovie-bml-parser.c \
|
||||
bmovie-bml-parser.h \
|
||||
bmovie-gif.c \
|
||||
bmovie-gif-parser.c \
|
||||
bmovie-gif-parser.h \
|
||||
bmovie-effects.c \
|
||||
bobject.c \
|
||||
bpacket.c \
|
||||
bparams.c \
|
||||
bparser.c \
|
||||
bproxyclient.c \
|
||||
bproxyserver.c \
|
||||
breceiver.c \
|
||||
bsender.c \
|
||||
bsocket.c \
|
||||
btheme.c \
|
||||
bthemes.c \
|
||||
btheme-parser.c \
|
||||
btheme-parser.h \
|
||||
btypes.c \
|
||||
butils.c \
|
||||
bwriter.c \
|
||||
$(libb_gif_sources)
|
||||
|
||||
|
||||
libb_la_built_sources = \
|
||||
bmarshal.c \
|
||||
bmarshal.h
|
||||
|
||||
|
||||
libb_la_extra_sources = \
|
||||
bmarshal.list
|
||||
|
||||
|
||||
libb_la_SOURCES = $(libb_la_built_sources) $(libb_la_sources)
|
||||
|
||||
libb_la_LDFLAGS = \
|
||||
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
|
||||
-release $(LT_RELEASE) -export-dynamic
|
||||
|
||||
|
||||
libb_la_LIBADD = @GLIB_LIBS@ @WIN32_LIBS@
|
||||
|
||||
EXTRA_DIST = $(libb_la_extra_sources)
|
||||
|
||||
#
|
||||
# rules to generate built sources
|
||||
#
|
||||
# setup autogeneration dependencies
|
||||
gen_sources = xgen-bmh xgen-bmc
|
||||
CLEANFILES = $(gen_sources)
|
||||
subdir = blib
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
|
||||
libb_la_DEPENDENCIES =
|
||||
am__objects_1 = bmarshal.lo
|
||||
am__objects_2 = gif-load.lo gif-save.lo
|
||||
am__objects_3 = blib.lo beffects.lo bmodule.lo bmodule-utils.lo \
|
||||
bmoduleinfo.lo bmovieplayer.lo bmovie.lo bmovie-blm.lo \
|
||||
bmovie-bml.lo bmovie-bml-parser.lo bmovie-gif.lo \
|
||||
bmovie-gif-parser.lo bmovie-effects.lo bobject.lo bpacket.lo \
|
||||
bparams.lo bparser.lo bproxyclient.lo bproxyserver.lo \
|
||||
breceiver.lo bsender.lo bsocket.lo btheme.lo bthemes.lo \
|
||||
btheme-parser.lo btypes.lo butils.lo bwriter.lo \
|
||||
$(am__objects_2)
|
||||
am_libb_la_OBJECTS = $(am__objects_1) $(am__objects_3)
|
||||
libb_la_OBJECTS = $(am_libb_la_OBJECTS)
|
||||
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/beffects.Plo ./$(DEPDIR)/blib.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmarshal.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmodule-utils.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmodule.Plo ./$(DEPDIR)/bmoduleinfo.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmovie-blm.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmovie-bml-parser.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmovie-bml.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmovie-effects.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmovie-gif-parser.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmovie-gif.Plo ./$(DEPDIR)/bmovie.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bmovieplayer.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bobject.Plo ./$(DEPDIR)/bpacket.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bparams.Plo ./$(DEPDIR)/bparser.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bproxyclient.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bproxyserver.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/breceiver.Plo ./$(DEPDIR)/bsender.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bsocket.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/btheme-parser.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/btheme.Plo ./$(DEPDIR)/bthemes.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/btypes.Plo ./$(DEPDIR)/butils.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/bwriter.Plo ./$(DEPDIR)/gif-load.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gif-save.Plo
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
|
||||
$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
DIST_SOURCES = $(libb_la_SOURCES)
|
||||
HEADERS = $(libb_la_include_HEADERS)
|
||||
|
||||
DIST_COMMON = $(libb_la_include_HEADERS) $(srcdir)/Makefile.in \
|
||||
Makefile.am
|
||||
SOURCES = $(libb_la_SOURCES)
|
||||
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu blib/Makefile
|
||||
Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||
libLTLIBRARIES_INSTALL = $(INSTALL)
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
|
||||
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
p="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
|
||||
done
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" = "$$p" && dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libb.la: $(libb_la_OBJECTS) $(libb_la_DEPENDENCIES)
|
||||
$(LINK) -rpath $(libdir) $(libb_la_LDFLAGS) $(libb_la_OBJECTS) $(libb_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT) core *.core
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/beffects.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blib.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmarshal.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmodule-utils.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmodule.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmoduleinfo.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmovie-blm.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmovie-bml-parser.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmovie-bml.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmovie-effects.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmovie-gif-parser.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmovie-gif.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmovie.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmovieplayer.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bobject.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpacket.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bparams.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bparser.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bproxyclient.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bproxyserver.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/breceiver.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsender.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsocket.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btheme-parser.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btheme.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bthemes.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btypes.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/butils.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bwriter.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gif-load.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gif-save.Plo@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
|
||||
@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
|
||||
@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
|
||||
@am__fastdepCC_TRUE@ fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
|
||||
@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
|
||||
@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
|
||||
@am__fastdepCC_TRUE@ fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
|
||||
@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
|
||||
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
|
||||
@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
|
||||
@am__fastdepCC_TRUE@ fi
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool
|
||||
uninstall-info-am:
|
||||
libb_la_includeHEADERS_INSTALL = $(INSTALL_HEADER)
|
||||
install-libb_la_includeHEADERS: $(libb_la_include_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(libb_la_includedir)
|
||||
@list='$(libb_la_include_HEADERS)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(libb_la_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(libb_la_includedir)/$$f"; \
|
||||
$(libb_la_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(libb_la_includedir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-libb_la_includeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(libb_la_include_HEADERS)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(libb_la_includedir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(libb_la_includedir)/$$f; \
|
||||
done
|
||||
|
||||
ETAGS = etags
|
||||
ETAGSFLAGS =
|
||||
|
||||
CTAGS = ctags
|
||||
CTAGSFLAGS =
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkinstalldirs) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
|
||||
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(libb_la_includedir)
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-libtool distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-libb_la_includeHEADERS
|
||||
|
||||
install-exec-am: install-libLTLIBRARIES
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES \
|
||||
uninstall-libb_la_includeHEADERS
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libLTLIBRARIES clean-libtool ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am info info-am install \
|
||||
install-am install-data install-data-am install-exec \
|
||||
install-exec-am install-info install-info-am \
|
||||
install-libLTLIBRARIES install-libb_la_includeHEADERS \
|
||||
install-man install-strip installcheck installcheck-am \
|
||||
installdirs maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-info-am uninstall-libLTLIBRARIES \
|
||||
uninstall-libb_la_includeHEADERS
|
||||
|
||||
|
||||
$(srcdir)/bmarshal.h: $(srcdir)/bmarshal.list
|
||||
$(GLIB_GENMARSHAL) --prefix=b_marshal $(srcdir)/bmarshal.list --header >> xgen-bmh \
|
||||
&& (cmp -s xgen-bmh $(@F) || cp xgen-bmh $(@F)) \
|
||||
&& rm -f xgen-bmh xgen-bmh~
|
||||
|
||||
$(srcdir)/bmarshal.c: $(srcdir)/bmarshal.h
|
||||
echo "#include \"bmarshal.h\"" >> xgen-bmc \
|
||||
&& $(GLIB_GENMARSHAL) --prefix=b_marshal $(srcdir)/bmarshal.list --body >> xgen-bmc \
|
||||
&& cp xgen-bmc $(@F) \
|
||||
&& rm -f xgen-bmc xgen-bmc~
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
|
@ -0,0 +1,214 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "beffects.h"
|
||||
|
||||
|
||||
static void b_effects_init (BEffects *effects);
|
||||
|
||||
|
||||
GType
|
||||
b_effects_get_type (void)
|
||||
{
|
||||
static GType effects_type = 0;
|
||||
|
||||
if (!effects_type)
|
||||
{
|
||||
static const GTypeInfo effects_info =
|
||||
{
|
||||
sizeof (BEffectsClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
NULL, /* class_init */
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BEffects),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_effects_init,
|
||||
};
|
||||
|
||||
effects_type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"BEffects", &effects_info, 0);
|
||||
}
|
||||
|
||||
return effects_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_effects_init (BEffects *effects)
|
||||
{
|
||||
effects->invert = B_EFFECT_SCOPE_NONE;
|
||||
effects->vflip = B_EFFECT_SCOPE_NONE;
|
||||
effects->hflip = B_EFFECT_SCOPE_NONE;
|
||||
effects->lmirror = B_EFFECT_SCOPE_NONE;
|
||||
effects->rmirror = B_EFFECT_SCOPE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_effects_new:
|
||||
*
|
||||
* Creates a new #BEffects object with default values.
|
||||
*
|
||||
* Return value: the newly allocate #BEffects object.
|
||||
**/
|
||||
BEffects *
|
||||
b_effects_new (void)
|
||||
{
|
||||
return g_object_new (B_TYPE_EFFECTS, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_effects_apply:
|
||||
* @effects: a #BEffects object
|
||||
* @frame_data: data to apply the effects on
|
||||
* @width: width of the @frame_data buffer
|
||||
* @height: height of the @frame_data buffer
|
||||
* @channels: number of channels in the @frame_data buffer
|
||||
* @maxval: the maximum value for the @frame_data buffer
|
||||
*
|
||||
* This function applies the effects described in the @effects object
|
||||
* to a single frame.
|
||||
**/
|
||||
void
|
||||
b_effects_apply (BEffects *effects,
|
||||
guchar *frame_data,
|
||||
gint width,
|
||||
gint height,
|
||||
gint channels,
|
||||
gint maxval)
|
||||
{
|
||||
BEffectScope scope;
|
||||
gint start_x;
|
||||
gint end_x;
|
||||
gint rowstride;
|
||||
|
||||
g_return_if_fail (B_IS_EFFECTS (effects));
|
||||
g_return_if_fail (frame_data != NULL);
|
||||
g_return_if_fail (channels == 1);
|
||||
|
||||
start_x = 0;
|
||||
end_x = width;
|
||||
rowstride = width;
|
||||
|
||||
for (scope = B_EFFECT_SCOPE_ALL; scope >= B_EFFECT_SCOPE_LEFT; scope--)
|
||||
{
|
||||
if (scope == B_EFFECT_SCOPE_RIGHT)
|
||||
{
|
||||
width /= 2;
|
||||
start_x = width;
|
||||
}
|
||||
else if (scope == B_EFFECT_SCOPE_LEFT)
|
||||
{
|
||||
start_x = 0;
|
||||
end_x = width;
|
||||
}
|
||||
|
||||
if (effects->invert == scope)
|
||||
{
|
||||
gint x, y;
|
||||
guchar *buf;
|
||||
|
||||
buf = (guchar *) frame_data;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = start_x; x < end_x; x++)
|
||||
{
|
||||
buf[x] = maxval - buf[x];
|
||||
}
|
||||
|
||||
buf += rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
if (effects->vflip == scope)
|
||||
{
|
||||
gint y;
|
||||
guchar temp[width];
|
||||
guchar *upper;
|
||||
guchar *lower;
|
||||
|
||||
for (y = 0; y < height / 2; y++)
|
||||
{
|
||||
upper = frame_data + rowstride * y;
|
||||
lower = frame_data + rowstride * (height - y - 1);
|
||||
|
||||
memcpy (temp, upper + start_x, width);
|
||||
memcpy (upper + start_x, lower + start_x, width);
|
||||
memcpy (lower + start_x, temp, width);
|
||||
}
|
||||
}
|
||||
|
||||
if (effects->hflip == scope)
|
||||
{
|
||||
gint x, y;
|
||||
guchar temp;
|
||||
guchar *buf;
|
||||
|
||||
buf = frame_data;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = start_x; x < (start_x + width / 2); x++)
|
||||
{
|
||||
gint swap_x;
|
||||
|
||||
swap_x = start_x + width - 1 - (x - start_x);
|
||||
|
||||
temp = buf[x];
|
||||
buf[x] = buf[swap_x];
|
||||
buf[swap_x] = temp;
|
||||
}
|
||||
|
||||
buf += rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
if (effects->lmirror == scope || effects->rmirror == scope)
|
||||
{
|
||||
gint x, y;
|
||||
guchar *buf;
|
||||
|
||||
buf = frame_data;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = start_x; x < (start_x + width / 2); x++)
|
||||
{
|
||||
if (effects->lmirror == scope)
|
||||
buf[width - 1 - x] = buf[x];
|
||||
else if (effects->rmirror == scope)
|
||||
buf[x] = buf[width - 1 - x];
|
||||
}
|
||||
|
||||
buf += rowstride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_EFFECTS_H__
|
||||
#define __B_EFFECTS_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
B_EFFECT_SCOPE_NONE = 0,
|
||||
B_EFFECT_SCOPE_LEFT = 1 << 0,
|
||||
B_EFFECT_SCOPE_RIGHT = 1 << 1,
|
||||
B_EFFECT_SCOPE_ALL = B_EFFECT_SCOPE_LEFT | B_EFFECT_SCOPE_RIGHT
|
||||
} BEffectScope;
|
||||
|
||||
#define B_TYPE_EFFECTS (b_effects_get_type ())
|
||||
#define B_EFFECTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_EFFECTS, BEffects))
|
||||
#define B_EFFECTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_EFFECTS, BEffectsClass))
|
||||
#define B_IS_EFFECTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_EFFECTS))
|
||||
#define B_IS_EFFECTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_EFFECTS))
|
||||
|
||||
typedef struct _BEffectsClass BEffectsClass;
|
||||
|
||||
struct _BEffectsClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _BEffects
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
BEffectScope invert;
|
||||
BEffectScope vflip;
|
||||
BEffectScope hflip;
|
||||
BEffectScope lmirror;
|
||||
BEffectScope rmirror;
|
||||
};
|
||||
|
||||
GType b_effects_get_type (void) G_GNUC_CONST;
|
||||
BEffects * b_effects_new (void);
|
||||
void b_effects_apply (BEffects *effects,
|
||||
guchar *frame_data,
|
||||
gint width,
|
||||
gint height,
|
||||
gint channels,
|
||||
gint maxval);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_EFFECTS_H__ */
|
|
@ -0,0 +1,134 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "butils.h"
|
||||
|
||||
static void b_register_transform_funcs (void);
|
||||
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
|
||||
/**
|
||||
* b_init:
|
||||
*
|
||||
* This function initializes the BLib library. It calls g_type_init()
|
||||
* for you, initializes the random number generator and registers some
|
||||
* transform functions needed for the deserialization routines.
|
||||
*
|
||||
* It is safe to call this function multiple times but you should at
|
||||
* least call it once before you use any other BLib functions.
|
||||
**/
|
||||
void
|
||||
b_init (void)
|
||||
{
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
srand (time (NULL));
|
||||
|
||||
g_type_init ();
|
||||
|
||||
b_register_transform_funcs ();
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
b_value_transform_string_int (const GValue *src_value,
|
||||
GValue *dest_value)
|
||||
{
|
||||
const gchar *str = g_value_get_string (src_value);
|
||||
gint i;
|
||||
|
||||
if (b_parse_int (str, &i))
|
||||
g_value_set_int (dest_value, i);
|
||||
else
|
||||
g_warning ("can not convert '%s' to an integer value", str);
|
||||
}
|
||||
|
||||
static void
|
||||
b_value_transform_string_double (const GValue *src_value,
|
||||
GValue *dest_value)
|
||||
{
|
||||
const gchar *str = g_value_get_string (src_value);
|
||||
gdouble d;
|
||||
|
||||
if (b_parse_double (str, &d))
|
||||
g_value_set_double (dest_value, d);
|
||||
else
|
||||
g_warning ("can not convert '%s' to a double value", str);
|
||||
}
|
||||
|
||||
static void
|
||||
b_value_transform_string_boolean (const GValue *src_value,
|
||||
GValue *dest_value)
|
||||
{
|
||||
const gchar *str = g_value_get_string (src_value);
|
||||
gboolean b;
|
||||
|
||||
if (b_parse_boolean (str, &b))
|
||||
g_value_set_boolean (dest_value, b);
|
||||
else
|
||||
g_warning ("can not convert '%s' to a boolean value", str);
|
||||
}
|
||||
|
||||
static void
|
||||
b_value_transform_string_enum (const GValue *src_value,
|
||||
GValue *dest_value)
|
||||
{
|
||||
GEnumClass *enum_class;
|
||||
GEnumValue *enum_value;
|
||||
|
||||
g_return_if_fail (G_VALUE_HOLDS_ENUM (dest_value));
|
||||
|
||||
enum_class = g_type_class_peek (G_VALUE_TYPE (dest_value));
|
||||
enum_value = g_enum_get_value_by_name (G_ENUM_CLASS (enum_class),
|
||||
g_value_get_string (src_value));
|
||||
if (!enum_value)
|
||||
enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (enum_class),
|
||||
g_value_get_string (src_value));
|
||||
|
||||
if (enum_value)
|
||||
g_value_set_enum (dest_value, enum_value->value);
|
||||
else
|
||||
g_warning ("can not convert '%s' to an enum value",
|
||||
g_value_get_string (src_value));
|
||||
}
|
||||
|
||||
static void
|
||||
b_register_transform_funcs (void)
|
||||
{
|
||||
g_value_register_transform_func (G_TYPE_STRING, G_TYPE_INT,
|
||||
b_value_transform_string_int);
|
||||
g_value_register_transform_func (G_TYPE_STRING, G_TYPE_DOUBLE,
|
||||
b_value_transform_string_double);
|
||||
g_value_register_transform_func (G_TYPE_STRING, G_TYPE_BOOLEAN,
|
||||
b_value_transform_string_boolean);
|
||||
g_value_register_transform_func (G_TYPE_STRING, G_TYPE_ENUM,
|
||||
b_value_transform_string_enum);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002-2003 The Blinkenlights Crew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __BLIB_H__
|
||||
#define __BLIB_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <blib/btypes.h>
|
||||
|
||||
#include <blib/beffects.h>
|
||||
#include <blib/bmovie.h>
|
||||
#include <blib/bmovie-blm.h>
|
||||
#include <blib/bmovie-bml.h>
|
||||
#include <blib/bmovie-gif.h>
|
||||
#include <blib/bmovie-effects.h>
|
||||
#include <blib/bobject.h>
|
||||
#include <blib/bpacket.h>
|
||||
#include <blib/bparams.h>
|
||||
#include <blib/bparser.h>
|
||||
#include <blib/bproxyclient.h>
|
||||
#include <blib/bproxyserver.h>
|
||||
#include <blib/breceiver.h>
|
||||
#include <blib/bsender.h>
|
||||
#include <blib/bsocket.h>
|
||||
#include <blib/btheme.h>
|
||||
#include <blib/bthemes.h>
|
||||
#include <blib/butils.h>
|
||||
#include <blib/bwriter.h>
|
||||
#include <blib/bmodule.h>
|
||||
#include <blib/bmodule-internal.h>
|
||||
#include <blib/bmodule-utils.h>
|
||||
#include <blib/bmoduleinfo.h>
|
||||
#include <blib/bmovieplayer.h>
|
||||
|
||||
#include <blib/gif-load.h>
|
||||
#include <blib/gif-save.h>
|
||||
|
||||
void b_init (void);
|
||||
|
||||
#endif /* __BLIB_H__ */
|
|
@ -0,0 +1,87 @@
|
|||
#include "bmarshal.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
|
||||
#define g_marshal_value_peek_char(v) g_value_get_char (v)
|
||||
#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
|
||||
#define g_marshal_value_peek_int(v) g_value_get_int (v)
|
||||
#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
|
||||
#define g_marshal_value_peek_long(v) g_value_get_long (v)
|
||||
#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
|
||||
#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
|
||||
#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
|
||||
#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
|
||||
#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
|
||||
#define g_marshal_value_peek_float(v) g_value_get_float (v)
|
||||
#define g_marshal_value_peek_double(v) g_value_get_double (v)
|
||||
#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
|
||||
#define g_marshal_value_peek_param(v) g_value_get_param (v)
|
||||
#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
|
||||
#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
|
||||
#define g_marshal_value_peek_object(v) g_value_get_object (v)
|
||||
#else /* !G_ENABLE_DEBUG */
|
||||
/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
|
||||
* Do not access GValues directly in your code. Instead, use the
|
||||
* g_value_get_*() functions
|
||||
*/
|
||||
#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
|
||||
#define g_marshal_value_peek_char(v) (v)->data[0].v_int
|
||||
#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
|
||||
#define g_marshal_value_peek_int(v) (v)->data[0].v_int
|
||||
#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
|
||||
#define g_marshal_value_peek_long(v) (v)->data[0].v_long
|
||||
#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
|
||||
#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
|
||||
#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
|
||||
#define g_marshal_value_peek_enum(v) (v)->data[0].v_int
|
||||
#define g_marshal_value_peek_flags(v) (v)->data[0].v_uint
|
||||
#define g_marshal_value_peek_float(v) (v)->data[0].v_float
|
||||
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
|
||||
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
|
||||
#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
|
||||
#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
|
||||
#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
|
||||
#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
|
||||
#endif /* !G_ENABLE_DEBUG */
|
||||
|
||||
|
||||
/* VOID:STRING,INT (./bmarshal.list:3) */
|
||||
void
|
||||
b_marshal_VOID__STRING_INT (GClosure *closure,
|
||||
GValue *return_value,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data)
|
||||
{
|
||||
typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer data1,
|
||||
gpointer arg_1,
|
||||
gint arg_2,
|
||||
gpointer data2);
|
||||
register GMarshalFunc_VOID__STRING_INT callback;
|
||||
register GCClosure *cc = (GCClosure*) closure;
|
||||
register gpointer data1, data2;
|
||||
|
||||
g_return_if_fail (n_param_values == 3);
|
||||
|
||||
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||
{
|
||||
data1 = closure->data;
|
||||
data2 = g_value_peek_pointer (param_values + 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
data1 = g_value_peek_pointer (param_values + 0);
|
||||
data2 = closure->data;
|
||||
}
|
||||
callback = (GMarshalFunc_VOID__STRING_INT) (marshal_data ? marshal_data : cc->callback);
|
||||
|
||||
callback (data1,
|
||||
g_marshal_value_peek_string (param_values + 1),
|
||||
g_marshal_value_peek_int (param_values + 2),
|
||||
data2);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef __b_marshal_MARSHAL_H__
|
||||
#define __b_marshal_MARSHAL_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* VOID:STRING,INT (./bmarshal.list:3) */
|
||||
extern void b_marshal_VOID__STRING_INT (GClosure *closure,
|
||||
GValue *return_value,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __b_marshal_MARSHAL_H__ */
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# see glib-genmarshal(1) for a detailed description of the file format,
|
||||
|
||||
VOID:STRING,INT
|
|
@ -0,0 +1,52 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MODULE_INTERNAL_H__
|
||||
#define __B_MODULE_INTERNAL_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
BModule * b_module_new (GType module_type,
|
||||
gint width,
|
||||
gint height,
|
||||
guchar *buffer,
|
||||
BModulePaintCallback paint_callback,
|
||||
gpointer paint_data,
|
||||
GError **error);
|
||||
void b_module_set_aspect (BModule *module,
|
||||
gdouble aspect_ratio);
|
||||
gboolean b_module_prepare (BModule *module,
|
||||
GError **error);
|
||||
void b_module_relax (BModule *module);
|
||||
void b_module_start (BModule *module);
|
||||
void b_module_stop (BModule *module);
|
||||
void b_module_event (BModule *module,
|
||||
BModuleEvent *event);
|
||||
gint b_module_tick (BModule *module);
|
||||
void b_module_describe (BModule *module,
|
||||
gchar **title,
|
||||
gchar **description,
|
||||
gchar **author);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MODULE_INTERNAL_H__ */
|
|
@ -0,0 +1,266 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* Clipping functions and bresenham implementation based on code taken
|
||||
* from DirectFB (http://www.directfb.org/).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmodule.h"
|
||||
#include "bmodule-utils.h"
|
||||
|
||||
typedef struct _BRegion BRegion;
|
||||
|
||||
struct _BRegion
|
||||
{
|
||||
gint x1;
|
||||
gint y1;
|
||||
gint x2;
|
||||
gint y2;
|
||||
};
|
||||
|
||||
#define SIGN(x) ((x<0) ? -1 : ((x>0) ? 1 : 0))
|
||||
|
||||
|
||||
static gboolean
|
||||
clip_line (const BRegion *clip,
|
||||
BRegion *line)
|
||||
{
|
||||
#define REGION_CODE(x,y,cx1,cx2,cy1,cy2) ( ( (y) > (cy2) ? 8 : 0) | \
|
||||
( (y) < (cy1) ? 4 : 0) | \
|
||||
( (x) > (cx2) ? 2 : 0) | \
|
||||
( (x) < (cx1) ? 1 : 0) )
|
||||
|
||||
guchar region_code1 = REGION_CODE (line->x1, line->y1,
|
||||
clip->x1, clip->x2, clip->y1, clip->y2);
|
||||
guchar region_code2 = REGION_CODE (line->x2, line->y2,
|
||||
clip->x1, clip->x2, clip->y1, clip->y2);
|
||||
|
||||
while (region_code1 | region_code2)
|
||||
{
|
||||
if (region_code1 & region_code2)
|
||||
return FALSE; /* line completely outside the clipping rectangle */
|
||||
|
||||
if (region_code1)
|
||||
{
|
||||
if (region_code1 & 8)
|
||||
{ /* divide line at bottom*/
|
||||
line->x1 = (line->x1 + (line->x2-line->x1) *
|
||||
(clip->y2 - line->y1) / (line->y2-line->y1));
|
||||
line->y1 = clip->y2;
|
||||
}
|
||||
else if (region_code1 & 4)
|
||||
{ /* divide line at top*/
|
||||
line->x1 = (line->x1 + (line->x2-line->x1) *
|
||||
(clip->y1 - line->y1) / (line->y2-line->y1));
|
||||
line->y1 = clip->y1;
|
||||
}
|
||||
else if (region_code1 & 2)
|
||||
{ /* divide line at right*/
|
||||
line->y1 = (line->y1 +(line->y2-line->y1) *
|
||||
(clip->x2 - line->x1) / (line->x2-line->x1));
|
||||
line->x1 = clip->x2;
|
||||
}
|
||||
else if (region_code1 & 1)
|
||||
{ /* divide line at right*/
|
||||
line->y1 = (line->y1 +(line->y2-line->y1) *
|
||||
(clip->x1 - line->x1) / (line->x2-line->x1));
|
||||
line->x1 = clip->x1;
|
||||
}
|
||||
|
||||
region_code1 = REGION_CODE (line->x1, line->y1,
|
||||
clip->x1, clip->x2, clip->y1, clip->y2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (region_code2 & 8)
|
||||
{ /* divide line at bottom*/
|
||||
line->x2 = (line->x1 + (line->x2-line->x1) *
|
||||
(clip->y2 - line->y1) / (line->y2-line->y1));
|
||||
line->y2 = clip->y2;
|
||||
}
|
||||
else if (region_code2 & 4)
|
||||
{ /* divide line at top*/
|
||||
line->x2 = (line->x1 +(line->x2-line->x1) *
|
||||
(clip->y1 - line->y1) / (line->y2-line->y1));
|
||||
line->y2 = clip->y1;
|
||||
}
|
||||
else if (region_code2 & 2)
|
||||
{ /* divide line at right*/
|
||||
line->y2 = (line->y1 +(line->y2-line->y1) *
|
||||
(clip->x2 - line->x1) / (line->x2-line->x1));
|
||||
line->x2 = clip->x2;
|
||||
}
|
||||
else if (region_code2 & 1)
|
||||
{ /* divide line at right*/
|
||||
line->y2 = (line->y1 +(line->y2-line->y1) *
|
||||
(clip->x1 - line->x1) / (line->x2-line->x1));
|
||||
line->x2 = clip->x1;
|
||||
}
|
||||
|
||||
region_code2 = REGION_CODE (line->x2, line->y2,
|
||||
clip->x1, clip->x2, clip->y1, clip->y2);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_draw_point:
|
||||
* @module: a #BModule object
|
||||
* @x: x coordinate
|
||||
* @y: y coordinate
|
||||
* @value: the color to draw with
|
||||
*
|
||||
* Draws a point to the @module's frame buffer. It is safe to specify
|
||||
* coordinates outside the buffer.
|
||||
**/
|
||||
void
|
||||
b_module_draw_point (BModule *module,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar value)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
|
||||
if (x < 0 || x >= module->width)
|
||||
return;
|
||||
if (y < 0 || y >= module->height)
|
||||
return;
|
||||
|
||||
module->buffer[module->width * y + x] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_draw_line:
|
||||
* @module: a #BModule object
|
||||
* @x1: x coordinate of the start point
|
||||
* @y1: y coordinate of the start point
|
||||
* @x2: x coordinate of the end point
|
||||
* @y2: y coordinate of the end point
|
||||
* @value: the color to draw with
|
||||
*
|
||||
* Draws a one-pixel wide line between two points to the module's
|
||||
* frame buffer. The endpoints are included in the line. If the line
|
||||
* exceeds the buffer, it is properly clipped.
|
||||
**/
|
||||
void
|
||||
b_module_draw_line (BModule *module,
|
||||
gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2,
|
||||
guchar value)
|
||||
{
|
||||
BRegion clip;
|
||||
BRegion line;
|
||||
gint x, y, i;
|
||||
gint dx, dy, sdy;
|
||||
gint dxabs, dyabs;
|
||||
guchar *d;
|
||||
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
|
||||
clip.x1 = 0;
|
||||
clip.y1 = 0;
|
||||
clip.x2 = module->width - 1;
|
||||
clip.y2 = module->height - 1;
|
||||
|
||||
line.x1 = x1;
|
||||
line.y1 = y1;
|
||||
line.x2 = x2;
|
||||
line.y2 = y2;
|
||||
|
||||
if (!clip_line (&clip, &line))
|
||||
return;
|
||||
|
||||
/* the horizontal distance of the line */
|
||||
dx = line.x2 - line.x1;
|
||||
dxabs = abs (dx);
|
||||
|
||||
/* the vertical distance of the line */
|
||||
dy = line.y2 - line.y1;
|
||||
dyabs = abs (dy);
|
||||
|
||||
sdy = dx ? SIGN(dy) * SIGN(dx) : SIGN(dy);
|
||||
|
||||
d = module->buffer;
|
||||
|
||||
if (dx >= 0)
|
||||
d += line.y1 * module->width + line.x1;
|
||||
else
|
||||
d += line.y2 * module->width + line.x2;
|
||||
|
||||
x = dyabs >> 1;
|
||||
y = dxabs >> 1;
|
||||
|
||||
if (dxabs >= dyabs)
|
||||
{ /* the line is more horizontal than vertical */
|
||||
for (i = 0; i <= dxabs; i++)
|
||||
{
|
||||
*d = value;
|
||||
|
||||
d++;
|
||||
y += dyabs;
|
||||
if (y >= dxabs)
|
||||
{
|
||||
y -= dxabs;
|
||||
d += sdy * module->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* the line is more vertical than horizontal */
|
||||
{
|
||||
for (i = 0; i <= dyabs; i++)
|
||||
{
|
||||
*d = value;
|
||||
d += sdy * module->width;
|
||||
|
||||
x += dxabs;
|
||||
if (x >= dyabs)
|
||||
{
|
||||
x -= dyabs;
|
||||
d++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_fill:
|
||||
* @module: a #BModule object
|
||||
* @value: the color to draw with
|
||||
*
|
||||
* Fills the module's framebuffer with @value.
|
||||
**/
|
||||
void
|
||||
b_module_fill (BModule *module,
|
||||
guchar value)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
|
||||
memset (module->buffer, value, module->width * module->height);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MODULE_UTILS_H__
|
||||
#define __B_MODULE_UTILS_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void b_module_draw_point (BModule *module,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar value);
|
||||
void b_module_draw_line (BModule *module,
|
||||
gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2,
|
||||
guchar value);
|
||||
void b_module_fill (BModule *module,
|
||||
guchar value);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MODULE_H__ */
|
|
@ -0,0 +1,674 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmodule.h"
|
||||
#include "bmodule-internal.h"
|
||||
|
||||
enum
|
||||
{
|
||||
START,
|
||||
STOP,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_SPEED,
|
||||
PROP_LIFETIME
|
||||
};
|
||||
|
||||
static void b_module_class_init (BModuleClass *klass);
|
||||
static void b_module_init (BModule *module);
|
||||
static void b_module_finalize (GObject *object);
|
||||
static void b_module_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static gint tick (BModule *module);
|
||||
static void describe (BModule *module,
|
||||
const gchar **title,
|
||||
const gchar **description,
|
||||
const gchar **author);
|
||||
static void stop_callback (BModule *module);
|
||||
|
||||
|
||||
static guint module_signals[LAST_SIGNAL] = { 0 };
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_module_get_type (void)
|
||||
{
|
||||
static GType module_type = 0;
|
||||
|
||||
if (!module_type)
|
||||
{
|
||||
static const GTypeInfo module_info =
|
||||
{
|
||||
sizeof (BModuleClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_module_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BModule),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_module_init,
|
||||
};
|
||||
|
||||
module_type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"BModule", &module_info, 0);
|
||||
}
|
||||
|
||||
return module_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_module_class_init (BModuleClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
GParamSpec *param_spec;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
object_class->finalize = b_module_finalize;
|
||||
object_class->set_property = b_module_set_property;
|
||||
|
||||
module_signals[START] = g_signal_new ("start",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (BModuleClass, start),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
module_signals[STOP] = g_signal_new ("stop",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (BModuleClass, stop),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
param_spec = g_param_spec_double ("speed", NULL,
|
||||
"Allows to tune the playback speed.",
|
||||
0.01, 100.0, 1.0,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (object_class, PROP_SPEED, param_spec);
|
||||
|
||||
param_spec = g_param_spec_int ("lifetime", NULL,
|
||||
"Maximum time a module is allowed to run "
|
||||
"(in milliseconds).",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (object_class, PROP_LIFETIME, param_spec);
|
||||
|
||||
klass->max_players = 0;
|
||||
|
||||
klass->query = NULL;
|
||||
klass->prepare = NULL;
|
||||
klass->start = NULL;
|
||||
klass->stop = NULL;
|
||||
klass->event = NULL;
|
||||
klass->tick = NULL;
|
||||
klass->describe = describe;
|
||||
}
|
||||
|
||||
static void
|
||||
b_module_init (BModule *module)
|
||||
{
|
||||
module->aspect = 1.0;
|
||||
|
||||
module->speed = 1.0;
|
||||
module->lifetime = 0;
|
||||
|
||||
module->num_players = 0;
|
||||
|
||||
module->ready = FALSE;
|
||||
module->running = FALSE;
|
||||
module->tick_source_id = 0;
|
||||
module->life_source_id = 0;
|
||||
|
||||
g_signal_connect (G_OBJECT (module), "stop",
|
||||
G_CALLBACK (stop_callback),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
b_module_finalize (GObject *object)
|
||||
{
|
||||
BModule *module = B_MODULE (object);
|
||||
|
||||
if (module->ready)
|
||||
b_module_relax (module);
|
||||
|
||||
if (module->tick_source_id)
|
||||
{
|
||||
g_source_remove (module->tick_source_id);
|
||||
module->tick_source_id = 0;
|
||||
}
|
||||
if (module->life_source_id)
|
||||
{
|
||||
g_source_remove (module->life_source_id);
|
||||
module->life_source_id = 0;
|
||||
}
|
||||
if (module->owns_buffer && module->buffer)
|
||||
{
|
||||
g_free (module->buffer);
|
||||
module->buffer = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
b_module_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BModule *module = B_MODULE (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_SPEED:
|
||||
g_return_if_fail (g_value_get_double (value) > 0.0);
|
||||
module->speed = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
case PROP_LIFETIME:
|
||||
module->lifetime = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tick (BModule *module)
|
||||
{
|
||||
gint timeout;
|
||||
|
||||
g_object_ref (module);
|
||||
|
||||
timeout = (gdouble) b_module_tick (module) / module->speed;
|
||||
|
||||
if (timeout > 0)
|
||||
module->tick_source_id = g_timeout_add (timeout,
|
||||
(GSourceFunc) tick, module);
|
||||
else
|
||||
module->tick_source_id = 0;
|
||||
|
||||
g_object_unref (module);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
lifetime_expired (BModule *module)
|
||||
{
|
||||
module->life_source_id = 0;
|
||||
|
||||
b_module_stop (module);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
describe (BModule *module,
|
||||
const gchar **title,
|
||||
const gchar **description,
|
||||
const gchar **author)
|
||||
{
|
||||
*title = g_type_name_from_instance ((GTypeInstance *) module);
|
||||
*description = NULL;
|
||||
*author = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
stop_callback (BModule *module)
|
||||
{
|
||||
/* this is a real signal callback, no virtual function implementation */
|
||||
|
||||
module->running = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
* internal module functions *
|
||||
*****************************/
|
||||
|
||||
/**
|
||||
* b_module_new:
|
||||
* @module_type: the type of module to create
|
||||
* @width: width of the frame buffer
|
||||
* @height: height of the frame buffer
|
||||
* @buffer: pointer to a preallocated buffer or %NULL
|
||||
* @paint_callback: the function to call in b_module_paint()
|
||||
* @paint_data: data to pass to the @paint_callback
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* This function tries to create the class for the @module_type and
|
||||
* queries it with the given width and height. Only if the class can
|
||||
* handle the requested size, a #BModule instance is created and
|
||||
* initialized with the given values.
|
||||
*
|
||||
* Return value: the newly allocate #BModule object
|
||||
**/
|
||||
BModule *
|
||||
b_module_new (GType module_type,
|
||||
gint width,
|
||||
gint height,
|
||||
guchar *buffer,
|
||||
BModulePaintCallback paint_callback,
|
||||
gpointer paint_data,
|
||||
GError **error)
|
||||
{
|
||||
BModuleClass *klass;
|
||||
BModule *module = NULL;
|
||||
|
||||
g_return_val_if_fail (module_type != B_TYPE_MODULE, NULL);
|
||||
g_return_val_if_fail (g_type_is_a (module_type, B_TYPE_MODULE), NULL);
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
g_return_val_if_fail (paint_callback != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
klass = g_type_class_ref (module_type);
|
||||
|
||||
if (!B_IS_MODULE_CLASS (klass))
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Class '%s' is not a BModuleClass.",
|
||||
g_type_name (module_type));
|
||||
}
|
||||
else if (!klass->query || !klass->prepare)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Module '%s' does not implement the BModule vtable.",
|
||||
g_type_name (module_type));
|
||||
}
|
||||
else if (klass->query (width, height, 1, 255))
|
||||
{
|
||||
module = (BModule *) g_object_new (module_type, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Module '%s' cannot handle the requested configuration.",
|
||||
g_type_name (module_type));
|
||||
}
|
||||
|
||||
g_type_class_unref (klass);
|
||||
|
||||
if (!module)
|
||||
return NULL;
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
module->owns_buffer = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = g_new0 (guchar, width * height);
|
||||
module->owns_buffer = TRUE;
|
||||
}
|
||||
|
||||
module->width = width;
|
||||
module->height = height;
|
||||
module->channels = 1;
|
||||
module->maxval = 255;
|
||||
module->buffer = buffer;
|
||||
module->paint_callback = paint_callback;
|
||||
module->paint_data = paint_data;
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_set_aspect:
|
||||
* @module: a #BModule object
|
||||
* @aspect_ratio: the new pixel aspect ratio (x / y)
|
||||
*
|
||||
* Sets the pixel (or window) aspect ratio for the @module. Most
|
||||
* modules ignore this value but some may adapt their output to take
|
||||
* the shape of pixels into account.
|
||||
**/
|
||||
void
|
||||
b_module_set_aspect (BModule *module,
|
||||
gdouble aspect_ratio)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
g_return_if_fail (aspect_ratio >= 0.01 && aspect_ratio <= 100.0);
|
||||
|
||||
module->aspect = aspect_ratio;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_prepare:
|
||||
* @module: a #BModule object
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* This function first queries the module once more to check that it
|
||||
* can handle the current settings. If the query succeeds, the prepare()
|
||||
* method of the module is called. The module should then prepare
|
||||
* itself and will be able to start as soon as b_module_start() is called.
|
||||
*
|
||||
* Return value: %TRUE is the module has successfully prepared itself,
|
||||
* %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_module_prepare (BModule *module,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_MODULE (module), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
g_return_val_if_fail (module->ready == FALSE, FALSE);
|
||||
|
||||
/* first query the module again with the current values */
|
||||
module->ready = B_MODULE_GET_CLASS (module)->query (module->width,
|
||||
module->height,
|
||||
module->channels,
|
||||
module->maxval);
|
||||
|
||||
if (!module->ready)
|
||||
{
|
||||
g_set_error (error, 0, 0, "Module can not handle this configuration.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
module->ready = B_MODULE_GET_CLASS (module)->prepare (module, error);
|
||||
|
||||
if (!module->ready && error && *error == NULL)
|
||||
g_set_error (error, 0, 0, "Module gave no reason.");
|
||||
|
||||
return module->ready;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_relax:
|
||||
* @module: a #BModule object
|
||||
*
|
||||
* Calls the relax() method of the @module causing it to release
|
||||
* resources allocated in b_module_prepare().
|
||||
**/
|
||||
void
|
||||
b_module_relax (BModule *module)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
g_return_if_fail (module->ready == TRUE);
|
||||
|
||||
if (B_MODULE_GET_CLASS (module)->relax)
|
||||
B_MODULE_GET_CLASS (module)->relax (module);
|
||||
|
||||
module->ready = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_start:
|
||||
* @module: a #BModule object
|
||||
*
|
||||
* Emits the start signal for @module. If @module has a lifetime set,
|
||||
* a timer is installed that stops the module when the lifetime expires.
|
||||
*
|
||||
* You need to prepare @module by calling b_module_prepare() before it
|
||||
* can be started.
|
||||
**/
|
||||
void
|
||||
b_module_start (BModule *module)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
g_return_if_fail (module->ready == TRUE);
|
||||
g_return_if_fail (module->running == FALSE);
|
||||
|
||||
module->running = TRUE;
|
||||
|
||||
g_signal_emit (G_OBJECT (module), module_signals[START], 0);
|
||||
|
||||
if (module->lifetime > 0)
|
||||
module->life_source_id = g_timeout_add (module->lifetime,
|
||||
(GSourceFunc) lifetime_expired,
|
||||
module);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_stop:
|
||||
* @module: a #BModule object
|
||||
*
|
||||
* Emits the stop signal for @module. You may only call this function
|
||||
* for a #BModule that is currently running.
|
||||
**/
|
||||
void
|
||||
b_module_stop (BModule *module)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
g_return_if_fail (module->running == TRUE);
|
||||
|
||||
if (module->life_source_id)
|
||||
{
|
||||
g_source_remove (module->life_source_id);
|
||||
module->life_source_id = 0;
|
||||
}
|
||||
|
||||
b_module_ticker_stop (module);
|
||||
|
||||
g_signal_emit (G_OBJECT (module), module_signals[STOP], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_event:
|
||||
* @module: a #BModule object
|
||||
* @event: pointer to a #BModuleEvent
|
||||
*
|
||||
* Dispatches an event to @module by calling its event() method with
|
||||
* @event. This function has no effect if the module is not currently
|
||||
* running.
|
||||
**/
|
||||
void
|
||||
b_module_event (BModule *module,
|
||||
BModuleEvent *event)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
g_return_if_fail (event != NULL);
|
||||
|
||||
if (!module->running)
|
||||
return;
|
||||
|
||||
if (B_MODULE_GET_CLASS (module)->event)
|
||||
B_MODULE_GET_CLASS (module)->event (module, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_tick:
|
||||
* @module: a #BModule object
|
||||
*
|
||||
* Calls the tick() method of @module. You may only call this function
|
||||
* for a #BModule that is currently running.
|
||||
*
|
||||
* Return value: the number of milliseconds until tick() should be
|
||||
* called again or -1 to indicate that no further ticks are requested
|
||||
**/
|
||||
gint
|
||||
b_module_tick (BModule *module)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_MODULE (module), -1);
|
||||
g_return_val_if_fail (module->running == TRUE, -1);
|
||||
|
||||
if (!B_MODULE_GET_CLASS (module)->tick)
|
||||
return -1;
|
||||
|
||||
return B_MODULE_GET_CLASS (module)->tick (module);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_describe:
|
||||
* @module: a #BModule object
|
||||
* @title: return location for the module title or %NULL
|
||||
* @description: return location for the module description or %NULL
|
||||
* @author: return location for the name of the module author or %NULL
|
||||
*
|
||||
* This function queries @module for a title, description and the name
|
||||
* of the author. It does so by calling the modules describe() method.
|
||||
* You may pass %NULL as return location if you are not interested in
|
||||
* a particular information. The @title is guaranteed to be available,
|
||||
* @description and @author may be %NULL if the module doesn't provide
|
||||
* this information.
|
||||
*
|
||||
* You must free all returned strings using g_free() if you don't need
|
||||
* them any longer.
|
||||
**/
|
||||
void
|
||||
b_module_describe (BModule *module,
|
||||
gchar **title,
|
||||
gchar **description,
|
||||
gchar **author)
|
||||
{
|
||||
const gchar *t, *d, *a;
|
||||
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
|
||||
B_MODULE_GET_CLASS (module)->describe (module, &t, &d, &a);
|
||||
|
||||
if (!t)
|
||||
{
|
||||
g_warning ("Module %s didn't return a title in b_module_describe()!",
|
||||
g_type_name_from_instance ((GTypeInstance *) module));
|
||||
t = g_type_name_from_instance ((GTypeInstance *) module);
|
||||
}
|
||||
|
||||
if (title)
|
||||
*title = g_strdup (t);
|
||||
|
||||
if (description)
|
||||
*description = g_strdup (d);
|
||||
|
||||
if (author)
|
||||
*author = g_strdup (a);
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
* public module functions *
|
||||
***************************/
|
||||
|
||||
/**
|
||||
* b_module_ticker_start:
|
||||
* @module: a #BModule object
|
||||
* @timeout: the timeout interval in milliseconds
|
||||
*
|
||||
* Starts a timeout for @module that will call cause its tick() method
|
||||
* to be called in @timeout milliseconds. The return value of the
|
||||
* tick() method is then used to install a new timeout for @module.
|
||||
* This proceeds until the tick() method returns -1,
|
||||
* b_module_ticker_stop() is called or the module is stopped.
|
||||
*
|
||||
* You may only call this function for a #BModule that is currently
|
||||
* running.
|
||||
**/
|
||||
void
|
||||
b_module_ticker_start (BModule *module,
|
||||
gint timeout)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
g_return_if_fail (B_MODULE_GET_CLASS (module)->tick);
|
||||
g_return_if_fail (module->running == TRUE);
|
||||
g_return_if_fail (timeout > 0);
|
||||
|
||||
b_module_ticker_stop (module);
|
||||
|
||||
timeout = (gdouble) timeout / module->speed;
|
||||
|
||||
if (timeout > 0)
|
||||
module->tick_source_id = g_timeout_add (timeout,
|
||||
(GSourceFunc) tick, module);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_ticker_stop:
|
||||
* @module: a #BModule object
|
||||
*
|
||||
* Stops the ticker for @module. If there is a pending timeout for
|
||||
* @module, it is removed.
|
||||
*
|
||||
* You may only call this function for a #BModule that is currently
|
||||
* running.
|
||||
**/
|
||||
void
|
||||
b_module_ticker_stop (BModule *module)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
g_return_if_fail (module->running == TRUE);
|
||||
|
||||
if (module->tick_source_id)
|
||||
{
|
||||
g_source_remove (module->tick_source_id);
|
||||
module->tick_source_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_request_stop:
|
||||
* @module: a #BModule object
|
||||
*
|
||||
* This function causes the module to be stopped. This is for example
|
||||
* used when a game module decides that the game is over.
|
||||
*
|
||||
* You may only call this function for a #BModule that is currently
|
||||
* running.
|
||||
**/
|
||||
void
|
||||
b_module_request_stop (BModule *module)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
g_return_if_fail (module->running == TRUE);
|
||||
|
||||
b_module_stop (module);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_paint:
|
||||
* @module: a #BModule object
|
||||
*
|
||||
* This function causes a repaint of the screen.
|
||||
**/
|
||||
void
|
||||
b_module_paint (BModule *module)
|
||||
{
|
||||
g_return_if_fail (B_IS_MODULE (module));
|
||||
g_return_if_fail (module->running == TRUE);
|
||||
g_return_if_fail (module->paint_callback != NULL);
|
||||
|
||||
if (!module->running)
|
||||
return;
|
||||
|
||||
module->paint_callback (module, module->buffer, module->paint_data);
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MODULE_H__
|
||||
#define __B_MODULE_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _BModuleEvent
|
||||
{
|
||||
gint device_id;
|
||||
BModuleEventType type;
|
||||
BModuleKey key;
|
||||
};
|
||||
|
||||
typedef gboolean (* BModulePaintCallback) (BModule *bmodule,
|
||||
guchar *buffer,
|
||||
gpointer data);
|
||||
|
||||
|
||||
#define B_TYPE_MODULE (b_module_get_type ())
|
||||
#define B_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_MODULE, BModule))
|
||||
#define B_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_MODULE, BModuleClass))
|
||||
#define B_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_MODULE))
|
||||
#define B_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_MODULE))
|
||||
#define B_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_MODULE, BModuleClass))
|
||||
|
||||
typedef struct _BModuleClass BModuleClass;
|
||||
|
||||
struct _BModule
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gint width;
|
||||
gint height;
|
||||
gint channels;
|
||||
gint maxval;
|
||||
gdouble aspect;
|
||||
|
||||
gdouble speed;
|
||||
gint lifetime;
|
||||
|
||||
gint num_players;
|
||||
|
||||
guchar *buffer;
|
||||
|
||||
/*< private >*/
|
||||
gboolean owns_buffer;
|
||||
|
||||
BModulePaintCallback paint_callback;
|
||||
gpointer paint_data;
|
||||
|
||||
gboolean ready; /* TRUE between prepare() and relax() */
|
||||
gboolean running; /* TRUE between start() and stop() */
|
||||
guint tick_source_id;
|
||||
guint life_source_id;
|
||||
|
||||
gpointer pad1;
|
||||
gpointer pad2;
|
||||
gpointer pad3;
|
||||
gpointer pad4;
|
||||
};
|
||||
|
||||
struct _BModuleClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* max_players defaults to 0. It needs to be set to a value between
|
||||
1 and 4 to indicate that the module can handle events from this
|
||||
number of different devices. */
|
||||
gint max_players;
|
||||
|
||||
/* query() can be called w/o a module instance, it returns TRUE if
|
||||
the module class can handle the given parameters, FALSE otherwise. */
|
||||
gboolean (* query) (gint width,
|
||||
gint height,
|
||||
gint channels,
|
||||
gint maxval);
|
||||
|
||||
/* In prepare() the module prepares itself for being started but it
|
||||
doesn't perform any visible action yet, i.e. it may not call
|
||||
b_module_paint(). */
|
||||
gboolean (* prepare) (BModule *module,
|
||||
GError **error);
|
||||
/* In relax() the module releases any resources it has allocated in
|
||||
the prepare() method. */
|
||||
void (* relax) (BModule *module);
|
||||
|
||||
/* start() signals that the module should start to run. It may call
|
||||
b_module_paint() to clear the screen or show an intro and it
|
||||
should call b_module_start_ticker() if it needs ticks. */
|
||||
void (* start) (BModule *module);
|
||||
|
||||
/* stop() signals that the module is stopped. It may call
|
||||
b_module_paint() once more (but it shouldn't). */
|
||||
void (* stop) (BModule *module);
|
||||
|
||||
/* An event occured and the module may do anything in response. */
|
||||
void (* event) (BModule *bmodule,
|
||||
BModuleEvent *event);
|
||||
|
||||
/* A previously set timeout expired. The module should do whatever it
|
||||
likes and return a new timeout (in milliseconds). If the return
|
||||
value is <= 0, no new timeout is installed. */
|
||||
gint (* tick) (BModule *module);
|
||||
|
||||
void (* describe) (BModule *module,
|
||||
const gchar **title,
|
||||
const gchar **description,
|
||||
const gchar **author);
|
||||
|
||||
/* padding for future use */
|
||||
gpointer pad1;
|
||||
gpointer pad2;
|
||||
gpointer pad3;
|
||||
gpointer pad4;
|
||||
};
|
||||
|
||||
|
||||
GType b_module_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
/* functions the module implementations may call */
|
||||
|
||||
void b_module_ticker_start (BModule *module,
|
||||
gint timeout);
|
||||
void b_module_ticker_stop (BModule *module);
|
||||
void b_module_request_stop (BModule *module);
|
||||
void b_module_paint (BModule *module);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MODULE_H__ */
|
|
@ -0,0 +1,250 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmoduleinfo.h"
|
||||
|
||||
|
||||
static void b_module_info_class_init (BModuleInfoClass *klass);
|
||||
static void b_module_info_init (BModuleInfo *module_info);
|
||||
static void b_module_info_finalize (GObject *object);
|
||||
static gboolean b_module_info_load (GTypeModule *gmodule);
|
||||
static void b_module_info_unload (GTypeModule *gmodule);
|
||||
|
||||
|
||||
static GSList *module_infos = NULL;
|
||||
static GTypeModuleClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_module_info_get_type (void)
|
||||
{
|
||||
static GType module_info_type = 0;
|
||||
|
||||
if (! module_info_type)
|
||||
{
|
||||
static const GTypeInfo module_info_info =
|
||||
{
|
||||
sizeof (BModuleInfoClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) b_module_info_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BModuleInfo),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_module_info_init,
|
||||
};
|
||||
|
||||
module_info_type = g_type_register_static (G_TYPE_TYPE_MODULE,
|
||||
"BModuleInfo",
|
||||
&module_info_info, 0);
|
||||
}
|
||||
|
||||
return module_info_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_module_info_class_init (BModuleInfoClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
GTypeModuleClass *module_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
module_class = G_TYPE_MODULE_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
object_class->finalize = b_module_info_finalize;
|
||||
|
||||
module_class->load = b_module_info_load;
|
||||
module_class->unload = b_module_info_unload;
|
||||
}
|
||||
|
||||
static void
|
||||
b_module_info_init (BModuleInfo *module)
|
||||
{
|
||||
module->module = NULL;
|
||||
module->filename = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
b_module_info_finalize (GObject *object)
|
||||
{
|
||||
BModuleInfo *module_info;
|
||||
|
||||
module_info = B_MODULE_INFO (object);
|
||||
|
||||
if (module_info->filename)
|
||||
{
|
||||
g_free (module_info->filename);
|
||||
module_info->filename = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_module_info_load (GTypeModule *gmodule)
|
||||
{
|
||||
BModuleInfo *module_info;
|
||||
|
||||
module_info = B_MODULE_INFO (gmodule);
|
||||
|
||||
g_return_val_if_fail (module_info->filename != NULL, FALSE);
|
||||
|
||||
module_info->module = g_module_open (module_info->filename,
|
||||
G_MODULE_BIND_LAZY);
|
||||
|
||||
if (! module_info->module)
|
||||
{
|
||||
g_warning (g_module_error ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! g_module_symbol (module_info->module, "b_module_register",
|
||||
(gpointer *) &module_info->register_module))
|
||||
{
|
||||
g_warning (g_module_error ());
|
||||
g_module_close (module_info->module);
|
||||
module_info->module = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return module_info->register_module (gmodule);
|
||||
}
|
||||
|
||||
static void
|
||||
b_module_info_unload (GTypeModule *gmodule)
|
||||
{
|
||||
BModuleInfo *module_info;
|
||||
|
||||
module_info = B_MODULE_INFO (gmodule);
|
||||
|
||||
g_return_if_fail (module_info->module != NULL);
|
||||
|
||||
g_module_close (module_info->module); /* FIXME: error handling */
|
||||
module_info->module = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_info_new:
|
||||
* @filename: the filename of the loadable module
|
||||
*
|
||||
* Creates a new #BModuleInfo object a loadable module.
|
||||
*
|
||||
* Return value: a newly allocated #BModuleInfo object
|
||||
**/
|
||||
BModuleInfo *
|
||||
b_module_info_new (const gchar *filename)
|
||||
{
|
||||
BModuleInfo *module_info;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (g_module_supported (), NULL);
|
||||
|
||||
module_info = B_MODULE_INFO (g_object_new (B_TYPE_MODULE_INFO, NULL));
|
||||
|
||||
module_info->filename = g_strdup (filename);
|
||||
|
||||
if (! b_module_info_load (G_TYPE_MODULE (module_info)))
|
||||
{
|
||||
g_object_unref (G_OBJECT (module_info));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b_module_info_unload (G_TYPE_MODULE (module_info));
|
||||
|
||||
return module_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_module_infos_scan_dir:
|
||||
* @dirname: the name of the directory to scan or %NULL to use the
|
||||
* default directory
|
||||
*
|
||||
* Scans the given directory for loadable modules and registers the
|
||||
* types implemented by the found modules.
|
||||
*
|
||||
* Return value: the number of successfully registered modules
|
||||
**/
|
||||
gint
|
||||
b_module_infos_scan_dir (const gchar *dirname)
|
||||
{
|
||||
gint count = 0;
|
||||
GDir *dir;
|
||||
const gchar *name;
|
||||
char *full_name;
|
||||
BModuleInfo *module_info;
|
||||
|
||||
if (!dirname)
|
||||
dirname = MODULEPATH;
|
||||
|
||||
dir = g_dir_open (dirname, 0, NULL);
|
||||
if (dir == NULL)
|
||||
{
|
||||
g_warning ("Unable to open dir '%s': %s", dirname, g_strerror (errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((name = g_dir_read_name (dir)))
|
||||
{
|
||||
if ((strlen (name) < 7) ||
|
||||
strncmp (name, "lib", 3) ||
|
||||
strcmp (name + strlen (name) - 3, ".la"))
|
||||
continue;
|
||||
|
||||
full_name = g_build_filename (dirname, name, NULL);
|
||||
|
||||
#ifdef VERBOSE
|
||||
g_print ("Testing file '%s'\n", full_name);
|
||||
#endif
|
||||
|
||||
if (g_file_test (full_name, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
module_info = b_module_info_new (full_name);
|
||||
|
||||
if (module_info)
|
||||
{
|
||||
#ifdef VERBOSE
|
||||
g_print ("Successfully loaded module '%s'\n", full_name);
|
||||
#endif
|
||||
module_infos = g_slist_append (module_infos, module_info);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (full_name);
|
||||
}
|
||||
|
||||
g_dir_close (dir);
|
||||
|
||||
return count;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MODULE_INFO_H__
|
||||
#define __B_MODULE_INFO_H__
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
#define B_TYPE_MODULE_INFO (b_module_info_get_type ())
|
||||
#define B_MODULE_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_MODULE_INFO, BModuleInfo))
|
||||
#define B_MODULE_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_MODULE_INFO, BModuleInfoClass))
|
||||
#define B_IS_MODULE_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_MODULE_INFO))
|
||||
#define B_IS_MODULE_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_MODULE_INFO))
|
||||
#define B_MODULE_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_MODULE_INFO, BModuleInfoClass))
|
||||
|
||||
|
||||
typedef struct _BModuleInfoClass BModuleInfoClass;
|
||||
|
||||
struct _BModuleInfo
|
||||
{
|
||||
GTypeModule parent_instance;
|
||||
|
||||
GModule *module;
|
||||
gchar *filename;
|
||||
|
||||
gboolean (* register_module) (GTypeModule *module);
|
||||
};
|
||||
|
||||
struct _BModuleInfoClass
|
||||
{
|
||||
GTypeModuleClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType b_module_info_get_type (void) G_GNUC_CONST;
|
||||
BModuleInfo * b_module_info_new (const gchar *filename);
|
||||
|
||||
gint b_module_infos_scan_dir (const gchar *dirname);
|
||||
|
||||
|
||||
#endif /* __B_MODULE_INFO_H__ */
|
|
@ -0,0 +1,365 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmovie-blm.h"
|
||||
|
||||
|
||||
static void b_movie_blm_class_init (BMovieBLMClass *class);
|
||||
static void b_movie_blm_init (BMovie *movie);
|
||||
|
||||
static gboolean b_movie_blm_load_info (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
static gboolean b_movie_blm_load_all (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
static gboolean b_movie_blm_save (BMovie *movie,
|
||||
FILE *stream,
|
||||
GError **error);
|
||||
|
||||
static gboolean b_movie_blm_parse_header_line (BMovie *movie,
|
||||
const gchar *buf,
|
||||
gsize len,
|
||||
gboolean *magic);
|
||||
|
||||
static void b_movie_blm_save_header (FILE *stream,
|
||||
const gchar *name,
|
||||
const gchar *value);
|
||||
|
||||
static BMovieClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_movie_blm_get_type (void)
|
||||
{
|
||||
static GType movie_type = 0;
|
||||
|
||||
if (!movie_type)
|
||||
{
|
||||
static const GTypeInfo movie_info =
|
||||
{
|
||||
sizeof (BMovieBLMClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_movie_blm_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BMovieBLM),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_movie_blm_init
|
||||
};
|
||||
|
||||
movie_type = g_type_register_static (B_TYPE_MOVIE,
|
||||
"BMovieBLM",
|
||||
&movie_info, 0);
|
||||
}
|
||||
|
||||
return movie_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_blm_class_init (BMovieBLMClass *class)
|
||||
{
|
||||
BMovieClass *movie_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
movie_class = B_MOVIE_CLASS (class);
|
||||
|
||||
movie_class->load_info = b_movie_blm_load_info;
|
||||
movie_class->load_all = b_movie_blm_load_all;
|
||||
movie_class->save = b_movie_blm_save;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_blm_init (BMovie *movie)
|
||||
{
|
||||
movie->maxval = 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_blm_load_info (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
GString *str = g_string_new_len (NULL, 128);
|
||||
gboolean magic = FALSE;
|
||||
|
||||
while (g_io_channel_read_line_string (io, str, NULL,
|
||||
error) == G_IO_STATUS_NORMAL)
|
||||
{
|
||||
if (! b_movie_blm_parse_header_line (movie, str->str, str->len, &magic))
|
||||
{
|
||||
if (!magic)
|
||||
g_set_error (error, 0, 0, "Error parsing movie header.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
|
||||
return magic;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_blm_load_all (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
GString *str = g_string_new_len (NULL, 128);
|
||||
guchar *data = NULL;
|
||||
gboolean header_parsed = FALSE;
|
||||
gboolean magic = FALSE;
|
||||
gint line = -1;
|
||||
gint duration;
|
||||
|
||||
while (g_io_channel_read_line_string (io, str, NULL,
|
||||
error) == G_IO_STATUS_NORMAL)
|
||||
{
|
||||
if (!header_parsed)
|
||||
{
|
||||
if (! b_movie_blm_parse_header_line (movie,
|
||||
str->str, str->len, &magic))
|
||||
{
|
||||
if (magic)
|
||||
header_parsed = TRUE;
|
||||
else
|
||||
break;
|
||||
|
||||
movie->duration = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (header_parsed)
|
||||
{
|
||||
const gchar *buf = str->str;
|
||||
gint len = str->len;
|
||||
|
||||
if (!data)
|
||||
data = g_malloc (movie->width * movie->height);
|
||||
|
||||
/* skip empty lines and bufs */
|
||||
if (len == 0 || buf[0] == '#' || g_ascii_isspace (buf[0]))
|
||||
continue;
|
||||
|
||||
if (line == -1)
|
||||
{
|
||||
if (buf[0] == '@')
|
||||
{
|
||||
if (sscanf (buf+1, "%d", &duration) == 1 && duration > 0)
|
||||
line = 0;
|
||||
|
||||
if (duration < B_MOVIE_MIN_DELAY)
|
||||
{
|
||||
g_printerr ("Frame with %d ms duration, "
|
||||
"using %d ms instead\n",
|
||||
duration, B_MOVIE_MIN_DELAY);
|
||||
duration = B_MOVIE_MIN_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buf[0] == '@' || len - 1 < movie->width)
|
||||
{
|
||||
g_printerr ("Invalid frame, skipping.\n");
|
||||
line = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < movie->width; i++)
|
||||
{
|
||||
gint d = (buf[i] == '1' ? 1 : 0);
|
||||
data[movie->width * line + i] = d * movie->maxval;
|
||||
}
|
||||
|
||||
if (++line == movie->height)
|
||||
{
|
||||
b_movie_prepend_frame (movie, duration, data);
|
||||
line = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
g_string_free (str, TRUE);
|
||||
|
||||
/* caller checks movie->n_frames and sets an error if no frames were found */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_blm_save (BMovie *movie,
|
||||
FILE *stream,
|
||||
GError **error)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
if (movie->channels != 1)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Cannot save movie with more than one channel as BLM");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fprintf (stream,
|
||||
"# Blinkenlights Movie %dx%d\n", movie->width, movie->height);
|
||||
|
||||
b_movie_blm_save_header (stream, "name", movie->title);
|
||||
b_movie_blm_save_header (stream, "description", movie->description);
|
||||
b_movie_blm_save_header (stream, "creator", movie->creator);
|
||||
b_movie_blm_save_header (stream, "creator", "blib " VERSION);
|
||||
b_movie_blm_save_header (stream, "author", movie->author);
|
||||
b_movie_blm_save_header (stream, "email", movie->email);
|
||||
b_movie_blm_save_header (stream, "url", movie->url);
|
||||
|
||||
fprintf (stream, "# duration = %d\n", movie->duration);
|
||||
|
||||
for (list = movie->frames; list; list = list->next)
|
||||
{
|
||||
BMovieFrame *frame = list->data;
|
||||
const guchar *data = frame->data;
|
||||
gint x, y;
|
||||
|
||||
fprintf (stream, "\n@%d\n", frame->duration);
|
||||
|
||||
for (y = 0; y < movie->height; y++)
|
||||
{
|
||||
for (x = 0; x < movie->width; x++, data++)
|
||||
fputc ((*data > movie->maxval / 2) ? '1' : '0', stream);
|
||||
|
||||
fputc ('\n', stream);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_blm_parse_header_line (BMovie *movie,
|
||||
const gchar *buf,
|
||||
gsize len,
|
||||
gboolean *magic)
|
||||
{
|
||||
const gchar *comment;
|
||||
|
||||
if (!len)
|
||||
return FALSE;
|
||||
|
||||
if (! *magic)
|
||||
{
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
if (sscanf (buf, " %dx%d", &width, &height) != 2 ||
|
||||
width < 1 || height < 1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
movie->width = width;
|
||||
movie->height = height;
|
||||
|
||||
*magic = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (buf[0] != '#')
|
||||
return FALSE;
|
||||
|
||||
comment = buf + 1;
|
||||
len--;
|
||||
while (len && g_ascii_isspace (*comment))
|
||||
{
|
||||
comment++;
|
||||
len--;
|
||||
}
|
||||
|
||||
if (!g_utf8_validate (comment, -1, NULL))
|
||||
return TRUE; /* ignore silently */
|
||||
|
||||
if (!movie->title)
|
||||
{
|
||||
if (g_ascii_strncasecmp (comment, "name=", 5) == 0)
|
||||
movie->title = g_strstrip (g_strndup (comment + 5, len - 6));
|
||||
else if (g_ascii_strncasecmp (comment, "name =", 6) == 0)
|
||||
movie->title = g_strstrip (g_strndup (comment + 6, len - 7));
|
||||
}
|
||||
if (!movie->description)
|
||||
{
|
||||
if (g_ascii_strncasecmp (comment, "description=", 12) == 0)
|
||||
movie->description = g_strstrip (g_strndup (comment + 12, len - 13));
|
||||
else if (g_ascii_strncasecmp (comment, "description =", 13) == 0)
|
||||
movie->description = g_strstrip (g_strndup (comment + 13, len - 14));
|
||||
}
|
||||
if (!movie->duration)
|
||||
{
|
||||
if (g_ascii_strncasecmp (comment, "duration=", 9) == 0 ||
|
||||
g_ascii_strncasecmp (comment, "duration =", 10) == 0)
|
||||
{
|
||||
sscanf (comment + 9, "%d", &movie->duration);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_blm_save_header (FILE *stream,
|
||||
const gchar *name,
|
||||
const gchar *value)
|
||||
{
|
||||
const gchar *end;
|
||||
|
||||
if (!value || !*value)
|
||||
return;
|
||||
|
||||
fprintf (stream, "# %s = ", name);
|
||||
|
||||
end = strchr (value, '\n');
|
||||
if (!end)
|
||||
end = value + MIN (strlen (value), 70 - strlen (name));
|
||||
|
||||
if (*end)
|
||||
{
|
||||
gchar *dup = g_strndup (value, end - value);
|
||||
fprintf (stream, dup);
|
||||
g_free (dup);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stream, value);
|
||||
}
|
||||
|
||||
fputc ('\n', stream);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MOVIE_BLM_H__
|
||||
#define __B_MOVIE_BLM_H__
|
||||
|
||||
#include "bmovie.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define B_TYPE_MOVIE_BLM (b_movie_blm_get_type ())
|
||||
#define B_MOVIE_BLM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_MOVIE_BLM, BMovieBLM))
|
||||
#define B_MOVIE_BLM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_MOVIE_BLM, BMovieBLMClass))
|
||||
#define B_IS_MOVIE_BLM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_MOVIE_BLM))
|
||||
#define B_IS_MOVIE_BLM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_MOVIE_BLM))
|
||||
|
||||
typedef struct _BMovieClass BMovieBLMClass;
|
||||
typedef struct _BMovie BMovieBLM;
|
||||
|
||||
GType b_movie_blm_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MOVIE_BLM_H__ */
|
|
@ -0,0 +1,468 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmovie.h"
|
||||
#include "bmovie-bml-parser.h"
|
||||
#include "bparser.h"
|
||||
#include "butils.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PARSER_IN_BLM = B_PARSER_STATE_USER,
|
||||
PARSER_IN_HEADER,
|
||||
PARSER_IN_TITLE,
|
||||
PARSER_IN_DESCRIPTION,
|
||||
PARSER_IN_CREATOR,
|
||||
PARSER_IN_AUTHOR,
|
||||
PARSER_IN_EMAIL,
|
||||
PARSER_IN_URL,
|
||||
PARSER_IN_DURATION,
|
||||
PARSER_IN_LOOP,
|
||||
PARSER_IN_FRAME,
|
||||
PARSER_IN_ROW,
|
||||
PARSER_FINISH,
|
||||
};
|
||||
|
||||
typedef struct _ParserData ParserData;
|
||||
|
||||
struct _ParserData
|
||||
{
|
||||
gint bits;
|
||||
gint channels;
|
||||
|
||||
gint frame_duration;
|
||||
guchar *frame_data;
|
||||
gint frame_next_row;
|
||||
|
||||
BMovie *movie;
|
||||
gboolean lazy;
|
||||
};
|
||||
|
||||
static BParserState parser_start_element (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static BParserState parser_end_element (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar *cdata,
|
||||
gsize cdata_len,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
static gboolean parse_blm_attributes (ParserData *data,
|
||||
const gchar **names,
|
||||
const gchar **values);
|
||||
static gboolean parse_frame_attributes (ParserData *data,
|
||||
const gchar **names,
|
||||
const gchar **values);
|
||||
|
||||
|
||||
gboolean
|
||||
b_movie_bml_parse_bml (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
gboolean lazy,
|
||||
GError **error)
|
||||
{
|
||||
BParser *parser;
|
||||
ParserData data;
|
||||
gboolean retval;
|
||||
|
||||
data.movie = movie;
|
||||
data.lazy = lazy;
|
||||
data.frame_data = NULL;
|
||||
|
||||
parser = b_parser_new (parser_start_element, parser_end_element, &data);
|
||||
|
||||
retval = b_parser_parse_io_channel (parser, io, FALSE, error);
|
||||
|
||||
if (retval && b_parser_get_state (parser) != PARSER_FINISH)
|
||||
{
|
||||
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"This doesn't look like Blinkenlights Markup Language");
|
||||
retval = FALSE;
|
||||
}
|
||||
|
||||
b_parser_free (parser);
|
||||
|
||||
g_free (data.frame_data);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* parser functions */
|
||||
|
||||
static BParserState
|
||||
parser_start_element (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
ParserData *data = (ParserData *) user_data;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case B_PARSER_STATE_TOPLEVEL:
|
||||
if (! strcmp (element_name, "blm"))
|
||||
{
|
||||
if (! parse_blm_attributes (data, attribute_names, attribute_values))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Invalid attributes for blm element");
|
||||
break;
|
||||
}
|
||||
|
||||
return PARSER_IN_BLM;
|
||||
}
|
||||
break;
|
||||
|
||||
case PARSER_IN_BLM:
|
||||
if (! strcmp (element_name, "header"))
|
||||
return PARSER_IN_HEADER;
|
||||
|
||||
if (data->lazy)
|
||||
return B_PARSER_STATE_UNKNOWN;
|
||||
|
||||
if (! strcmp (element_name, "frame"))
|
||||
{
|
||||
if (! parse_frame_attributes (data,
|
||||
attribute_names, attribute_values))
|
||||
{
|
||||
g_set_error (error, G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Invalid attributes for frame element number %d",
|
||||
data->movie->n_frames);
|
||||
break;
|
||||
}
|
||||
|
||||
if (data->frame_data)
|
||||
memset (data->frame_data, 0,
|
||||
data->movie->width * data->movie->height);
|
||||
else
|
||||
data->frame_data = g_new0 (guchar, (data->movie->width *
|
||||
data->movie->height));
|
||||
|
||||
data->frame_next_row = 0;
|
||||
|
||||
return PARSER_IN_FRAME;
|
||||
}
|
||||
break;
|
||||
|
||||
case PARSER_IN_HEADER:
|
||||
if (! strcmp (element_name, "title"))
|
||||
return PARSER_IN_TITLE;
|
||||
|
||||
if (! strcmp (element_name, "description"))
|
||||
return PARSER_IN_DESCRIPTION;
|
||||
|
||||
if (! strcmp (element_name, "creator"))
|
||||
return PARSER_IN_CREATOR;
|
||||
|
||||
if (! strcmp (element_name, "author"))
|
||||
return PARSER_IN_AUTHOR;
|
||||
|
||||
if (! strcmp (element_name, "email"))
|
||||
return PARSER_IN_EMAIL;
|
||||
|
||||
if (! strcmp (element_name, "url"))
|
||||
return PARSER_IN_URL;
|
||||
|
||||
/* only parse duration if we are lazy-loading ! */
|
||||
if (! strcmp (element_name, "duration") && data->lazy)
|
||||
return PARSER_IN_DURATION;
|
||||
|
||||
if (! strcmp (element_name, "loop"))
|
||||
return PARSER_IN_LOOP;
|
||||
|
||||
break;
|
||||
|
||||
case PARSER_IN_FRAME:
|
||||
if (! strcmp (element_name, "row"))
|
||||
{
|
||||
if (data->frame_next_row == data->movie->height)
|
||||
{
|
||||
g_set_error (error, G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Too many rows in frame number %d",
|
||||
data->movie->n_frames);
|
||||
break;
|
||||
}
|
||||
|
||||
return PARSER_IN_ROW;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return B_PARSER_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
static BParserState
|
||||
parser_end_element (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar *cdata,
|
||||
gsize cdata_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
ParserData *data = (ParserData *) user_data;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case PARSER_IN_BLM:
|
||||
return PARSER_FINISH;
|
||||
|
||||
case PARSER_IN_HEADER:
|
||||
return PARSER_IN_BLM;
|
||||
|
||||
case PARSER_IN_TITLE:
|
||||
if (!data->movie->title)
|
||||
data->movie->title = g_strdup (cdata);
|
||||
return PARSER_IN_HEADER;
|
||||
|
||||
case PARSER_IN_DESCRIPTION:
|
||||
if (!data->movie->description)
|
||||
data->movie->description = g_strdup (cdata);
|
||||
return PARSER_IN_HEADER;
|
||||
|
||||
case PARSER_IN_CREATOR:
|
||||
if (!data->movie->creator)
|
||||
data->movie->creator = g_strdup (cdata);
|
||||
return PARSER_IN_HEADER;
|
||||
|
||||
case PARSER_IN_AUTHOR:
|
||||
if (!data->movie->author)
|
||||
data->movie->author = g_strdup (cdata);
|
||||
return PARSER_IN_HEADER;
|
||||
|
||||
case PARSER_IN_EMAIL:
|
||||
if (!data->movie->email)
|
||||
data->movie->email = g_strdup (cdata);
|
||||
return PARSER_IN_HEADER;
|
||||
|
||||
case PARSER_IN_URL:
|
||||
if (!data->movie->url)
|
||||
data->movie->url = g_strdup (cdata);
|
||||
return PARSER_IN_HEADER;
|
||||
|
||||
case PARSER_IN_DURATION:
|
||||
b_parse_int (cdata, & data->movie->duration);
|
||||
return PARSER_IN_HEADER;
|
||||
|
||||
case PARSER_IN_LOOP:
|
||||
/* for backward compat, ignore loop if it has a value of "no" */
|
||||
if (!cdata_len || g_ascii_tolower (*cdata) != 'n')
|
||||
data->movie->loop = TRUE;
|
||||
return PARSER_IN_HEADER;
|
||||
|
||||
case PARSER_IN_FRAME:
|
||||
if (data->frame_next_row != data->movie->height)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Too few rows in frame number %d",
|
||||
data->movie->n_frames);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_movie_prepend_frame (data->movie,
|
||||
data->frame_duration, data->frame_data);
|
||||
}
|
||||
return PARSER_IN_BLM;
|
||||
|
||||
case PARSER_IN_ROW:
|
||||
{
|
||||
gchar *row;
|
||||
gchar *src;
|
||||
guchar *dest;
|
||||
gint bpp_src;
|
||||
gint i, x = 0;
|
||||
|
||||
row = g_strdup (cdata);
|
||||
|
||||
if ((data->bits <= 4 &&
|
||||
cdata_len != data->movie->width * data->channels) ||
|
||||
(data->bits > 4 &&
|
||||
cdata_len != data->movie->width * data->channels * 2))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Invalid row length in frame number %d",
|
||||
data->movie->n_frames);
|
||||
goto row_done;
|
||||
}
|
||||
|
||||
bpp_src = data->bits <= 4 ? 1 : 2;
|
||||
|
||||
src = row;
|
||||
dest = data->frame_data + (data->movie->width * data->frame_next_row);
|
||||
|
||||
for (; x < data->movie->width; x++, src += bpp_src, dest += 1)
|
||||
{
|
||||
*dest = 0;
|
||||
|
||||
for (i = 0; i < bpp_src; i++)
|
||||
{
|
||||
*dest <<= 4;
|
||||
|
||||
src[i] = g_ascii_tolower (src[i]);
|
||||
|
||||
switch (src[i])
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
*dest += src[i] - '0';
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
*dest += 10 + src[i] - 'a';
|
||||
break;
|
||||
|
||||
default:
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Invalid row data in frame number %d",
|
||||
data->movie->n_frames);
|
||||
goto row_done;
|
||||
}
|
||||
}
|
||||
|
||||
if (*dest > data->movie->maxval)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Row data exceeds maxval (%d) in frame number %d",
|
||||
data->movie->maxval, data->movie->n_frames);
|
||||
goto row_done;
|
||||
}
|
||||
}
|
||||
|
||||
row_done:
|
||||
g_free (row);
|
||||
data->frame_next_row++;
|
||||
|
||||
if (x != data->movie->width)
|
||||
return B_PARSER_STATE_UNKNOWN;
|
||||
}
|
||||
return PARSER_IN_FRAME;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return B_PARSER_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_blm_attributes (ParserData *data,
|
||||
const gchar **names,
|
||||
const gchar **values)
|
||||
{
|
||||
gint i;
|
||||
gint width = 0;
|
||||
gint height = 0;
|
||||
gint bits = 1;
|
||||
gint channels = 1;
|
||||
|
||||
for (i = 0; names[i] && values[i]; i++)
|
||||
{
|
||||
if (strcmp (names[i], "width") == 0)
|
||||
b_parse_int (values[i], &width);
|
||||
else if (strcmp (names[i], "height") == 0)
|
||||
b_parse_int (values[i], &height);
|
||||
else if (strcmp (names[i], "bits") == 0)
|
||||
b_parse_int (values[i], &bits);
|
||||
else if (strcmp (names[i], "channels") == 0)
|
||||
b_parse_int (values[i], &channels);
|
||||
}
|
||||
|
||||
if (width > 0 && height > 0 &&
|
||||
(bits >= 1 && bits <= 8) && (channels == 1)) /* channels == 3 */
|
||||
{
|
||||
data->movie->width = width;
|
||||
data->movie->height = height;
|
||||
data->movie->maxval = (1 << bits) - 1;
|
||||
data->movie->channels = channels;
|
||||
|
||||
data->bits = bits;
|
||||
data->channels = channels;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_frame_attributes (ParserData *data,
|
||||
const gchar **names,
|
||||
const gchar **values)
|
||||
{
|
||||
gint i;
|
||||
gint duration = 0;
|
||||
|
||||
for (i = 0; names[i] && values[i]; i++)
|
||||
{
|
||||
if (strcmp (names[i], "duration") == 0)
|
||||
b_parse_int (values[i], &duration);
|
||||
}
|
||||
|
||||
if (duration < B_MOVIE_MIN_DELAY)
|
||||
{
|
||||
g_printerr ("Frame with %d ms duration, using %d ms instead\n",
|
||||
duration, B_MOVIE_DEFAULT_DELAY);
|
||||
duration = B_MOVIE_DEFAULT_DELAY;
|
||||
}
|
||||
|
||||
data->frame_duration = duration;
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MOVIE_BML_PARSER_H__
|
||||
#define __B_MOVIE_BML_PARSER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean b_movie_bml_parse_bml (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
gboolean lazy,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MOVIE_BML_PARSER_H__ */
|
|
@ -0,0 +1,211 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bobject.h"
|
||||
#include "bmovie-bml.h"
|
||||
#include "bmovie-bml-parser.h"
|
||||
#include "bwriter.h"
|
||||
|
||||
|
||||
static void b_movie_bml_class_init (BMovieBMLClass *class);
|
||||
|
||||
static gboolean b_movie_bml_load_info (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
static gboolean b_movie_bml_load_all (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
static gboolean b_movie_bml_save (BMovie *movie,
|
||||
FILE *stream,
|
||||
GError **error);
|
||||
|
||||
|
||||
static BMovieClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_movie_bml_get_type (void)
|
||||
{
|
||||
static GType movie_type = 0;
|
||||
|
||||
if (!movie_type)
|
||||
{
|
||||
static const GTypeInfo movie_info =
|
||||
{
|
||||
sizeof (BMovieBMLClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_movie_bml_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BMovieBML),
|
||||
0, /* n_preallocs */
|
||||
NULL /* instance_init */
|
||||
};
|
||||
|
||||
movie_type = g_type_register_static (B_TYPE_MOVIE,
|
||||
"BMovieBML",
|
||||
&movie_info, 0);
|
||||
}
|
||||
|
||||
return movie_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_bml_class_init (BMovieBMLClass *class)
|
||||
{
|
||||
BMovieClass *movie_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
movie_class = B_MOVIE_CLASS (class);
|
||||
|
||||
movie_class->load_info = b_movie_bml_load_info;
|
||||
movie_class->load_all = b_movie_bml_load_all;
|
||||
movie_class->save = b_movie_bml_save;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_bml_load_info (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
return b_movie_bml_parse_bml (movie, io, TRUE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_bml_load_all (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
return b_movie_bml_parse_bml (movie, io, FALSE, error);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
b_movie_bml_save (BMovie *movie,
|
||||
FILE *stream,
|
||||
GError **error)
|
||||
{
|
||||
BWriter *writer;
|
||||
GList *list;
|
||||
gchar width[16];
|
||||
gchar height[16];
|
||||
gchar buf[16];
|
||||
gchar *row;
|
||||
guint len, bits;
|
||||
|
||||
if (movie->channels != 1)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Cannot yet save movie with more than one channel as BML");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* calculate bits from movie->maxval */
|
||||
for (len = movie->maxval, bits = 0; len; len >>= 1, bits++)
|
||||
;
|
||||
|
||||
g_snprintf (width, sizeof (width), "%d", movie->width);
|
||||
g_snprintf (height, sizeof (height), "%d", movie->height);
|
||||
g_snprintf (buf, sizeof (buf), "%u", bits);
|
||||
|
||||
writer = b_writer_new (stream, 4);
|
||||
|
||||
b_write_header (writer, "utf-8");
|
||||
|
||||
b_write_open_tag (writer, "blm",
|
||||
"width", width, "height", height, "bits", buf, NULL);
|
||||
|
||||
if (movie->title)
|
||||
{
|
||||
b_write_open_tag (writer, "header", NULL);
|
||||
|
||||
#define BML_WRITE_META(tag) \
|
||||
if (movie->tag) b_write_element (writer, #tag, movie->tag, NULL);
|
||||
|
||||
BML_WRITE_META (title);
|
||||
BML_WRITE_META (description);
|
||||
|
||||
if (movie->creator)
|
||||
b_write_element (writer, "creator", movie->creator, NULL);
|
||||
else
|
||||
b_write_element (writer, "creator", "blib " VERSION, NULL);
|
||||
|
||||
BML_WRITE_META (author);
|
||||
BML_WRITE_META (email);
|
||||
BML_WRITE_META (url);
|
||||
|
||||
g_snprintf (buf, sizeof (buf), "%d", movie->duration);
|
||||
b_write_element (writer, "duration", buf, NULL);
|
||||
|
||||
if (movie->loop)
|
||||
b_write_element (writer, "loop", NULL, NULL);
|
||||
|
||||
#undef BML_WRITE_META
|
||||
|
||||
b_write_close_tag (writer, "header");
|
||||
}
|
||||
|
||||
/* calculate length of row data */
|
||||
len = movie->width * (bits > 4 ? 2 : 1);
|
||||
row = g_new (gchar, len + 1);
|
||||
row[len] = '\0';
|
||||
|
||||
for (list = movie->frames; list; list = list->next)
|
||||
{
|
||||
BMovieFrame *frame = list->data;
|
||||
guchar *data = frame->data;
|
||||
gint x, y;
|
||||
|
||||
g_snprintf (buf, sizeof (buf), "%d", frame->duration);
|
||||
b_write_open_tag (writer, "frame", "duration", buf, NULL);
|
||||
|
||||
for (y = 0; y < movie->height; y++)
|
||||
{
|
||||
if (bits > 4)
|
||||
for (x = 0; x < movie->width; x++, data++)
|
||||
g_snprintf (row + x * 2, 3, "%02x", *data);
|
||||
else
|
||||
for (x = 0; x < movie->width; x++, data++)
|
||||
g_snprintf (row + x, 2, "%1x", *data);
|
||||
|
||||
b_write_element (writer, "row", row, NULL);
|
||||
}
|
||||
|
||||
b_write_close_tag (writer, "frame");
|
||||
}
|
||||
|
||||
g_free (row);
|
||||
|
||||
b_write_close_tag (writer, "blm");
|
||||
|
||||
b_writer_free (writer);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MOVIE_BML_H__
|
||||
#define __B_MOVIE_BML_H__
|
||||
|
||||
#include "bmovie.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define B_TYPE_MOVIE_BML (b_movie_bml_get_type ())
|
||||
#define B_MOVIE_BML(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_MOVIE_BML, BMovieBML))
|
||||
#define B_MOVIE_BML_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_MOVIE_BML, BMovieBMLClass))
|
||||
#define B_IS_MOVIE_BML(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_MOVIE_BML))
|
||||
#define B_IS_MOVIE_BML_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_MOVIE_BML))
|
||||
|
||||
typedef struct _BMovieClass BMovieBMLClass;
|
||||
typedef struct _BMovie BMovieBML;
|
||||
|
||||
GType b_movie_bml_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MOVIE_BML_H__ */
|
|
@ -0,0 +1,158 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "beffects.h"
|
||||
#include "bmovie.h"
|
||||
#include "bmovie-effects.h"
|
||||
|
||||
|
||||
/**
|
||||
* b_movie_normalize:
|
||||
* @movie: a #BMovie object
|
||||
* @maxval: the new maximum value to apply to @movie
|
||||
*
|
||||
* Changes the maximum value for @movie, that is the value that will
|
||||
* cause the lamp to glow with full intensity. This function iterates
|
||||
* over all frames of the movie and changes the frame data accordingly.
|
||||
**/
|
||||
void
|
||||
b_movie_normalize (BMovie *movie,
|
||||
gint maxval)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
g_return_if_fail (B_IS_MOVIE (movie));
|
||||
g_return_if_fail (maxval > 0 && maxval < 256);
|
||||
|
||||
if (movie->maxval == maxval)
|
||||
return;
|
||||
|
||||
for (list = movie->frames; list; list = list->next)
|
||||
{
|
||||
BMovieFrame *frame = list->data;
|
||||
guchar *data = frame->data;
|
||||
gint x, y;
|
||||
|
||||
for (y = 0; y < movie->height; y++)
|
||||
for (x = 0; x < movie->width; x++, data++)
|
||||
*data = ((gint) *data * maxval) / movie->maxval;
|
||||
}
|
||||
|
||||
movie->maxval = maxval;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_apply_colormap:
|
||||
* @movie: a #BMovie object
|
||||
* @map: a LUT that remaps each color value
|
||||
*
|
||||
* Applies a mapping defined by @map to all frames of the @movie. The
|
||||
* mapping must not exceed the movie's maxval.
|
||||
**/
|
||||
void
|
||||
b_movie_apply_colormap (BMovie *movie,
|
||||
guchar *map)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
g_return_if_fail (B_IS_MOVIE (movie));
|
||||
g_return_if_fail (map != NULL);
|
||||
|
||||
for (list = movie->frames; list; list = list->next)
|
||||
{
|
||||
BMovieFrame *frame = list->data;
|
||||
guchar *data = frame->data;
|
||||
gint x, y;
|
||||
|
||||
for (y = 0; y < movie->height; y++)
|
||||
for (x = 0; x < movie->width; x++, data++)
|
||||
*data = map[*data];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_apply_effects:
|
||||
* @movie: a #BMovie object
|
||||
* @effects: a #BEffects object or %NULL
|
||||
* @reverse: whether to reverse the order of frames in @movie
|
||||
* @speed: an adjustment factor to be applied on the frame timing
|
||||
*
|
||||
* If @effects is non-%NULL, the effects described by it are applied
|
||||
* to @movie. If @reverse is %TRUE, the order of frames is reversed.
|
||||
* If @speed is different from 1.0, the frame timing is adjusted; for
|
||||
* example a value of 2.0 makes the movie play with double speed.
|
||||
**/
|
||||
void
|
||||
b_movie_apply_effects (BMovie *movie,
|
||||
BEffects *effects,
|
||||
gboolean reverse,
|
||||
gdouble speed)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
g_return_if_fail (B_IS_MOVIE (movie));
|
||||
g_return_if_fail (effects == NULL || B_IS_EFFECTS (effects));
|
||||
g_return_if_fail (speed > 0.0);
|
||||
|
||||
for (list = movie->frames; list; list = list->next)
|
||||
{
|
||||
BMovieFrame *frame = list->data;
|
||||
|
||||
if (effects)
|
||||
{
|
||||
b_effects_apply (effects,
|
||||
frame->data,
|
||||
movie->width, movie->height,
|
||||
movie->channels, movie->maxval);
|
||||
}
|
||||
|
||||
if (speed != 1.0)
|
||||
{
|
||||
frame->start /= speed;
|
||||
frame->duration /= speed;
|
||||
}
|
||||
}
|
||||
|
||||
if (speed != 1.0)
|
||||
{
|
||||
movie->duration /= speed;
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
gint start = 0;
|
||||
|
||||
movie->frames = g_list_reverse (movie->frames);
|
||||
|
||||
for (list = movie->frames; list; list = list->next)
|
||||
{
|
||||
BMovieFrame *frame = list->data;
|
||||
|
||||
frame->start = start;
|
||||
start += frame->duration;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MOVIE_EFFECTS_H__
|
||||
#define __B_MOVIE_EFFECTS_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void b_movie_normalize (BMovie *movie,
|
||||
gint maxval);
|
||||
void b_movie_apply_colormap (BMovie *movie,
|
||||
guchar *map);
|
||||
void b_movie_apply_effects (BMovie *movie,
|
||||
BEffects *effects,
|
||||
gboolean reverse,
|
||||
gdouble speed);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MOVIE_EFFECTS_H__ */
|
|
@ -0,0 +1,282 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmovie.h"
|
||||
#include "bmovie-gif-parser.h"
|
||||
|
||||
#include "gif-load.h"
|
||||
|
||||
/* #define DEBUG_GIF 1 */
|
||||
|
||||
|
||||
static void
|
||||
b_movie_gif_compose_frame (BMovie *movie,
|
||||
guchar *gray_buf,
|
||||
guchar *image_buf,
|
||||
gint image_colors,
|
||||
guchar *image_cmap,
|
||||
guchar *frame_buf,
|
||||
GIFDisposeType frame_disposal,
|
||||
gint frame_duration,
|
||||
gint frame_transparent,
|
||||
gint frame_width,
|
||||
gint frame_height,
|
||||
gint frame_off_x,
|
||||
gint frame_off_y,
|
||||
gint frame_colors,
|
||||
guchar *frame_cmap)
|
||||
{
|
||||
guchar *src;
|
||||
guchar *dest;
|
||||
guchar *d;
|
||||
guchar *cmap;
|
||||
gint colors;
|
||||
gint x, y;
|
||||
|
||||
#if DEBUG_GIF
|
||||
g_printerr ("GIF frame: "
|
||||
"%dx%d @ %d,%d disposal: %d duration: %d transp: %d cmap: %s\n",
|
||||
frame_width, frame_height,
|
||||
frame_off_x, frame_off_y,
|
||||
frame_disposal,
|
||||
frame_duration,
|
||||
frame_transparent,
|
||||
frame_cmap ? "yes" : "no");
|
||||
#endif
|
||||
|
||||
cmap = frame_cmap ? frame_cmap : image_cmap;
|
||||
colors = frame_cmap ? frame_colors : image_colors;
|
||||
|
||||
src = frame_buf;
|
||||
dest = image_buf + frame_off_y * movie->width + frame_off_x;
|
||||
|
||||
for (y = 0; y < frame_height; y++)
|
||||
{
|
||||
d = dest;
|
||||
|
||||
for (x = 0; x < frame_width; x++)
|
||||
{
|
||||
if (frame_transparent > -1 &&
|
||||
*src == frame_transparent &&
|
||||
frame_disposal != DISPOSE_REPLACE)
|
||||
{
|
||||
d++;
|
||||
src++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*d++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
dest += movie->width;
|
||||
}
|
||||
|
||||
src = image_buf;
|
||||
dest = gray_buf;
|
||||
|
||||
for (y = 0; y < movie->height; y++)
|
||||
{
|
||||
d = dest;
|
||||
|
||||
for (x = 0; x < movie->width; x++)
|
||||
{
|
||||
if (*src < colors)
|
||||
{
|
||||
guchar *cmap_entry = cmap + *src * 3;
|
||||
|
||||
#define INTENSITY_RED 0.30
|
||||
#define INTENSITY_GREEN 0.59
|
||||
#define INTENSITY_BLUE 0.11
|
||||
#define INTENSITY(r,g,b) ((r) * INTENSITY_RED + \
|
||||
(g) * INTENSITY_GREEN + \
|
||||
(b) * INTENSITY_BLUE + \
|
||||
(1) * (1.0 / 256.0))
|
||||
|
||||
*d = INTENSITY (cmap_entry[0], cmap_entry[1], cmap_entry[2]);
|
||||
|
||||
#undef INTENSITY_RED
|
||||
#undef INTENSITS_GREEN
|
||||
#undef INTENSITY_BLUE
|
||||
#undef INTENSITY
|
||||
}
|
||||
else
|
||||
{
|
||||
*d = 0;
|
||||
}
|
||||
|
||||
d++;
|
||||
src++;
|
||||
}
|
||||
|
||||
dest += movie->width;
|
||||
}
|
||||
|
||||
b_movie_prepend_frame (movie, frame_duration, gray_buf);
|
||||
}
|
||||
|
||||
gboolean
|
||||
b_movie_gif_parse_gif (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
gboolean lazy,
|
||||
GError **error)
|
||||
{
|
||||
gint width;
|
||||
gint height;
|
||||
gint background;
|
||||
gint colors;
|
||||
guchar *cmap = NULL;
|
||||
GIFRecordType record_type;
|
||||
gint duration = 0;
|
||||
gchar *comment = NULL;
|
||||
guchar *buffer = NULL;
|
||||
guchar *frame_buffer = NULL;
|
||||
guchar *gray_buffer = NULL;
|
||||
gboolean success = FALSE;
|
||||
GIFDisposeType frame_disposal = DISPOSE_REPLACE;
|
||||
gint frame_delay = 100;
|
||||
gint frame_transparent = -1;
|
||||
|
||||
if (! GIFDecodeHeader (io,
|
||||
TRUE, &width, &height, &background, &colors, &cmap))
|
||||
goto cleanup;
|
||||
|
||||
movie->width = width;
|
||||
movie->height = height;
|
||||
|
||||
#if DEBUG_GIF
|
||||
g_printerr ("GIF background: %d colors: %d\n", background, colors);
|
||||
#endif
|
||||
|
||||
buffer = g_new0 (guchar, width * height);
|
||||
frame_buffer = g_new0 (guchar, width * height);
|
||||
gray_buffer = g_new0 (guchar, width * height);
|
||||
|
||||
if (background > -1)
|
||||
memset (buffer, background, width * height);
|
||||
|
||||
while (GIFDecodeRecordType (io, &record_type))
|
||||
{
|
||||
switch (record_type)
|
||||
{
|
||||
case IMAGE:
|
||||
{
|
||||
gint frame_width;
|
||||
gint frame_height;
|
||||
gint frame_off_x;
|
||||
gint frame_off_y;
|
||||
gint frame_colors;
|
||||
guchar *frame_cmap;
|
||||
|
||||
if (! GIFDecodeImage (io,
|
||||
&frame_width, &frame_height,
|
||||
&frame_off_x, &frame_off_y,
|
||||
&frame_colors, &frame_cmap,
|
||||
frame_buffer))
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Broken or missing image frame");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (frame_delay < B_MOVIE_MIN_DELAY)
|
||||
{
|
||||
g_printerr ("Frame with %d ms duration, using %d ms instead\n",
|
||||
frame_delay, B_MOVIE_DEFAULT_DELAY);
|
||||
frame_delay = B_MOVIE_DEFAULT_DELAY;
|
||||
}
|
||||
|
||||
duration += frame_delay;
|
||||
|
||||
if (! lazy)
|
||||
{
|
||||
b_movie_gif_compose_frame (movie,
|
||||
gray_buffer,
|
||||
buffer,
|
||||
colors,
|
||||
cmap,
|
||||
frame_buffer,
|
||||
frame_disposal,
|
||||
frame_delay,
|
||||
frame_transparent,
|
||||
frame_width,
|
||||
frame_height,
|
||||
frame_off_x,
|
||||
frame_off_y,
|
||||
frame_colors,
|
||||
frame_cmap);
|
||||
}
|
||||
|
||||
g_free (frame_cmap);
|
||||
}
|
||||
break;
|
||||
|
||||
case GRAPHIC_CONTROL_EXTENSION:
|
||||
if (! GIFDecodeGraphicControlExt (io,
|
||||
&frame_disposal,
|
||||
&frame_delay,
|
||||
&frame_transparent))
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Broken or missing graphic control extension");
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMENT_EXTENSION:
|
||||
if (! GIFDecodeCommentExt (io, &comment))
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Broken or missing comment extension");
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case UNKNOWN_EXTENSION:
|
||||
GIFDecodeUnknownExt (io);
|
||||
break;
|
||||
|
||||
case TERMINATOR:
|
||||
success = TRUE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
if (success && lazy)
|
||||
movie->duration = duration;
|
||||
|
||||
g_free (cmap);
|
||||
g_free (buffer);
|
||||
g_free (frame_buffer);
|
||||
g_free (gray_buffer);
|
||||
g_free (comment);
|
||||
|
||||
return success;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MOVIE_GIF_PARSER_H__
|
||||
#define __B_MOVIE_GIF_PARSER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean b_movie_gif_parse_gif (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
gboolean all,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MOVIE_GIF_PARSER_H__ */
|
|
@ -0,0 +1,165 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmovie-gif.h"
|
||||
#include "bmovie-gif-parser.h"
|
||||
|
||||
#include "gif-save.h"
|
||||
|
||||
|
||||
static void b_movie_gif_class_init (BMovieGIFClass *class);
|
||||
static void b_movie_gif_init (BMovie *movie);
|
||||
|
||||
static gboolean b_movie_gif_load_info (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
static gboolean b_movie_gif_load_all (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
static gboolean b_movie_gif_save (BMovie *movie,
|
||||
FILE *stream,
|
||||
GError **error);
|
||||
|
||||
|
||||
static BMovieClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_movie_gif_get_type (void)
|
||||
{
|
||||
static GType movie_type = 0;
|
||||
|
||||
if (!movie_type)
|
||||
{
|
||||
static const GTypeInfo movie_info =
|
||||
{
|
||||
sizeof (BMovieGIFClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_movie_gif_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BMovieGIF),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_movie_gif_init
|
||||
};
|
||||
|
||||
movie_type = g_type_register_static (B_TYPE_MOVIE,
|
||||
"BMovieGIF",
|
||||
&movie_info, 0);
|
||||
}
|
||||
|
||||
return movie_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_gif_class_init (BMovieGIFClass *class)
|
||||
{
|
||||
BMovieClass *movie_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
movie_class = B_MOVIE_CLASS (class);
|
||||
|
||||
movie_class->load_info = b_movie_gif_load_info;
|
||||
movie_class->load_all = b_movie_gif_load_all;
|
||||
movie_class->save = b_movie_gif_save;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_gif_init (BMovie *movie)
|
||||
{
|
||||
movie->maxval = 255;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_gif_load_info (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
return b_movie_gif_parse_gif (movie, io, TRUE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_gif_load_all (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
return b_movie_gif_parse_gif (movie, io, FALSE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_gif_save (BMovie *movie,
|
||||
FILE *stream,
|
||||
GError **error)
|
||||
{
|
||||
GList *list;
|
||||
guchar *cmap;
|
||||
guint i, len;
|
||||
guint bits;
|
||||
|
||||
g_return_val_if_fail (movie->maxval > 0, FALSE);
|
||||
|
||||
/* calculate bits from movie->maxval */
|
||||
for (len = movie->maxval, bits = 0; len; len >>= 1, bits++)
|
||||
;
|
||||
|
||||
len = 1 << bits;
|
||||
cmap = g_new0 (guchar, 3 * len);
|
||||
|
||||
for (i = 0; i <= movie->maxval; i++)
|
||||
{
|
||||
guint value = (i * 255) / movie->maxval;
|
||||
|
||||
cmap[i*3 + 0] = value;
|
||||
cmap[i*3 + 1] = value;
|
||||
cmap[i*3 + 2] = value;
|
||||
}
|
||||
|
||||
GIFEncodeHeader (stream, TRUE, movie->width, movie->height, 0, bits, cmap);
|
||||
|
||||
if (movie->loop)
|
||||
GIFEncodeLoopExt (stream, 0);
|
||||
|
||||
GIFEncodeCommentExt (stream, "Blinkenlights Movie written by blib " VERSION);
|
||||
|
||||
for (list = movie->frames; list; list = list->next)
|
||||
{
|
||||
BMovieFrame *frame = list->data;
|
||||
guchar *data = frame->data;
|
||||
|
||||
GIFEncodeGraphicControlExt (stream,
|
||||
DISPOSE_REPLACE, frame->duration, TRUE, -1);
|
||||
GIFEncodeImageData (stream,
|
||||
movie->width, movie->height, bits, 0, 0, data);
|
||||
}
|
||||
|
||||
GIFEncodeClose (stream);
|
||||
|
||||
g_free (cmap);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MOVIE_GIF_H__
|
||||
#define __B_MOVIE_GIF_H__
|
||||
|
||||
#include "bmovie.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define B_TYPE_MOVIE_GIF (b_movie_gif_get_type ())
|
||||
#define B_MOVIE_GIF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_MOVIE_GIF, BMovieGIF))
|
||||
#define B_MOVIE_GIF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_MOVIE_GIF, BMovieGIFClass))
|
||||
#define B_IS_MOVIE_GIF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_MOVIE_GIF))
|
||||
#define B_IS_MOVIE_GIF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_MOVIE_GIF))
|
||||
|
||||
typedef struct _BMovieClass BMovieGIFClass;
|
||||
typedef struct _BMovie BMovieGIF;
|
||||
|
||||
GType b_movie_gif_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MOVIE_GIF_H__ */
|
|
@ -0,0 +1,657 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmovie.h"
|
||||
#include "bobject.h"
|
||||
#include "bparser.h"
|
||||
|
||||
/* it's bad style to include our own subclasses, but... */
|
||||
#include "bmovie-blm.h"
|
||||
#include "bmovie-bml.h"
|
||||
#include "bmovie-gif.h"
|
||||
|
||||
|
||||
static void b_movie_class_init (BMovieClass *class);
|
||||
static void b_movie_init (BMovie *movie);
|
||||
static void b_movie_finalize (GObject *object);
|
||||
static void b_movie_finalize_data (BMovie *movie,
|
||||
gboolean all);
|
||||
static void b_movie_nullify_data (BMovie *movie,
|
||||
gboolean all);
|
||||
static gboolean b_movie_load_info (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
static gboolean b_movie_load_all (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
static BMovie * b_movie_new_from_io_channel (GIOChannel *io,
|
||||
const gchar *filename,
|
||||
const gchar *name,
|
||||
gboolean lazy,
|
||||
GError **error);
|
||||
static GType b_movie_type_from_io_channel(GIOChannel *io,
|
||||
GError **error);
|
||||
|
||||
|
||||
static BObjectClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_movie_get_type (void)
|
||||
{
|
||||
static GType movie_type = 0;
|
||||
|
||||
if (!movie_type)
|
||||
{
|
||||
static const GTypeInfo movie_info =
|
||||
{
|
||||
sizeof (BMovieClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_movie_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BMovie),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_movie_init,
|
||||
};
|
||||
|
||||
movie_type = g_type_register_static (B_TYPE_OBJECT,
|
||||
"BMovie", &movie_info, 0);
|
||||
}
|
||||
|
||||
return movie_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_class_init (BMovieClass *class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = b_movie_finalize;
|
||||
|
||||
class->load_info = NULL;
|
||||
class->load_all = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_init (BMovie *movie)
|
||||
{
|
||||
movie->width = 0;
|
||||
movie->height = 0;
|
||||
movie->maxval = 0;
|
||||
movie->channels = 1;
|
||||
|
||||
movie->load_count = 0;
|
||||
|
||||
b_movie_nullify_data (movie, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_finalize (GObject *object)
|
||||
{
|
||||
BMovie *movie = B_MOVIE (object);
|
||||
|
||||
b_movie_finalize_data (movie, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_finalize_data (BMovie *movie,
|
||||
gboolean all)
|
||||
{
|
||||
BMovieFrame *frame;
|
||||
GList *list;
|
||||
|
||||
g_return_if_fail (B_IS_MOVIE (movie));
|
||||
|
||||
if (all)
|
||||
{
|
||||
g_free (movie->title);
|
||||
g_free (movie->description);
|
||||
g_free (movie->creator);
|
||||
g_free (movie->author);
|
||||
g_free (movie->email);
|
||||
g_free (movie->url);
|
||||
}
|
||||
|
||||
for (list = movie->frames; list; list = g_list_next (list))
|
||||
{
|
||||
frame = (BMovieFrame *) list->data;
|
||||
|
||||
g_free (frame->data);
|
||||
g_free (frame);
|
||||
}
|
||||
g_list_free (movie->frames);
|
||||
|
||||
b_movie_nullify_data (movie, all);
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_nullify_data (BMovie *movie,
|
||||
gboolean all)
|
||||
{
|
||||
movie->duration = 0;
|
||||
movie->n_frames = 0;
|
||||
movie->frames = NULL;
|
||||
|
||||
if (all)
|
||||
{
|
||||
movie->title = NULL;
|
||||
movie->description = NULL;
|
||||
movie->creator = NULL;
|
||||
movie->author = NULL;
|
||||
movie->email = NULL;
|
||||
movie->url = NULL;
|
||||
movie->loop = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_load_info (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
if (B_MOVIE_GET_CLASS (movie)->load_info)
|
||||
return B_MOVIE_GET_CLASS (movie)->load_info (movie, io, error);
|
||||
|
||||
g_warning ("b_movie_load_info() unimplemented");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_load_all (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
|
||||
b_movie_finalize_data (movie, TRUE);
|
||||
|
||||
if (B_MOVIE_GET_CLASS (movie)->load_all)
|
||||
success = B_MOVIE_GET_CLASS (movie)->load_all (movie, io, error);
|
||||
else
|
||||
g_warning ("b_movie_load_all() unimplemented");
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (movie->n_frames > 0)
|
||||
{
|
||||
movie->frames = g_list_reverse (movie->frames);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Couldn't find any valid frames in the input.");
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_new_from_file:
|
||||
* @filename: the name of the file to load
|
||||
* @lazy_load: whether to do lazy-loading, i.e. only load the header
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Tries to load a #BMovie from the file pointed to by @filename. If
|
||||
* @lazy_load is %TRUE, only the header is loaded and no frames are stored.
|
||||
*
|
||||
* Return value: a newly allocated #BMovie object or %NULL if the load
|
||||
* failed
|
||||
**/
|
||||
BMovie *
|
||||
b_movie_new_from_file (const gchar *filename,
|
||||
gboolean lazy_load,
|
||||
GError **error)
|
||||
{
|
||||
BMovie *movie = NULL;
|
||||
GIOChannel *io;
|
||||
gchar *name;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
name = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
|
||||
|
||||
io = g_io_channel_new_file (filename, "r", error);
|
||||
if (! io)
|
||||
return NULL;
|
||||
|
||||
g_io_channel_set_encoding (io, NULL, NULL);
|
||||
|
||||
movie = b_movie_new_from_io_channel (io, filename, name, lazy_load, error);
|
||||
|
||||
g_io_channel_unref (io);
|
||||
|
||||
g_free (name);
|
||||
|
||||
return movie;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_new_from_fd:
|
||||
* @fd: a UNIX file descriptor
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Tries to load a #BMovie from the UNIX file descriptor @fd. Lazy
|
||||
* loading from file descriptors is not implemented since it doesn't
|
||||
* seem to make much sense.
|
||||
*
|
||||
* Return value: a newly allocated #BMovie object or %NULL if the load
|
||||
* failed
|
||||
**/
|
||||
BMovie *
|
||||
b_movie_new_from_fd (gint fd,
|
||||
GError **error)
|
||||
{
|
||||
BMovie *movie = NULL;
|
||||
GIOChannel *io;
|
||||
const gchar *name;
|
||||
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
if (fd == 0)
|
||||
name = "<stdin>";
|
||||
else
|
||||
name = "<pipe>";
|
||||
|
||||
io = g_io_channel_unix_new (fd);
|
||||
|
||||
g_io_channel_set_encoding (io, NULL, NULL);
|
||||
|
||||
movie = b_movie_new_from_io_channel (io, NULL, name, FALSE, error);
|
||||
|
||||
g_io_channel_unref (io);
|
||||
|
||||
return movie;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_load:
|
||||
* @movie: a #BMovie object
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Assures that the frames of the @movie are loaded.
|
||||
*
|
||||
* Return value: %TRUE if the movie was loaded successfully.
|
||||
**/
|
||||
gboolean
|
||||
b_movie_load (BMovie *movie,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_MOVIE (movie), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (movie->load_count == 0)
|
||||
{
|
||||
const gchar *filename;
|
||||
GIOChannel *io;
|
||||
gboolean success;
|
||||
|
||||
g_return_val_if_fail (movie->frames == NULL && movie->n_frames == 0,
|
||||
FALSE);
|
||||
|
||||
filename = b_object_get_filename (B_OBJECT (movie));
|
||||
if (!filename)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Cannot load a movie that has no filename");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
io = g_io_channel_new_file (filename, "r", error);
|
||||
if (! io)
|
||||
return FALSE;
|
||||
|
||||
g_io_channel_set_encoding (io, NULL, NULL);
|
||||
|
||||
success = ((b_movie_type_from_io_channel (io, error) ==
|
||||
G_TYPE_FROM_INSTANCE (movie)) &&
|
||||
b_movie_load_all (movie, io, error));
|
||||
|
||||
g_io_channel_unref (io);
|
||||
|
||||
if (!success)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
movie->load_count++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_unload:
|
||||
* @movie: a #BMovie object
|
||||
*
|
||||
* Unloads the frames of a movie.
|
||||
*
|
||||
* The movie object counts how many times you call b_movie_load() and
|
||||
* b_movie_unload() and only really unloads the frames if
|
||||
* b_movie_unload() was called as often as b_movie_load(). Note that
|
||||
* b_movie_new_from_file() and b_movie_new_from_fd() call
|
||||
* b_movie_load() unless lazy-loading was requested.
|
||||
**/
|
||||
void
|
||||
b_movie_unload (BMovie *movie)
|
||||
{
|
||||
g_return_if_fail (B_IS_MOVIE (movie));
|
||||
g_return_if_fail (movie->load_count > 0);
|
||||
|
||||
movie->load_count--;
|
||||
|
||||
if (movie->load_count == 0)
|
||||
b_movie_finalize_data (movie, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_save:
|
||||
* @movie: a #BMovie object
|
||||
* @stream: a FILE stream ready for writing
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Saves a #BMovie object to a @stream.
|
||||
*
|
||||
* Return value: %TRUE on success or %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_movie_save (BMovie *movie,
|
||||
FILE *stream,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_MOVIE (movie), FALSE);
|
||||
g_return_val_if_fail (stream != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
return b_movie_save_as (movie, G_TYPE_FROM_INSTANCE (movie), stream, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_save_as:
|
||||
* @movie: a #BMovie object
|
||||
* @movie_type: the movie type to use for saving
|
||||
* @stream: a FILE stream ready for writing
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Saves a #BMovie object to a @stream and allows to specify the file
|
||||
* format to use.
|
||||
*
|
||||
* The format is specified by passing a type derived from
|
||||
* #B_TYPE_MOVIE as @movie_type. At the moment B_TYPE_MOVIE_BML,
|
||||
* B_TYPE_MOVIE_BLM and B_TYPE_MOVIE_GIF are supported types.
|
||||
*
|
||||
* Return value: %TRUE on success or %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_movie_save_as (BMovie *movie,
|
||||
GType movie_type,
|
||||
FILE *stream,
|
||||
GError **error)
|
||||
{
|
||||
BMovieClass *movie_class;
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (B_IS_MOVIE (movie), FALSE);
|
||||
g_return_val_if_fail (g_type_is_a (movie_type, B_TYPE_MOVIE), FALSE);
|
||||
g_return_val_if_fail (stream != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (! b_movie_load (movie, error))
|
||||
return FALSE;
|
||||
|
||||
movie_class = g_type_class_ref (movie_type);
|
||||
|
||||
retval = B_MOVIE_CLASS (movie_class)->save (movie, stream, error);
|
||||
|
||||
g_type_class_unref (movie_class);
|
||||
|
||||
b_movie_unload (movie);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_get_frame_at_time:
|
||||
* @movie: a loaded #BMovie object
|
||||
* @seed: an optional GList pointer that can speed up the search
|
||||
* @time: the time in milliseconds
|
||||
*
|
||||
* Looks for the frame active after @time milliseconds.
|
||||
*
|
||||
* If you are calling this function subsequentially with increasing
|
||||
* time values, you can speed up the search by passing the last return
|
||||
* value as the @seed parameter.
|
||||
*
|
||||
* Return value: a GList pointer that has the frame as data or %NULL
|
||||
* if the time was out of the @movie's range.
|
||||
**/
|
||||
GList *
|
||||
b_movie_get_frame_at_time (BMovie *movie,
|
||||
GList *seed,
|
||||
gint time)
|
||||
{
|
||||
BMovieFrame *frame;
|
||||
GList *list;
|
||||
|
||||
g_return_val_if_fail (B_IS_MOVIE (movie), FALSE);
|
||||
|
||||
if (!movie->frames)
|
||||
return NULL;
|
||||
|
||||
list = seed ? seed : movie->frames;
|
||||
|
||||
frame = (BMovieFrame *) list->data;
|
||||
|
||||
while (time > frame->start && list->next)
|
||||
{
|
||||
list = list->next;
|
||||
frame = (BMovieFrame *) list->data;
|
||||
}
|
||||
|
||||
while (list->prev && time <= frame->start)
|
||||
{
|
||||
list = list->prev;
|
||||
frame = (BMovieFrame *) list->data;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_movie_prepend_frame:
|
||||
* @movie:
|
||||
* @duration:
|
||||
* @data:
|
||||
*
|
||||
* This is an internal function used by the movie loaders. It should
|
||||
* never be called from anywhere else.
|
||||
**/
|
||||
void
|
||||
b_movie_prepend_frame (BMovie *movie,
|
||||
gint duration,
|
||||
const guchar *data)
|
||||
{
|
||||
BMovieFrame *frame;
|
||||
|
||||
g_return_if_fail (B_IS_MOVIE (movie));
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
frame = g_new (BMovieFrame, 1);
|
||||
|
||||
frame->start = movie->duration;
|
||||
frame->duration = duration;
|
||||
frame->data = g_memdup (data,
|
||||
movie->width * movie->height * movie->channels);
|
||||
|
||||
movie->frames = g_list_prepend (movie->frames, frame);
|
||||
movie->n_frames++;
|
||||
movie->duration += duration;
|
||||
}
|
||||
|
||||
static BMovie *
|
||||
b_movie_new_from_io_channel (GIOChannel *io,
|
||||
const gchar *filename,
|
||||
const gchar *name,
|
||||
gboolean lazy,
|
||||
GError **error)
|
||||
{
|
||||
BMovie *movie;
|
||||
GType movie_type;
|
||||
gboolean success;
|
||||
|
||||
movie_type = b_movie_type_from_io_channel (io, error);
|
||||
|
||||
if (movie_type == G_TYPE_NONE)
|
||||
{
|
||||
if (error && !*error)
|
||||
g_set_error (error, 0, 0, "Unknown file type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
movie = B_MOVIE (g_object_new (movie_type,
|
||||
"filename", filename,
|
||||
"name", name,
|
||||
NULL));
|
||||
|
||||
if (lazy)
|
||||
{
|
||||
success = b_movie_load_info (movie, io, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = b_movie_load_all (movie, io, error);
|
||||
movie->load_count++;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
g_object_unref (movie);
|
||||
movie = NULL;
|
||||
}
|
||||
|
||||
if (movie && !movie->title)
|
||||
movie->title = g_strdup (b_object_get_name (B_OBJECT (movie)));
|
||||
|
||||
return movie;
|
||||
}
|
||||
|
||||
static GType
|
||||
b_movie_type_from_io_channel (GIOChannel *io,
|
||||
GError **error)
|
||||
{
|
||||
GType movie_type = G_TYPE_NONE;
|
||||
const gchar *magic = NULL;
|
||||
gsize magic_len = 1;
|
||||
gsize len = 0;
|
||||
gchar buf[1024];
|
||||
|
||||
for (len = 0; len < sizeof (buf); len++)
|
||||
{
|
||||
GIOStatus status;
|
||||
|
||||
status = g_io_channel_read_chars (io, buf + len, 1, NULL, error);
|
||||
|
||||
if (status == G_IO_STATUS_ERROR || status == G_IO_STATUS_EOF)
|
||||
return G_TYPE_NONE;
|
||||
|
||||
if (movie_type == G_TYPE_NONE)
|
||||
{
|
||||
switch (buf[len])
|
||||
{
|
||||
case '#':
|
||||
movie_type = B_TYPE_MOVIE_BLM;
|
||||
magic = buf + len + 1;
|
||||
break;
|
||||
case '<':
|
||||
movie_type = B_TYPE_MOVIE_BML;
|
||||
magic = buf + len;
|
||||
break;
|
||||
case 'G':
|
||||
if (len == 0)
|
||||
movie_type = B_TYPE_MOVIE_GIF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (movie_type == B_TYPE_MOVIE_BLM)
|
||||
{
|
||||
if (magic_len == 1 && buf[len] == ' ')
|
||||
magic++;
|
||||
else
|
||||
magic_len++;
|
||||
|
||||
if (magic_len == 20)
|
||||
{
|
||||
if (g_ascii_strncasecmp (magic, "BlinkenLights Movie", 19))
|
||||
return G_TYPE_NONE;
|
||||
else
|
||||
return B_TYPE_MOVIE_BLM;
|
||||
}
|
||||
}
|
||||
else if (movie_type == B_TYPE_MOVIE_GIF)
|
||||
{
|
||||
if (len < 5)
|
||||
continue;
|
||||
|
||||
if (len == 5 &&
|
||||
(strncmp (buf, "GIF87a", 6) == 0 ||
|
||||
strncmp (buf, "GIF89a", 6) == 0))
|
||||
return B_TYPE_MOVIE_GIF;
|
||||
|
||||
return G_TYPE_NONE;
|
||||
}
|
||||
else if (movie_type == B_TYPE_MOVIE_BML)
|
||||
{
|
||||
magic_len++;
|
||||
if (magic_len == 5)
|
||||
{
|
||||
if (strncmp (magic, "<?xml", 5))
|
||||
return G_TYPE_NONE;
|
||||
}
|
||||
else if (magic_len > 6 && buf[len-1] == '?' && buf[len] == '>')
|
||||
{
|
||||
gboolean ret;
|
||||
gchar *encoding = b_parse_encoding (magic, magic_len);
|
||||
|
||||
ret = g_io_channel_set_encoding (io, encoding, error);
|
||||
g_free (encoding);
|
||||
|
||||
return (ret ? B_TYPE_MOVIE_BML : G_TYPE_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return G_TYPE_NONE;
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MOVIE_H__
|
||||
#define __B_MOVIE_H__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <blib/bobject.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define B_MOVIE_MIN_DELAY 20
|
||||
#define B_MOVIE_DEFAULT_DELAY 100
|
||||
|
||||
#define B_TYPE_MOVIE (b_movie_get_type ())
|
||||
#define B_MOVIE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_MOVIE, BMovie))
|
||||
#define B_MOVIE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_MOVIE, BMovieClass))
|
||||
#define B_IS_MOVIE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_MOVIE))
|
||||
#define B_IS_MOVIE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_MOVIE))
|
||||
#define B_MOVIE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_MOVIE, BMovieClass))
|
||||
|
||||
|
||||
typedef struct _BMovieClass BMovieClass;
|
||||
|
||||
struct _BMovieClass
|
||||
{
|
||||
BObjectClass parent_class;
|
||||
|
||||
gboolean (* load_info) (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
gboolean (* load_all) (BMovie *movie,
|
||||
GIOChannel *io,
|
||||
GError **error);
|
||||
gboolean (* save) (BMovie *movie,
|
||||
FILE *stream,
|
||||
GError **error);
|
||||
};
|
||||
|
||||
struct _BMovie
|
||||
{
|
||||
BObject parent_instance;
|
||||
|
||||
gint width;
|
||||
gint height;
|
||||
gint channels;
|
||||
gint maxval;
|
||||
|
||||
/* movie data */
|
||||
gint duration;
|
||||
gint load_count;
|
||||
gint n_frames;
|
||||
GList *frames;
|
||||
|
||||
/* meta data */
|
||||
gchar *title;
|
||||
gchar *description;
|
||||
gchar *creator;
|
||||
gchar *author;
|
||||
gchar *email;
|
||||
gchar *url;
|
||||
gboolean loop;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _BMovieFrame BMovieFrame;
|
||||
|
||||
struct _BMovieFrame
|
||||
{
|
||||
gint start;
|
||||
gint duration;
|
||||
guchar *data;
|
||||
};
|
||||
|
||||
|
||||
GType b_movie_get_type (void) G_GNUC_CONST;
|
||||
BMovie * b_movie_new_from_file (const gchar *filename,
|
||||
gboolean lazy_load,
|
||||
GError **error);
|
||||
BMovie * b_movie_new_from_fd (gint fd,
|
||||
GError **error);
|
||||
|
||||
gboolean b_movie_load (BMovie *movie,
|
||||
GError **error);
|
||||
void b_movie_unload (BMovie *movie);
|
||||
|
||||
gboolean b_movie_save (BMovie *movie,
|
||||
FILE *stream,
|
||||
GError **error);
|
||||
gboolean b_movie_save_as (BMovie *movie,
|
||||
GType movie_type,
|
||||
FILE *stream,
|
||||
GError **error);
|
||||
|
||||
GList * b_movie_get_frame_at_time (BMovie *movie,
|
||||
GList *seed,
|
||||
gint time);
|
||||
|
||||
/* private, should only be used by movie loaders */
|
||||
void b_movie_prepend_frame (BMovie *movie,
|
||||
gint duration,
|
||||
const guchar *data);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MOVIE_H__ */
|
|
@ -0,0 +1,423 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2002 The Blinkenlights Crew
|
||||
+ Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmodule.h"
|
||||
#include "bmodule-utils.h"
|
||||
#include "bmovie.h"
|
||||
#include "bmovieplayer.h"
|
||||
#include "bparams.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_MOVIE,
|
||||
PROP_REVERSE,
|
||||
PROP_CLEAR,
|
||||
PROP_HALIGN,
|
||||
PROP_VALIGN
|
||||
};
|
||||
|
||||
static void b_movie_player_class_init (BMoviePlayerClass *klass);
|
||||
static void b_movie_player_init (BMoviePlayer *player);
|
||||
static void b_movie_player_finalize (GObject *object);
|
||||
static void b_movie_player_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static gboolean b_movie_player_query (gint width,
|
||||
gint height,
|
||||
gint channels,
|
||||
gint maxval);
|
||||
static gboolean b_movie_player_prepare (BModule *module,
|
||||
GError **error);
|
||||
static void b_movie_player_relax (BModule *module);
|
||||
static void b_movie_player_start (BModule *module);
|
||||
static gint b_movie_player_tick (BModule *module);
|
||||
static void b_movie_player_describe (BModule *module,
|
||||
const gchar **title,
|
||||
const gchar **description,
|
||||
const gchar **author);
|
||||
static gint b_movie_player_next_frame (BMoviePlayer *player);
|
||||
static void b_movie_player_request_stop (BModule *module);
|
||||
static void
|
||||
b_movie_player_real_request_stop (BModule *module);
|
||||
|
||||
|
||||
static BModuleClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_movie_player_get_type (void)
|
||||
{
|
||||
static GType player_type = 0;
|
||||
|
||||
if (! player_type)
|
||||
{
|
||||
static const GTypeInfo player_info =
|
||||
{
|
||||
sizeof (BMoviePlayerClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_movie_player_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BMoviePlayer),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_movie_player_init,
|
||||
};
|
||||
|
||||
player_type = g_type_register_static (B_TYPE_MODULE,
|
||||
"BMoviePlayer",
|
||||
&player_info, 0);
|
||||
}
|
||||
|
||||
return player_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_player_class_init (BMoviePlayerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
GParamSpec *param_spec;
|
||||
BModuleClass *module_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
module_class = B_MODULE_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
object_class->set_property = b_movie_player_set_property;
|
||||
object_class->finalize = b_movie_player_finalize;
|
||||
|
||||
param_spec = b_param_spec_filename ("movie", NULL,
|
||||
"The filename of the movie to play.",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (object_class, PROP_MOVIE, param_spec);
|
||||
|
||||
param_spec = g_param_spec_boolean ("reverse", NULL,
|
||||
"Allows to play the movie backwards.",
|
||||
FALSE,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (object_class, PROP_REVERSE, param_spec);
|
||||
|
||||
param_spec = g_param_spec_boolean ("clear", NULL,
|
||||
"Clear the screen before starting.",
|
||||
TRUE,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (object_class, PROP_CLEAR, param_spec);
|
||||
|
||||
param_spec = g_param_spec_double ("h-align", NULL,
|
||||
"Horizontal alignment on the screen.",
|
||||
0.0, 1.0, 0.5,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (object_class, PROP_HALIGN, param_spec);
|
||||
|
||||
param_spec = g_param_spec_double ("v-align", NULL,
|
||||
"Vertical alignment on the screen.",
|
||||
0.0, 1.0, 0.5,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (object_class, PROP_VALIGN, param_spec);
|
||||
|
||||
module_class->query = b_movie_player_query;
|
||||
module_class->prepare = b_movie_player_prepare;
|
||||
module_class->relax = b_movie_player_relax;
|
||||
module_class->start = b_movie_player_start;
|
||||
module_class->tick = b_movie_player_tick;
|
||||
module_class->describe = b_movie_player_describe;
|
||||
|
||||
klass->request_stop = b_movie_player_real_request_stop;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_player_init (BMoviePlayer *player)
|
||||
{
|
||||
player->current = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_player_finalize (GObject *object)
|
||||
{
|
||||
BMoviePlayer *player;
|
||||
|
||||
player = B_MOVIE_PLAYER (object);
|
||||
|
||||
if (player->movie)
|
||||
{
|
||||
g_object_unref (G_OBJECT (player->movie));
|
||||
player->movie = NULL;
|
||||
}
|
||||
if (player->filename)
|
||||
{
|
||||
g_free (player->filename);
|
||||
player->filename = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_player_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BMoviePlayer *player = B_MOVIE_PLAYER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_MOVIE:
|
||||
if (player->movie)
|
||||
{
|
||||
g_object_unref (player->movie);
|
||||
player->movie = NULL;
|
||||
player->current = NULL;
|
||||
}
|
||||
|
||||
if (player->filename)
|
||||
g_free (player->filename);
|
||||
|
||||
player->filename = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_REVERSE:
|
||||
player->reverse = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_CLEAR:
|
||||
player->clear = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_HALIGN:
|
||||
player->halign = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
case PROP_VALIGN:
|
||||
player->valign = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_player_query (gint width,
|
||||
gint height,
|
||||
gint channels,
|
||||
gint maxval)
|
||||
{
|
||||
return (width > 0 && height > 0 && channels == 1 && maxval == 255);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_movie_player_prepare (BModule *module,
|
||||
GError **error)
|
||||
{
|
||||
BMoviePlayer *player = B_MOVIE_PLAYER (module);
|
||||
|
||||
if (!player->filename)
|
||||
{
|
||||
g_set_error (error, 0, 0, "No movie configured.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
player->current = NULL;
|
||||
|
||||
if (player->movie)
|
||||
g_object_unref (player->movie);
|
||||
|
||||
player->movie = b_movie_new_from_file (player->filename, FALSE, error);
|
||||
if (!player->movie)
|
||||
{
|
||||
if (error && *error)
|
||||
{
|
||||
gchar *tmp = g_strdup_printf ("movie '%s': %s",
|
||||
player->filename, (*error)->message);
|
||||
|
||||
g_free ((*error)->message);
|
||||
(*error)->message = tmp;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (module->channels != player->movie->channels)
|
||||
{
|
||||
g_object_unref (player->movie);
|
||||
player->movie = NULL;
|
||||
|
||||
g_set_error (error, 0, 0,
|
||||
"Can't handle movie '%s' with more than one channel.",
|
||||
player->filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
player->xoffset =
|
||||
(gdouble)(module->width - player->movie->width) * player->halign;
|
||||
player->yoffset =
|
||||
(gdouble)(module->height - player->movie->height) * player->valign;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_player_relax (BModule *module)
|
||||
{
|
||||
BMoviePlayer *player = B_MOVIE_PLAYER (module);
|
||||
|
||||
if (player->movie)
|
||||
{
|
||||
g_object_unref (player->movie);
|
||||
player->movie = NULL;
|
||||
}
|
||||
|
||||
player->current = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_player_start (BModule *module)
|
||||
{
|
||||
BMoviePlayer *player = B_MOVIE_PLAYER (module);
|
||||
gint timeout;
|
||||
|
||||
if (player->clear)
|
||||
b_module_fill (module, 0);
|
||||
|
||||
timeout = b_movie_player_next_frame (player);
|
||||
|
||||
if (timeout > 0)
|
||||
b_module_ticker_start (module, timeout);
|
||||
}
|
||||
|
||||
static gint
|
||||
b_movie_player_tick (BModule *module)
|
||||
{
|
||||
return b_movie_player_next_frame (B_MOVIE_PLAYER (module));
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_player_describe (BModule *module,
|
||||
const gchar **title,
|
||||
const gchar **description,
|
||||
const gchar **author)
|
||||
{
|
||||
BMoviePlayer *player = B_MOVIE_PLAYER (module);
|
||||
BMovie *movie = player->movie;
|
||||
|
||||
if (movie)
|
||||
{
|
||||
*title = (movie->title ?
|
||||
movie->title : b_object_get_name (B_OBJECT (movie)));
|
||||
*description = movie->description;
|
||||
*author = movie->author;
|
||||
}
|
||||
else
|
||||
{
|
||||
B_MODULE_CLASS (parent_class)->describe (module,
|
||||
title, description, author);
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
b_movie_player_next_frame (BMoviePlayer *player)
|
||||
{
|
||||
BMovieFrame *frame;
|
||||
BModule *module;
|
||||
|
||||
do
|
||||
{
|
||||
if (player->current)
|
||||
{
|
||||
if (player->reverse)
|
||||
player->current = g_list_previous (player->current);
|
||||
else
|
||||
player->current = g_list_next (player->current);
|
||||
}
|
||||
else if (player->movie)
|
||||
{
|
||||
if (player->reverse)
|
||||
player->current = g_list_last (player->movie->frames);
|
||||
else
|
||||
player->current = g_list_first (player->movie->frames);
|
||||
}
|
||||
|
||||
if (! player->current) /* movie finished */
|
||||
{
|
||||
b_movie_player_request_stop (B_MODULE (player));
|
||||
return 0;
|
||||
}
|
||||
|
||||
frame = (BMovieFrame *) player->current->data;
|
||||
}
|
||||
while (frame->duration <= 0);
|
||||
|
||||
module = B_MODULE (player);
|
||||
|
||||
{
|
||||
BMovie *movie = B_MOVIE (player->movie);
|
||||
guchar *s, *d = module->buffer;
|
||||
gint max = movie->maxval;
|
||||
gint x, y;
|
||||
|
||||
for (y = 0; y < module->height; y++, d += module->width)
|
||||
{
|
||||
if (y - player->yoffset < 0 || y - player->yoffset >= movie->height)
|
||||
continue;
|
||||
|
||||
s = frame->data + (y - player->yoffset) * movie->width;
|
||||
|
||||
for (x = 0; x < module->width; x++)
|
||||
{
|
||||
if (x - player->xoffset < 0 || x - player->xoffset >= movie->width)
|
||||
continue;
|
||||
|
||||
if (max == 255)
|
||||
d[x] = s[x - player->xoffset];
|
||||
else
|
||||
d[x] = ((gint) (s[x - player->xoffset]) * 255) / max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b_module_paint (module);
|
||||
|
||||
return frame->duration;
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_player_request_stop (BModule *module)
|
||||
{
|
||||
B_MOVIE_PLAYER_GET_CLASS (module)->request_stop (module);
|
||||
}
|
||||
|
||||
static void
|
||||
b_movie_player_real_request_stop (BModule *module)
|
||||
{
|
||||
b_module_request_stop (module);
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2002 The Blinkenlights Crew
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_MOVIE_PLAYER_H__
|
||||
#define __B_MOVIE_PLAYER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define B_TYPE_MOVIE_PLAYER (b_movie_player_get_type ())
|
||||
#define B_MOVIE_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_MOVIE_PLAYER, BMoviePlayer))
|
||||
#define B_MOVIE_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_MOVIE_PLAYER, BMoviePlayerClass))
|
||||
#define B_IS_MOVIE_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_MOVIE_PLAYER))
|
||||
#define B_IS_MOVIE_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_MOVIE_PLAYER))
|
||||
#define B_MOVIE_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_MOVIE_PLAYER, BMoviePlayerClass))
|
||||
|
||||
typedef struct _BMoviePlayerClass BMoviePlayerClass;
|
||||
|
||||
struct _BMoviePlayer
|
||||
{
|
||||
BModule parent_instance;
|
||||
|
||||
BMovie *movie;
|
||||
GList *current;
|
||||
|
||||
gchar *filename;
|
||||
gboolean reverse;
|
||||
|
||||
gboolean clear;
|
||||
gdouble halign;
|
||||
gdouble valign;
|
||||
gint xoffset;
|
||||
gint yoffset;
|
||||
};
|
||||
|
||||
struct _BMoviePlayerClass
|
||||
{
|
||||
BModuleClass parent_class;
|
||||
|
||||
void (* request_stop) (BModule *module);
|
||||
};
|
||||
|
||||
GType b_movie_player_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_MOVIE_PLAYER_H__ */
|
|
@ -0,0 +1,246 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bobject.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_FILENAME,
|
||||
PROP_NAME
|
||||
};
|
||||
|
||||
|
||||
static void b_object_class_init (BObjectClass *class);
|
||||
static void b_object_init (BObject *object);
|
||||
static void b_object_finalize (GObject *object);
|
||||
static void b_object_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void b_object_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_object_get_type (void)
|
||||
{
|
||||
static GType object_type = 0;
|
||||
|
||||
if (!object_type)
|
||||
{
|
||||
static const GTypeInfo object_info =
|
||||
{
|
||||
sizeof (BObjectClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_object_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BObject),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_object_init,
|
||||
};
|
||||
|
||||
object_type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"BObject", &object_info, 0);
|
||||
}
|
||||
|
||||
return object_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_object_class_init (BObjectClass *class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
GParamSpec *param_spec;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->set_property = b_object_set_property;
|
||||
object_class->get_property = b_object_get_property;
|
||||
object_class->finalize = b_object_finalize;
|
||||
|
||||
param_spec = g_param_spec_string ("filename", NULL,
|
||||
"The filename associated with the object. "
|
||||
"This is a string in the filesystems's "
|
||||
"encoding.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_FILENAME, param_spec);
|
||||
|
||||
param_spec = g_param_spec_string ("name", NULL,
|
||||
"The name associated with the object. "
|
||||
"This is a string in UTF-8 encoding.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_NAME, param_spec);
|
||||
}
|
||||
|
||||
static void
|
||||
b_object_init (BObject *object)
|
||||
{
|
||||
object->filename = NULL;
|
||||
object->name = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
b_object_finalize (GObject *object)
|
||||
{
|
||||
BObject *bobject;
|
||||
|
||||
bobject = B_OBJECT (object);
|
||||
|
||||
g_free (bobject->filename);
|
||||
g_free (bobject->name);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
b_object_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_FILENAME:
|
||||
b_object_set_filename (B_OBJECT (object), g_value_get_string (value));
|
||||
break;
|
||||
case PROP_NAME:
|
||||
b_object_set_name (B_OBJECT (object), g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
b_object_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_FILENAME:
|
||||
g_value_set_string (value, B_OBJECT (object)->filename);
|
||||
break;
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, B_OBJECT (object)->name);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* b_object_set_filename:
|
||||
* @object: a #BObject.
|
||||
* @filename: the new filename, a nul-terminated string in the filesystem's
|
||||
* encoding.
|
||||
*
|
||||
* Sets the filename associated with @object.
|
||||
**/
|
||||
void
|
||||
b_object_set_filename (BObject *object,
|
||||
const gchar *filename)
|
||||
{
|
||||
g_return_if_fail (B_IS_OBJECT (object));
|
||||
|
||||
g_free (object->filename);
|
||||
object->filename = g_strdup (filename);
|
||||
|
||||
g_object_notify (G_OBJECT (object), "filename");
|
||||
}
|
||||
|
||||
/**
|
||||
* b_object_set_name:
|
||||
* @object: a #BObject.
|
||||
* @name: the new name, a nul-terminated string in UTF-8 encoding.
|
||||
*
|
||||
* Sets the name associated with @object.
|
||||
**/
|
||||
void
|
||||
b_object_set_name (BObject *object,
|
||||
const gchar *name)
|
||||
{
|
||||
g_return_if_fail (B_IS_OBJECT (object));
|
||||
g_return_if_fail (g_utf8_validate (name, -1, NULL));
|
||||
|
||||
g_free (object->name);
|
||||
object->name = g_strdup (name);
|
||||
|
||||
g_object_notify (G_OBJECT (object), "name");
|
||||
}
|
||||
|
||||
/**
|
||||
* b_object_get_filename:
|
||||
* @object: a #BObject.
|
||||
*
|
||||
* This functions retrieves the filename associated with @object. The
|
||||
* returned value must not be freed.
|
||||
*
|
||||
* Return value: the fileanme or %NULL if no filename was set for @object.
|
||||
**/
|
||||
const gchar *
|
||||
b_object_get_filename (BObject *object)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_OBJECT (object), NULL);
|
||||
|
||||
return object->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_object_get_name:
|
||||
* @object: a #BObject.
|
||||
*
|
||||
* This functions retrieves the name associated with @object. If no
|
||||
* name has been set for @object, the name is generated from the
|
||||
* @object's filename. The returned value must not be freed.
|
||||
*
|
||||
* Return value: the name or %NULL if no name and no filename was set
|
||||
* for @object.
|
||||
**/
|
||||
const gchar *
|
||||
b_object_get_name (BObject *object)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_OBJECT (object), NULL);
|
||||
|
||||
if (!object->name && object->filename)
|
||||
object->name = g_filename_to_utf8 (object->filename, -1, NULL, NULL, NULL);
|
||||
|
||||
return object->name;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_OBJECT_H__
|
||||
#define __B_OBJECT_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define B_TYPE_OBJECT (b_object_get_type ())
|
||||
#define B_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_OBJECT, BObject))
|
||||
#define B_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_OBJECT, BObjectClass))
|
||||
#define B_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_OBJECT))
|
||||
#define B_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_OBJECT))
|
||||
#define B_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_OBJECT, BObjectClass))
|
||||
|
||||
|
||||
typedef struct _BObjectClass BObjectClass;
|
||||
|
||||
struct _BObjectClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _BObject
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gchar *filename; /* in filesystem encoding */
|
||||
gchar *name; /* UTF-8 encoded, defaults to converted filename */
|
||||
};
|
||||
|
||||
|
||||
GType b_object_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void b_object_set_filename (BObject *object,
|
||||
const gchar *filename);
|
||||
void b_object_set_name (BObject *object,
|
||||
const gchar *name);
|
||||
|
||||
const gchar * b_object_get_filename (BObject *object);
|
||||
const gchar * b_object_get_name (BObject *object);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_OBJECT_H__ */
|
|
@ -0,0 +1,181 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bpacket.h"
|
||||
|
||||
|
||||
/**
|
||||
* b_packet_new:
|
||||
* @width: the number of pixels per row
|
||||
* @height: the number of pixels per column
|
||||
* @channels: the number of channels per pixels
|
||||
* @maxval: the maximum value
|
||||
* @data_size: returns the size of the packet data
|
||||
*
|
||||
* Allocates a new #BPacket structure and initializes it with the
|
||||
* given values. If @data_size is non-NULL the size of the data area
|
||||
* (in bytes) is returned via this variable.
|
||||
*
|
||||
* The packet should be freed with g_free() when it is not needed any
|
||||
* longer.
|
||||
*
|
||||
* Return value: a newly allocated #BPacket.
|
||||
**/
|
||||
BPacket *
|
||||
b_packet_new (gint width,
|
||||
gint height,
|
||||
gint channels,
|
||||
gint maxval,
|
||||
gint *data_size)
|
||||
{
|
||||
BPacket *packet;
|
||||
gint size;
|
||||
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
g_return_val_if_fail (channels > 0, NULL);
|
||||
g_return_val_if_fail (maxval > 0 && maxval <= 255, NULL);
|
||||
|
||||
size = width * height * channels;
|
||||
|
||||
packet = (BPacket *) g_new0 (guchar, sizeof (BPacket) + size);
|
||||
|
||||
packet->header.mcu_frame_h.magic = MAGIC_MCU_FRAME;
|
||||
packet->header.mcu_frame_h.width = width;
|
||||
packet->header.mcu_frame_h.height = height;
|
||||
packet->header.mcu_frame_h.channels = channels;
|
||||
packet->header.mcu_frame_h.maxval = maxval;
|
||||
|
||||
if (data_size)
|
||||
*data_size = size;
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
gsize
|
||||
b_packet_size (BPacket *packet)
|
||||
{
|
||||
guint32 *magic;
|
||||
|
||||
g_return_val_if_fail (packet != NULL, 0);
|
||||
|
||||
magic = (guint32 *) packet;
|
||||
|
||||
switch (*magic)
|
||||
{
|
||||
case MAGIC_MCU_FRAME:
|
||||
{
|
||||
mcu_frame_header_t *header = &packet->header.mcu_frame_h;
|
||||
|
||||
return (sizeof (BPacket) +
|
||||
header->width * header->height * header->channels);
|
||||
}
|
||||
|
||||
default:
|
||||
return (sizeof (BPacket));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* byte order conversions */
|
||||
|
||||
/**
|
||||
* b_packet_hton:
|
||||
* @packet: pointer to a #BPacket
|
||||
*
|
||||
* Converts all members of @packet from host to network byteorder.
|
||||
**/
|
||||
void
|
||||
b_packet_hton (BPacket *packet)
|
||||
{
|
||||
guint32 *magic = (guint32 *) packet;
|
||||
|
||||
switch (*magic)
|
||||
{
|
||||
case MAGIC_MCU_FRAME:
|
||||
{
|
||||
mcu_frame_header_t *header = &packet->header.mcu_frame_h;
|
||||
|
||||
header->magic = g_htonl (header->magic);
|
||||
header->width = g_htons (header->width);
|
||||
header->height = g_htons (header->height);
|
||||
header->channels = g_htons (header->channels);
|
||||
header->maxval = g_htons (header->maxval);
|
||||
}
|
||||
break;
|
||||
|
||||
case MAGIC_HEARTBEAT:
|
||||
{
|
||||
heartbeat_header_t *header = &packet->header.heartbeat_h;
|
||||
|
||||
header->magic = g_htonl (header->magic);
|
||||
header->version = g_htons (header->version);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*magic = g_htonl (magic);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* b_packet_ntoh:
|
||||
* @packet: pointer to a #BPacket
|
||||
*
|
||||
* Converts all members of @packet from network to host byteorder.
|
||||
**/
|
||||
void
|
||||
b_packet_ntoh (BPacket *packet)
|
||||
{
|
||||
guint32 *magic = (guint32 *) packet;
|
||||
|
||||
*magic = g_ntohl (*magic);
|
||||
|
||||
switch (*magic)
|
||||
{
|
||||
case MAGIC_MCU_FRAME:
|
||||
{
|
||||
mcu_frame_header_t *header = &packet->header.mcu_frame_h;
|
||||
|
||||
header->width = g_ntohs (header->width);
|
||||
header->height = g_ntohs (header->height);
|
||||
header->channels = g_ntohs (header->channels);
|
||||
header->maxval = g_ntohs (header->maxval);
|
||||
}
|
||||
break;
|
||||
|
||||
case MAGIC_HEARTBEAT:
|
||||
{
|
||||
heartbeat_header_t *header = &packet->header.heartbeat_h;
|
||||
|
||||
header->version = g_ntohs (header->version);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_PACKET_H__
|
||||
#define __B_PACKET_H__
|
||||
|
||||
#include "blib/bprotocol.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef union _BPacketHeader BPacketHeader;
|
||||
|
||||
union _BPacketHeader
|
||||
{
|
||||
mcu_frame_header_t mcu_frame_h;
|
||||
heartbeat_header_t heartbeat_h;
|
||||
};
|
||||
|
||||
struct _BPacket
|
||||
{
|
||||
BPacketHeader header;
|
||||
guchar data[0];
|
||||
};
|
||||
|
||||
BPacket * b_packet_new (gint width,
|
||||
gint height,
|
||||
gint channels,
|
||||
gint maxval,
|
||||
gint *data_size);
|
||||
gsize b_packet_size (BPacket *packet);
|
||||
void b_packet_hton (BPacket *packet);
|
||||
void b_packet_ntoh (BPacket *packet);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_PACKET_H__ */
|
|
@ -0,0 +1,87 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bparams.h"
|
||||
|
||||
static void b_param_filename_class_init (GParamSpecClass *class);
|
||||
|
||||
GType
|
||||
b_param_filename_get_type (void)
|
||||
{
|
||||
static GType spec_type = 0;
|
||||
|
||||
if (!spec_type)
|
||||
{
|
||||
static const GTypeInfo type_info =
|
||||
{
|
||||
sizeof (GParamSpecClass),
|
||||
NULL, NULL,
|
||||
(GClassInitFunc) b_param_filename_class_init,
|
||||
NULL, NULL,
|
||||
sizeof (GParamSpecString),
|
||||
0, NULL, NULL
|
||||
};
|
||||
|
||||
spec_type = g_type_register_static (G_TYPE_PARAM_STRING,
|
||||
"BParamFilename", &type_info, 0);
|
||||
}
|
||||
|
||||
return spec_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_param_filename_class_init (GParamSpecClass *class)
|
||||
{
|
||||
class->value_type = B_TYPE_FILENAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_param_spec_filename:
|
||||
* @name: the property name
|
||||
* @nick: an optional short version of the name
|
||||
* @blurb: an optional description
|
||||
* @default_value: the default value (may be %NULL)
|
||||
* @flags: the #GParamFlags for this param_spec
|
||||
*
|
||||
* Creates a new #GParamSpec for a #B_TYPE_FILENAME property.
|
||||
*
|
||||
* Return value: the newly allocate #GParamSpec.
|
||||
**/
|
||||
GParamSpec *
|
||||
b_param_spec_filename (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gchar *default_value,
|
||||
GParamFlags flags)
|
||||
{
|
||||
GParamSpecString *pspec;
|
||||
|
||||
pspec = g_param_spec_internal (B_TYPE_PARAM_FILENAME,
|
||||
name, nick, blurb, flags);
|
||||
|
||||
pspec->default_value = default_value;
|
||||
|
||||
return G_PARAM_SPEC (pspec);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_PARAMS_H__
|
||||
#define __B_PARAMS_H__
|
||||
|
||||
#define B_TYPE_PARAM_FILENAME (b_param_filename_get_type ())
|
||||
#define B_IS_PARAM_SPEC_FILENAME(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), B_TYPE_PARAM_FILENAME))
|
||||
|
||||
GType b_param_filename_get_type (void) G_GNUC_CONST;
|
||||
GParamSpec * b_param_spec_filename (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gchar *default_value,
|
||||
GParamFlags flags);
|
||||
|
||||
#endif /* __B_PARAMS_H__ */
|
|
@ -0,0 +1,466 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bparser.h"
|
||||
|
||||
|
||||
struct _BParser
|
||||
{
|
||||
GMarkupParseContext *context;
|
||||
BParserState state;
|
||||
BParserState last_state;
|
||||
gint unknown_depth;
|
||||
GString *cdata;
|
||||
gpointer user_data;
|
||||
BParserStartFunc start_element;
|
||||
BParserEndFunc end_element;
|
||||
};
|
||||
|
||||
|
||||
static void parser_start_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static void parser_end_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static void parser_text (GMarkupParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static void parser_start_unknown (BParser *parser);
|
||||
static void parser_end_unknown (BParser *parser);
|
||||
|
||||
|
||||
static const GMarkupParser markup_parser =
|
||||
{
|
||||
parser_start_element,
|
||||
parser_end_element,
|
||||
parser_text,
|
||||
NULL, /* passthrough */
|
||||
NULL, /* error */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* b_parser_new:
|
||||
* @start_element: the function to call when an element is started
|
||||
* @end_element: the function to call when an element is closed
|
||||
* @user_data: data to pass to the functions above
|
||||
*
|
||||
* Creates a new #BParser suited to parse XML files. The #BParser
|
||||
* should later be freed using b_parser_free().
|
||||
*
|
||||
* Return value: a newly allocated #BParser
|
||||
**/
|
||||
BParser *
|
||||
b_parser_new (BParserStartFunc start_element,
|
||||
BParserEndFunc end_element,
|
||||
gpointer user_data)
|
||||
{
|
||||
BParser *parser;
|
||||
|
||||
parser = g_new0 (BParser, 1);
|
||||
|
||||
parser->context = g_markup_parse_context_new (&markup_parser,
|
||||
0, parser, NULL);
|
||||
|
||||
parser->state = B_PARSER_STATE_TOPLEVEL;
|
||||
parser->cdata = g_string_new (NULL);
|
||||
parser->user_data = user_data;
|
||||
|
||||
parser->start_element = start_element;
|
||||
parser->end_element = end_element;
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parser_parse:
|
||||
* @parser: a #BParser
|
||||
* @text: pointer to a text buffer to parse
|
||||
* @text_len: the number of bytes to parse from @text
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Let the @parser process a chunk of @text. You need to call
|
||||
* b_parser_end_parse() after you passed the last chunk to the @parser.
|
||||
*
|
||||
* Return value: %TRUE if parsing was successful, %FALSE if an error occured
|
||||
**/
|
||||
gboolean
|
||||
b_parser_parse (BParser *parser,
|
||||
const gchar *text,
|
||||
gssize text_len,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (parser != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
return g_markup_parse_context_parse (parser->context, text, text_len, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parser_end_parse:
|
||||
* @parser: a #BParser
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Finishes the @parser. After calling this function, you must not
|
||||
* call b_parser_parse() on the parser again.
|
||||
*
|
||||
* Return value: %TRUE if @parser was successfully finished, %FALSE
|
||||
* otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_parser_end_parse (BParser *parser,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (parser != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
return g_markup_parse_context_end_parse (parser->context, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parser_parse_io_channel:
|
||||
* @parser: a #BParser
|
||||
* @io: a #GIOChannel to read the text to parse from
|
||||
* @recode: %TRUE if you want the parser to do automatic encoding conversion
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Reads data from the #GIOChannel @io and passes it to @parser. If
|
||||
* @recode is TRUE, the data should start with an XML header so this
|
||||
* function can determine the encoding of the XML data and convert it
|
||||
* to UTF-8 for you.
|
||||
*
|
||||
* Return value: %TRUE if parsing was successful, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_parser_parse_io_channel (BParser *parser,
|
||||
GIOChannel *io,
|
||||
gboolean recode,
|
||||
GError **error)
|
||||
{
|
||||
GIOStatus status;
|
||||
guchar buffer[8192];
|
||||
gsize len = 0;
|
||||
gsize bytes;
|
||||
|
||||
g_return_val_if_fail (parser != NULL, FALSE);
|
||||
g_return_val_if_fail (io != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (recode)
|
||||
{
|
||||
const gchar *io_encoding = g_io_channel_get_encoding (io);
|
||||
gchar *encoding = NULL;
|
||||
|
||||
if (io_encoding && strcmp (io_encoding, "UTF-8"))
|
||||
{
|
||||
g_warning ("b_parser_parse_io_channel(): "
|
||||
"The encoding has already been set on this IOChannel!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* try to determine the encoding */
|
||||
|
||||
g_io_channel_set_encoding (io, NULL, NULL);
|
||||
|
||||
while (len < sizeof (buffer) && !encoding)
|
||||
{
|
||||
status = g_io_channel_read_chars (io,
|
||||
buffer + len, 1, &bytes, error);
|
||||
len += bytes;
|
||||
|
||||
if (status == G_IO_STATUS_ERROR)
|
||||
return FALSE;
|
||||
if (status == G_IO_STATUS_EOF)
|
||||
break;
|
||||
|
||||
encoding = b_parse_encoding (buffer, len);
|
||||
}
|
||||
|
||||
if (encoding)
|
||||
{
|
||||
if (!g_io_channel_set_encoding (io, encoding, error))
|
||||
return FALSE;
|
||||
|
||||
g_free (encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_io_channel_set_encoding (io, "UTF-8", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (!b_parser_parse (parser, buffer, len, error))
|
||||
return FALSE;
|
||||
|
||||
status = g_io_channel_read_chars (io,
|
||||
buffer, sizeof(buffer), &len, error);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case G_IO_STATUS_ERROR:
|
||||
return FALSE;
|
||||
case G_IO_STATUS_EOF:
|
||||
return b_parser_end_parse (parser, error);
|
||||
case G_IO_STATUS_NORMAL:
|
||||
case G_IO_STATUS_AGAIN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parser_free:
|
||||
* @parser: a #BParser
|
||||
*
|
||||
* Frees the resources allocated for @parser. You must not access
|
||||
* @parser after calling this function.
|
||||
**/
|
||||
void
|
||||
b_parser_free (BParser *parser)
|
||||
{
|
||||
g_return_if_fail (parser != NULL);
|
||||
|
||||
g_markup_parse_context_free (parser->context);
|
||||
|
||||
g_string_free (parser->cdata, TRUE);
|
||||
g_free (parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parser_get_state:
|
||||
* @parser: a #BParser
|
||||
*
|
||||
* Retrieves the current state of @parser.
|
||||
*
|
||||
* Return value: the state of @parser
|
||||
**/
|
||||
BParserState
|
||||
b_parser_get_state (BParser *parser)
|
||||
{
|
||||
g_return_val_if_fail (parser != NULL, B_PARSER_STATE_UNKNOWN);
|
||||
|
||||
return parser->state;
|
||||
}
|
||||
|
||||
static void
|
||||
parser_start_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
BParserState new_state;
|
||||
BParser *parser = (BParser *) user_data;
|
||||
|
||||
switch (parser->state)
|
||||
{
|
||||
case B_PARSER_STATE_TOPLEVEL:
|
||||
default:
|
||||
if (parser->start_element &&
|
||||
(new_state = parser->start_element (parser->state,
|
||||
element_name,
|
||||
attribute_names,
|
||||
attribute_values,
|
||||
parser->user_data,
|
||||
error)))
|
||||
{
|
||||
parser->last_state = parser->state;
|
||||
parser->state = new_state;
|
||||
break;
|
||||
}
|
||||
/* else fallthru */
|
||||
case B_PARSER_STATE_UNKNOWN:
|
||||
parser_start_unknown (parser);
|
||||
break;
|
||||
}
|
||||
|
||||
g_string_truncate (parser->cdata, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
parser_end_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
BParser *parser = (BParser *) user_data;
|
||||
|
||||
switch (parser->state)
|
||||
{
|
||||
case B_PARSER_STATE_TOPLEVEL:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (parser->end_element)
|
||||
{
|
||||
gint len;
|
||||
|
||||
/* strip trailing spaces */
|
||||
for (len = parser->cdata->len;
|
||||
len > 0 && g_ascii_isspace (parser->cdata->str[len-1]);
|
||||
len--)
|
||||
; /* do nothing */
|
||||
|
||||
g_string_truncate (parser->cdata, len);
|
||||
|
||||
parser->state = parser->end_element (parser->state,
|
||||
element_name,
|
||||
parser->cdata->str,
|
||||
parser->cdata->len,
|
||||
parser->user_data,
|
||||
error);
|
||||
break;
|
||||
}
|
||||
/* else fallthru */
|
||||
case B_PARSER_STATE_UNKNOWN:
|
||||
parser_end_unknown (parser);
|
||||
break;
|
||||
}
|
||||
|
||||
g_string_truncate (parser->cdata, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
parser_text (GMarkupParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
BParser *parser = (BParser *) user_data;
|
||||
gboolean space;
|
||||
gint i;
|
||||
|
||||
space = (parser->cdata->len == 0 ||
|
||||
g_ascii_isspace (parser->cdata->str[parser->cdata->len]));
|
||||
|
||||
for (i = 0; i < text_len; i++)
|
||||
{
|
||||
if (g_ascii_isspace (text[i]))
|
||||
{
|
||||
if (space)
|
||||
continue;
|
||||
space = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
space = FALSE;
|
||||
}
|
||||
|
||||
g_string_append_c (parser->cdata, text[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_start_unknown (BParser *parser)
|
||||
{
|
||||
if (parser->unknown_depth == 0)
|
||||
{
|
||||
parser->last_state = parser->state;
|
||||
parser->state = B_PARSER_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
parser->unknown_depth++;
|
||||
}
|
||||
|
||||
static void
|
||||
parser_end_unknown (BParser *parser)
|
||||
{
|
||||
parser->unknown_depth--;
|
||||
|
||||
if (parser->unknown_depth == 0)
|
||||
parser->state = parser->last_state;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parse_encoding:
|
||||
* @text: a string to parse, must be at least 20 bytes
|
||||
* @text_len: the maximum number of bytes to parse from @text
|
||||
*
|
||||
* Scans the @text for an XML header with encoding specification.
|
||||
*
|
||||
* Return value: a copy of the encoding string or %NULL if none was
|
||||
* found
|
||||
**/
|
||||
gchar *
|
||||
b_parse_encoding (const gchar *text,
|
||||
gint text_len)
|
||||
{
|
||||
const gchar *start;
|
||||
const gchar *end;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (text, NULL);
|
||||
|
||||
if (text_len < 20)
|
||||
return NULL;
|
||||
|
||||
start = g_strstr_len (text, text_len, "<?xml");
|
||||
if (!start)
|
||||
return NULL;
|
||||
|
||||
end = g_strstr_len (start, text_len - (start - text), "?>");
|
||||
if (!end)
|
||||
return NULL;
|
||||
|
||||
text_len = end - start;
|
||||
if (text_len < 12)
|
||||
return NULL;
|
||||
|
||||
start = g_strstr_len (start + 1, text_len - 1, "encoding=");
|
||||
if (!start)
|
||||
return NULL;
|
||||
|
||||
start += 9;
|
||||
if (*start != '\"' && *start != '\'')
|
||||
return NULL;
|
||||
|
||||
text_len = end - start;
|
||||
if (text_len < 1)
|
||||
return NULL;
|
||||
|
||||
for (i = 1; i < text_len; i++)
|
||||
if (start[i] == start[0])
|
||||
break;
|
||||
|
||||
if (i == text_len || i < 3)
|
||||
return NULL;
|
||||
|
||||
return g_strndup (start + 1, i - 1);
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_PARSER_H__
|
||||
#define __B_PARSER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
B_PARSER_STATE_UNKNOWN,
|
||||
B_PARSER_STATE_TOPLEVEL,
|
||||
B_PARSER_STATE_USER = 0x10 /* first user state, use as many as you need */
|
||||
} BParserState;
|
||||
|
||||
|
||||
/* Called for open tags <foo bar="baz">, returns the new state or
|
||||
B_PARSER_STATE_UNKNOWN if it couldn't handle the tag. */
|
||||
typedef BParserState (* BParserStartFunc) (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
/* Called for close tags </foo>, returns the new state. */
|
||||
typedef BParserState (* BParserEndFunc) (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar *cdata,
|
||||
gsize cdata_len,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
|
||||
|
||||
BParser *b_parser_new (BParserStartFunc start_element,
|
||||
BParserEndFunc end_element,
|
||||
gpointer user_data);
|
||||
void b_parser_free (BParser *parser);
|
||||
|
||||
/* chunk parsing API */
|
||||
gboolean b_parser_parse (BParser *parser,
|
||||
const gchar *text,
|
||||
gssize text_len,
|
||||
GError **error);
|
||||
gboolean b_parser_end_parse (BParser *parser,
|
||||
GError **error);
|
||||
|
||||
/* convenience function for IO channels */
|
||||
gboolean b_parser_parse_io_channel (BParser *parser,
|
||||
GIOChannel *io,
|
||||
gboolean recode,
|
||||
GError **error);
|
||||
|
||||
BParserState b_parser_get_state (BParser *parser);
|
||||
|
||||
/* parses an XML header */
|
||||
gchar * b_parse_encoding (const gchar *text,
|
||||
gint text_len);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_PARSER_H__ */
|
|
@ -0,0 +1,151 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2003 The Blinkenlights Crew
|
||||
* Tim Pritlove <tim@ccc.de>
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_PROTOCOL_H__
|
||||
#define __B_PROTOCOL_H__
|
||||
|
||||
#define MAGIC_MCU_SETUP 0x2342FEED /* MCU Configuration packet */
|
||||
#define MAGIC_MCU_FRAME 0x23542666 /* MCU Frame packet */
|
||||
#define MAGIC_MCU_DEVCTRL 0x23542667 /* MCU Device Control packet */
|
||||
|
||||
#define MAGIC_BLFRAME 0xDEADBEEF /* Original BL Frame Packet */
|
||||
#define MAGIC_BLFRAME_256 0xFEEDBEEF /* Extendend BL Frame Packet (Greyscale) */
|
||||
|
||||
#define MAGIC_HEARTBEAT 0x42424242 /* Heartbeat packet */
|
||||
|
||||
#define MCU_LISTENER_PORT 2323
|
||||
#define MCU_ID_ANY -1
|
||||
|
||||
#define B_HEARTBEAT_PORT 4242
|
||||
#define B_HEARTBEAT_INTERVAL 5000 /* Heartbeat interval in ms */
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
/*
|
||||
* Legacy Blinkenlights bl_frame format
|
||||
*/
|
||||
|
||||
typedef struct bl_frame_header bl_frame_header_t;
|
||||
|
||||
struct bl_frame_header
|
||||
{
|
||||
guint32 frame_magic; /* == MAGIC_BLFRAME */
|
||||
guint32 frame_count;
|
||||
guint16 frame_width;
|
||||
guint16 frame_height;
|
||||
/*
|
||||
* followed by
|
||||
* unsigned char data[rows][columns];
|
||||
*/
|
||||
};
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
/*
|
||||
* MCU Frame packet
|
||||
*/
|
||||
|
||||
typedef struct mcu_frame_header mcu_frame_header_t;
|
||||
|
||||
struct mcu_frame_header
|
||||
{
|
||||
guint32 magic; /* == MAGIC_MCU_FRAME */
|
||||
guint16 height; /* rows */
|
||||
guint16 width; /* columns */
|
||||
guint16 channels; /* Number of channels (mono/grey: 1, rgb: 3) */
|
||||
guint16 maxval; /* maximum pixel value (only 8 bits used) */
|
||||
/*
|
||||
* followed by
|
||||
* unsigned char data[rows][columns][channels];
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* MCU Setup packet
|
||||
*/
|
||||
|
||||
typedef struct mcu_setup_pixel mcu_setup_pixel_t;
|
||||
|
||||
struct mcu_setup_pixel
|
||||
{
|
||||
unsigned char row;
|
||||
unsigned char column;
|
||||
};
|
||||
|
||||
|
||||
typedef struct mcu_setup_header mcu_setup_header_t;
|
||||
|
||||
struct mcu_setup_header
|
||||
{
|
||||
guint32 magic; /* == MAGIC_MCU_SETUP */
|
||||
|
||||
char mcu_id; /* target MCU id ( -1 = any) */
|
||||
unsigned char _reserved[3]; /* padding */
|
||||
|
||||
guint16 height;
|
||||
guint16 width;
|
||||
guint16 channels;
|
||||
|
||||
guint16 pixels; /* number of ports used (starting from 0) */
|
||||
/*
|
||||
* followed by
|
||||
* mcu_setup_pixel_t pixel[pixels];
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* MCU Device Control packet
|
||||
*/
|
||||
|
||||
#define MCU_DEVCTRL_OFF 0 /* switch device off */
|
||||
#define MCU_DEVCTRL_ON 1 /* switch device on */
|
||||
|
||||
typedef struct mcu_devctrl_header mcu_devctrl_header_t;
|
||||
|
||||
struct mcu_devctrl_header
|
||||
{
|
||||
guint32 magic; /* == MAGIC_MCU_DEVCTRL */
|
||||
guint16 pixels; /* number of pixels used (starting from 0) */
|
||||
guint16 _reserved; /* 32 bit padding */
|
||||
/*
|
||||
* followed by
|
||||
* unsigned char control[pixels];
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
* Heartbeat Packet
|
||||
*/
|
||||
|
||||
typedef struct heartbeat_header heartbeat_header_t;
|
||||
|
||||
struct heartbeat_header
|
||||
{
|
||||
guint32 magic; /* == MAGIC_HEARTBEAT */
|
||||
guint16 version; /* hearbeat protocol version number (0) */
|
||||
};
|
||||
|
||||
|
||||
#endif /* __B_PROTOCOL_H__ */
|
|
@ -0,0 +1,233 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2003 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bpacket.h"
|
||||
#include "bproxyclient.h"
|
||||
#include "breceiver.h"
|
||||
#include "bsocket.h"
|
||||
|
||||
|
||||
static void b_proxy_client_class_init (BProxyClientClass *class);
|
||||
static void b_proxy_client_init (BProxyClient *client);
|
||||
static void b_proxy_client_finalize (GObject *object);
|
||||
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_proxy_client_get_type (void)
|
||||
{
|
||||
static GType client_type = 0;
|
||||
|
||||
if (!client_type)
|
||||
{
|
||||
static const GTypeInfo client_info =
|
||||
{
|
||||
sizeof (BProxyClientClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_proxy_client_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BProxyClient),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_proxy_client_init,
|
||||
};
|
||||
|
||||
client_type = g_type_register_static (B_TYPE_RECEIVER,
|
||||
"BProxyClient", &client_info, 0);
|
||||
}
|
||||
|
||||
return client_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_proxy_client_class_init (BProxyClientClass *class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = b_proxy_client_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
b_proxy_client_init (BProxyClient *client)
|
||||
{
|
||||
client->fd = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
b_proxy_client_finalize (GObject *object)
|
||||
{
|
||||
BProxyClient *client = B_PROXY_CLIENT (object);
|
||||
|
||||
if (client->fd != -1)
|
||||
{
|
||||
close (client->fd);
|
||||
client->fd = -1;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_proxy_client_new:
|
||||
* @proxy_host: the blinkenproxy host
|
||||
* @proxy_port: the blinkenproxy port
|
||||
* @listen_port: the local port to listen to for Blinkenlights packages
|
||||
* or -1 to bind to an arbitrary free local port
|
||||
* @callback: the function to call when a new frame arrives
|
||||
* @callback_data: data to pass to the @callback
|
||||
* @error: return location for a possible error
|
||||
*
|
||||
* Creates a new #BProxyClient object, ready to use.
|
||||
*
|
||||
* Return value: a newly allocate #BProxyClient object
|
||||
**/
|
||||
BProxyClient *
|
||||
b_proxy_client_new (const gchar *proxy_host,
|
||||
gint proxy_port,
|
||||
gint listen_port,
|
||||
BReceiverCallback callback,
|
||||
gpointer callback_data,
|
||||
GError **error)
|
||||
{
|
||||
BProxyClient *client;
|
||||
struct hostent *dest;
|
||||
struct sockaddr_in sock;
|
||||
gint fd;
|
||||
|
||||
g_return_val_if_fail (proxy_host != NULL && proxy_host != '\0', NULL);
|
||||
g_return_val_if_fail (proxy_port > 0, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (! b_socket_init (error))
|
||||
return NULL;
|
||||
|
||||
dest = gethostbyname (proxy_host);
|
||||
if (dest == NULL)
|
||||
{
|
||||
g_set_error (error, 0, 0, "Unable to resolve host '%s'", proxy_host);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = b_socket_udp_new (B_SO_REUSEADDR, error);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
if (listen_port > 0)
|
||||
{
|
||||
sock.sin_addr.s_addr = INADDR_ANY;
|
||||
sock.sin_family = AF_INET;
|
||||
sock.sin_port = g_htons (listen_port);
|
||||
|
||||
if (bind (fd, (struct sockaddr *) &sock, sizeof (sock)) < 0)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Can't bind socket for %s to local port %d: %s\n",
|
||||
proxy_host, listen_port, g_strerror (errno));
|
||||
close (fd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
sock.sin_family = AF_INET;
|
||||
sock.sin_port = g_htons (proxy_port);
|
||||
memcpy (&sock.sin_addr.s_addr, dest->h_addr_list[0], dest->h_length);
|
||||
|
||||
if (connect (fd, (struct sockaddr *) &sock, sizeof (sock)) < 0)
|
||||
{
|
||||
g_set_error (error, 0, 0, "Can't connect socket to %s:%d: %s\n",
|
||||
proxy_host, proxy_port, g_strerror (errno));
|
||||
close (fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
client = g_object_new (B_TYPE_PROXY_CLIENT,
|
||||
"callback", callback,
|
||||
"callback_data", callback_data,
|
||||
NULL);
|
||||
|
||||
client->fd = fd;
|
||||
|
||||
b_receiver_listen_fd (B_RECEIVER (client), fd);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_proxy_client_send_heartbeat:
|
||||
* @client: a #BProxyClient
|
||||
*
|
||||
* Make the @client send a heartbeat packet. This function should
|
||||
* be called periodically with the suggested interval of
|
||||
* %B_HEARTBEAT_INTERVAL. To achieve, use this function with
|
||||
* g_timeout_add().
|
||||
*
|
||||
* Return value: always %TRUE
|
||||
**/
|
||||
gboolean
|
||||
b_proxy_client_send_heartbeat (BProxyClient *client)
|
||||
{
|
||||
BPacket packet;
|
||||
|
||||
g_return_val_if_fail (B_IS_PROXY_CLIENT (client), FALSE);
|
||||
|
||||
if (client->fd == -1)
|
||||
return TRUE;
|
||||
|
||||
memset (&packet, 0, sizeof (BPacket));
|
||||
|
||||
packet.header.heartbeat_h.magic = MAGIC_HEARTBEAT;
|
||||
|
||||
b_packet_hton (&packet);
|
||||
|
||||
send (client->fd, &packet, sizeof (BPacket), 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2003 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __B_PROXY_CLIENT_H__
|
||||
#define __B_PROXY_CLIENT_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#include <blib/breceiver.h>
|
||||
|
||||
#define B_TYPE_PROXY_CLIENT (b_proxy_client_get_type ())
|
||||
#define B_PROXY_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_PROXY_CLIENT, BProxyClient))
|
||||
#define B_PROXY_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_PROXY_CLIENT, BProxyClientClass))
|
||||
#define B_IS_PROXY_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_PROXY_CLIENT))
|
||||
#define B_IS_PROXY_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_PROXY_CLIENT))
|
||||
#define B_PROXY_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_PROXY_CLIENT, BProxyClientClass))
|
||||
|
||||
|
||||
typedef struct _BProxyClientClass BProxyClientClass;
|
||||
|
||||
struct _BProxyClientClass
|
||||
{
|
||||
BReceiverClass parent_class;
|
||||
};
|
||||
|
||||
struct _BProxyClient
|
||||
{
|
||||
BReceiver parent_instance;
|
||||
|
||||
gint fd;
|
||||
};
|
||||
|
||||
GType b_proxy_client_get_type (void) G_GNUC_CONST;
|
||||
BProxyClient * b_proxy_client_new (const gchar *proxy_host,
|
||||
gint proxy_port,
|
||||
gint listen_port,
|
||||
BReceiverCallback callback,
|
||||
gpointer callback_data,
|
||||
GError **error);
|
||||
gboolean b_proxy_client_send_heartbeat (BProxyClient *client);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_PROXY_CLIENT_H__ */
|
|
@ -0,0 +1,370 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2004 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bmarshal.h"
|
||||
#include "bpacket.h"
|
||||
#include "bproxyserver.h"
|
||||
#include "breceiver.h"
|
||||
#include "bsocket.h"
|
||||
|
||||
|
||||
#define HEARTBEAT_TIMEOUT (B_HEARTBEAT_INTERVAL * 12)
|
||||
|
||||
enum
|
||||
{
|
||||
CLIENT_ADDED,
|
||||
CLIENT_REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BProxyServer *server;
|
||||
gulong addr;
|
||||
gushort port;
|
||||
GSource *timeout;
|
||||
} BClient;
|
||||
|
||||
|
||||
static void b_proxy_server_class_init (BProxyServerClass *klass);
|
||||
static void b_proxy_server_init (BProxyServer *server);
|
||||
static void b_proxy_server_finalize (GObject *object);
|
||||
|
||||
static gboolean b_proxy_server_heartbeat_callback (BProxyServer *server,
|
||||
BPacket *packet,
|
||||
gpointer data);
|
||||
|
||||
static guint b_client_hash (const BClient *client);
|
||||
static gboolean b_client_equal (const BClient *a,
|
||||
const BClient *b);
|
||||
static void b_client_add (const BClient *template);
|
||||
static gboolean b_client_remove (BClient *client);
|
||||
|
||||
static void b_client_send_packet (gpointer key,
|
||||
BClient *client,
|
||||
BPacket *packet);
|
||||
|
||||
|
||||
static guint server_signals[LAST_SIGNAL] = { 0 };
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_proxy_server_get_type (void)
|
||||
{
|
||||
static GType server_type = 0;
|
||||
|
||||
if (!server_type)
|
||||
{
|
||||
static const GTypeInfo server_info =
|
||||
{
|
||||
sizeof (BProxyServerClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_proxy_server_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BProxyServer),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_proxy_server_init,
|
||||
};
|
||||
|
||||
server_type = g_type_register_static (B_TYPE_RECEIVER,
|
||||
"BProxyServer", &server_info, 0);
|
||||
}
|
||||
|
||||
return server_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_proxy_server_class_init (BProxyServerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = b_proxy_server_finalize;
|
||||
|
||||
server_signals[CLIENT_ADDED] =
|
||||
g_signal_new ("client_added",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (BProxyServerClass, client_added),
|
||||
NULL, NULL,
|
||||
b_marshal_VOID__STRING_INT,
|
||||
G_TYPE_NONE,
|
||||
2, G_TYPE_STRING, G_TYPE_INT);
|
||||
server_signals[CLIENT_REMOVED] =
|
||||
g_signal_new ("client_removed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (BProxyServerClass, client_removed),
|
||||
NULL, NULL,
|
||||
b_marshal_VOID__STRING_INT,
|
||||
G_TYPE_NONE,
|
||||
2, G_TYPE_STRING, G_TYPE_INT);
|
||||
}
|
||||
|
||||
static void
|
||||
b_proxy_server_init (BProxyServer *server)
|
||||
{
|
||||
server->fd = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
b_proxy_server_finalize (GObject *object)
|
||||
{
|
||||
BProxyServer *server = B_PROXY_SERVER (object);
|
||||
|
||||
if (server->fd != -1)
|
||||
{
|
||||
close (server->fd);
|
||||
server->fd = -1;
|
||||
}
|
||||
|
||||
if (server->clients)
|
||||
{
|
||||
g_hash_table_destroy (server->clients);
|
||||
server->clients = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_proxy_server_new:
|
||||
* @port: the local port to listen to for heartbeat packages
|
||||
* @error: return location for a possible error
|
||||
*
|
||||
* Creates a new #BProxyServer object, ready to use.
|
||||
*
|
||||
* Return value: a newly allocate #BProxyServer object
|
||||
**/
|
||||
BProxyServer *
|
||||
b_proxy_server_new (gint port,
|
||||
GError **error)
|
||||
{
|
||||
BProxyServer *server;
|
||||
struct sockaddr_in sock;
|
||||
gint fd;
|
||||
|
||||
g_return_val_if_fail (port > 0, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (! b_socket_init (error))
|
||||
return NULL;
|
||||
|
||||
fd = b_socket_udp_new (B_SO_REUSEADDR, error);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
sock.sin_addr.s_addr = INADDR_ANY;
|
||||
sock.sin_family = AF_INET;
|
||||
sock.sin_port = g_htons (port);
|
||||
|
||||
if (bind (fd, (struct sockaddr *) &sock, sizeof (sock)) < 0)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Can't bind socket to local port %d: %s\n",
|
||||
port, g_strerror (errno));
|
||||
close (fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
server = g_object_new (B_TYPE_PROXY_SERVER,
|
||||
"callback", b_proxy_server_heartbeat_callback,
|
||||
NULL);
|
||||
|
||||
server->fd = fd;
|
||||
|
||||
server->clients = g_hash_table_new_full ((GHashFunc) b_client_hash,
|
||||
(GEqualFunc) b_client_equal,
|
||||
(GDestroyNotify) NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
b_receiver_listen_fd (B_RECEIVER (server), fd);
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
gboolean
|
||||
b_proxy_server_send_packet (BProxyServer *server,
|
||||
BPacket *packet)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_PROXY_SERVER (server), FALSE);
|
||||
g_return_val_if_fail (packet != NULL, FALSE);
|
||||
|
||||
if (server->clients)
|
||||
g_hash_table_foreach (server->clients,
|
||||
(GHFunc) b_client_send_packet, packet);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint
|
||||
b_proxy_server_num_clients (BProxyServer *server)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_PROXY_SERVER (server), 0);
|
||||
|
||||
return (server->clients ? g_hash_table_size (server->clients) : 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_proxy_server_heartbeat_callback (BProxyServer *server,
|
||||
BPacket *packet,
|
||||
gpointer data)
|
||||
{
|
||||
BClient lookup;
|
||||
BClient *client;
|
||||
|
||||
if (packet->header.heartbeat_h.magic != MAGIC_HEARTBEAT ||
|
||||
packet->header.heartbeat_h.version != 0)
|
||||
return TRUE;
|
||||
|
||||
lookup.server = server;
|
||||
lookup.addr = B_RECEIVER (server)->addr;
|
||||
lookup.port = B_RECEIVER (server)->port;
|
||||
|
||||
client = g_hash_table_lookup (server->clients, &lookup);
|
||||
|
||||
if (client)
|
||||
{
|
||||
g_source_destroy (client->timeout);
|
||||
|
||||
client->timeout = g_timeout_source_new (HEARTBEAT_TIMEOUT);
|
||||
g_source_set_callback (client->timeout,
|
||||
(GSourceFunc) b_client_remove, client, NULL);
|
||||
g_source_attach (client->timeout, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
b_client_add (&lookup);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
b_client_hash (const BClient *client)
|
||||
{
|
||||
return (guint) client->addr;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_client_equal (const BClient *a,
|
||||
const BClient *b)
|
||||
{
|
||||
return (a->addr == b->addr && a->port == b->port);
|
||||
}
|
||||
|
||||
static void
|
||||
b_client_add (const BClient *template)
|
||||
{
|
||||
BClient *client = g_memdup (template, sizeof (BClient));
|
||||
struct in_addr addr;
|
||||
const gchar *host;
|
||||
gint port;
|
||||
|
||||
client->timeout = g_timeout_source_new (HEARTBEAT_TIMEOUT);
|
||||
g_source_set_callback (client->timeout,
|
||||
(GSourceFunc) b_client_remove, client, NULL);
|
||||
g_source_attach (client->timeout, NULL);
|
||||
|
||||
g_hash_table_insert (client->server->clients, client, client);
|
||||
|
||||
addr.s_addr = client->addr;
|
||||
|
||||
host = inet_ntoa (addr);
|
||||
port = g_ntohs (client->port);
|
||||
|
||||
g_signal_emit (client->server,
|
||||
server_signals[CLIENT_ADDED], 0,
|
||||
host, port);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_client_remove (BClient *client)
|
||||
{
|
||||
BProxyServer *server = client->server;
|
||||
struct in_addr addr;
|
||||
const gchar *host;
|
||||
gint port;
|
||||
|
||||
addr.s_addr = client->addr;
|
||||
|
||||
host = inet_ntoa (addr);
|
||||
port = g_ntohs (client->port);
|
||||
|
||||
g_hash_table_remove (server->clients, client);
|
||||
|
||||
g_signal_emit (server,
|
||||
server_signals[CLIENT_REMOVED], 0,
|
||||
host, port);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
b_client_send_packet (gpointer key,
|
||||
BClient *client,
|
||||
BPacket *packet)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
gsize size = b_packet_size (packet);
|
||||
BPacket *copy = g_memdup (packet, size);
|
||||
|
||||
b_packet_hton (copy);
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = client->port;
|
||||
addr.sin_addr.s_addr = client->addr;
|
||||
|
||||
sendto (client->server->fd, copy, size, 0,
|
||||
(struct sockaddr *) &addr, sizeof (addr));
|
||||
|
||||
g_free (copy);
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2004 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __B_PROXY_SERVER_H__
|
||||
#define __B_PROXY_SERVER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#include <blib/breceiver.h>
|
||||
|
||||
#define B_TYPE_PROXY_SERVER (b_proxy_server_get_type ())
|
||||
#define B_PROXY_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_PROXY_SERVER, BProxyServer))
|
||||
#define B_PROXY_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_PROXY_SERVER, BProxyServerClass))
|
||||
#define B_IS_PROXY_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_PROXY_SERVER))
|
||||
#define B_IS_PROXY_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_PROXY_SERVER))
|
||||
#define B_PROXY_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_PROXY_SERVER, BProxyServerClass))
|
||||
|
||||
|
||||
typedef struct _BProxyServerClass BProxyServerClass;
|
||||
|
||||
struct _BProxyServerClass
|
||||
{
|
||||
BReceiverClass parent_class;
|
||||
|
||||
void (* client_added) (BProxyServer *server,
|
||||
const gchar *host,
|
||||
gint port);
|
||||
void (* client_removed) (BProxyServer *server,
|
||||
const gchar *host,
|
||||
gint port);
|
||||
};
|
||||
|
||||
struct _BProxyServer
|
||||
{
|
||||
BReceiver parent_instance;
|
||||
|
||||
gint fd;
|
||||
GHashTable *clients;
|
||||
};
|
||||
|
||||
|
||||
GType b_proxy_server_get_type (void) G_GNUC_CONST;
|
||||
BProxyServer * b_proxy_server_new (gint port,
|
||||
GError **error);
|
||||
|
||||
gboolean b_proxy_server_send_packet (BProxyServer *server,
|
||||
BPacket *packet);
|
||||
gint b_proxy_server_num_clients (BProxyServer *server);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_PROXY_SERVER_H__ */
|
|
@ -0,0 +1,385 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2003 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include <winsock2.h>
|
||||
#ifndef socklen_t
|
||||
#define socklen_t unsigned int
|
||||
#endif
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bpacket.h"
|
||||
#include "breceiver.h"
|
||||
#include "bsocket.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CALLBACK,
|
||||
PROP_CALLBACK_DATA
|
||||
};
|
||||
|
||||
|
||||
static void b_receiver_class_init (BReceiverClass *class);
|
||||
static void b_receiver_init (BReceiver *receiver);
|
||||
static void b_receiver_finalize (GObject *object);
|
||||
static void b_receiver_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static gboolean b_receiver_io_func (GIOChannel *io,
|
||||
GIOCondition cond,
|
||||
gpointer data);
|
||||
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_receiver_get_type (void)
|
||||
{
|
||||
static GType receiver_type = 0;
|
||||
|
||||
if (!receiver_type)
|
||||
{
|
||||
static const GTypeInfo receiver_info =
|
||||
{
|
||||
sizeof (BReceiverClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_receiver_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BReceiver),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_receiver_init,
|
||||
};
|
||||
|
||||
receiver_type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"BReceiver", &receiver_info, 0);
|
||||
}
|
||||
|
||||
return receiver_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_receiver_class_init (BReceiverClass *class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = b_receiver_finalize;
|
||||
object_class->set_property = b_receiver_set_property;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_CALLBACK,
|
||||
g_param_spec_pointer ("callback",
|
||||
NULL, NULL,
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_WRITABLE));
|
||||
g_object_class_install_property (object_class, PROP_CALLBACK_DATA,
|
||||
g_param_spec_pointer ("callback_data",
|
||||
NULL, NULL,
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_WRITABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
b_receiver_init (BReceiver *receiver)
|
||||
{
|
||||
receiver->io_channel = NULL;
|
||||
receiver->watch_source = 0;
|
||||
receiver->callback = NULL;
|
||||
receiver->callback_data = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
b_receiver_finalize (GObject *object)
|
||||
{
|
||||
BReceiver *receiver = B_RECEIVER (object);
|
||||
|
||||
if (receiver->io_channel)
|
||||
g_io_channel_unref (receiver->io_channel);
|
||||
|
||||
receiver->callback = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
b_receiver_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BReceiver *receiver = B_RECEIVER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CALLBACK:
|
||||
receiver->callback = g_value_get_pointer (value);
|
||||
break;
|
||||
case PROP_CALLBACK_DATA:
|
||||
receiver->callback_data = g_value_get_pointer (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* b_receiver_new:
|
||||
* @callback: the function to call when a new frame arrives
|
||||
* @callback_data: data to pass to the @callback
|
||||
*
|
||||
* Creates a new #BReceiver object.
|
||||
*
|
||||
* Return value: a newly allocate #BReceiver object
|
||||
**/
|
||||
BReceiver *
|
||||
b_receiver_new (BReceiverCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
return B_RECEIVER (g_object_new (B_TYPE_RECEIVER,
|
||||
"callback", callback,
|
||||
"callback_data", callback_data,
|
||||
NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* b_receiver_listen:
|
||||
* @receiver: a #BReceiver object
|
||||
* @port: the UDP port to listen to
|
||||
*
|
||||
* Causes the @receiver to start to listen to the specified UDP
|
||||
* port. For each successfully received Blinkenlights packet, the
|
||||
* packet will be converted to host byteorder and the callback that
|
||||
* was specified on b_receiver_new() will be called.
|
||||
*
|
||||
* Return value: %TRUE if the receiver listens to @port, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_receiver_listen (BReceiver *receiver,
|
||||
gint port)
|
||||
{
|
||||
struct sockaddr_in local_address;
|
||||
gint status;
|
||||
gint listen_fd;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (B_IS_RECEIVER (receiver), FALSE);
|
||||
g_return_val_if_fail (receiver->io_channel == NULL, FALSE);
|
||||
|
||||
listen_fd = b_socket_udp_new (B_SO_REUSEADDR, &error);
|
||||
if (listen_fd == -1)
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
local_address.sin_family = PF_INET;
|
||||
local_address.sin_port = g_htons (port);
|
||||
local_address.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
status = bind (listen_fd,
|
||||
(struct sockaddr *) &local_address, sizeof (local_address));
|
||||
if (status == -1)
|
||||
{
|
||||
g_printerr ("BReceiver: Can't bind local address");
|
||||
close (listen_fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
status = fcntl (listen_fd, F_SETFL, O_NONBLOCK);
|
||||
if (status == -1)
|
||||
{
|
||||
g_printerr ("BReceiver: Can't set non-blocking mode on socket");
|
||||
close (listen_fd);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
b_receiver_listen_fd (receiver, listen_fd);
|
||||
|
||||
g_io_channel_set_close_on_unref (receiver->io_channel, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_receiver_listen_fd:
|
||||
* @receiver: a #BReceiver object
|
||||
* @fd: a file descriptor
|
||||
*
|
||||
* Causes the @receiver to start to listen to the given file descriptor.
|
||||
* This function is rarely useful, it is used internally by #BProxyClient.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
**/
|
||||
gboolean
|
||||
b_receiver_listen_fd (BReceiver *receiver,
|
||||
gint fd)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_RECEIVER (receiver), FALSE);
|
||||
g_return_val_if_fail (receiver->io_channel == NULL, FALSE);
|
||||
|
||||
receiver->io_channel = g_io_channel_unix_new (fd);
|
||||
|
||||
g_io_channel_set_encoding (receiver->io_channel, NULL, NULL);
|
||||
|
||||
receiver->watch_source = g_io_add_watch (receiver->io_channel,
|
||||
G_IO_IN | G_IO_PRI,
|
||||
b_receiver_io_func, receiver);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_receiver_stop:
|
||||
* @receiver: a #BReceiver object
|
||||
*
|
||||
* Makes the @receiver stop listening.
|
||||
**/
|
||||
void
|
||||
b_receiver_stop (BReceiver *receiver)
|
||||
{
|
||||
g_return_if_fail (B_IS_RECEIVER (receiver));
|
||||
|
||||
if (!receiver->io_channel)
|
||||
return;
|
||||
|
||||
if (receiver->watch_source)
|
||||
{
|
||||
g_source_remove (receiver->watch_source);
|
||||
receiver->watch_source = 0;
|
||||
}
|
||||
|
||||
g_io_channel_unref (receiver->io_channel);
|
||||
receiver->io_channel = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_receiver_io_func (GIOChannel *io,
|
||||
GIOCondition cond,
|
||||
gpointer data)
|
||||
{
|
||||
BReceiver *receiver;
|
||||
mcu_frame_header_t *header;
|
||||
guchar buf[0xfff];
|
||||
BPacket *packet = NULL;
|
||||
BPacket *fake = NULL;
|
||||
BPacket *new = NULL;
|
||||
gssize buf_read;
|
||||
gboolean success = TRUE;
|
||||
|
||||
gint req_fd;
|
||||
struct sockaddr_in req_addr;
|
||||
socklen_t req_addr_length = sizeof (req_addr);
|
||||
|
||||
receiver = B_RECEIVER (data);
|
||||
|
||||
if (! receiver->callback)
|
||||
return TRUE;
|
||||
|
||||
req_fd = g_io_channel_unix_get_fd (io);
|
||||
|
||||
buf_read = recvfrom (req_fd, buf, sizeof (buf), 0,
|
||||
(struct sockaddr *) &req_addr, &req_addr_length);
|
||||
|
||||
if (buf_read < sizeof (BPacket))
|
||||
return TRUE;
|
||||
|
||||
new = (BPacket *) buf;
|
||||
|
||||
b_packet_ntoh (new);
|
||||
|
||||
header = &new->header.mcu_frame_h;
|
||||
|
||||
switch (header->magic)
|
||||
{
|
||||
case MAGIC_MCU_FRAME:
|
||||
if (buf_read < (sizeof (BPacket) +
|
||||
header->width * header->height * header->channels))
|
||||
return TRUE;
|
||||
/* else fallthru */
|
||||
|
||||
case MAGIC_HEARTBEAT:
|
||||
packet = new;
|
||||
break;
|
||||
|
||||
case MAGIC_BLFRAME:
|
||||
{
|
||||
gint size;
|
||||
|
||||
fake = b_packet_new (18, 8, 1, 1, &size);
|
||||
|
||||
memcpy (fake->data, (guchar *) new + sizeof (BPacket), size);
|
||||
|
||||
packet = fake;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_printerr ("BReceiver: Unknown magic: %08x, dropping packet!",
|
||||
new->header.mcu_frame_h.magic);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
receiver->addr = req_addr.sin_addr.s_addr;
|
||||
receiver->port = req_addr.sin_port;
|
||||
|
||||
success = receiver->callback (receiver, packet, receiver->callback_data);
|
||||
|
||||
receiver->addr = 0;
|
||||
receiver->port = 0;
|
||||
|
||||
if (fake)
|
||||
g_free (fake);
|
||||
|
||||
return success;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __B_RECEIVER_H__
|
||||
#define __B_RECEIVER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define B_TYPE_RECEIVER (b_receiver_get_type ())
|
||||
#define B_RECEIVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_RECEIVER, BReceiver))
|
||||
#define B_RECEIVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_RECEIVER, BReceiverClass))
|
||||
#define B_IS_RECEIVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_RECEIVER))
|
||||
#define B_IS_RECEIVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_RECEIVER))
|
||||
#define B_RECEIVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_RECEIVER, BReceiverClass))
|
||||
|
||||
|
||||
typedef struct _BReceiverClass BReceiverClass;
|
||||
|
||||
typedef gboolean (* BReceiverCallback) (BReceiver *receiver,
|
||||
BPacket *packet,
|
||||
gpointer callback_data);
|
||||
|
||||
struct _BReceiverClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _BReceiver
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GIOChannel *io_channel;
|
||||
guint watch_source;
|
||||
|
||||
BReceiverCallback callback;
|
||||
gpointer callback_data;
|
||||
|
||||
gulong addr; /* in network byte order */
|
||||
gushort port; /* in network byte order */
|
||||
};
|
||||
|
||||
GType b_receiver_get_type (void) G_GNUC_CONST;
|
||||
BReceiver * b_receiver_new (BReceiverCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean b_receiver_listen (BReceiver *receiver,
|
||||
gint port);
|
||||
gboolean b_receiver_listen_fd (BReceiver *receiver,
|
||||
gint fd);
|
||||
void b_receiver_stop (BReceiver *receiver);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_RECEIVER_H__ */
|
|
@ -0,0 +1,479 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2003 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bobject.h"
|
||||
#include "bpacket.h"
|
||||
#include "bsender.h"
|
||||
#include "bsocket.h"
|
||||
|
||||
|
||||
typedef struct _BRecipient
|
||||
{
|
||||
gint fd;
|
||||
struct sockaddr_in addr;
|
||||
gchar *hostname;
|
||||
gint port;
|
||||
} BRecipient;
|
||||
|
||||
|
||||
static void b_sender_class_init (BSenderClass *class);
|
||||
static void b_sender_init (BSender *sender);
|
||||
static void b_sender_finalize (GObject *object);
|
||||
|
||||
static BObjectClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
b_sender_get_type (void)
|
||||
{
|
||||
static GType sender_type = 0;
|
||||
|
||||
if (!sender_type)
|
||||
{
|
||||
static const GTypeInfo sender_info =
|
||||
{
|
||||
sizeof (BSenderClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_sender_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BSender),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_sender_init,
|
||||
};
|
||||
|
||||
sender_type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"BSender", &sender_info, 0);
|
||||
}
|
||||
|
||||
return sender_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_sender_class_init (BSenderClass *class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = b_sender_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
b_sender_init (BSender *sender)
|
||||
{
|
||||
sender->recipients = NULL;
|
||||
sender->packet = NULL;
|
||||
sender->size = 0;
|
||||
sender->verbose = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
b_sender_finalize (GObject *object)
|
||||
{
|
||||
BSender *sender;
|
||||
GList *item;
|
||||
|
||||
sender = B_SENDER (object);
|
||||
|
||||
for (item = sender->recipients; item; item = item->next)
|
||||
{
|
||||
BRecipient *rec = item->data;
|
||||
|
||||
if (!rec)
|
||||
continue;
|
||||
|
||||
if (rec->fd > -1)
|
||||
close (rec->fd);
|
||||
|
||||
g_free (rec);
|
||||
}
|
||||
|
||||
g_list_free (sender->recipients);
|
||||
|
||||
if (sender->packet)
|
||||
g_free (sender->packet);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_sender_new:
|
||||
*
|
||||
* Creates a new #BSender object.
|
||||
*
|
||||
* Return value: a newly allocated #BSender object
|
||||
**/
|
||||
BSender *
|
||||
b_sender_new (void)
|
||||
{
|
||||
return B_SENDER (g_object_new (B_TYPE_SENDER, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* b_sender_configure:
|
||||
* @sender: a #BSender object
|
||||
* @width: number of pixels per row
|
||||
* @height: number of pixels per column
|
||||
* @channels: number of channels per pixel
|
||||
* @maxval: the maximum value
|
||||
*
|
||||
* Prepares @sender to send Blinkenlights UDP packets with the given
|
||||
* parameters.
|
||||
*
|
||||
* Return value: %TRUE if @sender was successfully reconfigured,
|
||||
* %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_sender_configure (BSender *sender,
|
||||
gint width,
|
||||
gint height,
|
||||
gint channels,
|
||||
gint maxval)
|
||||
{
|
||||
g_return_val_if_fail (B_IS_SENDER (sender), FALSE);
|
||||
g_return_val_if_fail (width > 0 && height > 0, FALSE);
|
||||
|
||||
/* prepare packet */
|
||||
if (sender->packet)
|
||||
g_free (sender->packet);
|
||||
|
||||
sender->packet = b_packet_new (width, height, channels, maxval,
|
||||
&sender->size);
|
||||
|
||||
b_packet_hton (sender->packet);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_sender_add_recipient:
|
||||
* @sender: a #BSender object
|
||||
* @src_port: originating UDP port (-1 to leave unspecified)
|
||||
* @dest_host: destination hostname or IP address
|
||||
* @dest_port: destination UDP port
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Tries to resolve @host and adds it to the @sender's list of recipients.
|
||||
*
|
||||
* Return value: %TRUE if the recipient was successfully added, %FALSE
|
||||
* otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_sender_add_recipient (BSender *sender,
|
||||
gint src_port,
|
||||
const gchar *dest_host,
|
||||
gint dest_port,
|
||||
GError **error)
|
||||
{
|
||||
BRecipient *rec;
|
||||
struct hostent *dest;
|
||||
struct sockaddr_in sock;
|
||||
|
||||
g_return_val_if_fail (B_IS_SENDER (sender), FALSE);
|
||||
g_return_val_if_fail (dest_host != NULL && *dest_host != '\0', FALSE);
|
||||
g_return_val_if_fail (dest_port > 0, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (! b_socket_init (error))
|
||||
return FALSE;
|
||||
|
||||
dest = gethostbyname (dest_host);
|
||||
if (dest == NULL)
|
||||
{
|
||||
g_set_error (error, 0, 0, "Unable to resolve host '%s'", dest_host);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rec = g_new0 (BRecipient, 1);
|
||||
rec->fd = -1;
|
||||
|
||||
rec->addr.sin_family = AF_INET;
|
||||
rec->addr.sin_port = g_htons (dest_port);
|
||||
|
||||
memcpy (&rec->addr.sin_addr.s_addr, dest->h_addr_list[0], dest->h_length);
|
||||
|
||||
rec->fd = b_socket_udp_new (B_SO_BROADCAST | B_SO_REUSEADDR, error);
|
||||
if (rec->fd < 0)
|
||||
return FALSE;
|
||||
|
||||
if (src_port > 0)
|
||||
{
|
||||
sock.sin_addr.s_addr = INADDR_ANY;
|
||||
sock.sin_family = AF_INET;
|
||||
sock.sin_port = g_htons (src_port);
|
||||
|
||||
if (bind (rec->fd, (struct sockaddr *) &sock, sizeof (sock)) < 0)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Couldn't bind socket for %s to local port %d: %s\n",
|
||||
dest_host, src_port, g_strerror (errno));
|
||||
close (rec->fd);
|
||||
g_free (rec);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (connect (rec->fd,
|
||||
(struct sockaddr *) &rec->addr, sizeof (rec->addr)) < 0)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Couldn't connect socket for %s: %s\n",
|
||||
dest_host, g_strerror (errno));
|
||||
close (rec->fd);
|
||||
g_free (rec);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rec->hostname = g_strdup (dest_host);
|
||||
rec->port = dest_port;
|
||||
|
||||
/* To avoid duplicate entries, first remove all recipients with
|
||||
same hostname and same port. */
|
||||
b_sender_remove_recipient (sender, rec->hostname, rec->port, NULL);
|
||||
|
||||
sender->recipients = g_list_append (sender->recipients, rec);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_sender_remove_recipient:
|
||||
* @sender: a #BSender object
|
||||
* @dest_host: destination hostname or IP address
|
||||
* @dest_port: destination UDP port
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Removes all recipients with matching host and port from the
|
||||
* @sender's list of recipients.
|
||||
*
|
||||
* Return value: %TRUE if at least one matching recipient was found
|
||||
* and removed, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_sender_remove_recipient (BSender *sender,
|
||||
const gchar *dest_host,
|
||||
gint dest_port,
|
||||
GError **error)
|
||||
{
|
||||
GList *item;
|
||||
gboolean done = FALSE;
|
||||
|
||||
g_return_val_if_fail (B_IS_SENDER (sender), FALSE);
|
||||
g_return_val_if_fail (dest_host != NULL && *dest_host != '\0', FALSE);
|
||||
g_return_val_if_fail (dest_port > 0, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
for (item = sender->recipients; item; item = item->next)
|
||||
{
|
||||
BRecipient *rec = item->data;
|
||||
|
||||
if (!rec)
|
||||
continue;
|
||||
|
||||
if (rec->port == dest_port &&
|
||||
g_ascii_strcasecmp (rec->hostname, dest_host) == 0)
|
||||
{
|
||||
if (rec->fd > -1)
|
||||
close (rec->fd);
|
||||
|
||||
g_free (rec->hostname);
|
||||
g_free (rec);
|
||||
|
||||
item->data = NULL;
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (done)
|
||||
sender->recipients = g_list_remove_all (sender->recipients, NULL);
|
||||
else
|
||||
g_set_error (error, 0, 0,
|
||||
"No such host in recipient list: %s, port %d\n",
|
||||
dest_host, dest_port);
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_sender_list_recipients:
|
||||
* @sender: a #BSender object
|
||||
*
|
||||
* Creates a list of strings that describe the @senders
|
||||
* recipients. You should free the strings as well as the list when
|
||||
* it is no longer needed.
|
||||
*
|
||||
* Return value: a newly allocated #GList of newly allocated strings
|
||||
**/
|
||||
GList *
|
||||
b_sender_list_recipients (BSender *sender)
|
||||
{
|
||||
GList *item, *list = NULL;
|
||||
|
||||
for (item = sender->recipients; item; item = item->next)
|
||||
{
|
||||
BRecipient *rec = item->data;
|
||||
|
||||
if (!rec)
|
||||
continue;
|
||||
|
||||
list = g_list_append (list,
|
||||
g_strdup_printf ("%s:%d",
|
||||
rec->hostname, rec->port));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_sender_send_frame:
|
||||
* @sender: a #Bsender object
|
||||
* @data: the frame data to send
|
||||
*
|
||||
* Sends Blinkenlights packets to all recipients registered with
|
||||
* @sender. The @data should match the values of the last call to
|
||||
* b_sender_configure() for @sender.
|
||||
*
|
||||
* Return value: %FALSE in case of a fatal error, %TRUE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_sender_send_frame (BSender *sender,
|
||||
const guchar *data)
|
||||
{
|
||||
GList *item;
|
||||
gssize packet_size = sender->size + sizeof (BPacket);
|
||||
|
||||
g_return_val_if_fail (B_IS_SENDER (sender), FALSE);
|
||||
|
||||
if (sender->packet == NULL)
|
||||
{
|
||||
g_warning ("Call b_sender_configure() before sending packages!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (data)
|
||||
memcpy (sender->packet->data, data, sender->size);
|
||||
else
|
||||
memset (sender->packet->data, 0, sender->size);
|
||||
|
||||
/* ...send it. */
|
||||
for (item = sender->recipients; item; item = item->next)
|
||||
{
|
||||
BRecipient *rec = (BRecipient *) item->data;
|
||||
|
||||
if (rec == NULL)
|
||||
continue;
|
||||
|
||||
if (send (rec->fd, sender->packet, packet_size, 0) != packet_size)
|
||||
{
|
||||
if (sender->verbose)
|
||||
g_printerr ("Unable to send to %s: %s\n",
|
||||
rec->hostname, g_strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_sender_send_heartbeat:
|
||||
* @sender: a #Bsender object
|
||||
*
|
||||
* This function is deprecated and might be removed in the future.
|
||||
* If you need the heartbeat functionality, use #BProxyClient instead.
|
||||
*
|
||||
* Return value: %TRUE always
|
||||
**/
|
||||
gboolean
|
||||
b_sender_send_heartbeat (BSender *sender)
|
||||
{
|
||||
GList *item;
|
||||
BPacket packet;
|
||||
|
||||
g_return_val_if_fail (B_IS_SENDER (sender), FALSE);
|
||||
|
||||
memset (&packet, 0, sizeof (BPacket));
|
||||
|
||||
packet.header.heartbeat_h.magic = MAGIC_HEARTBEAT;
|
||||
|
||||
b_packet_hton (&packet);
|
||||
|
||||
for (item = sender->recipients; item; item = item->next)
|
||||
{
|
||||
BRecipient *rec = (BRecipient *) item->data;
|
||||
|
||||
if (rec == NULL)
|
||||
continue;
|
||||
|
||||
if (send (rec->fd, &packet, sizeof (BPacket), 0) != sizeof (BPacket))
|
||||
{
|
||||
if (sender->verbose)
|
||||
g_printerr ("Unable to send heartbeat to %s: %s\n",
|
||||
rec->hostname, g_strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_sender_set_verbose:
|
||||
* @sender: a #Bsender object
|
||||
* @verbose: whether the @sender should do verbose error reporting or not
|
||||
*
|
||||
* In earlier BLib versions #BSender used to print a message to stderr
|
||||
* when send() failed. This message is now suppressed by default, but
|
||||
* you can get the old behaviour back using this function.
|
||||
**/
|
||||
void
|
||||
b_sender_set_verbose (BSender *sender,
|
||||
gboolean verbose)
|
||||
{
|
||||
g_return_if_fail (B_IS_SENDER (sender));
|
||||
|
||||
sender->verbose = (verbose != FALSE);
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Michael Natterer <mitch@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_SENDER_H__
|
||||
#define __B_SENDER_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define B_TYPE_SENDER (b_sender_get_type ())
|
||||
#define B_SENDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_SENDER, BSender))
|
||||
#define B_SENDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_SENDER, BSenderClass))
|
||||
#define B_IS_SENDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_SENDER))
|
||||
#define B_IS_SENDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_SENDER))
|
||||
#define B_SENDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_SENDER, BSenderClass))
|
||||
|
||||
|
||||
typedef struct _BSenderClass BSenderClass;
|
||||
|
||||
struct _BSenderClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _BSender
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GList *recipients;
|
||||
|
||||
BPacket *packet;
|
||||
gsize size;
|
||||
|
||||
gboolean verbose;
|
||||
};
|
||||
|
||||
GType b_sender_get_type (void) G_GNUC_CONST;
|
||||
BSender * b_sender_new (void);
|
||||
|
||||
gboolean b_sender_add_recipient (BSender *sender,
|
||||
gint src_port,
|
||||
const gchar *dest_host,
|
||||
gint dest_port,
|
||||
GError **error);
|
||||
gboolean b_sender_remove_recipient (BSender *sender,
|
||||
const gchar *dest_host,
|
||||
gint dest_port,
|
||||
GError **error);
|
||||
GList * b_sender_list_recipients (BSender *sender);
|
||||
|
||||
gboolean b_sender_configure (BSender *sender,
|
||||
gint width,
|
||||
gint height,
|
||||
gint channels,
|
||||
gint maxval);
|
||||
gboolean b_sender_send_frame (BSender *sender,
|
||||
const guchar *data);
|
||||
void b_sender_set_verbose (BSender *sender,
|
||||
gboolean verbose);
|
||||
|
||||
#ifndef B_DISABLE_DEPRECATED
|
||||
gboolean b_sender_send_heartbeat (BSender *sender);
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_SENDER_H__ */
|
|
@ -0,0 +1,156 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2004 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "bsocket.h"
|
||||
|
||||
|
||||
/**
|
||||
* b_socket_init:
|
||||
* @error: return location for possible errors.
|
||||
*
|
||||
* Initialize network sockets. This function does nothing on
|
||||
* UNIXes. On Win32 it initializes the Winsock DLL. You may call this
|
||||
* function any number of times, the initialization is only done once.
|
||||
*
|
||||
* Return value: %TRUE on success, %FALSE in case of an error
|
||||
**/
|
||||
gboolean
|
||||
b_socket_init (GError **error)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
static gboolean winsock_initialized = FALSE;
|
||||
|
||||
if (! winsock_initialized)
|
||||
{
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
|
||||
wVersionRequested = MAKEWORD (2, 2);
|
||||
|
||||
if (WSAStartup (wVersionRequested, &wsaData) == 0)
|
||||
{
|
||||
winsock_initialized = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, 0, 0, "Can't initialize the Winsock DLL");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_socket_udp_new:
|
||||
* @options: #BSocketOptions to set on the socket.
|
||||
* @error: return location for possible errors.
|
||||
*
|
||||
* Creates an UDP socket and configures it according to @options.
|
||||
*
|
||||
* Return value: a socket descriptor or -1 in case of an error
|
||||
**/
|
||||
gint
|
||||
b_socket_udp_new (BSocketOptions options,
|
||||
GError **error)
|
||||
{
|
||||
gint fd;
|
||||
gint value;
|
||||
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, -1);
|
||||
|
||||
if (! b_socket_init (error))
|
||||
return FALSE;
|
||||
|
||||
fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (fd == -1)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Can't create socket: %s", g_strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (options & B_SO_BROADCAST)
|
||||
{
|
||||
value = 1;
|
||||
if (setsockopt (fd,
|
||||
SOL_SOCKET, SO_BROADCAST, &value, sizeof (value)) < 0)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Can't set socket option (SO_BROADCAST): %s",
|
||||
g_strerror (errno));
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (options & B_SO_REUSEADDR)
|
||||
{
|
||||
value = 1;
|
||||
if (setsockopt (fd,
|
||||
SOL_SOCKET, SO_REUSEADDR, &value, sizeof (value)) < 0)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Can't set socket option (SO_REUSEADDR): %s",
|
||||
g_strerror (errno));
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SO_REUSEPORT
|
||||
value = 1;
|
||||
if (setsockopt (fd,
|
||||
SOL_SOCKET, SO_REUSEPORT, &value, sizeof (value)) < 0)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"Can't set socket option (SO_REUSEPORT): %s",
|
||||
g_strerror (errno));
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2004 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
* Daniel Mack <daniel@yoobay.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_SOCKET_H__
|
||||
#define __B_SOCKET_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
B_SO_NONE = 0,
|
||||
B_SO_BROADCAST = 1 << 0,
|
||||
B_SO_REUSEADDR = 1 << 1
|
||||
} BSocketOptions;
|
||||
|
||||
gboolean b_socket_init (GError **error);
|
||||
gint b_socket_udp_new (BSocketOptions options,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_SOCKET_H__ */
|
|
@ -0,0 +1,536 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bobject.h"
|
||||
#include "bparser.h"
|
||||
#include "btheme.h"
|
||||
#include "btheme-parser.h"
|
||||
#include "butils.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
THEME = B_PARSER_STATE_USER,
|
||||
BACKGROUND,
|
||||
OVERLAY,
|
||||
GRID,
|
||||
GRID_WINDOW,
|
||||
SPAN,
|
||||
SPAN_WINDOW,
|
||||
WINDOW,
|
||||
FINISH
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BTheme *theme;
|
||||
gchar *dirname;
|
||||
gboolean lazy;
|
||||
BOverlay *overlay;
|
||||
gint dx, dy;
|
||||
gint sx, sy;
|
||||
GList *windows;
|
||||
} ParserData;
|
||||
|
||||
|
||||
static BParserState b_theme_start_element (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static BParserState b_theme_end_element (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar *cdata,
|
||||
gsize cdata_len,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
static void b_theme_parse_header (BTheme *theme,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values);
|
||||
static void b_theme_parse_image (ParserData *data,
|
||||
BOverlay *overlay,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values);
|
||||
static void b_theme_parse_grid (ParserData *data,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values);
|
||||
static void b_theme_parse_window (BWindow *window,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values);
|
||||
static void b_theme_overlay_add_window (BTheme *theme,
|
||||
BOverlay *overlay,
|
||||
const BWindow *window);
|
||||
static gboolean b_theme_window_validate (BTheme *theme,
|
||||
const BWindow *window);
|
||||
|
||||
|
||||
gboolean
|
||||
b_theme_parser_parse (BTheme *theme,
|
||||
gboolean lazy,
|
||||
GError **error)
|
||||
{
|
||||
BParser *parser;
|
||||
ParserData data = { NULL };
|
||||
GIOChannel *io;
|
||||
const gchar *filename;
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (theme != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
filename = b_object_get_filename (B_OBJECT (theme));
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
|
||||
io = g_io_channel_new_file (filename, "r", error);
|
||||
if (!io)
|
||||
return FALSE;
|
||||
|
||||
data.theme = theme;
|
||||
data.dirname = g_path_get_dirname (filename);
|
||||
data.lazy = lazy;
|
||||
|
||||
parser = b_parser_new (b_theme_start_element, b_theme_end_element, &data);
|
||||
|
||||
retval = b_parser_parse_io_channel (parser, io, TRUE, error);
|
||||
|
||||
if (retval && b_parser_get_state (parser) != FINISH)
|
||||
{
|
||||
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"This does not look like a Blinkenlights Theme");
|
||||
retval = FALSE;
|
||||
}
|
||||
|
||||
g_io_channel_unref (io);
|
||||
|
||||
b_parser_free (parser);
|
||||
|
||||
g_free (data.dirname);
|
||||
|
||||
if (retval &&
|
||||
(theme->rows < 1 || theme->columns < 1 ||
|
||||
theme->channels < 1 ||
|
||||
theme->maxval < 1 || theme->maxval > 256 ||
|
||||
theme->width < 1 || theme->height < 1))
|
||||
{
|
||||
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Incorrect theme header");
|
||||
retval = FALSE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static BParserState
|
||||
b_theme_start_element (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
ParserData *data = (ParserData *) user_data;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case B_PARSER_STATE_TOPLEVEL:
|
||||
if (strcmp (element_name, "blinkentheme") == 0)
|
||||
{
|
||||
b_theme_parse_header (data->theme,
|
||||
attribute_names, attribute_values);
|
||||
return THEME;
|
||||
}
|
||||
break;
|
||||
|
||||
case THEME:
|
||||
if (data->lazy)
|
||||
return B_PARSER_STATE_UNKNOWN;
|
||||
|
||||
if (strcmp (element_name, "background") == 0)
|
||||
{
|
||||
b_theme_parse_image (data, NULL,
|
||||
attribute_names, attribute_values);
|
||||
b_parse_coordinates (attribute_names, attribute_values,
|
||||
&data->theme->bg_image_x,
|
||||
&data->theme->bg_image_y);
|
||||
return BACKGROUND;
|
||||
}
|
||||
else if (strcmp (element_name, "overlay") == 0)
|
||||
{
|
||||
BOverlay *overlay = g_new0 (BOverlay, 1);
|
||||
|
||||
b_theme_parse_image (data, overlay,
|
||||
attribute_names, attribute_values);
|
||||
|
||||
data->overlay = overlay;
|
||||
return OVERLAY;
|
||||
}
|
||||
break;
|
||||
|
||||
case OVERLAY:
|
||||
if (strcmp (element_name, "grid") == 0)
|
||||
{
|
||||
b_theme_parse_grid (data, attribute_names, attribute_values);
|
||||
return GRID;
|
||||
}
|
||||
else if (strcmp (element_name, "span") == 0)
|
||||
{
|
||||
b_theme_parse_grid (data, attribute_names, attribute_values);
|
||||
return SPAN;
|
||||
}
|
||||
else if (strcmp (element_name, "window") == 0)
|
||||
{
|
||||
BWindow window;
|
||||
|
||||
b_theme_parse_window (&window, attribute_names, attribute_values);
|
||||
|
||||
if (b_theme_window_validate (data->theme, &window))
|
||||
b_theme_overlay_add_window (data->theme, data->overlay, &window);
|
||||
|
||||
return WINDOW;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GRID:
|
||||
case SPAN:
|
||||
if (strcmp (element_name, "window") == 0)
|
||||
{
|
||||
BWindow window;
|
||||
|
||||
b_theme_parse_window (&window, attribute_names, attribute_values);
|
||||
if (b_theme_window_validate (data->theme, &window))
|
||||
data->windows = g_list_append (data->windows,
|
||||
g_memdup (&window,
|
||||
sizeof (BWindow)));
|
||||
|
||||
return state == GRID ? GRID_WINDOW : SPAN_WINDOW;
|
||||
}
|
||||
break;
|
||||
|
||||
case GRID_WINDOW:
|
||||
case SPAN_WINDOW:
|
||||
case WINDOW:
|
||||
g_printerr ("window element should be empty");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return B_PARSER_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
static BParserState
|
||||
b_theme_end_element (BParserState state,
|
||||
const gchar *element_name,
|
||||
const gchar *cdata,
|
||||
gsize cdata_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
ParserData *data = (ParserData *) user_data;
|
||||
GList *list;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case THEME:
|
||||
data->theme->overlays = g_list_reverse (data->theme->overlays);
|
||||
return FINISH;
|
||||
|
||||
case BACKGROUND:
|
||||
return THEME;
|
||||
|
||||
case OVERLAY:
|
||||
g_return_val_if_fail (data->overlay != NULL, THEME);
|
||||
|
||||
if (data->overlay->windows)
|
||||
{
|
||||
data->overlay->windows = g_list_reverse (data->overlay->windows);
|
||||
data->theme->overlays = g_list_prepend (data->theme->overlays,
|
||||
data->overlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_printerr ("no windows defined in overlay, skipping");
|
||||
|
||||
g_free (data->overlay->image);
|
||||
g_free (data->overlay);
|
||||
}
|
||||
data->overlay = NULL;
|
||||
return THEME;
|
||||
|
||||
case GRID:
|
||||
case SPAN:
|
||||
for (list = data->windows; list; list = list->next)
|
||||
{
|
||||
BWindow *template = list->data;
|
||||
gint row, col;
|
||||
|
||||
template->column = 0;
|
||||
if (state == GRID)
|
||||
template->row = 0;
|
||||
|
||||
for (row = template->row; row < data->theme->rows; row++)
|
||||
{
|
||||
for (col = 0; col < data->theme->columns; col++)
|
||||
{
|
||||
BWindow window = *template;
|
||||
|
||||
window.row = row;
|
||||
window.column = col;
|
||||
window.src_x += col * data->sx;
|
||||
window.rect.x += col * data->dx;
|
||||
|
||||
#if 0
|
||||
g_print ("window %d,%d (%d) is %dx%d @ %d,%d src=%d,%d\n",
|
||||
window.column, window.row, window.value,
|
||||
window.rect.w, window.rect.h,
|
||||
window.rect.x, window.rect.y,
|
||||
window.src_x, window.src_y);
|
||||
#endif
|
||||
|
||||
b_theme_overlay_add_window (data->theme, data->overlay,
|
||||
&window);
|
||||
}
|
||||
|
||||
if (state == SPAN)
|
||||
break;
|
||||
|
||||
template->src_y += data->sy;
|
||||
template->rect.y += data->dy;
|
||||
}
|
||||
|
||||
g_free (template);
|
||||
}
|
||||
|
||||
g_list_free (data->windows);
|
||||
data->windows = NULL;
|
||||
return OVERLAY;
|
||||
|
||||
case GRID_WINDOW:
|
||||
return GRID;
|
||||
|
||||
case SPAN_WINDOW:
|
||||
return SPAN;
|
||||
|
||||
case WINDOW:
|
||||
return OVERLAY;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return B_PARSER_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
static void
|
||||
b_theme_parse_header (BTheme *theme,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values)
|
||||
{
|
||||
const gchar **name;
|
||||
const gchar **value;
|
||||
|
||||
if (theme->type)
|
||||
{
|
||||
g_free (theme->type);
|
||||
theme->type = NULL;
|
||||
}
|
||||
|
||||
theme->rows = 0;
|
||||
theme->columns = 0;
|
||||
theme->channels = 1;
|
||||
theme->maxval = 1;
|
||||
theme->width = 0;
|
||||
theme->height = 0;
|
||||
|
||||
for (name = attribute_names, value = attribute_values;
|
||||
*name && *value;
|
||||
name++, value++)
|
||||
{
|
||||
if (strcmp (*name, "title") == 0)
|
||||
b_object_set_name (B_OBJECT (theme), *value);
|
||||
if (strcmp (*name, "type") == 0)
|
||||
theme->type = g_strdup (*value);
|
||||
if (strcmp (*name, "rows") == 0)
|
||||
b_parse_int (*value, &theme->rows);
|
||||
if (strcmp (*name, "columns") == 0)
|
||||
b_parse_int (*value, &theme->columns);
|
||||
if (strcmp (*name, "channels") == 0)
|
||||
b_parse_int (*value, &theme->channels);
|
||||
if (strcmp (*name, "maxval") == 0)
|
||||
b_parse_int (*value, &theme->maxval);
|
||||
if (strcmp (*name, "width") == 0)
|
||||
b_parse_int (*value, &theme->width);
|
||||
if (strcmp (*name, "height") == 0)
|
||||
b_parse_int (*value, &theme->height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
b_theme_parse_image (ParserData *data,
|
||||
BOverlay *overlay,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values)
|
||||
{
|
||||
const gchar **name;
|
||||
const gchar **value;
|
||||
gchar **image;
|
||||
BColor *color;
|
||||
|
||||
image = overlay ? &overlay->image : &data->theme->bg_image;
|
||||
|
||||
for (name = attribute_names, value = attribute_values;
|
||||
*name && *value;
|
||||
name++, value++)
|
||||
{
|
||||
if (!*image && strcmp (*name, "image") == 0)
|
||||
*image = g_build_filename (data->dirname, *value, NULL);
|
||||
}
|
||||
|
||||
color = overlay ? &overlay->color : &data->theme->bg_color;
|
||||
|
||||
if (overlay)
|
||||
color->r = color->g = color->b = 0xFF;
|
||||
else
|
||||
color->r = color->g = color->b = 0x00;
|
||||
|
||||
color->a = 0xFF;
|
||||
|
||||
b_parse_color (attribute_names, attribute_values, color);
|
||||
}
|
||||
|
||||
static void
|
||||
b_theme_parse_grid (ParserData *data,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values)
|
||||
{
|
||||
const gchar **name;
|
||||
const gchar **value;
|
||||
|
||||
data->dx = data->dy = data->sx = data->sy = 0;
|
||||
|
||||
for (name = attribute_names, value = attribute_values;
|
||||
*name && *value;
|
||||
name++, value++)
|
||||
{
|
||||
if (strcmp (*name, "dx") == 0)
|
||||
b_parse_int (*value, &data->dx);
|
||||
if (strcmp (*name, "dy") == 0)
|
||||
b_parse_int (*value, &data->dy);
|
||||
if (strcmp (*name, "sx") == 0)
|
||||
b_parse_int (*value, &data->sx);
|
||||
if (strcmp (*name, "sy") == 0)
|
||||
b_parse_int (*value, &data->sy);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
b_theme_parse_window (BWindow *window,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values)
|
||||
{
|
||||
const gchar **name;
|
||||
const gchar **value;
|
||||
|
||||
window->value = B_WINDOW_VALUE_ALL;
|
||||
window->row = window->column = 0;
|
||||
window->src_x = window->src_y = 0;
|
||||
window->rect.x = window->rect.y = window->rect.w = window->rect.h = 0;
|
||||
|
||||
for (name = attribute_names, value = attribute_values;
|
||||
*name && *value;
|
||||
name++, value++)
|
||||
{
|
||||
if (strcmp (*name, "value") == 0 && strcmp (*value, "all"))
|
||||
b_parse_int (*value, &window->value);
|
||||
if (strcmp (*name, "row") == 0)
|
||||
b_parse_int (*value, &window->row);
|
||||
if (strcmp (*name, "column") == 0)
|
||||
b_parse_int (*value, &window->column);
|
||||
if (strcmp (*name, "src-x") == 0)
|
||||
b_parse_int (*value, &window->src_x);
|
||||
if (strcmp (*name, "src-y") == 0)
|
||||
b_parse_int (*value, &window->src_y);
|
||||
}
|
||||
|
||||
b_parse_rectangle (attribute_names, attribute_values, &window->rect);
|
||||
}
|
||||
|
||||
static void
|
||||
b_theme_overlay_add_window (BTheme *theme,
|
||||
BOverlay *overlay,
|
||||
const BWindow *window)
|
||||
{
|
||||
BWindow *windows;
|
||||
GList *list;
|
||||
gint i;
|
||||
|
||||
for (list = overlay->windows; list; list = list->next)
|
||||
{
|
||||
windows = list->data;
|
||||
|
||||
if (windows->row == window->row && windows->column == window->column)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!list)
|
||||
{
|
||||
windows = g_new (BWindow, theme->maxval);
|
||||
for (i = 0; i < theme->maxval; i++)
|
||||
{
|
||||
windows[i] = *window;
|
||||
windows[i].value = B_WINDOW_VALUE_ALL;
|
||||
}
|
||||
overlay->windows = g_list_prepend (overlay->windows, windows);
|
||||
}
|
||||
|
||||
if (window->value != B_WINDOW_VALUE_ALL)
|
||||
{
|
||||
windows[window->value - 1] = *window;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_theme_window_validate (BTheme *theme,
|
||||
const BWindow *window)
|
||||
{
|
||||
if (window
|
||||
&&
|
||||
(window->value != B_WINDOW_VALUE_ALL &&
|
||||
(window->value < 1 || window->value > theme->maxval))
|
||||
&&
|
||||
(window->row < 0 || window->row >= theme->rows ||
|
||||
window->column < 0 || window->column >= theme->columns))
|
||||
{
|
||||
g_printerr ("Invalid window, skipping");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_THEME_PARSER_H__
|
||||
#define __B_THEME_PARSER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean b_theme_parser_parse (BTheme *theme,
|
||||
gboolean lazy,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_THEME_PARSER_H__ */
|
|
@ -0,0 +1,426 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002-2004 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bobject.h"
|
||||
#include "btheme.h"
|
||||
#include "btheme-parser.h"
|
||||
#include "butils.h"
|
||||
|
||||
|
||||
static void b_theme_class_init (BThemeClass *class);
|
||||
static void b_theme_init (BTheme *theme);
|
||||
static void b_theme_finalize (GObject *object);
|
||||
|
||||
|
||||
static BObjectClass *parent_class = NULL;
|
||||
|
||||
GType
|
||||
b_theme_get_type (void)
|
||||
{
|
||||
static GType theme_type = 0;
|
||||
|
||||
if (!theme_type)
|
||||
{
|
||||
static const GTypeInfo theme_info =
|
||||
{
|
||||
sizeof (BThemeClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) b_theme_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (BTheme),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) b_theme_init
|
||||
};
|
||||
|
||||
theme_type = g_type_register_static (B_TYPE_OBJECT,
|
||||
"BTheme", &theme_info, 0);
|
||||
}
|
||||
|
||||
return theme_type;
|
||||
}
|
||||
|
||||
static void
|
||||
b_theme_class_init (BThemeClass *class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = b_theme_finalize;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
b_theme_init (BTheme *theme)
|
||||
{
|
||||
theme->bg_color.a = 0xFF;
|
||||
theme->bg_image_x = 0;
|
||||
theme->bg_image_y = 0;
|
||||
theme->needs_blending = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
b_theme_finalize (GObject *object)
|
||||
{
|
||||
BTheme *theme;
|
||||
|
||||
theme = B_THEME (object);
|
||||
|
||||
if (theme->type)
|
||||
{
|
||||
g_free (theme->type);
|
||||
theme->type = NULL;
|
||||
}
|
||||
|
||||
b_theme_unload (theme);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_theme_needs_blending (BTheme *theme)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
if (theme->maxval == 1)
|
||||
return FALSE;
|
||||
|
||||
for (list = theme->overlays; list; list = list->next)
|
||||
{
|
||||
BOverlay *overlay = list->data;
|
||||
GList *windows;
|
||||
|
||||
for (windows = overlay->windows; windows; windows = windows->next)
|
||||
{
|
||||
BWindow *window = windows->data;
|
||||
|
||||
if (window->value == B_WINDOW_VALUE_ALL)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* b_theme_new_from_file:
|
||||
* @filename: the name of the file to load the theme from
|
||||
* @lazy_load: whether to do lazy-loading
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Tries to load a #BTheme from the file pointed to by @filename. If
|
||||
* @lazy_load is %TRUE, only the header is loaded.
|
||||
*
|
||||
* Return value: a newly allocated #BTheme object or %NULL if the load
|
||||
* failed
|
||||
**/
|
||||
BTheme *
|
||||
b_theme_new_from_file (const gchar *filename,
|
||||
gboolean lazy_load,
|
||||
GError **error)
|
||||
{
|
||||
BTheme *theme;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (g_path_is_absolute (filename))
|
||||
{
|
||||
theme = g_object_new (B_TYPE_THEME, "filename", filename, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *cwd = g_get_current_dir ();
|
||||
gchar *abs = g_build_filename (cwd, filename, NULL);
|
||||
|
||||
theme = g_object_new (B_TYPE_THEME, "filename", abs, NULL);
|
||||
|
||||
g_free (abs);
|
||||
g_free (cwd);
|
||||
}
|
||||
|
||||
if (! b_theme_parser_parse (theme, lazy_load, error))
|
||||
{
|
||||
g_object_unref (theme);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
theme->needs_blending = b_theme_needs_blending (theme);
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_theme_new_from_scratch:
|
||||
* @title: a descriptive title
|
||||
* @type: the theme type or %NULL
|
||||
* @rows: the number of rows of windows
|
||||
* @columns: the number of columns of windows
|
||||
* @channels: the number of channels per window (must be 1)
|
||||
* @maxval: the maximum value
|
||||
* @width: screen width in pixels
|
||||
* @height: screen height in pixels
|
||||
*
|
||||
* Creates a new #BTheme object from scratch. This may be useful if
|
||||
* you want to quickly test a movie for a layout you don't have a
|
||||
* theme for. You need to call b_theme_load() before you can use the
|
||||
* new theme.
|
||||
*
|
||||
* Return value: a newly allocated, lazy-loaded, #BTheme object
|
||||
**/
|
||||
BTheme *
|
||||
b_theme_new_from_scratch (const gchar *title,
|
||||
const gchar *type,
|
||||
gint rows,
|
||||
gint columns,
|
||||
gint channels,
|
||||
gint maxval,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
BTheme *theme;
|
||||
|
||||
g_return_val_if_fail (title != NULL, NULL);
|
||||
g_return_val_if_fail (rows > 0 && columns > 0, NULL);
|
||||
g_return_val_if_fail (channels == 1, NULL);
|
||||
g_return_val_if_fail (maxval > 0 && maxval < 256, NULL);
|
||||
g_return_val_if_fail (width > 0 && height > 0, NULL);
|
||||
|
||||
theme = g_object_new (B_TYPE_THEME, "name", title, NULL);
|
||||
|
||||
theme->type = g_strdup (type);
|
||||
theme->rows = rows;
|
||||
theme->columns = columns;
|
||||
theme->channels = channels;
|
||||
theme->maxval = maxval;
|
||||
theme->width = width;
|
||||
theme->height = height;
|
||||
|
||||
theme->needs_blending = b_theme_needs_blending (theme);
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
static void
|
||||
b_theme_load_from_scratch (BTheme *theme)
|
||||
{
|
||||
BOverlay *overlay;
|
||||
gint row;
|
||||
gint column;
|
||||
gint i;
|
||||
|
||||
overlay = g_new0 (BOverlay, 1);
|
||||
|
||||
overlay->color.a = 0xFF;
|
||||
overlay->color.r = 0xFF;
|
||||
overlay->color.g = 0xFF;
|
||||
overlay->color.b = 0xFF;
|
||||
|
||||
for (row = 0; row < theme->rows; row++)
|
||||
for (column = 0; column < theme->columns; column++)
|
||||
{
|
||||
BWindow *windows;
|
||||
BWindow template;
|
||||
|
||||
template.value = B_WINDOW_VALUE_ALL;
|
||||
template.row = row;
|
||||
template.column = column;
|
||||
template.src_x = template.src_y = 0;
|
||||
template.rect.w = theme->width / theme->columns;
|
||||
template.rect.h = theme->height / theme->rows;
|
||||
template.rect.x = column * template.rect.w;
|
||||
template.rect.y = row * template.rect.h;
|
||||
|
||||
windows = g_new0 (BWindow, theme->maxval);
|
||||
|
||||
for (i = 0; i < theme->maxval; i++)
|
||||
windows[i] = template;
|
||||
|
||||
overlay->windows = g_list_prepend (overlay->windows, windows);
|
||||
}
|
||||
|
||||
overlay->windows = g_list_reverse (overlay->windows);
|
||||
|
||||
theme->overlays = g_list_prepend (NULL, overlay);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_theme_load:
|
||||
* @theme: a #BTheme object
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Loads all data into the @theme. You only need to call this if you
|
||||
* lazy-loaded the theme or called b_theme_unload() before.
|
||||
*
|
||||
* Return value: %TRUE on success, FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_theme_load (BTheme *theme,
|
||||
GError **error)
|
||||
{
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (B_IS_THEME (theme), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
b_theme_unload (theme);
|
||||
|
||||
if (b_object_get_filename (B_OBJECT (theme)))
|
||||
{
|
||||
retval = b_theme_parser_parse (theme, FALSE, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
b_theme_load_from_scratch (theme);
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
theme->needs_blending = b_theme_needs_blending (theme);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_theme_unload:
|
||||
* @theme: a #BTheme object
|
||||
*
|
||||
* Frees all data of a BTheme except the meta information stored in
|
||||
* the header.
|
||||
**/
|
||||
void
|
||||
b_theme_unload (BTheme *theme)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
g_return_if_fail (B_IS_THEME (theme));
|
||||
|
||||
g_free (theme->bg_image);
|
||||
theme->bg_image = NULL;
|
||||
|
||||
for (list = theme->overlays; list; list = list->next)
|
||||
{
|
||||
BOverlay *overlay = list->data;
|
||||
GList *window;
|
||||
|
||||
g_free (overlay->image);
|
||||
overlay->image = NULL;
|
||||
|
||||
for (window = overlay->windows; window; window = window->next)
|
||||
g_free (window->data);
|
||||
|
||||
g_list_free (overlay->windows);
|
||||
g_free (overlay);
|
||||
}
|
||||
|
||||
g_list_free (theme->overlays);
|
||||
theme->overlays = NULL;
|
||||
|
||||
theme->needs_blending = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
b_theme_frame_boundary (BTheme *theme,
|
||||
BWindow *window,
|
||||
guchar data,
|
||||
BRectangle *bbox)
|
||||
{
|
||||
if (! data)
|
||||
return;
|
||||
|
||||
window += (data * theme->maxval) / 256;
|
||||
|
||||
b_rectangle_union (&window->rect, bbox, bbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_theme_frame_diff_boundary
|
||||
* @theme: a #BTheme
|
||||
* @prev_data: data of the previous frame
|
||||
* @frame_data: data of the current frame
|
||||
* @bbox: returns bounding box
|
||||
*
|
||||
* Computes the bounding box of the difference image between two frames.
|
||||
*
|
||||
* Return value: %TRUE if the bounding box is not empty.
|
||||
**/
|
||||
gboolean
|
||||
b_theme_frame_diff_boundary (BTheme *theme,
|
||||
const guchar *prev_data,
|
||||
const guchar *frame_data,
|
||||
BRectangle *bbox)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
g_return_val_if_fail (B_IS_THEME (theme), FALSE);
|
||||
g_return_val_if_fail (bbox != NULL, FALSE);
|
||||
|
||||
bbox->x = 0;
|
||||
bbox->y = 0;
|
||||
bbox->w = 0;
|
||||
bbox->h = 0;
|
||||
|
||||
for (list = theme->overlays; list; list = list->next)
|
||||
{
|
||||
BOverlay *overlay = list->data;
|
||||
|
||||
if (overlay->image)
|
||||
{
|
||||
GList *iter;
|
||||
|
||||
for (iter = overlay->windows; iter; iter = iter->next)
|
||||
{
|
||||
BWindow *window = iter->data;
|
||||
guint index = window->column + window->row * theme->columns;
|
||||
|
||||
if (prev_data && frame_data)
|
||||
{
|
||||
if (frame_data[index] != prev_data[index])
|
||||
{
|
||||
b_theme_frame_boundary (theme,
|
||||
window, frame_data[index], bbox);
|
||||
b_theme_frame_boundary (theme,
|
||||
window, prev_data[index], bbox);
|
||||
}
|
||||
}
|
||||
else if (prev_data)
|
||||
{
|
||||
b_theme_frame_boundary (theme,
|
||||
window, prev_data[index], bbox);
|
||||
}
|
||||
else if (frame_data)
|
||||
{
|
||||
b_theme_frame_boundary (theme,
|
||||
window, frame_data[index], bbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (bbox->w > 0 && bbox->h > 0);
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002-2004 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_THEME_H__
|
||||
#define __B_THEME_H__
|
||||
|
||||
#define B_WINDOW_VALUE_ALL 0
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _BWindow BWindow;
|
||||
typedef struct _BOverlay BOverlay;
|
||||
|
||||
struct _BWindow
|
||||
{
|
||||
gint value;
|
||||
gint row;
|
||||
gint column;
|
||||
gint src_x;
|
||||
gint src_y;
|
||||
BRectangle rect;
|
||||
};
|
||||
|
||||
struct _BOverlay
|
||||
{
|
||||
gchar *image;
|
||||
BColor color;
|
||||
|
||||
GList *windows;
|
||||
};
|
||||
|
||||
|
||||
#define B_TYPE_THEME (b_theme_get_type ())
|
||||
#define B_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_THEME, BTheme))
|
||||
#define B_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_THEME, BThemeClass))
|
||||
#define B_IS_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_THEME))
|
||||
#define B_IS_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_THEME))
|
||||
#define B_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_THEME, BThemeClass))
|
||||
|
||||
|
||||
typedef struct _BThemeClass BThemeClass;
|
||||
|
||||
struct _BThemeClass
|
||||
{
|
||||
BObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _BTheme
|
||||
{
|
||||
BObjectClass parent_class;
|
||||
|
||||
gchar *type;
|
||||
|
||||
gint rows;
|
||||
gint columns;
|
||||
gint channels;
|
||||
gint maxval;
|
||||
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
BColor bg_color;
|
||||
gchar *bg_image;
|
||||
gint bg_image_x;
|
||||
gint bg_image_y;
|
||||
|
||||
GList *overlays;
|
||||
|
||||
gboolean needs_blending; /* for optimizations */
|
||||
};
|
||||
|
||||
|
||||
GType b_theme_get_type (void) G_GNUC_CONST;
|
||||
|
||||
BTheme * b_theme_new_from_file (const gchar *filename,
|
||||
gboolean lazy_load,
|
||||
GError **error);
|
||||
BTheme * b_theme_new_from_scratch (const gchar *title,
|
||||
const gchar *type,
|
||||
gint rows,
|
||||
gint columns,
|
||||
gint channels,
|
||||
gint maxval,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
gboolean b_theme_load (BTheme *theme,
|
||||
GError **error);
|
||||
void b_theme_unload (BTheme *theme);
|
||||
|
||||
gboolean b_theme_frame_diff_boundary (BTheme *theme,
|
||||
const guchar *prev_data,
|
||||
const guchar *frame_data,
|
||||
BRectangle *bbox);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_THEME_H__ */
|
|
@ -0,0 +1,306 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bobject.h"
|
||||
#include "btheme.h"
|
||||
#include "bthemes.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BThemesQuery *query;
|
||||
GList *list;
|
||||
} BThemesQueryData;
|
||||
|
||||
|
||||
static const gchar *
|
||||
b_themes_get_path (void)
|
||||
{
|
||||
const gchar *env = g_getenv ("B_THEME_PATH");
|
||||
|
||||
if (env)
|
||||
return env;
|
||||
|
||||
return THEMEPATH;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
b_themes_match_query (BTheme *theme,
|
||||
gpointer callback_data)
|
||||
{
|
||||
BThemesQueryData *data = callback_data;
|
||||
BThemesQuery *query = data->query;
|
||||
|
||||
if ((query->flags & B_THEMES_QUERY_ROWS) &&
|
||||
(query->rows != theme->rows))
|
||||
return TRUE;
|
||||
if ((query->flags & B_THEMES_QUERY_COLUMNS) &&
|
||||
(query->columns != theme->columns))
|
||||
return TRUE;
|
||||
if ((query->flags & B_THEMES_QUERY_WIDTH) &&
|
||||
(query->width != theme->width))
|
||||
return TRUE;
|
||||
if ((query->flags & B_THEMES_QUERY_HEIGHT) &&
|
||||
(query->height != theme->height))
|
||||
return TRUE;
|
||||
|
||||
if ((query->flags & B_THEMES_QUERY_TYPE))
|
||||
{
|
||||
if (query->type)
|
||||
{
|
||||
if (theme->type == NULL || strcmp (query->type, theme->type))
|
||||
return TRUE;
|
||||
}
|
||||
else if (theme->type)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((query->flags & B_THEMES_QUERY_NAME))
|
||||
{
|
||||
const gchar *name = b_object_get_name (B_OBJECT (theme));
|
||||
|
||||
if (query->name)
|
||||
{
|
||||
if (name == NULL || strcmp (query->name, name))
|
||||
return TRUE;
|
||||
}
|
||||
else if (name)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_object_ref (G_OBJECT (theme));
|
||||
data->list = g_list_prepend (data->list, theme);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_themes_query:
|
||||
* @themepath: a colon-separated list of directories to search or %NULL to
|
||||
* use the default path
|
||||
* @query: pointer to a #BThemesQuery
|
||||
*
|
||||
* Looks for themes as defined by @query. If @themepath is not
|
||||
* specified the default path is used. The default path can be overridden
|
||||
* by setting the environment variable B_THEME_PATH.
|
||||
*
|
||||
* Each theme that matches the @query is lazy-loaded.
|
||||
*
|
||||
* Return value: a #GList of newly allocated, lazy-loaded #BTheme objects
|
||||
* or %NULL if no matching theme was found
|
||||
**/
|
||||
GList *
|
||||
b_themes_query (const gchar *themepath,
|
||||
BThemesQuery *query)
|
||||
{
|
||||
BThemesQueryData query_data;
|
||||
|
||||
g_return_val_if_fail (query != NULL, FALSE);
|
||||
|
||||
query_data.query = query;
|
||||
query_data.list = NULL;
|
||||
|
||||
b_themes_foreach (themepath, b_themes_match_query, &query_data);
|
||||
|
||||
return g_list_reverse (query_data.list);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_themes_foreach
|
||||
* @themepath: a colon-separated list of directories to search or %NULL to
|
||||
* use the default path
|
||||
* @callback: a function to call for each theme
|
||||
* @callback_data: data to pass to the @callback
|
||||
*
|
||||
* This function iterates over all themes in the @themepath, lazy-loads them,
|
||||
* runs @callback on the theme and unrefs it again. The iteration is stopped
|
||||
* if a @callback returns %FALSE.
|
||||
*
|
||||
* If @themepath is not specified, the default path is used. The
|
||||
* default path can be overridden by setting the environment variable
|
||||
* B_THEME_PATH.
|
||||
**/
|
||||
void
|
||||
b_themes_foreach (const gchar *themepath,
|
||||
BThemesForeachFunc callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
BTheme *theme;
|
||||
gchar **dirs;
|
||||
gint i;
|
||||
gboolean cont = TRUE;
|
||||
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
if (!themepath)
|
||||
themepath = b_themes_get_path ();
|
||||
|
||||
dirs = g_strsplit (themepath, G_SEARCHPATH_SEPARATOR_S, 12);
|
||||
|
||||
for (i = 0; cont && dirs[i]; i++)
|
||||
{
|
||||
const gchar *dirname = dirs[i];
|
||||
const gchar *name;
|
||||
GDir *dir;
|
||||
|
||||
dir = g_dir_open (dirname, 0, NULL);
|
||||
if (!dir)
|
||||
continue;
|
||||
|
||||
while (cont && (name = g_dir_read_name (dir)))
|
||||
{
|
||||
gchar *filename = g_build_filename (dirname, name, NULL);
|
||||
|
||||
if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
theme = b_theme_new_from_file (filename, TRUE, NULL);
|
||||
if (theme)
|
||||
{
|
||||
cont = callback (theme, callback_data);
|
||||
g_object_unref (theme);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
g_dir_close (dir);
|
||||
}
|
||||
|
||||
g_strfreev (dirs);
|
||||
}
|
||||
|
||||
|
||||
/* some wrappers that provide the old (pre 1.0) API, don't use */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GHFunc callback;
|
||||
gpointer data;
|
||||
} WrapperData;
|
||||
|
||||
static gboolean
|
||||
wrapper (BTheme *theme,
|
||||
gpointer callback_data)
|
||||
{
|
||||
WrapperData *wrapper_data = callback_data;
|
||||
gchar *basename;
|
||||
gchar *suffix;
|
||||
|
||||
basename = g_path_get_basename (b_object_get_filename (B_OBJECT (theme)));
|
||||
|
||||
if ((suffix = g_strrstr (basename, ".xml")) != NULL)
|
||||
suffix[0] = '\0';
|
||||
|
||||
wrapper_data->callback (basename, theme, wrapper_data->data);
|
||||
|
||||
g_free (basename);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_themes_foreach_theme:
|
||||
* @themepath:
|
||||
* @callback:
|
||||
* @callback_data:
|
||||
*
|
||||
* Shouldn't be used in new code, use b_themes_foreach() instead.
|
||||
**/
|
||||
void
|
||||
b_themes_foreach_theme (const gchar *themepath,
|
||||
GHFunc callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
WrapperData wrapper_data = { callback, callback_data };
|
||||
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
b_themes_foreach (themepath, wrapper, &wrapper_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_themes_lookup_theme:
|
||||
* @name:
|
||||
* @themepath:
|
||||
* @error:
|
||||
*
|
||||
* Shouldn't be used in new code, use b_themes_query() instead.
|
||||
*
|
||||
* Return value:
|
||||
**/
|
||||
BTheme *
|
||||
b_themes_lookup_theme (const gchar *name,
|
||||
const gchar *themepath,
|
||||
GError **error)
|
||||
{
|
||||
BTheme *theme = NULL;
|
||||
gchar **dirs;
|
||||
gchar *filename;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (!themepath)
|
||||
themepath = b_themes_get_path ();
|
||||
|
||||
filename = g_strconcat (name, ".xml", NULL);
|
||||
|
||||
dirs = g_strsplit (themepath, G_SEARCHPATH_SEPARATOR_S, 12);
|
||||
|
||||
for (i = 0; !theme && dirs[i]; i++)
|
||||
{
|
||||
const gchar *dirname = dirs[i];
|
||||
gchar *fullname = g_build_filename (dirname, filename, NULL);
|
||||
|
||||
if (g_file_test (fullname, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
theme = b_theme_new_from_file (fullname, TRUE, NULL);
|
||||
}
|
||||
else /* try w/o the suffix */
|
||||
{
|
||||
g_free (fullname);
|
||||
fullname = g_build_filename (dirname, name, NULL);
|
||||
|
||||
if (g_file_test (fullname, G_FILE_TEST_IS_REGULAR))
|
||||
theme = b_theme_new_from_file (fullname, TRUE, NULL);
|
||||
}
|
||||
|
||||
g_free (fullname);
|
||||
}
|
||||
|
||||
g_strfreev (dirs);
|
||||
|
||||
g_free (filename);
|
||||
|
||||
if (!theme)
|
||||
g_set_error (error, 0, 0,
|
||||
"No theme of this name found in '%s'", themepath);
|
||||
|
||||
return theme;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_THEMES_H__
|
||||
#define __B_THEMES_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
B_THEMES_QUERY_NONE = 0,
|
||||
B_THEMES_QUERY_NAME = 1 << 0,
|
||||
B_THEMES_QUERY_TYPE = 1 << 1,
|
||||
B_THEMES_QUERY_ROWS = 1 << 2,
|
||||
B_THEMES_QUERY_COLUMNS = 1 << 3,
|
||||
B_THEMES_QUERY_WIDTH = 1 << 4,
|
||||
B_THEMES_QUERY_HEIGHT = 1 << 5
|
||||
} BThemesQueryFlags;
|
||||
|
||||
struct _BThemesQuery
|
||||
{
|
||||
BThemesQueryFlags flags;
|
||||
|
||||
const gchar *name;
|
||||
const gchar *type;
|
||||
gint rows;
|
||||
gint columns;
|
||||
gint width;
|
||||
gint height;
|
||||
};
|
||||
|
||||
typedef gboolean (* BThemesForeachFunc) (BTheme *theme,
|
||||
gpointer callback_data);
|
||||
|
||||
|
||||
/* searches a theme in the theme path */
|
||||
GList * b_themes_query (const gchar *themepath,
|
||||
BThemesQuery *query); /* may be NULL */
|
||||
|
||||
/* calls callback for each theme with the short name and the theme */
|
||||
void b_themes_foreach (const gchar *themepath, /* may be NULL */
|
||||
BThemesForeachFunc callback,
|
||||
gpointer callback_data);
|
||||
|
||||
|
||||
#ifndef B_DISABLE_DEPRECATED
|
||||
|
||||
/* some wrappers that provide the old (pre 1.0) API, don't use */
|
||||
void b_themes_foreach_theme (const gchar *themepath, /* may be NULL */
|
||||
GHFunc callback,
|
||||
gpointer callback_data);
|
||||
BTheme * b_themes_lookup_theme (const gchar *name,
|
||||
const gchar *themepath, /* may be NULL */
|
||||
GError **error);
|
||||
|
||||
#endif /* B_DISABLE_DEPRECATED */
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_THEMES_H__ */
|
|
@ -0,0 +1,41 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
|
||||
GType
|
||||
b_filename_get_type (void)
|
||||
{
|
||||
static GType filename_type = 0;
|
||||
|
||||
if (!filename_type)
|
||||
{
|
||||
static const GTypeInfo type_info = { 0, };
|
||||
|
||||
filename_type = g_type_register_static (G_TYPE_STRING, "BFilename",
|
||||
&type_info, 0);
|
||||
}
|
||||
|
||||
return filename_type;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_TYPES_H__
|
||||
#define __B_TYPES_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
B_KEY_0,
|
||||
B_KEY_1,
|
||||
B_KEY_2,
|
||||
B_KEY_3,
|
||||
B_KEY_4,
|
||||
B_KEY_5,
|
||||
B_KEY_6,
|
||||
B_KEY_7,
|
||||
B_KEY_8,
|
||||
B_KEY_9,
|
||||
B_KEY_HASH,
|
||||
B_KEY_ASTERISK
|
||||
} BModuleKey;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
B_EVENT_TYPE_UNKNOWN = 0,
|
||||
B_EVENT_TYPE_KEY,
|
||||
B_EVENT_TYPE_PLAYER_ENTERED,
|
||||
B_EVENT_TYPE_PLAYER_LEFT
|
||||
} BModuleEventType;
|
||||
|
||||
struct _BColor
|
||||
{
|
||||
guchar a;
|
||||
guchar r;
|
||||
guchar g;
|
||||
guchar b;
|
||||
};
|
||||
|
||||
struct _BRectangle
|
||||
{
|
||||
gint x;
|
||||
gint y;
|
||||
gint w;
|
||||
gint h;
|
||||
};
|
||||
|
||||
typedef struct _BColor BColor;
|
||||
typedef struct _BEffects BEffects;
|
||||
typedef struct _BModule BModule;
|
||||
typedef struct _BModuleEvent BModuleEvent;
|
||||
typedef struct _BModuleInfo BModuleInfo;
|
||||
typedef struct _BMovie BMovie;
|
||||
typedef struct _BMoviePlayer BMoviePlayer;
|
||||
typedef struct _BObject BObject;
|
||||
typedef struct _BPacket BPacket;
|
||||
typedef struct _BParser BParser;
|
||||
typedef struct _BProxyClient BProxyClient;
|
||||
typedef struct _BProxyServer BProxyServer;
|
||||
typedef struct _BReceiver BReceiver;
|
||||
typedef struct _BRectangle BRectangle;
|
||||
typedef struct _BSender BSender;
|
||||
typedef struct _BTheme BTheme;
|
||||
typedef struct _BThemesQuery BThemesQuery;
|
||||
typedef struct _BWriter BWriter;
|
||||
|
||||
|
||||
#define B_TYPE_FILENAME (b_filename_get_type ())
|
||||
#define B_VALUE_HOLDS_FILENAME(value) (G_TYPE_CHECK_VALUE_TYPE ((value), B_TYPE_FILENAME))
|
||||
|
||||
GType b_filename_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_TYPES_H__ */
|
|
@ -0,0 +1,496 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002-2004 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bparams.h"
|
||||
#include "butils.h"
|
||||
|
||||
|
||||
/**
|
||||
* b_filename_from_utf8:
|
||||
* @name: the filename in UTF-8 encoding
|
||||
* @root: an optional path to use
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Convert @name in UTF-8 encoding to a filename in the filesystem's
|
||||
* encoding. If @root is non-%NULL and @name is not an absolute
|
||||
* filename, the returned filename is built using @root as a prefix.
|
||||
*
|
||||
* Return value: a pointer to the newly allocated filename or %NULL in
|
||||
* case of an error. This value must be freed with g_free().
|
||||
**/
|
||||
gchar *
|
||||
b_filename_from_utf8 (const gchar *name,
|
||||
const gchar *root,
|
||||
GError **error)
|
||||
{
|
||||
gchar *filename;
|
||||
GError *conv_error = NULL;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
filename = g_filename_from_utf8 (name, -1, NULL, NULL, &conv_error);
|
||||
|
||||
if (!filename)
|
||||
{
|
||||
const gchar *charset;
|
||||
|
||||
g_get_charset (&charset);
|
||||
|
||||
g_set_error (error, 0, 0,
|
||||
"Couldn't convert filename '%s' to "
|
||||
"your filesystem encoding (%s): %s",
|
||||
name, charset, conv_error->message);
|
||||
g_error_free (conv_error);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (root && !g_path_is_absolute (filename))
|
||||
{
|
||||
gchar *tmp = g_build_filename (root, filename, NULL);
|
||||
g_free (filename);
|
||||
filename = tmp;
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parse_int:
|
||||
* @str: the string to parse
|
||||
* @value: location to store the integer value
|
||||
*
|
||||
* Parse an integer value from a string.
|
||||
*
|
||||
* Return value: %TRUE if the string could be parsed, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_parse_int (const gchar *str,
|
||||
gint *value)
|
||||
{
|
||||
gchar *err;
|
||||
glong l;
|
||||
|
||||
g_return_val_if_fail (str != NULL, FALSE);
|
||||
|
||||
l = strtol (str, &err, 0);
|
||||
|
||||
if (*str && *err)
|
||||
return FALSE;
|
||||
|
||||
if (value)
|
||||
*value = l;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parse_boolean:
|
||||
* @str: the string to parse
|
||||
* @value: location to store the boolean value
|
||||
*
|
||||
* Parse a boolean value from a string.
|
||||
*
|
||||
* Return value: %TRUE if the string could be parsed, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_parse_boolean (const gchar *str,
|
||||
gboolean *value)
|
||||
{
|
||||
g_return_val_if_fail (str != NULL, FALSE);
|
||||
|
||||
if (g_ascii_strcasecmp (str, "yes") == 0)
|
||||
*value = TRUE;
|
||||
else if (g_ascii_strcasecmp (str, "no") == 0)
|
||||
*value = FALSE;
|
||||
else if (g_ascii_strcasecmp (str, "oui") == 0)
|
||||
*value = TRUE;
|
||||
else if (g_ascii_strcasecmp (str, "non") == 0)
|
||||
*value = FALSE;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parse_double:
|
||||
* @str: the string to parse
|
||||
* @value: location to store the double value
|
||||
*
|
||||
* Parse a double (floating-point) value from a string.
|
||||
*
|
||||
* Return value: %TRUE if the string could be parsed, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_parse_double (const gchar *str,
|
||||
gdouble *value)
|
||||
{
|
||||
gchar *end;
|
||||
gdouble d;
|
||||
|
||||
g_return_val_if_fail (str != NULL, FALSE);
|
||||
|
||||
d = g_ascii_strtod (str, &end);
|
||||
|
||||
if (end && *end)
|
||||
return FALSE;
|
||||
|
||||
if (value)
|
||||
*value = d;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parse_coordinates:
|
||||
* @names: a %NULL-terminated array of names
|
||||
* @values: a %NULL-terminated array of values
|
||||
* @x: location to store the value of the x coordinate
|
||||
* @y: location to store the value of the y coordinate
|
||||
*
|
||||
* Parses a pair of name/value arrays looking for the names "x" and "y"
|
||||
* and tries to parse the associated values into integer values.
|
||||
*
|
||||
* Return value: %TRUE if both coordinates could be parsed, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_parse_coordinates (const gchar **names,
|
||||
const gchar **values,
|
||||
gint *x,
|
||||
gint *y)
|
||||
{
|
||||
const gchar **name;
|
||||
const gchar **value;
|
||||
guint f = 0;
|
||||
|
||||
g_return_val_if_fail (names != NULL && values != NULL, FALSE);
|
||||
|
||||
for (name = names, value = values; *name && *value; name++, value++)
|
||||
{
|
||||
if (!(f&1) && strcmp (*name, "x") == 0 && b_parse_int (*value, x))
|
||||
f |= 1;
|
||||
if (!(f&2) && strcmp (*name, "y") == 0 && b_parse_int (*value, y))
|
||||
f |= 2;
|
||||
}
|
||||
|
||||
return (f == (1 | 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parse_rectangle:
|
||||
* @names: a %NULL-terminated array of names
|
||||
* @values: a %NULL-terminated array of values
|
||||
* @rect: pointer to a #BRectangle to store the result
|
||||
*
|
||||
* Parses a pair of name/value arrays looking for the names "x", "y",
|
||||
* "width" and "heigth" and tries to parse the associated values into
|
||||
* a #BRectangle.
|
||||
*
|
||||
* Return value: %TRUE if the rectangle could be parsed, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_parse_rectangle (const gchar **names,
|
||||
const gchar **values,
|
||||
BRectangle *rect)
|
||||
{
|
||||
const gchar **name;
|
||||
const gchar **value;
|
||||
guint f = 0;
|
||||
|
||||
g_return_val_if_fail (names != NULL && values != NULL, FALSE);
|
||||
g_return_val_if_fail (rect != NULL, FALSE);
|
||||
|
||||
for (name = names, value = values; *name && *value; name++, value++)
|
||||
{
|
||||
if (!(f&1) && strcmp (*name, "x") == 0 &&
|
||||
b_parse_int (*value, &rect->x))
|
||||
f |= 1;
|
||||
|
||||
if (!(f&2) && strcmp (*name, "y") == 0 &&
|
||||
b_parse_int (*value, &rect->y))
|
||||
f |= 2;
|
||||
|
||||
if (!(f&4) && strcmp (*name, "width") == 0 &&
|
||||
b_parse_int (*value, &rect->w))
|
||||
f |= 4;
|
||||
|
||||
if (!(f&8) && strcmp (*name, "height") == 0 &&
|
||||
b_parse_int (*value, &rect->h))
|
||||
f |= 8;
|
||||
}
|
||||
|
||||
return (f == (1 | 2 | 4 | 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parse_color:
|
||||
* @names: a %NULL-terminated array of names
|
||||
* @values: a %NULL-terminated array of values
|
||||
* @color: pointer to a #BColor to store the result
|
||||
*
|
||||
* Parses a pair of name/value arrays looking for the name "color" and
|
||||
* tries to convert the associated value to a #BColor. The color value
|
||||
* is expected to be in hexadecimal notation as in HTML.
|
||||
*
|
||||
* Return value: %TRUE if the color could be parsed, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_parse_color (const gchar **names,
|
||||
const gchar **values,
|
||||
BColor *color)
|
||||
{
|
||||
const gchar **name;
|
||||
const gchar **value;
|
||||
|
||||
g_return_val_if_fail (names != NULL && values != NULL, FALSE);
|
||||
g_return_val_if_fail (color != NULL, FALSE);
|
||||
|
||||
for (name = names, value = values; *name && *value; name++, value++)
|
||||
{
|
||||
if (strcmp (*name, "color") == 0 && **value == '#')
|
||||
{
|
||||
gchar *err;
|
||||
guint32 argb = strtoul (*value + 1, &err, 16);
|
||||
|
||||
if (*err)
|
||||
continue;
|
||||
|
||||
color->b = argb & 0xFF; argb >>= 8;
|
||||
color->g = argb & 0xFF; argb >>= 8;
|
||||
color->r = argb & 0xFF; argb >>= 8;
|
||||
|
||||
if (strlen (*value + 1) > 6)
|
||||
color->a = argb & 0xFF;
|
||||
else
|
||||
color->a = 0xFF;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_parse_param:
|
||||
* @object: a #GObject
|
||||
* @root: an optional string to use as root if a filename is set
|
||||
* @names: a %NULL-terminated array of names
|
||||
* @values: a %NULL-terminated array of values
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Parses a pair of name/value arrays looking for the names "key" and
|
||||
* "value". The key/value pair is then used to set the respective object
|
||||
* property by calling b_object_set_property().
|
||||
*
|
||||
* Return value: %TRUE if parsing was successful, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_parse_param (GObject *object,
|
||||
const gchar *root,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
GError **error)
|
||||
{
|
||||
const gchar *key = NULL;
|
||||
const gchar *val = NULL;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
|
||||
g_return_val_if_fail (names != NULL && values != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
for (i = 0; names[i] && values[i]; i++)
|
||||
{
|
||||
if (! strcmp (names[i], "key"))
|
||||
{
|
||||
key = values[i];
|
||||
val = NULL;
|
||||
}
|
||||
else if (! strcmp (names[i], "value"))
|
||||
{
|
||||
if (key)
|
||||
val = values[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!key)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"key attribute is missing for param element");
|
||||
return FALSE;
|
||||
}
|
||||
if (!val)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"value attribute is missing for param element");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return b_object_set_property (object, key, val, root, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_object_set_property:
|
||||
* @object: a #GObject
|
||||
* @key: the name of the property
|
||||
* @value: the property value as a string
|
||||
* @root: an optional string to use as root if a filename property is set
|
||||
* @error: location to store the error occuring, or %NULL to ignore errors
|
||||
*
|
||||
* Sets the object property %key by interpreting the string
|
||||
* @value. This function takes care of converting the string to the
|
||||
* proper type. If the property is a %B_TYPE_FILENAME the filename is
|
||||
* build using the @root parameter.
|
||||
*
|
||||
* Return value: %TRUE on success, %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
b_object_set_property (GObject *object,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
const gchar *root,
|
||||
GError **error)
|
||||
{
|
||||
GObjectClass *class;
|
||||
GParamSpec *spec;
|
||||
GValue gvalue = { 0 };
|
||||
|
||||
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
class = G_OBJECT_GET_CLASS (object);
|
||||
spec = g_object_class_find_property (class, key);
|
||||
|
||||
if (!spec)
|
||||
{
|
||||
g_set_error (error, 0, 0,
|
||||
"%s doesn't have a property named '%s'",
|
||||
G_OBJECT_CLASS_NAME (class), key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (B_IS_PARAM_SPEC_FILENAME (spec))
|
||||
{
|
||||
gchar *filename = b_filename_from_utf8 (value, root, error);
|
||||
|
||||
if (!filename)
|
||||
return FALSE;
|
||||
|
||||
g_value_init (&gvalue, G_TYPE_STRING);
|
||||
g_value_set_string_take_ownership (&gvalue, filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_init (&gvalue, G_TYPE_STRING);
|
||||
g_value_set_static_string (&gvalue, value);
|
||||
}
|
||||
|
||||
g_object_set_property (object, key, &gvalue);
|
||||
|
||||
g_value_unset (&gvalue);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
b_rectangle_union (const BRectangle *src1,
|
||||
const BRectangle *src2,
|
||||
BRectangle *dest)
|
||||
{
|
||||
gint dest_x, dest_y;
|
||||
|
||||
g_return_if_fail (src1 != NULL);
|
||||
g_return_if_fail (src2 != NULL);
|
||||
g_return_if_fail (dest != NULL);
|
||||
|
||||
if (src1->w > 0 && src1->h > 0 && src2->w > 0 && src2->h > 0)
|
||||
{
|
||||
dest_x = MIN (src1->x, src2->x);
|
||||
dest_y = MIN (src1->y, src2->y);
|
||||
|
||||
dest->w = MAX (src1->x + src1->w, src2->x + src2->w) - dest_x;
|
||||
dest->h = MAX (src1->y + src1->h, src2->y + src2->h) - dest_y;
|
||||
dest->x = dest_x;
|
||||
dest->y = dest_y;
|
||||
}
|
||||
else if (src1->w > 0 && src1->h > 0)
|
||||
{
|
||||
*dest = *src1;
|
||||
}
|
||||
else if (src2->w > 0 && src2->h > 0)
|
||||
{
|
||||
*dest = *src2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest->x = dest->y = dest->w = dest->h = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
b_rectangle_intersect (const BRectangle *src1,
|
||||
const BRectangle *src2,
|
||||
BRectangle *dest)
|
||||
{
|
||||
gint dest_x, dest_y;
|
||||
gint dest_w, dest_h;
|
||||
|
||||
g_return_val_if_fail (src1 != NULL, FALSE);
|
||||
g_return_val_if_fail (src2 != NULL, FALSE);
|
||||
|
||||
dest_x = MAX (src1->x, src2->x);
|
||||
dest_y = MAX (src1->y, src2->y);
|
||||
dest_w = MIN (src1->x + src1->w, src2->x + src2->w) - dest_x;
|
||||
dest_h = MIN (src1->y + src1->h, src2->y + src2->h) - dest_y;
|
||||
|
||||
if (dest_w > 0 && dest_h > 0)
|
||||
{
|
||||
if (dest)
|
||||
{
|
||||
dest->x = dest_x;
|
||||
dest->y = dest_y;
|
||||
dest->w = dest_w;
|
||||
dest->h = dest_h;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (dest)
|
||||
{
|
||||
dest->w = 0;
|
||||
dest->h = 0;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2001-2003 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_UTILS_H__
|
||||
#define __B_UTILS_H__
|
||||
|
||||
gchar * b_filename_from_utf8 (const gchar *name,
|
||||
const gchar *root,
|
||||
GError **error);
|
||||
|
||||
gboolean b_parse_int (const gchar *str,
|
||||
gint *value);
|
||||
gboolean b_parse_boolean (const gchar *str,
|
||||
gboolean *value);
|
||||
gboolean b_parse_double (const gchar *str,
|
||||
gdouble *value);
|
||||
gboolean b_parse_coordinates (const gchar **names,
|
||||
const gchar **values,
|
||||
gint *x,
|
||||
gint *y);
|
||||
gboolean b_parse_rectangle (const gchar **names,
|
||||
const gchar **values,
|
||||
BRectangle *rect);
|
||||
gboolean b_parse_color (const gchar **names,
|
||||
const gchar **values,
|
||||
BColor *color);
|
||||
gboolean b_parse_param (GObject *object,
|
||||
const gchar *root,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
GError **error);
|
||||
|
||||
gboolean b_object_set_property (GObject *object,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
const gchar *root,
|
||||
GError **error);
|
||||
|
||||
void b_rectangle_union (const BRectangle *src1,
|
||||
const BRectangle *src2,
|
||||
BRectangle *dest);
|
||||
gboolean b_rectangle_intersect (const BRectangle *src1,
|
||||
const BRectangle *src2,
|
||||
BRectangle *dest);
|
||||
|
||||
#endif /* __B_UTILS_H__ */
|
|
@ -0,0 +1,241 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* Based on code written 2001 for convergence integrated media GmbH.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "btypes.h"
|
||||
#include "bwriter.h"
|
||||
|
||||
struct _BWriter
|
||||
{
|
||||
FILE *stream;
|
||||
gint indent;
|
||||
gint indent_level;
|
||||
};
|
||||
|
||||
|
||||
static void b_write_attributes (BWriter *writer,
|
||||
va_list attributes);
|
||||
static void inline b_write_indent (BWriter *writer);
|
||||
|
||||
|
||||
/**
|
||||
* b_writer_new:
|
||||
* @stream: a FILE stream prepared for writing
|
||||
* @indent: how many characters to indent per nesting level
|
||||
*
|
||||
* Creates a new #BWriter which gives a convenient interface to write
|
||||
* XML data to @stream. The writer should later be freed using
|
||||
* b_writer_free().
|
||||
*
|
||||
* Return value: a newly allocate #BWriter
|
||||
**/
|
||||
BWriter *
|
||||
b_writer_new (FILE *stream,
|
||||
gint indent)
|
||||
{
|
||||
BWriter *writer;
|
||||
|
||||
g_return_val_if_fail (stream != NULL, NULL);
|
||||
g_return_val_if_fail (indent >= 0, NULL);
|
||||
|
||||
writer = g_new0 (BWriter, 1);
|
||||
|
||||
writer->stream = stream;
|
||||
writer->indent = indent;
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* b_writer_free:
|
||||
* @writer: a #BWriter
|
||||
*
|
||||
* Frees the resources allocated for @writer. You must not access
|
||||
* @writer after calling this function.
|
||||
**/
|
||||
void
|
||||
b_writer_free (BWriter *writer)
|
||||
{
|
||||
g_return_if_fail (writer != NULL);
|
||||
|
||||
g_free (writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_write_header:
|
||||
* @writer: a #BWriter
|
||||
* @encoding: an optional encoding string or %NULL
|
||||
*
|
||||
* Writes an XML header to the stream associated with @writer.
|
||||
**/
|
||||
void
|
||||
b_write_header (BWriter *writer,
|
||||
const gchar *encoding)
|
||||
{
|
||||
g_return_if_fail (writer != NULL);
|
||||
|
||||
if (encoding && *encoding)
|
||||
fprintf (writer->stream,
|
||||
"<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
|
||||
else
|
||||
fprintf (writer->stream, "<?xml version=\"1.0\"?>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* b_write_open_tag:
|
||||
* @writer: a #BWriter
|
||||
* @tag: the name of the element to open
|
||||
* @Varargs: an optional key/value pairs interpreted as attributes
|
||||
*
|
||||
* Writes an opening XML tag with the element name @tag to the stream
|
||||
* associated with @writer. You can pass a %NULL-terminated list of
|
||||
* key/value pairs that are written out as attributes.
|
||||
**/
|
||||
void
|
||||
b_write_open_tag (BWriter *writer,
|
||||
const gchar *tag,
|
||||
...)
|
||||
{
|
||||
va_list attributes;
|
||||
|
||||
g_return_if_fail (writer != NULL);
|
||||
g_return_if_fail (tag != NULL);
|
||||
|
||||
va_start (attributes, tag);
|
||||
|
||||
b_write_indent (writer);
|
||||
|
||||
fprintf (writer->stream, "<%s", tag);
|
||||
b_write_attributes (writer, attributes);
|
||||
fprintf (writer->stream, ">\n");
|
||||
|
||||
writer->indent_level++;
|
||||
|
||||
va_end (attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_write_close_tag:
|
||||
* @writer: a #BWriter
|
||||
* @tag: the name of the element to close
|
||||
*
|
||||
* Writes a closing XML tag with the element name @tag to the stream
|
||||
* associated with @writer.
|
||||
**/
|
||||
void
|
||||
b_write_close_tag (BWriter *writer,
|
||||
const gchar *tag)
|
||||
{
|
||||
g_return_if_fail (writer != NULL);
|
||||
g_return_if_fail (tag != NULL);
|
||||
|
||||
writer->indent_level--;
|
||||
b_write_indent (writer);
|
||||
|
||||
fprintf (writer->stream, "</%s>\n", tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* b_write_element:
|
||||
* @writer: a #BWriter
|
||||
* @tag: the element name
|
||||
* @value: the element value
|
||||
* @Varargs: an optional key/value pairs interpreted as attributes
|
||||
*
|
||||
* Writes an XML element with the name @tag and the value @value to
|
||||
* the stream associated with @writer. If @value is %NULL, an empty
|
||||
* element is written. You can pass a %NULL-terminated list of
|
||||
* key/value pairs that are written out as attributes.
|
||||
**/
|
||||
void
|
||||
b_write_element (BWriter *writer,
|
||||
const gchar *tag,
|
||||
const gchar *value,
|
||||
...)
|
||||
{
|
||||
va_list attributes;
|
||||
|
||||
g_return_if_fail (writer != NULL);
|
||||
g_return_if_fail (tag != NULL);
|
||||
|
||||
va_start (attributes, value);
|
||||
|
||||
b_write_indent (writer);
|
||||
|
||||
fprintf (writer->stream, "<%s", tag);
|
||||
b_write_attributes (writer, attributes);
|
||||
|
||||
if (value)
|
||||
{
|
||||
gchar *escaped = g_markup_escape_text (value, strlen (value));
|
||||
fprintf (writer->stream, ">%s</%s>\n", escaped, tag);
|
||||
g_free (escaped);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (writer->stream, "/>\n");
|
||||
}
|
||||
|
||||
va_end (attributes);
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
b_write_attributes (BWriter *writer,
|
||||
va_list attributes)
|
||||
{
|
||||
const gchar *name;
|
||||
const gchar *attribute;
|
||||
|
||||
name = va_arg (attributes, const gchar *);
|
||||
|
||||
while (name)
|
||||
{
|
||||
attribute = va_arg (attributes, const gchar *);
|
||||
|
||||
fprintf (writer->stream, " %s=\"%s\"", name, attribute);
|
||||
|
||||
name = va_arg (attributes, const gchar *);
|
||||
}
|
||||
}
|
||||
|
||||
static const gchar *spaces = " "; /* 16 spaces */
|
||||
|
||||
static inline void
|
||||
b_write_indent (BWriter *writer)
|
||||
{
|
||||
gint indent = writer->indent * writer->indent_level;
|
||||
|
||||
while (indent > 16)
|
||||
{
|
||||
fprintf (writer->stream, spaces);
|
||||
indent -= 16;
|
||||
}
|
||||
fprintf (writer->stream, spaces + 16 - indent);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (C) 2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __B_WRITER_H__
|
||||
#define __B_WRITER_H__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
BWriter * b_writer_new (FILE *stream,
|
||||
gint indent);
|
||||
void b_writer_free (BWriter *writer);
|
||||
|
||||
void b_write_header (BWriter *writer,
|
||||
const gchar *encoding);
|
||||
void b_write_open_tag (BWriter *writer,
|
||||
const gchar *tag,
|
||||
...);
|
||||
void b_write_close_tag (BWriter *writer,
|
||||
const gchar *tag);
|
||||
void b_write_element (BWriter *writer,
|
||||
const gchar *tag,
|
||||
const gchar *value,
|
||||
...);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __B_WRITER_H__ */
|
|
@ -0,0 +1,643 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* GIF loading routines stripped out of the GIF loading filter for The GIMP.
|
||||
*
|
||||
* Modified for blinkentools in 2001 by Sven Neumann <sven@gimp.org>.
|
||||
* Included into blib in 2002 by Sven Neumann <sven@gimp.org>.
|
||||
*
|
||||
* GIMP plug-in written by Adam D. Moss <adam@gimp.org> <adam@foxbox.org>
|
||||
*
|
||||
* Based around original GIF code by David Koblas.
|
||||
*
|
||||
* This filter uses code taken from the "giftopnm" and "ppmtogif" programs
|
||||
* which are part of the "netpbm" package.
|
||||
*
|
||||
*
|
||||
* "The Graphics Interchange Format(c) is the Copyright property of
|
||||
* CompuServe Incorporated. GIF(sm) is a Service Mark property of
|
||||
* CompuServe Incorporated."
|
||||
*/
|
||||
|
||||
/* Copyright notice for GIF code from which this plugin was long ago *
|
||||
* derived (David Koblas has granted permission to relicense): *
|
||||
* +-------------------------------------------------------------------+ *
|
||||
* | Copyright 1990, 1991, 1993, David Koblas. (koblas@extra.com) | *
|
||||
* +-------------------------------------------------------------------+ */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gif-load.h"
|
||||
|
||||
|
||||
#define MAX_LZW_BITS 12
|
||||
|
||||
#define INTERLACE 0x40
|
||||
#define LOCALCOLORMAP 0x80
|
||||
#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
|
||||
|
||||
#define LM_to_uint(a,b) (((b)<<8)|(a))
|
||||
|
||||
|
||||
static int ReadColorMap (GIOChannel *io,
|
||||
int number,
|
||||
unsigned char *buffer);
|
||||
static int GetDataBlock (GIOChannel *io,
|
||||
unsigned char *buf);
|
||||
static int GetCode (GIOChannel *io,
|
||||
int code_size,
|
||||
int flag);
|
||||
static int LZWReadByte (GIOChannel *io,
|
||||
int flag,
|
||||
int input_code_size);
|
||||
|
||||
|
||||
static gboolean
|
||||
ReadOK (GIOChannel *io,
|
||||
gchar *buffer,
|
||||
gsize len)
|
||||
{
|
||||
while (len > 0)
|
||||
{
|
||||
GIOStatus status;
|
||||
gsize bytes;
|
||||
|
||||
status = g_io_channel_read_chars (io, buffer, len, &bytes, NULL);
|
||||
|
||||
if (status == G_IO_STATUS_ERROR || status == G_IO_STATUS_EOF)
|
||||
break;
|
||||
|
||||
len -= bytes;
|
||||
}
|
||||
|
||||
return (len == 0);
|
||||
}
|
||||
|
||||
int
|
||||
GIFDecodeHeader (GIOChannel *io,
|
||||
gboolean skip_magic,
|
||||
int *Width,
|
||||
int *Height,
|
||||
int *Background,
|
||||
int *colors,
|
||||
unsigned char **cmap)
|
||||
{
|
||||
int AspectRatio;
|
||||
unsigned char buf[16];
|
||||
char version[4];
|
||||
|
||||
if (!skip_magic)
|
||||
{
|
||||
if (!ReadOK (io, buf, 6))
|
||||
{
|
||||
fprintf (stderr, "GIF: error reading magic number\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp ((char *) buf, "GIF", 3) != 0)
|
||||
{
|
||||
fprintf (stderr, "GIF: not a GIF file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy (version, (char *) buf + 3, 3);
|
||||
version[3] = '\0';
|
||||
|
||||
if ((strcmp (version, "87a") != 0) && (strcmp (version, "89a") != 0))
|
||||
{
|
||||
fprintf (stderr, "GIF: bad version number, not '87a' or '89a'\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ReadOK (io, buf, 7))
|
||||
{
|
||||
fprintf (stderr, "GIF: failed to read screen descriptor\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*Width = LM_to_uint (buf[0], buf[1]);
|
||||
*Height = LM_to_uint (buf[2], buf[3]);
|
||||
*colors = 2 << (buf[4] & 0x07);
|
||||
if (Background)
|
||||
*Background = buf[5];
|
||||
|
||||
AspectRatio = buf[6];
|
||||
if (AspectRatio != 0 && AspectRatio != 49)
|
||||
fprintf (stderr, "GIF: warning - non-square pixels\n");
|
||||
|
||||
*cmap = NULL;
|
||||
|
||||
if (BitSet (buf[4], LOCALCOLORMAP))
|
||||
{
|
||||
guchar *colormap;
|
||||
|
||||
colormap = g_new0 (guchar, 3 * *colors);
|
||||
|
||||
/* Global Colormap */
|
||||
if (!ReadColorMap (io, *colors, colormap))
|
||||
{
|
||||
fprintf (stderr, "GIF: error reading global colormap\n");
|
||||
g_free (colormap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*cmap = colormap;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
GIFDecodeRecordType (GIOChannel *io,
|
||||
GIFRecordType *type)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
if (!ReadOK (io, &c, 1))
|
||||
{
|
||||
fprintf (stderr, "GIF: EOF / read error on image data\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case ',':
|
||||
*type = IMAGE;
|
||||
return 1;
|
||||
|
||||
case '!':
|
||||
if (!ReadOK (io, &c, 1))
|
||||
{
|
||||
fprintf (stderr, "GIF: EOF / read error on extension function code\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0xf9:
|
||||
*type = GRAPHIC_CONTROL_EXTENSION;
|
||||
break;
|
||||
case 0xfe:
|
||||
*type = COMMENT_EXTENSION;
|
||||
break;
|
||||
case 0x01: /* PLAINTEXT_EXTENSION */
|
||||
case 0xff: /* APPLICATION_EXTENSION */
|
||||
*type = UNKNOWN_EXTENSION;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
case ';':
|
||||
*type = TERMINATOR;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "GIF: bogus character 0x%02x, ignoring\n", c);
|
||||
return GIFDecodeRecordType (io, type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
GIFDecodeImage (GIOChannel *io,
|
||||
int *Width,
|
||||
int *Height,
|
||||
int *offx,
|
||||
int *offy,
|
||||
int *colors,
|
||||
unsigned char **cmap,
|
||||
unsigned char *data)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
unsigned char c;
|
||||
unsigned char *dest;
|
||||
int local_cmap;
|
||||
int interlace;
|
||||
int v;
|
||||
int width, height;
|
||||
int xpos = 0, ypos = 0, pass = 0;
|
||||
|
||||
if (!ReadOK (io, buf, 9))
|
||||
{
|
||||
fprintf (stderr, "GIF: couldn't read image data\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*colors = 0;
|
||||
*cmap = NULL;
|
||||
|
||||
local_cmap = BitSet (buf[8], LOCALCOLORMAP);
|
||||
|
||||
if (local_cmap)
|
||||
{
|
||||
guchar *colormap;
|
||||
|
||||
*colors = 2 << (buf[8] & 0x07);
|
||||
colormap = g_new0 (guchar, 3 * *colors);
|
||||
|
||||
if (!ReadColorMap (io, *colors, colormap))
|
||||
{
|
||||
g_free (colormap);
|
||||
fprintf (stderr, "GIF: error reading local colormap\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*cmap = colormap;
|
||||
}
|
||||
|
||||
*Width = width = LM_to_uint (buf[4], buf[5]);
|
||||
*Height = height = LM_to_uint (buf[6], buf[7]);
|
||||
*offx = LM_to_uint (buf[0], buf[1]);
|
||||
*offy = LM_to_uint (buf[2], buf[3]);
|
||||
|
||||
interlace = BitSet (buf[8], INTERLACE);
|
||||
|
||||
if (!ReadOK (io, &c, 1))
|
||||
{
|
||||
fprintf (stderr, "GIF: EOF / read error on image data\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (LZWReadByte (io, 1, c) < 0)
|
||||
{
|
||||
fprintf (stderr, "GIF: error while reading\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
while ((v = LZWReadByte (io, 0, c)) >= 0)
|
||||
{
|
||||
dest = data + (ypos * width) + xpos;
|
||||
*dest = (unsigned char) v;
|
||||
|
||||
xpos++;
|
||||
if (xpos == width)
|
||||
{
|
||||
xpos = 0;
|
||||
if (interlace)
|
||||
{
|
||||
switch (pass)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
ypos += 8;
|
||||
break;
|
||||
case 2:
|
||||
ypos += 4;
|
||||
break;
|
||||
case 3:
|
||||
ypos += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ypos >= height)
|
||||
{
|
||||
pass++;
|
||||
switch (pass)
|
||||
{
|
||||
case 1:
|
||||
ypos = 4;
|
||||
break;
|
||||
case 2:
|
||||
ypos = 2;
|
||||
break;
|
||||
case 3:
|
||||
ypos = 1;
|
||||
break;
|
||||
default:
|
||||
goto fini;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ypos++;
|
||||
}
|
||||
}
|
||||
if (ypos >= height)
|
||||
break;
|
||||
}
|
||||
|
||||
fini:
|
||||
if (LZWReadByte (io, 0, c) >= 0)
|
||||
fprintf (stderr, "GIF: too much input data, ignoring extra...\n");
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
g_free (*cmap);
|
||||
*cmap = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
GIFDecodeGraphicControlExt (GIOChannel *io,
|
||||
GIFDisposeType *Disposal,
|
||||
int *Delay,
|
||||
int *Transparent)
|
||||
{
|
||||
unsigned char buf[256];
|
||||
|
||||
if (GetDataBlock (io, buf) < 4)
|
||||
return 0;
|
||||
|
||||
*Disposal = (buf[0] >> 2) & 0x7;
|
||||
*Delay = LM_to_uint (buf[1], buf[2]) * 10; /* the external API is ms */
|
||||
|
||||
if ((buf[0] & 0x1) != 0)
|
||||
*Transparent = buf[3];
|
||||
else
|
||||
*Transparent = -1;
|
||||
|
||||
while (GetDataBlock (io, buf) > 0)
|
||||
;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
GIFDecodeCommentExt (GIOChannel *io,
|
||||
char **comment)
|
||||
{
|
||||
gchar buf[256];
|
||||
gint comment_len;
|
||||
gint len;
|
||||
|
||||
*comment = NULL;
|
||||
comment_len = 0;
|
||||
|
||||
while ((len = GetDataBlock (io, (unsigned char *) buf)) > 0)
|
||||
{
|
||||
*comment = g_realloc (*comment, comment_len + len + 1);
|
||||
strncpy (*comment + comment_len, buf, len);
|
||||
comment_len += len;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
GIFDecodeUnknownExt (GIOChannel *io)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
while (GetDataBlock (io, buf) > 0)
|
||||
;
|
||||
}
|
||||
|
||||
static int
|
||||
ReadColorMap (GIOChannel *io,
|
||||
int number,
|
||||
unsigned char *cmap)
|
||||
{
|
||||
int i;
|
||||
unsigned char rgb[3];
|
||||
|
||||
for (i = 0; i < number; ++i)
|
||||
{
|
||||
if (!ReadOK (io, rgb, sizeof (rgb)))
|
||||
{
|
||||
fprintf (stderr, "GIF: bad colormap\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*cmap++ = rgb[0];
|
||||
*cmap++ = rgb[1];
|
||||
*cmap++ = rgb[2];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int ZeroDataBlock = 0;
|
||||
|
||||
static int
|
||||
GetDataBlock (GIOChannel *io,
|
||||
unsigned char *buf)
|
||||
{
|
||||
unsigned char count;
|
||||
|
||||
if (!ReadOK (io, &count, 1))
|
||||
{
|
||||
fprintf (stderr, "GIF: error in getting DataBlock size\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ZeroDataBlock = count == 0;
|
||||
|
||||
if ((count != 0) && (!ReadOK (io, buf, count)))
|
||||
{
|
||||
fprintf (stderr, "GIF: error in reading DataBlock\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int
|
||||
GetCode (GIOChannel *io,
|
||||
int code_size,
|
||||
int flag)
|
||||
{
|
||||
static unsigned char buf[280];
|
||||
static int curbit, lastbit, done, last_byte;
|
||||
int i, j, ret;
|
||||
unsigned char count;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
curbit = 0;
|
||||
lastbit = 0;
|
||||
done = 0;
|
||||
last_byte = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((curbit + code_size) >= lastbit)
|
||||
{
|
||||
if (done)
|
||||
{
|
||||
if (curbit >= lastbit)
|
||||
fprintf (stderr, "GIF: ran off the end of my bits\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = buf[last_byte - 2];
|
||||
buf[1] = buf[last_byte - 1];
|
||||
|
||||
if ((count = GetDataBlock (io, &buf[2])) <= 0)
|
||||
done = 1;
|
||||
|
||||
last_byte = 2 + count;
|
||||
curbit = (curbit - lastbit) + 16;
|
||||
lastbit = (2 + count) * 8;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
for (i = curbit, j = 0; j < code_size; ++i, ++j)
|
||||
ret |= ((buf[i / 8] & (1 << (i % 8))) != 0) << j;
|
||||
|
||||
curbit += code_size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
LZWReadByte (GIOChannel *io,
|
||||
int flag,
|
||||
int input_code_size)
|
||||
{
|
||||
static int fresh = 0;
|
||||
int code, incode;
|
||||
static int code_size, set_code_size;
|
||||
static int max_code, max_code_size;
|
||||
static int firstcode, oldcode;
|
||||
static int clear_code, end_code;
|
||||
static int table[2][(1 << MAX_LZW_BITS)];
|
||||
static int stack[(1 << (MAX_LZW_BITS)) * 2], *sp;
|
||||
register int i;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
set_code_size = input_code_size;
|
||||
code_size = set_code_size + 1;
|
||||
clear_code = 1 << set_code_size;
|
||||
end_code = clear_code + 1;
|
||||
max_code_size = 2 * clear_code;
|
||||
max_code = clear_code + 2;
|
||||
|
||||
GetCode (io, 0, 1);
|
||||
|
||||
fresh = 1;
|
||||
|
||||
for (i = 0; i < clear_code; ++i)
|
||||
{
|
||||
table[0][i] = 0;
|
||||
table[1][i] = i;
|
||||
}
|
||||
for (; i < (1 << MAX_LZW_BITS); ++i)
|
||||
table[0][i] = table[1][0] = 0;
|
||||
|
||||
sp = stack;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (fresh)
|
||||
{
|
||||
fresh = 0;
|
||||
do
|
||||
{
|
||||
firstcode = oldcode =
|
||||
GetCode (io, code_size, 0);
|
||||
}
|
||||
while (firstcode == clear_code);
|
||||
return firstcode;
|
||||
}
|
||||
|
||||
if (sp > stack)
|
||||
return *--sp;
|
||||
|
||||
while ((code = GetCode (io, code_size, 0)) >= 0)
|
||||
{
|
||||
if (code == clear_code)
|
||||
{
|
||||
for (i = 0; i < clear_code; ++i)
|
||||
{
|
||||
table[0][i] = 0;
|
||||
table[1][i] = i;
|
||||
}
|
||||
for (; i < (1 << MAX_LZW_BITS); ++i)
|
||||
table[0][i] = table[1][i] = 0;
|
||||
code_size = set_code_size + 1;
|
||||
max_code_size = 2 * clear_code;
|
||||
max_code = clear_code + 2;
|
||||
sp = stack;
|
||||
firstcode = oldcode =
|
||||
GetCode (io, code_size, 0);
|
||||
return firstcode;
|
||||
}
|
||||
else if (code == end_code)
|
||||
{
|
||||
int count;
|
||||
unsigned char buf[260];
|
||||
|
||||
if (ZeroDataBlock)
|
||||
return -2;
|
||||
|
||||
while ((count = GetDataBlock (io, buf)) > 0)
|
||||
;
|
||||
|
||||
if (count != 0)
|
||||
fprintf (stderr,
|
||||
"GIF: missing EOD in data stream (common occurence)");
|
||||
return -2;
|
||||
}
|
||||
|
||||
incode = code;
|
||||
|
||||
if (code >= max_code)
|
||||
{
|
||||
*sp++ = firstcode;
|
||||
code = oldcode;
|
||||
}
|
||||
|
||||
while (code >= clear_code)
|
||||
{
|
||||
*sp++ = table[1][code];
|
||||
if (code == table[0][code])
|
||||
{
|
||||
fprintf (stderr, "GIF: circular table entry BIG ERROR\n");
|
||||
return -2;
|
||||
}
|
||||
code = table[0][code];
|
||||
}
|
||||
|
||||
*sp++ = firstcode = table[1][code];
|
||||
|
||||
if ((code = max_code) < (1 << MAX_LZW_BITS))
|
||||
{
|
||||
table[0][code] = oldcode;
|
||||
table[1][code] = firstcode;
|
||||
++max_code;
|
||||
if ((max_code >= max_code_size) &&
|
||||
(max_code_size < (1 << MAX_LZW_BITS)))
|
||||
{
|
||||
max_code_size *= 2;
|
||||
++code_size;
|
||||
}
|
||||
}
|
||||
|
||||
oldcode = incode;
|
||||
|
||||
if (sp > stack)
|
||||
return *--sp;
|
||||
}
|
||||
return code;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* GIF loading routines stripped out of the GIF loading filter for The GIMP.
|
||||
*
|
||||
* Modified for blinkentools in 2001 by Sven Neumann <sven@gimp.org>.
|
||||
* Included into blib in 2002 by Sven Neumann <sven@gimp.org>.
|
||||
*
|
||||
* GIMP plug-in written by Adam D. Moss <adam@gimp.org> <adam@foxbox.org>
|
||||
*
|
||||
* Based around original GIF code by David Koblas.
|
||||
*
|
||||
* This filter uses code taken from the "giftopnm" and "ppmtogif" programs
|
||||
* which are part of the "netpbm" package.
|
||||
*
|
||||
* "The Graphics Interchange Format(c) is the Copyright property of
|
||||
* CompuServe Incorporated. GIF(sm) is a Service Mark property of
|
||||
* CompuServe Incorporated."
|
||||
*/
|
||||
|
||||
/* Copyright notice for GIF code from which this plugin was long ago *
|
||||
* derived (David Koblas has granted permission to relicense): *
|
||||
* +-------------------------------------------------------------------+ *
|
||||
* | Copyright 1990, 1991, 1993, David Koblas. (koblas@extra.com) | *
|
||||
* +-------------------------------------------------------------------+ */
|
||||
|
||||
|
||||
#ifndef __GIF_LOAD_H__
|
||||
#define __GIF_LOAD_H__
|
||||
|
||||
#include <blib/gif-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
int GIFDecodeHeader (GIOChannel *io,
|
||||
gboolean skip_magic,
|
||||
int *Width,
|
||||
int *Height,
|
||||
int *Background,
|
||||
int *colors,
|
||||
unsigned char **cmap);
|
||||
int GIFDecodeRecordType (GIOChannel *io,
|
||||
GIFRecordType *type);
|
||||
int GIFDecodeImage (GIOChannel *io,
|
||||
int *Width,
|
||||
int *Height,
|
||||
int *offx,
|
||||
int *offy,
|
||||
int *colors,
|
||||
unsigned char **cmap,
|
||||
unsigned char *data);
|
||||
int GIFDecodeGraphicControlExt (GIOChannel *io,
|
||||
GIFDisposeType *Disposal,
|
||||
int *Delay,
|
||||
int *Transparent);
|
||||
int GIFDecodeCommentExt (GIOChannel *io,
|
||||
char **comment);
|
||||
void GIFDecodeUnknownExt (GIOChannel *io);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GIF_LOAD_H__ */
|
|
@ -0,0 +1,736 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* GIF savinging routines stripped out of the GIF saving filter for The GIMP.
|
||||
*
|
||||
* Modified for blinkentools in 2001 by Sven Neumann <sven@gimp.org>.
|
||||
* Included into blib in 2002 by Sven Neumann <sven@gimp.org>.
|
||||
*
|
||||
* GIMP plug-in written by Adam D. Moss <adam@gimp.org> <adam@foxbox.org>
|
||||
*
|
||||
* Based around original GIF code by David Koblas.
|
||||
*
|
||||
* This filter uses code taken from the "giftopnm" and "ppmtogif" programs
|
||||
* which are part of the "netpbm" package.
|
||||
*
|
||||
* "The Graphics Interchange Format(c) is the Copyright property of
|
||||
* CompuServe Incorporated. GIF(sm) is a Service Mark property of
|
||||
* CompuServe Incorporated."
|
||||
*/
|
||||
|
||||
/* Copyright notice for GIF code from which this plugin was long ago *
|
||||
* derived (David Koblas has granted permission to relicense): *
|
||||
* +-------------------------------------------------------------------+ *
|
||||
* | Copyright 1990, 1991, 1993, David Koblas. (koblas@extra.com) | *
|
||||
* +-------------------------------------------------------------------+ */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gif-save.h"
|
||||
|
||||
|
||||
static int GIFNextPixel (void);
|
||||
|
||||
/*
|
||||
* a code_int must be able to hold 2**BITS values of type int, and also -1
|
||||
*/
|
||||
typedef int code_int;
|
||||
typedef long int count_int;
|
||||
|
||||
|
||||
unsigned char *pixels;
|
||||
|
||||
static void Putword (int, FILE *);
|
||||
static void compress (int, FILE *);
|
||||
static void output (code_int);
|
||||
static void cl_block (void);
|
||||
static void cl_hash (count_int);
|
||||
static void writeerr (void);
|
||||
static void char_init (void);
|
||||
static void char_out (int);
|
||||
static void flush_char (void);
|
||||
|
||||
|
||||
static long CountDown;
|
||||
|
||||
/*
|
||||
* Return the next pixel from the image
|
||||
*/
|
||||
int
|
||||
GIFNextPixel (void)
|
||||
{
|
||||
if (CountDown == 0)
|
||||
return EOF;
|
||||
|
||||
--CountDown;
|
||||
|
||||
return *pixels++;
|
||||
}
|
||||
|
||||
/* public */
|
||||
|
||||
void
|
||||
GIFEncodeHeader (FILE *fp,
|
||||
int gif89,
|
||||
int Width,
|
||||
int Height,
|
||||
int Background,
|
||||
int BitsPerPixel,
|
||||
char *cmap)
|
||||
{
|
||||
int B;
|
||||
int Resolution;
|
||||
int ColorMapSize;
|
||||
int i;
|
||||
|
||||
ColorMapSize = 1 << BitsPerPixel;
|
||||
|
||||
Resolution = BitsPerPixel;
|
||||
|
||||
/*
|
||||
* Write the Magic header
|
||||
*/
|
||||
fwrite (gif89 ? "GIF89a" : "GIF87a", 1, 6, fp);
|
||||
|
||||
/*
|
||||
* Write out the screen width and height
|
||||
*/
|
||||
Putword (Width, fp);
|
||||
Putword (Height, fp);
|
||||
|
||||
/*
|
||||
* Indicate that there is a global colour map
|
||||
*/
|
||||
B = 0x80; /* Yes, there is a color map */
|
||||
|
||||
/*
|
||||
* OR in the resolution
|
||||
*/
|
||||
B |= (Resolution - 1) << 5;
|
||||
|
||||
/*
|
||||
* OR in the Bits per Pixel
|
||||
*/
|
||||
B |= (BitsPerPixel - 1);
|
||||
|
||||
/*
|
||||
* Write it out
|
||||
*/
|
||||
fputc (B, fp);
|
||||
|
||||
/*
|
||||
* Write out the Background colour
|
||||
*/
|
||||
fputc (Background, fp);
|
||||
|
||||
/*
|
||||
* Byte of 0's (future expansion)
|
||||
*/
|
||||
fputc (0, fp);
|
||||
|
||||
/*
|
||||
* Write out the Global Colour Map
|
||||
*/
|
||||
for (i = 0; i < 3 * ColorMapSize; i++)
|
||||
fputc (cmap[i], fp);
|
||||
}
|
||||
|
||||
void
|
||||
GIFEncodeGraphicControlExt (FILE *fp,
|
||||
GIFDisposeType Disposal,
|
||||
int Delay,
|
||||
int Animation,
|
||||
int Transparent)
|
||||
{
|
||||
Delay /= 10; /* the external API is ms */
|
||||
|
||||
/*
|
||||
* Write out extension for transparent colour index, if necessary.
|
||||
*/
|
||||
if ( (Transparent >= 0) || (Animation) )
|
||||
{
|
||||
/* Extension Introducer - fixed. */
|
||||
fputc ('!', fp);
|
||||
/* Graphic Control Label - fixed. */
|
||||
fputc (0xf9, fp);
|
||||
/* Block Size - fixed. */
|
||||
fputc (4, fp);
|
||||
|
||||
/* Packed Fields - XXXdddut (d=disposal, u=userInput, t=transFlag) */
|
||||
/* s8421 */
|
||||
fputc ( ((Transparent >= 0) ? 0x01 : 0x00) /* TRANSPARENCY */
|
||||
|
||||
/* DISPOSAL */
|
||||
| (Animation ? (Disposal << 2) : 0x00),
|
||||
/* 0x03 or 0x01 build frames cumulatively */
|
||||
/* 0x02 clears frame before drawing */
|
||||
/* 0x00 'don't care' */
|
||||
|
||||
fp);
|
||||
|
||||
fputc (Delay & 255, fp);
|
||||
fputc ((Delay>>8) & 255, fp);
|
||||
|
||||
fputc (Transparent, fp);
|
||||
fputc (0, fp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIFEncodeImageData (FILE *fp,
|
||||
int Width,
|
||||
int Height,
|
||||
int BitsPerPixel,
|
||||
int offset_x,
|
||||
int offset_y,
|
||||
char *data)
|
||||
{
|
||||
int Resolution;
|
||||
int ColorMapSize;
|
||||
int InitCodeSize;
|
||||
|
||||
ColorMapSize = 1 << BitsPerPixel;
|
||||
|
||||
Resolution = BitsPerPixel;
|
||||
|
||||
/*
|
||||
* Calculate number of bits we are expecting
|
||||
*/
|
||||
CountDown = (long) Width * (long) Height;
|
||||
pixels = data;
|
||||
|
||||
/*
|
||||
* The initial code size
|
||||
*/
|
||||
if (BitsPerPixel <= 1)
|
||||
InitCodeSize = 2;
|
||||
else
|
||||
InitCodeSize = BitsPerPixel;
|
||||
|
||||
/*
|
||||
* Write an Image separator
|
||||
*/
|
||||
fputc (',', fp);
|
||||
|
||||
/*
|
||||
* Write the Image header
|
||||
*/
|
||||
Putword (offset_x, fp);
|
||||
Putword (offset_y, fp);
|
||||
Putword (Width, fp);
|
||||
Putword (Height, fp);
|
||||
|
||||
/* no interlacing */
|
||||
fputc (0x0, fp);
|
||||
|
||||
/*
|
||||
* Write out the initial code size
|
||||
*/
|
||||
fputc (InitCodeSize, fp);
|
||||
|
||||
/*
|
||||
* Go and actually compress the data
|
||||
*/
|
||||
compress (InitCodeSize + 1, fp);
|
||||
|
||||
/*
|
||||
* Write out a Zero-length packet (to end the series)
|
||||
*/
|
||||
fputc (0x0, fp);
|
||||
}
|
||||
|
||||
void
|
||||
GIFEncodeClose (FILE *fp)
|
||||
{
|
||||
/*
|
||||
* Write the GIF file terminator
|
||||
*/
|
||||
fputc (';', fp);
|
||||
|
||||
/*
|
||||
* And close the file
|
||||
*/
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
void
|
||||
GIFEncodeLoopExt (FILE *fp,
|
||||
int num_loops)
|
||||
{
|
||||
fputc(0x21,fp);
|
||||
fputc(0xff,fp);
|
||||
fputc(0x0b,fp);
|
||||
fputs("NETSCAPE2.0",fp);
|
||||
fputc(0x03,fp);
|
||||
fputc(0x01,fp);
|
||||
Putword(num_loops,fp);
|
||||
fputc(0x00,fp);
|
||||
|
||||
/* NOTE: num_loops==0 means 'loop infinitely' */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GIFEncodeCommentExt (FILE *fp,
|
||||
char *comment)
|
||||
{
|
||||
if (!comment || !*comment)
|
||||
return;
|
||||
|
||||
if (strlen(comment)>240)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"GIF: warning: comment too large - comment block not written.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fputc(0x21,fp);
|
||||
fputc(0xfe,fp);
|
||||
fputc(strlen(comment),fp);
|
||||
fputs((const char *)comment,fp);
|
||||
fputc(0x00,fp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Write out a word to the GIF file
|
||||
*/
|
||||
static void
|
||||
Putword (int w,
|
||||
FILE *fp)
|
||||
{
|
||||
fputc (w & 0xff, fp);
|
||||
fputc ((w / 256) & 0xff, fp);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* GIFCOMPR.C - GIF Image compression routines
|
||||
*
|
||||
* Lempel-Ziv compression based on 'compress'. GIF modifications by
|
||||
* David Rowley (mgardi@watdcsu.waterloo.edu)
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* General DEFINEs
|
||||
*/
|
||||
|
||||
#define GIF_BITS 12
|
||||
|
||||
#define HSIZE 5003 /* 80% occupancy */
|
||||
|
||||
#ifdef NO_UCHAR
|
||||
typedef char char_type;
|
||||
#else /*NO_UCHAR */
|
||||
typedef unsigned char char_type;
|
||||
#endif /*NO_UCHAR */
|
||||
|
||||
/*
|
||||
|
||||
* GIF Image compression - modified 'compress'
|
||||
*
|
||||
* Based on: compress.c - File compression ala IEEE Computer, June 1984.
|
||||
*
|
||||
* By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
|
||||
* Jim McKie (decvax!mcvax!jim)
|
||||
* Steve Davies (decvax!vax135!petsd!peora!srd)
|
||||
* Ken Turkowski (decvax!decwrl!turtlevax!ken)
|
||||
* James A. Woods (decvax!ihnp4!ames!jaw)
|
||||
* Joe Orost (decvax!vax135!petsd!joe)
|
||||
*
|
||||
*/
|
||||
#include <ctype.h>
|
||||
|
||||
#define ARGVAL() (*++(*argv) || (--argc && *++argv))
|
||||
|
||||
static int n_bits; /* number of bits/code */
|
||||
static int maxbits = GIF_BITS; /* user settable max # bits/code */
|
||||
static code_int maxcode; /* maximum code, given n_bits */
|
||||
static code_int maxmaxcode = (code_int) 1 << GIF_BITS; /* should NEVER generate this code */
|
||||
#ifdef COMPATIBLE /* But wrong! */
|
||||
#define MAXCODE(Mn_bits) ((code_int) 1 << (Mn_bits) - 1)
|
||||
#else /*COMPATIBLE */
|
||||
#define MAXCODE(Mn_bits) (((code_int) 1 << (Mn_bits)) - 1)
|
||||
#endif /*COMPATIBLE */
|
||||
|
||||
static count_int htab[HSIZE];
|
||||
static unsigned short codetab[HSIZE];
|
||||
#define HashTabOf(i) htab[i]
|
||||
#define CodeTabOf(i) codetab[i]
|
||||
|
||||
const code_int hsize = HSIZE; /* the original reason for this being
|
||||
variable was "for dynamic table sizing",
|
||||
but since it was never actually changed
|
||||
I made it const --Adam. */
|
||||
|
||||
/*
|
||||
* To save much memory, we overlay the table used by compress() with those
|
||||
* used by decompress(). The tab_prefix table is the same size and type
|
||||
* as the codetab. The tab_suffix table needs 2**GIF_BITS characters. We
|
||||
* get this from the beginning of htab. The output stack uses the rest
|
||||
* of htab, and contains characters. There is plenty of room for any
|
||||
* possible stack (stack used to be 8000 characters).
|
||||
*/
|
||||
|
||||
#define tab_prefixof(i) CodeTabOf(i)
|
||||
#define tab_suffixof(i) ((char_type*)(htab))[i]
|
||||
#define de_stack ((char_type*)&tab_suffixof((code_int)1<<GIF_BITS))
|
||||
|
||||
static code_int free_ent = 0; /* first unused entry */
|
||||
|
||||
/*
|
||||
* block compression parameters -- after all codes are used up,
|
||||
* and compression rate changes, start over.
|
||||
*/
|
||||
static int clear_flg = 0;
|
||||
|
||||
static int offset;
|
||||
static long int in_count = 1; /* length of input */
|
||||
static long int out_count = 0; /* # of codes output (for debugging) */
|
||||
|
||||
/*
|
||||
* compress stdin to stdout
|
||||
*
|
||||
* Algorithm: use open addressing double hashing (no chaining) on the
|
||||
* prefix code / next character combination. We do a variant of Knuth's
|
||||
* algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
|
||||
* secondary probe. Here, the modular division first probe is gives way
|
||||
* to a faster exclusive-or manipulation. Also do block compression with
|
||||
* an adaptive reset, whereby the code table is cleared when the compression
|
||||
* ratio decreases, but after the table fills. The variable-length output
|
||||
* codes are re-sized at this point, and a special CLEAR code is generated
|
||||
* for the decompressor. Late addition: construct the table according to
|
||||
* file size for noticeable speed improvement on small files. Please direct
|
||||
* questions about this implementation to ames!jaw.
|
||||
*/
|
||||
|
||||
static int g_init_bits;
|
||||
static FILE *g_outfile;
|
||||
|
||||
static int ClearCode;
|
||||
static int EOFCode;
|
||||
|
||||
|
||||
static unsigned long cur_accum;
|
||||
static int cur_bits;
|
||||
|
||||
static unsigned long masks[] =
|
||||
{0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
|
||||
0x001F, 0x003F, 0x007F, 0x00FF,
|
||||
0x01FF, 0x03FF, 0x07FF, 0x0FFF,
|
||||
0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
|
||||
|
||||
|
||||
static void
|
||||
compress (int init_bits,
|
||||
FILE *outfile)
|
||||
{
|
||||
register long fcode;
|
||||
register code_int i /* = 0 */ ;
|
||||
register int c;
|
||||
register code_int ent;
|
||||
register code_int disp;
|
||||
register code_int hsize_reg;
|
||||
register int hshift;
|
||||
|
||||
|
||||
/*
|
||||
* Set up the globals: g_init_bits - initial number of bits
|
||||
* g_outfile - pointer to output file
|
||||
*/
|
||||
g_init_bits = init_bits;
|
||||
g_outfile = outfile;
|
||||
|
||||
cur_bits = 0;
|
||||
cur_accum = 0;
|
||||
|
||||
/*
|
||||
* Set up the necessary values
|
||||
*/
|
||||
offset = 0;
|
||||
out_count = 0;
|
||||
clear_flg = 0;
|
||||
in_count = 1;
|
||||
|
||||
ClearCode = (1 << (init_bits - 1));
|
||||
EOFCode = ClearCode + 1;
|
||||
free_ent = ClearCode + 2;
|
||||
|
||||
|
||||
/* Had some problems here... should be okay now. --Adam */
|
||||
n_bits = g_init_bits;
|
||||
maxcode = MAXCODE (n_bits);
|
||||
|
||||
char_init ();
|
||||
|
||||
ent = GIFNextPixel ();
|
||||
|
||||
hshift = 0;
|
||||
for (fcode = (long) hsize; fcode < 65536L; fcode *= 2L)
|
||||
++hshift;
|
||||
hshift = 8 - hshift; /* set hash code range bound */
|
||||
|
||||
hsize_reg = hsize;
|
||||
cl_hash ((count_int) hsize_reg); /* clear hash table */
|
||||
|
||||
output ((code_int) ClearCode);
|
||||
|
||||
while ((c = GIFNextPixel()) != EOF)
|
||||
{
|
||||
++in_count;
|
||||
|
||||
fcode = (long) (((long) c << maxbits) + ent);
|
||||
i = (((code_int) c << hshift) ^ ent); /* xor hashing */
|
||||
|
||||
if (HashTabOf (i) == fcode)
|
||||
{
|
||||
ent = CodeTabOf (i);
|
||||
continue;
|
||||
}
|
||||
else if ((long) HashTabOf (i) < 0) /* empty slot */
|
||||
goto nomatch;
|
||||
disp = hsize_reg - i; /* secondary hash (after G. Knott) */
|
||||
if (i == 0)
|
||||
disp = 1;
|
||||
probe:
|
||||
if ((i -= disp) < 0)
|
||||
i += hsize_reg;
|
||||
|
||||
if (HashTabOf (i) == fcode)
|
||||
{
|
||||
ent = CodeTabOf (i);
|
||||
continue;
|
||||
}
|
||||
if ((long) HashTabOf (i) > 0)
|
||||
goto probe;
|
||||
nomatch:
|
||||
output ((code_int) ent);
|
||||
++out_count;
|
||||
ent = c;
|
||||
|
||||
if (free_ent < maxmaxcode)
|
||||
{
|
||||
CodeTabOf (i) = free_ent++; /* code -> hashtable */
|
||||
HashTabOf (i) = fcode;
|
||||
}
|
||||
else
|
||||
cl_block ();
|
||||
}
|
||||
/*
|
||||
* Put out the final code.
|
||||
*/
|
||||
output ((code_int) ent);
|
||||
++out_count;
|
||||
output ((code_int) EOFCode);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* TAG( output )
|
||||
*
|
||||
* Output the given code.
|
||||
* Inputs:
|
||||
* code: A n_bits-bit integer. If == -1, then EOF. This assumes
|
||||
* that n_bits =< (long)wordsize - 1.
|
||||
* Outputs:
|
||||
* Outputs code to the file.
|
||||
* Assumptions:
|
||||
* Chars are 8 bits long.
|
||||
* Algorithm:
|
||||
* Maintain a GIF_BITS character long buffer (so that 8 codes will
|
||||
* fit in it exactly). Use the VAX insv instruction to insert each
|
||||
* code in turn. When the buffer fills up empty it and start over.
|
||||
*/
|
||||
|
||||
static void
|
||||
output (code_int code)
|
||||
{
|
||||
cur_accum &= masks[cur_bits];
|
||||
|
||||
if (cur_bits > 0)
|
||||
cur_accum |= ((long) code << cur_bits);
|
||||
else
|
||||
cur_accum = code;
|
||||
|
||||
cur_bits += n_bits;
|
||||
|
||||
while (cur_bits >= 8)
|
||||
{
|
||||
char_out ((unsigned int) (cur_accum & 0xff));
|
||||
cur_accum >>= 8;
|
||||
cur_bits -= 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the next entry is going to be too big for the code size,
|
||||
* then increase it, if possible.
|
||||
*/
|
||||
if (free_ent > maxcode || clear_flg)
|
||||
{
|
||||
if (clear_flg)
|
||||
{
|
||||
|
||||
maxcode = MAXCODE (n_bits = g_init_bits);
|
||||
clear_flg = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
++n_bits;
|
||||
if (n_bits == maxbits)
|
||||
maxcode = maxmaxcode;
|
||||
else
|
||||
maxcode = MAXCODE (n_bits);
|
||||
}
|
||||
}
|
||||
|
||||
if (code == EOFCode)
|
||||
{
|
||||
/*
|
||||
* At EOF, write the rest of the buffer.
|
||||
*/
|
||||
while (cur_bits > 0)
|
||||
{
|
||||
char_out ((unsigned int) (cur_accum & 0xff));
|
||||
cur_accum >>= 8;
|
||||
cur_bits -= 8;
|
||||
}
|
||||
|
||||
flush_char ();
|
||||
|
||||
fflush (g_outfile);
|
||||
|
||||
if (ferror (g_outfile))
|
||||
writeerr ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear out the hash table
|
||||
*/
|
||||
static void
|
||||
cl_block () /* table clear for block compress */
|
||||
{
|
||||
|
||||
cl_hash ((count_int) hsize);
|
||||
free_ent = ClearCode + 2;
|
||||
clear_flg = 1;
|
||||
|
||||
output ((code_int) ClearCode);
|
||||
}
|
||||
|
||||
static void
|
||||
cl_hash (register count_int hsize) /* reset code table */
|
||||
{
|
||||
|
||||
register count_int *htab_p = htab + hsize;
|
||||
|
||||
register long i;
|
||||
register long m1 = -1;
|
||||
|
||||
i = hsize - 16;
|
||||
do
|
||||
{ /* might use Sys V memset(3) here */
|
||||
*(htab_p - 16) = m1;
|
||||
*(htab_p - 15) = m1;
|
||||
*(htab_p - 14) = m1;
|
||||
*(htab_p - 13) = m1;
|
||||
*(htab_p - 12) = m1;
|
||||
*(htab_p - 11) = m1;
|
||||
*(htab_p - 10) = m1;
|
||||
*(htab_p - 9) = m1;
|
||||
*(htab_p - 8) = m1;
|
||||
*(htab_p - 7) = m1;
|
||||
*(htab_p - 6) = m1;
|
||||
*(htab_p - 5) = m1;
|
||||
*(htab_p - 4) = m1;
|
||||
*(htab_p - 3) = m1;
|
||||
*(htab_p - 2) = m1;
|
||||
*(htab_p - 1) = m1;
|
||||
htab_p -= 16;
|
||||
}
|
||||
while ((i -= 16) >= 0);
|
||||
|
||||
for (i += 16; i > 0; --i)
|
||||
*--htab_p = m1;
|
||||
}
|
||||
|
||||
static void
|
||||
writeerr ()
|
||||
{
|
||||
fprintf (stderr, "GIF: error writing output file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* GIF Specific routines
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Number of characters so far in this 'packet'
|
||||
*/
|
||||
static int a_count;
|
||||
|
||||
/*
|
||||
* Set up the 'byte output' routine
|
||||
*/
|
||||
static void
|
||||
char_init ()
|
||||
{
|
||||
a_count = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define the storage for the packet accumulator
|
||||
*/
|
||||
static char accum[256];
|
||||
|
||||
/*
|
||||
* Add a character to the end of the current packet, and if it is 254
|
||||
* characters, flush the packet to disk.
|
||||
*/
|
||||
static void
|
||||
char_out (int c)
|
||||
{
|
||||
accum[a_count++] = c;
|
||||
if (a_count >= 254)
|
||||
flush_char ();
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the packet to disk, and reset the accumulator
|
||||
*/
|
||||
static void
|
||||
flush_char (void)
|
||||
{
|
||||
if (a_count > 0)
|
||||
{
|
||||
fputc (a_count, g_outfile);
|
||||
fwrite (accum, 1, a_count, g_outfile);
|
||||
a_count = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* GIF savinging routines stripped out of the GIF saving filter for The GIMP.
|
||||
*
|
||||
* Modified for blinkentools in 2001 by Sven Neumann <sven@gimp.org>.
|
||||
* Included into blib in 2002 by Sven Neumann <sven@gimp.org>.
|
||||
*
|
||||
* GIMP plug-in written by Adam D. Moss <adam@gimp.org> <adam@foxbox.org>
|
||||
*
|
||||
* Based around original GIF code by David Koblas.
|
||||
*
|
||||
* This filter uses code taken from the "giftopnm" and "ppmtogif" programs
|
||||
* which are part of the "netpbm" package.
|
||||
*
|
||||
* "The Graphics Interchange Format(c) is the Copyright property of
|
||||
* CompuServe Incorporated. GIF(sm) is a Service Mark property of
|
||||
* CompuServe Incorporated."
|
||||
*/
|
||||
|
||||
/* Copyright notice for GIF code from which this plugin was long ago *
|
||||
* derived (David Koblas has granted permission to relicense): *
|
||||
* +-------------------------------------------------------------------+ *
|
||||
* | Copyright 1990, 1991, 1993, David Koblas. (koblas@extra.com) | *
|
||||
* +-------------------------------------------------------------------+ */
|
||||
|
||||
|
||||
#ifndef __GIF_SAVE_H__
|
||||
#define __GIF_SAVE_H__
|
||||
|
||||
#include <blib/gif-types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void GIFEncodeHeader (FILE *fp,
|
||||
int gif89,
|
||||
int Width,
|
||||
int Height,
|
||||
int Background,
|
||||
int BitsPerPixel,
|
||||
char *cmap);
|
||||
void GIFEncodeGraphicControlExt (FILE *fp,
|
||||
GIFDisposeType Disposal,
|
||||
int Delay,
|
||||
int Animation,
|
||||
int Transparent);
|
||||
void GIFEncodeImageData (FILE *fp,
|
||||
int Width,
|
||||
int Height,
|
||||
int BitsPerPixel,
|
||||
int offset_x,
|
||||
int offset_y,
|
||||
char *data);
|
||||
void GIFEncodeClose (FILE *fp);
|
||||
void GIFEncodeCommentExt (FILE *fp,
|
||||
char *comment);
|
||||
void GIFEncodeLoopExt (FILE *fp,
|
||||
int num_loops);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GIF_SAVE_H__ */
|
|
@ -0,0 +1,76 @@
|
|||
/* blib - Library of useful things to hack the Blinkenlights
|
||||
*
|
||||
* Copyright (c) 2001-2002 The Blinkenlights Crew
|
||||
* Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* GIF loading routines stripped out of the GIF loading filter for The GIMP.
|
||||
*
|
||||
* Modified for blinkentools in 2001 by Sven Neumann.
|
||||
* Included into blib in 2002 by Sven Neumann.
|
||||
*
|
||||
* GIMP plug-in written by Adam D. Moss <adam@gimp.org> <adam@foxbox.org>
|
||||
*
|
||||
* Based around original GIF code by David Koblas.
|
||||
*
|
||||
* This filter uses code taken from the "giftopnm" and "ppmtogif" programs
|
||||
* which are part of the "netpbm" package.
|
||||
*
|
||||
* "The Graphics Interchange Format(c) is the Copyright property of
|
||||
* CompuServe Incorporated. GIF(sm) is a Service Mark property of
|
||||
* CompuServe Incorporated."
|
||||
*/
|
||||
|
||||
/* Copyright notice for code which this plugin was long ago derived from */
|
||||
/* +-------------------------------------------------------------------+ */
|
||||
/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */
|
||||
/* | Permission to use, copy, modify, and distribute this software | */
|
||||
/* | and its documentation for any purpose and without fee is hereby | */
|
||||
/* | granted, provided that the above copyright notice appear in all | */
|
||||
/* | copies and that both that copyright notice and this permission | */
|
||||
/* | notice appear in supporting documentation. This software is | */
|
||||
/* | provided "as is" without express or implied warranty. | */
|
||||
/* +-------------------------------------------------------------------+ */
|
||||
|
||||
#ifndef __GIF_TYPES_H__
|
||||
#define __GIF_TYPES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DISPOSE_UNSPECIFIED,
|
||||
DISPOSE_COMBINE,
|
||||
DISPOSE_REPLACE
|
||||
} GIFDisposeType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IMAGE,
|
||||
GRAPHIC_CONTROL_EXTENSION,
|
||||
COMMENT_EXTENSION,
|
||||
UNKNOWN_EXTENSION,
|
||||
TERMINATOR
|
||||
} GIFRecordType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GIF_TYPES_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,61 @@
|
|||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* The Blib version */
|
||||
#undef BLIB_VERSION
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,340 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(blib/blib.h)
|
||||
|
||||
# Save this values here, since automake will set cflags later
|
||||
cflags_set="${CFLAGS}set"
|
||||
|
||||
# Making releases:
|
||||
# BLIB_MICRO_VERSION += 1;
|
||||
# BLIB_INTERFACE_AGE += 1;
|
||||
# BLIB_BINARY_AGE += 1;
|
||||
# if any functions have been added, set BLIB_INTERFACE_AGE to 0.
|
||||
# if backwards compatibility has been broken,
|
||||
# set BLIB_BINARY_AGE and BLIB_INTERFACE_AGE to 0.
|
||||
#
|
||||
BLIB_MAJOR_VERSION=1
|
||||
BLIB_MINOR_VERSION=1
|
||||
BLIB_MICRO_VERSION=7
|
||||
BLIB_INTERFACE_AGE=0
|
||||
BLIB_BINARY_AGE=0
|
||||
BLIB_API_VERSION=$BLIB_MAJOR_VERSION.$BLIB_MINOR_VERSION
|
||||
BLIB_VERSION=$BLIB_MAJOR_VERSION.$BLIB_MINOR_VERSION.$BLIB_MICRO_VERSION
|
||||
|
||||
AC_SUBST(BLIB_MAJOR_VERSION)
|
||||
AC_SUBST(BLIB_MINOR_VERSION)
|
||||
AC_SUBST(BLIB_MICRO_VERSION)
|
||||
AC_SUBST(BLIB_INTERFACE_AGE)
|
||||
AC_SUBST(BLIB_BINARY_AGE)
|
||||
AC_SUBST(BLIB_VERSION)
|
||||
|
||||
AC_DEFINE_UNQUOTED(BLIB_VERSION,"$BLIB_VERSION",[The Blib version])
|
||||
|
||||
# libtool versioning
|
||||
LT_RELEASE=$BLIB_MAJOR_VERSION.$BLIB_MINOR_VERSION
|
||||
LT_CURRENT=`expr $BLIB_MICRO_VERSION - $BLIB_INTERFACE_AGE`
|
||||
LT_REVISION=$BLIB_INTERFACE_AGE
|
||||
LT_AGE=`expr $BLIB_BINARY_AGE - $BLIB_INTERFACE_AGE`
|
||||
|
||||
AC_SUBST(LT_RELEASE)
|
||||
AC_SUBST(LT_CURRENT)
|
||||
AC_SUBST(LT_REVISION)
|
||||
AC_SUBST(LT_AGE)
|
||||
|
||||
VERSION=$BLIB_VERSION
|
||||
PACKAGE=blib
|
||||
|
||||
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
AC_ISC_POSIX
|
||||
AM_SANITY_CHECK
|
||||
AM_PROG_CC_STDC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_MAKE_SET
|
||||
AC_HEADER_STDC
|
||||
AC_C_CONST
|
||||
|
||||
AC_CHECK_HEADERS(unistd.h)
|
||||
|
||||
|
||||
AC_MSG_CHECKING([for target architecture])
|
||||
case x"$target" in
|
||||
xNONE | x)
|
||||
target_or_host="$host" ;;
|
||||
*)
|
||||
target_or_host="$target" ;;
|
||||
esac
|
||||
AC_MSG_RESULT([$target_or_host])
|
||||
|
||||
|
||||
AC_MSG_CHECKING([for native Win32])
|
||||
case "$target_or_host" in
|
||||
*-*-mingw*)
|
||||
os_win32=yes
|
||||
;;
|
||||
*)
|
||||
os_win32=no
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT([$os_win32])
|
||||
AM_CONDITIONAL(OS_WIN32, test "$os_win32" = "yes")
|
||||
|
||||
|
||||
if test x"$os_win32" = xyes; then
|
||||
WIN32_LIBS=-lwsock32
|
||||
fi
|
||||
AC_SUBST(WIN32_LIBS)
|
||||
|
||||
|
||||
# Ensure MSVC-compatible struct packing convention is used when
|
||||
# compiling for Win32 with gcc.
|
||||
# What flag to depends on gcc version: gcc3 uses "-mms-bitfields", while
|
||||
# gcc2 uses "-fnative-struct".
|
||||
if test x"$os_win32" = xyes; then
|
||||
if test x"$GCC" = xyes; then
|
||||
msnative_struct=''
|
||||
AC_MSG_CHECKING([how to get MSVC-compatible struct packing])
|
||||
if test -z "$ac_cv_prog_CC"; then
|
||||
our_gcc="$CC"
|
||||
else
|
||||
our_gcc="$ac_cv_prog_CC"
|
||||
fi
|
||||
case `$our_gcc --version | sed -e 's,\..*,.,' -e q` in
|
||||
2.)
|
||||
if $our_gcc -v --help 2>/dev/null | grep fnative-struct >/dev/null; then
|
||||
msnative_struct='-fnative-struct'
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if $our_gcc -v --help 2>/dev/null | grep ms-bitfields >/dev/null; then
|
||||
msnative_struct='-mms-bitfields'
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if test x"$msnative_struct" = x ; then
|
||||
AC_MSG_RESULT([no way])
|
||||
AC_MSG_WARN([build will be incompatible with GTK+ DLLs])
|
||||
else
|
||||
WIN32_CFLAGS=$msnative_struct
|
||||
AC_MSG_RESULT([$WIN32_CFLAGS])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(WIN32_CFLAGS)
|
||||
|
||||
|
||||
if test "x$GCC" = xyes; then
|
||||
CFLAGS="$CFLAGS -Wall $WIN32_CFLAGS"
|
||||
fi
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
|
||||
|
||||
DATADIR=$datadir/blib-$BLIB_API_VERSION
|
||||
INCLUDEDIR=$includedir/blib-$BLIB_API_VERSION
|
||||
THEMEPATH=$datadir/blib-$BLIB_API_VERSION/themes
|
||||
MODULEPATH=$libdir/blib-$BLIB_API_VERSION/modules
|
||||
|
||||
AC_SUBST(DATADIR)
|
||||
AC_SUBST(INCLUDEDIR)
|
||||
AC_SUBST(THEMEPATH)
|
||||
AC_SUBST(MODULEPATH)
|
||||
|
||||
AM_PATH_GLIB_2_0(2.0.1,,
|
||||
AC_MSG_ERROR([
|
||||
*** blib depends on glib-2.0 which doesn't seem to be available.]),
|
||||
gobject gmodule)
|
||||
|
||||
|
||||
AC_ARG_ENABLE(directfb,
|
||||
[ --disable-directfb disable support for DirectFB [default=auto]], ,
|
||||
enable_directfb=yes)
|
||||
|
||||
if test "x$enable_directfb" = "xyes"; then
|
||||
PKG_CHECK_MODULES(DIRECTFB, directfb >= 0.9.11,
|
||||
have_directfb=yes, have_directfb=no)
|
||||
else
|
||||
have_directfb=no
|
||||
fi
|
||||
|
||||
if test $have_directfb = yes; then
|
||||
DIRECTFB_VIEW_TYPE=b_view_directfb_get_type
|
||||
fi
|
||||
|
||||
AC_SUBST(DIRECTFB_VIEW_TYPE)
|
||||
|
||||
AM_CONDITIONAL(HAVE_DIRECTFB, test $have_directfb = yes)
|
||||
|
||||
|
||||
AC_ARG_ENABLE(gdk_pixbuf,
|
||||
[ --disable-gdk-pixbuf disable support for gdk-pixbuf [default=auto]], ,
|
||||
enable_gdk_pixbuf=yes)
|
||||
|
||||
if test "x$enable_gdk_pixbuf" = "xyes"; then
|
||||
PKG_CHECK_MODULES(GDK_PIXBUF, gdk-pixbuf-2.0 >= 2.0.0,
|
||||
have_pixbuf=yes, have_pixbuf=no)
|
||||
else
|
||||
have_pixbuf=no
|
||||
fi
|
||||
|
||||
if test $have_pixbuf = yes; then
|
||||
PIXBUF_VIEW_TYPE=b_view_pixbuf_get_type
|
||||
fi
|
||||
|
||||
AC_SUBST(PIXBUF_VIEW_TYPE)
|
||||
|
||||
AM_CONDITIONAL(HAVE_PIXBUF, test $have_pixbuf = yes)
|
||||
|
||||
|
||||
AC_ARG_ENABLE(gtk,
|
||||
[ --disable-gtk disable support for GTK+-2.0 [default=auto]], ,
|
||||
enable_gtk=yes)
|
||||
|
||||
if test "x$enable_gtk" = "xyes"; then
|
||||
PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.0.3,
|
||||
have_gtk=yes, have_gtk=no)
|
||||
else
|
||||
have_gtk=no
|
||||
fi
|
||||
|
||||
if test $have_gtk = yes; then
|
||||
GTK_VIEW_TYPE=b_view_gtk_get_type
|
||||
fi
|
||||
|
||||
AC_SUBST(GTK_VIEW_TYPE)
|
||||
|
||||
AM_CONDITIONAL(HAVE_GTK, test $have_gtk = yes)
|
||||
|
||||
|
||||
AC_ARG_ENABLE(aa,
|
||||
[ --disable-aa disable support for AA-lib [default=auto]], ,
|
||||
enable_aa=yes)
|
||||
|
||||
have_aa=no
|
||||
if test "x$enable_aa" = "xyes"; then
|
||||
AC_CHECK_LIB(aa, aa_fastrender,
|
||||
[AC_CHECK_HEADER(aalib.h,
|
||||
have_aa=yes
|
||||
AA_LIBS='-laa')])
|
||||
fi
|
||||
|
||||
AC_SUBST(AA_LIBS)
|
||||
|
||||
if test $have_aa = yes; then
|
||||
AA_VIEW_TYPE=b_view_aa_get_type
|
||||
fi
|
||||
|
||||
AC_SUBST(AA_VIEW_TYPE)
|
||||
|
||||
AM_CONDITIONAL(HAVE_AA, test $have_aa = "yes")
|
||||
|
||||
|
||||
AC_ARG_ENABLE(modules,
|
||||
[ --disable-modules disable the build of modules], ,
|
||||
enable_modules=yes)
|
||||
|
||||
AM_CONDITIONAL(BUILD_MODULES, test $enable_modules = yes)
|
||||
|
||||
|
||||
dnl **************************
|
||||
dnl *** Checks for gtk-doc ***
|
||||
dnl **************************
|
||||
|
||||
AC_ARG_WITH(html-dir, [ --with-html-dir=PATH path to installed docs])
|
||||
|
||||
if test "x$with_html_dir" = "x" ; then
|
||||
HTML_DIR='${datadir}/gtk-doc/html'
|
||||
else
|
||||
HTML_DIR=$with_html_dir
|
||||
fi
|
||||
|
||||
AC_SUBST(HTML_DIR)
|
||||
|
||||
AC_CHECK_PROG(GTKDOC, gtkdoc-mkdb, true, false)
|
||||
|
||||
gtk_doc_min_version=0.10
|
||||
if $GTKDOC ; then
|
||||
gtk_doc_version=`gtkdoc-mkdb --version`
|
||||
AC_MSG_CHECKING([gtk-doc version ($gtk_doc_version) >= $gtk_doc_min_version])
|
||||
|
||||
IFS="${IFS= }"; blib_save_IFS="$IFS"; IFS="."
|
||||
set $gtk_doc_version
|
||||
for min in $gtk_doc_min_version ; do
|
||||
cur=$1; shift
|
||||
if test -z $min ; then break; fi
|
||||
if test -z $cur ; then GTKDOC=false; break; fi
|
||||
if test $cur -gt $min ; then break ; fi
|
||||
if test $cur -lt $min ; then GTKDOC=false; break ; fi
|
||||
done
|
||||
IFS="$blib_save_IFS"
|
||||
|
||||
if $GTKDOC ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_GTK_DOC, $GTKDOC)
|
||||
AC_SUBST(HAVE_GTK_DOC)
|
||||
|
||||
AC_CHECK_PROG(DB2HTML, db2html, true, false)
|
||||
AM_CONDITIONAL(HAVE_DOCBOOK, $DB2HTML)
|
||||
|
||||
dnl Let people disable the gtk-doc stuff.
|
||||
AC_ARG_ENABLE(gtk-doc, [ --enable-gtk-doc use gtk-doc to build documentation [default=auto]], enable_gtk_doc="$enableval", enable_gtk_doc=no)
|
||||
|
||||
if test x$enable_gtk_doc = xyes ; then
|
||||
if test x$GTKDOC = xtrue ; then
|
||||
enable_gtk_doc=yes
|
||||
else
|
||||
enable_gtk_doc=no
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl NOTE: We need to use a separate automake conditional for this
|
||||
dnl to make this work with the tarballs.
|
||||
AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes)
|
||||
|
||||
|
||||
AC_OUTPUT([
|
||||
blib.pc
|
||||
blib-aa.pc
|
||||
blib-directfb.pc
|
||||
blib-gtk.pc
|
||||
blib-pixbuf.pc
|
||||
Makefile
|
||||
blib/Makefile
|
||||
data/Makefile
|
||||
docs/Makefile
|
||||
docs/reference/Makefile
|
||||
docs/reference/blib.types
|
||||
docs/reference/version
|
||||
gfx/Makefile
|
||||
modules/Makefile
|
||||
test/Makefile
|
||||
test/movies/Makefile
|
||||
test/modules/Makefile
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([
|
||||
Build options:
|
||||
Version $VERSION
|
||||
Install prefix $prefix
|
||||
Include dir $INCLUDEDIR
|
||||
Data dir $DATADIR
|
||||
Theme path $THEMEPATH
|
||||
Module path $MODULEPATH
|
||||
|
||||
Views:
|
||||
DirectFB $have_directfb
|
||||
GdkPixbuf $have_pixbuf
|
||||
GTK+-2.0 $have_gtk
|
||||
AA-lib $have_aa
|
||||
]);
|
|
@ -0,0 +1,10 @@
|
|||
## Makefile.am for blib/data
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
blibdatadir = $(DATADIR)
|
||||
|
||||
blibdata_DATA = \
|
||||
bml.dtd \
|
||||
blinkentheme.dtd
|
||||
|
||||
EXTRA_DIST = $(blibdata_DATA)
|
|
@ -0,0 +1,368 @@
|
|||
# Makefile.in generated by automake 1.7.9 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
# Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_triplet = @host@
|
||||
AA_LIBS = @AA_LIBS@
|
||||
AA_VIEW_TYPE = @AA_VIEW_TYPE@
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMDEP_FALSE = @AMDEP_FALSE@
|
||||
AMDEP_TRUE = @AMDEP_TRUE@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BLIB_BINARY_AGE = @BLIB_BINARY_AGE@
|
||||
BLIB_INTERFACE_AGE = @BLIB_INTERFACE_AGE@
|
||||
BLIB_MAJOR_VERSION = @BLIB_MAJOR_VERSION@
|
||||
BLIB_MICRO_VERSION = @BLIB_MICRO_VERSION@
|
||||
BLIB_MINOR_VERSION = @BLIB_MINOR_VERSION@
|
||||
BLIB_VERSION = @BLIB_VERSION@
|
||||
BUILD_MODULES_FALSE = @BUILD_MODULES_FALSE@
|
||||
BUILD_MODULES_TRUE = @BUILD_MODULES_TRUE@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DATADIR = @DATADIR@
|
||||
DB2HTML = @DB2HTML@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DIRECTFB_CFLAGS = @DIRECTFB_CFLAGS@
|
||||
DIRECTFB_LIBS = @DIRECTFB_LIBS@
|
||||
DIRECTFB_VIEW_TYPE = @DIRECTFB_VIEW_TYPE@
|
||||
ECHO = @ECHO@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ENABLE_GTK_DOC_FALSE = @ENABLE_GTK_DOC_FALSE@
|
||||
ENABLE_GTK_DOC_TRUE = @ENABLE_GTK_DOC_TRUE@
|
||||
EXEEXT = @EXEEXT@
|
||||
F77 = @F77@
|
||||
FFLAGS = @FFLAGS@
|
||||
GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@
|
||||
GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@
|
||||
GLIB_CFLAGS = @GLIB_CFLAGS@
|
||||
GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
|
||||
GLIB_LIBS = @GLIB_LIBS@
|
||||
GLIB_MKENUMS = @GLIB_MKENUMS@
|
||||
GOBJECT_QUERY = @GOBJECT_QUERY@
|
||||
GTKDOC = @GTKDOC@
|
||||
GTK_CFLAGS = @GTK_CFLAGS@
|
||||
GTK_LIBS = @GTK_LIBS@
|
||||
GTK_VIEW_TYPE = @GTK_VIEW_TYPE@
|
||||
HAVE_AA_FALSE = @HAVE_AA_FALSE@
|
||||
HAVE_AA_TRUE = @HAVE_AA_TRUE@
|
||||
HAVE_DIRECTFB_FALSE = @HAVE_DIRECTFB_FALSE@
|
||||
HAVE_DIRECTFB_TRUE = @HAVE_DIRECTFB_TRUE@
|
||||
HAVE_DOCBOOK_FALSE = @HAVE_DOCBOOK_FALSE@
|
||||
HAVE_DOCBOOK_TRUE = @HAVE_DOCBOOK_TRUE@
|
||||
HAVE_GTK_DOC = @HAVE_GTK_DOC@
|
||||
HAVE_GTK_DOC_FALSE = @HAVE_GTK_DOC_FALSE@
|
||||
HAVE_GTK_DOC_TRUE = @HAVE_GTK_DOC_TRUE@
|
||||
HAVE_GTK_FALSE = @HAVE_GTK_FALSE@
|
||||
HAVE_GTK_TRUE = @HAVE_GTK_TRUE@
|
||||
HAVE_PIXBUF_FALSE = @HAVE_PIXBUF_FALSE@
|
||||
HAVE_PIXBUF_TRUE = @HAVE_PIXBUF_TRUE@
|
||||
HTML_DIR = @HTML_DIR@
|
||||
INCLUDEDIR = @INCLUDEDIR@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_AGE = @LT_AGE@
|
||||
LT_CURRENT = @LT_CURRENT@
|
||||
LT_RELEASE = @LT_RELEASE@
|
||||
LT_REVISION = @LT_REVISION@
|
||||
MAINT = @MAINT@
|
||||
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
|
||||
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MODULEPATH = @MODULEPATH@
|
||||
OBJEXT = @OBJEXT@
|
||||
OS_WIN32_FALSE = @OS_WIN32_FALSE@
|
||||
OS_WIN32_TRUE = @OS_WIN32_TRUE@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PIXBUF_VIEW_TYPE = @PIXBUF_VIEW_TYPE@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
RANLIB = @RANLIB@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
THEMEPATH = @THEMEPATH@
|
||||
VERSION = @VERSION@
|
||||
WIN32_CFLAGS = @WIN32_CFLAGS@
|
||||
WIN32_LIBS = @WIN32_LIBS@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_F77 = @ac_ct_F77@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
|
||||
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
oldincludedir = @oldincludedir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
|
||||
blibdatadir = $(DATADIR)
|
||||
|
||||
blibdata_DATA = \
|
||||
bml.dtd \
|
||||
blinkentheme.dtd
|
||||
|
||||
|
||||
EXTRA_DIST = $(blibdata_DATA)
|
||||
subdir = data
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
DIST_SOURCES =
|
||||
DATA = $(blibdata_DATA)
|
||||
|
||||
DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu data/Makefile
|
||||
Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool
|
||||
uninstall-info-am:
|
||||
blibdataDATA_INSTALL = $(INSTALL_DATA)
|
||||
install-blibdataDATA: $(blibdata_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(blibdatadir)
|
||||
@list='$(blibdata_DATA)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(blibdataDATA_INSTALL) $$d$$p $(DESTDIR)$(blibdatadir)/$$f"; \
|
||||
$(blibdataDATA_INSTALL) $$d$$p $(DESTDIR)$(blibdatadir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-blibdataDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(blibdata_DATA)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(blibdatadir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(blibdatadir)/$$f; \
|
||||
done
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
ctags: CTAGS
|
||||
CTAGS:
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||
list='$(DISTFILES)'; for file in $$list; do \
|
||||
case $$file in \
|
||||
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||
esac; \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkinstalldirs) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(DATA)
|
||||
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(blibdatadir)
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-libtool
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-blibdataDATA
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-blibdataDATA uninstall-info-am
|
||||
|
||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
||||
distclean distclean-generic distclean-libtool distdir dvi \
|
||||
dvi-am info info-am install install-am install-blibdataDATA \
|
||||
install-data install-data-am install-exec install-exec-am \
|
||||
install-info install-info-am install-man install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
|
||||
uninstall-blibdataDATA uninstall-info-am
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
|
@ -0,0 +1,83 @@
|
|||
<!-- DTD for Blinkenlights Themes -->
|
||||
<!-- See http://www.blinkenlights.de/ for more information. -->
|
||||
|
||||
<!-- Implied numerical values are 0, implied strings are empty! -->
|
||||
|
||||
|
||||
<!-- The toplevel blinkentheme element describes a Blinkentheme. -->
|
||||
<!-- The width and height attributes define the themes screen -->
|
||||
<!-- dimensions. -->
|
||||
|
||||
<!ELEMENT blinkentheme (background?, overlay+)>
|
||||
<!ATTLIST blinkentheme
|
||||
version CDATA #FIXED "1.0"
|
||||
title CDATA #REQUIRED
|
||||
columns CDATA #REQUIRED
|
||||
rows CDATA #REQUIRED
|
||||
maxval CDATA "1"
|
||||
channels CDATA "1"
|
||||
width CDATA #REQUIRED
|
||||
height CDATA #REQUIRED
|
||||
type CDATA>
|
||||
|
||||
|
||||
<!-- The background element describes a color and/or an image used -->
|
||||
<!-- to draw the background. The image attribute is the path to a -->
|
||||
<!-- PNG image. The path must be either absolute or relative to the -->
|
||||
<!-- blinkentheme XML file. A color can specified be specified as -->
|
||||
<!-- #aarrggbb. If the alpha channel is omitted, full opacity is -->
|
||||
<!-- implied. -->
|
||||
|
||||
<!ELEMENT background EMPTY>
|
||||
<!ATTLIST background
|
||||
color CDATA "#ff000000"
|
||||
image CDATA
|
||||
x CDATA "0"
|
||||
y CDATA "0">
|
||||
|
||||
|
||||
<!-- The overlay element describes a color and/or an image used -->
|
||||
<!-- to lighten the windows. See the background element for -->
|
||||
<!-- comments about the image and color attributes. -->
|
||||
|
||||
<!ELEMENT overlay (grid*, span*, window*)>
|
||||
<!ATTLIST overlay
|
||||
color CDATA "#ffffffff"
|
||||
image CDATA>
|
||||
|
||||
|
||||
<!-- The grid element describes how to a create a rectilinear grid -->
|
||||
<!-- of windows. -->
|
||||
|
||||
<!ELEMENT grid (window+)>
|
||||
<!ATTLIST grid
|
||||
dx CDATA #REQUIRED
|
||||
dy CDATA #REQUIRED
|
||||
sx CDATA "0"
|
||||
sy CDATA "0">
|
||||
|
||||
|
||||
<!-- The span element describes how to create a row of windows. -->
|
||||
|
||||
<!ELEMENT span (window+)>
|
||||
<!ATTLIST span
|
||||
dx CDATA #REQUIRED
|
||||
sx CDATA "0">
|
||||
|
||||
|
||||
<!-- The window element describes a window. -->
|
||||
|
||||
<!ELEMENT window EMPTY>
|
||||
<!ATTLIST window
|
||||
value CDATA "all"
|
||||
row CDATA #IMPLIED
|
||||
column CDATA #IMPLIED
|
||||
x CDATA #IMPLIED
|
||||
y CDATA #IMPLIED
|
||||
width CDATA #IMPLIED
|
||||
height CDATA #IMPLIED
|
||||
src-x CDATA "0"
|
||||
src-y CDATA "0">
|
||||
|
||||
|
||||
<!-- end of the DTD -->
|
|
@ -0,0 +1,48 @@
|
|||
<!-- DTD for the Blinkenlights Markup Language version 1.0 -->
|
||||
<!-- See http://www.blinkenlights.de/ for more information. -->
|
||||
|
||||
|
||||
<!-- The toplevel blm element describes a Blinkenlights movie. -->
|
||||
|
||||
<!ELEMENT blm (header?, frame+)>
|
||||
<!ATTLIST blm
|
||||
version CDATA #FIXED "1.0"
|
||||
width CDATA #REQUIRED
|
||||
height CDATA #REQUIRED
|
||||
channels CDATA "1"
|
||||
bits CDATA "1">
|
||||
|
||||
|
||||
<!-- The header element is optional and solely informative. -->
|
||||
<!-- No application should rely on any information found herein. -->
|
||||
|
||||
<!ELEMENT header (title,
|
||||
description?, creator?, author?, email?, url?,
|
||||
duration?, loop?)>
|
||||
<!ELEMENT title ( #PCDATA )>
|
||||
<!ELEMENT description ( #PCDATA )>
|
||||
<!ELEMENT creator ( #PCDATA )>
|
||||
<!ELEMENT author ( #PCDATA )>
|
||||
<!ELEMENT email ( #PCDATA )>
|
||||
<!ELEMENT url ( #PCDATA )>
|
||||
<!ELEMENT duration ( #PCDATA )>
|
||||
<!ELEMENT loop ( #PCDATA )>
|
||||
|
||||
|
||||
<!-- The frame element describes a single frame. -->
|
||||
<!-- The frame duration is specified in milliseconds. -->
|
||||
|
||||
<!ELEMENT frame (row+)>
|
||||
<!ATTLIST frame
|
||||
duration CDATA #REQUIRED>
|
||||
|
||||
|
||||
<!-- The row element describes one row of pixels. -->
|
||||
<!-- Pixels values are specified in hexidecimal notation. -->
|
||||
<!-- Depending on the number of significant bits defined in the -->
|
||||
<!-- blm element there may be one or two characters per pixel. -->
|
||||
|
||||
<!ELEMENT row ( #PCDATA )>
|
||||
|
||||
|
||||
<!-- end of the DTD -->
|
|
@ -0,0 +1,5 @@
|
|||
blib (1.1.0) unstable; urgency=low
|
||||
|
||||
* unofficial debian packages
|
||||
|
||||
-- Sven Neumann <sven@gimp.org> Mon, 22 Dec 2003 20:20:22 +0100
|
|
@ -0,0 +1,70 @@
|
|||
Source: blib
|
||||
Priority: optional
|
||||
Maintainer: Sven Neumann <sven@gimp.org>
|
||||
Build-Depends: debhelper (>> 3.0.0), autoconf
|
||||
Standards-Version: 3.5.6
|
||||
|
||||
Package: libblib
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: libglib2.0-0
|
||||
Description: a library of useful things to hack the Blinkenlights
|
||||
blib contains some code that you will find useful if you want to
|
||||
create any kind of software related to Blinkenlights,
|
||||
|
||||
Package: libblib-dev
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: libblib (= ${Source-Version}), libc6-dev, libglib2.0-dev
|
||||
Section: devel
|
||||
Description: Blinkenlights library, development files
|
||||
blib contains some code that you will find useful if you want to
|
||||
create any kind of software related to Blinkenlights,
|
||||
.
|
||||
This package contains the files needed to compile and link
|
||||
programs which use blib.
|
||||
|
||||
Package: libblib-directfb
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: libblib (= ${Source-Version}), libdirectfb-0.9-19
|
||||
Description: Blinkenlights display library using DirectFB
|
||||
blib contains some code that you will find useful if you want to
|
||||
create any kind of software related to Blinkenlights,
|
||||
.
|
||||
This packages contains the DirectFB backend of the Blinkenlights
|
||||
display widget.
|
||||
|
||||
Package: libblib-directfb-dev
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: libblib-dev (= ${Source-Version}), libdirectfb-dev
|
||||
Description: Blinkenlights display library using DirectFB
|
||||
blib contains some code that you will find useful if you want to
|
||||
create any kind of software related to Blinkenlights,
|
||||
.
|
||||
This packages contains the files needed to compile and link programs
|
||||
that use the DirectFB backend of the Blinkenlights display widget.
|
||||
|
||||
Package: libblib-gtk
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, libblib (= ${Source-Version}), libgtk2.0-0
|
||||
Description: Blinkenlights display library using GTK+
|
||||
blib contains some code that you will find useful if you want to
|
||||
create any kind of software related to Blinkenlights,
|
||||
.
|
||||
This packages contains the DirectFB backend of the Blinkenlights
|
||||
display widget.
|
||||
|
||||
Package: libblib-gtk-dev
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: libblib-dev (= ${Source-Version}), libgtk2.0-dev
|
||||
Description: Blinkenlights display library using GTK+
|
||||
blib contains some code that you will find useful if you want to
|
||||
create any kind of software related to Blinkenlights,
|
||||
.
|
||||
This packages contains the files needed to compile and link programs
|
||||
that use the GTK+ backend of the Blinkenlights display widget.
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
This package was debianized by Sven Neumann <sven@gimp.org>
|
||||
Mon Dec 22 20:22:42 CET 2003
|
||||
|
||||
It was downloaded from http://sven.gimp.org/blinkenlights
|
||||
|
||||
Upstream Authors:
|
||||
|
||||
Sven Neumann <sven@gimp.org>
|
||||
Michael Natterer <mitch@gimp.org>
|
||||
Daniel Mack <daniel@yoobay.net>
|
||||
|
||||
Copyright:
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
On Debian GNU/Linux systems, the complete text of the GNU General
|
||||
Public License can be found in `/usr/share/common-licenses/GPL'.
|
|
@ -0,0 +1 @@
|
|||
usr
|
|
@ -0,0 +1,2 @@
|
|||
README
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
libblib_1.1.0_i386.deb libs optional
|
||||
libblib-dev_1.1.0_i386.deb devel optional
|
||||
libblib-directfb_1.1.0_i386.deb libs optional
|
||||
libblib-directfb-dev_1.1.0_i386.deb libs optional
|
||||
libblib-gtk_1.1.0_i386.deb libs optional
|
||||
libblib-gtk-dev_1.1.0_i386.deb libs optional
|
|
@ -0,0 +1,4 @@
|
|||
usr/include/*
|
||||
usr/lib/libb.a
|
||||
usr/lib/libb.la
|
||||
usr/lib/pkgconfig/blib.pc
|
|
@ -0,0 +1,3 @@
|
|||
usr/lib/libb-directfb.a
|
||||
usr/lib/libb-directfb.la
|
||||
usr/lib/pkgconfig/blib-directfb.pc
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue