Compare commits

...

1 Commits

Author SHA1 Message Date
Joe Shaw
52f36c58a4 bring the branch up in sync with 2.12.1, and tag it as
NAUTILUS_SEARCH_2_12_2_MERGEPOINT
2005-10-31 18:20:27 +00:00
667 changed files with 30 additions and 390087 deletions

View File

@@ -1,38 +0,0 @@
ABOUT-NLS
.new.ltmain.sh
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.cache
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
configure.scan
intl
libtool
ltconfig
ltmain.sh
missing
mkinstalldirs
install-sh
stamp-h
stamp-h.in
version.h
intl
macros
INSTALL
control-center.spec
my_control_center_idl
*.tar.gz
Gnome.directory
intltool-*
confdefs.h
libgswitchit
libsound
depcomp
stamp-h1

View File

@@ -1 +0,0 @@
Jonathan Blandford <jrb@redhat.com>

340
COPYING
View File

@@ -1,340 +0,0 @@
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.

4360
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
Email: jody@gnome.org
Email: jrb@gnome.org

View File

@@ -1,23 +0,0 @@
SUBDIRS = po libsounds libbackground libwindow-settings libgswitchit libkbdraw gnome-settings-daemon capplets control-center vfs-methods idl schemas $(TYPING_BREAK)
#I removed the root-manager for now
#
# it generated this error :
# root-manager.c:55:31: security/pam_appl.h: No such file or directory
# while compiling. I guess we need to check for pam or something
# in the configure.in file. Since we are not using it now, i will
# remove it from the default build. Chema
dist-hook: control-center.spec
cp control-center.spec $(distdir)
DISTCLEANFILES = \
intltool-extract \
intltool-merge \
intltool-update
EXTRA_DIST = \
control-center.spec.in \
intltool-extract.in \
intltool-merge.in \
intltool-update.in

439
NEWS
View File

@@ -1,439 +0,0 @@
gnome-control-center 2.11.3
- fix mute handling, particularly for devices without hardware mute support
or with applications that use volume=0 for mute (Ronald S. Bultje)
- clipboard manager (Anders Carlsson)
- canvas a11y support (Carlos Garnacho Parro)
- name and description to the object information (Rodrigo Moya)
translator:
Vladimir Petkov (bg)
Miloslav Trmac (cs)
Rhys Jones (cy)
Martin Willemoes Hansen (da)
Adam Weinberger (en_CA)
Alessio Dessì (it)
Takeshi AIHANA (ja)
Kjartan Maraas (nb)
Kjartan Maraas (no)
Elian Myftiu (sq)
Theppitak Karoonboonyanan (th)
------------------------------------------------------------------------------
gnome-control-center 2.11.1
- allow to configure the menubar shortcut (Sebastien Bacher)
- new shell layout code (Carlos Garnacho Parro)
- port of the font capplet to gtk_font_button and some cleanup (Paolo Borelli)
- make proxy settings HIG compliant (Jorn Baayen)
- lot of cleanups (Kjartan Maraas)
- don't list themes using the Hidden property (Shakti Sen).
- fix the theme preview crasher with xorg/composite (Colin Gibbs)
translators:
Vladimir Petkov (bg)
Miloslav Trmac (cs)
Kostas Papadimas (el)
Adam Weinberger (en_CA)
Ivar Smolin (et)
Iñaki Larrañaga Murgoitio (eu)
Gabor Kelemen (hu)
Elian Myftiu (sq)
Maxim Dziumanenko (uk)
Canonical Ltd (xh)
------------------------------------------------------------------------------
gnome-control-center 2.10.0
background:
- fix the crashes with non-UTF8 names (Rodney Dawes)
general:
- do not warn vnc users that their XKB does not work. We already know.
(Jody Goldberg)
translators:
Vladimir Petkov (bg)
Jordi Mallach (ca)
Miloslav Trmac (cs)
Martin Willemoes Hansen (da)
Frank Arnold (de)
Kostas Papadimas (el)
Adam Weinberger (en_CA)
David Lodge (en_GB)
Francisco Javier F. Serrador (es)
Priit Laes (et)
Pauli Virtanen (fi)
Simon Manlay (fr)
Ankit Patel (gu)
Gabor Kelemen (hu)
Alessio Dessì (it)
Takeshi AIHANA (ja)
Changwoo Ryu (ko)
Žygimantas BeruÄ<75>ka (lt)
Kjartan Maraas (nb)
Reinout van Schouwen (nl)
Kjartan Maraas (no)
Gnome PL Team (pl)
Raphael Higino (pt_BR)
Duarte Loreto (pt)
Dan Damian (ro)
Leonid Kanter (ru)
Marcel Telka (sk)
Elian Myftiu (sq)
Veljko M. Stanojevic (sr)
Christian Rose (sv)
Theppitak Karoonboonyanan (th)
Maxim Dziumanenko (uk)
Woodman Tuen (zh_TW)
------------------------------------------------------------------------------
gnome-control-center 2.9.91
general:
- check for xmodmap files, and offer to load them (#143487)
- changing the default value for "handleIndicators" to false (#161343)
(Sergey V. Udaltsov)
- check for screensaver functionality in libXext.so also when deciding
to build typing-break (#155461) (Leena Gunda)
- providing ability to suppress the "x sysconfig changed" warning message
(#150435) (Sergey V. Udaltsov).
- handle the modmap settings (#143487) (Shakti Sen)
- fix number of leaks (Kjartan Maraas)
background:
- use the boolean argument to specify if we want to update gconf or not.
Always get the colors for both primary and secondary and update the thumbnail
(#166486) (Rodney Dawes)
- force using the GTK backend (#154978) (Rodney Dawes)
common:
- leak fixes, use GtkIconTheme (#166267) (Kjartan Maraas)
network:
- adding/removing the host name instantly to/from gconf (#166233) (Shakti Sen)
theme-switcher:
- new install procedure (#102216) (David Sedeño)
- some string fixes (#166550) (David Lodge)
- remove a load of leaks and make sure newly installed themes show up in the
relevant lists without having to close/open the dialog again (#166267)
(Kjartan Maraas)
- fix an infinite loop that was bringing single-CPU systems to their
knees (#160803) (Elijah Newren).
Translators:
Vladimir Petkov (bg)
Miloslav Trmac (cs)
Frank Arnold (de)
Nikos Charonitakis (el)
Adam Weinberger (en_CA)
David Lodge (en_GB)
Francisco Javier F. Serrador (es)
Ivar Smolin (et)
Pauli Virtanen (fi)
Alessio Dessì (it)
Takeshi AIHANA (ja)
Changwoo Ryu (ko)
Žygimantas BeruÄ<75>ka (lt)
Kjartan Maraas (nb)
rajeev shrestha (ne)
Åsmund Skjæveland (nn)
Kjartan Maraas (no)
Raphael Higino (pt_BR)
Duarte Loreto (pt)
Leonid Kanter (ru)
Elian Myftiu (sq)
Christian Rose (sv)
Theppitak Karoonboonyanan (th)
Baris Cicek (tr)
Funda Wang (zh_CN)
------------------------------------------------------------------------------
gnome-control-center 2.9.4
- fix the build out of the source dir (Closes: #158333).
- don't set "close" as the default button for the differents capplets
(Closes: #98202).
- use a temporary filename to not overwrite existant files in ~/.themes
(Closes: #97180).
- theme-thumbnailer doesn't require an absolute path (Closes: #153203).
- use ~/ instead of / as working directory for programs launched with the
multimedia keys (Closes: #162069).
- fixed the "locate pointer" feature (Closes: #149383).
- load the translated descriptions in the backgrounds capplet
(Closes: # 160700)
- add a preview in the backgrounds fileselector (Closes: #139714).
- add a proxy exclusion list configuration in the network capplet
(Closes: #147666).
- some bugs and leaks fixed.
Translators:
Vladimir Petkov (bg)
Miloslav Trmac (cs)
Kostas Papadimas (el)
Adam Weinberger (en_CA)
Francisco Javier F. Serrador (es)
Takeshi AIHANA (ja)
Žygimantas BeruÄ<75>ka (lt)
Kjartan Maraas (nb)
rajeev shrestha (ne)
Kjartan Maraas (no)
Leonid Kanter (ru)
Elian Myftiu (sq)
Christian Rose (sv)
gnome-control-center 2.9.3
- Add a button to turn off a sound event (#14272).
- Allow to use themes with the ".tgz" extension (#148895).
- Don't nuke .Xdefaults when restarting g-s-d (#127050).
- Fix the themes installation with the non GNU versions of tar (#114553).
- Mask the "Text Editor" tab since the new mime system doesn't use this
setting.
- Updated the tooltips to respect the HIG.
- Updated to use libnautilus-extensions.
- Updated the menu entries for the new gnome-menus system.
gnome-control-center 2.8.1
- Some tweaking of the available default applications
- Background capplet fixes (#154003)
- keyboard patchs (#144490) (#153866)
- Patch leak in XKB code
- update translations
------------------------------------------------------------------------------
gnome-control-center 2.8.0
Jody Goldberg
* Fixed float/int mismatch in peditor
Jonathan Blandford
* Fix docs link for at-properties capplet.
Pierre Ossman
* display the volume dialog in the correct place
Sergey V. Udaltsov
* default switchcut (Alt*2) is introduced
Translations:
* All translations updated
------------------------------------------------------------------------------
gnome-control-center 2.7.1
Translations:
* Bosnian translation added.
Frederic Crozat:
* Use themed icon for windows
Rodney Dawes:
* Add "W x H pixels" to description, and remove file size for bg capplet
Sergey:
* Fixes to keybinding capplet
Kjartan Maraas:
* text cleanup
Jeroen Zwartepoorte:
* Use the parent type in the G_DEFINE_TYPE
------------------------------------------------------------------------------
gnome-control-center 2.7.0
* No NEWS file updates this time due to time pressures. 2.7.1
should have a full change.
------------------------------------------------------------------------------
gnome-control-center 2.6.1
Jody:
* Add the ximian shell to the tarball and polish it up a bit
Michael Terry:
* Fix ui-review comments for keybinding capplet
Sergey:
* Add a hook to libgswitchit to notify when xkb is reloaded
Shailesh Mittal:
http://bugzilla.gnome.org/show_bug.cgi?id=114832
* IPV6 support in the file types capplet
Sergey V. Udaltsov:
* Merged the keyboard preview branch. The keyboard capplet got another tab.
------------------------------------------------------------------------------
gnome-control-center 2.6.1
Alex Larsson:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=119494
* Fix reverting a size change.
Chris Lahey:
* Fix ordering of themes in theme manager
* Fix sizing of svg backgrounds
Glynn:
* Toplevel window icons should use the icon themes
Jody:
http://bugzilla.gnome.org/show_bug.cgi?id=139190
* Fix uniqueness test for binding special keys with no name
* Fix theme manager selection when not running metacity
http://bugzilla.gnome.org/show_bug.cgi?id=139605
* Mouse buttons are not valid modifiers for keybindings
* Force libxklavier 1.0.2 so that we can work with x.org and xfree86
* Match nautilus' interpretation of icons in desktop files
Padraig O'Briain:
http://bugzilla.gnome.org/show_bug.cgi?id=131538.
------------------------------------------------------------------------------
gnome-control-center 2.6.0.3
Jody:
http://bugzilla.gnome.org/show_bug.cgi?id=138701
* Fix typo
* Fix uniqueness test for keybindings
* Merge in some build fixes for sun's forte and Irix
------------------------------------------------------------------------------
gnome-control-center 2.5.4
Dennis Cranston :
http://bugzilla.gnome.org/show_bug.cgi?id=133715
* Improve layout of display capplet
Alexander Winston :
http://bugzilla.gnome.org/show_bug.cgi?id=133214
* quote the AC_DEFUN properly
Jody :
http://bugzilla.gnome.org/show_bug.cgi?id=124064
* Add a test for ngettext
* Delete some of the unused file cluttering the tree
http://bugzilla.gnome.org/show_bug.cgi?id=134446
* Trivial string consistency adjustment
http://bugzilla.gnome.org/show_bug.cgi?id=128164
* Handle sorted trees
* Fix incorrect string in gnome-settings-daemon
Muktha Narayan :
http://bugzilla.gnome.org/show_bug.cgi?id=124032
* Do not popup the logout dialog when the close button (X)
Jan Arne Petersen :
* Move a few capplets to the new file selector
Padraig O'Briain :
* Fix the ATK relations for the file-type capplet
Julio M. Merino Vidal :
* Make fontilus and themus respect the gconf install settings
Rodney Dawes:
http://bugzilla.gnome.org/show_bug.cgi?id=134171
* Fix transtions for titles of colour pickers.
Kaushal Kumar:
http://bugzilla.gnome.org/show_bug.cgi?id=109091
* Warn before deleting a type
Richard Hult:
* Improve Dr Wright.
msuarezalvarez@arnet.com.ar :
http://bugzilla.gnome.org/show_bug.cgi?id=134699
* Another typo in the new a11y settings daemon extensions
------------------------------------------------------------------------------
gnome-control-center 2.5.1
Jody:
http://bugzilla.gnome.org/show_bug.cgi?id=125899
http://bugzilla.gnome.org/show_bug.cgi?id=125970
* Fix the build and configure on older X servers.
* Use icon themes
Sergey:
* Merge gswitchit into gnome-settings-daemon and keyboard capplet
------------------------------------------------------------------------------
gnome-control-center 2.5.0
Jody:
* Add libxklavier and prep for inclusion of gswitchit's
xkb-properties-capplet
* http://bugzilla.gnome.org/show_bug.cgi?id=120842 [HIGification broke accessx]
* http://bugzilla.gnome.org/show_bug.cgi?id=106489 [protect against gconf failure]
* http://bugzilla.gnome.org/show_bug.cgi?id=124513 [Handle TruColor Displays]
* http://bugzilla.gnome.org/show_bug.cgi?id=116710 [smarter maximum dpi]
------------------------------------------------------------------------------
gnome-control-center 2.1.6
Jody:
* gnome-keyboard-properties.c (accessibility_button_clicked) : fix
minor typo that disables the error dialog in the event of failure.
Jonathan:
* gnome-theme-info.c : Rewrite. Now working
* gnome-theme-manager : Fix lots of bugs. Use the rewrite.
gnome-control-center 2.1.0.2
Jody:
http://bugzilla.gnome.org/show_bug.cgi?id=93211
* disable edit button when selecting mime catagory
* Tidy labels and accelerators in file-type edit dialogs
Michael:
http://bugzilla.gnome.org/show_bug.cgi?id=91535
* Don't start esd just to stop it
Iain Holmes:
* Add an image size label for background capplet.
------------------------------------------------------------------------------
gnome-control-center 2.1.0.1
Jody:
* Some minor ui tweaks for accessx.
* Some aix portabiltiy patches
* fix accelerators for ui-properties capplet.
------------------------------------------------------------------------------
gnome-control-center 2.0.1
Chema:
http://bugzilla.gnome.org/show_bug.cgi?id=86018
* Only assign the filename to the label if the file is valid.
GMan:
* Fix titles to use 'preferences' rather than 'properties'
Jody:
* Clean up the handling of custom applications in mime type capplet.
* Supply some decent defaults for new mime types.
* Implement Background capplet UI recommendations.
* Implement Font capplet UI recommendations.
* Reorganize the AccessX UI.
* Fix cmd line args for file-type capplet.
http://bugzilla.gnome.org/show_bug.cgi?id=84014
* Handle Drag-n-Drop of uris with escaped characters.
------------------------------------------------------------------------------
First split version of this package

62
README
View File

@@ -1,62 +0,0 @@
GNOME Control Center
====================
Requirements -
intltool >= 0.21
gtk+ >= 2.3.0
gconf >= 2.0.0
libgnome >= 2.0.0
libgnomeui >= 2.0.0
libglade >= 2.0.0
libbonobo >= 2.0.0
libbonoboui >= 2.0.0
libgnomevfs >= 2.0.0
gnome-desktop >= 2.0.0
gnome-icon-theme >= 1.1.3
Installation -
See the file 'INSTALL'
How to report bugs -
Bugs should be reported to the GNOME bug tracking system under the product
control-center. It is available at http://bugzilla.gnome.org.
In the report please include the following information -
Operating system and version
For Linux, version of the C library
How to reproduce the bug if possible
If the bug was a crash, include the exact text that was printed out
A stacktrace where possible [see below]
How to get a stack trace -
If the crash is reproducible, it is possible to get a stack trace and
attach it to the bug report. The following steps are used to obtain a
stack trace -
Run the program in gdb [the GNU debugger] or any other debugger
ie. gdb gnome-calculator
Start the program
ie. (gdb) run
Reproduce the crash and the program will exit to the gdb prompt
Get the back trace
ie. (gdb) bt
Once you have the backtrace, copy and paste this either into the
'Comments' field or attach a file with it included.
Patches -
Patches should be submitted to bugzilla.gnome.org or emailed to one of
the people listed in the MAINTAINERS file. If using bugzilla, attach
the patch to a new bug report [or preferably, check to see if there is
already a bug report that corresponds to your patch]. Bug reports
containing patches should include the 'PATCH' keyword.
Patches should be created using the unified diff form.
ie. cvs diff -u file-to-be-patched.c > patch.diff

105
TODO
View File

@@ -1,105 +0,0 @@
[ Things prefaced with GSD need to be fixed in the gnome-settings daemon
and not the dialog ]
ACCESSIBILITY:
* UI love
* Figure out Keyboard/peripherals integration
BACKGROUND:
* Seth love
* Get actual GNOME backgrounds
DEFAULT APPLICATIONS PROPERTIES:
* Merge in Window Manager selection
FILE TYPES:
* Stability issues
* UI Love
FONT AND THEME:
* merge them
GNOME SETTINGS DAEMON:
* disk monitor
KEYBOARD SHORTCUTS:
* Not sure I like the name.
* Needs icon
* Add a way to add new ones
KEYBOARD PROPERTIES:
* GSD: support keyboard bell
* Remove awful jrb-art and replace with actual blinking cursor
MOUSE PROPERTIES:
* GSD: Add support for devices other than CoreInput.
KEYBINDINGS:
* Metacity keyboard merging. See what hp plans to do
PANEL:
* UI love
* port gconf-peditor functionality
SAWFISH????
SOUND:
* Unknown
* Buggy as heck
SCREENSAVER:
* See what Jacob wants to do
* xscreensaver release
UI-PROPERTIES:
* Seems to be okay
GENERAL:
* Where we have keys, add a restore to defaults context menu button.
* Kill 'advanced'
* Control center itself seems to be fine
* Change buttons to use whatever the UI team comes up with
* Make sure we handle 'locked down' keys
* Make sure we handle all broken keys!
GOING FORWARD:
Hardware Integration
- hwbrowser??? Kde has one; should we?
- peripherals (RH only?)
- gphoto/sane/cd burning?? Userland hw.
Nautilus:
- Move nautilus settings
- Desktop should be a separate dialog
Background:
- Merge nautilus pane and bg capplet;
- possibly even popup a nautilus window of bg's for DnD
- Integrate better w/ nautilus
- per Workspace?
Workspace/Tasks
- Set number and name of workspaces
- Maybe something else?
Identification Capplet
- GDM screen
- Mail capplet
Password Capplet?
- ssh/smb
Themes and Appearance:
- blah
Sound:
- blah
Bugzilla
- Start using it better

View File

@@ -1,19 +0,0 @@
<todo>
<title>GNOME Control Center TODO list</title>
<section>
<title>Capplets</title>
<entry size="big" status="10%" target="1.4">
<title>Screensaver XML descriptions</title>
<description>
<p>
Create XML descriptions to allow dialog configuration of the various
screensavers that come with XScreensaver. See
capplets/new-screensaver-properties/screensavers/README for
documentaiton.
</p>
</description>
<contact>hovinen@helixcode.com</contact>
</entry>
</section> <!--Capplets-->
</todo>

View File

@@ -1,18 +0,0 @@
.deps
.libs
*.lo
*.la
Makefile
ximia-archiver
Makefile.in
ximian-config-manager
ximian_archiverConf.sh
ximian-archiver
bonobo-moniker-archiver
config-archiver
config_archiverConf.sh
Bonobo_Moniker_archiver.oaf
ConfigArchiver.h
ConfigArchiver-stubs.c
ConfigArchiver-skels.c
ConfigArchiver-common.c

View File

@@ -1,35 +0,0 @@
<oaf_info>
<oaf_server iid="OAFIID:Bonobo_Moniker_archiver_Factory" type="exe" location="bonobo-moniker-archiver">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/GenericFactory:1.0"/>
</oaf_attribute>
<oaf_attribute name="name" type="string" value="XML Database Moniker factory"/>
</oaf_server>
<oaf_server iid="OAFIID:Bonobo_Moniker_archiverdb" type="factory"
location="OAFIID:Bonobo_Moniker_archiver_Factory">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/Moniker:1.0"/>
<item value="IDL:Bonobo/Unknown:1.0"/>
</oaf_attribute>
<oaf_attribute name="name" type="string" value="XML Database Moniker with archiver interface"/>
<oaf_attribute name="bonobo:moniker" type="stringv">
<item value="archiverdb:"/>
</oaf_attribute>
</oaf_server>
<oaf_server iid="OAFIID:Bonobo_Moniker_archive" type="factory"
location="OAFIID:Bonobo_Moniker_archiver_Factory">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/Moniker:1.0"/>
<item value="IDL:Bonobo/Unknown:1.0"/>
</oaf_attribute>
<oaf_attribute name="name" type="string" value="XML archiver interface"/>
<oaf_attribute name="bonobo:moniker" type="stringv">
<item value="archive:"/>
</oaf_attribute>
</oaf_server>
</oaf_info>

File diff suppressed because it is too large Load Diff

View File

@@ -1,99 +0,0 @@
confexecdir = $(libdir)
confexec_DATA = config_archiverConf.sh
Locationmetadir = $(datadir)/control-center/archiver
Locationmeta_DATA = default-user.xml default-global.xml
includedir = $(prefix)/include/config-archiver
INCLUDES = \
-DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-I$(includedir) \
$(GNOME_INCLUDEDIR) \
-DVERSION=\""$(VERSION)"\" \
-DG_LOG_DOMAIN=\"libconfig-archiver\" \
-DCONFIGDIR=\""/etc"\" \
-DLOCATION_DIR=\""$(datadir)/control-center/archiver"\" \
-DGLADE_DIR=\""$(INTERFACES_DIR)"\" \
-DXST_BACKEND_LOCATION=\""$(datadir)/setup-tool-backends/scripts"\" \
@ARCHIVER_CFLAGS@ \
@MONIKER_CFLAGS@
CORBA_SOURCE = \
ConfigArchiver.h \
ConfigArchiver-common.c \
ConfigArchiver-stubs.c \
ConfigArchiver-skels.c
idl_flags = `gnome-config --cflags idl`
$(CORBA_SOURCE): $(top_srcdir)/idl/ConfigArchiver.idl
orbit-idl $(top_srcdir)/idl/ConfigArchiver.idl -I$(top_srcdir)/idl $(idl_flags)
bin_PROGRAMS = bonobo-moniker-archiver config-archiver
lib_LTLIBRARIES = libconfig_archiver.la
libconfig_archiver_la_SOURCES = \
util.c util.h \
archiver-client.c \
$(CORBA_SOURCE)
libconfig_archiver_la_LIBADD = \
@GNOME_XML_LIBS@
archiver-client.c: $(CORBA_SOURCE)
include_HEADERS = \
ConfigArchiver.h \
archiver-client.h
config_archiver_SOURCES = \
config-archiver.c
config_archiver_LDADD = \
@ARCHIVER_LIBS@ \
libconfig_archiver.la
#
# Create the config_archiverConf.sh file from the sh.in file
#
config_archiverConf.sh: config_archiverConf.sh.in Makefile
sed -e 's?\@VERSION\@?$(VERSION)?' \
-e 's?\@CONFIG_ARCHIVER_LIBDIR\@?$(CONFIG_ARCHIVER_LIBDIR)?g' \
-e 's?\@CONFIG_ARCHIVER_LIBS\@?$(CONFIG_ARCHIVER_LIBS)?g' \
-e 's?\@CONFIG_ARCHIVER_INCLUDEDIR\@?$(CONFIG_ARCHIVER_INCLUDEDIR)?g' \
< $(srcdir)/config_archiverConf.sh.in > config_archiverConf.tmp \
&& mv config_archiverConf.tmp config_archiverConf.sh
OAF_FILES = \
Bonobo_Moniker_archiver.oaf
oafdir = $(datadir)/oaf
oaf_DATA = $(OAF_FILES)
monikerdir = $(libdir)/bonobo/monikers
Bonobo_Moniker_archiver.oaf : $(srcdir)/Bonobo_Moniker_archiver.oaf.in $(top_builddir)/config.status
sed -e "s|\@MONIKER_LIBDIR\@|$(monikerdir)|" \
$(srcdir)/Bonobo_Moniker_archiver.oaf.in > Bonobo_Moniker_archiver.oaf
clean-local:
-rm -f $(OAF_FILES) $(CORBA_SOURCE)
bonobo_moniker_archiver_SOURCES = \
bonobo-config-archiver.c bonobo-config-archiver.h \
archive.c archive.h \
location.c location.h \
config-log.c config-log.h \
backend-list.c backend-list.h \
cluster.c cluster.h \
cluster-location.c cluster-location.h \
bonobo-moniker-archiver.c
bonobo_moniker_archiver_LDADD = @MONIKER_LIBS@ libconfig_archiver.la
EXTRA_DIST = \
$(Locationmeta_DATA) \
config_archiverConf.sh.in \
Bonobo_Moniker_archiver.oaf.in

View File

@@ -1,2 +0,0 @@
This module is no longer built as a part of control-center.

View File

@@ -1,40 +0,0 @@
* Add per-user master list
* Archiving changes in location metadata
* Fix race in lock handling and add timeout support (look in gnome-mime)
* Support multiple backends from CLI
* Add translateable backend description support
* Some way to store the rollback time for each backend, for GUI purposes
* Have defaults stored somewhere, to be restored when the user goes
back before the first configuration edit
Long-term
* Add clustering support:
- Add Cluster class inheriting Archive class and overriding path
semantics
- Change location rollback functionality to send data through to
clients if the archive is a cluster
* Allow backend specs to identify an order in which they should be applied
- Specify this in the master list; have each location look up that
information before invoking multiple backends
Questions
Done
* Global list of configs for a given archive
* Location should store backend data in the location where it is valid
* Add support for dumping XML to stdout rather than running the backend
* Fix bug where EOF not sent through pipe
* Changing the name of a location
* Adding per-user/global backends
- Don't try to write out contains list on toplevel locations
- Give error if the user tries to add a backend to a toplevel location
* Consistency check on adding and removing backends
- Make sure the backend is included in the global metadata list before
adding
- When removing global and per-user backends, mark the backend
"invalid" and exclude from location_foreach_backend,
location_rollback_all_to, and location_contains.
* Refactor master list into an attribute of Archive
* Roll back x number of steps rather than by date
* Try to factor out populate_locations_list to be common between the
different dialogs

View File

@@ -1,781 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* archive.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include "archive.h"
#include "util.h"
static GtkObjectClass *parent_class;
enum {
ARG_0,
ARG_PREFIX,
ARG_IS_GLOBAL
};
#define ARCHIVE_FROM_SERVANT(servant) (ARCHIVE (bonobo_object_from_servant (servant)))
static void archive_init (Archive *archive);
static void archive_class_init (ArchiveClass *klass);
static void archive_destroy (GtkObject *object);
static void archive_set_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void archive_get_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void load_all_locations (Archive *archive);
/* CORBA interface methods */
static ConfigArchiver_Location
impl_ConfigArchiver_Archive_getLocation (PortableServer_Servant servant,
const CORBA_char *locid,
CORBA_Environment *ev)
{
Location *loc;
loc = archive_get_location (ARCHIVE_FROM_SERVANT (servant), locid);
if (loc == NULL) {
bonobo_exception_set (ev, ex_ConfigArchiver_Archive_LocationNotFound);
return CORBA_OBJECT_NIL;
} else {
return CORBA_Object_duplicate (BONOBO_OBJREF (loc), ev);
}
}
static ConfigArchiver_Location
impl_ConfigArchiver_Archive_createLocation (PortableServer_Servant servant,
const CORBA_char *locid,
const CORBA_char *label,
const ConfigArchiver_Location parent_ref,
CORBA_Environment *ev)
{
Location *loc;
loc = archive_create_location (ARCHIVE_FROM_SERVANT (servant), locid, label,
LOCATION (bonobo_object_from_servant (parent_ref->servant)));
return CORBA_Object_duplicate (BONOBO_OBJREF (loc), ev);
}
static ConfigArchiver_LocationSeq *
impl_ConfigArchiver_Archive_getChildLocations (PortableServer_Servant servant,
ConfigArchiver_Location location_ref,
CORBA_Environment *ev)
{
ConfigArchiver_LocationSeq *ret;
Archive *archive;
Location *location;
GList *locs, *tmp;
guint i = 0;
archive = ARCHIVE_FROM_SERVANT (servant);
if (location_ref == CORBA_OBJECT_NIL)
location = NULL;
else
location = LOCATION (bonobo_object_from_servant (location_ref->servant));
locs = archive_get_child_locations (archive, location);
ret = ConfigArchiver_LocationSeq__alloc ();
ret->_length = g_list_length (locs);
ret->_buffer = CORBA_sequence_ConfigArchiver_Location_allocbuf (ret->_length);
for (tmp = locs; tmp != NULL; tmp = tmp->next)
ret->_buffer[i++] = CORBA_Object_duplicate (BONOBO_OBJREF (tmp->data), ev);
g_list_free (locs);
return ret;
}
static CORBA_char *
impl_ConfigArchiver_Archive__get_prefix (PortableServer_Servant servant,
CORBA_Environment *ev)
{
return CORBA_string_dup (ARCHIVE_FROM_SERVANT (servant)->prefix);
}
static CORBA_boolean
impl_ConfigArchiver_Archive__get_isGlobal (PortableServer_Servant servant,
CORBA_Environment *ev)
{
return ARCHIVE_FROM_SERVANT (servant)->is_global;
}
static ConfigArchiver_BackendList
impl_ConfigArchiver_Archive__get_backendList (PortableServer_Servant servant,
CORBA_Environment *ev)
{
return bonobo_object_dup_ref (BONOBO_OBJREF (ARCHIVE_FROM_SERVANT (servant)->backend_list), ev);
}
static ConfigArchiver_Location
impl_ConfigArchiver_Archive__get_currentLocation (PortableServer_Servant servant,
CORBA_Environment *ev)
{
return CORBA_Object_duplicate (BONOBO_OBJREF (archive_get_current_location (ARCHIVE_FROM_SERVANT (servant))), ev);
}
static void
impl_ConfigArchiver_Archive__set_currentLocation (PortableServer_Servant servant,
ConfigArchiver_Location location_ref,
CORBA_Environment *ev)
{
Archive *archive = ARCHIVE_FROM_SERVANT (servant);
Location *location;
location = LOCATION (bonobo_object_from_servant (location_ref->servant));
if (location == NULL)
bonobo_exception_set (ev, ex_ConfigArchiver_Archive_LocationNotFound);
else
archive_set_current_location (archive, location);
}
static void
impl_ConfigArchiver_Archive__set_currentLocationId (PortableServer_Servant servant,
const CORBA_char *locid,
CORBA_Environment *ev)
{
archive_set_current_location_id (ARCHIVE_FROM_SERVANT (servant), locid);
}
CORBA_char *
impl_ConfigArchiver_Archive__get_currentLocationId (PortableServer_Servant servant,
CORBA_Environment *ev)
{
return CORBA_string_dup (archive_get_current_location_id (ARCHIVE_FROM_SERVANT (servant)));
}
BONOBO_X_TYPE_FUNC_FULL (Archive, ConfigArchiver_Archive, BONOBO_X_OBJECT_TYPE, archive);
static void
archive_init (Archive *archive)
{
archive->prefix = NULL;
archive->locations = g_tree_new ((GCompareFunc) strcmp);
archive->current_location_id = NULL;
}
static void
archive_class_init (ArchiveClass *klass)
{
GtkObjectClass *object_class;
object_class = GTK_OBJECT_CLASS (klass);
object_class->destroy = archive_destroy;
object_class->set_arg = archive_set_arg;
object_class->get_arg = archive_get_arg;
gtk_object_add_arg_type ("Archive::prefix",
GTK_TYPE_POINTER,
GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY,
ARG_PREFIX);
gtk_object_add_arg_type ("Archive::is-global",
GTK_TYPE_INT,
GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY,
ARG_IS_GLOBAL);
klass->epv.getLocation = impl_ConfigArchiver_Archive_getLocation;
klass->epv.createLocation = impl_ConfigArchiver_Archive_createLocation;
klass->epv.getChildLocations = impl_ConfigArchiver_Archive_getChildLocations;
klass->epv._get_prefix = impl_ConfigArchiver_Archive__get_prefix;
klass->epv._get_isGlobal = impl_ConfigArchiver_Archive__get_isGlobal;
klass->epv._get_backendList = impl_ConfigArchiver_Archive__get_backendList;
klass->epv._get_currentLocation = impl_ConfigArchiver_Archive__get_currentLocation;
klass->epv._get_currentLocationId = impl_ConfigArchiver_Archive__get_currentLocationId;
klass->epv._set_currentLocation = impl_ConfigArchiver_Archive__set_currentLocation;
klass->epv._set_currentLocationId = impl_ConfigArchiver_Archive__set_currentLocationId;
parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE);
}
static void
archive_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
Archive *archive;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_ARCHIVE (object));
g_return_if_fail (arg != NULL);
archive = ARCHIVE (object);
switch (arg_id) {
case ARG_PREFIX:
if (GTK_VALUE_POINTER (*arg) != NULL)
archive->prefix = g_strdup (GTK_VALUE_POINTER (*arg));
break;
case ARG_IS_GLOBAL:
archive->is_global = GTK_VALUE_INT (*arg);
archive->backend_list =
BACKEND_LIST (backend_list_new (archive->is_global));
break;
default:
break;
}
}
static void
archive_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
Archive *archive;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_ARCHIVE (object));
g_return_if_fail (arg != NULL);
archive = ARCHIVE (object);
switch (arg_id) {
case ARG_PREFIX:
GTK_VALUE_POINTER (*arg) = archive->prefix;
break;
case ARG_IS_GLOBAL:
GTK_VALUE_INT (*arg) = archive->is_global;
break;
default:
arg->type = GTK_TYPE_INVALID;
break;
}
}
/**
* archive_construct:
* @archive:
* @is_new: TRUE iff this is a new archive
*
* Load the archive information from disk
*
* Returns: TRUE on success and FALSE on failure
*/
gboolean
archive_construct (Archive *archive, gboolean is_new)
{
gint ret = 0;
g_return_val_if_fail (archive != NULL, FALSE);
g_return_val_if_fail (IS_ARCHIVE (archive), FALSE);
g_return_val_if_fail (archive->prefix != NULL, FALSE);
if (is_new) {
if (g_file_exists (archive->prefix))
return FALSE;
ret = mkdir (archive->prefix, S_IREAD | S_IWRITE | S_IEXEC);
if (ret == -1) return FALSE;
} else {
if (!g_file_test (archive->prefix, G_FILE_TEST_ISDIR))
return FALSE;
}
return TRUE;
}
/**
* archive_load:
* @is_global: TRUE iff we should load the global archive
*
* Load either the global or per-user configuration archive
*
* Return value: Reference to archive
**/
BonoboObject *
archive_load (gboolean is_global)
{
BonoboObject *object;
gchar *prefix;
if (is_global)
prefix = "/var/ximian-setup-tools";
else
prefix = g_concat_dir_and_file (g_get_home_dir (),
".gnome/capplet-archive");
object = BONOBO_OBJECT (gtk_object_new (archive_get_type (),
"prefix", prefix,
"is-global", is_global,
NULL));
if (!is_global)
g_free (prefix);
if (archive_construct (ARCHIVE (object), FALSE) == FALSE &&
archive_construct (ARCHIVE (object), TRUE) == FALSE)
{
bonobo_object_unref (object);
return NULL;
}
return object;
}
static gint
free_location_cb (gchar *locid, BonoboObject *location)
{
bonobo_object_unref (location);
g_free (locid);
return FALSE;
}
static void
archive_destroy (GtkObject *object)
{
Archive *archive;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_ARCHIVE (object));
DEBUG_MSG ("Enter");
archive = ARCHIVE (object);
g_tree_traverse (archive->locations,
(GTraverseFunc) free_location_cb,
G_IN_ORDER,
NULL);
g_tree_destroy (archive->locations);
if (archive->current_location_id != NULL)
g_free (archive->current_location_id);
if (archive->backend_list != NULL)
bonobo_object_unref (BONOBO_OBJECT (archive->backend_list));
GTK_OBJECT_CLASS (parent_class)->destroy (GTK_OBJECT (archive));
}
/**
* archive_get_location:
* @locid:
*
* Get a reference to the location with the given name.
*
* Return value: Reference to location, NULL if no such location exists
**/
Location *
archive_get_location (Archive *archive,
const gchar *locid)
{
BonoboObject *loc_obj;
gchar *tmp;
g_return_val_if_fail (archive != NULL, NULL);
g_return_val_if_fail (IS_ARCHIVE (archive), NULL);
g_return_val_if_fail (locid != NULL, NULL);
/* Stupid borken glib... */
tmp = g_strdup (locid);
loc_obj = g_tree_lookup (archive->locations, tmp);
g_free (tmp);
if (loc_obj == NULL) {
loc_obj = location_open (archive, locid);
if (loc_obj == NULL)
return NULL;
else
g_tree_insert (archive->locations,
g_strdup (locid), loc_obj);
} else {
bonobo_object_ref (loc_obj);
}
return LOCATION (loc_obj);
}
/**
* archive_create_location:
* @archive:
* @location:
*
* Creates a new location
*/
Location *
archive_create_location (Archive *archive,
const gchar *locid,
const gchar *label,
Location *parent)
{
Location *location;
g_return_val_if_fail (archive != NULL, NULL);
g_return_val_if_fail (IS_ARCHIVE (archive), NULL);
g_return_val_if_fail (locid != NULL, NULL);
g_return_val_if_fail (label != NULL, NULL);
g_return_val_if_fail (parent == NULL || IS_LOCATION (parent), NULL);
location = LOCATION (location_new (archive, locid, label, parent));
if (location == NULL)
return NULL;
g_tree_insert (archive->locations, g_strdup (locid), location);
return location;
}
/**
* archive_unregister_location:
* @archive:
* @location:
*
* Unregisters a location from the archive
**/
void
archive_unregister_location (Archive *archive, Location *location)
{
gchar *tmp;
g_return_if_fail (archive != NULL);
g_return_if_fail (IS_ARCHIVE (archive));
g_return_if_fail (location != NULL);
g_return_if_fail (IS_LOCATION (location));
if (GTK_OBJECT_DESTROYED (archive)) return;
tmp = g_strdup (location_get_id (location));
g_tree_remove (archive->locations, tmp);
g_free (tmp);
}
/**
* archive_get_current_location:
*
* Convenience function to get a pointer to the current location
*
* Return value: Pointer to current location, or NULL if the current location
* does not exist and a default location could not be created
**/
Location *
archive_get_current_location (Archive *archive)
{
const gchar *locid;
g_return_val_if_fail (archive != NULL, NULL);
g_return_val_if_fail (IS_ARCHIVE (archive), NULL);
locid = archive_get_current_location_id (archive);
if (locid == NULL)
return NULL;
else
return archive_get_location (archive, locid);
}
/**
* archive_set_current_location:
* @location: Location to which to set archive
*
* Set the current location in an archive to the location given; apply
* configuration for the new location to all backends necessary
**/
void
archive_set_current_location (Archive *archive,
Location *location)
{
Location *old_location;
GList *backends;
g_return_if_fail (archive != NULL);
g_return_if_fail (IS_ARCHIVE (archive));
g_return_if_fail (location != NULL);
g_return_if_fail (IS_LOCATION (location));
old_location = archive_get_current_location (archive);
archive_set_current_location_id (archive, location_get_id (location));
backends = location_get_changed_backends (location, old_location);
location_rollback_backends_to (location, NULL, 0, backends, TRUE);
}
/**
* archive_set_current_location_id:
* @name:
*
* Sets the current location's name, but does not invoke any rollback
**/
void
archive_set_current_location_id (Archive *archive,
const gchar *locid)
{
g_return_if_fail (archive != NULL);
g_return_if_fail (IS_ARCHIVE (archive));
g_return_if_fail (locid != NULL);
if (archive->current_location_id != NULL)
g_free (archive->current_location_id);
archive->current_location_id = g_strdup (locid);
if (archive->is_global)
gnome_config_set_string
("/ximian-setup-tools/config/current/global-location",
archive->current_location_id);
else
gnome_config_set_string
("/capplet-archive/config/current/location",
archive->current_location_id);
gnome_config_sync ();
}
/**
* archive_get_current_location_id:
*
* Get the name of the current location
*
* Return value: String containing current location, should not be freed, or
* NULL if no current location exists and the default location could not be
* created
**/
const gchar *
archive_get_current_location_id (Archive *archive)
{
gboolean def;
Location *loc;
Location *current_location;
g_return_val_if_fail (archive != NULL, NULL);
g_return_val_if_fail (IS_ARCHIVE (archive), NULL);
if (archive->current_location_id == NULL) {
if (archive->is_global)
archive->current_location_id =
gnome_config_get_string_with_default
("/ximian-setup-tools/config/current/global-location=default", &def);
else
archive->current_location_id =
gnome_config_get_string_with_default
("/capplet-archive/config/current/location=default", &def);
/* Create default location if it does not exist */
if (def) {
current_location =
archive_get_location (archive, archive->current_location_id);
if (current_location == NULL) {
loc = archive_create_location (archive, archive->current_location_id,
_("Default location"), NULL);
if (archive->is_global &&
location_store_full_snapshot (loc) < 0)
{
location_delete (loc);
return NULL;
}
bonobo_object_unref (BONOBO_OBJECT (loc));
} else {
bonobo_object_unref (BONOBO_OBJECT (current_location));
}
}
}
return archive->current_location_id;
}
/**
* archive_get_prefix:
* @archive:
*
* Get the prefix for locations in this archive
*
* Return value: String containing prefix; should not be freed
**/
const gchar *
archive_get_prefix (Archive *archive)
{
g_return_val_if_fail (archive != NULL, FALSE);
g_return_val_if_fail (IS_ARCHIVE (archive), FALSE);
return archive->prefix;
}
/**
* archive_is_global:
* @archive:
*
* Tell whether the archive is global or per-user
*
* Return value: TRUE if global, FALSE if per-user
**/
gboolean
archive_is_global (Archive *archive)
{
g_return_val_if_fail (archive != NULL, FALSE);
g_return_val_if_fail (IS_ARCHIVE (archive), FALSE);
return archive->is_global;
}
/**
* archive_get_backend_list:
* @archive:
*
* Get the master backend list for this archive
*
* Return value: Reference to the master backend list
**/
BackendList *
archive_get_backend_list (Archive *archive)
{
g_return_val_if_fail (archive != NULL, FALSE);
g_return_val_if_fail (IS_ARCHIVE (archive), FALSE);
return archive->backend_list;
}
/**
* archive_foreach_child_location:
* @archive:
* @callback: Callback to invoke
* @parent: Iterate through the children of this location; iterate through
* toplevel locations if this is NULL
* @data: Arbitrary data to pass to the callback
*
* Invoke the given callback for each location that inherits the given
* location, or for each toplevel location if the parent given is
* NULL. Terminate the iteration if any child returns a nonzero value
**/
static gint
foreach_build_list_cb (gchar *key, Location *value, GList **node)
{
if (!location_is_deleted (value))
*node = g_list_prepend (*node, value);
return 0;
}
GList *
archive_get_child_locations (Archive *archive,
Location *parent)
{
GList *list = NULL, *node, *tmp;
Location *loc;
g_return_val_if_fail (archive != NULL, NULL);
g_return_val_if_fail (IS_ARCHIVE (archive), NULL);
load_all_locations (archive);
g_tree_traverse (archive->locations,
(GTraverseFunc) foreach_build_list_cb,
G_IN_ORDER,
&list);
node = list;
while (node != NULL) {
loc = node->data;
tmp = node->next;
if (location_get_parent (loc) != parent) {
list = g_list_remove_link (list, node);
g_list_free_1 (node);
bonobo_object_unref (BONOBO_OBJECT (loc));
}
node = tmp;
}
return list;
}
/* Load and register all the locations for this archive */
static void
load_all_locations (Archive *archive)
{
DIR *archive_dir;
struct dirent entry, *entryp;
gchar *filename;
Location *location;
archive_dir = opendir (archive->prefix);
if (archive_dir == NULL) {
g_warning ("load_all_locations: %s", g_strerror (errno));
return;
}
while (1) {
if (readdir_r (archive_dir, &entry, &entryp)) {
g_warning ("load_all_locations: %s",
g_strerror (errno));
break;
}
if (entryp == NULL) break;
if (strcmp (entry.d_name, ".") &&
strcmp (entry.d_name, ".."))
{
filename = g_concat_dir_and_file (archive->prefix,
entry.d_name);
if (g_file_test (filename, G_FILE_TEST_ISDIR)) {
location = archive_get_location (archive, entry.d_name);
if (location_is_deleted (location))
bonobo_object_unref (BONOBO_OBJECT (location));
}
}
}
}

View File

@@ -1,94 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* archive.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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 __ARCHIVE_H
#define __ARCHIVE_H
#include <gnome.h>
#include "ConfigArchiver.h"
#include "location.h"
#include "backend-list.h"
#define ARCHIVE(obj) GTK_CHECK_CAST (obj, archive_get_type (), Archive)
#define ARCHIVE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, archive_get_type (), ArchiveClass)
#define IS_ARCHIVE(obj) GTK_CHECK_TYPE (obj, archive_get_type ())
typedef struct _ArchiveClass ArchiveClass;
struct _Archive
{
BonoboXObject object;
gchar *prefix;
GTree *locations;
gboolean is_global;
gchar *current_location_id;
BackendList *backend_list;
};
struct _ArchiveClass
{
BonoboXObjectClass parent;
POA_ConfigArchiver_Archive__epv epv;
};
GType archive_get_type (void);
gboolean archive_construct (Archive *archive,
gboolean is_new);
BonoboObject *archive_load (gboolean is_global);
void archive_close (Archive *archive);
Location *archive_get_location (Archive *archive,
const gchar *locid);
Location *archive_create_location (Archive *archive,
const gchar *locid,
const gchar *label,
Location *parent);
void archive_unregister_location (Archive *archive,
Location *location);
Location *archive_get_current_location (Archive *archive);
void archive_set_current_location (Archive *archive,
Location *location);
const gchar *archive_get_current_location_id (Archive *archive);
void archive_set_current_location_id (Archive *archive,
const gchar *locid);
const gchar *archive_get_prefix (Archive *archive);
gboolean archive_is_global (Archive *archive);
BackendList *archive_get_backend_list (Archive *archive);
GList *archive_get_child_locations (Archive *archive,
Location *parent);
#endif /* __ARCHIVE */

View File

@@ -1,442 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* archiver-client.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <libbonobo.h>
#include <gnome-xml/parser.h>
#include "archiver-client.h"
#include "util.h"
static void merge_xml_docs (xmlDocPtr child_doc,
xmlDocPtr parent_doc);
static void subtract_xml_doc (xmlDocPtr child_doc,
xmlDocPtr parent_doc,
gboolean strict);
static void merge_xml_nodes (xmlNodePtr node1,
xmlNodePtr node2);
static xmlNodePtr subtract_xml_node (xmlNodePtr node1,
xmlNodePtr node2,
gboolean strict);
static gboolean compare_xml_nodes (xmlNodePtr node1, xmlNodePtr node2);
/**
* location_client_load_rollback_data
* @location:
* @date:
* @steps:
* @backend_id:
* @parent_chain:
*
* Loads the XML data for rolling back as specified and returns the document
* object
**/
xmlDocPtr
location_client_load_rollback_data (ConfigArchiver_Location location,
const struct tm *date,
guint steps,
const gchar *backend_id,
gboolean parent_chain,
CORBA_Environment *opt_ev)
{
gchar *filename;
struct tm *date_c;
time_t time_g;
xmlDocPtr doc = NULL;
xmlDocPtr parent_doc = NULL;
ConfigArchiver_ContainmentType type = ConfigArchiver_CONTAIN_FULL;
ConfigArchiver_Location parent = CORBA_OBJECT_NIL;
CORBA_Environment my_ev;
g_return_val_if_fail (location != CORBA_OBJECT_NIL, NULL);
if (opt_ev == NULL) {
opt_ev = &my_ev;
CORBA_exception_init (opt_ev);
}
if (date != NULL) {
date_c = dup_date (date);
time_g = mktime (date_c);
#ifdef __USE_BSD
time_g += date_c->tm_gmtoff;
#endif /* __USE_BSD */
if (date_c->tm_isdst) time_g -= 3600;
g_free (date_c);
} else {
time_g = 0;
}
filename = ConfigArchiver_Location_getRollbackFilename
(location, time_g, steps, backend_id, parent_chain, opt_ev);
if (!BONOBO_EX (opt_ev) && filename != NULL)
DEBUG_MSG ("Loading rollback data: %s", filename);
if (!BONOBO_EX (opt_ev) && filename != NULL)
doc = xmlParseFile (filename);
else if (parent_chain)
type = ConfigArchiver_Location_contains (location, backend_id, opt_ev);
if (type == ConfigArchiver_CONTAIN_PARTIAL)
parent = ConfigArchiver_Location__get_parent (location, opt_ev);
if (parent != CORBA_OBJECT_NIL) {
parent_doc = location_client_load_rollback_data
(parent, date, steps, backend_id, TRUE, opt_ev);
bonobo_object_release_unref (parent, NULL);
}
if (doc != NULL && parent_doc != NULL)
merge_xml_docs (doc, parent_doc);
else if (parent_doc != NULL)
doc = parent_doc;
if (opt_ev == &my_ev)
CORBA_exception_free (opt_ev);
return doc;
}
/**
* location_client_store_xml:
* @location:
* @backend_id:
* @input:
* @store_type: STORE_FULL means blindly store the data, without
* modification. STORE_COMPARE_PARENT means subtract the settings the parent
* has that are different and store the result. STORE_MASK_PREVIOUS means
* store only those settings that are reflected in the previous logged data;
* if there do not exist such data, act as in STORE_COMPARE_PARENT
* @opt_ev:
*
* Store configuration data from the given XML document object in the location
* under the given backend id
**/
void
location_client_store_xml (ConfigArchiver_Location location,
const gchar *backend_id,
xmlDocPtr xml_doc,
ConfigArchiver_StoreType store_type,
CORBA_Environment *opt_ev)
{
xmlDocPtr parent_doc;
xmlDocPtr prev_doc = NULL;
char *filename;
ConfigArchiver_ContainmentType contain_type;
ConfigArchiver_Location parent;
CORBA_Environment my_ev;
g_return_if_fail (location != CORBA_OBJECT_NIL);
g_return_if_fail (xml_doc != NULL);
if (opt_ev == NULL) {
opt_ev = &my_ev;
CORBA_exception_init (opt_ev);
}
contain_type = ConfigArchiver_Location_contains (location, backend_id, opt_ev);
parent = ConfigArchiver_Location__get_parent (location, opt_ev);
if (contain_type == ConfigArchiver_CONTAIN_NONE) {
if (parent == CORBA_OBJECT_NIL) {
fprintf (stderr, "Could not find a location in the " \
"tree ancestry that stores this " \
"backend: %s.\n", backend_id);
} else {
location_client_store_xml (parent, backend_id, xml_doc, store_type, opt_ev);
bonobo_object_release_unref (parent, NULL);
}
if (opt_ev == &my_ev)
CORBA_exception_free (opt_ev);
return;
}
if (contain_type == ConfigArchiver_CONTAIN_PARTIAL && store_type != ConfigArchiver_STORE_FULL && parent != CORBA_OBJECT_NIL) {
g_assert (store_type == ConfigArchiver_STORE_MASK_PREVIOUS ||
store_type == ConfigArchiver_STORE_COMPARE_PARENT);
parent_doc = location_client_load_rollback_data
(parent, NULL, 0, backend_id, TRUE, opt_ev);
if (store_type == ConfigArchiver_STORE_MASK_PREVIOUS)
prev_doc = location_client_load_rollback_data (location, NULL, 0, backend_id, FALSE, opt_ev);
if (store_type == ConfigArchiver_STORE_COMPARE_PARENT) {
subtract_xml_doc (xml_doc, parent_doc, FALSE);
} else {
subtract_xml_doc (parent_doc, prev_doc, FALSE);
subtract_xml_doc (xml_doc, parent_doc, TRUE);
}
xmlFreeDoc (parent_doc);
if (prev_doc != NULL)
xmlFreeDoc (prev_doc);
}
if (parent != CORBA_OBJECT_NIL)
bonobo_object_release_unref (parent, NULL);
filename = ConfigArchiver_Location_getStorageFilename
(location, backend_id, store_type == ConfigArchiver_STORE_DEFAULT, opt_ev);
if (!BONOBO_EX (opt_ev) && filename != NULL) {
xmlSaveFile (filename, xml_doc);
ConfigArchiver_Location_storageComplete (location, filename, opt_ev);
CORBA_free (filename);
}
if (opt_ev == &my_ev)
CORBA_exception_free (opt_ev);
}
static void
merge_xml_docs (xmlDocPtr child_doc, xmlDocPtr parent_doc)
{
merge_xml_nodes (xmlDocGetRootElement (child_doc),
xmlDocGetRootElement (parent_doc));
}
static void
subtract_xml_doc (xmlDocPtr child_doc, xmlDocPtr parent_doc, gboolean strict)
{
subtract_xml_node (xmlDocGetRootElement (child_doc),
xmlDocGetRootElement (parent_doc), strict);
}
/* Merge contents of node1 and node2, where node1 overrides node2 as
* appropriate
*
* Notes: Two XML nodes are considered to be "the same" iff their names and
* all names and values of their attributes are the same. If that is not the
* case, they are considered "different" and will both be present in the
* merged node. If nodes are "the same", then this algorithm is called
* recursively. If nodes are CDATA, then node1 overrides node2 and the
* resulting node is just node1. The node merging is order-independent; child
* node from one tree are compared with all child nodes of the other tree
* regardless of the order they appear in. Hence one may have documents with
* different node orderings and the algorithm should still run correctly. It
* will not, however, run correctly in cases when the agent using this
* facility depends on the nodes being in a particular order.
*
* This XML node merging/comparison facility requires that the following
* standard be set for DTDs:
*
* Attributes' sole purpose is to identify a node. For example, a network
* configuration DTD might have an element like <interface name="eth0"> with a
* bunch of child nodes to configure that interface. The attribute "name" does
* not specify the configuration for the interface. It differentiates the node
* from the configuration for, say, interface eth1. Conversely, a node must be
* completely identified by its attributes. One cannot include identification
* information in the node's children, since otherwise the merging and
* subtraction algorithms will not know what to look for.
*
* As a corollary to the above, all configuration information must ultimately
* be in text nodes. For example, a text string might be stored as
* <configuration-item>my-value</configuration-item> but never as
* <configuration-item value="my-value"/>. As an example, if the latter is
* used, a child location might override a parent's setting for
* configuration-item. This algorithm will interpret those as different nodes
* and include them both in the merged result, since it will not have any way
* of knowing that they are really the same node with different
* configuration.
*/
static void
merge_xml_nodes (xmlNodePtr node1, xmlNodePtr node2)
{
xmlNodePtr child, tmp, iref;
GList *node1_children = NULL, *i;
gboolean found;
if (node1->type == XML_TEXT_NODE)
return;
for (child = node1->childs; child != NULL; child = child->next)
node1_children = g_list_prepend (node1_children, child);
node1_children = g_list_reverse (node1_children);
child = node2->childs;
while (child != NULL) {
tmp = child->next;
i = node1_children; found = FALSE;
while (i != NULL) {
iref = (xmlNodePtr) i->data;
if (compare_xml_nodes (iref, child)) {
merge_xml_nodes (iref, child);
if (i == node1_children)
node1_children = node1_children->next;
g_list_remove_link (node1_children, i);
g_list_free_1 (i);
found = TRUE;
break;
} else {
i = i->next;
}
}
if (found == FALSE) {
xmlUnlinkNode (child);
xmlAddChild (node1, child);
}
child = tmp;
}
g_list_free (node1_children);
}
/* Modifies node1 so that it only contains the parts different from node2;
* returns the modified node or NULL if the node should be destroyed
*
* strict determines whether the settings themselves are compared; it should
* be set to FALSE when the trees are being compared for the purpose of
* seeing what settings should be included in a tree and TRUE when one wants
* to restrict the settings included in a tree to those that have already been
* specified
*/
static xmlNodePtr
subtract_xml_node (xmlNodePtr node1, xmlNodePtr node2, gboolean strict)
{
xmlNodePtr child, tmp, iref;
GList *node2_children = NULL, *i;
gboolean found, same, all_same = TRUE;
if (node1->type == XML_TEXT_NODE) {
if (node2->type == XML_TEXT_NODE &&
(strict || !strcmp (xmlNodeGetContent (node1),
xmlNodeGetContent (node2))))
return NULL;
else
return node1;
}
if (node1->childs == NULL && node2->childs == NULL)
return NULL;
for (child = node2->childs; child != NULL; child = child->next)
node2_children = g_list_prepend (node2_children, child);
node2_children = g_list_reverse (node2_children);
child = node1->childs;
while (child != NULL) {
tmp = child->next;
i = node2_children; found = FALSE; all_same = TRUE;
while (i != NULL) {
iref = (xmlNodePtr) i->data;
if (compare_xml_nodes (child, iref)) {
same = (subtract_xml_node
(child, iref, strict) == NULL);
all_same = all_same && same;
if (same) {
xmlUnlinkNode (child);
xmlFreeNode (child);
}
if (i == node2_children)
node2_children = node2_children->next;
g_list_remove_link (node2_children, i);
g_list_free_1 (i);
found = TRUE;
break;
} else {
i = i->next;
}
}
if (!found)
all_same = FALSE;
child = tmp;
}
g_list_free (node2_children);
if (all_same)
return NULL;
else
return node1;
}
/* Return TRUE iff node1 and node2 are "the same" in the sense defined above */
static gboolean
compare_xml_nodes (xmlNodePtr node1, xmlNodePtr node2)
{
xmlAttrPtr attr;
gint count = 0;
if (strcmp (node1->name, node2->name))
return FALSE;
/* FIXME: This is worst case O(n^2), which can add up. Could we
* optimize for the case where people have attributes in the same
* order, or does not not matter? It probably does not matter, though,
* since people don't generally have more than one or two attributes
* in a tag anyway.
*/
for (attr = node1->properties; attr != NULL; attr = attr->next) {
g_assert (xmlNodeIsText (attr->val));
if (strcmp (xmlNodeGetContent (attr->val),
xmlGetProp (node2, attr->name)))
return FALSE;
count++;
}
/* FIXME: Is checking if the two nodes have the same number of
* attributes the correct policy here? Should we instead merge the
* attribute(s) that node1 is missing?
*/
for (attr = node2->properties; attr != NULL; attr = attr->next)
count--;
if (count == 0)
return TRUE;
else
return FALSE;
}

View File

@@ -1,46 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* archiver-client.h
* Copyright (C) 2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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 __ARCHIVER_CLIENT_H
#define __ARCHIVER_CLIENT_H
#include <gnome.h>
#include <gnome-xml/tree.h>
#include <time.h>
#include "ConfigArchiver.h"
xmlDocPtr location_client_load_rollback_data (ConfigArchiver_Location location,
const struct tm *date,
guint steps,
const gchar *backend_id,
gboolean parent_chain,
CORBA_Environment *opt_ev);
void location_client_store_xml (ConfigArchiver_Location location,
const gchar *backend_id,
xmlDocPtr xml_doc,
ConfigArchiver_StoreType store_type,
CORBA_Environment *opt_ev);
#endif /* __ARCHIVER_CLIENT_H */

View File

@@ -1,122 +0,0 @@
Rollback archiving internals
Copyright (C) 2001 Ximian Code, Inc.
Written by Bradford Hovinen <hovinen@ximian.com>
1. Directory format
Diagram:
+ toplevel
|-+ Location 1
| |- <id>.xml
| | .
| | .
| | .
| |- metadata.log:
| | [<id> <date> <time> <backend> ] ^
| | [ . ] | Time
| | [ . ] |
| | [ . ] |
| \- metadata.xml:
| [... ]
| [<inherits>location</inherits> ]
| [<contains backend-id="backend" type="full|partial"/> ]
| [... ]
|-+ Location 2
| ...
There is one toplevel directory for each archive. This directory
contains one or more location directories. Each location directory
must contain two files: an XML file describing the location and a log
of changes made in that location. Each change corresponds to an XML
file containing a snapshot of the configuration as modified. There is
one XML file per backend. Each change has an id number that is
incremented atomicall by the archiving script when it stores
configuration changes. The id number, as well as the date and time of
storage, form a filename that uniquely identifies each configuration
change. The archiving script must also store in the log file a line
with the id number, date and time of storage, and backend used
whenever it stores XML data. New entries are stored at the head of the
file, so that during rollback, the file may be foreward scanned to
find the appropriate identifier for the configuration file. The
per-location XML configuration file contains information on what the
location's parent is and what configurations that location defines.
For now, the backend shall be referred to by its executable name. When
the backends gain CORBA interfaces, I suggest that the OAF id be used
instead. This reduces the problem of setting a backend's configuration
to a simple object activation and method invocation. The OAF id may
also be used to resolve the backend's human-readable name.
2. Meta-configuration details
In order that this system be complete, there must be a way to
ascertain the current location and to roll back changes in location. I
propose that there be a special archive in the configuration hierarchy
that contains location history in the same format as other
locations. The archiver can then be a single script that accepts
command-line arguments describing the request action: `archive this
data', `roll back this backend's configuration', and `switch to this
location'. It then handles all the details of interfacing with the
archive and applying the changes in the correct order. Conceptually,
the archiver becomes a backend in and of itself, where the frontend is
located in the GUI of HCM. It would therefore be adviseable to use the
same standards for the archiver as for other backends and hence make
it a CORBA service, where the tool-specific interface is as described
above.
3. Fine-grained location management
A slight modification of the basic location management system allows
individual settings to be covered by a location as well as entire
backends. The contains tag in a location's metadata file contains the
attribute type, which may either by "full" or "partial". In the former
case, rollback proceeds as described above. If it is the latter, the
archiver, upon rolling back or setting configuration for the relevant
backend in that location, first retrieves the required configuration
from both the location and its parent using the same algorithm. It
then uses an XML merging algorithm to combine the two XML files into
one, allowing the child location's data to override its parent's
data. This can be accomplished using the same technique as Bonobo uses
to allow components to override toolbars and menus in the container.
When a child location partially defines the data for a particular
backend, it must store only those configuration settings that the user
explicitly changed when updating that backend's configuration under
that location. If the frontend simply dumped its entire XML snapshot
to the log, all of the configuration settings would be reflected in
that snapshot, and under the method indicated above, partial
containment would be equivalent to full containment. Therefore, when a
frontend stores its configuration under partial containment, the
archiver must run a node-for-node comparison between the XML data of
the parent location (retrieved using the method indicated above) and
that of the child location. Only those nodes that are different are
actually stored in the configuration log.
When comparing XML nodes, there must be a way to identify distinct
nodes for comparison. For example, in a network configuration backend,
there might be one node for each interface. If, under the parent
location, the nodes are ordered with interface "eth0" before interface
"eth1", while under the child location, they are in reverse order, but
the configuration is otherwise identical, it is not the intention of
the user that child location should override any configuration data of
the parent location. Therefore, the best method for comparing XML data
is to compare each child of a given node in one source to all the
children of the relevant node in the other source. If any child in the
other source matches, then the XML node is a duplicate and may be
thrown out. If there is another node such that the name and attributes
are the same, but the children are different, then the algorithm
should be invoked recursively to determine the differences among the
children. If there is no such node, then the node should be included.
4. Future directions
The metafile log structure may run into scalability problems for
installations have have been in place for a long time. An alternative
structure that uses binary indexing might be in order. A command line
utility (with GUI interface) could be written to recover the file in
the case of corruption; such a utility could simply introspect each of
the XML files in a directory. Provided that each XML file contains
enough information to create a file entry, which is trivial, recovery
is assured.

View File

@@ -1,363 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* backend-list.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@ximian.com>
*
* 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, 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.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <parser.h>
#include <tree.h>
#include "backend-list.h"
enum {
ARG_0,
ARG_IS_GLOBAL
};
struct _BackendListPrivate
{
gboolean is_global;
gchar *filename;
GList *backend_ids;
};
#define BACKEND_LIST_FROM_SERVANT(servant) (BACKEND_LIST (bonobo_object_from_servant (servant)))
static BonoboXObjectClass *parent_class;
static void backend_list_init (BackendList *backend_list);
static void backend_list_class_init (BackendListClass *class);
static void backend_list_set_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void backend_list_get_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void backend_list_finalize (GtkObject *object);
static void do_load (BackendList *backend_list);
static void do_save (BackendList *backend_list);
/* CORBA interface methods */
static CORBA_boolean
impl_ConfigArchiver_BackendList_contains (PortableServer_Servant servant,
const CORBA_char *backend_id,
CORBA_Environment *ev)
{
return backend_list_contains (BACKEND_LIST_FROM_SERVANT (servant), backend_id);
}
static void
impl_ConfigArchiver_BackendList_add (PortableServer_Servant servant,
const CORBA_char *backend_id,
CORBA_Environment *ev)
{
backend_list_add (BACKEND_LIST_FROM_SERVANT (servant), backend_id);
}
static void
impl_ConfigArchiver_BackendList_remove (PortableServer_Servant servant,
const CORBA_char *backend_id,
CORBA_Environment *ev)
{
backend_list_remove (BACKEND_LIST_FROM_SERVANT (servant), backend_id);
}
static void
impl_ConfigArchiver_BackendList_save (PortableServer_Servant servant,
CORBA_Environment *ev)
{
backend_list_save (BACKEND_LIST_FROM_SERVANT (servant));
}
static ConfigArchiver_StringSeq *
impl_ConfigArchiver_BackendList__get_backends (PortableServer_Servant servant,
CORBA_Environment *ev)
{
ConfigArchiver_StringSeq *seq;
BackendList *backend_list = BACKEND_LIST_FROM_SERVANT (servant);
guint i = 0;
GList *node;
g_return_val_if_fail (backend_list != NULL, NULL);
g_return_val_if_fail (IS_BACKEND_LIST (backend_list), NULL);
seq = ConfigArchiver_StringSeq__alloc ();
seq->_length = g_list_length (backend_list->p->backend_ids);
seq->_buffer = CORBA_sequence_CORBA_string_allocbuf (seq->_length);
CORBA_sequence_set_release (seq, TRUE);
for (node = backend_list->p->backend_ids; node != NULL; node = node->next)
seq->_buffer[i++] = CORBA_string_dup (node->data);
return seq;
}
BONOBO_X_TYPE_FUNC_FULL (BackendList, ConfigArchiver_BackendList, BONOBO_X_OBJECT_TYPE, backend_list);
static void
backend_list_init (BackendList *backend_list)
{
backend_list->p = g_new0 (BackendListPrivate, 1);
}
static void
backend_list_class_init (BackendListClass *class)
{
GtkObjectClass *object_class;
gtk_object_add_arg_type ("BackendList::is-global",
GTK_TYPE_INT,
GTK_ARG_CONSTRUCT_ONLY | GTK_ARG_READWRITE,
ARG_IS_GLOBAL);
object_class = GTK_OBJECT_CLASS (class);
object_class->finalize = backend_list_finalize;
object_class->set_arg = backend_list_set_arg;
object_class->get_arg = backend_list_get_arg;
class->epv.contains = impl_ConfigArchiver_BackendList_contains;
class->epv.add = impl_ConfigArchiver_BackendList_add;
class->epv.remove = impl_ConfigArchiver_BackendList_remove;
class->epv.save = impl_ConfigArchiver_BackendList_save;
class->epv._get_backends = impl_ConfigArchiver_BackendList__get_backends;
parent_class = BONOBO_X_OBJECT_CLASS
(gtk_type_class (BONOBO_X_OBJECT_TYPE));
}
static void
backend_list_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
BackendList *backend_list;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_BACKEND_LIST (object));
backend_list = BACKEND_LIST (object);
switch (arg_id) {
case ARG_IS_GLOBAL:
backend_list->p->is_global = GTK_VALUE_INT (*arg);
backend_list->p->filename = backend_list->p->is_global ?
LOCATION_DIR "/default-global.xml" :
LOCATION_DIR "/default-user.xml";
do_load (backend_list);
break;
default:
g_warning ("Bad argument set");
break;
}
}
static void
backend_list_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
BackendList *backend_list;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_BACKEND_LIST (object));
backend_list = BACKEND_LIST (object);
switch (arg_id) {
case ARG_IS_GLOBAL:
GTK_VALUE_INT (*arg) = backend_list->p->is_global;
break;
default:
g_warning ("Bad argument get");
break;
}
}
static void
backend_list_finalize (GtkObject *object)
{
BackendList *backend_list;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_BACKEND_LIST (object));
backend_list = BACKEND_LIST (object);
g_list_foreach (backend_list->p->backend_ids, (GFunc) g_free, NULL);
g_list_free (backend_list->p->backend_ids);
g_free (backend_list->p);
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
BonoboObject *
backend_list_new (gboolean is_global)
{
return BONOBO_OBJECT
(gtk_object_new (backend_list_get_type (),
"is-global", is_global,
NULL));
}
gboolean
backend_list_contains (BackendList *backend_list, const gchar *backend_id)
{
GList *node;
g_return_val_if_fail (backend_list != NULL, FALSE);
g_return_val_if_fail (IS_BACKEND_LIST (backend_list), FALSE);
for (node = backend_list->p->backend_ids; node != NULL;
node = node->next)
if (!strcmp (node->data, backend_id))
return TRUE;
return FALSE;
}
/**
* backend_list_foreach:
* @backend_list:
* @callback:
* @data:
*
* Iterates through all the backends, invoking the callback given and aborting
* if any callback returns a nonzero value
*
* Return value: TRUE iff no callback issued a nonzero value, FALSE otherwise
**/
gboolean
backend_list_foreach (BackendList *backend_list, BackendCB callback,
gpointer data)
{
GList *node;
g_return_val_if_fail (backend_list != NULL, FALSE);
g_return_val_if_fail (IS_BACKEND_LIST (backend_list), FALSE);
g_return_val_if_fail (callback != NULL, FALSE);
for (node = backend_list->p->backend_ids; node; node = node->next)
if (callback (backend_list, node->data, data)) return FALSE;
return TRUE;
}
void
backend_list_add (BackendList *backend_list, const gchar *backend_id)
{
g_return_if_fail (backend_list != NULL);
g_return_if_fail (IS_BACKEND_LIST (backend_list));
g_return_if_fail (backend_id != NULL);
backend_list->p->backend_ids =
g_list_prepend (backend_list->p->backend_ids, g_strdup (backend_id));
}
void
backend_list_remove (BackendList *backend_list, const gchar *backend_id)
{
gchar *tmp;
GList *node;
g_return_if_fail (backend_list != NULL);
g_return_if_fail (IS_BACKEND_LIST (backend_list));
g_return_if_fail (backend_id != NULL);
tmp = g_strdup (backend_id);
node = g_list_find (backend_list->p->backend_ids, tmp);
backend_list->p->backend_ids =
g_list_remove_link (backend_list->p->backend_ids, node);
g_free (node->data);
g_free (tmp);
g_list_free_1 (node);
}
void
backend_list_save (BackendList *backend_list)
{
g_return_if_fail (backend_list != NULL);
g_return_if_fail (IS_BACKEND_LIST (backend_list));
do_save (backend_list);
}
static void
do_load (BackendList *backend_list)
{
xmlNodePtr root_node, node;
xmlDocPtr doc;
GList *list_tail = NULL;
gchar *contains_str;
doc = xmlParseFile (backend_list->p->filename);
if (doc == NULL) return;
root_node = xmlDocGetRootElement (doc);
for (node = root_node->childs; node; node = node->next) {
if (!strcmp (node->name, "contains")) {
contains_str = xmlGetProp (node, "backend");
if (contains_str != NULL) {
contains_str = g_strdup (contains_str);
list_tail = g_list_append (list_tail,
contains_str);
if (backend_list->p->backend_ids == NULL)
backend_list->p->backend_ids =
list_tail;
else
list_tail = list_tail->next;
} else {
g_warning ("Bad backends list: " \
"contains element with no " \
"backend attribute");
}
}
}
}
static void
do_save (BackendList *backend_list)
{
xmlNodePtr root_node, child_node;
xmlDocPtr doc;
GList *node;
doc = xmlNewDoc ("1.0");
root_node = xmlNewDocNode (doc, NULL, "location", NULL);
for (node = backend_list->p->backend_ids; node; node = node->next) {
child_node = xmlNewChild (root_node, NULL, "contains", NULL);
xmlNewProp (child_node, "backend", node->data);
}
xmlDocSetRootElement (doc, root_node);
xmlSaveFile (backend_list->p->filename, doc);
xmlFreeDoc (doc);
}

View File

@@ -1,78 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* backend-list.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@ximian.com>
*
* 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, 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 __BACKEND_LIST_H
#define __BACKEND_LIST_H
#include <gnome.h>
#include <bonobo.h>
#include "ConfigArchiver.h"
BEGIN_GNOME_DECLS
#define BACKEND_LIST(obj) GTK_CHECK_CAST (obj, backend_list_get_type (), BackendList)
#define BACKEND_LIST_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, backend_list_get_type (), BackendListClass)
#define IS_BACKEND_LIST(obj) GTK_CHECK_TYPE (obj, backend_list_get_type ())
typedef struct _BackendList BackendList;
typedef struct _BackendListClass BackendListClass;
typedef struct _BackendListPrivate BackendListPrivate;
typedef gint (*BackendCB) (BackendList *, gchar *, gpointer);
struct _BackendList
{
BonoboXObject parent;
BackendListPrivate *p;
};
struct _BackendListClass
{
BonoboXObjectClass parent_class;
POA_ConfigArchiver_BackendList__epv epv;
};
GType backend_list_get_type (void);
BonoboObject *backend_list_new (gboolean is_global);
gboolean backend_list_contains (BackendList *backend_list,
const gchar *backend_id);
gboolean backend_list_foreach (BackendList *backend_list,
BackendCB callback,
gpointer data);
void backend_list_add (BackendList *backend_list,
const gchar *backend_id);
void backend_list_remove (BackendList *backend_list,
const gchar *backend_id);
void backend_list_save (BackendList *backend_list);
END_GNOME_DECLS
#endif /* __BACKEND_LIST_H */

View File

@@ -1,942 +0,0 @@
/**
* bonobo-config-archiver.c: XML configuration database with an interface to
* the XML archiver
*
* Author:
* Dietmar Maurer (dietmar@ximian.com)
* Bradford Hovinen <hovinen@ximian.com>
*
* Copyright 2000, 2001 Ximian, Inc.
*/
#include <config.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <bonobo.h>
#include <bonobo-conf/bonobo-config-utils.h>
#include <gnome-xml/xmlmemory.h>
#include <gtk/gtkmain.h>
#include "util.h"
#include "bonobo-config-archiver.h"
static GtkObjectClass *parent_class = NULL;
#define CLASS(o) BONOBO_CONFIG_ARCHIVER_CLASS (GTK_OBJECT(o)->klass)
#define PARENT_TYPE BONOBO_CONFIG_DATABASE_TYPE
#define FLUSH_INTERVAL 30 /* 30 seconds */
/* Small Bonobo bug here... */
#undef BONOBO_RET_EX
#define BONOBO_RET_EX(ev) \
G_STMT_START{ \
if (BONOBO_EX (ev)) \
return; \
}G_STMT_END
extern int daytime;
static DirEntry *
dir_lookup_entry (DirData *dir,
char *name,
gboolean create)
{
GSList *l;
DirEntry *de;
l = dir->entries;
while (l) {
de = (DirEntry *)l->data;
if (!strcmp (de->name, name))
return de;
l = l->next;
}
if (create) {
de = g_new0 (DirEntry, 1);
de->dir = dir;
de->name = g_strdup (name);
dir->entries = g_slist_prepend (dir->entries, de);
return de;
}
return NULL;
}
static DirData *
dir_lookup_subdir (DirData *dir,
char *name,
gboolean create)
{
GSList *l;
DirData *dd;
l = dir->subdirs;
while (l) {
dd = (DirData *)l->data;
if (!strcmp (dd->name, name))
return dd;
l = l->next;
}
if (create) {
dd = g_new0 (DirData, 1);
dd->dir = dir;
dd->name = g_strdup (name);
dir->subdirs = g_slist_prepend (dir->subdirs, dd);
return dd;
}
return NULL;
}
static DirData *
lookup_dir (DirData *dir,
const char *path,
gboolean create)
{
const char *s, *e;
char *name;
DirData *dd = dir;
s = path;
while (*s == '/') s++;
if (*s == '\0')
return dir;
if ((e = strchr (s, '/')))
name = g_strndup (s, e - s);
else
name = g_strdup (s);
if ((dd = dir_lookup_subdir (dd, name, create))) {
if (e)
dd = lookup_dir (dd, e, create);
g_free (name);
return dd;
} else {
g_free (name);
}
return NULL;
}
static DirEntry *
lookup_dir_entry (BonoboConfigArchiver *archiver_db,
const char *key,
gboolean create)
{
char *dir_name;
char *leaf_name;
DirEntry *de;
DirData *dd;
if ((dir_name = bonobo_config_dir_name (key))) {
dd = lookup_dir (archiver_db->dir, dir_name, create);
if (dd && !dd->node) {
dd->node = xmlNewChild (archiver_db->doc->root, NULL,
"section", NULL);
xmlSetProp (dd->node, "path", dir_name);
}
g_free (dir_name);
} else {
dd = archiver_db->dir;
if (!dd->node)
dd->node = xmlNewChild (archiver_db->doc->root, NULL,
"section", NULL);
}
if (!dd)
return NULL;
if (!(leaf_name = bonobo_config_leaf_name (key)))
return NULL;
de = dir_lookup_entry (dd, leaf_name, create);
g_free (leaf_name);
return de;
}
static CORBA_any *
real_get_value (BonoboConfigDatabase *db,
const CORBA_char *key,
const CORBA_char *locale,
CORBA_Environment *ev)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db);
DirEntry *de;
CORBA_any *value = NULL;
de = lookup_dir_entry (archiver_db, key, FALSE);
if (!de) {
bonobo_exception_set (ev, ex_Bonobo_ConfigDatabase_NotFound);
return NULL;
}
if (de->value)
return bonobo_arg_copy (de->value);
/* localized value */
if (de->node && de->node->childs && de->node->childs->next)
value = bonobo_config_xml_decode_any ((BonoboUINode *)de->node,
locale, ev);
if (!value)
bonobo_exception_set (ev, ex_Bonobo_ConfigDatabase_NotFound);
return value;
}
/* Produce a new, dynamically allocated string with the OAF IID of the listener
* associated with the given backend id
*/
static gchar *
get_listener_oafiid (const gchar *backend_id)
{
gchar *oafiid, *tmp, *tmp1;
tmp = g_strdup (backend_id);
if ((tmp1 = strstr (tmp, "-properties")) != NULL) *tmp1 = '\0';
oafiid = g_strconcat ("OAFIID:Bonobo_Listener_Config_", tmp, NULL);
g_free (tmp);
return oafiid;
}
static void
real_sync (BonoboConfigDatabase *db,
CORBA_Environment *ev)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db);
BonoboArg *arg;
gchar *listener_oafiid;
Bonobo_Listener listener;
if (!db->writeable)
return;
/* FIXME: This will not work correctly in the pathlogical case that two
* ConfigArchiver objects sync at almost exactly the same time.
*/
archiver_db->is_up_to_date = TRUE;
location_client_store_xml (archiver_db->location, archiver_db->backend_id,
archiver_db->doc, ConfigArchiver_STORE_MASK_PREVIOUS, ev);
BONOBO_RET_EX (ev);
/* Try to find a listener to apply the settings. If we can't, don't
* worry about it
*/
listener_oafiid = get_listener_oafiid (archiver_db->backend_id);
listener = bonobo_get_object (listener_oafiid, "IDL:Bonobo/Listener:1.0", ev);
g_free (listener_oafiid);
if (BONOBO_EX (ev)) {
listener = CORBA_OBJECT_NIL;
CORBA_exception_init (ev);
}
arg = bonobo_arg_new (BONOBO_ARG_NULL);
bonobo_event_source_notify_listeners (archiver_db->es, "Bonobo/ConfigDatabase:sync", arg, ev);
bonobo_arg_release (arg);
if (listener != CORBA_OBJECT_NIL)
bonobo_object_release_unref (listener, NULL);
}
static void
notify_listeners (BonoboConfigArchiver *archiver_db,
const char *key,
const CORBA_any *value)
{
CORBA_Environment ev;
char *dir_name;
char *leaf_name;
char *ename;
if (GTK_OBJECT_DESTROYED (archiver_db))
return;
if (!key)
return;
CORBA_exception_init (&ev);
ename = g_strconcat ("Bonobo/Property:change:", key, NULL);
bonobo_event_source_notify_listeners (archiver_db->es, ename, value, &ev);
g_free (ename);
if (!(dir_name = bonobo_config_dir_name (key)))
dir_name = g_strdup ("");
if (!(leaf_name = bonobo_config_leaf_name (key)))
leaf_name = g_strdup ("");
ename = g_strconcat ("Bonobo/ConfigDatabase:change", dir_name, ":",
leaf_name, NULL);
bonobo_event_source_notify_listeners (archiver_db->es, ename, value, &ev);
CORBA_exception_free (&ev);
g_free (ename);
g_free (dir_name);
g_free (leaf_name);
}
static void
real_set_value (BonoboConfigDatabase *db,
const CORBA_char *key,
const CORBA_any *value,
CORBA_Environment *ev)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db);
DirEntry *de;
char *name;
de = lookup_dir_entry (archiver_db, key, TRUE);
if (de->value)
CORBA_free (de->value);
de->value = bonobo_arg_copy (value);
if (de->node) {
xmlUnlinkNode (de->node);
xmlFreeNode (de->node);
}
name = bonobo_config_leaf_name (key);
de->node = (xmlNodePtr) bonobo_config_xml_encode_any (value, name, ev);
g_free (name);
bonobo_ui_node_add_child ((BonoboUINode *)de->dir->node,
(BonoboUINode *)de->node);
notify_listeners (archiver_db, key, value);
}
static Bonobo_KeyList *
real_list_dirs (BonoboConfigDatabase *db,
const CORBA_char *dir,
CORBA_Environment *ev)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db);
Bonobo_KeyList *key_list;
DirData *dd, *sub;
GSList *l;
int len;
key_list = Bonobo_KeyList__alloc ();
key_list->_length = 0;
if (!(dd = lookup_dir (archiver_db->dir, dir, FALSE)))
return key_list;
if (!(len = g_slist_length (dd->subdirs)))
return key_list;
key_list->_buffer = CORBA_sequence_CORBA_string_allocbuf (len);
CORBA_sequence_set_release (key_list, TRUE);
for (l = dd->subdirs; l != NULL; l = l->next) {
sub = (DirData *)l->data;
key_list->_buffer [key_list->_length] =
CORBA_string_dup (sub->name);
key_list->_length++;
}
return key_list;
}
static Bonobo_KeyList *
real_list_keys (BonoboConfigDatabase *db,
const CORBA_char *dir,
CORBA_Environment *ev)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db);
Bonobo_KeyList *key_list;
DirData *dd;
DirEntry *de;
GSList *l;
int len;
key_list = Bonobo_KeyList__alloc ();
key_list->_length = 0;
if (!(dd = lookup_dir (archiver_db->dir, dir, FALSE)))
return key_list;
if (!(len = g_slist_length (dd->entries)))
return key_list;
key_list->_buffer = CORBA_sequence_CORBA_string_allocbuf (len);
CORBA_sequence_set_release (key_list, TRUE);
for (l = dd->entries; l != NULL; l = l->next) {
de = (DirEntry *)l->data;
key_list->_buffer [key_list->_length] =
CORBA_string_dup (de->name);
key_list->_length++;
}
return key_list;
}
static CORBA_boolean
real_dir_exists (BonoboConfigDatabase *db,
const CORBA_char *dir,
CORBA_Environment *ev)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db);
if (lookup_dir (archiver_db->dir, dir, FALSE))
return TRUE;
return FALSE;
}
static void
delete_dir_entry (DirEntry *de)
{
CORBA_free (de->value);
if (de->node) {
xmlUnlinkNode (de->node);
xmlFreeNode (de->node);
}
g_free (de->name);
g_free (de);
}
static void
real_remove_value (BonoboConfigDatabase *db,
const CORBA_char *key,
CORBA_Environment *ev)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db);
DirEntry *de;
if (!(de = lookup_dir_entry (archiver_db, key, FALSE)))
return;
de->dir->entries = g_slist_remove (de->dir->entries, de);
delete_dir_entry (de);
}
static void
delete_dir_data (DirData *dd, gboolean is_root)
{
GSList *l;
for (l = dd->subdirs; l; l = l->next)
delete_dir_data ((DirData *)l->data, FALSE);
g_slist_free (dd->subdirs);
dd->subdirs = NULL;
for (l = dd->entries; l; l = l->next)
delete_dir_entry ((DirEntry *)l->data);
g_slist_free (dd->entries);
dd->entries = NULL;
if (!is_root) {
g_free (dd->name);
if (dd->node) {
xmlUnlinkNode (dd->node);
xmlFreeNode (dd->node);
}
g_free (dd);
}
}
static void
real_remove_dir (BonoboConfigDatabase *db,
const CORBA_char *dir,
CORBA_Environment *ev)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db);
DirData *dd;
if (!(dd = lookup_dir (archiver_db->dir, dir, FALSE)))
return;
if (dd != archiver_db->dir && dd->dir)
dd->dir->subdirs = g_slist_remove (dd->dir->subdirs, dd);
delete_dir_data (dd, dd == archiver_db->dir);
}
static void
pb_get_fn (BonoboPropertyBag *bag, BonoboArg *arg,
guint arg_id, CORBA_Environment *ev,
gpointer user_data)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (user_data);
time_t val;
val = ConfigArchiver_Location_getModificationTime
(archiver_db->location, archiver_db->backend_id, ev);
BONOBO_ARG_SET_GENERAL (arg, val, TC_ulonglong, CORBA_unsigned_long_long, NULL);
}
static void
pb_set_fn (BonoboPropertyBag *bag, const BonoboArg *arg,
guint arg_id, CORBA_Environment *ev,
gpointer user_data)
{
g_assert_not_reached ();
}
static void
bonobo_config_archiver_destroy (GtkObject *object)
{
BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (object);
CORBA_Environment ev;
DEBUG_MSG ("Enter");
CORBA_exception_init (&ev);
if (archiver_db->moniker != NULL) {
bonobo_url_unregister ("BONOBO_CONF:ARCHIVER", archiver_db->moniker, &ev);
g_free (archiver_db->moniker);
if (BONOBO_EX (&ev)) {
g_critical ("Could not unregister the archiver URL");
CORBA_exception_init (&ev);
}
}
if (archiver_db->listener_id != 0) {
bonobo_event_source_client_remove_listener
(archiver_db->location, archiver_db->listener_id, &ev);
if (BONOBO_EX (&ev))
g_critical ("Could not remove the rollback data listener");
}
CORBA_exception_free (&ev);
if (archiver_db->doc != NULL) {
delete_dir_data (archiver_db->dir, TRUE);
archiver_db->dir = NULL;
xmlFreeDoc (archiver_db->doc);
}
if (archiver_db->filename != NULL)
g_free (archiver_db->filename);
if (archiver_db->fp != NULL)
fclose (archiver_db->fp);
if (archiver_db->location != CORBA_OBJECT_NIL)
bonobo_object_release_unref (archiver_db->location, NULL);
if (archiver_db->archive != CORBA_OBJECT_NIL)
bonobo_object_release_unref (archiver_db->archive, NULL);
parent_class->destroy (object);
DEBUG_MSG ("Exit");
}
static void
bonobo_config_archiver_class_init (BonoboConfigDatabaseClass *class)
{
GtkObjectClass *object_class = (GtkObjectClass *) class;
BonoboConfigDatabaseClass *cd_class;
parent_class = gtk_type_class (PARENT_TYPE);
object_class->destroy = bonobo_config_archiver_destroy;
cd_class = BONOBO_CONFIG_DATABASE_CLASS (class);
cd_class->get_value = real_get_value;
cd_class->set_value = real_set_value;
cd_class->list_dirs = real_list_dirs;
cd_class->list_keys = real_list_keys;
cd_class->dir_exists = real_dir_exists;
cd_class->remove_value = real_remove_value;
cd_class->remove_dir = real_remove_dir;
cd_class->sync = real_sync;
}
static void
bonobo_config_archiver_init (BonoboConfigArchiver *archiver_db)
{
archiver_db->dir = g_new0 (DirData, 1);
/* This will always be writeable */
BONOBO_CONFIG_DATABASE (archiver_db)->writeable = TRUE;
}
BONOBO_X_TYPE_FUNC (BonoboConfigArchiver, PARENT_TYPE, bonobo_config_archiver);
static void
read_section (DirData *dd)
{
CORBA_Environment ev;
DirEntry *de;
xmlNodePtr s;
gchar *name;
CORBA_exception_init (&ev);
s = dd->node->childs;
while (s) {
if (s->type == XML_ELEMENT_NODE &&
!strcmp (s->name, "entry") &&
(name = xmlGetProp(s, "name"))) {
de = dir_lookup_entry (dd, name, TRUE);
de->node = s;
/* we only decode it if it is a single value,
* multiple (localized) values are decoded in the
* get_value function */
if (!(s->childs && s->childs->next))
de->value = bonobo_config_xml_decode_any
((BonoboUINode *)s, NULL, &ev);
xmlFree (name);
}
s = s->next;
}
CORBA_exception_free (&ev);
}
static void
fill_cache (BonoboConfigArchiver *archiver_db)
{
xmlNodePtr n;
gchar *path;
DirData *dd;
n = archiver_db->doc->root->childs;
while (n) {
if (n->type == XML_ELEMENT_NODE &&
!strcmp (n->name, "section")) {
path = xmlGetProp(n, "path");
if (!path || !strcmp (path, "")) {
dd = archiver_db->dir;
} else
dd = lookup_dir (archiver_db->dir, path, TRUE);
if (!dd->node)
dd->node = n;
read_section (dd);
xmlFree (path);
}
n = n->next;
}
}
/* parse_name
*
* Given a moniker with a backend id and (possibly) a location id encoded
* therein, parse out the backend id and the location id and set the pointers
* given to them.
*
* FIXME: Is this encoding really the way we want to do this? Ask Dietmar and
* Michael.
*/
static gboolean
parse_name (const gchar *name, gchar **backend_id, gchar **location, struct tm **date)
{
gchar *e, *e1, *time_str = NULL;
*date = NULL;
if (name[0] == '[') {
e = strchr (name + 1, '|');
if (e != NULL) {
*location = g_strndup (name + 1, e - (name + 1));
e1 = strchr (e + 1, ']');
if (e1 != NULL) {
time_str = g_strndup (e + 1, e1 - (e + 1));
*date = parse_date (time_str);
g_free (time_str);
}
*backend_id = g_strdup (e1 + 1);
} else {
e = strchr (name + 1, ']');
if (e != NULL)
*location = g_strndup (name + 1, e - (name + 1));
else
return FALSE;
*backend_id = g_strdup (e + 1);
}
} else {
*backend_id = g_strdup (name);
*location = NULL;
}
if (*location != NULL && **location == '\0') {
g_free (*location);
*location = NULL;
}
return TRUE;
}
static void
new_rollback_cb (BonoboListener *listener,
gchar *event_name,
CORBA_any *any,
CORBA_Environment *ev,
BonoboConfigArchiver *archiver_db)
{
BonoboArg *arg;
if (archiver_db->is_up_to_date) {
archiver_db->is_up_to_date = FALSE;
return;
}
if (archiver_db->dir != NULL) {
delete_dir_data (archiver_db->dir, TRUE);
g_free (archiver_db->dir->name);
g_free (archiver_db->dir);
archiver_db->dir = g_new0 (DirData, 1);
}
if (archiver_db->doc != NULL)
xmlFreeDoc (archiver_db->doc);
archiver_db->doc = location_client_load_rollback_data
(archiver_db->location, NULL, 0, archiver_db->backend_id, TRUE, ev);
if (archiver_db->doc == NULL)
g_critical ("Could not load new rollback data");
else
fill_cache (archiver_db);
arg = bonobo_arg_new (BONOBO_ARG_NULL);
bonobo_event_source_notify_listeners (archiver_db->es, "Bonobo/ConfigDatabase:sync", arg, ev);
bonobo_arg_release (arg);
}
Bonobo_ConfigDatabase
bonobo_config_archiver_new (Bonobo_Moniker parent,
const Bonobo_ResolveOptions *options,
const char *moniker,
CORBA_Environment *ev)
{
BonoboConfigArchiver *archiver_db;
Bonobo_ConfigDatabase db;
ConfigArchiver_Archive archive;
ConfigArchiver_Location location;
gchar *moniker_tmp;
gchar *backend_id;
gchar *location_id;
struct tm *date;
g_return_val_if_fail (backend_id != NULL, NULL);
/* Check the Bonobo URL database to see if this archiver database has
* already been created, and return it if it has */
moniker_tmp = g_strdup (moniker);
db = bonobo_url_lookup ("BONOBO_CONF:ARCHIVER", moniker_tmp, ev);
g_free (moniker_tmp);
if (BONOBO_EX (ev)) {
db = CORBA_OBJECT_NIL;
CORBA_exception_init (ev);
}
if (db != CORBA_OBJECT_NIL)
return bonobo_object_dup_ref (db, NULL);
/* Parse out the backend id, location id, and rollback date from the
* moniker given */
if (parse_name (moniker, &backend_id, &location_id, &date) < 0) {
EX_SET_NOT_FOUND (ev);
return CORBA_OBJECT_NIL;
}
/* Resolve the parent archive and the location */
archive = Bonobo_Moniker_resolve (parent, options, "IDL:ConfigArchiver/Archive:1.0", ev);
if (BONOBO_EX (ev) || archive == CORBA_OBJECT_NIL) {
g_free (location_id);
g_free (date);
return CORBA_OBJECT_NIL;
}
if (location_id == NULL || *location_id == '\0')
location = ConfigArchiver_Archive__get_currentLocation (archive, ev);
else
location = ConfigArchiver_Archive_getLocation (archive, location_id, ev);
g_free (location_id);
if (location == CORBA_OBJECT_NIL) {
g_free (date);
bonobo_object_release_unref (archive, NULL);
return CORBA_OBJECT_NIL;
}
/* Construct the database object proper and fill in its values */
if ((archiver_db = gtk_type_new (BONOBO_CONFIG_ARCHIVER_TYPE)) == NULL) {
g_free (date);
return CORBA_OBJECT_NIL;
}
archiver_db->backend_id = backend_id;
archiver_db->moniker = g_strdup (moniker);
archiver_db->archive = archive;
archiver_db->location = location;
/* Load the XML data, or use the defaults file if none are present */
archiver_db->doc = location_client_load_rollback_data
(archiver_db->location, date, 0, archiver_db->backend_id, TRUE, ev);
g_free (date);
if (BONOBO_EX (ev) || archiver_db->doc == NULL) {
gchar *filename;
filename = g_strconcat (GNOMECC_DEFAULTS_DIR "/", archiver_db->backend_id, ".xml", NULL);
archiver_db->doc = xmlParseFile (filename);
g_free (filename);
if (archiver_db->doc == NULL) {
bonobo_object_release_unref (archiver_db->location, NULL);
bonobo_object_release_unref (archiver_db->archive, NULL);
bonobo_object_unref (BONOBO_OBJECT (archiver_db));
return CORBA_OBJECT_NIL;
}
CORBA_exception_init (ev);
}
/* Load data from the XML file */
if (archiver_db->doc->root == NULL)
archiver_db->doc->root =
xmlNewDocNode (archiver_db->doc, NULL, "bonobo-config", NULL);
if (strcmp (archiver_db->doc->root->name, "bonobo-config")) {
xmlFreeDoc (archiver_db->doc);
archiver_db->doc = xmlNewDoc("1.0");
archiver_db->doc->root =
xmlNewDocNode (archiver_db->doc, NULL, "bonobo-config", NULL);
}
fill_cache (archiver_db);
/* Construct the associated property bag and event source */
#if 0
archiver_db->es = bonobo_event_source_new ();
bonobo_object_add_interface (BONOBO_OBJECT (archiver_db),
BONOBO_OBJECT (archiver_db->es));
#endif
archiver_db->pb = bonobo_property_bag_new (pb_get_fn,
pb_set_fn,
archiver_db);
bonobo_object_add_interface (BONOBO_OBJECT (archiver_db),
BONOBO_OBJECT (archiver_db->pb));
archiver_db->es = archiver_db->pb->es;
bonobo_property_bag_add (archiver_db->pb,
"last_modified", 1, TC_ulonglong, NULL,
"Date (time_t) of modification",
BONOBO_PROPERTY_READABLE);
/* Listen for events pertaining to new rollback data */
if (date == NULL && location_id == NULL)
archiver_db->listener_id =
bonobo_event_source_client_add_listener
(location, (BonoboListenerCallbackFn) new_rollback_cb,
"ConfigArchiver/Location:newRollbackData", ev, archiver_db);
else
archiver_db->listener_id = 0;
/* Prepare to return the database object */
db = CORBA_Object_duplicate (BONOBO_OBJREF (archiver_db), NULL);
moniker_tmp = g_strdup (moniker);
bonobo_url_register ("BONOBO_CONF:ARCHIVER", moniker_tmp, NULL, db, ev);
g_free (moniker_tmp);
return db;
}

View File

@@ -1,89 +0,0 @@
/**
* bonobo-config-archiver.h: xml configuration database implementation, with
* interface to the archiver
*
* Author:
* Dietmar Maurer (dietmar@ximian.com)
* Bradford Hovinen <hovinen@ximian.com>
*
* Copyright 2000 Ximian, Inc.
*/
#ifndef __BONOBO_CONFIG_ARCHIVER_H__
#define __BONOBO_CONFIG_ARCHIVER_H__
#include <stdio.h>
#include <bonobo-conf/bonobo-config-database.h>
#include <gnome-xml/tree.h>
#include <gnome-xml/parser.h>
#include <bonobo/bonobo-event-source.h>
#include <bonobo/bonobo-property-bag.h>
#include "archiver-client.h"
BEGIN_GNOME_DECLS
#define EX_SET_NOT_FOUND(ev) bonobo_exception_set (ev, ex_Bonobo_Moniker_InterfaceNotFound)
#define BONOBO_CONFIG_ARCHIVER_TYPE (bonobo_config_archiver_get_type ())
#define BONOBO_CONFIG_ARCHIVER(o) (GTK_CHECK_CAST ((o), BONOBO_CONFIG_ARCHIVER_TYPE, BonoboConfigArchiver))
#define BONOBO_CONFIG_ARCHIVER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), BONOBO_CONFIG_ARCHIVER_TYPE, BonoboConfigArchiverClass))
#define BONOBO_IS_CONFIG_ARCHIVER(o) (GTK_CHECK_TYPE ((o), BONOBO_CONFIG_ARCHIVER_TYPE))
#define BONOBO_IS_CONFIG_ARCHIVER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), BONOBO_CONFIG_ARCHIVER_TYPE))
typedef struct _DirData DirData;
struct _DirData {
char *name;
GSList *entries;
GSList *subdirs;
xmlNodePtr node;
DirData *dir;
};
typedef struct {
char *name;
CORBA_any *value;
xmlNodePtr node;
DirData *dir;
} DirEntry;
typedef struct _BonoboConfigArchiver BonoboConfigArchiver;
struct _BonoboConfigArchiver {
BonoboConfigDatabase base;
char *filename;
FILE *fp;
xmlDocPtr doc;
DirData *dir;
guint time_id;
ConfigArchiver_Archive archive;
ConfigArchiver_Location location;
gchar *backend_id;
gchar *moniker;
BonoboEventSource *es;
BonoboPropertyBag *pb;
Bonobo_EventSource_ListenerId listener_id;
gboolean is_up_to_date;
};
typedef struct {
BonoboConfigDatabaseClass parent_class;
} BonoboConfigArchiverClass;
GtkType
bonobo_config_archiver_get_type (void);
Bonobo_ConfigDatabase
bonobo_config_archiver_new (Bonobo_Moniker parent,
const Bonobo_ResolveOptions *options,
const char *moniker,
CORBA_Environment *ev);
END_GNOME_DECLS
#endif /* ! __BONOBO_CONFIG_ARCHIVER_H__ */

View File

@@ -1,146 +0,0 @@
/*
* bonobo-moniker-archiver.c: archiver xml database moniker implementation
*
* Author:
* Dietmar Maurer (dietmar@ximian.com)
* Bradford Hovinen <hovinen@ximian.com>
*
* Copyright 2001 Ximian, Inc.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <bonobo.h>
#include "bonobo-config-archiver.h"
#include "archive.h"
#include "util.h"
static Archive *user_archive = NULL;
static Archive *global_archive = NULL;
static void
archive_destroy_cb (Archive *archive)
{
if (archive == global_archive)
global_archive = NULL;
else if (archive == user_archive)
user_archive = NULL;
}
static Bonobo_Unknown
archive_resolve (BonoboMoniker *moniker,
const Bonobo_ResolveOptions *options,
const CORBA_char *requested_interface,
CORBA_Environment *ev)
{
const gchar *name;
Bonobo_Unknown ret;
if (strcmp (requested_interface, "IDL:ConfigArchiver/Archive:1.0")) {
EX_SET_NOT_FOUND (ev);
return CORBA_OBJECT_NIL;
}
name = bonobo_moniker_get_name (moniker);
if (!strcmp (name, "global-archive")) {
if (global_archive == NULL) {
global_archive = ARCHIVE (archive_load (TRUE));
gtk_signal_connect (GTK_OBJECT (global_archive), "destroy", GTK_SIGNAL_FUNC (archive_destroy_cb), NULL);
ret = CORBA_Object_duplicate (BONOBO_OBJREF (global_archive), ev);
} else {
ret = bonobo_object_dup_ref (BONOBO_OBJREF (global_archive), ev);
}
if (BONOBO_EX (ev)) {
g_critical ("Cannot duplicate object");
bonobo_object_release_unref (ret, NULL);
ret = CORBA_OBJECT_NIL;
}
}
else if (!strcmp (name, "user-archive")) {
if (user_archive == NULL) {
user_archive = ARCHIVE (archive_load (FALSE));
gtk_signal_connect (GTK_OBJECT (user_archive), "destroy", GTK_SIGNAL_FUNC (archive_destroy_cb), NULL);
ret = CORBA_Object_duplicate (BONOBO_OBJREF (user_archive), ev);
} else {
ret = bonobo_object_dup_ref (BONOBO_OBJREF (user_archive), ev);
}
if (BONOBO_EX (ev)) {
g_critical ("Cannot duplicate object");
bonobo_object_release_unref (ret, NULL);
ret = CORBA_OBJECT_NIL;
}
} else {
EX_SET_NOT_FOUND (ev);
ret = CORBA_OBJECT_NIL;
}
return ret;
}
static Bonobo_Unknown
archiverdb_resolve (BonoboMoniker *moniker,
const Bonobo_ResolveOptions *options,
const CORBA_char *requested_interface,
CORBA_Environment *ev)
{
Bonobo_Moniker parent;
Bonobo_ConfigDatabase db;
const gchar *name;
if (strcmp (requested_interface, "IDL:Bonobo/ConfigDatabase:1.0")) {
EX_SET_NOT_FOUND (ev);
return CORBA_OBJECT_NIL;
}
parent = bonobo_moniker_get_parent (moniker, ev);
if (BONOBO_EX (ev))
return CORBA_OBJECT_NIL;
if (parent == CORBA_OBJECT_NIL) {
EX_SET_NOT_FOUND (ev);
return CORBA_OBJECT_NIL;
}
name = bonobo_moniker_get_name (moniker);
db = bonobo_config_archiver_new (parent, options, name, ev);
if (db == CORBA_OBJECT_NIL || BONOBO_EX (ev))
EX_SET_NOT_FOUND (ev);
bonobo_object_release_unref (parent, NULL);
return db;
}
static BonoboObject *
bonobo_moniker_archiver_factory (BonoboGenericFactory *this,
const char *object_id,
void *closure)
{
if (!strcmp (object_id, "OAFIID:Bonobo_Moniker_archiverdb")) {
return BONOBO_OBJECT (bonobo_moniker_simple_new
("archiverdb:", archiverdb_resolve));
}
else if (!strcmp (object_id, "OAFIID:Bonobo_Moniker_archive")) {
return BONOBO_OBJECT (bonobo_moniker_simple_new
("archive:", archive_resolve));
} else {
g_warning ("Failing to manufacture a '%s'", object_id);
}
return NULL;
}
BONOBO_OAF_FACTORY_MULTI ("OAFIID:Bonobo_Moniker_archiver_Factory",
"bonobo xml archiver database moniker", "1.0",
bonobo_moniker_archiver_factory,
NULL);

View File

@@ -1,222 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* cluster-location.c
* Copyright (C) 2000 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@helixcode.com>
*
* 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, 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.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "cluster.h"
#include "cluster-location.h"
typedef struct _pair_t pair_t;
enum {
ARG_0,
ARG_SAMPLE
};
struct _ClusterLocationPrivate
{
/* Private data members */
};
struct _pair_t
{
gpointer a, b;
};
static LocationClass *parent_class;
static void cluster_location_init (ClusterLocation *cluster_location);
static void cluster_location_class_init (ClusterLocationClass *class);
static void cluster_location_set_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void cluster_location_get_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void cluster_location_finalize (GtkObject *object);
static gboolean cluster_location_do_rollback (Location *location,
gchar *backend_id,
xmlDocPtr doc);
static gboolean host_cb (Cluster *cluster,
gchar *hostname,
pair_t *pair);
GType
cluster_location_get_type (void)
{
static GType cluster_location_type = 0;
if (!cluster_location_type) {
GtkTypeInfo cluster_location_info = {
"ClusterLocation",
sizeof (ClusterLocation),
sizeof (ClusterLocationClass),
(GtkClassInitFunc) cluster_location_class_init,
(GtkObjectInitFunc) cluster_location_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL
};
cluster_location_type =
gtk_type_unique (location_get_type (),
&cluster_location_info);
}
return cluster_location_type;
}
static void
cluster_location_init (ClusterLocation *cluster_location)
{
cluster_location->p = g_new0 (ClusterLocationPrivate, 1);
}
static void
cluster_location_class_init (ClusterLocationClass *class)
{
GtkObjectClass *object_class;
LocationClass *location_class;
gtk_object_add_arg_type ("ClusterLocation::sample",
GTK_TYPE_POINTER,
GTK_ARG_READWRITE,
ARG_SAMPLE);
object_class = GTK_OBJECT_CLASS (class);
object_class->finalize = cluster_location_finalize;
object_class->set_arg = cluster_location_set_arg;
object_class->get_arg = cluster_location_get_arg;
location_class = LOCATION_CLASS (class);
location_class->do_rollback = cluster_location_do_rollback;
parent_class = LOCATION_CLASS
(gtk_type_class (location_get_type ()));
}
static void
cluster_location_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
ClusterLocation *cluster_location;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER_LOCATION (object));
cluster_location = CLUSTER_LOCATION (object);
switch (arg_id) {
case ARG_SAMPLE:
break;
default:
g_warning ("Bad argument set");
break;
}
}
static void
cluster_location_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
ClusterLocation *cluster_location;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER_LOCATION (object));
cluster_location = CLUSTER_LOCATION (object);
switch (arg_id) {
case ARG_SAMPLE:
break;
default:
g_warning ("Bad argument get");
break;
}
}
static void
cluster_location_finalize (GtkObject *object)
{
ClusterLocation *cluster_location;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER_LOCATION (object));
cluster_location = CLUSTER_LOCATION (object);
g_free (cluster_location->p);
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
GtkObject *
cluster_location_new (void)
{
return gtk_object_new (cluster_location_get_type (),
NULL);
}
static gboolean
cluster_location_do_rollback (Location *location, gchar *backend_id,
xmlDocPtr doc)
{
Cluster *cluster;
pair_t pair;
g_return_val_if_fail (location != NULL, FALSE);
g_return_val_if_fail (IS_CLUSTER_LOCATION (location), FALSE);
g_return_val_if_fail (backend_id != NULL, FALSE);
g_return_val_if_fail (doc != NULL, FALSE);
gtk_object_get (GTK_OBJECT (location), "archive", &cluster, NULL);
pair.a = doc;
pair.b = backend_id;
cluster_foreach_host (cluster, (ClusterHostCB) host_cb, &pair);
return TRUE;
}
static gboolean
host_cb (Cluster *cluster, gchar *hostname, pair_t *pair)
{
xmlDocPtr doc;
gchar *backend_id, *command;
FILE *output;
doc = pair->a;
backend_id = pair->b;
command = g_strconcat ("ssh ", hostname, " ", backend_id, " --set",
NULL);
output = popen (command, "w");
xmlDocDump (output, doc);
pclose (output);
g_free (command);
return FALSE;
}

View File

@@ -1,59 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* cluster-location.h
* Copyright (C) 2000 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@helixcode.com>
*
* 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, 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 __CLUSTER_LOCATION_H
#define __CLUSTER_LOCATION_H
#include <gnome.h>
#include "location.h"
BEGIN_GNOME_DECLS
#define CLUSTER_LOCATION(obj) GTK_CHECK_CAST (obj, cluster_location_get_type (), ClusterLocation)
#define CLUSTER_LOCATION_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cluster_location_get_type (), ClusterLocationClass)
#define IS_CLUSTER_LOCATION(obj) GTK_CHECK_TYPE (obj, cluster_location_get_type ())
typedef struct _ClusterLocation ClusterLocation;
typedef struct _ClusterLocationClass ClusterLocationClass;
typedef struct _ClusterLocationPrivate ClusterLocationPrivate;
struct _ClusterLocation
{
Location parent;
ClusterLocationPrivate *p;
};
struct _ClusterLocationClass
{
LocationClass location_class;
};
GType cluster_location_get_type (void);
GtkObject *cluster_location_new (void);
END_GNOME_DECLS
#endif /* __CLUSTER_LOCATION_H */

View File

@@ -1,437 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* cluster.c
* Copyright (C) 2000 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@helixcode.com>
*
* 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, 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.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <parser.h>
#include "cluster.h"
enum {
ARG_0,
ARG_SAMPLE
};
typedef struct _SlaveHost SlaveHost;
struct _SlaveHost
{
gchar *hostname;
};
struct _ClusterPrivate
{
GList *slave_hosts;
};
static ArchiveClass *parent_class;
static void cluster_init (Cluster *cluster);
static void cluster_class_init (ClusterClass *class);
static void cluster_set_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void cluster_get_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void cluster_destroy (GtkObject *object);
static void cluster_finalize (GtkObject *object);
static gboolean cluster_construct (Cluster *cluster,
gboolean is_new);
static gboolean load_metadata (Cluster *cluster);
static void save_metadata (Cluster *cluster);
static void cluster_add_slave_host (Cluster *cluster,
SlaveHost *slave_host);
static void cluster_remove_slave_host (Cluster *cluster,
SlaveHost *slave_host);
static SlaveHost *find_slave_host (Cluster *cluster,
gchar *hostname);
static gchar *get_metadata_filename (Cluster *cluster);
static SlaveHost *slave_host_new (gchar *hostname);
static SlaveHost *slave_host_read_xml (xmlNodePtr node);
static xmlNodePtr slave_host_write_xml (SlaveHost *host);
GType
cluster_get_type (void)
{
static GType cluster_type = 0;
if (!cluster_type) {
GtkTypeInfo cluster_info = {
"Cluster",
sizeof (Cluster),
sizeof (ClusterClass),
(GtkClassInitFunc) cluster_class_init,
(GtkObjectInitFunc) cluster_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL
};
cluster_type =
gtk_type_unique (archive_get_type (),
&cluster_info);
}
return cluster_type;
}
static void
cluster_init (Cluster *cluster)
{
cluster->p = g_new0 (ClusterPrivate, 1);
}
static void
cluster_class_init (ClusterClass *class)
{
GtkObjectClass *object_class;
gtk_object_add_arg_type ("Cluster::sample",
GTK_TYPE_POINTER,
GTK_ARG_READWRITE,
ARG_SAMPLE);
object_class = GTK_OBJECT_CLASS (class);
object_class->destroy = cluster_destroy;
object_class->finalize = cluster_finalize;
object_class->set_arg = cluster_set_arg;
object_class->get_arg = cluster_get_arg;
parent_class = ARCHIVE_CLASS
(gtk_type_class (archive_get_type ()));
}
static void
cluster_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
Cluster *cluster;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER (object));
cluster = CLUSTER (object);
switch (arg_id) {
case ARG_SAMPLE:
break;
default:
g_warning ("Bad argument set");
break;
}
}
static void
cluster_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
Cluster *cluster;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER (object));
cluster = CLUSTER (object);
switch (arg_id) {
case ARG_SAMPLE:
break;
default:
g_warning ("Bad argument get");
break;
}
}
static void
cluster_destroy (GtkObject *object)
{
Cluster *cluster;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER (object));
cluster = CLUSTER (object);
save_metadata (cluster);
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
cluster_finalize (GtkObject *object)
{
Cluster *cluster;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER (object));
cluster = CLUSTER (object);
g_free (cluster->p);
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
GtkObject *
cluster_new (gchar *prefix)
{
GtkObject *object;
object = gtk_object_new (cluster_get_type (),
"prefix", prefix,
"is-global", TRUE,
NULL);
if (cluster_construct (CLUSTER (object), TRUE) == FALSE) {
gtk_object_destroy (object);
return NULL;
}
return object;
}
GtkObject *
cluster_load (gchar *prefix)
{
GtkObject *object;
object = gtk_object_new (cluster_get_type (),
"prefix", prefix,
"is-global", TRUE,
NULL);
if (cluster_construct (CLUSTER (object), FALSE) == FALSE) {
gtk_object_destroy (object);
return NULL;
}
return object;
}
void
cluster_foreach_host (Cluster *cluster, ClusterHostCB callback, gpointer data)
{
GList *node;
SlaveHost *host;
g_return_if_fail (cluster != NULL);
g_return_if_fail (IS_CLUSTER (cluster));
g_return_if_fail (callback != NULL);
for (node = cluster->p->slave_hosts; node; node = node->next) {
host = node->data;
if (callback (cluster, host->hostname, data)) break;
}
}
void
cluster_add_host (Cluster *cluster, gchar *hostname)
{
g_return_if_fail (cluster != NULL);
g_return_if_fail (IS_CLUSTER (cluster));
g_return_if_fail (hostname != NULL);
cluster_add_slave_host (cluster, slave_host_new (hostname));
}
void
cluster_remove_host (Cluster *cluster, gchar *hostname)
{
g_return_if_fail (cluster != NULL);
g_return_if_fail (IS_CLUSTER (cluster));
g_return_if_fail (hostname != NULL);
cluster_remove_slave_host (cluster,
find_slave_host (cluster, hostname));
}
static gboolean
cluster_construct (Cluster *cluster, gboolean is_new)
{
if (archive_construct (ARCHIVE (cluster), is_new) == FALSE)
return FALSE;
if (!is_new) {
if (load_metadata (cluster) == FALSE)
return FALSE;
}
return TRUE;
}
/* Loads the metadata associated with the cluster; returns TRUE on success and
* FALSE on failure
*/
static gboolean
load_metadata (Cluster *cluster)
{
xmlDocPtr doc;
xmlNodePtr root_node, node;
gchar *filename;
SlaveHost *new_host;
filename = get_metadata_filename (cluster);
doc = xmlParseFile (filename);
g_free (filename);
if (doc == NULL) return FALSE;
root_node = xmlDocGetRootElement (doc);
if (strcmp (root_node->name, "cluster")) {
xmlFreeDoc (doc);
return FALSE;
}
for (node = root_node->childs; node != NULL; node = node->next) {
if (!strcmp (node->name, "host")) {
new_host = slave_host_read_xml (node);
if (new_host != NULL)
cluster_add_slave_host (cluster, new_host);
}
}
xmlFreeDoc (doc);
return TRUE;
}
static void
save_metadata (Cluster *cluster)
{
xmlDocPtr doc;
xmlNodePtr root_node;
GList *list_node;
gchar *filename;
doc = xmlNewDoc ("1.0");
root_node = xmlNewDocNode (doc, NULL, "cluster", NULL);
for (list_node = cluster->p->slave_hosts; list_node != NULL;
list_node = list_node->next)
{
xmlAddChild (root_node,
slave_host_write_xml (list_node->data));
}
xmlDocSetRootElement (doc, root_node);
filename = get_metadata_filename (cluster);
xmlSaveFile (filename, doc);
g_free (filename);
}
/* Adds a slave host to the list of slave hosts for this cluster */
static void
cluster_add_slave_host (Cluster *cluster, SlaveHost *slave_host)
{
if (slave_host == NULL) return;
cluster->p->slave_hosts =
g_list_append (cluster->p->slave_hosts, slave_host);
}
static void
cluster_remove_slave_host (Cluster *cluster, SlaveHost *slave_host)
{
if (slave_host == NULL) return;
cluster->p->slave_hosts =
g_list_remove (cluster->p->slave_hosts, slave_host);
}
static SlaveHost *
find_slave_host (Cluster *cluster, gchar *hostname)
{
SlaveHost *host;
GList *node;
g_return_val_if_fail (hostname != NULL, NULL);
for (node = cluster->p->slave_hosts; node != NULL; node = node->next) {
host = node->data;
if (!strcmp (host->hostname, hostname))
return host;
}
return NULL;
}
/* Returns the filename of the metadata file (should be freed after use) */
static gchar *
get_metadata_filename (Cluster *cluster)
{
return g_concat_dir_and_file
(archive_get_prefix (ARCHIVE (cluster)), "cluster.xml");
}
/* Constructs a new slave host structure */
static SlaveHost *
slave_host_new (gchar *hostname)
{
SlaveHost *new_host;
new_host = g_new0 (SlaveHost, 1);
new_host->hostname = g_strdup (hostname);
return new_host;
}
/* Constructs a new slave host structure from an XML node */
static SlaveHost *
slave_host_read_xml (xmlNodePtr node)
{
gchar *hostname;
hostname = xmlGetProp (node, "name");
if (hostname != NULL)
return slave_host_new (hostname);
else
return NULL;
}
/* Constructs an XML node for the slave host */
static xmlNodePtr
slave_host_write_xml (SlaveHost *host)
{
xmlNodePtr node;
node = xmlNewNode (NULL, "host");
xmlNewProp (node, "name", host->hostname);
return node;
}

View File

@@ -1,71 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* cluster.h
* Copyright (C) 2000 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@helixcode.com>
*
* 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, 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 __CLUSTER_H
#define __CLUSTER_H
#include <gnome.h>
#include "archive.h"
BEGIN_GNOME_DECLS
#define CLUSTER(obj) GTK_CHECK_CAST (obj, cluster_get_type (), Cluster)
#define CLUSTER_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cluster_get_type (), ClusterClass)
#define IS_CLUSTER(obj) GTK_CHECK_TYPE (obj, cluster_get_type ())
typedef struct _Cluster Cluster;
typedef struct _ClusterClass ClusterClass;
typedef struct _ClusterPrivate ClusterPrivate;
typedef gboolean (*ClusterHostCB) (Cluster *, gchar *, gpointer);
struct _Cluster
{
Archive parent;
ClusterPrivate *p;
};
struct _ClusterClass
{
ArchiveClass archive_class;
};
GType cluster_get_type (void);
GtkObject *cluster_new (gchar *prefix);
GtkObject *cluster_load (gchar *prefix);
void cluster_foreach_host (Cluster *cluster,
ClusterHostCB callback,
gpointer data);
void cluster_add_host (Cluster *cluster,
gchar *hostname);
void cluster_remove_host (Cluster *cluster,
gchar *hostname);
END_GNOME_DECLS
#endif /* __CLUSTER_H */

View File

@@ -1,439 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* main.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <sys/file.h>
#include <unistd.h>
#include <errno.h>
#include <gnome.h>
#include <bonobo.h>
#include <gnome-xml/parser.h>
#include "archiver-client.h"
#include "util.h"
/* Variables resulting from command line parsing */
static gboolean store;
static gboolean rollback;
static gboolean change_location;
static gboolean rename_location;
static gboolean push_config;
static gboolean garbage_collect;
static gboolean add_location;
static gboolean remove_location;
static gboolean add_backend;
static gboolean remove_backend;
static gboolean global;
static const gchar *location_id;
static gchar *backend_id;
static gboolean compare_parent;
static gboolean mask_previous;
static gchar *date_str;
static gboolean all;
static gchar *revision_id;
static gboolean last;
static guint steps;
static gboolean show;
static gchar *parent_str;
static gchar *new_name;
static gboolean contain_full;
static gboolean contain_partial;
static gboolean master;
static struct poptOption archiver_operations[] = {
{"store", 's', POPT_ARG_NONE, &store, 0,
N_("Store XML data in the archive")},
{"rollback", 'r', POPT_ARG_NONE, &rollback, 0,
N_("Roll back the configuration to a given point")},
{"change-location", 'c', POPT_ARG_NONE, &change_location, 0,
N_("Change the location profile to the given one")},
{"push-config", 'p', POPT_ARG_NONE, &push_config, 0,
N_("Push configuration data out to client machines (UNIMPLEMENTED)")},
{"rename-location", '\0', POPT_ARG_NONE, &rename_location, 0,
N_("Rename a location to a new name")},
{"add-location", '\0', POPT_ARG_NONE, &add_location, 0,
N_("Add a new location to the archive")},
{"remove-location", '\0', POPT_ARG_NONE, &remove_location, 0,
N_("Remove a location from the archive")},
{"add-backend", '\0', POPT_ARG_NONE, &add_backend, 0,
N_("Add a given backend to the given location")},
{"remove-backend", '\0', POPT_ARG_NONE, &remove_backend, 0,
N_("Remove the given backend from the given location")},
{"garbage-collect", '\0', POPT_ARG_NONE, &garbage_collect, 0,
N_("Perform garbage collection on the given location")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption global_options[] = {
{"global", 'g', POPT_ARG_NONE, &global, 0,
N_("Use the global repository")},
{"location", 'l', POPT_ARG_STRING, &location_id, 0,
N_("Identifier of location profile on which to operate"),
N_("LOCATION")},
{"backend", 'b', POPT_ARG_STRING, &backend_id, 0,
N_("Backend being used for this operation"), N_("BACKEND_ID")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption store_options[] = {
{"compare-parent", '\0', POPT_ARG_NONE, &compare_parent, 0,
N_("Store only the differences with the parent location's config")},
{"mask-previous", '\0', POPT_ARG_NONE, &mask_previous, 0,
N_("Store only those settings set in the previous config")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption rollback_options[] = {
{"date", 'd', POPT_ARG_STRING, &date_str, 0,
N_("Date to which to roll back"), N_("DATE")},
{"all", 'a', POPT_ARG_NONE, &all, 0,
N_("Roll back all configuration items")},
{"revision-id", 'i', POPT_ARG_INT, &revision_id, 0,
N_("Roll back to the revision REVISION_ID"), N_("REVISION_ID")},
{"last", 't', POPT_ARG_NONE, &last, 0,
N_("Roll back to the last known revision")},
{"steps", '\0', POPT_ARG_INT, &steps, 0,
N_("Roll back by STEPS revisions"), N_("STEPS")},
{"show", 'h', POPT_ARG_NONE, &show, 0,
N_("Don't run the backend, just dump the output")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption add_rename_location_options[] = {
{"parent", '\0', POPT_ARG_STRING, &parent_str, 0,
N_("Parent location for the new location"), N_("PARENT")},
{"new-name", '\0', POPT_ARG_STRING, &new_name, 0,
N_("New name to assign to the location"), N_("NEW_NAME")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption add_remove_backend_options[] = {
{"master", '\0', POPT_ARG_NONE, &master, 0,
N_("Add/remove this backend to/from the master backend list")},
{"full", '\0', POPT_ARG_NONE, &contain_full, 0,
N_("Full containment")},
{"partial", '\0', POPT_ARG_NONE, &contain_partial, 0,
N_("Partial containment")},
{NULL, '\0', 0, NULL, 0}
};
static xmlDocPtr
xml_load_from_stream (FILE *stream)
{
GString *str;
gchar buffer[4097];
xmlDocPtr doc;
size_t t;
str = g_string_new ("");
while (!feof (stream)) {
t = fread (buffer, sizeof (char), 4096, stream);
buffer[t] = '\0';
g_string_append (str, buffer);
}
doc = xmlParseDoc (str->str);
g_string_free (str, TRUE);
return doc;
}
static ConfigArchiver_StringSeq *
make_backend_id_seq (gchar *backend_id, ...)
{
ConfigArchiver_StringSeq *seq;
seq = ConfigArchiver_StringSeq__alloc ();
seq->_length = 1;
seq->_buffer = CORBA_sequence_CORBA_string_allocbuf (1);
seq->_buffer[0] = CORBA_string_dup (backend_id);
return seq;
}
static void
do_store (ConfigArchiver_Location location, CORBA_Environment *ev)
{
ConfigArchiver_StoreType type;
xmlDocPtr doc;
if (!backend_id) {
fprintf (stderr, "No backend specified\n");
return;
}
if (mask_previous)
type = ConfigArchiver_STORE_MASK_PREVIOUS;
else if (compare_parent)
type = ConfigArchiver_STORE_COMPARE_PARENT;
else
type = ConfigArchiver_STORE_FULL;
doc = xml_load_from_stream (stdin);
location_client_store_xml (location, backend_id, doc, type, ev);
}
static void
do_rollback (ConfigArchiver_Location location, CORBA_Environment *ev)
{
struct tm *date = NULL;
ConfigArchiver_StringSeq *seq;
ConfigArchiver_Time tm;
xmlDocPtr doc;
if (date_str)
date = parse_date (date_str);
else if (last || steps > 0)
date = NULL;
else if (!revision_id) {
fprintf (stderr, "No date specified\n");
return;
}
if (backend_id != NULL && (date != NULL || last)) {
/* FIXME: Need to support specifying multiple backends */
if (show) {
doc = location_client_load_rollback_data (location, date, 0, backend_id, TRUE, ev);
xmlDocDump (stdout, doc);
xmlFreeDoc (doc);
} else {
tm = mktime (date);
seq = make_backend_id_seq (backend_id, NULL);
ConfigArchiver_Location_rollbackBackends (location, tm, 0, seq, TRUE, ev);
CORBA_free (seq);
}
}
else if (backend_id != NULL && steps != 0) {
if (show) {
doc = location_client_load_rollback_data (location, date, steps, backend_id, TRUE, ev);
xmlDocDump (stdout, doc);
xmlFreeDoc (doc);
} else {
seq = make_backend_id_seq (backend_id, NULL);
ConfigArchiver_Location_rollbackBackends (location, 0, steps, seq, TRUE, ev);
CORBA_free (seq);
}
} else {
g_message ("No backend specified\n");
return;
}
}
static void
do_change_location (ConfigArchiver_Archive archive, ConfigArchiver_Location location, CORBA_Environment *ev)
{
ConfigArchiver_Archive__set_currentLocation (archive, location, ev);
}
static void
do_rename_location (ConfigArchiver_Archive archive, ConfigArchiver_Location location, CORBA_Environment *ev)
{
gboolean is_current;
CORBA_char *locid, *cid;
if (new_name == NULL) {
fprintf (stderr, "You did not specify a new name. Try --help\n");
} else {
locid = ConfigArchiver_Location__get_id (location, ev);
cid = ConfigArchiver_Archive__get_currentLocationId (archive, ev);
if (!strcmp (locid, cid))
is_current = TRUE;
else
is_current = FALSE;
CORBA_free (locid);
CORBA_free (cid);
ConfigArchiver_Location__set_id (location, new_name, ev);
if (is_current)
ConfigArchiver_Archive__set_currentLocationId (archive, new_name, ev);
}
}
static void
do_add_location (ConfigArchiver_Archive archive, CORBA_Environment *ev)
{
ConfigArchiver_Location parent_location = CORBA_OBJECT_NIL;
if (location_id == NULL) {
fprintf (stderr, "Error: You did not specify a location name\n");
return;
}
if (parent_str != NULL) {
parent_location = ConfigArchiver_Archive_getLocation (archive, parent_str, ev);
if (parent_location == NULL && !strcmp (parent_str, "default"))
parent_location =
ConfigArchiver_Archive_createLocation (archive, "default", _("Default Location"),
CORBA_OBJECT_NIL, ev);
}
ConfigArchiver_Archive_createLocation (archive, location_id, location_id, parent_location, ev);
}
static void
do_remove_location (ConfigArchiver_Location location, CORBA_Environment *ev)
{
ConfigArchiver_Location_delete (location, ev);
}
static void
do_add_backend (ConfigArchiver_Location location, CORBA_Environment *ev)
{
ConfigArchiver_ContainmentType type;
if (contain_full && contain_partial) {
fprintf (stderr, "Error: Cannot have both full and partial "
"containment\n");
return;
}
else if (contain_partial) {
type = ConfigArchiver_CONTAIN_PARTIAL;
} else {
type = ConfigArchiver_CONTAIN_FULL;
}
ConfigArchiver_Location_addBackend (location, backend_id, type, ev);
}
static void
do_remove_backend (ConfigArchiver_Location location, CORBA_Environment *ev)
{
ConfigArchiver_Location_removeBackend (location, backend_id, ev);
}
static void
do_garbage_collect (ConfigArchiver_Location location, CORBA_Environment *ev)
{
ConfigArchiver_Location_garbageCollect (location, ev);
}
int
main (int argc, char **argv)
{
CORBA_ORB orb;
ConfigArchiver_Archive archive;
ConfigArchiver_Location location = CORBA_OBJECT_NIL;
CORBA_Environment ev;
/* For Electric Fence */
free (malloc (1));
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
CORBA_exception_init (&ev);
gnomelib_register_popt_table (global_options,
_("Global archiver options"));
gnomelib_register_popt_table (archiver_operations,
_("Archiver commands"));
gnomelib_register_popt_table (store_options,
_("Options for storing data"));
gnomelib_register_popt_table (rollback_options,
_("Options for rolling back"));
gnomelib_register_popt_table (add_rename_location_options,
_("Options for adding or renaming " \
"locations"));
gnomelib_register_popt_table (add_remove_backend_options,
_("Options for adding and removing " \
"backends"));
gtk_type_init ();
gnomelib_init ("archiver", VERSION);
gnomelib_parse_args (argc, argv, 0);
orb = oaf_init (argc, argv);
if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
g_error ("Cannot initialize Bonobo");
if (global)
archive = bonobo_get_object ("archive:global-archive", "IDL:ConfigArchiver/Archive:1.0", &ev);
else
archive = bonobo_get_object ("archive:user-archive", "IDL:ConfigArchiver/Archive:1.0", &ev);
if (archive == CORBA_OBJECT_NIL) {
g_critical ("Could not open archive\n");
return -1;
}
if (!add_location) {
if (location_id == NULL)
location_id = ConfigArchiver_Archive__get_currentLocationId (archive, &ev);
location = ConfigArchiver_Archive_getLocation (archive, location_id, &ev);
if (location == CORBA_OBJECT_NIL) {
g_critical ("Error: Could not open location %s\n", location_id);
return -1;
}
}
if (store)
do_store (location, &ev);
else if (rollback)
do_rollback (location, &ev);
else if (change_location)
do_change_location (archive, location, &ev);
else if (rename_location)
do_rename_location (archive, location, &ev);
else if (add_location)
do_add_location (archive, &ev);
else if (remove_location)
do_remove_location (location, &ev);
else if (add_backend)
do_add_backend (location, &ev);
else if (remove_backend)
do_remove_backend (location, &ev);
else if (garbage_collect)
do_garbage_collect (location, &ev);
bonobo_object_release_unref (archive, NULL);
if (location != CORBA_OBJECT_NIL)
bonobo_object_release_unref (location, NULL);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,90 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* config-log.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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 __CONFIG_LOG_H
#define __CONFIG_LOG_H
#include <gnome.h>
#include <stdio.h>
#include <time.h>
#define CONFIG_LOG(obj) GTK_CHECK_CAST (obj, config_log_get_type (), ConfigLog)
#define CONFIG_LOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, config_log_get_type (), ConfigLogClass)
#define IS_CONFIG_LOG(obj) GTK_CHECK_TYPE (obj, config_log_get_type ())
typedef struct _ConfigLog ConfigLog;
typedef struct _ConfigLogClass ConfigLogClass;
typedef struct _ConfigLogPrivate ConfigLogPrivate;
typedef struct _Location Location;
typedef gint (*ConfigLogIteratorCB) (ConfigLog *, gint, gchar *,
struct tm *, gpointer);
typedef void (*GarbageCollectCB) (ConfigLog *, gchar *, gint, gpointer);
struct _ConfigLog
{
GtkObject object;
ConfigLogPrivate *p;
};
struct _ConfigLogClass
{
GtkObjectClass parent;
};
GType config_log_get_type (void);
GtkObject *config_log_open (Location *location);
void config_log_delete (ConfigLog *config_log);
gint config_log_get_rollback_id_for_date (ConfigLog *config_log,
struct tm *date,
const gchar *backend_id);
gint config_log_get_rollback_id_by_steps (ConfigLog *config_log,
guint steps,
const gchar *backend_id);
const gchar *config_log_get_backend_id_for_id (ConfigLog *config_log,
gint id);
const struct tm *config_log_get_date_for_id (ConfigLog *config_log,
gint id);
gint config_log_write_entry (ConfigLog *config_log,
const gchar *backend_id,
gboolean is_default_data);
void config_log_iterate (ConfigLog *config_log,
ConfigLogIteratorCB callback,
gpointer data);
void config_log_reset_filenames (ConfigLog *config_log);
void config_log_reload (ConfigLog *config_log);
void config_log_garbage_collect (ConfigLog *config_log,
gchar *backend_id,
GarbageCollectCB callback,
gpointer data);
#endif /* __CONFIG_LOG */

View File

@@ -1,54 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* config-manager.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@ximian.com>
*
* 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, 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include <glade/glade.h>
#include "config-manager-dialog.h"
int
main (int argc, char **argv)
{
GtkWidget *dialog;
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
gnome_init ("config-manager", VERSION, argc, argv);
glade_gnome_init ();
dialog = config_manager_dialog_new (CM_DIALOG_USER_ONLY);
gtk_widget_show (dialog);
gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
gtk_main_quit, NULL);
gtk_main ();
return 0;
}

View File

@@ -1,4 +0,0 @@
CONFIG_ARCHIVER_LIBDIR="@CONFIG_ARCHIVER_LIBDIR@"
CONFIG_ARCHIVER_LIBS="@CONFIG_ARCHIVER_LIBS@"
CONFIG_ARCHIVER_INCLUDEDIR="@CONFIG_ARCHIVER_INCLUDEDIR@"
MODULE_VERSION="config-archiver-@VERSION@"

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<location>
<contains backend="boot-conf"/>
<contains backend="disks-conf"/>
<contains backend="memory-conf"/>
<contains backend="network-conf"/>
<contains backend="print-conf"/>
<contains backend="shares-conf"/>
<contains backend="time-conf"/>
<contains backend="users-conf"/>
<contains backend="display-conf"/>
</location>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<location>
<contains backend="background-properties"/>
<contains backend="bell-properties-capplet"/>
<contains backend="sound-properties"/>
<contains backend="keyboard-properties"/>
<contains backend="mouse-properties"/>
<contains backend="screensaver-properties-capplet"/>
</location>

View File

@@ -1,95 +0,0 @@
Changes to the Helix Configuration Manager
Copyright (C) 2000 Ximian, Inc.
Written by Bradford Hovinen <hovinen@ximian.com>
As it stands, capplets and Ximian Setup Tools are both run as separate
processes through the exec() facility. It is planned that the capplets
shall become Bonobo controls in the future, once the OAF/gnorba
compatibility problems are worked out. This changes the design of the
configuration system considerably, and several things should be done
to take full advantage of these changes.
1. Capplets become Bonobo controls
It stands to reason that the front ends for Ximian Setup Tools should
become Bonobo controls at the same time as capplets. They can each
implement the same interface (say, Bonobo::Capplet) with methods
getXML(), setXML(), ok(), cancel(), and init() and hence look the same
to the shell. This means that the front ends for the Ximian Setup Tools
run as the same user as XCM and respond in the same way as capplets do
to requests to embed them in the XCM shell window. This is essential
for a consistent user interface that will not result in end-user
confusion [1]. XCM itself may then export an interface that includes
the method runBackend(), to which the frontend supplies a stream of
XML that XCM passes through the root manager to the backend via a
standard pipe [2]. The backend is then responsible for running the
program that archives the XML -- there is no other way to place that
XML in a central, system-wide repository. I suggest, therefore, that
we modify the design of the current system to make that change, so
that we do not have to undo existing work later.
2. Backends get CORBA interfaces through Perl/ORBit
At this point, there must be a way for the root manager to forward
CORBA sockets to the user securely. This could be done by modifying
ORBit so as to give the running program very precise control over the
nature of the socket. Access could be granted specifically to the user
running the root manager by placing the socket in a directory owned by
that user with permissions no more lax than 0700. When the CORBA
interfaces are created, applications will be able to make use of it to
make system-wide changes as necessary (say, to add a new user during
the installation of a piece of software). This means that the
traditional rollback facilities must be extended to allow users to
roll back changes made by applications. In addition, the application
must treat the backend as a black box -- it should never be expected
to do anything unusual to support rollback, since buggy or
poorly-written applications would otherwise cause trouble for
unsuspecting users.
At this point I suggest that each backend export two interfaces: one
that is universal to all backends and one that is specific to that
particular tool. The former may include the methods getXML(),
setXML(), and commit(). When changes are made through the
tool-specific interface, the tool decides whether or not to apply
those changes immediately or to queue them up until a commit() is
invoked. If changes are made through the backend's CORBA interface and
it is deactivated before a commit(), the backend must roll back those
changes under the assumption that they are not intended to be
permanent.
Of course, this makes implementation of the cancel() interface on the
frontends very easy -- simply deactivate the backend without
commit()ing. ok() can be implemented by flushing any remaining
changes, calling commit(), and then deactivating the backend. The
frontend can and should use the CORBA interface to invoke changes
whenever they are made, as long as it makes sense. It is then the
backend that sets the policy of whether or not the updates are live,
as described above. The frontend must still be able to read XML,
though, since it is through that that it will get an initial
description of the setup with which to fill in the dialog. In
addition, since the frontend may be invoked to make changes to an
inactive location, it should be able to write out an XML description
of the dialog's contents so that those changes may be archived rather
than applied immediately.
Notes
[1] A visual cue that signals to the user that he is running a
system-wide configuration tool rather than a personal one would be
advantageous. Such could take the form of an icon on the dialog, a
layout or formatting convention for the dialog proper, or some sort of
coloring convention of some of the controls. However, simply having
the tool run with root's Gtk+ theme and ignoring the embedding
preference, as would be the case if we do not Bonobize the HST
frontends, is inconsistent as many users will leave their themes as
the default and elect not to embed capplets -- eliminating all visual
cues. In addition, it is not particularly lucid and many users will
merely be confused by the inconsistent interface. One may imagine many
users filing bug reports in the belief that the behavior is
erroneous. Hence, that solution is insufficient.
[2] There must then be a method of multiplexing I/O throught the root
manager, as there may be multiple backends running concurrently. A
simple protocol could be implemented to do this, or a named pipe could
be created if done very carefully as to ensure a high degree of
security.

File diff suppressed because it is too large Load Diff

View File

@@ -1,144 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* location.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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 __LOCATION_H
#define __LOCATION_H
#include <gnome.h>
#include <tree.h>
#include <bonobo.h>
#include "ConfigArchiver.h"
#include "config-log.h"
#define LOCATION(obj) GTK_CHECK_CAST (obj, location_get_type (), Location)
#define LOCATION_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, location_get_type (), LocationClass)
#define IS_LOCATION(obj) GTK_CHECK_TYPE (obj, location_get_type ())
typedef struct _LocationClass LocationClass;
typedef struct _LocationPrivate LocationPrivate;
typedef struct _Archive Archive;
typedef ConfigArchiver_ContainmentType ContainmentType;
typedef ConfigArchiver_StoreType StoreType;
typedef int (*LocationBackendCB) (Location *, gchar *, gpointer);
struct _Location
{
BonoboXObject object;
LocationPrivate *p;
};
struct _LocationClass
{
BonoboXObjectClass parent;
POA_ConfigArchiver_Location__epv epv;
gboolean (*do_rollback) (Location *location,
gchar *backend_id,
xmlDocPtr xml_doc);
};
GType location_get_type (void);
BonoboObject *location_new (Archive *archive,
const gchar *locid,
const gchar *label,
Location *parent);
BonoboObject *location_open (Archive *archive,
const gchar *locid);
void location_delete (Location *location);
gchar *location_get_storage_filename (Location *location,
const gchar *backend_id,
gboolean is_default);
gchar *location_get_rollback_filename (Location *location,
struct tm *date,
gint steps,
const gchar *backend_id,
gboolean parent_chain);
void location_storage_complete (Location *location,
const gchar *filename);
gint location_store (Location *location,
gchar *backend_id,
FILE *input,
ConfigArchiver_StoreType store_type);
void location_store_xml (Location *location,
gchar *backend_id,
xmlDocPtr xml_doc,
ConfigArchiver_StoreType store_type);
void location_rollback_backends_to (Location *location,
struct tm *date,
gint steps,
GList *backends,
gboolean parent_chain);
const struct tm *location_get_modification_time (Location *location,
const gchar *backend_id);
ContainmentType location_contains (Location *location,
const gchar *backend_id);
gint location_add_backend (Location *location,
const gchar *backend_id,
ContainmentType type);
void location_remove_backend (Location *location,
const gchar *backend_id);
void location_foreach_backend (Location *location,
LocationBackendCB callback,
gpointer data);
GList *location_find_path_from_common_parent (Location *location,
Location *location2);
Location *location_get_parent (Location *location);
const gchar *location_get_path (Location *location);
const gchar *location_get_label (Location *location);
const gchar *location_get_id (Location *location);
void location_set_id (Location *location,
const gchar *locid);
gint location_store_full_snapshot (Location *location);
GList *location_get_changed_backends (Location *location,
Location *location1);
gboolean location_does_backend_change (Location *location,
Location *location1,
const gchar *backend_id);
ConfigLog *location_get_config_log (Location *location);
void location_garbage_collect (Location *location);
gboolean location_is_deleted (const Location *location);
#endif /* __LOCATION */

View File

@@ -1,384 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* main.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <sys/file.h>
#include <unistd.h>
#include <errno.h>
#include <gnome.h>
#include "util.h"
#include "archive.h"
/* Variables resulting from command line parsing */
static gboolean store;
static gboolean rollback;
static gboolean change_location;
static gboolean rename_location;
static gboolean push_config;
static gboolean garbage_collect;
static gboolean add_location;
static gboolean remove_location;
static gboolean add_backend;
static gboolean remove_backend;
static gboolean global;
static const gchar *location_id;
static gchar *backend_id;
static gboolean compare_parent;
static gboolean mask_previous;
static gchar *date_str;
static gboolean all;
static gchar *revision_id;
static gboolean last;
static guint steps;
static gboolean show;
static gchar *parent_str;
static gchar *new_name;
static gboolean contain_full;
static gboolean contain_partial;
static gboolean master;
static struct poptOption archiver_operations[] = {
{"store", 's', POPT_ARG_NONE, &store, 0,
N_("Store XML data in the archive")},
{"rollback", 'r', POPT_ARG_NONE, &rollback, 0,
N_("Roll back the configuration to a given point")},
{"change-location", 'c', POPT_ARG_NONE, &change_location, 0,
N_("Change the location profile to the given one")},
{"push-config", 'p', POPT_ARG_NONE, &push_config, 0,
N_("Push configuration data out to client machines (UNIMPLEMENTED)")},
{"rename-location", '\0', POPT_ARG_NONE, &rename_location, 0,
N_("Rename a location to a new name")},
{"add-location", '\0', POPT_ARG_NONE, &add_location, 0,
N_("Add a new location to the archive")},
{"remove-location", '\0', POPT_ARG_NONE, &remove_location, 0,
N_("Remove a location from the archive")},
{"add-backend", '\0', POPT_ARG_NONE, &add_backend, 0,
N_("Add a given backend to the given location")},
{"remove-backend", '\0', POPT_ARG_NONE, &remove_backend, 0,
N_("Remove the given backend from the given location")},
{"garbage-collect", '\0', POPT_ARG_NONE, &garbage_collect, 0,
N_("Perform garbage collection on the given location")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption global_options[] = {
{"global", 'g', POPT_ARG_NONE, &global, 0,
N_("Use the global repository")},
{"location", 'l', POPT_ARG_STRING, &location_id, 0,
N_("Identifier of location profile on which to operate"),
N_("LOCATION")},
{"backend", 'b', POPT_ARG_STRING, &backend_id, 0,
N_("Backend being used for this operation"), N_("BACKEND_ID")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption store_options[] = {
{"compare-parent", '\0', POPT_ARG_NONE, &compare_parent, 0,
N_("Store only the differences with the parent location's config")},
{"mask-previous", '\0', POPT_ARG_NONE, &mask_previous, 0,
N_("Store only those settings set in the previous config")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption rollback_options[] = {
{"date", 'd', POPT_ARG_STRING, &date_str, 0,
N_("Date to which to roll back"), N_("DATE")},
{"all", 'a', POPT_ARG_NONE, &all, 0,
N_("Roll back all configuration items")},
{"revision-id", 'i', POPT_ARG_INT, &revision_id, 0,
N_("Roll back to the revision REVISION_ID"), N_("REVISION_ID")},
{"last", 't', POPT_ARG_NONE, &last, 0,
N_("Roll back to the last known revision")},
{"steps", '\0', POPT_ARG_INT, &steps, 0,
N_("Roll back by STEPS revisions"), N_("STEPS")},
{"show", 'h', POPT_ARG_NONE, &show, 0,
N_("Don't run the backend, just dump the output")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption add_rename_location_options[] = {
{"parent", '\0', POPT_ARG_STRING, &parent_str, 0,
N_("Parent location for the new location"), N_("PARENT")},
{"new-name", '\0', POPT_ARG_STRING, &new_name, 0,
N_("New name to assign to the location"), N_("NEW_NAME")},
{NULL, '\0', 0, NULL, 0}
};
static struct poptOption add_remove_backend_options[] = {
{"master", '\0', POPT_ARG_NONE, &master, 0,
N_("Add/remove this backend to/from the master backend list")},
{"full", '\0', POPT_ARG_NONE, &contain_full, 0,
N_("Full containment")},
{"partial", '\0', POPT_ARG_NONE, &contain_partial, 0,
N_("Partial containment")},
{NULL, '\0', 0, NULL, 0}
};
static void
do_store (Location *location)
{
StoreType type;
if (!backend_id) {
fprintf (stderr, "No backend specified\n");
return;
}
if (mask_previous)
type = STORE_MASK_PREVIOUS;
else if (compare_parent)
type = STORE_COMPARE_PARENT;
else
type = STORE_FULL;
location_store (location, backend_id, stdin, type);
}
static void
do_rollback (Location *location)
{
gint id;
struct tm *date = NULL;
if (date_str)
date = parse_date (date_str);
else if (last || steps > 0)
date = NULL;
else if (!revision_id) {
fprintf (stderr, "No date specified\n");
return;
}
if (all) {
location_rollback_all_to (location, date, TRUE);
}
else if (backend_id && (date || last)) {
/* FIXME: Need to support specifying multiple backends */
if (show)
location_dump_rollback_data (location, date, 0,
backend_id, TRUE, stdout);
else
location_rollback_backend_to (location, date,
backend_id, TRUE);
}
else if (backend_id && steps) {
if (show)
location_dump_rollback_data (location, NULL, steps,
backend_id, TRUE, stdout);
else
location_rollback_backend_by (location, steps,
backend_id, TRUE);
}
else if (revision_id) {
sscanf (revision_id, "%x", &id);
if (id >= 0)
location_rollback_id (location, id);
else
fprintf (stderr, "Bad id specified\n");
} else {
g_message ("No backend specified\n");
return;
}
}
static void
do_change_location (Archive *archive, Location *location)
{
archive_set_current_location (archive, location);
}
static void
do_rename_location (Archive *archive, Location *location)
{
gboolean is_current;
if (new_name == NULL) {
fprintf (stderr,
"You did not specify a new name. Try --help\n");
} else {
if (!strcmp (location_get_id (location),
archive_get_current_location_id (archive)))
is_current = TRUE;
else
is_current = FALSE;
location_set_id (location, new_name);
if (is_current)
archive_set_current_location_id (archive, new_name);
}
}
static void
do_add_location (Archive *archive)
{
GtkObject *location;
Location *parent_location = NULL;
if (location_id == NULL) {
fprintf (stderr,
"Error: You did not specify a location name\n");
return;
}
if (parent_str != NULL) {
parent_location = archive_get_location (archive, parent_str);
if (parent_location == NULL && !strcmp (parent_str, "default"))
parent_location =
LOCATION
(location_new (archive, "default", NULL));
}
location = location_new (archive, location_id, parent_location);
}
static void
do_remove_location (Location *location)
{
location_delete (location);
}
static void
do_add_backend (Location *location)
{
ContainmentType type;
if (contain_full && contain_partial) {
fprintf (stderr, "Error: Cannot have both full and partial "
"containment\n");
return;
}
else if (contain_partial) {
type = CONTAIN_PARTIAL;
} else {
type = CONTAIN_FULL;
}
location_add_backend (location, backend_id, type);
}
static void
do_remove_backend (Location *location)
{
location_remove_backend (location, backend_id);
}
static void
do_garbage_collect (Location *location)
{
location_garbage_collect (location);
}
int
main (int argc, char **argv)
{
Archive *archive;
Location *location = NULL;
/* For Electric Fence */
free (malloc (1));
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (PACKAGE, "UTF-8");
textdomain (PACKAGE);
gnomelib_register_popt_table (global_options,
_("Global archiver options"));
gnomelib_register_popt_table (archiver_operations,
_("Archiver commands"));
gnomelib_register_popt_table (store_options,
_("Options for storing data"));
gnomelib_register_popt_table (rollback_options,
_("Options for rolling back"));
gnomelib_register_popt_table (add_rename_location_options,
_("Options for adding or renaming " \
"locations"));
gnomelib_register_popt_table (add_remove_backend_options,
_("Options for adding and removing " \
"backends"));
gtk_type_init ();
gnomelib_init ("archiver", VERSION);
gnomelib_parse_args (argc, argv, 0);
archive = ARCHIVE (archive_load (global));
if (archive == NULL) {
fprintf (stderr, "Could not open archive\n");
return -1;
}
if (!add_location) {
if (location_id == NULL)
location_id =
archive_get_current_location_id (archive);
location = archive_get_location (archive, location_id);
if (location == NULL) {
fprintf (stderr, "Error: Could not open location %s\n",
location_id);
return -1;
}
}
if (store)
do_store (location);
else if (rollback)
do_rollback (location);
else if (change_location)
do_change_location (archive, location);
else if (rename_location)
do_rename_location (archive, location);
else if (add_location)
do_add_location (archive);
else if (remove_location)
do_remove_location (location);
else if (add_backend)
do_add_backend (location);
else if (remove_backend)
do_remove_backend (location);
else if (garbage_collect)
do_garbage_collect (location);
archive_close (archive);
return 0;
}

View File

@@ -1,125 +0,0 @@
2004-10-14 Jody Goldberg <jody@gnome.org>
* Release 2.8.1
2004-04-15 Jody Goldberg <jody@gnome.org>
* Release 2.6.1
2004-04-01 Jody Goldberg <jody@gnome.org>
* Release 2.6.0.3
2004-03-30 Jody Goldberg <jody@gnome.org>
* Release 2.6.0.1
2004-03-23 Jody Goldberg <jody@gnome.org>
* Release 2.6.0
2004-03-11 Jody Goldberg <jody@gnome.org>
* Release 2.5.4
2004-02-13 Jody Goldberg <jody@gnome.org>
* Release 2.5.3
2004-01-14 Jody Goldberg <jody@gnome.org>
* Release 2.5.2
2003-12-30 Jody Goldberg <jody@gnome.org>
* Release 2.5.1.1
2003-12-30 Jody Goldberg <jody@gnome.org>
* Release 2.5.1
2003-10-28 Jody Goldberg <jody@gnome.org>
* Release 2.5.0
2003-07-07 Jody Goldberg <jody@gnome.org>
* Release 2.3.4
2003-06-24 Jody Goldberg <jody@gnome.org>
* Release 2.3.3
2003-05-07 Jody Goldberg <jody@gnome.org>
* Release 2.3.1
Tue Feb 4 17:09:18 2003 Jonathan Blandford <jrb@redhat.com>
* Release 2.2.0.1
Tue Jan 21 01:15:14 2003 Jonathan Blandford <jrb@gnome.org>
* Release 2.2.0
Thu Jan 16 02:41:09 2003 Jonathan Blandford <jrb@gnome.org>
* Release 2.1.7
2003-01-10 Jody Goldberg <jody@gnome.org>
* Release 2.1.6
2002-12-18 Jody Goldberg <jody@gnome.org>
* Release 2.1.5
2002-11-23 Jody Goldberg <jody@gnome.org>
* Release 2.1.3
2002-11-02 Jody Goldberg <jody@gnome.org>
* Release 2.1.2
2002-10-21 Jody Goldberg <jody@gnome.org>
* Release 2.1.1
2002-10-01 Jody Goldberg <jody@gnome.org>
* Release 2.1.0.1
2002-08-21 Jody Goldberg <jody@gnome.org>
* Release 2.1.0
2002-06-17 Jody Goldberg <jody@gnome.org>
* Release 2.0.0
2001-07-27 Bradford Hovinen <hovinen@ximian.com>
* RELEASE : 1.5.2
2001-07-20 Chema Celorio <chema@celorio.com>
* RELEASE : 1.5.0
2001-05-24 Arturo Espinosa Aldama <arturo@ximian.com>
* 0.5 RELEASE
2001-05-09 Arturo Espinosa Aldama <arturo@ximian.com>
* 0.4 RELEASE
2001-02-20 Bradford Hovinen <hovinen@ximian.com>
* test-3.sh: Created
* test-2.sh: Removed parts dealing with partial containment
2001-02-19 Bradford Hovinen <hovinen@ximian.com>
* Added test-1.sh and test-2.sh, the first two tests in the test suite

View File

@@ -1,48 +0,0 @@
This is a test suite for the archiver. It is designed to ease the pain
of formulating the (rather complex) tests the check all the
functionality of the archiver. Simply loading up the GUI and playing
around with it is not enough, since one wrong move can destroy a
person's configuration.
Tests: The test suite checks the following functionality:
1. On an account or machine where data have never been
archived, the default location and archive are properly
and automatically set up without user intervention.
2. Locations inheriting the default location are created
and destroyed properly.
3. Backends can be added and removed from non-toplevel
locations, with both full and partial containment. Any
attempt to do so on a toplevel location results in an
error.
4. Rollback data may be stored on both the base and derived
locations. When stored in the derived location where the
backend is marked with partial containment, the rollback
data represent only the differences between the derived and
parent configurations. The most recent configuration from
the parent location is used for making this determination.
5. When rolling a backend back in a derived location, if the
backend is not marked as contained in the derived location,
the data are retrieved from the location's parent
recursively. If the backend is marked as partially
contained, then the XML data are merged with the parent's
data.
6. Changing the current location correctly invokes the
rollback algorithm
7. Rolling back by date and by number of steps works in a
manner similar to the above.
8. Logs accurately represent the data archived.
9. Backends are invoked properly and data are sent to them
properly.
10. All erroneous input should result in an error and not a
crash. The program should return an appropriate error
condition.

View File

@@ -1,187 +0,0 @@
#!/bin/sh
#
# test-1.sh
# Copyright (C) 2001 Ximian, Inc.
# Written by Bradford Hovinen <hovinen@ximian.com>
#
# 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, 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.
#
# Test suite, part I
#
# Given an archive to work with (global or per-user):
#
# - Destroy the entire archive forcibly (rm -rf)
# - Store backend data in the archive
# - Check to see that a new archive has been created with default
# location "Default", and that the data have been properly stored
# there
XIMIAN_ARCHIVER=${XIMIAN_ARCHIVER:-'../ximian-archiver'}
function get_unused_tmpfile () {
tmp_file_no=0
while [ -e "/tmp/$1-$tmp_file_no" ]; do
let 'tmp_file_no=tmp_file_no+1'
done
echo "/tmp/$1-$tmp_file_no";
}
function run_command () {
if [ "x$use_gdb" == "xyes" ]; then
commands_file=`get_unused_tmpfile gdb-commands-file`
echo "set args $extra_args $@" >$commands_file
gdb ../.libs/lt-ximian-archiver -x $commands_file
else
echo "Running archiver program with the following command line:"
echo $XIMIAN_ARCHIVER $extra_args $@
$XIMIAN_ARCHIVER $extra_args $@
echo
fi
}
if [ "x$1" == "x" ]; then
echo "Usage: test-1.sh --global|--per-user [--gdb]"
exit 1
fi
for test_option; do
case "$test_option" in
--global)
extra_args="--global"
archive_dir=/usr/share/ximian-config
;;
--per-user)
extra_args=""
archive_dir=$HOME/.gnome/ximian-config
;;
--gdb)
use_gdb=yes
;;
*)
echo "Usage: test-1.sh --global|--per-user [--gdb]"
exit 1
esac
done
if [ -d $archive_dir ]; then
mv $archive_dir "$archive_dir-backup"
fi
##############################################################################
# Test proper
##############################################################################
archiver_test_data_file=`get_unused_tmpfile ximian-archiver-test-data`;
cat >$archiver_test_data_file <<EOF
<?xml version="1.0"?>
<background-properties>
<bg-color1>#111128</bg-color1>
<bg-color2>#796dff</bg-color2>
<enabled/>
<wallpaper/>
<gradient/>
<orientation>vertical</orientation>
<wallpaper-type>0</wallpaper-type>
<wallpaper-filename>/home/hovinen/media/Propaganda/Vol3/9a.jpg</wallpaper-filename>
<wallpaper-sel-path>./</wallpaper-sel-path>
<auto-apply/>
<adjust-opacity/>
<opacity>172</opacity>
</background-properties>
EOF
run_command --store --backend=background-properties-capplet \
<$archiver_test_data_file
##############################################################################
# Results check
##############################################################################
echo -n "Checking whether default location was created properly..."
if [ -d "$archive_dir/default" ]; then
echo "yes -- good"
else
echo "no -- error"
fi
echo -n "Checking whether the XML data snapshot was created..."
if [ -f "$archive_dir/default/00000000.xml" ]; then
echo "yes -- good"
else
echo "no -- error"
fi
echo -n "Checking whether the XML data match the XML data given..."
differences_file=`get_unused_tmpfile differences`
diff -u $archive_dir/default/00000000.xml $archiver_test_data_file \
>$differences_file
if [ ! -s $differences_file ]; then
echo "yes -- good"
else
echo "no -- error"
echo "Differences are as follows:"
cat $differences_file
echo
fi
rm -f $differences_file
echo -n "Checking if the config log data are correct..."
config_log_id=`awk '{print $1}' $archive_dir/default/config.log`
config_log_backend=`awk '{print $4}' $archive_dir/default/config.log`
if [ "x$config_log_id" == "x00000000" -a \
"x$config_log_backend" == "xbackground-properties-capplet" ]; then
echo "yes -- good"
else
echo "no -- error"
echo "Config log is as follows:"
cat $archive_dir/default/config.log
echo
fi
##############################################################################
# Putting the results together
##############################################################################
rm -f $archiver_test_data_file
results_dir="ximian-config-results-`date +%Y%m%d`"
results_dir=`get_unused_tmpfile $results_dir`
mkdir $results_dir
(cd $archive_dir && tar cf - *) | (cd $results_dir && tar xf -)
rm -rf $archive_dir
if [ -d "$archive_dir-backup" ]; then
mv "$archive_dir-backup" $archive_dir
fi
echo
echo "Test complete"
echo "Resulting archive data in $results_dir"

View File

@@ -1,219 +0,0 @@
#!/bin/sh
#
# test-2.sh
# Copyright (C) 2001 Ximian, Inc.
# Written by Bradford Hovinen <hovinen@ximian.com>
#
# 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, 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.
#
# Test suite, part II
#
# Given an archive to work with (global or per-user):
#
# - Destroy the entire archive forcibly (rm -rf)
# - Create a new location inheriting from the default location
# (the default location should be created automatically in this case)
# - Sets the new location as the current one
# - Stores data for a backend not contained in the new location
# (this should pass the data through to default)
# - Adds a backend to the new location (full containment)
# - Stores data for that backend in the new location
XIMIAN_ARCHIVER=${XIMIAN_ARCHIVER:-'../ximian-archiver'}
function get_unused_tmpfile () {
tmp_file_no=0
while [ -e "/tmp/$1-$tmp_file_no" ]; do
let 'tmp_file_no=tmp_file_no+1'
done
echo "/tmp/$1-$tmp_file_no";
}
function run_command () {
input_param=$1
shift
if [ "x$use_gdb" == "xyes" ]; then
commands_file=`get_unused_tmpfile gdb-commands-file`
echo "set args $extra_args $@ <$input_param" >$commands_file
gdb ../.libs/ximian-archiver -x $commands_file
rm -f $commands_file
else
echo "Running archiver program with the following command line:" >&2
echo "$XIMIAN_ARCHIVER $extra_args $@ <$input_param" >&2
$XIMIAN_ARCHIVER $extra_args $@ <$input_param
echo
fi
}
if [ "x$1" == "x" ]; then
echo "Usage: test-2.sh --global|--per-user [--gdb]"
exit 1
fi
for test_option; do
case "$test_option" in
--global)
extra_args="--global"
archive_dir=/usr/share/ximian-config
;;
--per-user)
extra_args=""
archive_dir=$HOME/.gnome/ximian-config
;;
--gdb)
use_gdb=yes
;;
*)
echo "Error -- invalid option: $test_option"
exit 1
esac
done
if [ -d $archive_dir ]; then
mv $archive_dir "$archive_dir-backup"
fi
##############################################################################
# Test proper
##############################################################################
# Test 1: Creating a new location
run_command /dev/null --add-location --parent=default --location=Boston-Office
run_command /dev/null --change-location --location=Boston-Office
# Test 2: Storing data that should "pass through" to the parent
archiver_test_data_file1=`get_unused_tmpfile ximian-archiver-test-data`;
cat >$archiver_test_data_file1 <<EOF
<?xml version="1.0"?>
<background-properties>
<bg-color1>#111128</bg-color1>
<bg-color2>#796dff</bg-color2>
<enabled/>
<wallpaper/>
<gradient/>
<orientation>vertical</orientation>
<wallpaper-type>0</wallpaper-type>
<wallpaper-filename>/home/hovinen/media/Propaganda/Vol3/9a.jpg</wallpaper-filename>
<wallpaper-sel-path>./</wallpaper-sel-path>
<auto-apply/>
<adjust-opacity/>
<opacity>172</opacity>
</background-properties>
EOF
run_command $archiver_test_data_file1 \
--store --backend=background-properties-capplet
# Test 3: Adding a backend (full containment) and storing data that
# should be stored in the child location
run_command /dev/null --add-backend --full \
--backend=keyboard-properties-capplet
archiver_test_data_file2=`get_unused_tmpfile ximian-archiver-test-data`;
cat >$archiver_test_data_file2 <<EOF
<?xml version="1.0"?>
<keyboard-properties>
<rate>255</rate>
<delay>0</delay>
<repeat/>
<volume>0</volume>
</keyboard-properties>
EOF
run_command $archiver_test_data_file2 \
--store --backend=keyboard-properties-capplet
# Test 5: Retrieve the background properties data previously stored
# and compare it with the data we have here to see if everything is ok
archiver_test_data_file3=`get_unused_tmpfile ximian-archiver-test-data`
run_command /dev/null --rollback --show --last \
--backend=background-properties-capplet \
>$archiver_test_data_file3
##############################################################################
# Results check
##############################################################################
echo -n "Checking whether default location was created properly..."
if [ -d "$archive_dir/default" ]; then
echo "yes -- good"
else
echo "no -- error"
fi
echo -n "Checking whether derived location was created properly..."
if [ -d "$archive_dir/Boston-Office" ]; then
echo "yes -- good"
else
echo "no -- error"
fi
echo -n "Checking whether the XML data retrieved match the XML data given..."
differences_file=`get_unused_tmpfile differences`
diff -u $archiver_test_data_file3 $archiver_test_data_file1 >$differences_file
if [ ! -s $differences_file ]; then
echo "yes -- good"
else
echo "no -- error"
echo "Differences are as follows:"
cat $differences_file
echo
fi
rm -f $differences_file
##############################################################################
# Putting the results together
##############################################################################
rm -f $archiver_test_data_file1
rm -f $archiver_test_data_file2
rm -f $archiver_test_data_file3
results_dir="ximian-config-results-`date +%Y%m%d`"
results_dir=`get_unused_tmpfile $results_dir`
mkdir $results_dir
(cd $archive_dir && tar cf - *) | (cd $results_dir && tar xf -)
rm -rf $archive_dir
if [ -d "$archive_dir-backup" ]; then
mv "$archive_dir-backup" $archive_dir
fi
echo
echo "Test complete"
echo "Resulting archive data in $results_dir"

View File

@@ -1,245 +0,0 @@
#!/bin/sh
#
# test-3.sh
# Copyright (C) 2001 Ximian, Inc.
# Written by Bradford Hovinen <hovinen@ximian.com>
#
# 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, 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.
#
# Test suite, part III
#
# Given an archive to work with (global or per-user):
#
# - Destroy the entire archive forcibly (rm -rf)
# - Create a new location inheriting from the default location
# (the default location should be created automatically in this case)
# - Sets the new location as the current one
# - Stores data for a particular backend, so that it should pass
# through to the parent location
# - Adds that backend to the new location (partial containment)
# - Stores data for that backend in the new location, so that the
# nodes should be subtracted
# - Retrieves the data for that backend from the new location, so
# that the nodes should be merged
XIMIAN_ARCHIVER=${XIMIAN_ARCHIVER:-'../ximian-archiver'}
function get_unused_tmpfile () {
tmp_file_no=0
while [ -e "/tmp/$1-$tmp_file_no" ]; do
let 'tmp_file_no=tmp_file_no+1'
done
echo "/tmp/$1-$tmp_file_no";
}
function run_command () {
input_param=$1
shift
if [ "x$use_gdb" == "xyes" ]; then
commands_file=`get_unused_tmpfile gdb-commands-file`
echo "set args $extra_args $@ <$input_param" >$commands_file
gdb ../.libs/ximian-archiver -x $commands_file
rm -f $commands_file
else
echo "Running archiver program with the following command line:" >&2
echo "$XIMIAN_ARCHIVER $extra_args $@ <$input_param" >&2
$XIMIAN_ARCHIVER $extra_args $@ <$input_param
echo
fi
}
if [ "x$1" == "x" ]; then
echo "Usage: test-2.sh --global|--per-user [--gdb]"
exit 1
fi
for test_option; do
case "$test_option" in
--global)
extra_args="--global"
archive_dir=/usr/share/ximian-config
;;
--per-user)
extra_args=""
archive_dir=$HOME/.gnome/ximian-config
;;
--gdb)
use_gdb=yes
;;
*)
echo "Error -- invalid option: $test_option"
exit 1
esac
done
if [ -d $archive_dir ]; then
mv $archive_dir "$archive_dir-backup"
fi
##############################################################################
# Test proper
##############################################################################
run_command /dev/null --add-location --parent=default --location=Boston-Office
run_command /dev/null --change-location --location=Boston-Office
# Test 1: Adding a backend (partial containment) and storing data that
# should be stored in the child location
#
# Note: These are not real data
archiver_test_data_file1=`get_unused_tmpfile ximian-archiver-test-data`;
cat >$archiver_test_data_file1 <<EOF
<?xml version="1.0"?>
<mouse-properties>
<acceleration>7</acceleration>
<threshold>1</threshold>
<fake-node id="1">
<another-node>data</another-node>
</fake-node>
<fake-node id="2">
<my-node>blah blah blah</my-node>
<another-node>more data</another-node>
</fake-node>
</mouse-properties>
EOF
run_command $archiver_test_data_file1 \
--store --backend=mouse-properties-capplet
run_command /dev/null --add-backend --partial \
--backend=mouse-properties-capplet
archiver_test_data_file2=`get_unused_tmpfile ximian-archiver-test-data`;
cat >$archiver_test_data_file2 <<EOF
<?xml version="1.0"?>
<mouse-properties>
<acceleration>7</acceleration>
<threshold>3</threshold>
<fake-node id="1">
<another-node>data</another-node>
</fake-node>
<fake-node id="2">
<my-node>blah blah blah</my-node>
<another-node>different data</another-node>
</fake-node>
</mouse-properties>
EOF
run_command $archiver_test_data_file2 \
--store --backend=mouse-properties-capplet --compare-parent
# This should be the resulting file:
archiver_test_data_file2_correct=`get_unused_tmpfile ximian-archiver-check`;
cat >$archiver_test_data_file2_correct <<EOF
<?xml version="1.0"?>
<mouse-properties>
<threshold>3</threshold>
<fake-node id="2">
<another-node>different data</another-node>
</fake-node>
</mouse-properties>
EOF
# Test 2: Retrieve the mouse properties data from the location manager
# to see if node merging works properly
archiver_test_data_file3=`get_unused_tmpfile ximian-archiver-test-data`
run_command /dev/null --rollback --last --show \
--backend=mouse-properties-capplet >$archiver_test_data_file3
##############################################################################
# Results check
##############################################################################
echo -n "Checking whether the XML data match the XML data given..."
differences_file=`get_unused_tmpfile differences`
diff -u "$archive_dir/Boston-Office/00000000.xml" \
$archiver_test_data_file2_correct \
>$differences_file
if [ ! -s $differences_file ]; then
echo "yes -- good"
else
echo "no -- error"
echo "Differences are as follows:"
cat $differences_file
echo
fi
rm -f $differences_file
echo -n "Checking whether the XML data retrieved match the XML data given..."
differences_file=`get_unused_tmpfile differences`
diff -u $archiver_test_data_file3 $archiver_test_data_file2 >$differences_file
if [ ! -s $differences_file ]; then
echo "yes -- good"
else
echo "no -- error"
echo "Check manually to see whether this is correct. Nodes may be"
echo "out of order."
echo "File retrieved is as follows:"
cat $archiver_test_data_file3
echo
echo "File is supposed to be as follows:"
cat $archiver_test_data_file2
echo
fi
rm -f $differences_file
##############################################################################
# Putting the results together
##############################################################################
rm -f $archiver_test_data_file1
rm -f $archiver_test_data_file2
rm -f $archiver_test_data_file3
rm -f $archiver_test_data_file4
rm -f $archiver_test_data_file5
results_dir="ximian-config-results-`date +%Y%m%d`"
results_dir=`get_unused_tmpfile $results_dir`
mkdir $results_dir
(cd $archive_dir && tar cf - *) | (cd $results_dir && tar xf -)
rm -rf $archive_dir
if [ -d "$archive_dir-backup" ]; then
mv "$archive_dir-backup" $archive_dir
fi
echo
echo "Test complete"
echo "Resulting archive data in $results_dir"

View File

@@ -1,113 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* util.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
/* Read a fixed-digit number from a string, advancing the string
* pointer. Return TRUE if the extraction was successful, FALSE if
* there was no number to extract or if the number was too short.
*/
gboolean
extract_number (char **str, int *number, int digits)
{
char buf[64];
if (!isdigit (**str)) return FALSE;
if (digits > 63) digits = 63;
strncpy (buf, *str, digits);
buf[digits] = '\0';
*number = atoi (buf);
if (strlen (buf) < digits) return FALSE;
*str += digits;
return TRUE;
}
struct tm *
parse_date (char *str)
{
struct tm *date;
gboolean ok;
gint value;
ok = extract_number (&str, &value, 4);
if (!ok) return NULL;
date = g_new (struct tm, 1);
date->tm_isdst = 0;
date->tm_year = value - 1900;
date->tm_mon = 11;
date->tm_mday = 31;
date->tm_hour = 23;
date->tm_min = 59;
date->tm_sec = 59;
if (extract_number (&str, &value, 2))
date->tm_mon = value - 1;
else
return date;
if (extract_number (&str, &value, 2))
date->tm_mday = value;
else
return date;
if (extract_number (&str, &value, 2))
date->tm_hour = value;
else
return date;
if (extract_number (&str, &value, 2))
date->tm_min = value;
else
return date;
if (extract_number (&str, &value, 2))
date->tm_sec = value;
#ifdef __USE_BSD
date->tm_zone = "GMT";
date->tm_gmtoff = 0;
#endif
return date;
}
struct tm *
dup_date (const struct tm *date)
{
struct tm *date1;
date1 = g_new (struct tm, 1);
memcpy (date1, date, sizeof (struct tm));
return date1;
}

View File

@@ -1,51 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* util.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* 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, 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 __UTIL_H
#define __UTIL_H
#include <time.h>
#include <glib.h>
/* Uncomment this if you want debugs: */
#define DEBUG_ME_MORE
#ifdef DEBUG_ME_MORE
# ifdef __GNUC__
# define DEBUG_MSG(str, args...) \
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "(%d:%s) " str, \
getpid (), __FUNCTION__ , ## args)
# else
# define DEBUG_MSG(str, args...)
# endif
#else
/* This was redefined here because it was messing with the frontend->backend
* talk. Arturo */
# define DEBUG_MSG(str, args...)
#endif
gboolean extract_number (char **str, int *number, int digits);
struct tm *parse_date (char *str);
struct tm *dup_date (const struct tm *date);
#endif /* __UTIL_H */

View File

@@ -1,193 +0,0 @@
Configuration rollback, location management, and cluster support
Copyright (C) 2001 Ximian, Inc.
Written by Bradford Hovinen <hovinen@ximian.com>
I. Basic architecture
A. Components
1. Ximian Configuration Manager
The GUI shell, here referred to as the Ximian Configuration Manager
(XCM), acts as launching point for the capplets and Ximian Tools,
and a control center for managing rollback, location management, and
clustering. It launches other components and knows how to find
archived configuration data for rollback. When rollback or a change of
location is required, it invokes the required backends or capplets
with the --set option and feeds the required XML to them.
2. Capplets
Capplets handle user configuration; they combine the front and back
ends into one process. They will eventually run as Bonobo controls
implementing the Bonobo::Capplet interface, but for now they are run
as regular processes. They all support the --get and --set command
line options (which will be methods in the Bonobo::Capplet
interface). --get returns an XML description of the capplet's state
for archival purposes and --set takes an XML description of the
capplet's state and applies those settings to the desktop.
3. Ximian Setup Tools (XSTs)
These programs are for system-wide configuration and must run as root
in order to apply changes. They may also run as a regular user in
`read-only' mode. They have separate front- and backends, the former
typically written in C and the latter normally written in Perl. This
facilitates in-place modification of existing configuration files
without the need for creating out own separate, incompatible way of
configuring the system. The backends support the --get and --set
arguments, analogous to the arguments in capplets mentioned above.
2. Root manager
The root manager process runs as root and is launched through
gnome-su. It accepts on stdin a set of programs to launch, one per
line, with command line arguments. XCM uses it to launch Ximian Setup
Tools so that they run as root, without needing to ask the user for a
password each time a tool is run. The root manager is run exactly once
through console-helper the first time a tool that must be run as root
is invoked. On subsequent occasions the command to start the tool is
passed to the root manager through stdin.
3. The script do-changes
do-changes is responsible for archiving changes made to the system's
configuration and passing them on to the backend, if appropriate. It
accepts a stream of XML on stdin and stores this XML in the
configuration archive directory. If a backend is specified on the
command line, it also spawns the backend process with the --set option
and feeds the XML to it through stdin.
II. Configuration process
When a user makes changes to either his own configuration or that of
the system, those changes must be archived so that the system may be
rolled back in the future. In the case of capplets, the capplet
currently dumps an XML snapshot of its current state to the script
do-changes when the user clicks `Ok'. do-changes then archives the
state in ~/.gnome/config/<location>/<revision> where <location> is the
name of the active location (cf. section IV) and <revision> is
incremented after each change.
When the capplets are converted into Bonobo controls, the situation
will be slightly different. XCM will be the recipient of the `Ok'
signal, so it will invoke the OKClicked() method of the
Bonobo::Capplet interface on the appropriate capplet. It will also
invoke the GetXML() method of the same interface in order to retrieve
an XML snapshot of the state and store that snapshot with
do-changes. Hence, much of the action moves from the capplet to XCM.
In the case of Ximian Setup Tools, the frontend passes the XML through
the do-changes script to the backend whenever the `Ok' button is
clicked. It passes to do-changes the argument --backend <backend name>
so that do-changes will also invoke the indicated backend and pass the
XML to it.
III. Rollback process
From within the XCM, the user may elect to roll back either his
personal configuration or that of the system to a particular
date. XCM looks for a revision directory in the current location
profile with the most recent modification date that is not more recent
than the date specified by the user. XCM also has a list of what
capplets (or XSTs) constitute a complete snapshot of the system's
configuration. In order to perform a complete rollback, it backtracks
through the revision directories, picking up XML snapshots of capplets
until it has a complete set and applies them through the --set
method. In the case of XSTs, the XCM knows how to invoke the backend
and does so as necessary.
IV. Location management
The system may have one or more profiles, each giving different system
configurations. For example, a user may own a laptop and wish to hook
that laptop up to different networks at different times. Each network
may be located in a different time zone, have different network
configuration parameters (e.g., DHCP vs. static IPs), and use different
default printers. When the user hooks his laptop up in a particular
network, it would be advantageous to switch to that network's
configuration with a minimum of hassle.
As mentioned above, configuration data is stored in separate
directories corresponding to the name of a given location. XCM has the
ability to apply a set of configuration files from a given location in
a manner similar to the rollback procedure described above. When the
user selects an alternative configuration, it simply goes through the
revision history for that location, pulls a complete set of
configuration files, and applies them. The procedure is similar for
both capplets and XSTs.
In addition, locations may be expressed hierarchically. For example, a
user might specify a location called `Boston' that describes language,
time zone, currency, and other locale data, and another location called
`Boston Office' that includes network parameters. `Boston Office'
inherits its locale data from `Boston', overriding the latter's
network configuration.
To implement this, each location directory contains some metadata that
describes what configuration data is valid for it and what other
configuration it inherits from. There are one or more root
configurations that contain a complete set of data. When applying a
new location, XCM looks first at that location's directory, pulling a
complete set of all the configuration data defined by that location,
and then goes to the next level up in the location hierarchy and does
the same thing. It also keeps track of the common subtree root between
the old and new locations so that only the configuration items that
actually change are collected.
From a user's perspective, the XCM will present a tree showing the
existing locations. Users may create a new location derived from an
existing one. When the user elects to configure a particular location,
the XCM shell includes icons that are grayed out, indicating that
those configuration items are not set in this particular location. If
the user attempts to change them, they become specific to that
particular location and are recolored accordingly.
V. Clustering
A single server may archive the configuration for a large number of
individual workstations, providing configuration data to each of the
clients on demand. An administrator can then push configuration
updates out to each machine with the press of a button, rather than
having to go to each machine and update it manually.
To enable this, each client machine will run a daemon that accepts
configuration data pushed out by the server. Some sort of public key
signing will be implemented to ensure that this is done securely. On
the server end, a series of host groups is maintained, each one
containing a set of hosts. These form the top two levels of a
configuration hierarchy not unlike what is described above. Each host
may override certain configuration values for the cluster as a
whole. The cluster may also have multiple `locations', e.g. for
configuring a computer lab for computer science during one class and
for math during another. Locations may be selected down to the
granularity of a single host, or for the entire cluster at
once. Cluster-wide configurations occur between the cluster and host
level in the configuration hierarchy.
VI. Issues
1. We need a way to get an XML state without actually applying
changes, so that the user can configure a location without switching
to it.
2. Can we make the XST frontends Bonobo controls, and can we have them
run as the regular user rather than as root? This would ensure that
certain user interface preferences, such as themes, are kept
consistent for a given user between capplets and XSTs. The way to
implement this is to have a method on the XCM interface called
RunBackend() which returns a BonoboObject referring to the backend
that implements the Bonobo::XSTBackend interface, which is similar to
the Bonobo::Capplet interface mentioned above. The interface defines
the GetXML and SetXML methods. The object should also implement
another, XST-specific interface to facilitate setting specific
configuration variables, so that live update may be implemented. The
root manager must then be extended to support some sort of secure
forwarding, allowing the user to access that particular CORBA object.
3. If we make the XSTs into Bonobo controls, can we give them the same
Bonobo::Capplet interface that is given to the Capplets? This would
make everything a bit simpler from the XCM's perspective, since it
then does not need to know the difference between Capplets and
XSTs -- it then only needs to implement the RunBackend() method for
the benefit of the XSTs.

View File

@@ -1,27 +0,0 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
PKG_NAME="control-center"
(test -f $srcdir/configure.in \
&& test -f $srcdir/autogen.sh \
&& test -d $srcdir/control-center) || {
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
echo " top-level $PKG_NAME directory"
exit 1
}
DIE=0
rm -f .using-gnome-libs-package
if ! which gnome-autogen.sh ; then
echo "You need to install the gnome-common module and make"
echo "sure the gnome-autogen.sh script is in your \$PATH."
exit 1
fi
REQUIRED_AUTOMAKE_VERSION=1.7 . gnome-autogen.sh

View File

@@ -1,2 +0,0 @@
Makefile.in
Makefile

View File

@@ -1,17 +0,0 @@
always_built_SUBDIRS = \
common accessibility \
default-applications font \
background keyboard mouse sound \
theme-switcher ui-properties \
keybindings network windows
if HAVE_RANDR
randr_SUBDIRS = display
else
randr_SUBDIRS =
endif
SUBDIRS = $(always_built_SUBDIRS) $(randr_SUBDIRS)
DIST_SUBDIRS = \
$(always_built_SUBDIRS) display

View File

@@ -1,2 +0,0 @@
Diego Gonzalez Gonzalez <diego@pemas.net>
Chris Toshok <toshok@ximian.com>

View File

@@ -1,22 +0,0 @@
2005-05-16 Olav Vitters <olav@bkor.dhs.org>
* gnome-about-me.glade: Remove garbage text. Patch by Benjamin
LeMasurier. Fixes bug #162492.
2005-04-01 Diego Gonzalez <diego@pemas.net>
* gnome-about-me.c: fix the case where the self uid is wrong
and the edition when the self contact is created for the
first time.
2005-03-29 Diego Gonzalez <diego@pemas.net>
* Makefile.am: fix tabs
2005-02-09 Sebastien Bacher <seb128@debian.org>
* Makefile.am: build e-util-marshal.c.
2004-12-23 Sebastien Bacher <seb128@debian.org>
* gnome-about-me.glade: fixed a typo (Closes: #162094).

View File

@@ -1,38 +0,0 @@
bin_PROGRAMS = gnome-about-me
pixmapdir = $(GNOMECC_PIXMAPS_DIR)
pixmap_DATA = \
gnome-about-me.png
gnome_about_me_LDADD = $(GNOMECC_CAPPLETS_LIBS) $(LIBEBOOK_LIBS) -lutil
gnome_about_me_SOURCES = \
e-util-marshal.c \
e-util-marshal.h \
gnome-about-me-password.c \
e-image-chooser.c \
gnome-about-me.c
e-util-marshal.h: e-util-marshal.list
( @GLIB_GENMARSHAL@ --prefix=e_util_marshal $(srcdir)/e-util-marshal.list \
--header > util-marshal.tmp \
&& mv util-marshal.tmp e-util-marshal.h ) \
|| ( rm -f util-marshal.tmp && exit 1 )
e-util-marshal.c: e-util-marshal.h
( @GLIB_GENMARSHAL@ --prefix=e_util_marshal $(srcdir)/e-util-marshal.list \
--body > util-marshal.tmp \
&& mv util-marshal.tmp e-util-marshal.c ) \
|| ( rm -f util-marshal.tmp && exit 1 )
@INTLTOOL_DESKTOP_RULE@
desktopdir = $(datadir)/applications
Desktop_in_files = gnome-about-me.desktop.in
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
Gladedir = $(GNOMECC_GLADE_DIR)
Glade_DATA = gnome-about-me.glade
INCLUDES = $(GNOMECC_CAPPLETS_CFLAGS) $(LIBEBOOK_CFLAGS)
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES)
EXTRA_DIST = e-util-marshal.list $(Glade_DATA) $(Desktop_in_files) $(pixmap_DATA)

View File

@@ -1,522 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* e-image-chooser.c
* Copyright (C) 2004 Novell, Inc.
* Author: Chris Toshok <toshok@ximian.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* 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 library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <glib/gi18n.h>
#include <gtk/gtkalignment.h>
#include <gtk/gtkframe.h>
#include <gtk/gtkimage.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkdnd.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include "e-image-chooser.h"
#include "e-util-marshal.h"
struct _EImageChooserPrivate {
GtkWidget *frame;
GtkWidget *image;
GtkWidget *browse_button;
char *image_buf;
int image_buf_size;
int image_width;
int image_height;
gboolean editable;
};
enum {
CHANGED,
LAST_SIGNAL
};
static gint image_chooser_signals [LAST_SIGNAL] = { 0 };
static void e_image_chooser_init (EImageChooser *chooser);
static void e_image_chooser_class_init (EImageChooserClass *klass);
#if 0
static void e_image_chooser_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void e_image_chooser_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
#endif
static void e_image_chooser_dispose (GObject *object);
static gboolean image_drag_motion_cb (GtkWidget *widget,
GdkDragContext *context,
gint x, gint y, guint time, EImageChooser *chooser);
static void image_drag_leave_cb (GtkWidget *widget,
GdkDragContext *context,
guint time, EImageChooser *chooser);
static gboolean image_drag_drop_cb (GtkWidget *widget,
GdkDragContext *context,
gint x, gint y, guint time, EImageChooser *chooser);
static void image_drag_data_received_cb (GtkWidget *widget,
GdkDragContext *context,
gint x, gint y,
GtkSelectionData *selection_data,
guint info, guint time, EImageChooser *chooser);
static GtkObjectClass *parent_class = NULL;
#define PARENT_TYPE GTK_TYPE_VBOX
enum DndTargetType {
DND_TARGET_TYPE_URI_LIST
};
#define URI_LIST_TYPE "text/uri-list"
static GtkTargetEntry image_drag_types[] = {
{ URI_LIST_TYPE, 0, DND_TARGET_TYPE_URI_LIST },
};
static const int num_image_drag_types = sizeof (image_drag_types) / sizeof (image_drag_types[0]);
GtkWidget *
e_image_chooser_new (void)
{
return g_object_new (E_TYPE_IMAGE_CHOOSER, NULL);
}
GType
e_image_chooser_get_type (void)
{
static GType eic_type = 0;
if (!eic_type) {
static const GTypeInfo eic_info = {
sizeof (EImageChooserClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) e_image_chooser_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (EImageChooser),
0, /* n_preallocs */
(GInstanceInitFunc) e_image_chooser_init,
};
eic_type = g_type_register_static (PARENT_TYPE, "EImageChooser", &eic_info, 0);
}
return eic_type;
}
static void
e_image_chooser_class_init (EImageChooserClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_ref (PARENT_TYPE);
image_chooser_signals [CHANGED] =
g_signal_new ("changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (EImageChooserClass, changed),
NULL, NULL,
e_util_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
/*
object_class->set_property = e_image_chooser_set_property;
object_class->get_property = e_image_chooser_get_property;
*/
object_class->dispose = e_image_chooser_dispose;
}
#if UI_CHANGE_OK
static void
browse_for_image_cb (GtkWidget *button, gpointer data)
{
}
#endif
static void
e_image_chooser_init (EImageChooser *chooser)
{
EImageChooserPrivate *priv;
GtkWidget *alignment;
priv = chooser->priv = g_new0 (EImageChooserPrivate, 1);
alignment = gtk_alignment_new (0, 0, 0, 0);
priv->frame = gtk_frame_new ("");
priv->image = gtk_image_new ();
gtk_container_add (GTK_CONTAINER (alignment), priv->image);
#if UI_CHANGE_OK
priv->browse_button = gtk_button_new_with_label (_("Choose Image"));
#endif
gtk_frame_set_shadow_type (GTK_FRAME (priv->frame), GTK_SHADOW_NONE);
gtk_container_add (GTK_CONTAINER (priv->frame), alignment);
gtk_box_set_homogeneous (GTK_BOX (chooser), FALSE);
gtk_box_pack_start (GTK_BOX (chooser), priv->frame, TRUE, TRUE, 0);
#if UI_CHANGE_OK
gtk_box_pack_start (GTK_BOX (chooser), priv->browse_button, FALSE, FALSE, 0);
g_signal_connect (priv->browse_button, "clicked", G_CALLBACK (browse_for_image_cb), NULL);
#endif
gtk_drag_dest_set (priv->image, 0, image_drag_types, num_image_drag_types, GDK_ACTION_COPY);
g_signal_connect (priv->image,
"drag_motion", G_CALLBACK (image_drag_motion_cb), chooser);
g_signal_connect (priv->image,
"drag_leave", G_CALLBACK (image_drag_leave_cb), chooser);
g_signal_connect (priv->image,
"drag_drop", G_CALLBACK (image_drag_drop_cb), chooser);
g_signal_connect (priv->image,
"drag_data_received", G_CALLBACK (image_drag_data_received_cb), chooser);
gtk_widget_show_all (priv->frame);
#if UI_CHANGE_OK
gtk_widget_show (priv->browse_button);
#endif
/* we default to being editable */
priv->editable = TRUE;
}
static void
e_image_chooser_dispose (GObject *object)
{
EImageChooser *eic = E_IMAGE_CHOOSER (object);
if (eic->priv) {
EImageChooserPrivate *priv = eic->priv;
if (priv->image_buf) {
g_free (priv->image_buf);
priv->image_buf = NULL;
}
g_free (eic->priv);
eic->priv = NULL;
}
if (G_OBJECT_CLASS (parent_class)->dispose)
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
static gboolean
set_image_from_data (EImageChooser *chooser,
char *data, int length)
{
gboolean rv = FALSE;
GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
GdkPixbuf *pixbuf;
gdk_pixbuf_loader_write (loader, data, length, NULL);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
if (pixbuf)
gdk_pixbuf_ref (pixbuf);
gdk_pixbuf_loader_close (loader, NULL);
g_object_unref (loader);
if (pixbuf) {
GdkPixbuf *scaled;
GdkPixbuf *composite;
float scale;
int new_height, new_width;
new_height = gdk_pixbuf_get_height (pixbuf);
new_width = gdk_pixbuf_get_width (pixbuf);
if (chooser->priv->image_height == 0
&& chooser->priv->image_width == 0) {
scale = 1.0;
}
else if (chooser->priv->image_height < new_height
|| chooser->priv->image_width < new_width) {
/* we need to scale down */
if (new_height > new_width)
scale = (float)chooser->priv->image_height / new_height;
else
scale = (float)chooser->priv->image_width / new_width;
}
else {
/* we need to scale up */
printf ("we need to scale up\n");
if (new_height > new_width)
scale = (float)new_height / chooser->priv->image_height;
else
scale = (float)new_width / chooser->priv->image_width;
}
if (scale == 1.0) {
gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image), pixbuf);
chooser->priv->image_width = new_width;
chooser->priv->image_height = new_height;
}
else {
new_width *= scale;
new_height *= scale;
new_width = MIN (new_width, chooser->priv->image_width);
new_height = MIN (new_height, chooser->priv->image_height);
scaled = gdk_pixbuf_scale_simple (pixbuf,
new_width, new_height,
GDK_INTERP_BILINEAR);
composite = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, gdk_pixbuf_get_bits_per_sample (pixbuf),
chooser->priv->image_width, chooser->priv->image_height);
gdk_pixbuf_fill (composite, 0x00000000);
gdk_pixbuf_copy_area (scaled, 0, 0, new_width, new_height,
composite,
chooser->priv->image_width / 2 - new_width / 2,
chooser->priv->image_height / 2 - new_height / 2);
gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image), composite);
gdk_pixbuf_unref (scaled);
gdk_pixbuf_unref (composite);
}
gdk_pixbuf_unref (pixbuf);
g_free (chooser->priv->image_buf);
chooser->priv->image_buf = data;
chooser->priv->image_buf_size = length;
g_signal_emit (chooser,
image_chooser_signals [CHANGED], 0);
rv = TRUE;
}
return rv;
}
static gboolean
image_drag_motion_cb (GtkWidget *widget,
GdkDragContext *context,
gint x, gint y, guint time, EImageChooser *chooser)
{
GList *p;
if (!chooser->priv->editable)
return FALSE;
for (p = context->targets; p != NULL; p = p->next) {
char *possible_type;
possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
if (!strcmp (possible_type, URI_LIST_TYPE)) {
g_free (possible_type);
gdk_drag_status (context, GDK_ACTION_COPY, time);
gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_IN);
return TRUE;
}
g_free (possible_type);
}
gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
return FALSE;
}
static void
image_drag_leave_cb (GtkWidget *widget,
GdkDragContext *context,
guint time, EImageChooser *chooser)
{
gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
}
static gboolean
image_drag_drop_cb (GtkWidget *widget,
GdkDragContext *context,
gint x, gint y, guint time, EImageChooser *chooser)
{
GList *p;
if (!chooser->priv->editable)
return FALSE;
if (context->targets == NULL) {
gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
return FALSE;
}
for (p = context->targets; p != NULL; p = p->next) {
char *possible_type;
possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
if (!strcmp (possible_type, URI_LIST_TYPE)) {
g_free (possible_type);
gtk_drag_get_data (widget, context,
GDK_POINTER_TO_ATOM (p->data),
time);
gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
return TRUE;
}
g_free (possible_type);
}
gtk_frame_set_shadow_type (GTK_FRAME (chooser->priv->frame), GTK_SHADOW_NONE);
return FALSE;
}
static void
image_drag_data_received_cb (GtkWidget *widget,
GdkDragContext *context,
gint x, gint y,
GtkSelectionData *selection_data,
guint info, guint time, EImageChooser *chooser)
{
char *target_type;
gboolean handled = FALSE;
target_type = gdk_atom_name (selection_data->target);
if (!strcmp (target_type, URI_LIST_TYPE)) {
GnomeVFSResult result;
GnomeVFSHandle *handle;
char *uri;
char *nl = strstr (selection_data->data, "\r\n");
char *buf = NULL;
GnomeVFSFileInfo info;
if (nl)
uri = g_strndup (selection_data->data, nl - (char*)selection_data->data);
else
uri = g_strdup (selection_data->data);
printf ("uri == %s\n", uri);
result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
if (result == GNOME_VFS_OK) {
result = gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_DEFAULT);
if (result == GNOME_VFS_OK) {
GnomeVFSFileSize num_left;
GnomeVFSFileSize num_read;
GnomeVFSFileSize total_read;
printf ("file size = %d\n", (int)info.size);
buf = g_malloc (info.size);
num_left = info.size;
total_read = 0;
while ((result = gnome_vfs_read (handle, buf + total_read, num_left, &num_read)) == GNOME_VFS_OK) {
num_left -= num_read;
total_read += num_read;
}
printf ("read %d bytes\n", (int)total_read);
if (set_image_from_data (chooser, buf, total_read)) {
handled = TRUE;
}
else {
/* XXX we should pop up a warning dialog here */
g_free (buf);
}
}
gnome_vfs_close (handle);
}
else {
printf ("gnome_vfs_open failed (%s)\n", gnome_vfs_result_to_string (result));
}
g_free (uri);
}
gtk_drag_finish (context, handled, FALSE, time);
}
gboolean
e_image_chooser_set_from_file (EImageChooser *chooser, const char *filename)
{
gchar *data;
gsize data_length;
g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE);
g_return_val_if_fail (filename, FALSE);
if (!g_file_get_contents (filename, &data, &data_length, NULL)) {
return FALSE;
}
if (!set_image_from_data (chooser, data, data_length))
g_free (data);
return TRUE;
}
void
e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable)
{
g_return_if_fail (E_IS_IMAGE_CHOOSER (chooser));
chooser->priv->editable = editable;
gtk_widget_set_sensitive (chooser->priv->browse_button, editable);
}
gboolean
e_image_chooser_get_image_data (EImageChooser *chooser, char **data, gsize *data_length)
{
g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE);
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (data_length != NULL, FALSE);
*data_length = chooser->priv->image_buf_size;
*data = g_malloc (*data_length);
memcpy (*data, chooser->priv->image_buf, *data_length);
return TRUE;
}
gboolean
e_image_chooser_set_image_data (EImageChooser *chooser, char *data, gsize data_length)
{
char *buf;
g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser), FALSE);
g_return_val_if_fail (data != NULL, FALSE);
/* yuck, a copy... */
buf = g_malloc (data_length);
memcpy (buf, data, data_length);
if (!set_image_from_data (chooser, buf, data_length)) {
g_free (buf);
return FALSE;
}
return TRUE;
}

View File

@@ -1,64 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* e-image-chooser.c
* Copyright (C) 2004 Novell, Inc.
* Author: Chris Toshok <toshok@ximian.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* 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 library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _E_IMAGE_CHOOSER_H_
#define _E_IMAGE_CHOOSER_H_
#include <gtk/gtkvbox.h>
G_BEGIN_DECLS
#define E_TYPE_IMAGE_CHOOSER (e_image_chooser_get_type ())
#define E_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_IMAGE_CHOOSER, EImageChooser))
#define E_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_IMAGE_CHOOSER, EImageChooserClass))
#define E_IS_IMAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_IMAGE_CHOOSER))
#define E_IS_IMAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_IMAGE_CHOOSER))
typedef struct _EImageChooser EImageChooser;
typedef struct _EImageChooserClass EImageChooserClass;
typedef struct _EImageChooserPrivate EImageChooserPrivate;
struct _EImageChooser
{
GtkVBox parent;
EImageChooserPrivate *priv;
};
struct _EImageChooserClass
{
GtkVBoxClass parent_class;
/* signals */
void (*changed) (EImageChooser *chooser);
};
GtkWidget *e_image_chooser_new (void);
GType e_image_chooser_get_type (void);
gboolean e_image_chooser_set_from_file (EImageChooser *chooser, const char *filename);
gboolean e_image_chooser_set_image_data (EImageChooser *chooser, char *data, gsize data_length);
void e_image_chooser_set_editable (EImageChooser *chooser, gboolean editable);
gboolean e_image_chooser_get_image_data (EImageChooser *chooser, char **data, gsize *data_length);
#endif /* _E_IMAGE_CHOOSER_H_ */

View File

@@ -1,3 +0,0 @@
NONE:NONE
NONE:INT
NONE:POINTER

View File

@@ -1,333 +0,0 @@
/* gnome-about-me.c
* Copyright (C) 2002 Diego Gonzalez
*
* Written by: Diego Gonzalez <diego@pemas.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, 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.
*
* Parts of this code come from Gnome-System-Tools.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include <pwd.h>
#include <glade/glade.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <termios.h>
#include <pty.h>
#include "capplet-util.h"
typedef struct {
GtkWidget *dialog;
GtkWidget *old_password;
GtkWidget *new_password;
GtkWidget *retyped_password;
/* Communication with the passwd program */
FILE *backend_stream;
int backend_master_fd;
int backend_pid;
guint timeout_id;
} PasswordDialog;
enum
{
RESPONSE_APPLY = 1,
RESPONSE_CLOSE
};
static void passdlg_set_busy (PasswordDialog *dlg, gboolean busy);
#define REDRAW_NCHARS 1
static gboolean
wait_child (PasswordDialog *pdialog)
{
GtkWidget *dialog;
gint status, pid;
gchar *primary_text = NULL;
gchar *secondary_text = NULL;
pid = waitpid (pdialog->backend_pid, &status, WNOHANG);
if (pid > 0) {
if (WIFEXITED (status) && (WEXITSTATUS(status) == 0)) {
passdlg_set_busy (pdialog, FALSE);
primary_text = g_strdup (_("Password changed successfully"));
dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
primary_text, secondary_text);
g_signal_connect (G_OBJECT (dialog), "response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
gtk_widget_show (dialog);
return FALSE;
} else if ((WIFEXITED (status)) && (WEXITSTATUS (status)) && (WEXITSTATUS(status) < 255)) {
/* the proccess was running su */
primary_text = g_strdup (_("The entered password is invalid"));
secondary_text = g_strdup (_("Check that you typed it correctly "
"and that you haven't activated the \"caps lock\" key"));
} else if ((WIFEXITED (status)) && (WEXITSTATUS (status)) && (WEXITSTATUS (status) == 255)) {
primary_text = g_strdup (_("Could not run passwd"));
secondary_text = g_strdup (_("Check that you have permissions to run this command"));
} else {
primary_text = g_strdup (_("An unexpected error has ocurred"));
}
if (primary_text) {
passdlg_set_busy (pdialog, FALSE);
dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
primary_text, secondary_text);
g_signal_connect (G_OBJECT (dialog), "response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
gtk_widget_show (dialog);
g_free (primary_text);
g_free (secondary_text);
}
return FALSE;
}
return TRUE;
}
static gboolean
is_string_complete (gchar *str, GSList *list)
{
GSList *elem;
if (strlen (str) == 0)
return FALSE;
for (elem = list; elem; elem = g_slist_next (elem))
if (g_strrstr (str, elem->data) != NULL)
return TRUE;
return FALSE;
}
static char *
read_from_backend_va (PasswordDialog *pdialog, gchar *needle, va_list ap)
{
GString *str = g_string_new ("");
gboolean may_exit = FALSE;
gint i = 0;
gchar c, *ptr, *arg;
GSList *list = NULL;
list = g_slist_prepend (list, needle);
while ((arg = va_arg (ap, char*)) != NULL)
list = g_slist_prepend (list, arg);
va_end (ap);
while (!is_string_complete (str->str, list)) {
c = fgetc (pdialog->backend_stream);
i++;
if (*str->str)
g_string_append_c (str, c);
else {
/* the string is still empty, read with O_NONBLOCK until
* it gets a char, this is done for not blocking the UI
*/
if (c != EOF) {
g_string_append_c (str, c);
fcntl (pdialog->backend_master_fd, F_SETFL, 0);
}
usleep (500);
}
/* ugly hack for redrawing UI without too much overload */
if (i == REDRAW_NCHARS) {
while (gtk_events_pending ())
gtk_main_iteration ();
i = 0;
}
}
fcntl (pdialog->backend_master_fd, F_SETFL, O_NONBLOCK);
ptr = str->str;
g_string_free (str, FALSE);
return ptr;
}
static gchar*
read_from_backend (PasswordDialog *pdialog, gchar *needle, ...)
{
va_list ap;
va_start (ap, needle);
return read_from_backend_va (pdialog, needle, ap);
}
static void
write_to_backend (PasswordDialog *pdialog, char *str)
{
gint nread = 0;
int ret;
/* turn the descriptor blocking for writing the configuration */
fcntl (pdialog->backend_master_fd, F_SETFL, 0);
do {
ret = fputc (str [nread], pdialog->backend_stream);
if (ret != EOF)
nread++;
/* ugly hack for redrawing UI */
if (nread % REDRAW_NCHARS == 0)
while (gtk_events_pending ())
gtk_main_iteration ();
} while (nread < strlen (str));
while (fflush (pdialog->backend_stream) != 0);
fcntl (pdialog->backend_master_fd, F_SETFL, O_NONBLOCK);
}
static void
passdlg_set_busy (PasswordDialog *pdialog, gboolean busy)
{
GtkWindow *toplevel = GTK_WINDOW (pdialog->dialog);
GdkCursor *cursor = NULL;
GdkDisplay *display;
display = gtk_widget_get_display (GTK_WIDGET (toplevel));
if (busy)
cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
gdk_window_set_cursor (GTK_WIDGET (toplevel)->window, cursor);
gdk_display_flush (display);
if (busy)
gdk_cursor_unref (cursor);
}
static void
passdlg_button_clicked_cb (GtkDialog *dialog, gint response_id, PasswordDialog *pdialog)
{
char *new_password;
char *retyped_password;
char *old_password;
char *args[2];
gchar *s;
if (response_id == GTK_RESPONSE_OK) {
/* */
old_password = g_strdup_printf ("%s\n", gtk_entry_get_text (GTK_ENTRY (pdialog->old_password)));
new_password = g_strdup_printf ("%s\n", gtk_entry_get_text (GTK_ENTRY (pdialog->new_password)));
retyped_password = g_strdup_printf ("%s\n", gtk_entry_get_text (GTK_ENTRY (pdialog->retyped_password)));
/* Set the busy cursor as this can be a long process */
passdlg_set_busy (pdialog, TRUE);
/* Prepare the execution environment of passwd */
args[0] = "/usr/bin/passwd";
args[1] = NULL;
pdialog->backend_pid = forkpty (&pdialog->backend_master_fd, NULL, NULL, NULL);
if (pdialog->backend_pid < 0) {
g_warning ("could not fork to backend");
gtk_main_quit ();
} else if (pdialog->backend_pid == 0) {
execv (args[0], args);
exit (255);
} else {
fcntl (pdialog->backend_master_fd, F_SETFL, O_NONBLOCK);
pdialog->timeout_id = g_timeout_add (1000, (GSourceFunc) wait_child, pdialog);
pdialog->backend_stream = fdopen (pdialog->backend_master_fd, "a+");
}
/* Send current password to backend */
s = read_from_backend (pdialog, "assword:", ": ", NULL);
write_to_backend (pdialog, old_password);
s = read_from_backend (pdialog, "assword:", ": ", "\n", NULL);
while (strlen(s) < 4) {
usleep(1000);
s = read_from_backend (pdialog, "assword:", ": ", "\n", NULL);
}
/* Send new password to backend */
write_to_backend (pdialog, new_password);
s = read_from_backend (pdialog, "assword:", ": ", "\n", NULL);
while (strlen(s) < 4) {
usleep(1000);
s = read_from_backend (pdialog, "assword:", ": ", "\n", NULL);
}
/* Send new and retyped password to backend */
write_to_backend (pdialog, retyped_password);
s = read_from_backend (pdialog, "assword:", ": ", "\n", NULL);
while (strlen(s) < 4) {
usleep(1000);
s = read_from_backend (pdialog, "\n", NULL);
}
} else {
gtk_main_quit ();
}
}
void
gnome_about_me_password (void)
{
PasswordDialog *pdialog;
GladeXML *dialog;
pdialog = g_new0 (PasswordDialog, 1);
dialog = glade_xml_new (GNOMECC_DATA_DIR "/interfaces/gnome-about-me.glade", "change-password", NULL);
pdialog->dialog = WID ("change-password");
g_signal_connect (G_OBJECT (pdialog->dialog), "response",
G_CALLBACK (passdlg_button_clicked_cb), pdialog);
pdialog->old_password = WID ("old-password");
pdialog->new_password = WID ("new-password");
pdialog->retyped_password = WID ("retyped-password");
gtk_window_set_resizable (GTK_WINDOW (pdialog->dialog), FALSE);
gtk_widget_show_all (pdialog->dialog);
gtk_main ();
gtk_widget_destroy (pdialog->dialog);
g_object_unref (G_OBJECT (dialog));
g_free (pdialog);
}

View File

@@ -1,7 +0,0 @@
#ifndef __GNOME_ABOUT_ME_PASSWORD_H__
#define __GNOME_ABOUT_ME_PASSWORD_H__
void
gnome_about_me_password (void);
#endif /* __GNOME_ABOUT_ME_PASSWORD_H__ */

View File

@@ -1,720 +0,0 @@
/* gnome-about-me.c
* Copyright (C) 2002 Diego Gonzalez
*
* Written by: Diego Gonzalez <diego@pemas.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, 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include <pwd.h>
#include <gconf/gconf-client.h>
#include <glade/glade.h>
#include <pwd.h>
#include <unistd.h>
#include <bonobo/bonobo-main.h>
#include <libebook/e-book.h>
#include "e-image-chooser.h"
#include "gnome-about-me-password.h"
#include "capplet-util.h"
typedef struct {
EContact *contact;
EBook *book;
GladeXML *dialog;
GtkWidget *fsel;
GdkScreen *screen;
GtkIconTheme *theme;
EContactAddress *addr1;
EContactAddress *addr2;
gboolean have_image;
gboolean image_changed;
gboolean create_self;
gchar *person;
} GnomeAboutMe;
static GnomeAboutMe *me;
struct WidToCid{
gchar *wid;
guint cid;
};
enum {
ADDRESS_STREET = 1,
ADDRESS_POBOX,
ADDRESS_LOCALITY,
ADDRESS_CODE,
ADDRESS_REGION,
ADDRESS_COUNTRY
};
#define ADDRESS_HOME 21
#define ADDRESS_WORK 27
struct WidToCid ids[] = {
{ "email-work-e", E_CONTACT_EMAIL_1 }, /* 00 */
{ "email-home-e", E_CONTACT_EMAIL_2 }, /* 01 */
{ "phone-home-e", E_CONTACT_PHONE_HOME }, /* 02 */
{ "phone-mobile-e", E_CONTACT_PHONE_MOBILE }, /* 03 */
{ "phone-work-e", E_CONTACT_PHONE_BUSINESS }, /* 04 */
{ "phone-work-fax-e", E_CONTACT_PHONE_BUSINESS_FAX }, /* 05 */
{ "im-jabber-e", E_CONTACT_IM_JABBER_HOME_1 }, /* 06 */
{ "im-msn-e", E_CONTACT_IM_MSN_HOME_1 }, /* 07 */
{ "im-icq-e", E_CONTACT_IM_ICQ_HOME_1 }, /* 08 */
{ "im-yahoo-e", E_CONTACT_IM_YAHOO_HOME_1 }, /* 09 */
{ "im-aim-e", E_CONTACT_IM_AIM_HOME_1 }, /* 10 */
{ "im-groupwise-e", E_CONTACT_IM_GROUPWISE_HOME_1 }, /* 11 */
{ "web-homepage-e", E_CONTACT_HOMEPAGE_URL }, /* 12 */
{ "web-calendar-e", E_CONTACT_CALENDAR_URI }, /* 13 */
{ "web-weblog-e", E_CONTACT_BLOG_URL }, /* 14 */
{ "job-profession-e", E_CONTACT_ROLE }, /* 15 */
{ "job-title-e", E_CONTACT_TITLE }, /* 16 */
{ "job-dept-e", E_CONTACT_ORG_UNIT }, /* 17 */
{ "job-assistant-e", E_CONTACT_ASSISTANT }, /* 18 */
{ "job-company-e", E_CONTACT_ORG }, /* 19 */
{ "job-manager-e", E_CONTACT_MANAGER }, /* 20 */
{ "addr-street-1", ADDRESS_STREET }, /* 21 */
{ "addr-po-1", ADDRESS_POBOX }, /* 22 */
{ "addr-locality-1", ADDRESS_LOCALITY }, /* 23 */
{ "addr-code-1", ADDRESS_CODE }, /* 24 */
{ "addr-region-1", ADDRESS_REGION }, /* 25 */
{ "addr-country-1", ADDRESS_COUNTRY }, /* 26 */
{ "addr-street-2", ADDRESS_STREET }, /* 27 */
{ "addr-po-2", ADDRESS_POBOX }, /* 28 */
{ "addr-locality-2", ADDRESS_LOCALITY }, /* 29 */
{ "addr-code-2", ADDRESS_CODE }, /* 30 */
{ "addr-region-2", ADDRESS_REGION }, /* 31 */
{ "addr-country-2", ADDRESS_COUNTRY }, /* 32 */
{ NULL, 0 }
};
enum
{
RESPONSE_APPLY = 1,
RESPONSE_CLOSE
};
static void about_me_set_address_field (EContactAddress *, guint, gchar *);
/********************/
static void
about_me_commit (GnomeAboutMe *me)
{
GError *error = NULL;
if (me->create_self) {
e_contact_set (me->contact, E_CONTACT_FILE_AS, "asdffff");
e_contact_set (me->contact, E_CONTACT_NICKNAME, "nickname");
e_contact_set (me->contact, E_CONTACT_FULL_NAME, "fullname");
}
if (me->create_self) {
e_book_add_contact (me->book, me->contact, &error);
e_book_set_self (me->book, me->contact, &error);
} else {
if (e_book_commit_contact (me->book, me->contact, &error) == FALSE)
g_print ("There was an undeterminad error\n");
}
me->create_self = FALSE;
}
static gboolean
about_me_focus_out (GtkWidget *widget, GdkEventFocus *event, GnomeAboutMe *me)
{
gchar *str = NULL;
const gchar *wid;
gint i;
wid = glade_get_widget_name (widget);
for (i = 0; ids[i].wid != NULL; i++)
if (g_ascii_strcasecmp (ids[i].wid, wid) == 0)
break;
if (ids[i].cid == 0) {
g_warning ("returning at invalid point\n");
return FALSE;
}
if (GTK_IS_ENTRY (widget)) {
str = gtk_editable_get_chars (GTK_EDITABLE (widget), 0, -1);
} else if (GTK_IS_TEXT_VIEW (widget)) {
GtkTextBuffer *buffer;
GtkTextIter iter_start;
GtkTextIter iter_end;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
gtk_text_buffer_get_start_iter (buffer, &iter_start);
iter_end = iter_start;
gtk_text_iter_forward_to_end (&iter_end);
str = gtk_text_iter_get_text (&iter_start, &iter_end);
}
str = str ? str : "";
if (i >= ADDRESS_HOME && i < ADDRESS_WORK) {
about_me_set_address_field (me->addr1, ids[i].cid, str);
e_contact_set (me->contact, E_CONTACT_ADDRESS_HOME, me->addr1);
} else if (i >= ADDRESS_WORK) {
about_me_set_address_field (me->addr2, ids[i].cid, str);
e_contact_set (me->contact, E_CONTACT_ADDRESS_WORK, me->addr2);
} else {
e_contact_set (me->contact, ids[i].cid, str);
}
g_free (str);
about_me_commit (me);
return FALSE;
}
/********************/
static char *
get_user_login (void)
{
char buf[LINE_MAX * 4];
struct passwd pwd, *err;
int i;
i = getpwuid_r(getuid(), &pwd, buf, sizeof(buf), &err);
return ((i == 0) && (err == &pwd)) ? g_strdup(pwd.pw_name) : NULL;
}
/*
* Helpers
*/
GtkWidget *
about_me_get_widget (GladeXML *dialog, gchar *name, gint suffix)
{
GtkWidget *widget;
gchar *str;
str = g_strdup_printf ("%s-%d", name, suffix);
widget = WID(str);
g_free (str);
return widget;
}
static gchar *
about_me_get_address_field (EContactAddress *addr, guint cid)
{
gchar *str = NULL;
if (addr == NULL)
return NULL;
switch (cid) {
case ADDRESS_STREET:
str = addr->street;
break;
case ADDRESS_POBOX:
str = addr->po;
break;
case ADDRESS_LOCALITY:
str = addr->locality;
break;
case ADDRESS_CODE:
str = addr->code;
break;
case ADDRESS_REGION:
str = addr->region;
break;
case ADDRESS_COUNTRY:
str = addr->country;
break;
}
return str;
}
static void
about_me_set_address_field (EContactAddress *addr, guint cid, gchar *str)
{
switch (cid) {
case ADDRESS_STREET:
if (addr->street)
g_free (addr->street);
addr->street = g_strdup (str);
break;
case ADDRESS_POBOX:
if (addr->po)
g_free (addr->po);
addr->po = g_strdup (str);
break;
case ADDRESS_LOCALITY:
if (addr->locality)
g_free (addr->locality);
addr->locality = g_strdup (str);
break;
case ADDRESS_CODE:
if (addr->code)
g_free (addr->code);
addr->code = g_strdup (str);
break;
case ADDRESS_REGION:
if (addr->region)
g_free (addr->region);
addr->region = g_strdup (str);
break;
case ADDRESS_COUNTRY:
if (addr->country)
g_free (addr->country);
addr->country = g_strdup (str);
break;
}
}
/**
*
* wid: glade widget name
* cid: id of the field (EDS id)
* aid: position in the array WidToCid
**/
static void
about_me_load_string_field (GnomeAboutMe *me, const gchar *wid, guint cid, guint aid)
{
GtkWidget *widget;
GladeXML *dialog;
gchar *str;
dialog = me->dialog;
widget = WID (wid);
if (me->create_self == TRUE) {
g_signal_connect (widget, "focus-out-event", G_CALLBACK (about_me_focus_out), me);
return;
}
if (aid >= ADDRESS_HOME && aid < ADDRESS_WORK) {
str = about_me_get_address_field (me->addr1, cid);
} else if (aid >= ADDRESS_WORK) {
str = about_me_get_address_field (me->addr2, cid);
} else {
str = e_contact_get_const (me->contact, cid);
}
str = str ? str : "";
if (GTK_IS_ENTRY (widget)) {
gtk_entry_set_text (GTK_ENTRY (widget), str);
} else if (GTK_IS_TEXT_VIEW (widget)) {
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
gtk_text_buffer_set_text (buffer, str, -1);
}
g_signal_connect (widget, "focus-out-event", G_CALLBACK (about_me_focus_out), me);
}
static void
about_me_load_photo (GnomeAboutMe *me, EContact *contact)
{
GtkWidget *widget;
GladeXML *dialog;
EContactPhoto *photo;
dialog = me->dialog;
widget = WID("image-chooser");
e_image_chooser_set_from_file (E_IMAGE_CHOOSER (widget), me->person);
photo = e_contact_get (contact, E_CONTACT_PHOTO);
if (photo) {
me->have_image = TRUE;
e_image_chooser_set_image_data (E_IMAGE_CHOOSER (widget), photo->data, photo->length);
e_contact_photo_free (photo);
} else {
me->have_image = FALSE;
}
}
static void
about_me_update_photo (GnomeAboutMe *me)
{
GtkWidget *widget;
GladeXML *dialog;
EContactPhoto *photo;
gchar *file;
FILE *fp;
dialog = me->dialog;
if (me->image_changed && me->have_image) {
widget = WID ("image-chooser");
photo = g_new0 (EContactPhoto, 1);
e_image_chooser_get_image_data (E_IMAGE_CHOOSER (widget), &photo->data, &photo->length);
e_contact_set (me->contact, E_CONTACT_PHOTO, photo);
/* Save the image for GDM */
file = g_strdup_printf ("%s/.gnome2/face.png", g_get_home_dir ());
fp = fopen (file, "wb");
fwrite (photo->data, 1, photo->length, fp);
fclose (fp);
/* Update GDM configuration */
gnome_config_set_string ("/gdmphotosetup/last/picture", file);
gnome_config_set_string ("/gdm/face/picture", file);
gnome_config_sync ();
g_free (file);
e_contact_photo_free (photo);
} else if (me->image_changed && !me->have_image) {
/* Update the image in the card */
e_contact_set (me->contact, E_CONTACT_PHOTO, NULL);
/* Update GDM configuration */
gnome_config_set_string ("/gdmphotosetup/last/picture", "");
gnome_config_set_string ("/gdm/face/picture", "");
gnome_config_sync ();
}
about_me_commit (me);
}
static void
about_me_load_info (GnomeAboutMe *me)
{
gint i;
if (me->create_self == FALSE) {
me->addr1 = e_contact_get (me->contact, E_CONTACT_ADDRESS_HOME);
if (me->addr1 == NULL)
me->addr1 = g_new0 (EContactAddress, 1);
me->addr2 = e_contact_get (me->contact, E_CONTACT_ADDRESS_WORK);
if (me->addr2 == NULL)
me->addr2 = g_new0 (EContactAddress, 1);
}
for (i = 0; ids[i].wid != NULL; i++) {
about_me_load_string_field (me, ids[i].wid, ids[i].cid, i);
}
}
GtkWidget *
eab_create_image_chooser_widget(gchar *name,
gchar *string1, gchar *string2,
gint int1, gint int2)
{
GtkWidget *w = NULL;
w = e_image_chooser_new ();
gtk_widget_show_all (w);
return w;
}
/*
* Functions to handle the photo changing stuff
*/
static void
image_selected (GnomeAboutMe *me)
{
GtkWidget *widget;
GladeXML *dialog;
gchar *image;
me->have_image = TRUE;
me->image_changed = TRUE;
dialog = me->dialog;
widget = WID ("image-chooser");
/* obtener el fichero seleccionado */
image = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (me->fsel));
e_image_chooser_set_from_file (E_IMAGE_CHOOSER (widget), image);
g_free (image);
about_me_update_photo (me);
return;
}
static void
image_cleared (GnomeAboutMe *me)
{
GtkWidget *widget;
GladeXML *dialog;
me->have_image = FALSE;
me->image_changed = TRUE;
dialog = me->dialog;
widget = WID ("image-chooser");
e_image_chooser_set_from_file (E_IMAGE_CHOOSER (widget), me->person);
about_me_update_photo (me);
return;
}
static void
about_me_file_chooser_response (GtkWidget *widget, gint response, GnomeAboutMe *me)
{
if (response == GTK_RESPONSE_ACCEPT)
image_selected (me);
else if (response == GTK_RESPONSE_NO)
image_cleared (me);
gtk_widget_hide (me->fsel);
}
static void
about_me_image_clicked_cb (GtkWidget *button, GnomeAboutMe *me)
{
char *title = _("Select Image");
char *noimage = _("No Image");
me->fsel = gtk_file_chooser_dialog_new (title, NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
noimage, GTK_RESPONSE_NO,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (me->fsel), GTK_RESPONSE_ACCEPT);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (me->fsel), g_get_home_dir ());
g_signal_connect (me->fsel, "response",
G_CALLBACK (about_me_file_chooser_response), me);
gtk_window_present (GTK_WINDOW (me->fsel));
}
/* About Me Dialog Callbacks */
static void
about_me_icon_theme_changed (GtkWindow *window,
GtkIconTheme *theme)
{
GtkWidget *widget;
GtkIconInfo *icon;
GladeXML *dialog;
icon = gtk_icon_theme_lookup_icon (me->theme, "stock_person", 80, 0);
if (icon == NULL) {
g_print ("Icon not found\n");
}
g_free (me->person);
me->person = g_strdup (gtk_icon_info_get_filename (icon));
gtk_icon_info_free (icon);
if (me->have_image) {
dialog = me->dialog;
widget = WID ("image-chooser");
e_image_chooser_set_from_file (E_IMAGE_CHOOSER (widget), me->person);
}
}
static void
about_me_button_clicked_cb (GtkDialog *dialog, gint response_id, GnomeAboutMe *me)
{
if (response_id == GTK_RESPONSE_HELP)
g_print ("Help goes here");
else {
e_contact_address_free (me->addr1);
e_contact_address_free (me->addr2);
g_object_unref (me->contact);
g_object_unref (me->book);
g_object_unref (me->dialog);
g_free (me->person);
g_free (me);
gtk_main_quit ();
}
}
static void
about_me_passwd_clicked_cb (GtkWidget *button, gpointer data)
{
gnome_about_me_password ();
}
static void
about_me_setup_dialog (void)
{
GtkWidget *widget;
GtkIconInfo *icon;
GladeXML *dialog;
GError *error = NULL;
struct passwd *pwent;
char *user = NULL;
gchar *str;
me = g_new0 (GnomeAboutMe, 1);
dialog = glade_xml_new (GNOMECC_DATA_DIR "/interfaces/gnome-about-me.glade",
"about-me-dialog", NULL);
me->dialog = dialog;
/* Setup theme details */
me->screen = gtk_window_get_screen (WID ("about-me-dialog"));
me->theme = gtk_icon_theme_get_for_screen (me->screen);
icon = gtk_icon_theme_lookup_icon (me->theme, "stock_person", 80, 0);
if (icon == NULL) {
g_print ("Icon not found\n");
}
me->person = g_strdup (gtk_icon_info_get_filename (icon));
gtk_icon_info_free (icon);
g_signal_connect_object (me->theme, "changed",
G_CALLBACK (about_me_icon_theme_changed),
GTK_WIDGET (WID("about-me-dialog")),
G_CONNECT_SWAPPED);
/* Get the self contact */
if (!e_book_get_self (&me->contact, &me->book, &error)) {
me->create_self = TRUE;
me->contact = e_contact_new ();
g_print ("%s\n", error->message);
g_clear_error (&error);
if (me->book == NULL) {
me->book = e_book_new_system_addressbook (&error);
if (me->book == NULL)
g_print ("error message: %s\n", error->message);
if (e_book_open (me->book, FALSE, NULL) == FALSE)
g_print ("unable to open book, bailing out\n");
}
}
/************************************************/
user = get_user_login ();
setpwent ();
pwent = getpwnam (user);
if (pwent == NULL) {
printf ("error\n");
return ;
}
gchar **tok;
tok = g_strsplit (pwent->pw_gecos, ",", 0);
/************************************************/
/* Fill in the blanks */
/* Contact Tab */
about_me_load_photo (me, me->contact);
widget = WID ("fullname");
if (tok[0] == NULL || strlen(tok[0]) == 0) {
str = g_strdup ("<b><span size=\"xx-large\">COMO LO HAGO?</span></b>");
} else {
str = g_strdup_printf ("<b><span size=\"xx-large\">%s</span></b>", tok[0]);
}
gtk_label_set_markup (GTK_LABEL (widget), str);
g_free (str);
widget = WID ("login");
gtk_label_set_text (GTK_LABEL (widget), user);
widget = WID ("about-me-dialog");
str = g_strdup_printf ("About %s", tok[0]);
gtk_window_set_title (GTK_WINDOW (widget), str);
g_free (str);
widget = WID("password");
g_signal_connect (G_OBJECT (widget), "clicked",
G_CALLBACK (about_me_passwd_clicked_cb), NULL);
widget = WID ("button-image");
g_signal_connect (G_OBJECT (widget), "clicked",
G_CALLBACK (about_me_image_clicked_cb), me);
about_me_load_info (me);
/* Connect the close button signal */
widget = WID ("about-me-dialog");
g_signal_connect (G_OBJECT (widget), "response",
G_CALLBACK (about_me_button_clicked_cb), me);
/* TODO: Set dialog icon */
gtk_window_set_resizable (GTK_WINDOW (widget), FALSE);
capplet_set_icon (widget, "gnome-about-me.png");
gtk_widget_show_all (widget);
}
int
main (int argc, char **argv)
{
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
gnome_program_init ("gnome-about-me", VERSION,
LIBGNOMEUI_MODULE, argc, argv,
GNOME_PARAM_APP_DATADIR, GNOMECC_DATA_DIR,
NULL);
if (bonobo_init (&argc, argv) == FALSE)
g_error ("Could not initialize Bonobo");
about_me_setup_dialog ();
gtk_main ();
return 0;
}

View File

@@ -1,13 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
_Name=About me
_Comment=Information about myself
Exec=gnome-about-me
Icon=gnome-about-me.png
Terminal=false
Type=Application
StartupNotify=true
Categories=GNOME;Application;Settings;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=control-center
X-GNOME-Bugzilla-Component=other-capplets

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,2 +0,0 @@
Makefile
Makefile.in

View File

@@ -1 +0,0 @@
SUBDIRS = keyboard at-properties

View File

@@ -1,5 +0,0 @@
*.desktop
Makefile
Makefile.in
gnome-at-properties
at-properties.desktop.in

View File

@@ -1,99 +0,0 @@
2004-11-09 Mark McLoughlin <mark@skynet.ie>
* Makefile.am: install the .desktop file in
$(datadir)/applications.
* at-properties.desktop.in: add OnlyShowIn=GNOME;
2004-10-14 Jody Goldberg <jody@gnome.org>
* Release 2.8.1
Thu Sep 2 17:06:28 2004 Jonathan Blandford <jrb@redhat.com>
* main.c: (cb_dialog_response): Change to use help docs instead of
the "foo"/"bar" that's there.
2004-08-20 Frederic Crozat <fcrozat@mandrakesoft.com>
* main.c: (setup_dialog):
Use themed icon for window hint.
2004-04-15 Jody Goldberg <jody@gnome.org>
* Release 2.6.1
2004-04-01 Jody Goldberg <jody@gnome.org>
* Release 2.6.0.3
2004-03-30 Jody Goldberg <jody@gnome.org>
* Release 2.6.0.1
2004-03-23 Jody Goldberg <jody@gnome.org>
* Release 2.6.0
2004-03-11 Jody Goldberg <jody@gnome.org>
* Release 2.5.4
2003-11-27 Muktha <muktha.narayan@wipro.com>
* main.c: Do not popup the logout dialog when the close button (X) of
window manager is clicked. Fixes bug #124032.
2004-02-13 Jody Goldberg <jody@gnome.org>
* Release 2.5.3
2004-01-14 Jody Goldberg <jody@gnome.org>
* Release 2.5.2
2003-12-30 Jody Goldberg <jody@gnome.org>
* Release 2.5.1.1
2003-12-30 Jody Goldberg <jody@gnome.org>
* Release 2.5.1
2003-10-28 Jody Goldberg <jody@gnome.org>
* Release 2.5.0
2003-08-01 Dennis Cranston <dennis_cranston at yahoo com>
* at-enable-dialog.glade: Patch to add two more pixels of spacing
between action area and vbox of preferences dialog.
Fri Aug 1 14:28:52 2003 Jonathan Blandford <jrb@redhat.com>
* main.c (init_startup_state): remove markup tags from translated
strings, #118801.
2003-07-18 Jonathan Blandford <jrb@gnome.org>
* main.c: Add a check to confirm that the AT's are installed. Add
a warning message if they are not. Change widget naming scheme.
* at-enable-dialog.glade: Change widget naming scheme.
2003-07-16 Dennis Cranston <dennis_cranston at yahoo com>
* at-enable-dialog.glade: Make close the default button.
2003-07-16 Dennis Cranston <dennis_cranston at yahoo com>
* at-enable-dialog.glade: Adjust widget padding and remove
separator per HIG.
2003-07-07 Jody Goldberg <jody@gnome.org>
* Release 2.3.4
2003-07-01 Daniel Baeyens <daniel.baeyens@hispalinux.es>
* capplets/accessibility/at-properties/at-enable-dialog.glade:
"Assistive" is misspelled.

View File

@@ -1,29 +0,0 @@
bin_PROGRAMS = gnome-at-properties
gnome_at_properties_LDADD = $(AT_CAPPLET_LIBS) $(top_builddir)/capplets/common/libcommon.la
gnome_at_properties_SOURCES = \
main.c \
at-startup-session.h \
at-startup-session.c
gnome_at_properties_LDFLAGS = -export-dynamic
@INTLTOOL_DESKTOP_RULE@
desktopdir = $(datadir)/applications
Desktop_in_files = at-properties.desktop.in
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
pixmapdir = $(GNOMECC_PIXMAPS_DIR)
pixmap_DATA = \
at-startup.png \
at-support.png
gladedir = $(GNOMECC_GLADE_DIR)
glade_DATA = at-enable-dialog.glade
INCLUDES = $(AT_CAPPLET_CFLAGS) \
$(GNOMECC_CAPPLETS_CFLAGS) \
-DGLADEDIR=\""$(gladedir)"\" \
-DPIXMAPDIR=\""$(pixmapdir)"\"
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES) $(Desktop_in_files) $(desktop_DATA)
EXTRA_DIST = $(glade_DATA) $(pixmap_DATA)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -1,465 +0,0 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<requires lib="gnome"/>
<widget class="GtkDialog" id="at_properties_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Assistive Technology Preferences</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">False</property>
<property name="destroy_with_parent">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="at_help_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-help</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-11</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="at_close_logout_button">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">0</property>
<child>
<widget class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="at_close_and_logout_image">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="label" translatable="yes">Close and _Log Out</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkButton" id="at_close_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-7</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">18</property>
<child>
<widget class="GtkVBox" id="at_support_frame">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Support&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">12</property>
<child>
<widget class="GtkImage" id="at_enable_image">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox3">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkCheckButton" id="at_enable_toggle">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Enable assistive technologies</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="at_warning_label">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;&lt;b&gt;Note:&lt;/b&gt; Changes to this setting will not take effect until you next log in.&lt;/i&gt;&lt;/small&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="at_applications_frame">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkVBox" id="vbox7">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Applications&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">12</property>
<child>
<widget class="GtkImage" id="at_applications_image">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox5">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkLabel" id="at_applications_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Start these assistive technologies every time you log in:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">6</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="at_screenreader_toggle">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Screenreader</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="at_magnifier_toggle">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Magnifier</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="at_keyboard_toggle">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_On-screen keyboard</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="at_applications_hseparator">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="at_applications_warning_label">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@@ -1,15 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
_Name=Assistive Technology Support
_Comment=Enable support for GNOME assistive technologies at login
Exec=gnome-at-properties
Icon=gnome-settings-accessibility-technologies
Terminal=false
Type=Application
StartupNotify=true
Categories=GNOME;Settings;Accessibility;
OnlyShowIn=GNOME;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=control-center
X-GNOME-Bugzilla-Component=Assistive Technology Support
X-GNOME-Bugzilla-Version=@VERSION@

View File

@@ -1,160 +0,0 @@
#include <config.h>
#include <string.h>
#include <glib-object.h>
#include <gconf/gconf-client.h>
#include "at-startup-session.h"
#define AT_STARTUP_KEY "/desktop/gnome/accessibility/startup/exec_ats"
#define GNOPERNICUS_MAGNIFIER_KEY "/apps/gnopernicus/srcore/mag_active"
#define GNOPERNICUS_SPEECH_KEY "/apps/gnopernicus/srcore/sp_active"
#define GNOPERNICUS_BRAILLE_KEY "/apps/gnopernicus/srcore/br_active"
static AtStartupState at_startup_state_recent;
static GSList *
at_startup_get_list (GConfClient *client)
{
GError *error = NULL;
GSList *at_list = gconf_client_get_list (client, AT_STARTUP_KEY, GCONF_VALUE_STRING, &error);
if (error) {
g_warning ("Error getting value of " AT_STARTUP_KEY ": %s", error->message);
g_error_free (error);
return NULL;
}
return at_list;
}
gint
at_startup_string_compare (gconstpointer s1, gconstpointer s2)
{
if (s1 && s2) {
return strcmp (s1, s2);
}
else
return ((char *)s2-(char *)s1);
}
static GSList *
at_startup_list_add (GSList *list, const gchar *exec_name)
{
GSList *l = g_slist_find_custom (list, exec_name, at_startup_string_compare);
if (!l) {
list = g_slist_append (list, g_strdup (exec_name));
}
return list;
}
static GSList *
at_startup_list_remove (GSList *list, const gchar *exec_name)
{
GSList *l = g_slist_find_custom (list, exec_name, at_startup_string_compare);
if (l) {
g_free (l->data);
list = g_slist_delete_link (list, l);
}
return list;
}
void
at_startup_state_init (AtStartupState *startup_state)
{
gboolean mag_active, speech_active, braille_active;
GSList *l;
GConfClient *client = gconf_client_get_default ();
GSList *at_list = at_startup_get_list (client);
gchar *prog;
for (l = at_list; l; l = l->next) {
gchar *exec_name = (char *) l->data;
if (exec_name && !strcmp (exec_name, "gnopernicus")) {
braille_active = gconf_client_get_bool (client,
GNOPERNICUS_BRAILLE_KEY,
NULL);
mag_active = gconf_client_get_bool (client,
GNOPERNICUS_MAGNIFIER_KEY,
NULL);
speech_active = gconf_client_get_bool (client,
GNOPERNICUS_SPEECH_KEY,
NULL);
startup_state->enabled.screenreader = (braille_active || speech_active);
startup_state->enabled.magnifier = mag_active;
}
else if (exec_name && !strcmp(exec_name, "gok")) {
startup_state->enabled.osk = TRUE;
}
g_free (exec_name);
}
g_slist_free (at_list);
g_object_unref (client);
at_startup_state_recent.flags = startup_state->flags;
prog = g_find_program_in_path ("gok");
if (prog != NULL) {
startup_state->enabled.osk_installed = TRUE;
g_free (prog);
} else {
startup_state->enabled.osk_installed = FALSE;
}
prog = g_find_program_in_path ("gnopernicus");
if (prog != NULL) {
startup_state->enabled.magnifier_installed = TRUE;
startup_state->enabled.screenreader_installed = TRUE;
g_free (prog);
} else {
startup_state->enabled.magnifier_installed = FALSE;
startup_state->enabled.screenreader_installed = FALSE;
}
}
void
at_startup_state_update (AtStartupState *startup_state)
{
GError *error = NULL;
GConfClient *client = gconf_client_get_default ();
GSList *at_list = at_startup_get_list (client);
if (startup_state->enabled.screenreader != at_startup_state_recent.enabled.screenreader) {
gconf_client_set_bool (client, GNOPERNICUS_SPEECH_KEY,
startup_state->enabled.screenreader, NULL);
gconf_client_set_bool (client, GNOPERNICUS_BRAILLE_KEY,
startup_state->enabled.screenreader, NULL);
}
if (startup_state->enabled.magnifier != at_startup_state_recent.enabled.magnifier) {
gconf_client_set_bool (client, GNOPERNICUS_MAGNIFIER_KEY,
startup_state->enabled.magnifier, NULL);
}
if (startup_state->enabled.screenreader || startup_state->enabled.magnifier) {
if (!(at_startup_state_recent.enabled.screenreader ||
at_startup_state_recent.enabled.magnifier))
/* new state includes SR or magnifier, initial one did not */
at_list = at_startup_list_add (at_list, "gnopernicus");
}
else {
if (at_startup_state_recent.enabled.screenreader ||
at_startup_state_recent.enabled.magnifier)
at_list = at_startup_list_remove (at_list, "gnopernicus");
}
if (startup_state->enabled.osk) {
if (!at_startup_state_recent.enabled.osk)
at_list = at_startup_list_add (at_list, "gok");
}
else {
if (at_startup_state_recent.enabled.osk)
at_list = at_startup_list_remove (at_list, "gok");
}
if (at_startup_state_recent.flags != startup_state->flags) {
at_startup_state_recent.flags = startup_state->flags;
gconf_client_set_list (client, AT_STARTUP_KEY, GCONF_VALUE_STRING, at_list, &error);
}
g_object_unref (client);
g_slist_free (at_list);
}

View File

@@ -1,18 +0,0 @@
#include <glib.h>
typedef union {
guint flags;
struct {
guint support:1;
guint osk:1;
guint magnifier:1;
guint screenreader:1;
guint osk_installed:1;
guint magnifier_installed:1;
guint screenreader_installed:1;
} enabled;
} AtStartupState;
void at_startup_state_init (AtStartupState *startup_state);
void at_startup_state_update (AtStartupState *startup_state);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,296 +0,0 @@
#include <config.h>
#include <gtk/gtk.h>
#include <gconf/gconf-client.h>
#include <glade/glade.h>
#include "capplet-util.h"
#include "gconf-property-editor.h"
#include "activate-settings-daemon.h"
#include "at-startup-session.h"
#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility"
#define ACCESSIBILITY_KEY_DIR "/desktop/gnome/interface"
#define AT_STARTUP_DIR "/desktop/gnome/accessibility/startup"
#define AT_STARTUP_KEY "/desktop/gnome/accessibility/startup/exec_ats"
#define SR_PREFS_DIR "/apps/gnopernicus/srcore"
static AtStartupState at_startup_state, at_startup_state_initial;
static void
init_startup_state (GladeXML *dialog)
{
GConfClient *client = gconf_client_get_default ();
at_startup_state.flags = (gconf_client_get_bool (client,
ACCESSIBILITY_KEY,
NULL)) ? 1 : 0;
at_startup_state_init (&at_startup_state);
at_startup_state_initial.flags = at_startup_state.flags;
g_object_unref (client);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_keyboard_toggle")),
at_startup_state.enabled.osk);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_screenreader_toggle")),
at_startup_state.enabled.screenreader);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_magnifier_toggle")),
at_startup_state.enabled.magnifier);
gtk_widget_set_sensitive (WID ("at_keyboard_toggle"),
at_startup_state.enabled.osk_installed);
gtk_widget_set_sensitive (WID ("at_screenreader_toggle"),
at_startup_state.enabled.screenreader_installed);
gtk_widget_set_sensitive (WID ("at_magnifier_toggle"),
at_startup_state.enabled.magnifier_installed);
if (at_startup_state.enabled.osk_installed &&
at_startup_state.enabled.screenreader_installed &&
at_startup_state.enabled.magnifier_installed) {
gtk_widget_hide (WID ("at_applications_warning_label"));
gtk_widget_hide (WID ("at_applications_hseparator"));
} else {
gchar *warning_label;
gtk_widget_show (WID ("at_applications_warning_label"));
gtk_widget_show (WID ("at_applications_hseparator"));
if (!at_startup_state.enabled.osk_installed &&
!(at_startup_state.enabled.screenreader_installed ||
at_startup_state.enabled.magnifier_installed)) {
warning_label = g_strdup_printf ("<i>%s</i>", _("No Assistive Technology is available on your system. The 'gok' package must be installed in order to get on-screen keyboard support, and the 'gnopernicus' package must be installed for screenreading and magnifying capabilities."));
} else if (!at_startup_state.enabled.osk_installed) {
warning_label = g_strdup_printf ("<i>%s</i>", _("Not all available assistive technologies are installed on your system. The 'gok' package must be installed in order to get on-screen keyboard support."));
} else {
warning_label = g_strdup_printf ("<i>%s</i>", _("Not all available assistive technologies are installed on your system. The 'gnopernicus' package must be installed for screenreading and magnifying capabilities."));
}
gtk_label_set_markup (GTK_LABEL (WID ("at_applications_warning_label")), warning_label);
g_free (warning_label);
}
}
static GladeXML *
create_dialog (void)
{
GladeXML *dialog;
dialog = glade_xml_new (GLADEDIR "/at-enable-dialog.glade", "at_properties_dialog", NULL);
gtk_image_set_from_stock (GTK_IMAGE (WID ("at_close_and_logout_image")),
GTK_STOCK_QUIT, GTK_ICON_SIZE_BUTTON);
gtk_image_set_from_file (GTK_IMAGE (WID ("at_enable_image")),
PIXMAPDIR "/at-support.png");
gtk_image_set_from_file (GTK_IMAGE (WID ("at_applications_image")),
PIXMAPDIR "/at-startup.png");
return dialog;
}
static void
cb_dialog_response (GtkDialog *dialog, gint response_id)
{
GnomeClient *client;
if (response_id == GTK_RESPONSE_HELP)
capplet_help (GTK_WINDOW (dialog),
"user-guide.xml",
"goscustaccess-11");
else if (response_id == GTK_RESPONSE_CLOSE || response_id == GTK_RESPONSE_DELETE_EVENT)
gtk_main_quit ();
else {
g_message ("CLOSE AND LOGOUT!");
if (!(client = gnome_master_client ())) {
gtk_main_quit ();
}
gnome_client_request_save (client, GNOME_SAVE_GLOBAL, TRUE,
GNOME_INTERACT_ANY, FALSE, TRUE);
}
}
static void
close_logout_update (GladeXML *dialog)
{
GConfClient *client = gconf_client_get_default ();
gboolean has_changed =
(at_startup_state.flags != at_startup_state_initial.flags) &&
gconf_client_get_bool (client, ACCESSIBILITY_KEY, NULL);
gtk_widget_set_sensitive (WID ("at_close_logout_button"), has_changed);
g_object_unref (client);
}
static void
at_startup_toggled (GtkToggleButton *toggle_button,
GladeXML *dialog)
{
if (toggle_button == GTK_TOGGLE_BUTTON (WID ("at_keyboard_toggle"))) {
at_startup_state.enabled.osk = gtk_toggle_button_get_active (toggle_button);
}
else if (toggle_button == GTK_TOGGLE_BUTTON (WID ("at_magnifier_toggle"))) {
at_startup_state.enabled.magnifier = gtk_toggle_button_get_active (toggle_button);
}
else if (toggle_button == GTK_TOGGLE_BUTTON (WID ("at_screenreader_toggle"))) {
at_startup_state.enabled.screenreader = gtk_toggle_button_get_active (toggle_button);
}
at_startup_state_update (&at_startup_state);
close_logout_update (dialog);
}
static void
at_enable_toggled (GtkToggleButton *toggle_button,
GladeXML *dialog)
{
GConfClient *client = gconf_client_get_default ();
gboolean is_enabled = gtk_toggle_button_get_active (toggle_button);
gconf_client_set_bool (client, ACCESSIBILITY_KEY,
is_enabled,
NULL);
at_startup_state.enabled.support = is_enabled;
g_object_unref (client);
}
static void
at_startup_update_ui (GConfClient *client,
GladeXML *dialog)
{
at_startup_state_init (&at_startup_state);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_keyboard_toggle")),
at_startup_state.enabled.osk);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_screenreader_toggle")),
at_startup_state.enabled.screenreader);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_magnifier_toggle")),
at_startup_state.enabled.magnifier);
}
static void
at_enable_update (GConfClient *client,
GladeXML *dialog)
{
gboolean is_enabled = gconf_client_get_bool (client, ACCESSIBILITY_KEY, NULL);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_enable_toggle")),
is_enabled);
gtk_widget_set_sensitive (WID ("at_applications_frame"), is_enabled);
}
static void
at_startup_changed (GConfClient *client,
guint cnxn_id,
GConfEntry *entry,
gpointer user_data)
{
at_startup_state_init (&at_startup_state);
at_startup_update_ui (client, user_data);
close_logout_update (user_data);
}
static void
at_enable_changed (GConfClient *client,
guint cnxn_id,
GConfEntry *entry,
gpointer user_data)
{
at_enable_update (client, user_data);
close_logout_update (user_data);
}
static void
setup_dialog (GladeXML *dialog)
{
GConfClient *client;
GtkWidget *widget;
GObject *peditor;
client = gconf_client_get_default ();
gconf_client_add_dir (client, ACCESSIBILITY_KEY_DIR,
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
widget = WID ("at_enable_toggle");
g_signal_connect (widget, "toggled",
G_CALLBACK (at_enable_toggled),
dialog);
peditor = gconf_peditor_new_boolean (NULL, ACCESSIBILITY_KEY,
widget,
NULL);
at_enable_update (client, dialog);
gconf_client_notify_add (client, ACCESSIBILITY_KEY_DIR,
at_enable_changed,
dialog, NULL, NULL);
gconf_client_add_dir (client, AT_STARTUP_DIR,
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
gconf_client_add_dir (client, SR_PREFS_DIR,
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
gconf_client_notify_add (client, AT_STARTUP_DIR,
at_startup_changed,
dialog, NULL, NULL);
gconf_client_notify_add (client, SR_PREFS_DIR,
at_startup_changed,
dialog, NULL, NULL);
widget = WID ("at_keyboard_toggle");
g_signal_connect (widget, "toggled",
G_CALLBACK (at_startup_toggled),
dialog);
widget = WID ("at_magnifier_toggle");
g_signal_connect (widget, "toggled",
G_CALLBACK (at_startup_toggled),
dialog);
widget = WID ("at_screenreader_toggle");
g_signal_connect (widget, "toggled",
G_CALLBACK (at_startup_toggled),
dialog);
widget = WID ("at_properties_dialog");
capplet_set_icon (widget, "gnome-settings-accessibility-technologies");
g_signal_connect (G_OBJECT (widget),
"response",
G_CALLBACK (cb_dialog_response), NULL);
gtk_widget_show (widget);
g_object_unref (client);
}
int
main (int argc, char *argv[])
{
GladeXML *dialog;
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
gnome_program_init ("gnome-at-properties", VERSION,
LIBGNOMEUI_MODULE, argc, argv,
GNOME_PARAM_APP_DATADIR, GNOMECC_DATA_DIR,
NULL);
activate_settings_daemon ();
dialog = create_dialog ();
init_startup_state (dialog);
setup_dialog (dialog);
gtk_main ();
return 0;
}

View File

@@ -1,12 +0,0 @@
Makefile
Makefile.in
.deps
.libs
*.o
*.lo
*.la
*.gladep
*.glade.bak
gnome-accessibility-keyboard-properties
accessibility-keyboard.desktop
accessibility-keyboard.desktop.in

View File

@@ -1,388 +0,0 @@
2005-01-05 Sebastien Bacher <seb128@debian.org>
* gnome-accessibility-keyboard-properties.glade: fixed a typo in the
label-for for the "pixels/second" label (Part of #162368).
2004-11-09 Mark McLoughlin <mark@skynet.ie>
* Makefile.am: install .desktop file in $(datadir)/applications.
* accessibility-keyboard.desktop.in: add OnlyShowIn=GNOME;
2004-10-14 Jody Goldberg <jody@gnome.org>
* Release 2.8.1
2004-08-20 Frederic Crozat <fcrozat@mandrakesoft.com>
* gnome-accessibility-keyboard-properties.c: (main):
Use themed icon for window hint.
2004-07-06 Padraig O'Briain <padraig.obriain@sun.com>
* gnome-accessibility-keyboard-properties.glade: Add label-for/
labelled-by relations. Fixes bug #144174.
2004-04-15 Jody Goldberg <jody@gnome.org>
* Release 2.6.1
2004-04-01 Jody Goldberg <jody@gnome.org>
* Release 2.6.0.3
2004-03-30 Jody Goldberg <jody@gnome.org>
* Release 2.6.0.1
2004-03-23 Jody Goldberg <jody@gnome.org>
* Release 2.6.0
2004-03-11 Jody Goldberg <jody@gnome.org>
* Release 2.5.4
2004-02-16 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c (cb_load_CDE_file) : Add a kludge to set
the vertical size based on the monitor size until the filesel can do
a better job of doing it itself.
2003-12-07 Jan Arne Petersen <jpetersen@uni-bonn.de>
* accessibility-keyboard.c: (load_CDE_file),
(fchooser_handle_response), (cb_load_CDE_file): replace
GtkFileSelection with GtkFileChooser.
2004-02-13 Jody Goldberg <jody@gnome.org>
* Release 2.5.3
2004-02-12 Mark McLoughlin <mark@skynet.ie>
* gnome-accessibility-keyboard-properties.c: (dialog_response): Update
help link to point to user-guide.xml
2004-01-14 Jody Goldberg <jody@gnome.org>
* Release 2.5.2
2003-12-30 Jody Goldberg <jody@gnome.org>
* Release 2.5.1.1
2003-12-30 Jody Goldberg <jody@gnome.org>
* Release 2.5.1
2003-11-18 Padraig O'Briain <padraig.obriain@sun.com>
* gnome-accessibility-keyboard-properties.glade: Add atk relations.
Fixes bug #126718
2003-11-03 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=120842
* gnome-accessibility-keyboard-properties.c : older xservers require
X11/Xlib.h too, its not sun specific.
2003-10-28 Jody Goldberg <jody@gnome.org>
* Release 2.5.0
2003-10-28 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=120842
* gnome-accessibility-keyboard-properties.glade : Remove bone headed
spitting of checkbox and label.
* accessibility-keyboard.c (setup_toggles) : It was probably done so
that the headers could be made bold.
Mon Aug 11 11:55:49 2003 Jonathan Blandford <jrb@redhat.com>
* gnome-accessibility-keyboard-properties.glade: Patch from Elijah
Newren <newren@math.utah.edu> to bring the possible repeat range
in sync with the keyboard capplet.
2003-08-01 Dennis Cranston <dennis_cranston at yahoo com>
* gnome-accessibility-keyboard-properties.glade: Patch to add
two more pixels of spacing between action area and vbox of
preferences dialog.
2003-07-24 Pasupathi Duraisamy <pasupathi.duraisamy@wipro.com>
* gnome-accessibility-keyboard-properties.glade:
Allow only numeric values in spinbutton.
Fixes bugzilla bug# 118175
2003-07-17 Dennis Cranston <dennis_cranston at yahoo com>
* gnome-accessibility-keyboard-properties.glade,
accessibility-keyboard.c: HIG fixes for ui-review bug
report #98915.
2003-07-16 Dennis Cranston <dennis_cranston at yahoo com>
* gnome-accessibility-keyboard-properties.glade: Adjust widget
padding to make dialog a little more HIG compliant.
2003-07-07 Jody Goldberg <jody@gnome.org>
* Release 2.3.4
2003-06-24 Jody Goldberg <jody@gnome.org>
* Release 2.3.3
2003-05-07 Jody Goldberg <jody@gnome.org>
* Release 2.3.1
2003-05-05 Kjartan Maraas <kmaraas@gnome.org>
* gnome-accessibility-keyboard-properties.c: Merge fix
for bug #110266.
2003-04-30 Alex Duggan <aldug@astrolinux.com>
* gnome-accessibility-keyboard-properties.c: use appropriate
window border icon.
2003-04-30 Kjartan Maraas <kmaraas@gnome.org>
* gnome-accessibility-keyboard-properties.c: Fix build
on Solaris. Fixes bug #106196.
2003-02-21 Calum Benson <calum.benson@sun.com>
* gnome-accessibility-keyboard-properties.glade:
HIG-ified frames and labels.
Tue Feb 4 17:09:18 2003 Jonathan Blandford <jrb@redhat.com>
* Release 2.2.0.1
Tue Jan 21 01:15:14 2003 Jonathan Blandford <jrb@gnome.org>
* Release 2.2.0
Thu Jan 16 02:41:09 2003 Jonathan Blandford <jrb@gnome.org>
* Release 2.1.7
2003-01-10 Jody Goldberg <jody@gnome.org>
* Release 2.1.6
2003-01-08 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=96483
* accessibility-keyboard.c : sigh. The defaults apparently need to be
0 too.
2003-01-08 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=96484
* accessibility-keyboard.c : make 0 min for slow and bounce
2003-01-07 Abel Cheung <maddog@linux.org.hk>
* gnome-accessibility-keyboard-properties.c (xkb_enabled): Fix typo
in error msg dialog.
2002-12-18 Jody Goldberg <jody@gnome.org>
* Release 2.1.5
2002-11-23 Jody Goldberg <jody@gnome.org>
* Release 2.1.3
2002-11-13 Pasupathi Duraisamy <pasupathi.duraisamy@wipro.com>
* accessibility-keyboard.c : Tweaked the incremental values
of spin button to 10. Fixes #95511
2002-11-02 Jody Goldberg <jody@gnome.org>
* Release 2.1.2
2002-11-02 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c : Merge in Calum's new layout
* gnome-accessibility-keyboard-properties.glade : ditto.
2002-10-21 Jody Goldberg <jody@gnome.org>
* Release 2.1.1
2002-10-11 Balamurali Viswanathan <balamurali.viswanathan@wipro.com>
* gnome-accessibility-keyboard-properties.c (xkb_enabled): Dismiss
the XKB extensions warning dialog. Fixes #95069
2002-10-01 Jody Goldberg <jody@gnome.org>
* Release 2.1.0.1
2002-09-26 Jody Goldberg <jody@gnome.org>
* gnome-accessibility-keyboard-properties.glade : add ellipsis for CDE
import and Repeat key buttons.
2002-09-25 Jody Goldberg <jody@gnome.org>
* gnome-accessibility-keyboard-properties.glade : remove spaces before
colons and fix the title.
2002-09-24 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c (load_CDE_file) : blah the
XrmGetFileDatabase is implementation specific in its handling of
invalid files. Add a hack that if the imported file did not contain
any resources it was invalid.
* gnome-accessibility-keyboard-properties.glade : add mnemonic_widget
for mousekeys_init_delay_title. Remove the atkrelations for things
with mnemonic_widget.
2002-09-11 Jody Goldberg <jody@gnome.org>
* gnome-accessibility-keyboard-properties.glade : Fix conflicting
accelerators.
* accessibility-keyboard.c (setup_dialog) : connect the simple items
before the master.
(cb_master_enable_toggle) : desensitize the subfeature content if the
master switch is disabled.
2002-09-09 Jody Goldberg <jody@gnome.org>
* gnome-accessibility-keyboard-properties.c (main) : add a warning if
xkb is not available.
2002-09-09 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c : on 2nd thought lets disable the 'beep on
feature change' if the master switch is off.
http://bugzilla.gnome.org/show_bug.cgi?id=92488
* gnome-accessibility-keyboard-properties.glade : tweak accelerators
2002-09-09 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=90936
* gnome-accessibility-keyboard-properties.glade : Add mnemonic_widget
assignments and fix a typo.
2002-08-28 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=91854
* accessibility-keyboard.c : the max slow key delay is 500ms.
We clamp that in the settings daemon. Fix the ui to reflect that.
2002-08-21 Jody Goldberg <jody@gnome.org>
* Release 2.1.0
2002-08-19 Ross Burton <ross@burtonini.com>
* accessibility-keyboard.desktop.in: Fix the desktop file so that
it validates.
2002-08-05 Jody Goldberg <jody@gnome.org>
* gnome-accessibility-keyboard-properties.glade : Restore the master
toggle.
* accessibility-keyboard.c (setup_dialog) : support the master toggle.
(cb_master_enable_toggle) : new.
2002-08-01 jacob berkman <jacob@ximian.com>
* accessibility-keyboard.c (setup_accessX_dialog): fix widget name
for the keyboard capplet button
* gnome-accessibility-keyboard-properties.c (dialog_response):
don't quit when the import accessx button is clicked (#89358)
2002-06-21 Satyajit Kanungo <satyajit.kanungo@wipro.com>
* gnome-accessibility-keyboard-properties.c :
Changed the help link to point to the correct document (#85895)
2002-06-10 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c : tweak the layout as requested and adjust
the max slowkey delay to 500 to avoid losing the keyboard due to some
sort of an X problem.
2002-06-17 Jody Goldberg <jody@gnome.org>
* Release 2.0.0
Sun May 26 11:44:41 2002 Jonathan Blandford <jrb@gnome.org>
* gnome-accessibility-keyboard-properties.c (main): use APPID
instead of argv[0]
2002-05-08 Jody Goldberg <jody@gnome.org>
* gnome-accessibility-keyboard-properties.c (dialog_response) : fix
path to help.
2002-04-24 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c : adjust the defaults.
2002-04-18 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c (setup_accessX_dialog) : Use 'clicked'
rather than 'activated' for the file sel.
2002-04-10 Jody Goldberg <jody@gnome.org>
* gnome-accessibility-keyboard-properties.glade2 (</) : slim down the
tooltips.
Wed Apr 10 18:02:29 2002 Jonathan Blandford <jrb@gnome.org>
* accessibility-keyboard.desktop.in (Exec): s/gnome2/gnome
2002-03-30 Jody Goldberg <jody@gnome.org>
* gnome-accessibility-keyboard-properties.glade2 : rename Sample -> Text
because that makes more sense.
http://bugzilla.gnome.org/show_bug.cgi?id=76315
* accessibility-keyboard.desktop.in : rename from AccessX -> Keyboard
2002-03-29 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c (setup_dialog) : spelling error.
(CONFIG_ROOT) : fix spelling error in the schema.
2002-03-29 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c : tweak the mouse key slider ranges
max_speed : 100 pixels every 10 msec is plenty fast Limit things to
1..100 default 10 step 5
accel_time : 10..5000 default 300 step 100
init_delay : 10..5000 default 300 step 100
2002-03-28 jacob berkman <jacob@ximian.com>
* accessibility-keyboard.c: on solaris Xresource.h sez /* You must
include <X11/Xlib.h> before including this file */
2002-03-25 Jody Goldberg <jody@gnome.org>
* accessibility-keyboard.c (setup_accessX_dialog) : Only load the
necessary toplevel widget in the non-dialog case.
(setup_dialog) : pass as_dialog to the sub-init routines.
(setup_images) : only load widgets appropriate for the current state.
(setup_ranges) : ditto, and be more vocal about invalid glade.
(setup_simple_toggles) : ditto.
(setup_toggles) : ditto.

View File

@@ -1,36 +0,0 @@
noinst_LIBRARIES = libaccessibility-keyboard.a
libaccessibility_keyboard_a_SOURCES = \
accessibility-keyboard.c \
accessibility-keyboard.h
# in case we need to forward port the sun accessX extension
# AccessXcomm.c
bin_PROGRAMS = gnome-accessibility-keyboard-properties
gnome_accessibility_keyboard_properties_SOURCES = gnome-accessibility-keyboard-properties.c
gnome_accessibility_keyboard_properties_LDADD = \
libaccessibility-keyboard.a $(GNOMECC_CAPPLETS_LIBS)
@INTLTOOL_DESKTOP_RULE@
pixmapdir = $(GNOMECC_PIXMAPS_DIR)
pixmap_DATA = \
accessibility-keyboard-togglekey.png \
accessibility-keyboard-mousekey.png \
accessibility-keyboard-slowkey.png \
accessibility-keyboard-stickykey.png \
accessibility-keyboard-bouncekey.png
Gladedir = $(GNOMECC_GLADE_DIR)
Glade_DATA = gnome-accessibility-keyboard-properties.glade
desktopdir = $(datadir)/applications
Desktop_in_files = accessibility-keyboard.desktop.in
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
INCLUDES = $(GNOMECC_CAPPLETS_CFLAGS)
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES) $(Desktop_in_files) $(desktop_DATA)
EXTRA_DIST = $(Glade_DATA) $(pixmap_DATA)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,477 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* accessibility-keyboard.c
* Copyright (C) 2002 Ximian, Inc.
*
* Written by: Jody Goldberg <jody@gnome.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, 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include <gconf/gconf-client.h>
#include <glade/glade.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <math.h>
#include "capplet-util.h"
#include "capplet-stock-icons.h"
#include "gconf-property-editor.h"
#include "activate-settings-daemon.h"
#define CONFIG_ROOT "/desktop/gnome/accessibility/keyboard"
static struct {
char const * const checkbox;
char const * const image;
char const * const image_file;
char const * const gconf_key;
char const * const content [3];
gboolean always_enabled;
} const features [] = {
{ "repeatkeys_enable", "repeatkeys_image", KEYBOARD_REPEAT,
"/desktop/gnome/peripherals/keyboard/repeat",
{ "repeatkeys_table", NULL, NULL }, TRUE },
{ "bouncekeys_enable", "bouncekeys_image", ACCESSX_KEYBOARD_BOUNCE,
CONFIG_ROOT "/bouncekeys_enable",
{ "bouncekey_table", NULL, NULL }, FALSE },
{ "slowkeys_enable", "slowkeys_image", ACCESSX_KEYBOARD_SLOW,
CONFIG_ROOT "/slowkeys_enable",
{ "slowkeys_table", NULL, NULL }, FALSE },
{ "mousekeys_enable", "mousekeys_image", ACCESSX_KEYBOARD_MOUSE,
CONFIG_ROOT "/mousekeys_enable",
{ "mousekeys_table", NULL, NULL }, FALSE },
{ "stickykeys_enable", "stickykeys_image", ACCESSX_KEYBOARD_STICK,
CONFIG_ROOT "/stickykeys_enable",
{ "stickeykeys_table", NULL, NULL }, FALSE },
{ "togglekeys_enable", "togglekeys_image", ACCESSX_KEYBOARD_TOGGLE,
CONFIG_ROOT "/togglekeys_enable",
{ NULL, NULL, NULL }, FALSE },
{ "timeout_enable", NULL, NULL,
CONFIG_ROOT "/timeout_enable",
{ "timeout_slide", "timeout_spin", "timeout_label" }, FALSE },
{ "feature_state_change_beep", NULL, NULL,
CONFIG_ROOT "/feature_state_change_beep",
{ NULL, NULL, NULL }, FALSE }
};
static struct {
char const * const slide;
char const * const spin;
int default_val;
int min_val;
int max_val;
int step_size;
char const * const gconf_key;
} const ranges [] = {
{ "repeatkeys_delay_slide", "repeatkeys_delay_spin", 500, 100, 1500, 10,
"/desktop/gnome/peripherals/keyboard/delay" },
{ "repeatkeys_rate_slide", "repeatkeys_rate_spin", 90, 10, 110, 10,
"/desktop/gnome/peripherals/keyboard/rate" },
{ "bouncekeys_delay_slide", "bouncekeys_delay_spin", 0, 0, 900, 10,
CONFIG_ROOT "/bouncekeys_delay" },
{ "slowkeys_delay_slide", "slowkeys_delay_spin", 0, 0, 500, 10,
CONFIG_ROOT "/slowkeys_delay" },
/* WARNING anything larger than approx 512 seems to loose all keyboard input */
{ "mousekeys_max_speed_slide", "mousekeys_max_speed_spin", 300, 10, 500, 10,
CONFIG_ROOT "/mousekeys_max_speed" },
{ "mousekeys_accel_time_slide", "mousekeys_accel_time_spin", 300, 10, 3000, 10,
CONFIG_ROOT "/mousekeys_accel_time" },
{ "mousekeys_init_delay_slide", "mousekeys_init_delay_spin", 300, 10, 5000, 10,
CONFIG_ROOT "/mousekeys_init_delay" },
{ "timeout_slide", "timeout_spin", 200, 10, 500, 10,
CONFIG_ROOT "/timeout" },
};
static void
set_sensitive (GladeXML *dialog, char const *name, gboolean state)
{
if (name != NULL)
gtk_widget_set_sensitive (WID (name), state);
}
/**
* cb_feature_toggled :
*
* NOTE : for this to work the toggle MUST be initialized to active in the
* glade file. That way if the gconf setting is FALSE the toggle will fire.
*/
static void
cb_feature_toggled (GtkToggleButton *btn, gpointer feature_index)
{
gboolean const state =
(GTK_WIDGET_STATE (btn) != GTK_STATE_INSENSITIVE) &&
gtk_toggle_button_get_active (btn);
GladeXML *dialog = g_object_get_data (G_OBJECT (btn), "dialog");
int feature, i;
g_return_if_fail (dialog != NULL);
feature = GPOINTER_TO_INT (feature_index);
if (features [feature].image != NULL)
set_sensitive (dialog, features [feature].image, state);
for (i = G_N_ELEMENTS (features [feature].content) ; i-- > 0 ; )
set_sensitive (dialog, features [feature].content [i], state);
}
static void
setup_toggles (GladeXML *dialog, GConfChangeSet *changeset)
{
GObject *peditor;
GtkWidget *checkbox;
GtkWidget *checkbox_label;
int i = G_N_ELEMENTS (features);
while (i-- > 0) {
checkbox = WID (features [i].checkbox);
g_return_if_fail (checkbox != NULL);
/* you can't do this from glade */
checkbox_label = gtk_bin_get_child (GTK_BIN (checkbox));
g_object_set (G_OBJECT (checkbox_label), "use_markup", TRUE, NULL);
g_object_set_data (G_OBJECT (checkbox), "dialog", dialog);
g_signal_connect (G_OBJECT (checkbox),
"toggled",
G_CALLBACK (cb_feature_toggled), GINT_TO_POINTER (i));
peditor = gconf_peditor_new_boolean (changeset,
(gchar *)features [i].gconf_key, checkbox, NULL);
}
}
static void
setup_simple_toggles (GladeXML *dialog, GConfChangeSet *changeset)
{
static struct {
char const *gconf_key;
char const *checkbox;
} const simple_toggles [] = {
{ CONFIG_ROOT "/bouncekeys_beep_reject", "bouncekeys_beep_reject" },
{ CONFIG_ROOT "/slowkeys_beep_press", "slowkeys_beep_press" },
{ CONFIG_ROOT "/slowkeys_beep_accept", "slowkeys_beep_accept" },
{ CONFIG_ROOT "/slowkeys_beep_reject", "slowkeys_beep_reject" },
{ CONFIG_ROOT "/stickykeys_two_key_off", "stickykeys_two_key_off" },
{ CONFIG_ROOT "/stickykeys_modifier_beep", "stickykeys_modifier_beep" },
};
int i = G_N_ELEMENTS (simple_toggles);
while (i-- > 0) {
GtkWidget *w = WID (simple_toggles [i].checkbox);
g_return_if_fail (w != NULL);
gconf_peditor_new_boolean (changeset,
(gchar *) simple_toggles [i].gconf_key,
w, NULL);
}
}
static void
setup_ranges (GladeXML *dialog, GConfChangeSet *changeset)
{
GObject *peditor;
GtkWidget *slide, *spin;
GtkAdjustment *adjustment;
int i = G_N_ELEMENTS (ranges);
while (i-- > 0) {
slide = WID (ranges [i].slide);
spin = WID (ranges [i].spin);
g_return_if_fail (slide != NULL);
g_return_if_fail (spin != NULL);
adjustment = gtk_range_get_adjustment (GTK_RANGE (slide));
g_return_if_fail (adjustment != NULL);
adjustment->value = ranges [i].default_val;
adjustment->lower = ranges [i].min_val;
adjustment->upper = ranges [i].max_val + ranges [i].step_size;
adjustment->step_increment = ranges [i].step_size;
adjustment->page_increment = ranges [i].step_size;
adjustment->page_size = ranges [i].step_size;
gtk_adjustment_changed (adjustment);
gtk_spin_button_configure (GTK_SPIN_BUTTON (spin), adjustment,
ranges [i].step_size, 0);
peditor = gconf_peditor_new_numeric_range (changeset,
(gchar *)ranges [i].gconf_key, slide,
NULL);
}
}
static void
setup_images (GladeXML *dialog)
{
int i = G_N_ELEMENTS (features);
while (i-- > 0)
if (features [i].image != NULL)
gtk_image_set_from_stock (GTK_IMAGE (WID (features [i].image)),
features [i].image_file,
keyboard_capplet_icon_get_size ());
}
static void
cb_launch_mouse_capplet (GtkButton *button, GtkWidget *dialog)
{
GError *err = NULL;
if (!g_spawn_command_line_async ("gnome-mouse-properties", &err))
capplet_error_dialog (GTK_WINDOW (gtk_widget_get_toplevel (dialog)),
_("There was an error launching the mouse preferences dialog: %s"),
err);
}
static void
cb_master_enable_toggle (GtkToggleButton *btn, GladeXML *dialog)
{
int i = G_N_ELEMENTS (features);
gboolean flag = gtk_toggle_button_get_active (btn);
GtkWidget *w;
while (i-- > 0) {
if (!features [i].always_enabled) {
w = WID (features [i].checkbox);
gtk_widget_set_sensitive (w, flag);
cb_feature_toggled (GTK_TOGGLE_BUTTON (w), GINT_TO_POINTER (i));
}
}
}
static void
setup_dialog (GladeXML *dialog, GConfChangeSet *changeset)
{
GtkWidget *master_enable = WID ("master_enable");
capplet_init_stock_icons ();
setup_images (dialog);
setup_ranges (dialog, changeset);
setup_toggles (dialog, changeset);
setup_simple_toggles (dialog, changeset);
g_signal_connect (master_enable,
"toggled",
G_CALLBACK (cb_master_enable_toggle), dialog);
gconf_peditor_new_boolean (changeset,
CONFIG_ROOT "/enable",
GTK_WIDGET (master_enable), NULL);
}
/*******************************************************************************/
static gboolean
xrm_get_bool (GConfClient *client, XrmDatabase *db, char const *gconf_key,
char const *res_str, char const *class_str)
{
XrmValue resourceValue;
char *res;
if (!XrmGetResource (*db, res_str, class_str, &res, &resourceValue))
return FALSE;
gconf_client_set_bool (client, gconf_key,
!g_ascii_strcasecmp (resourceValue.addr, "True"), NULL);
return TRUE;
}
static gboolean
xrm_get_int (GConfClient *client, XrmDatabase *db, char const *gconf_key,
char const *res_str, char const *class_str, float scale)
{
XrmValue resourceValue;
char *res;
int value, log_scale;
char resource [256];
snprintf (resource, sizeof (resource), "%s.value", res_str);
if (!XrmGetResource (*db, resource, class_str, &res, &resourceValue))
return FALSE;
value = atoi (resourceValue.addr);
snprintf (resource, sizeof (resource), "%s.decimalPoints", res_str);
if (!XrmGetResource (*db, resource, class_str, &res, &resourceValue))
return FALSE;
log_scale = atoi (resourceValue.addr);
while (log_scale-- > 0)
scale /= 10.;
gconf_client_set_int (client, gconf_key, value, NULL);
return TRUE;
}
/* This loads the current users XKB settings from their file */
static gboolean
load_CDE_file (GtkFileChooser *fchooser)
{
char *file = gtk_file_chooser_get_filename (fchooser);
GConfClient *client;
XrmDatabase db;
gboolean found = FALSE;
if (!(db = XrmGetFileDatabase (file))) {
GtkWidget *warn = gtk_message_dialog_new (
gtk_window_get_transient_for (GTK_WINDOW (fchooser)),
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
_("Unable to import AccessX settings from file '%s'"),
file);
g_signal_connect (warn,
"response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (warn);
g_free (file);
return FALSE;
}
client = gconf_client_get_default ();
gconf_client_set_bool (client, CONFIG_ROOT "/enable", TRUE, NULL);
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/feature_state_change_beep",
"*SoundOnOffToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/timeout_enable",
"*TimeOutToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/stickykeys_enable",
"*StickyKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/mousekeys_enable",
"*MouseKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/togglekeys_enable",
"*ToggleKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/slowkeys_enable",
"*SlowKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/bouncekeys_enable",
"*BounceKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/stickykeys_modifier_beep",
"*StickyModSoundToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/stickykeys_two_key_off",
"*StickyTwoKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/slowkeys_beep_press",
"*SlowKeysOnPressToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/slowkeys_beep_accept",
"*SlowKeysOnAcceptToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
found |= xrm_get_int (client, &db, CONFIG_ROOT "/timeout",
"*TimeOutScale", "AccessX*XmScale", 60);
found |= xrm_get_int (client, &db, CONFIG_ROOT "/mousekeys_max_speed",
"*MouseMaxSpeedScale", "AccessX*XmScale", 1);
found |= xrm_get_int (client, &db, CONFIG_ROOT "/mousekeys_accel_time",
"*MouseAccelScale", "AccessX*XmScale", 1);
found |= xrm_get_int (client, &db, CONFIG_ROOT "/mousekeys_init_delay",
"*MouseDelayScale", "AccessX*XmScale", 1);
found |= xrm_get_int (client, &db, CONFIG_ROOT "/slowkeys_delay",
"*KRGSlowKeysDelayScale", "AccessX*XmScale", 1000);
found |= xrm_get_int (client, &db, CONFIG_ROOT "/bouncekeys_delay",
"*KRGDebounceScale", "AccessX*XmScale", 1000);
/* Set the master enable flag last */
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/enable",
"*EnableAccessXToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
g_object_unref (client);
if (!found) {
/* it would be nice to have a better message bu that would
* break string freeze
*/
GtkWidget *warn = gtk_message_dialog_new (
gtk_window_get_transient_for (GTK_WINDOW (fchooser)),
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
_("Unable to import AccessX settings from file '%s'"),
file);
g_signal_connect (warn,
"response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (warn);
g_free (file);
return FALSE;
}
g_free(file);
return TRUE;
}
static void
fchooser_handle_response (GtkFileChooser *fchooser, gint response, gpointer data)
{
char *file_name;
if (response == GTK_RESPONSE_OK) {
file_name = gtk_file_chooser_get_filename (fchooser);
/* Change into directory if that's what user selected */
if (g_file_test (file_name, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (fchooser, file_name);
else if (load_CDE_file (fchooser))
gtk_widget_destroy (GTK_WIDGET (fchooser));
g_free (file_name);
} else {
gtk_widget_destroy (GTK_WIDGET (fchooser));
}
}
static void
cb_load_CDE_file (GtkButton *button, GtkWidget *dialog)
{
GtkFileChooser *fchooser = GTK_FILE_CHOOSER (
gtk_file_chooser_dialog_new (_("Import Feature Settings File"),
GTK_WINDOW (gtk_widget_get_toplevel (dialog)),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
_("_Import"), GTK_RESPONSE_OK,
NULL));
gtk_window_set_position (GTK_WINDOW (fchooser), GTK_WIN_POS_MOUSE);
gtk_window_set_modal (GTK_WINDOW (fchooser), TRUE);
g_signal_connect (G_OBJECT (fchooser),
"response",
G_CALLBACK (fchooser_handle_response), NULL);
gtk_widget_show (GTK_WIDGET (fchooser));
}
/*******************************************************************************/
GtkWidget *
setup_accessX_dialog (GConfChangeSet *changeset)
{
GConfClient *client;
char const *toplevel_name = "accessX_dialog";
GladeXML *dialog = glade_xml_new (GNOMECC_DATA_DIR
"/interfaces/gnome-accessibility-keyboard-properties.glade",
toplevel_name, NULL);
GtkWidget *toplevel = WID (toplevel_name);
client = gconf_client_get_default ();
gconf_client_add_dir (client, CONFIG_ROOT, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
g_object_unref (client);
setup_dialog (dialog, changeset);
g_signal_connect (G_OBJECT (WID ("load_CDE_file")),
"clicked",
G_CALLBACK (cb_load_CDE_file), toplevel);
g_signal_connect (G_OBJECT (WID ("launch_mouse_capplet")),
"clicked",
G_CALLBACK (cb_launch_mouse_capplet), toplevel);
return toplevel;
}

View File

@@ -1,15 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
_Name=Keyboard
_Comment=Set your keyboard accessibility preferences
Exec=gnome-accessibility-keyboard-properties
Icon=gnome-settings-accessibility-keyboard
Terminal=false
Type=Application
StartupNotify=true
Categories=GNOME;Application;Settings;Accessibility;
OnlyShowIn=GNOME;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=control-center
X-GNOME-Bugzilla-Component=Keyboard Accessibility
X-GNOME-Bugzilla-Version=@VERSION@

View File

@@ -1,32 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* accessibility-keyboard.c
* Copyright (C) 2002 Ximian, Inc.
*
* Written by: Jody Goldberg <jody@gnome.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, 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 GNOME_ACCESSIBILITY_KEYBOARD_H
#define GNOME_ACCESSIBILITY_KEYBOARD_H
#include <gconf/gconf-changeset.h>
#include <gtk/gtkwidget.h>
GtkWidget *setup_accessX_dialog (GConfChangeSet *changeset);
#endif /* GNOME_ACCESSIBILITY_KEYBOARD_H */

View File

@@ -1,116 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* gnome-accessibility-keyboard-properties.c
* Copyright (C) 2002 Ximian, Inc.
*
* Written by: Jody Goldberg <jody@gnome.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, 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include <gconf/gconf-client.h>
#include <capplet-util.h>
#include <activate-settings-daemon.h>
#include "accessibility-keyboard.h"
#ifdef HAVE_X11_EXTENSIONS_XKB_H
# include <X11/X.h>
# include <X11/Xlib.h>
# include <X11/XKBlib.h>
# include <X11/extensions/XKBstr.h>
# include <gdk/gdk.h>
# include <gdk/gdkx.h>
static void
xkb_enabled (void)
{
gboolean have_xkb = FALSE;
int opcode, errorBase, major, minor, xkbEventBase;
gdk_error_trap_push ();
have_xkb = XkbQueryExtension (GDK_DISPLAY (),
&opcode, &xkbEventBase, &errorBase, &major, &minor)
&& XkbUseExtension (GDK_DISPLAY (), &major, &minor);
XSync (GDK_DISPLAY (), FALSE);
gdk_error_trap_pop ();
if (!have_xkb) {
GtkWidget *warn = gtk_message_dialog_new (NULL, 0,
GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
_("This system does not seem to have the XKB extension. The keyboard accessibility features will not operate without it."));
gtk_dialog_run (GTK_DIALOG (warn));
gtk_widget_destroy (warn);
}
}
#endif
static void
dialog_response (GtkWidget *widget,
gint response_id,
GConfChangeSet *changeset)
{
switch (response_id) {
case GTK_RESPONSE_HELP:
capplet_help (GTK_WINDOW (widget),
"user-guide.xml",
"goscustaccess-6");
break;
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_CLOSE:
gtk_main_quit ();
break;
default:
/* Import CDE AccessX File */
break;
}
}
int
main (int argc, char **argv)
{
GtkWidget *dialog;
GConfChangeSet *changeset;
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
gnome_program_init ("gnome-accessibility-keyboard-properties", VERSION,
LIBGNOMEUI_MODULE, argc, argv,
GNOME_PARAM_APP_DATADIR, GNOMECC_DATA_DIR,
NULL);
activate_settings_daemon ();
#ifdef HAVE_X11_EXTENSIONS_XKB_H
xkb_enabled ();
#endif
changeset = NULL;
dialog = setup_accessX_dialog (changeset);
g_signal_connect (G_OBJECT (dialog),
"response",
G_CALLBACK (dialog_response), changeset);
capplet_set_icon (dialog, "gnome-settings-accessibility-keyboard");
gtk_widget_show_all (dialog);
gtk_main ();
return 0;
}

View File

@@ -1,14 +0,0 @@
Makefile
Makefile.in
.deps
.libs
*.o
*.lo
*.la
background.desktop
background.desktop.in
gnome-background-properties
gnome-wallpaper-properties
*.oaf
*.server

File diff suppressed because it is too large Load Diff

View File

@@ -1,48 +0,0 @@
WALLPAPER_DATADIR = $(datadir)/gnome-background-properties
INCLUDES = \
$(GNOMECC_CAPPLETS_CFLAGS) \
-DWALLPAPER_DATADIR=\""$(WALLPAPER_DATADIR)"\"
bin_PROGRAMS = gnome-background-properties
noinst_LTLIBRARIES = libgnomewp.la
gnome_background_properties_LDADD = \
$(GNOMECC_CAPPLETS_LIBS) \
libgnomewp.la
gnome_background_properties_SOURCES = \
gnome-wp-capplet.c gnome-wp-capplet.h \
gnome-wp-info.c gnome-wp-info.h
libgnomewp_la_SOURCES = \
gnome-wp-item.c gnome-wp-item.h \
gnome-wp-utils.c gnome-wp-utils.h \
gnome-wp-xml.c gnome-wp-xml.h
libgnomewp_la_LIBADD = \
$(GNOMECC_CAPPLETS_LIBS)
desktopdir = $(datadir)/applications
desktop_in_files = background.desktop.in
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
@INTLTOOL_DESKTOP_RULE@
gladedir = $(GNOMECC_GLADE_DIR)
glade_DATA = gnome-background-properties.glade
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(WALLPAPER_DATADIR)
EXTRA_DIST = \
background.desktop.in.in \
$(glade_DATA)
CLEANFILES = \
$(desktop_in_files) $(desktop_DATA)
MAINTAINERCLEANFILES = \
Makefile.in

View File

@@ -1,15 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
_Name=Desktop Background
_Comment=Change your Desktop Background settings
Exec=gnome-background-properties %F
Icon=gnome-settings-background
Terminal=false
Type=Application
StartupNotify=true
Categories=GNOME;Settings;Appearance;
OnlyShowIn=GNOME;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=control-center
X-GNOME-Bugzilla-Component=background
X-GNOME-Bugzilla-Version=@VERSION@

View File

@@ -1,483 +0,0 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<requires lib="gnome"/>
<widget class="GtkDialog" id="gnome_wp_properties">
<property name="visible">True</property>
<property name="title" translatable="yes">Desktop Background Preferences</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
<property name="modal">False</property>
<property name="default_width">360</property>
<property name="default_height">418</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="helpbutton1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-help</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-11</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="closebutton1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-7</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Desktop _Wallpaper&lt;/b&gt;</property>
<property name="use_underline">True</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">wp_tree</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox3">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkHBox" id="wp_hbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="wp_tree">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox4">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="label" translatable="yes">_Style:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">style_menu</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkOptionMenu" id="style_menu">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="history">-1</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="rem_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-remove</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="add_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-add</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">_Add Wallpaper</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;_Desktop Colors&lt;/b&gt;</property>
<property name="use_underline">True</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">color_menu</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox5">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkOptionMenu" id="color_menu">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="history">-1</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GnomeColorPicker" id="pcpicker">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="dither">True</property>
<property name="use_alpha">False</property>
<property name="title" translatable="yes">Pick a color</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GnomeColorPicker" id="scpicker">
<property name="can_focus">True</property>
<property name="dither">True</property>
<property name="use_alpha">False</property>
<property name="title" translatable="yes">Pick a color</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

File diff suppressed because it is too large Load Diff

View File

@@ -1,109 +0,0 @@
/*
* Authors: Rodney Dawes <dobey@ximian.com>
*
* Copyright 2003-2005 Novell, Inc. (www.novell.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation
*
* 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 Street #330, Boston, MA 02111-1307, USA.
*
*/
#ifndef _GNOME_WP_CAPPLET_H_
#define _GNOME_WP_CAPPLET_H_
#include <config.h>
#include <gnome.h>
#include <glib.h>
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
#include <libgnomevfs/gnome-vfs-mime-utils.h>
#include <libgnomeui/gnome-thumbnail.h>
#include <gconf/gconf-client.h>
#include <libxml/parser.h>
#include <glade/glade.h>
typedef struct _GnomeWPCapplet GnomeWPCapplet;
#include "gnome-wp-info.h"
#include "gnome-wp-item.h"
#include "gnome-wp-utils.h"
#include "gnome-wp-xml.h"
struct _GnomeWPCapplet {
GtkWidget * window;
/* List of files passed to command line */
GSList * uri_list;
/* The Tree View */
GtkWidget * treeview;
GtkTreeModel * model;
/* Option Menu for Scaling Options */
GtkWidget * wp_opts;
GtkWidget * rm_button;
/* Menu Items for Fill/Scale/Center/Tile Options */
GtkWidget * fitem;
GtkWidget * sitem;
GtkWidget * citem;
GtkWidget * witem;
/* Widgets for Color Options */
GtkWidget * color_opt;
GtkWidget * pc_picker;
GtkWidget * sc_picker;
/* Menu Items for Color Style Options */
GtkWidget * smenuitem;
GtkWidget * hmenuitem;
GtkWidget * vmenuitem;
/* GConf Client */
GConfClient * client;
/* Thumbnailing and Icon Theme stuff */
GnomeThumbnailFactory * thumbs;
GnomeIconTheme * theme;
/* Hash Table of Wallpapers */
GHashTable * wphash;
/* Keyboard Delay */
gint delay;
/* The Timeout ID for Setting the Wallpaper */
gint idleid;
/* File Chooser Dialog */
GtkWidget * filesel;
GtkWidget * image;
};
typedef enum {
GNOME_WP_SHADE_TYPE_SOLID,
GNOME_WP_SHADE_TYPE_HORIZ,
GNOME_WP_SHADE_TYPE_VERT
} GnomeWPShadeType;
typedef enum {
GNOME_WP_SCALE_TYPE_CENTERED,
GNOME_WP_SCALE_TYPE_STRETCHED,
GNOME_WP_SCALE_TYPE_SCALED,
GNOME_WP_SCALE_TYPE_TILED
} GnomeWPScaleType;
void gnome_wp_main_quit (GnomeWPCapplet * capplet);
#endif

View File

@@ -1,114 +0,0 @@
/*
* Authors: Rodney Dawes <dobey@ximian.com>
*
* Copyright 2003-2005 Novell, Inc. (www.novell.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation
*
* 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 Street #330, Boston, MA 02111-1307, USA.
*
*/
#include <config.h>
#include <gnome.h>
#include "gnome-wp-info.h"
GnomeWPInfo * gnome_wp_info_new (const gchar * uri,
GnomeThumbnailFactory * thumbs) {
GnomeWPInfo * new;
GnomeVFSFileInfo * info;
GnomeVFSResult result;
gchar *escaped_uri = gnome_vfs_escape_path_string (uri);
info = gnome_vfs_file_info_new ();
result = gnome_vfs_get_file_info (escaped_uri, info,
GNOME_VFS_FILE_INFO_DEFAULT |
GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
g_free (escaped_uri);
if (info == NULL || info->mime_type == NULL || result != GNOME_VFS_OK) {
if (!strcmp (uri, "(none)")) {
new = g_new0 (GnomeWPInfo, 1);
new->mime_type = g_strdup ("image/x-no-data");
new->uri = g_strdup (uri);
new->thumburi = g_strconcat (g_get_home_dir (),
"/.thumbnails/normal/",
gnome_thumbnail_md5 (gnome_vfs_escape_path_string (uri)),
".png",
NULL);
new->name = g_strdup (_("No Wallpaper"));
new->size = 0;
} else {
new = NULL;
}
} else {
new = g_new0 (GnomeWPInfo, 1);
new->uri = g_strdup (uri);
new->thumburi = gnome_thumbnail_factory_lookup (thumbs,
gnome_vfs_escape_path_string (new->uri),
info->mtime);
if (new->thumburi == NULL) {
new->thumburi = g_strconcat (g_get_home_dir (),
"/.thumbnails/normal/",
gnome_thumbnail_md5 (gnome_vfs_escape_path_string (uri)),
".png",
NULL);
}
new->name = g_strdup (info->name);
new->mime_type = g_strdup (info->mime_type);
new->size = info->size;
new->mtime = info->mtime;
}
gnome_vfs_file_info_unref (info);
return new;
}
GnomeWPInfo * gnome_wp_info_dup (const GnomeWPInfo * info) {
GnomeWPInfo * new;
new = g_new0 (GnomeWPInfo, 1);
new->uri = g_strdup (info->uri);
new->thumburi = g_strdup (info->uri);
new->name = g_strdup (info->name);
new->mime_type = g_strdup (info->mime_type);
new->size = info->size;
new->mtime = info->mtime;
return new;
}
void gnome_wp_info_free (GnomeWPInfo * info) {
if (info == NULL) {
return;
}
g_free (info->uri);
g_free (info->thumburi);
g_free (info->name);
g_free (info->mime_type);
info = NULL;
}

View File

@@ -1,47 +0,0 @@
/*
* Authors: Rodney Dawes <dobey@ximian.com>
*
* Copyright 2003-2005 Novell, Inc. (www.novell.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation
*
* 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 Street #330, Boston, MA 02111-1307, USA.
*
*/
#ifndef _GNOME_WP_INFO_H_
#define _GNOME_WP_INFO_H_
#include <glib.h>
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomeui/gnome-thumbnail.h>
typedef struct _GnomeWPInfo GnomeWPInfo;
struct _GnomeWPInfo {
gchar * uri;
gchar * thumburi;
gchar * name;
gchar * mime_type;
GnomeVFSFileSize size;
time_t mtime;
};
GnomeWPInfo * gnome_wp_info_new (const gchar * uri,
GnomeThumbnailFactory * thumbs);
GnomeWPInfo * gnome_wp_info_dup (const GnomeWPInfo * info);
void gnome_wp_info_free (GnomeWPInfo * info);
#endif

Some files were not shown because too many files have changed in this diff Show More