Compare commits

...

3 Commits

496 changed files with 189 additions and 193855 deletions

View File

@@ -1,33 +0,0 @@
ABOUT-NLS
.new.ltmain.sh
Makefile
Makefile.in
aclocal.m4
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

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.

3094
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
Email: hovinen@ximian.com
Email: jacob@ximian.com

View File

@@ -1,27 +0,0 @@
SUBDIRS = po libsounds libbackground libwindow-settings gnome-settings-daemon capplets control-center idl schemas
#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
pixmapdir = $(datadir)/pixmaps
pixmap_DATA = control-center2.png
dist-hook: control-center.spec
cp control-center.spec $(distdir)
#MAINTAINERCLEANFILES = \
# intltool-extract \
# intltool-merge \
# intltool-update
EXTRA_DIST = \
control-center.spec.in \
intltool-extract.in \
intltool-merge.in \
intltool-update.in \
control-center2.png

11
NEWS
View File

@@ -1,11 +0,0 @@
gnome-control-center 2.0.1
Jody:
* Clean up the handling of custom applications in mime type capplet.
* Supply some decent defaults for new mime types.
* Implement Background capplet UI reccommendations.
* Reorganize the AccessX UI.
* Fix cmd line args for file-type capplet.
------------------------------------------------------------------------------
First split version of this package

9
README
View File

@@ -1,9 +0,0 @@
We have just begun the GNOME 2 port of the control center on the HEAD
branch of CVS. At this point, it is not guaranteed to compile or
run. If you wish to have a working control center, use the branch
gnome-1-4-branch by issuing the following command:
cvs -z3 up -r gnome-1-4-branch
Please do not file bug reports pertaining to the current state of the
HEAD branch.

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,28 +0,0 @@
#undef ENABLE_NLS
#undef HAVE_CATGETS
#undef HAVE_DEVGTK
#undef HAVE_GETTEXT
#undef HAVE_LC_MESSAGES
#undef HAVE_STPCPY
#undef HAVE_LIBSM
#undef HAVE_PROGRAM_INVOCATION_SHORT_NAME
#undef HAVE_PROGRAM_INVOCATION_NAME
#undef GNOMECC_DATA_DIR
#undef GETTEXT_PACKAGE
#undef VERSION
#undef HAVE_ESD
#undef HAVE_LIBESD
/* Define if there is no `u_int64_t' and `int64_t'. */
#undef u_int64_t
#undef int64_t
#undef HAVE_DEVGTK
#undef WITH_SYMBOL_UNDERSCORE
#undef HAVE_PUTENV
#undef HAVE_SETENV

View File

@@ -1,164 +0,0 @@
# Configure paths for ESD
# Manish Singh 98-9-30
# stolen back from Frank Belew
# stolen from Manish Singh
# Shamelessly stolen from Owen Taylor
dnl AM_PATH_ESD([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for ESD, and define ESD_CFLAGS and ESD_LIBS
dnl
AC_DEFUN(AM_PATH_ESD,
[dnl
dnl Get the cflags and libraries from the esd-config script
dnl
AC_ARG_WITH(esd-prefix,[ --with-esd-prefix=PFX Prefix where ESD is installed (optional)],
esd_prefix="$withval", esd_prefix="")
AC_ARG_WITH(esd-exec-prefix,[ --with-esd-exec-prefix=PFX Exec prefix where ESD is installed (optional)],
esd_exec_prefix="$withval", esd_exec_prefix="")
AC_ARG_ENABLE(esdtest, [ --disable-esdtest Do not try to compile and run a test ESD program],
, enable_esdtest=yes)
if test x$esd_exec_prefix != x ; then
esd_args="$esd_args --exec-prefix=$esd_exec_prefix"
if test x${ESD_CONFIG+set} != xset ; then
ESD_CONFIG=$esd_exec_prefix/bin/esd-config
fi
fi
if test x$esd_prefix != x ; then
esd_args="$esd_args --prefix=$esd_prefix"
if test x${ESD_CONFIG+set} != xset ; then
ESD_CONFIG=$esd_prefix/bin/esd-config
fi
fi
AC_PATH_PROG(ESD_CONFIG, esd-config, no)
min_esd_version=ifelse([$1], ,0.2.5,$1)
AC_MSG_CHECKING(for ESD - version >= $min_esd_version)
no_esd=""
if test "$ESD_CONFIG" = "no" ; then
no_esd=yes
else
ESD_CFLAGS=`$ESD_CONFIG $esdconf_args --cflags`
ESD_LIBS=`$ESD_CONFIG $esdconf_args --libs`
esd_major_version=`$ESD_CONFIG $esd_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
esd_minor_version=`$ESD_CONFIG $esd_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
esd_micro_version=`$ESD_CONFIG $esd_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
if test "x$enable_esdtest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $ESD_CFLAGS"
LIBS="$LIBS $ESD_LIBS"
dnl
dnl Now check if the installed ESD is sufficiently new. (Also sanity
dnl checks the results of esd-config to some extent
dnl
rm -f conf.esdtest
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <esd.h>
char*
my_strdup (char *str)
{
char *new_str;
if (str)
{
new_str = malloc ((strlen (str) + 1) * sizeof(char));
strcpy (new_str, str);
}
else
new_str = NULL;
return new_str;
}
int main ()
{
int major, minor, micro;
char *tmp_version;
system ("touch conf.esdtest");
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = my_strdup("$min_esd_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_esd_version");
exit(1);
}
if (($esd_major_version > major) ||
(($esd_major_version == major) && ($esd_minor_version > minor)) ||
(($esd_major_version == major) && ($esd_minor_version == minor) && ($esd_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** 'esd-config --version' returned %d.%d.%d, but the minimum version\n", $esd_major_version, $esd_minor_version, $esd_micro_version);
printf("*** of ESD required is %d.%d.%d. If esd-config is correct, then it is\n", major, minor, micro);
printf("*** best to upgrade to the required version.\n");
printf("*** If esd-config was wrong, set the environment variable ESD_CONFIG\n");
printf("*** to point to the correct copy of esd-config, and remove the file\n");
printf("*** config.cache before re-running configure\n");
return 1;
}
}
],, no_esd=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_esd" = x ; then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
if test "$ESD_CONFIG" = "no" ; then
echo "*** The esd-config script installed by ESD could not be found"
echo "*** If ESD was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the ESD_CONFIG environment variable to the"
echo "*** full path to esd-config."
else
if test -f conf.esdtest ; then
:
else
echo "*** Could not run ESD test program, checking why..."
CFLAGS="$CFLAGS $ESD_CFLAGS"
LIBS="$LIBS $ESD_LIBS"
AC_TRY_LINK([
#include <stdio.h>
#include <esd.h>
], [ return 0; ],
[ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding ESD or finding the wrong"
echo "*** version of ESD. If it is not finding ESD, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means ESD was incorrectly installed"
echo "*** or that you have moved ESD since it was installed. In the latter case, you"
echo "*** may want to edit the esd-config script: $ESD_CONFIG" ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
ESD_CFLAGS=""
ESD_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(ESD_CFLAGS)
AC_SUBST(ESD_LIBS)
rm -f conf.esdtest
])

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>

View File

@@ -1,988 +0,0 @@
2002-06-17 Jody Goldberg <jody@gnome.org>
* Release 2.0.0
2002-02-27 Kjartan Maraas <kmaraas@gnome.org>
* config-archiver.c: s/PACKAGE/GETTEXT_PACKAGE/g
* config-manager.c: Same here.
2001-10-18 Bradford Hovinen <hovinen@ximian.com>
* bonobo-config-archiver.c (get_listener_oafiid): Update listener name
2001-10-13 Bradford Hovinen <hovinen@ximian.com>
* bonobo-config-archiver.c (real_sync): Try to resolve a listener
to make sure that something is listening when we issue the sync
event (disabled for now)
(get_listener_oafiid): Implement (disabled for now)
2001-10-05 Shaun Merrigan <shaun.merrigan@sun.com>
* archiver-client.c (location_client_load_rollback_data):
Only use tm_gmtoffm if __USE_BSD is defined.
2001-09-28 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (parse_line): Only set tm_gmtoff and tm_zone fields
if __USE_BSD is defined
* util.c (parse_date): Ditto
* bonobo-config-archiver.c (bonobo_config_archiver_new): Store the
listener id in the archiver_db structure
(bonobo_config_archiver_destroy): Remove the event source
listener; destroy the XML cache
(new_rollback_cb): Don't reload everything if we initiated the
sync ourselves
(real_sync): Mark that we are currently up to date
2001-09-22 Bradford Hovinen <hovinen@ximian.com>
* bonobo-config-archiver.c (notify_listeners): Abort if the object
is already destroyed
2001-09-07 Bradford Hovinen <hovinen@ximian.com>
* archiver-client.c (location_client_store_xml): Make backend_id
const
* util.c (parse_date): Set the time zone
(parse_date): Initialize tm_isdst
* archiver-client.c (location_client_store_xml): Call
ConfigArchiver_Location_storageComplete when done
(location_client_store_xml): Don't try to save the XML file if
there was an error getting the storage filename
* location.c (location_storage_complete): Implement
(impl_ConfigArchiver_Location_storageComplete): Implement
* config-log.c (config_log_get_backend_id_for_id): Make return
value const
2001-09-04 Bradford Hovinen <hovinen@ximian.com>
* location.c (location_get_storage_filename): Notify listeners
that new rollback data is available
* bonobo-config-archiver.c (new_rollback_cb): Implement
(bonobo_config_archiver_new): Connect above to event source
* location.c (location_store):
(location_init): Construct an event source and add its interface
* Makefile.am (INCLUDES): Remove -DDEFAULTS_DIR
2001-09-03 Bradford Hovinen <hovinen@ximian.com>
* bonobo-config-archiver.c (bonobo_config_archiver_new): Accept
complete moniker as an argument; do the parsing here
* archiver-client.c (location_client_load_rollback_data): Adjust
time from mktime according to time zone information
* bonobo-moniker-archiver.c (is_leap_year):
(mod_date_by_str): Implement
(parse_name): Use correct math for computing offsets
* bonobo-config-archiver.c (bonobo_config_archiver_new): Don't
print an error message if the parent moniker is bad
(bonobo_config_archiver_new): Remove debugging messages
* archiver-client.c (location_client_load_rollback_data): Make
date and backend_id const
* bonobo-moniker-archiver.c (archiverdb_resolve): Determine date
from moniker and pass to bonobo_config_archiver_new
* bonobo-config-archiver.c (bonobo_config_archiver_new): Accept
date structure as argument
2001-08-29 Bradford Hovinen <hovinen@ximian.com>
* archive.c (foreach_build_list_cb): Don't unref the location if
it is deleted
(load_all_locations): Check if the location is marked deleted and
throw it away if so
* location.c (location_new): Don't unref parent location
2001-08-28 Bradford Hovinen <hovinen@ximian.com>
* archive.c (foreach_build_list_cb): Unref the location given if
we are not going to use it
2001-08-27 Bradford Hovinen <hovinen@ximian.com>
* archive.c (foreach_build_list_cb): Don't add the location to the
list if it is marked deleted
(impl_ConfigArchiver_Archive_createLocation): Do
CORBA_Object_duplicate rather than bonobo_object_dup_ref
* location.c (location_is_deleted): Implement
2001-08-23 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (do_unload): Make sure we don't try to do this if
we are marked deleted
(config_log_delete): Call do_unload to eliminate memory leaks
* location.c (location_delete): Set the deleted flag
* config-log.c (dump_log): Don't try to dump the log if we are
deleted
* location.c (save_metadata): Don't try to save metadata if we are
deleted
2001-08-22 Hans Petter Jansson <hpj@ximian.com>
* archiver-client.h: Fixed include path, libxml -> gnome-xml. It's
consistent with the includes in archiver-client.c, and it stops
the build breaking here.
2001-08-21 Bradford Hovinen <hovinen@ximian.com>
* archive.c (archive_get_current_location_id): Use
archive_create_location rather than location_new
(archive_get_current_location_id): Unref the location once we have
created it
* archiver-client.c (location_client_load_rollback_data): Don't
try to parse the XML file if there was an exception
* bonobo-config-archiver.c (bonobo_config_archiver_new): Make sure
to release_unref location and archive if aborting
(bonobo_config_archiver_new): Reinitialize exception structure
after we have succeeded
* location.c (location_get_rollback_filename): Recurse on parent
location if parent_chain is set to TRUE
* archive.c (impl_ConfigArchiver_Archive_getLocation): Set the
LocationNotFound exception if the location returned was NULL
* location.c (impl_ConfigArchiver_Location_getRollbackFilename): Don't try
* archive.c (impl_ConfigArchiver_Archive_getLocation): Don't try
to CORBA_Object_duplicate the result if it is NULL
(archive_get_location): Don't try to cast the result of
location_open before we know whether it is non-NULL
(impl_ConfigArchiver_Archive_createLocation): Call
bonobo_object_from_servant on parent_ref->servant
* location.c (location_destroy): Remove debugging message; make
remaining debugging message more enlightening
* archive.c (archive_get_child_locations): Rename from
archive_foreach_child_location; rewrite to return a GList of child
locations
(impl_ConfigArchiver_Archive_getChildLocations): Use
archive_get_child_locations
(archive_destroy): Remove debugging message
* bonobo-moniker-archiver.c (archive_resolve): Remove debugging
messages
* archive.c (archive_get_location): Remove debugging messages
* config-log.c (dump_log): Remove debugging messages
* archive.c (archive_foreach_child_location): Build a list first
and then traverse it to avoid screwing up the tree traversal
2001-08-20 Richard Hestilow <hestilow@ximian.com>
* Makefile.am: Add dependency on CORBA_SOURCE to archiver-client.c.
(clean-local): Add CORBA_SOURCE to files to be removed.
2001-08-17 Bradford Hovinen <hovinen@ximian.com>
* all: Added CORBA interface for the archiver
* config-archiver.c: Ported to new CORBA interface
2001-08-20 Bradford Hovinen <hovinen@ximian.com>
* location.c (load_metadata_file): Support placing the location's
label in the metadata file
2001-08-03 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (load_log_entry): Return NULL if fgets returns NULL
(dump_log): If both first_old and log_data are NULL, go ahead and
dump the file, since nothing has been loaded yet
(config_log_garbage_collect): Don't bother dumping the log file or
reloading
(load_log_entry): Return NULL if file_stream is NULL
2001-08-02 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (config_log_garbage_collect): Implement
(dump_log): Don't dump the old file if first_old is NULL
* main.c (main): Support --garbage_collect
* location.c (location_garbage_collect):
(garbage_collect_cb): Implement
2001-07-31 Bradford Hovinen <hovinen@ximian.com>
* config-log.c: Remove socket-based synchronization system
entirely. Switch to using standard FILE streams for interfacing
with the configuration log
* archive.c (archive_get_current_location_id): Re-enable caching
mechanism
* bonobo-config-archiver.c (pb_get_fn): Use
location_get_config_log rather than config_log_open; don't destroy
the log
(bonobo_config_archiver_new): Eliminate unref mechanism; it is not
needed
2001-07-30 Bradford Hovinen <hovinen@ximian.com>
* archive.c (archive_set_current_location_id): Use
capplet-archive/config/current/location for current location to
avoid conflicting with control-center
(archive_get_current_location_id): Always retrieve the location id
from gnome_config
* config-log.c (socket_data_cb): Close the socket if we couldn't
load the log entry
(config_log_destroy):
(config_log_open): Disable socket sync system
(config_log_write_entry): Make sure to write log when socket_owner
not set
* location.c (location_get_config_log): Implement
2001-07-27 Bradford Hovinen <hovinen@ximian.com>
* bonobo-config-archiver.c (bonobo_config_archiver_destroy): Don't
unref the event source or the property bag
* RELEASE : 1.5.2
2001-07-24 Richard Hestilow <hestilow@ximian.com>
* bonobo-config-archiver.c (pb_set_fn): Do sanity checking on
the rollback ID we get.
2001-07-24 Richard Hestilow <hestilow@ximian.com>
* config-log.c (parse_line): Ok, bad fix. Move that to the archiver.
* bonobo-config-archiver.c (pb_set_fn): Moved here.
(bonobo_config_archiver_new): Don't aggregate against an EventSource,
since the PropertyBag already has one and everything will get confused.
Just use the one the bag has.
(bonobo_config_archiver_destroy): Don't unref the event source, we
don't own it any more.
2001-07-24 Richard Hestilow <hestilow@ximian.com>
* config-log.c (parse_line): Fix date parsing to work with DST.
* bonobo-config-archiver.[ch]: Export a PropertyBag interface that
has the last_modified date as a read-only property.
2001-07-24 Bradford Hovinen <hovinen@ximian.com>
* bonobo-config-archiver.c (real_sync): Notify listeners with a sync event
(real_sync): Use correct pointer type when passing to notify_listeners
2001-07-20 Chema Celorio <chema@celorio.com>
* RELEASE : 1.5.0
2001-07-17 Bradford Hovinen <hovinen@ximian.com>
* bonobo-config-archiver.c (bonobo_config_archiver_new): Add
mechanism for quitting once the moniker is no longer in use
(bonobo_config_archiver_new): Make archive a static variable
(bonobo_config_archiver_new): Explicitly destroy archive when
program quits
(timeout_cb): Remove
* config-log.c (slave_apprise_data): Remove
* archive.c (archive_unregister_location):
(archive_get_location): strdup the string to remove compiler warnings
* location.c (location_store): Use return value
(location_store_full_snapshot): Use return value
2001-07-12 Bradford Hovinen <hovinen@ximian.com>
* archive.c (archive_destroy): Clear appropriate global archive pointer
(archive_get_current_location_id): Logic fix.
2001-07-12 Chema Celorio <chema@celorio.com>
* Makefile.am (INCLUDES): update to the new location for the xst backends
2001-07-12 Bradford Hovinen <hovinen@ximian.com>
* archive.c (archive_get_current_location_id): Only try to store a
full snapshot if we are in a global archive
* bonobo-config-archiver.c (bonobo_config_archiver_new): Store
real_name in archiver_db
(bonobo_config_archiver_destroy): Use archiver_db->real_name with
bonobo_url_register
2001-07-10 Bradford Hovinen <hovinen@ximian.com>
* default-user.xml: Add sound-properties
* bonobo-moniker-archiver.c (archiver_resolve): Don't accept
PropertyBag interface
2001-07-09 Bradford Hovinen <hovinen@ximian.com>
* bonobo-config-archiver.c (bonobo_config_archiver_new): Use
bonobo_object_unref rather than gtk_object_destroy
* bonobo-moniker-archiver.c (archiver_resolve): Allow PropertyBag
interface as well
(parse_name): Set *location to NULL when there is no location
* archive.c (archive_load): Use .gnome/capplet-archive rather than
.gnome/control-center
(archive_set_current_location): Removed unused variables
* bonobo-config-archiver.c (bonobo_config_archiver_new): Try to
load the defaults file if no rollback data can be found
2001-07-05 Bradford Hovinen <hovinen@ximian.com>
* bonobo-config-archiver.[ch]: Use bonobo-conf rather than
bonobo-config for include path
* bonobo-moniker-archiver.c (archiver_resolve): Update call to
Bonobo_ConfigDatabase_addDatabase
* bonobo-config-archiver.h: Fix include directories
* Makefile.am (INCLUDES): Update to use pkg-config standards; add
BONOBO_CFLAGS
Include configuration moniker-related material
(SUBDIRS): Remove
(bin_PROGRAMS): Added ximian-archiver
2001-07-02 Tambet Ingo <tambet@ximian.com>
* default-global.xml: Added display-conf backend.
2001-06-22 Bradford Hovinen <hovinen@ximian.com>
* archive.c (archive_get_current_location): Return NULL if the
location id is NULL
(archive_get_current_location_id): Return NULL if storing the
snapshot results in an error
* location.c (location_store): Add return values for error
conditions; remove g_warning's and g_critical's
(location_store_full_snapshot): Folded in store_snapshot_cb; don't
call location_foreach_backend
(location_store_full_snapshot): Return error condition; 0 on
success, -1 if any backend failed
2001-06-21 Bradford Hovinen <hovinen@ximian.com>
* location.c (location_do_rollback): Wait for child process to
terminate
(run_backend_proc): Take an extra argument -- where to store the
PID of the child process
* archive.c (archive_set_current_location): Use
location_get_changed_backends
* location.c (location_get_changed_backends):
(location_does_backend_change): Implement
(create_backends_list):
(merge_backend_lists): Moved from archive.c
* config-log.c (dump_log): Don't call close on fd
(dump_log): Use g_critical on error conditions rather than g_warning
2001-06-20 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (slave_data_cb): Dump the log after loading it from
the slave
(dump_log): Set first_old to the beginning of the list after the dump
(do_load): Don't call do_unload
(socket_data_cb): Check for hang up first
(do_load): Don't call reset_filenames
(slave_data_cb):
(config_log_write_entry): Call io_buffer_destroy
* archive.c, Makefile.am: Replace all instances of ximian-config
with ximian-setup-tools
* config-log.c (slave_new): Don't apprise slave of new data
(config_log_write_entry): Dump log after every write
2001-06-19 Bradford Hovinen <hovinen@ximian.com>
* archive.c (archive_set_current_location): Free the location path
as we walk down it.
(create_backends_list): Implement
(merge_backend_lists): Implement
(archive_set_current_location): Call above functions
(create_backends_list): Get rid of dummy first element
(archive_set_current_location): Don't use backends->next when
calling rollback_backends_to
* location.c (run_backend_proc): Remember to close the writing end
(location_store): Change g_error to g_critical
(run_backend_proc): Don't getenv PATH
(run_backend_proc): Make sure to close other end of pipe in child
process
2001-06-18 Bradford Hovinen <hovinen@ximian.com>
* location.c (location_store): Use GString API
* config-log.c (slave_data_cb): Don't use == to test IO conditions
2001-06-01 Bradford Hovinen <hovinen@ximian.com>
* location.c (run_backend_proc): Don't free path string after
setting the path
2001-05-26 Chema Celorio <chema@celorio.com>
* Makefile.am (ximian_archiverConf.sh): create x_aConf.sh from
the XIMIAN_ARCHIVER_FOO_CONF varialbes
2001-05-24 Arturo Espinosa Aldama <arturo@ximian.com>
* 0.5 RELEASE
2001-05-24 Chema Celorio <chema@celorio.com>
* Makefile.am (libximian_archiver_la_SOURCES): add config-
manger-dialog so that distcheck would pass
(SUBDIRS): add the . dir because the capplet depends on
the archiver and we need to build the archiver first
(libximian_archiver_la_SOURCES): add location-list &
create-location-dialog
(ximian_archiverConf.sh): change to XIMIAN_ARVHIER_FOO
2001-05-24 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am (SUBDIRS): Added location-manager-capplet
2001-05-22 JP Rosevear <jpr@ximian.com>
* config-log.c (bind_socket): use AF_UNIX for the family
* location.c (run_backend_proc): use putenv() rather than setenv()
for solaris
* config-log.c: define the SUN_LEN macro for those systems not
having it
(connect_socket): use the more portable domain type, PF_LOCAL
seems to map to PF_UNIX on linux anyhow
2001-05-12 Chema Celorio <chema@celorio.com>
* location.c (location_store_xml): add a carriage return after the
warning message
2001-05-09 Arturo Espinosa Aldama <arturo@ximian.com>
* 0.4 RELEASE
2001-05-05 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am (ximian_archiverConf.sh): Add sed expression to
replace @VERSION@
2001-05-04 Bradford Hovinen <hovinen@ximian.com>
* cluster-location.c (cluster_location_do_rollback): Implement
* location.c (location_do_rollback): Rename from do_rollback; make
into virtual method
(location_rollback_backend_to):
(location_rollback_backend_by):
(location_rollback_id): Update to call virtual method
* Makefile.am (libximian_archiver_la_SOURCES):
(include_HEADERS): Add cluster.[ch], cluster-location.[ch]
2001-05-03 Bradford Hovinen <hovinen@ximian.com>
* cluster.[ch]: New class
* cluster.c (cluster_new):
(cluster_load): Implement
* archive.c (archive_set_arg): Add argument ARG_IS_GLOBAL
(archive_class_init): Make ARG_PREFIX construct-only
(archive_construct): Implement
(do_load): Remove
(archive_load): Use archive_construct; pass is_global as an
argument to the object constructor
* location.c (location_store_xml): Support STORE_DEFAULT
(store_snapshot_cb): Use STORE_DEFAULT rather than STORE_MASK_PREVIOUS
* location.h (_StoreType): Add STORE_DEFAULT
* config-log.c (config_log_get_rollback_id_by_steps): Return the
current id if the node represents default data
* main.c (do_add_location): Cast correctly, fixing compiler
warning
* config-log.c (config_log_write_entry): Add parameter
is_default_data; call get_beginning_of_time rather than
get_current_date iff is_default_data is TRUE
(get_beginning_of_time): Implement
(has_nondefaults): Implement. Return TRUE iff the config log
contains regular (non-default) entries
2001-04-26 Arturo Espinosa <arturo@ximian.com>
* location.c: changed g_critical to g_error. If a newer
version of glib is to be required, change configure.in then.
* util.h: Set a flag to disable the DEBUG_MSG macro, which
messes with the frontend<->backend talking.
2001-04-24 Bradford Hovinen <hovinen@ximian.com>
* location.c (location_store): Use read rather than fread
(location_add_backend):
(location_remove_backend): Save metadata immediately
2001-04-23 Bradford Hovinen <hovinen@ximian.com>
* location.c (location_store): Block SIGPIPE
(location_store): Fix off-by-one bug
* archive.c (archive_get_current_location_id): Store a full
snapshot of the system after the default location is created
* location.c (run_backend_proc): Added parameter do_get to allow
control of whether pipe is opened to read or write
(store_snapshot_cb): Implement. Invokes the given backend with
--get and stores the XML data
(location_store_full_snapshot): Implement. Stores a complete
snapshot with all backend data
(subtract_xml_node): Assume all nodes are the same
(location_store): Add string termination character
(location_store): Only store data if any data were actually read
2001-04-22 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (config_log_iterate): Use the correct data pointer
to pass to the callback
* location.c (location_new): Save the metadata for the newly
created location right away
* util.h: Defined DEBUG_MSG macro for debugging messages
* archive.c (archive_unregister_location): Don't remove the
location from the tree if the object is marked destroyed
2001-04-21 Bradford Hovinen <hovinen@ximian.com>
* archive.c (archive_destroy): Return if the archive was already
destroyed
* location.c (location_delete): Unregister the location before
destroying it
* config-log.c (config_log_delete): Set deleted flag
(config_log_destroy): Only dump the log if the log is not marked
deleted
* location.c (location_delete): Check return value of rmdir
* config-log.c (io_buffer_destroy): Call g_io_channel_close to
close the GIOChannel
(disconnect_socket): Force the removal of the source id from the
main loop
(config_log_destroy): Disconnect the socket after unloading, not
before
* location.c (location_delete): Remember to have a NULL at the end
of arguments to g_strconcat ()
2001-04-20 Bradford Hovinen <hovinen@ximian.com>
* config-log.c: Added InputBuffer, removed get_line
(struct _Slave):
(struct _ConfigLogPrivate ): Replaced GIOChannel * and FILE * with
InputBuffer *'s
(input_buffer_new): Implement. Constructs a new input buffer
(input_buffer_destroy): Implement. Destroys an input buffer and
closes the file descriptor
(input_buffer_cycle): Implement (borrowed from GDict). Reads
additional data from the input file
(input_buffer_read_line): Implement (borrowed from GDict). Reads a
line from the input file and returns a pointer to it
(input_buffer_write): Implement. Write the indicated string out to
the channel
2001-04-15 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (config_log_set_arg): Create semaphore for
auto-reloading
(do_load): Removed locking code
(load_log_entry): Support prepending log entries to the beginning
of the log; free entry->date if parsing was unsuccessful
(config_log_reset_filenames): Unlink socket filename if not owner
(config_log_reset_filenames): Rebind socket when filename is reset
(connect_socket): Implement. Creates or connects to the socket
associated with the config log
(check_socket_filename): Implement. Checks to see if the filename
associated with the socket is in use.
(bind_socket): Implement. Binds the socket to the filename.
(socket_connect_cb): Implement. Callback issued when a master gets
a new connection.
(socket_data_cb): Implement. Callback issued when a slave gets
data from the master.
(slave_new): Implement. Creates a new slave structure
(slave_destroy): Implement. Destroys a slave structure
(slave_data_cb): Implement. Callback issued when data comes in
from a slave
(slave_broadcast_data): Implement. Broadcast the first log entry
to all the slaves except the given one
(disconnect_socket): Implement. Disconnects the socket
(config_log_open): Call connect_socket
(do_unload): Don't dump the log unless currently the socket owner
(config_log_write_entry): Broadcast data to slaves or write data
to socket, depending on whether currently the socket owner
2001-04-14 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (do_unload): Add a parameter write_log to tell
whether to write out the log when unloading
(config_log_finalize): Implement
* config-log.[ch]: Put all data fields in ConfigLogPrivate
structure
2001-04-11 Bradford Hovinen <hovinen@ximian.com>
* location.c (run_backend_proc): Make sure to search location of
XST backends
* Makefile.am (INCLUDES): Added XST_BACKEND_LOCATION
* archive.c (archive_set_current_location_id): Don't use different
prefixes for per-user and global locations; we are assuming here
that the only person using this globally will be root anyway
(archive_get_current_location_id): Ditto
* Makefile.am (INCLUDES): Replace obsolete hcm directory names
with ximian-config
2001-02-20 Bradford Hovinen <hovinen@ximian.com>
* location.c (compare_xml_nodes): Use attr->val rather than
attr->node
2001-02-19 Bradford Hovinen <hovinen@ximian.com>
* location.c (location_foreach_backend): Update to use BackendNote
(do_rollback): Don't do rollback if the doc is NULL
(location_store_xml): Return if this location does not contain the
backend specified
(location_store_xml): Use fprintf rather than g_warning
(subtract_xml_node):
(merge_xml_nodes): Update child node while iterating
* config-log.c (config_log_get_rollback_ids_for_date): Remove
* location.c (location_set_arg): ref inherited object
* main.c (main): Don't check if the location is default; don't
create default location if non-existant
(main): Signal error if the user is adding a location and did not
specify a name
(main): Use fprintf to signal the error that a location could not
be opened
(main): Signal error and exit when archive cannot be opened,
rather than using g_error
(do_add_location): Check for NULL location_id
(do_add_location): Create default location if it does not exist
and it is specified as the parent
* archive.c (archive_get_current_location_id): Create the default
location if it does not exist
* backend-list.c (backend_list_contains): Use strcmp and iterate
through the list
* location.c (location_contains): Read whether the backend is in
the master list if this location is toplevel
2001-02-18 Bradford Hovinen <hovinen@ximian.com>
* main.c (do_add_backend): Support ContainmentType specification
(do_store): Support StoreType specification
(struct store_options): Add set of options to support
compare_parent, mask_previous, options
(struct add_remove_backend_options): Add option for partial
containment when adding backend
* location.c (subtract_xml_node):
(merge_xml_nodes):
(compare_xml_nodes):
(merge_xml_docs):
(subtract_xml_doc): Implement. XML node compare/merging operations
(location_store): Rewrite to call location_store_xml
(location_store_xml): Include support for diffing with
configuration data from parent config
(location_dump_rollback_data): Rewrite to use
location_load_rollback_data
(dump_xml_data): Remove
(do_rollback): Rewrite to use xmlDocDump; pass xmlDocPtr rather
than id number
(location_rollback_id): Add node merging support
(location_rollback_backend_by):
(location_rollback_backend_to): Rewrite to use
location_load_rollback_data
(location_rollback_backends_to): Rewrite to iterate through
backend list and call location_rollback_backend_to for each
element
(location_rollback_all_to): Ditto
2001-02-14 Bradford Hovinen <hovinen@ximian.com>
* location.h (_ContainmentType): Introduce. Specifies the type of
containment (full, partial, none), of a backend in a location
* location.c: Added struct BackendNote; have backend list include
type of containment as well as backend id
(location_contains): Use find_note
(find_note): Implement. Finds a note for the given backend id in
the backend list
(backend_note_new):
(backend_note_destroy): Implement. Convenience functions for
creating and destroying backend notes
(load_metadata_file):
(write_metadata_file): Read/write type of backend containment
(full or partial)
(location_add_backend): Pass parameter telling whether containment
is partial
2001-01-25 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (get_current_date): Use local time rather than
Greenwich Mean Time
* location.c (location_store_xml): Implement; copy from
location_store
(location_store): Free filename after use
* archive.c (archive_load): Free prefix only if not global
* location.c (location_rollback_all_to): Increment array
* util.c (parse_date): Normalize values
2001-01-24 Bradford Hovinen <hovinen@ximian.com>
* config-log.c (do_load): Disabled locking for now
* archiver-spec: Added fine-grained location management description
2001-01-15 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am: Added rule for ximian_archiverConf.sh; add
installation target for Conf.sh
2001-01-13 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am: Replaced occurrences of helix with ximian
Removed references to ximian_config_manager
2000-12-22 Bradford Hovinen <hovinen@helixcode.com>
* archive.c (foreach_cb):
(archive_foreach_child_location): Use auxillary structure to pass
data to traversal callback
(archive_get_location):
(archive_register_location): strdup() location ids
(free_location_cb): free() key
2000-12-20 Bradford Hovinen <hovinen@helixcode.com>
* location.c (location_get_parent): Implement
* archive.c (load_all_locations): Implement
(foreach_cb):
(archive_foreach_child_location): Implement
2000-12-19 Bradford Hovinen <hovinen@helixcode.com>
* Makefile.am (bin_PROGRAMS): Changed name of archiver to
helix-archiver
(lib_LIBRARIES): Added libhelix_archiver.a
(helix_archiver_SOURCES): Moved archiver core to
libhelix_archiver_a_SOURCES
(helix_archiver_LDADD): Added libhelix_archiver.a
(INCLUDES): Changed XML_CFLAGS to GNOME_XML_CFLAGS
(include_HEADERS): Create and include headers for
libhelix_archiver.a
(includedir): Set includedire to include/helix-archiver
2000-12-18 Bradford Hovinen <hovinen@helixcode.com>
* main.c (do_rollback): Support rolling back by steps
* location.c (location_rollback_backend_by): Implement
(location_dump_rollback_data): Support passing steps as well as
date
* config-log.c (config_log_get_rollback_id_by_steps): Implement
* location.c (write_metadata_file): Don't support writing out the
master list any more
(save_metadata): Ditto
(load_metadata_file): Get backends list from BackendList object
(rather than finding it out oneself) if location is toplevel
(do_create): Ditto
(get_backends_cb): Implement
(location_add_backend): Add return values for error conditions
2000-10-15 Bradford Hovinen <hovinen@helixcode.com>
* location.c (location_rollback_backends_to): Free id_array when done
* config-log.c (config_log_reset_filenames): Implement
* archive.c (archive_set_current_location_id): Move gnome_config_
code from set_current_location
* location.c (location_set_id): Implement
* main.c (do_rename_location): Implement
* archive.c (free_location_cb): Don't free locid
(archive_get_location):
(archive_register_location): Don't strdup the location id
(archive_set_current_location_id): Implement
* main.c: Add options for renaming locations and specifying that
backends should be added to or removed from the master list
* location.c (run_backend_proc): Close all descriptors other than
0, 1, 2
(location_set_id): Implement
(location_set_arg): Free previous locid if exists
* archive.c (add_location_cb): Implement
(archive_set_current_location): Add location change algorithm
* location.c (location_find_path_from_common_parent): Implement
(location_foreach_backend): Implement
* archive.c (archive_set_current_location): Set
archive->current_location_id
* main.c (do_add_location): Check parent_str for NULL before
loading location
(do_change_location): Implement
(main): Support changing location
* archive.c (archive_register_location): Implement
* location.c (do_create):
(do_load): Use archive_get_prefix
(do_create): Load global location metadata if this location does
not inherit from anything
(location_get_id): Implement
* archive.c (archive_get_prefix): Implement
* location.c (location_get_path): Implement
(load_metadata_file): Use archive_is_global
(location_set_arg): Set label when setting locid
* location.[ch]: Make all data members private
* main.c (main): Get current location name properly, create
location iff location id is "default"; bail out with error otherwise
(do_remove_location):
(do_add_location): Implement
* config-log.c: Include ctype.h to fix implicit declarations
* location.c (location_rollback_backends_to): Property initialize i
(location_contains): Fix precondition checks
(do_create): Remove unused variables
* archive.c (archive_get_location): Make a copy of locid before
working with it
(do_load): Fix precondition checks
* location.c (location_open):
(location_new): Make locid const
* archive.c (archive_get_location): Make locid const
* location.c (data_delete_cb):
(location_delete): Implement
* config-log.c (config_log_iterate): Implement
(config_log_destroy): Make private, pass GtkObject
(config_log_delete): Implement
2000-10-14 Bradford Hovinen <hovinen@helixcode.com>
* location.c (location_close): Add precondition checks
* archive.c (archive_destroy): Make private; pass GtkObject
* location.c (location_add_backend):
(location_remove_backend): Add precondition checks
(location_destroy): Make private
(location_destroy): Pass GtkObject pointer rather than Location
pointer; this cleans up assignment in _class_init
* archive.c (archive_get_current_location_id): Implement
(archive_get_current_location): Implement
2000-09-03 Bradford Hovinen <hovinen@helixcode.com>
* location.c (location_new): Set is_new
(save_metadata): Don't write file unless necessary
(save_metadata):
(write_metadata_file): Split out file writing into
write_metadata_file; write default data file as necessary
(location_add_backend):
(location_remove_backend): Implement
* main.c: Add command line arguments for adding/removing locations
and backends; move backend id argument into global options
* location.c (do_load):
(load_metadata_file): Split out file parsing logic into
load_metadata_file; call load_metadata_file on default file to get
contains list if current location doesn't inherit anything
(load_metadata_file): g_strdup backend string
(load_metadata_file): Warn if top-level location has contains clauses
(location_store): Check if the location contains the given backend
and try the location it inherits if it doesn't
* archive.c (archive_load): Set is_global in archive object
* Makefile.am (Locationmeta{dir|_DATA}): Added commands to install
data files
(INCLUDES): Added define for LOCATION_DIR
2000-09-03 Bradford Hovinen <hovinen@helixcode.com>
* location.c (save_metadata): Write attributes when saving

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,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,29 +0,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,45 +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
# This is a bit complicated here since we can't use gnome-config yet.
# It'll be easier after switching to pkg-config since we can then
# use pkg-config to find the gnome-autogen.sh script.
gnome_autogen=
gnome_datadir=
ifs_save="$IFS"; IFS=":"
for dir in $PATH ; do
test -z "$dir" && dir=.
if test -f $dir/gnome-autogen.sh ; then
gnome_autogen="$dir/gnome-autogen.sh"
gnome_datadir=`echo $dir | sed -e 's,/bin$,/share,'`
break
fi
done
IFS="$ifs_save"
if test -z "$gnome_autogen" ; 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
GNOME_DATADIR="$gnome_datadir" USE_GNOME2_MACROS=1 . $gnome_autogen

View File

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

View File

@@ -1,12 +0,0 @@
always_built_SUBDIRS = \
common accessibility \
default-applications desktop-links font \
background keyboard mouse sound \
file-types theme-switcher ui-properties \
keybindings network
SUBDIRS = $(always_built_SUBDIRS)
DIST_SUBDIRS = \
$(always_built_SUBDIRS) \
windows

View File

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

View File

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

View File

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

View File

@@ -1,78 +0,0 @@
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,42 +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
iconsdir = $(GNOMECC_ICONS_DIR)
icons_DATA = accessibility-keyboard-capplet.png
desktop_iconsdir = $(datadir)/pixmaps
desktop_icons_DATA = accessibility-keyboard-capplet.png
desktopdir = $(GNOMECC_DESKTOP_DIR)
Desktop_in_files = accessibility-keyboard.desktop.in
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
INCLUDES = $(GNOMECC_CAPPLETS_CFLAGS)
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES)
EXTRA_DIST = $(Glade_DATA) $(icons_DATA) $(Desktop_in_files) $(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,463 +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 "gconf-property-editor.h"
#include "activate-settings-daemon.h"
#define IDIR GNOMECC_DATA_DIR "/pixmaps/"
#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];
} const features [] = {
{ "bouncekeys_enable", "bouncekeys_image", IDIR "accessibility-keyboard-bouncekey.png",
CONFIG_ROOT "/bouncekeys_enable",
{ "bouncekey_table", NULL, NULL } },
{ "slowkeys_enable", "slowkeys_image", IDIR "accessibility-keyboard-slowkey.png",
CONFIG_ROOT "/slowkeys_enable",
{ "slowkeys_table", NULL, NULL } },
{ "mousekeys_enable", "mousekeys_image", IDIR "accessibility-keyboard-mousekey.png",
CONFIG_ROOT "/mousekeys_enable",
{ "mousekeys_table", NULL, NULL } },
{ "stickykeys_enable", "stickykeys_image", IDIR "accessibility-keyboard-stickykey.png",
CONFIG_ROOT "/stickykeys_enable",
{ "stickeykeys_table", NULL, NULL } },
{ "togglekeys_enable", "togglekeys_image", IDIR "accessibility-keyboard-togglekey.png",
CONFIG_ROOT "/togglekeys_enable",
{ NULL, NULL, NULL } },
{ "timeout_enable", NULL, NULL,
CONFIG_ROOT "/timeout_enable",
{ "timeout_slide", "timeout_spin", "timeout_label" } }
};
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 [] = {
{ "bouncekeys_delay_slide", "bouncekeys_delay_spin", 300, 10, 900, 10,
CONFIG_ROOT "/bouncekeys_delay" },
{ "slowkeys_delay_slide", "slowkeys_delay_spin", 300, 10, 900, 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, 20,
CONFIG_ROOT "/mousekeys_max_speed" },
{ "mousekeys_accel_time_slide", "mousekeys_accel_time_spin", 300, 10, 3000, 100,
CONFIG_ROOT "/mousekeys_accel_time" },
{ "mousekeys_init_delay_slide", "mousekeys_init_delay_spin", 300, 10, 5000, 100,
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_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;
int i = G_N_ELEMENTS (features);
while (i-- > 0) {
checkbox = WID (features [i].checkbox);
g_return_if_fail (checkbox != 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 "/feature_state_change_beep","feature_state_change_beep" },
{ 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 GConfValue*
cb_to_widget (GConfPropertyEditor *peditor, const GConfValue *value)
{
return gconf_value_int_to_float (value);
}
static GConfValue*
cb_from_widget (GConfPropertyEditor *peditor, const GConfValue *value)
{
return gconf_value_float_to_int (value);
}
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,
"conv-to-widget-cb", cb_to_widget,
"conv-from-widget-cb", cb_from_widget,
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_file (GTK_IMAGE (WID (features [i].image)),
features [i].image_file);
}
static void
cb_launch_keyboard_capplet (GtkButton *button, GtkWidget *dialog)
{
GError *err = NULL;
if (!g_spawn_command_line_async ("gnome-keyboard-properties", &err))
capplet_error_dialog (GTK_WINDOW (gtk_widget_get_toplevel (dialog)),
_("There was an error launching the keyboard capplet : %s"),
err);
}
static void
setup_dialog (GladeXML *dialog, GConfChangeSet *changeset)
{
setup_images (dialog);
setup_ranges (dialog, changeset);
setup_toggles (dialog, changeset);
setup_simple_toggles (dialog, changeset);
}
/*******************************************************************************/
static void
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))
gconf_client_set_bool (client, gconf_key,
!g_ascii_strcasecmp (resourceValue.addr, "True"), NULL);
}
static void
xrm_get_int (GConfClient *client, XrmDatabase *db, char const *gconf_key,
char const *res_str, char const *class_str)
{
XrmValue resourceValue;
char *res;
int value;
char resource [256];
snprintf (resource, sizeof (resource), "%s.value", res_str);
if (!XrmGetResource (*db, resource, class_str, &res, &resourceValue))
return;
value = atoi (resourceValue.addr);
#if 0
{
int decimal;
snprintf (resource, sizeof (resource), "%s.decimalPoints", res_str);
if (!XrmGetResource (*db, resource, class_str, &res, &resourceValue))
return;
decimal = atoi (resourceValue.addr);
}
#endif
gconf_client_set_int (client, gconf_key, value, NULL);
}
/* This loads the current users XKB settings from their file */
static gboolean
load_CDE_file (GtkFileSelection *fsel)
{
char const *file = gtk_file_selection_get_filename (fsel);
GConfClient *client;
XrmDatabase db;
if (!(db = XrmGetFileDatabase (file))) {
GtkWidget *warn = gtk_message_dialog_new (
gtk_window_get_transient_for (GTK_WINDOW (fsel)),
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);
return FALSE;
}
client = gconf_client_get_default ();
xrm_get_bool (client, &db, CONFIG_ROOT "/enable",
"*EnableAccessXToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/feature_state_change_beep",
"*SoundOnOffToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/timeout_enable",
"*TimeOutToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/stickykeys_enable",
"*StickyKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/mousekeys_enable",
"*MouseKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/togglekeys_enable",
"*ToggleKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/slowkeys_enable",
"*SlowKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/bouncekeys_enable",
"*BounceKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/stickykeys_modifier_beep",
"*StickyModSoundToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/stickykeys_two_key_off",
"*StickyTwoKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/slowkeys_beep_press",
"*SlowKeysOnPressToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_bool (client, &db, CONFIG_ROOT "/slowkeys_beep_accept",
"*SlowKeysOnAcceptToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
xrm_get_int (client, &db, CONFIG_ROOT "/timeout",
"*TimeOutScale", "AccessX*XmScale");
xrm_get_int (client, &db, CONFIG_ROOT "/mousekeys_max_speed",
"*MouseMaxSpeedScale", "AccessX*XmScale");
xrm_get_int (client, &db, CONFIG_ROOT "/mousekeys_accel_time",
"*MouseAccelScale", "AccessX*XmScale");
xrm_get_int (client, &db, CONFIG_ROOT "/mousekeys_init_delay",
"*MouseDelayScale", "AccessX*XmScale");
xrm_get_int (client, &db, CONFIG_ROOT "/slowkeys_delay",
"*KRGSlowKeysDelayScale", "AccessX*XmScale");
xrm_get_int (client, &db, CONFIG_ROOT "/bouncekeys_delay",
"*KRGDebounceScale", "AccessX*XmScale");
return TRUE;
}
static void
fsel_dialog_finish (GtkWidget *fsel)
{
gtk_widget_hide_all (fsel);
}
static void
fsel_handle_ok (GtkWidget *widget, GtkFileSelection *fsel)
{
gchar const *file_name;
file_name = gtk_file_selection_get_filename (fsel);
/* Change into directory if that's what user selected */
if (g_file_test (file_name, G_FILE_TEST_IS_DIR)) {
gint name_len;
gchar *dir_name;
name_len = strlen (file_name);
if (name_len < 1 || file_name [name_len - 1] != '/') {
/* The file selector needs a '/' at the end of a directory name */
dir_name = g_strconcat (file_name, "/", NULL);
} else {
dir_name = g_strdup (file_name);
}
gtk_file_selection_set_filename (fsel, dir_name);
g_free (dir_name);
} else if (load_CDE_file (fsel))
fsel_dialog_finish (GTK_WIDGET (fsel));
}
static void
fsel_handle_cancel (GtkWidget *widget, GtkFileSelection *fsel)
{
fsel_dialog_finish (GTK_WIDGET (fsel));
}
static gint
fsel_delete_event (GtkWidget *fsel, GdkEventAny *event)
{
fsel_dialog_finish (fsel);
return TRUE;
}
static gint
fsel_key_event (GtkWidget *fsel, GdkEventKey *event, gpointer user_data)
{
if (event->keyval == GDK_Escape) {
gtk_signal_emit_stop_by_name (GTK_OBJECT (fsel), "key_press_event");
fsel_dialog_finish (fsel);
return TRUE;
}
return FALSE;
}
static GtkFileSelection *fsel = NULL;
static void
cb_load_CDE_file (GtkButton *button, GtkWidget *dialog)
{
if (fsel == NULL) {
fsel = GTK_FILE_SELECTION (
gtk_file_selection_new (_("Select CDE AccessX file")));
gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (fsel));
gtk_file_selection_set_select_multiple (GTK_FILE_SELECTION (fsel), FALSE);
gtk_window_set_modal (GTK_WINDOW (fsel), TRUE);
gtk_window_set_transient_for (GTK_WINDOW (fsel),
GTK_WINDOW (gtk_widget_get_toplevel (dialog)));
g_signal_connect (G_OBJECT (fsel->ok_button),
"clicked",
G_CALLBACK (fsel_handle_ok), fsel);
g_signal_connect (G_OBJECT (fsel->cancel_button),
"clicked",
G_CALLBACK (fsel_handle_cancel), fsel);
g_signal_connect (G_OBJECT (fsel),
"key_press_event",
G_CALLBACK (fsel_key_event), NULL);
g_signal_connect (G_OBJECT (fsel),
"delete_event",
G_CALLBACK (fsel_delete_event), NULL);
}
gtk_widget_show_all (GTK_WIDGET (fsel));
}
/*******************************************************************************/
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);
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_repeat_button")),
"clicked",
G_CALLBACK (cb_launch_keyboard_capplet), toplevel);
return toplevel;
}

View File

@@ -1,8 +0,0 @@
[Desktop Entry]
_Name=Keyboard
_Comment=Keyboard Accessibility Properties
Exec=gnome-accessibility-keyboard-properties
Icon=accessibility-keyboard-capplet.png
Terminal=0
Type=Application
Categories=Application;Settings;Accessibility;

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,72 +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"
static void
dialog_response (GtkWidget *widget,
gint response_id,
GConfChangeSet *changeset)
{
if (response_id == GTK_RESPONSE_HELP)
capplet_help (GTK_WINDOW (widget),
"wgoscustaccess.xml",
"goscustaccess-2");
else
gtk_main_quit ();
}
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 ();
changeset = NULL;
dialog = setup_accessX_dialog (changeset);
g_signal_connect (G_OBJECT (dialog),
"response",
G_CALLBACK (dialog_response), changeset);
gtk_widget_show_all (dialog);
gtk_main ();
return 0;
}

View File

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

View File

@@ -1,684 +0,0 @@
2002-06-18 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=85628
* background-properties-capplet.c (main) : The dialog
- should not be modal
- has no parent to destroy with
- and should have a seperator
- set default response
2002-06-17 Jody Goldberg <jody@gnome.org>
* Release 2.0.0
2002-06-05 Gediminas Paulauskas <menesis@delfi.lt>
* background-properties.glade: radiobutton1 and similar things should
not be translatable.
2002-05-28 Satyajit Kanungo <satyajit.kanungo@wipro.com>
* background-properties-capplet.c : Changed the help file link
to get the help document from user-guide.
2002-05-26 Jody Goldberg <jody@gnome.org>
* background-properties-capplet.c (cb_dialog_response) : improve
handling of help failures.
Sun May 26 11:29:14 2002 Jonathan Blandford <jrb@gnome.org>
* background-properties-capplet.c (main): use APPID instead of
argv[0]
Thu May 16 02:25:03 2002 Jonathan Blandford <jrb@gnome.org>
* background-properties-capplet.c (drag_data_received_cb): accept
drops from the nautilus patterns pallet. There's something broken
here, though.
2002-05-10 Jody Goldberg <jody@gnome.org>
* background-properties.glade : merge in the missing atk patch.
2002-05-09 Jody Goldberg <jody@gnome.org>
* background-properties-capplet.c (main) : add a help button.
2002-05-02 Dennis Cranston <dennis_cranston@yahoo.com>
* background-properties.glade: add a stock information image
to the "You can drag image files..." text.
2002-05-08 Jody Goldberg <jody@gnome.org>
* background-properties-capplet.c (cb_dialog_response) : new.
(main) : support help.
2002-04-27 Seth Nickell <snickell@stanford.edu>
* background.desktop.in:
Improve the comment.
2002-04-21 Rachel Hestilow <hestilow@ximian.com>
* background-properties-capplet.c (setup_dialog): Update for
new enum peditor prototypes.
Wed Apr 10 18:06:35 2002 Jonathan Blandford <jrb@gnome.org>
* background.desktop.in (Exec): s/gnome2/gnome
Mon Apr 1 19:19:39 2002 Jonathan Blandford <jrb@redhat.com>
* background-properties-capplet.c (dialog_button_clicked_cb):
handle GTK_RESPONSE_DELETE_EVENT
* Makefile.am (bin_PROGRAMS):
s/gnome2-background-properties/gnome-background-properties
2002-03-28 Richard Hestilow <hestilow@ximian.com>
* background-properties-capplet.c (create_dialog),
background-properties.glade: Add mnemonics.
(main): Set title to "Background Preferences".
2002-03-21 Seth Nickell <snickell@stanford.edu>
* background-properties-capplet.c: (main):
Set the window icon.
2002-03-21 Seth Nickell <snickell@stanford.edu>
* background-properties-capplet.c: (string_to_orientation),
(update_color_widget_labels_and_visibility),
(peditor_value_changed), (setup_dialog), (create_dialog):
* background-properties.glade:
Recapture some of the more subtle interactions of "Seth's UI".
Change colour labels when the gradient orientation changes,
and use mnemonics so the capplet is accessible. Pad and space
as designed.
There are still at least two things wrong:
1) Havoc & Jonathan convinced me that the large button with
label was wrong. This should instead look like:
http://beauty.stanford.edu/bg_button.png
The new format should be right for all image selectors, the
old mechanism had serious usability problems.
2) "No Picture" should be the first toggle
2002-03-19 Richard Hestilow <hestilow@ximian.com>
* background-properties-capplet.c:
(everywhere): Use an ApplierSet instead of passing around
BGPreferences.
(real_realize_cb): Call applier_set_redraw.
(peditor_value_changed): Merge entry in set->prefs,
and call applier_set_redraw if realized. Also, hide the second
color option if shading type is solid.
(setup_dialog): Set data for the second color selector.
Also, update peditors for new UI.
(create_dialog): Add previews and labels to radio buttons.
(main): Create applier set. Also, connect to DnD signals.
* background-properties.glade: Implement seth's new UI.
2002-03-14 Richard Hestilow <hestilow@ximian.com>
* background-properties-capplet.c (setup_dialog): Use new enum
peditors, and convert to using the #defined gconf keys from
preferences.h.
2002-03-09 Richard Hestilow <hestilow@ximian.com>
* background-properties-capplet.c (setup_dialog): Hook up
the previewing file selector to the FileEntry.
2002-02-27 Kjartan Maraas <kmaraas@gnome.org>
* background-properties-capplet.c (main): s/PACKAGE/GETTEXT_PACKAGE/g
* main.c: Same here.
2002-02-17 Bradford Hovinen <hovinen@ximian.com>
* background-properties-capplet.c (main)
(dialog_button_clicked_cb): Switch to instant apply; remove apply
button
2002-02-12 Lauris Kaplinski <lauris@ximian.com>
* background-properties-capplet.c (dialog_button_clicked_cb): Use
GtkDialog instead of GnomeDialog
2002-02-06 Seth Nickell <snickell@stanford.edu>
* background-properties-capplet.c: (drag_motion_cb),
(drag_leave_cb), (drag_data_received_cb),
(change_background_type_toggles), (set_background_picture),
(quit_cb), (main):
* background-properties.glade:
* background-properties.glade1:
More fixes. Change layout in glade a bit, make DND work,
fix widget previews.
2002-02-04 Lauris Kaplinski <lauris@ximian.com>
* background-properties-capplet.c (setup_color_widgets): Kill warning
(set_background_image_preview): Use g_file_test, use g_object_unref
instead of gdk_pixbuf_unref
(image_filename_clicked): Use g_signal_connect
(dialog_button_clicked_cb): Use GtkDialog instead of GnomeDialog
(realize_2_cb): Comment out to kill warning
(realize_cb): Ditto
(real_realize_cb): Ditto
(string_to_background_type): Treat NULL string as default
(string_to_orientation): Ditto
2002-01-13 Seth Nickell <snickell@stanford.edu>
reviewed by: <delete if not using a buddy>
* .cvsignore:
* Makefile.am:
* background-properties-capplet.c: (set_picture_is_present),
(string_to_background_type), (background_type_to_string),
(orientation_to_string), (string_to_orientation),
(peditor_string_to_orientation), (peditor_orientation_to_string),
(update_preview_widgets), (get_legacy_settings),
(setup_color_widgets), (peditor_value_changed),
(set_background_image_preview), (file_selector_cb),
(image_filename_clicked), (background_type_toggled),
(change_background_type_toggles), (background_type_changed),
(create_dialog), (idle_draw), (dialog_button_clicked_cb), (main):
* background-properties.glade:
* background-properties.glade1:
* background-properties.xml:
2002-01-28 Richard Hestilow <hestilow@ximian.com>
* Link to libbackground.la.
2002-01-17 Jakub Steiner <jimmac@ximian.com>
* background-capplet.png: minor tweaks
2002-01-14 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am (bin_PROGRAMS): Rename binary gnome2-background-properties
2002-01-02 Bradford Hovinen <hovinen@ximian.com>
* background-properties-capplet.c (main): Removed call to set up
session management - obsolete
2001-12-20 Bradford Hovinen <hovinen@ximian.com>
* background-properties-capplet.c: Update
(main): Use a GtkDialog rather than a GnomeDialog
(main): Don't put weak ref on gtk_main_quit
(dialog_button_clicked_cb): Update
Eliminate compiler warnings
* Makefile.am: Update
* background.desktop.in.in (Exec): Update
* background-properties-capplet.c (dialog_button_clicked_cb):
Remove call to apply_settings
(apply_settings): Remove
(main): Remove apply_only support
2001-12-19 Seth Nickell <snickell@stanford.edu>
* background.desktop.in.in:
Add Categories field so it goes into the right location
in the panel menus.
2001-12-18 Bradford Hovinen <hovinen@ximian.com>
* background-properties-capplet.c: Use gconf_client rather than
gconf_engine
(setup_dialog): Use correct path for enabled
(main): Preload the background settings directory for performance
Don't #include bonobo.h
* background.schema: Update keys to use /desktop/gnome/background
* background-properties-capplet.c (property_change_cb): Remove
(create_dialog): Return GladeXML, not GtkWidget
(setup_dialog): Put GladeXML in the signature rather than
GtkWidget
(peditor_value_changed): Retrieve color_frame directory rather
than through Glade
(real_realize_cb): Ditto
(setup_dialog): Set color-frame rather than glade-data
(main): Construct the preview applier here rather than in
create_dialog
(main): Unref the applier object when the dialog is destroyed
(setup_dialog, create_dialog): Put the applier in the signature
Use weak_ref rather than the destroy signal for all relevant
objects
Update GConf keys to use /desktop/gnome/background
2001-12-17 Bradford Hovinen <hovinen@ximian.com>
* background.desktop.in.in (Exec): Update
* background-properties-capplet.c (setup_dialog): Don't hide
opacity controls
(dialog_button_clicked_cb): Apply settings after commiting the
change set
(peditor_value_changed): Implement
(setup_dialog): Connect value-changed signals
(setup_dialog): Store the applier in the preferences object
(peditor_value_changed): Retrieve the applier from the preferences
object and use it to apply settings on the preview widget
(setup_dialog): Connect missing signal
(setup_dialog): Enabled set_guard call
(peditor_value_changed): Set the sensitivity of the color frame
depending on the settings
(peditor_value_changed): Use correct keys
* background.schema: Added wallpaper-enabled
* background-properties-capplet.c (create_dialog): Use
prefs_widget rather than preview placeholder widget
2001-12-07 Bradford Hovinen <hovinen@ximian.com>
* background.schema: Fix default values
* background-properties-capplet.c (main): Connect the destroy
signal
* background.schema: Fix type on opacity schema
* background-properties-capplet.c (main): Remove use of
capplet_init, instead do the initialization ourselves (note: this
means we are no longer a Bonobo control)
(dialog_button_clicked_cb): Implement
(main): Show the dialog when we are done constructing it
(main): NULL-terminate the dialog construction parameters
2001-10-19 Jakub Steiner <jimmac@ximian.com>
* background-capplet.png: more clear brush
2001-10-12 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am ($(oaffile)): Make creation of the .oaf file generic
* applier.c (render_to_screen): Use standard gdk and gdk_pixbuf
rather than xlib and gdk_pixbuf_xlib
(make_root_pixmap): Create a GdkPixmap
(set_root_pixmap): Accept GdkPixmap and convert to X id
2001-09-28 Bradford Hovinen <hovinen@ximian.com>
* preferences.c (preferences_load_from_bonobo_db):
(preferences_load_from_bonobo_pbag): Use BONOBO_RET_EX rather than
RETURN_IF_EX; remove the definition of the latter macro
* applier.c (fill_gradient): Copied from control center 1.4.0
(render_background): Create the pixbuf first and then pass to
fill_gradient
(render_to_screen): Use XLIB_RGB_DITHER_MAX rather than
GDK_RGB_DITHER_NORMAL
* Makefile.am: Change the binary name to
background-properties-control and create a wrapper script from
../common/wrapper-script.in to be named
background-properties-capplet
Remove support for disabling bonobo-conf build
2001-09-22 Bradford Hovinen <hovinen@ximian.com>
* applier.c (run_render_pipeline): Create the root pixmap after we
know about the gradient geometry
(place_pixbuf):
(tile_pixbuf): Fix calls to gdk_pixbuf_composite[_color]
(render_wallpaper): Fix setting of pixbuf_xlate
(render_background): Fix pixbuf_render_geom here in case the
gradient geometry is small
2001-09-21 Bradford Hovinen <hovinen@ximian.com>
* applier.c: Total reorganization
2001-09-17 Bradford Hovinen <hovinen@ximian.com>
* preferences.c (preferences_save): Move from
applier.c:output_compat_prefs; it really belongs here
(preferences_class_init): Don't construct an applier here
* background-properties-capplet.c (setup_dialog): Create a new
applier for every dialog
(create_dialog): Create applier locally, just for this one widget
(apply_settings): Create applier locally and destroy on exit
(main): Remove call to gnome_window_set_...
2001-09-14 Bradford Hovinen <hovinen@ximian.com>
* background-properties-capplet.c (property_change_cb): Use
applier_render_color_p
(real_realize_cb): Ditto
(get_legacy_settings): Set the wallpaper_enabled flag based on the
value of wallpaper_filename; use (none) as the default for
wallpaper_filename
(setup_dialog): Removed unused variable
* applier.c (applier_render_color_p): Renamed from
applier_render_gradient_p; check both solid color and gradient
* preferences.c (preferences_need_color_opts): Removed; use
applier_render_color_p instead
2001-09-13 Bradford Hovinen <hovinen@ximian.com>
* preferences.c (preferences_load_from_bonobo_db):
(preferences_load_from_bonobo_pbag): Default to TRUE on enabled;
check value of wallpaper_filename to set wallpaper_enabled if
wallpaper_enabled could not be found
* background-properties-capplet.c (setup_dialog):
(apply_settings): Check for error condition after creating
preferences object
* preferences.c (preferences_destroy): Make this static
(read_color_from_string): Made argument const
(bonobo_color_to_gdk): Made argument const
(DB_GET_VALUE): Removed
(PB_GET_VALUE): Removed
(preferences_load_from_bonobo_pbag): Use
local_bonobo_property_bag_client_get_value_{color|filename}
(preferences_new_from_bonobo_db):
(preferences_new_from_bonobo_pbag): Deallocate object and return
NULL if there was an error
(local_bonobo_property_bag_client_get_value_color):
(local_bonobo_property_bag_client_get_value_filename): Implement
(MAKE_GET_SIMPLE): Implement (copy from bonobo-conf)
(preferences_load_from_bonobo_pbag): Read enabled property
(preferences_load_from_bonobo_pbag): Forgive wallpaper_enabled and
enabled not being found
* applier.c (applier_render_gradient_p): Implement
(applier_destroy): Make this static
* preferences.c (preferences_load_from_bonobo_db): Use
bonobo_config_get_boolean rather than BONOBO_ARG_GET_BOOLEAN
(DB_GET_VALUE ()). Ditto bonobo_config_get_long
(preferences_load_from_bonobo_db): Pass ev pointer to each call to
bonobo_config_get_*
(preferences_load_from_bonobo_db): Check ev pointer after each
call to bonobo_config_get_* and return if an exception is set
(preferences_load_from_bonobo_db): Allow the enabled flag not to
be present in the database since some older configurations don't
have it included
(all): Remove support for compiling without bonobo-conf
2001-09-07 Richard Hestilow <hestilow@ximian.com>
* background-properties.glade: Redid UI a bit to add new enabled
checkbox.
* background-properties.xml: Add default for "wallpaper_enabled".
* preferences.[ch]: New function preferences_need_color_opts.
(preferences_load_from_bonobo_db): Load wallpaper_enabled from
bonobo-conf.
(preferences_load_from_bonobo_pbag): Ditto.
* applier.[ch]: New function applier_get_wallpaper_pixbuf
(needed by preferences_need_color_opts, else pixbuf gets created
twice).
* background-properties-capplet.c (real_realize_cb): Set
color frame sensitivity based on preferences_need_color_opts.
(property_change_cb): Ditto.
(setup_dialog): Add peditor/guard for wallpaper_enabled. Also,
set glade object data on the preferences structure as well.
2001-09-03 Bradford Hovinen <hovinen@ximian.com>
* background-properties-capplet.c (setup_dialog): Apply
preferences now if the preview widget is already realized
2001-08-28 Bradford Hovinen <hovinen@ximian.com>
* background-properties-capplet.c (get_legacy_settings): Retrieve
the correct value for wallpaper_types
* applier.c (output_compat_prefs): Output the correct value for
wallpaperAlign
* preferences.c (preferences_load_from_bonobo_pbag): Don't adjust
the opacity if the opacity setting is invalid
(preferences_load_from_bonobo_db): Ditto
2001-08-27 Bradford Hovinen <hovinen@ximian.com>
* background-properties-capplet.c (setup_dialog): Initialize/free
the CORBA environment structure
(real_realize_cb): Put into an idle handler, called by
realize_2_cb, the new timeout handler
* preferences.c (preferences_load_from_bonobo_pbag):
(preferences_load_from_bonobo_db): Extract from preferences_new_*
* background-properties-capplet.c (property_change_cb):
(realize_cb): Accept prefs structure in lieu of
Bonobo_PropertyBag; don't reload the preferences structure from
the property bag
(property_change_cb): Call preferences_apply_event to modify the
preferences structure appropriately
(property_change_cb):
(realize_cb): If the preferences structure is marked destroyed,
just return
(setup_dialog): Create a preferences structure from the property
bag given and use that as the extra data passed to callbacks
(realize_cb): Put into an idle handler real_realize_cb
* preferences.c (preferences_apply_event): Implement
* applier.c (output_compat_prefs): Make prefs const
* applier.[ch]: Have applier_apply_prefs take a const Preferences
structure
* preferences.[ch]: Make preferences_clone take a const
Preferences structure
2001-08-26 Bradford Hovinen <hovinen@ximian.com>
* applier.c (renderer_render_background): Remove debugging message
(renderer_render_wallpaper): Ditto
2001-08-17 Bradford Hovinen <hovinen@ximian.com>
* applier.c (renderer_render_wallpaper): Adjust opacity value to
0...255 scale
* preferences.c (preferences_new_from_bonobo_pbag):
(preferences_new_from_bonobo_db): Use correct check to disable
opacity
2001-08-13 Richard Hestilow <hestilow@ximian.com>
* background-properties-capplet.c (setup_dialog): Really
override enabled this time. Really.
2001-08-13 Richard Hestilow <hestilow@ximian.com>
* applier.c (applier_apply_prefs): Only draw disabled message
if do_preview. Actually, the user will never see this because
the correct behavior (which is done) is to assume if they're
running capplet, prefs->enable should be TRUE. This is because
we are only honoring enable as a hacker-only setting.
(output_compat_prefs): Output the correct "Enable" setting.
* background-properties-capplet.c (get_legacy_settings): Support
the "Enabled" flag.
* preferences.c (preferences_new_from_bonobo_db): Import the
"enabled" flag. Note that this is not bothered with in the _pbag
function, because that's from the Proxy settings, which is only
used for the GUI capplet, which always sets enabled to True, because
this is a hacker-only option. Got it?
* background-properties.xml: Add "enabled".
2001-07-31 Chema Celorio <chema@celorio.com>
* Makefile.am (cappletname): add DISTDIR to install-data-local
2001-07-27 Bradford Hovinen <hovinen@ximian.com>
* background-properties-capplet.c (get_legacy_settings): Fix
val_ulong in the gradient case
* RELEASE : 1.5.2
2001-07-26 Bradford Hovinen <hovinen@ximian.com>
* applier.c (applier_apply_prefs): Don't try to load the wallpaper
if it's not enabled
* preferences.c (preferences_new_from_bonobo_pbag): Use
bonobo_property_editor_client_get_value_*
(preferences_new_from_bonobo_pbag): Set gradient_enabled properly
from property bag
(preferences_new_from_bonobo_pbag): Check for wallpaper == "(none)"
(preferences_new_from_bonobo_db): Ditto above
* applier.c (renderer_render_wallpaper): Restore some lost tweaks
from earlier.
* preferences.c (preferences_init): strdup the home directory
* applier.c: Store preview widget in the renderer, not the applier
itself
* background-properties-capplet.c (create_dialog): Add a "(none)"
string to the history
2001-07-26 Richard Hestilow <hestilow@ximian.com>
* applier.c: Remove all bonobo-conf stuff.
* preferences.[ch]: New functions preferences_new_from_bonobo_pbag
and preferences_new_from_bonobo_db.
2001-07-26 Bradford Hovinen <hovinen@ximian.com>
* background-properties.glade: Tweak borders and padding
* applier.c (get_geometry): Tweak geometry settings
(renderer_render_wallpaper): Rendering geometry fixes
(renderer_render_wallpaper): Remove debugging code
* background-properties-capplet.c (property_change_cb): Accept
applier as argument; retrieve property bag from applier
(realize_cb): Retrieve applier from widget
(setup_dialog): Store property bag in applier
* applier.c (renderer_new): Store applier inside renderer; accept
applier as function parameter
* background-properties-capplet.c (create_dialog): Store the
applier inside the widget
* applier.c (struct _ApplierPrivate ): Define preview_widget here
rather than globally
(applier_get_preview_widget): Make this a method of the applier class
2001-07-25 Chema Celorio <chema@celorio.com>
* Makefile.am ($(oaffile)): remove the oaffile_IN_RULE macro and copy
it here
* Makefile.am: remove the DESKTOP_IN_RULE and copy the sed here
2001-07-24 Bradford Hovinen <hovinen@ximian.com>
* main.c (setup_dialog): Use bonobo_peditor_option_menu_construct
2001-07-25 Richard Hestilow <hestilow@ximian.com>
* main.c (setup_dialog): Hide opacity settings for now.
* background-properties.glade: Rename opacity label.
2001-07-24 Richard Hestilow <hestilow@ximian.com>
* applier.c (output_compat_prefs): Write to gnome-config to make
nautilus happy.
(applier_apply_prefs): Change of is_nautilus_running handling
logic to still output legacy settings. Also, call
output_compat_prefs if is_root
.
2001-07-24 Richard Hestilow <hestilow@ximian.com>
* main.c (main): Pass in legacy files to capplet_init.
2001-07-23 Bradford Hovinen <hovinen@ximian.com>
* applier.c (renderer_render_wallpaper): Don't adjust pixmap width
2001-07-20 Chema Celorio <chema@celorio.com>
* RELEASE : 1.5.0
2001-07-19 Chema Celorio <chema@celorio.com>
* Makefile.am (cappletname): make distcheck love
2001-07-19 Richard Hestilow <hestilow@ximian.com>
* main.c: Add compatibility "-b" argument.
2001-07-19 Richard Hestilow <hestilow@ximian.com>
* applier.c: remove debugging spew
* main.c (get_legacy_settings): Fix for FileName corba type.
(apply_settings): Check to make sure applier exists.
2001-07-19 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am: Rename binary to background-properties
2001-07-19 Richard Hestilow <hestilow@ximian.com>
* background-properties.desktop.in.in: Change exec string for
bonobo-conf.
2001-07-19 Richard Hestilow <hestilow@ximian.com>
* bonobo-conf rewrite.
2001-07-19 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am: Remove SUBDIRS
(background_properties_SOURCES): Added missing applier.h
* prefs-widget.c: Remove references to auto apply feature
* applier.c (get_geometry): Use vwidth and vheight rather than
dwidth and dheight when computing aspect ratio
(get_geometry): Adjust rwidth and rheight according to above change
* preferences.c (preferences_changed): Disable auto-apply
* background-properties.glade: Remove apply automatically check
button; change "More Solid" to "More Opaque"
2001-07-17 Chema Celorio <chema@celorio.com>
* start

View File

@@ -1,24 +0,0 @@
bin_PROGRAMS = gnome-background-properties
gnome_background_properties_LDADD = $(GNOMECC_CAPPLETS_LIBS) $(top_builddir)/libbackground/libbackground.la
gnome_background_properties_SOURCES = background-properties-capplet.c
@INTLTOOL_DESKTOP_RULE@
Gladedir = $(GNOMECC_GLADE_DIR)
Glade_DATA = background-properties.glade
iconsdir = $(GNOMECC_ICONS_DIR)
icons_DATA = background-capplet.png
desktop_iconsdir = $(datadir)/pixmaps
desktop_icons_DATA = background-capplet.png
desktopdir = $(GNOMECC_DESKTOP_DIR)
Desktop_in_files = background.desktop.in
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
INCLUDES = $(GNOMECC_CAPPLETS_CFLAGS) -I$(top_srcdir)/libbackground
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES)
EXTRA_DIST = $(Glade_DATA) $(icons_DATA) $(Desktop_in_files)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,618 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* background-properties-capplet.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by: Bradford Hovinen <hovinen@ximian.com>,
* Rachel Hestilow <hestilow@ximian.com>
* Seth Nickell <snickell@stanford.edu>
*
* 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 <string.h>
#include <gnome.h>
#include <gconf/gconf-client.h>
#include <glade/glade.h>
#include <libgnomevfs/gnome-vfs.h>
#include "capplet-util.h"
#include "gconf-property-editor.h"
#include "applier.h"
#include "preview-file-selection.h"
#include "activate-settings-daemon.h"
enum
{
TARGET_URI_LIST,
TARGET_COLOR,
TARGET_BGIMAGE,
/* TARGET_BACKGROUND_RESET*/
};
static GtkTargetEntry drop_types[] =
{
{"text/uri-list", 0, TARGET_URI_LIST},
{ "application/x-color", 0, TARGET_COLOR },
{ "property/bgimage", 0, TARGET_BGIMAGE },
/* { "x-special/gnome-reset-background", 0, TARGET_BACKGROUND_RESET }*/
};
static gint n_drop_types = sizeof (drop_types) / sizeof (GtkTargetEntry);
static const int n_enum_vals = WPTYPE_NONE + 1;
typedef struct
{
BGApplier** appliers;
BGPreferences *prefs;
} ApplierSet;
/* Create a new set of appliers, and load the default preferences */
static ApplierSet*
applier_set_new (void)
{
int i;
ApplierSet *set = g_new0 (ApplierSet, 1);
set->appliers = g_new0 (BGApplier*, n_enum_vals);
for (i = 0; i < n_enum_vals; i++)
set->appliers[i] = BG_APPLIER (bg_applier_new (BG_APPLIER_PREVIEW));
set->prefs = BG_PREFERENCES (bg_preferences_new ());
bg_preferences_load (set->prefs);
return set;
}
/* Destroy all prefs/appliers in set, and free structure */
static void
applier_set_free (ApplierSet *set)
{
int i;
g_return_if_fail (set != NULL);
for (i = 0; i < n_enum_vals; i++)
g_object_unref (G_OBJECT (set->appliers[i]));
g_free (set->appliers);
g_object_unref (G_OBJECT (set->prefs));
}
/* Trigger a redraw in each applier in the set */
static void
applier_set_redraw (ApplierSet *set)
{
int i;
g_return_if_fail (set != NULL);
for (i = 0; i < n_enum_vals; i++)
{
set->prefs->wallpaper_enabled = TRUE;
set->prefs->wallpaper_type = i;
bg_applier_apply_prefs (set->appliers[i], set->prefs);
}
}
/* Retrieve legacy gnome_config settings and store them in the GConf
* database. This involves some translation of the settings' meanings.
*/
static void
get_legacy_settings (void)
{
int val_int;
char *val_string;
gboolean val_boolean;
gboolean def;
gchar *val_filename;
gchar *path;
gchar *prefix;
GConfClient *client;
/* gnome_config needs to be told to use the Gnome1 prefix */
path = g_build_filename (g_get_home_dir (), ".gnome", "Background", NULL);
prefix = g_strconcat ("=", path, "=", "/Default/", NULL);
gnome_config_push_prefix (prefix);
g_free (prefix);
g_free (path);
client = gconf_client_get_default ();
gconf_client_set_bool (client, BG_PREFERENCES_DRAW_BACKGROUND,
gnome_config_get_bool ("Enabled=true"), NULL);
val_filename = gnome_config_get_string ("wallpaper=(none)");
if (val_filename != NULL && strcmp (val_filename, "(none)"))
{
gconf_client_set_string (client, BG_PREFERENCES_PICTURE_FILENAME,
val_filename, NULL);
gconf_client_set_string (client, BG_PREFERENCES_PICTURE_OPTIONS,
bg_preferences_get_wptype_as_string (gnome_config_get_int ("wallpaperAlign=0")), NULL);
}
else
gconf_client_set_string (client, BG_PREFERENCES_PICTURE_OPTIONS, "none", NULL);
g_free (val_filename);
gconf_client_set_string (client, BG_PREFERENCES_PRIMARY_COLOR,
gnome_config_get_string ("color1"), NULL);
gconf_client_set_string (client, BG_PREFERENCES_SECONDARY_COLOR,
gnome_config_get_string ("color2"), NULL);
/* Code to deal with new enum - messy */
val_int = -1;
val_string = gnome_config_get_string_with_default ("simple=solid", &def);
if (!def) {
if (!strcmp (val_string, "solid")) {
val_int = ORIENTATION_SOLID;
} else {
g_free (val_string);
val_string = gnome_config_get_string_with_default ("gradient=vertical", &def);
if (!def)
val_int = (!strcmp (val_string, "vertical")) ? ORIENTATION_VERT : ORIENTATION_HORIZ;
}
}
g_free (val_string);
if (val_int != -1)
gconf_client_set_string (client, BG_PREFERENCES_COLOR_SHADING_TYPE, bg_preferences_get_orientation_as_string (val_int), NULL);
val_boolean = gnome_config_get_bool_with_default ("adjustOpacity=true", &def);
if (!def && val_boolean)
gconf_client_set_int (client, BG_PREFERENCES_PICTURE_OPACITY,
gnome_config_get_int ("opacity=100"), NULL);
else
gconf_client_set_int (client, BG_PREFERENCES_PICTURE_OPACITY, 100, NULL);
gnome_config_pop_prefix ();
}
static orientation_t
string_to_orientation (const gchar *string)
{
orientation_t type = ORIENTATION_SOLID;
if (string) {
if (!strncmp (string, "vertical-gradient", sizeof ("vertical-gradient"))) {
type = ORIENTATION_VERT;
} else if (!strncmp (string, "horizontal-gradient", sizeof ("horizontal-gradient"))) {
type = ORIENTATION_HORIZ;
}
}
return type;
}
static void
update_color_widget_labels_and_visibility (ApplierSet *set, const gchar *value_str)
{
gboolean two_colors = TRUE;
char *color1_string = NULL;
char *color2_string = NULL;
GtkWidget *color1_label;
GtkWidget *color2_label;
GtkWidget *color2_box;
orientation_t orientation = string_to_orientation (value_str);
switch (orientation) {
case ORIENTATION_SOLID: /* solid */
color1_string = _("C_olor:");
two_colors = FALSE;
break;
case ORIENTATION_HORIZ: /* horiz */
color1_string = _("_Left Color:");
color2_string = _("_Right Color:");
break;
case ORIENTATION_VERT: /* vert */
color1_string = _("_Top Color:");
color2_string = _("_Bottom Color:");
break;
default:
break;
}
color1_label = g_object_get_data (G_OBJECT (set->prefs), "color1-label");
color2_label = g_object_get_data (G_OBJECT (set->prefs), "color2-label");
color2_box = g_object_get_data (G_OBJECT (set->prefs), "color2-box");
g_assert (color1_label);
gtk_label_set_text_with_mnemonic (GTK_LABEL(color1_label), color1_string);
if (two_colors) {
gtk_widget_show (color2_box);
g_assert (color2_label);
gtk_label_set_text_with_mnemonic (GTK_LABEL(color2_label), color2_string);
} else {
gtk_widget_hide (color2_box);
}
}
/* Initial apply to the preview, and setting of the color frame's sensitivity.
*
* We use a double-delay mechanism: first waiting 100 ms, then working in an
* idle handler so that the preview gets rendered after the rest of the dialog
* is displayed. This prevents the program from appearing to stall on startup,
* making it feel more natural to the user.
*/
static gboolean
real_realize_cb (ApplierSet *set)
{
GtkWidget *color_frame;
g_return_val_if_fail (set != NULL, TRUE);
if (G_OBJECT (set->prefs)->ref_count == 0)
return FALSE;
color_frame = g_object_get_data (G_OBJECT (set->prefs), "color-frame");
applier_set_redraw (set);
gtk_widget_set_sensitive (color_frame, bg_applier_render_color_p (set->appliers[0], set->prefs));
return FALSE;
}
static gboolean
realize_2_cb (ApplierSet *set)
{
gtk_idle_add ((GtkFunction) real_realize_cb, set);
return FALSE;
}
static void
realize_cb (GtkWidget *widget, ApplierSet *set)
{
gtk_idle_add ((GtkFunction) real_realize_cb, set);
gtk_timeout_add (100, (GtkFunction) realize_2_cb, set);
}
/* Callback issued when some value changes in a property editor. This merges the
* value with the preferences object and applies the settings to the preview. It
* also sets the sensitivity of the color frame depending on whether the base
* colors are visible through the wallpaper (or whether the wallpaper is
* enabled). This cannot be done with a guard as it depends on a much more
* complex criterion than a simple boolean configuration property.
*/
static void
peditor_value_changed (GConfPropertyEditor *peditor, const gchar *key, const GConfValue *value, ApplierSet *set)
{
GConfEntry *entry;
GtkWidget *color_frame;
entry = gconf_entry_new (key, value);
bg_preferences_merge_entry (set->prefs, entry);
gconf_entry_free (entry);
if (GTK_WIDGET_REALIZED (bg_applier_get_preview_widget (set->appliers[n_enum_vals - 1])))
applier_set_redraw (set);
if (!strcmp (key, BG_PREFERENCES_PICTURE_FILENAME) ||
!strcmp (key, BG_PREFERENCES_PICTURE_OPTIONS))
{
color_frame = g_object_get_data (G_OBJECT (set->prefs), "color-frame");
gtk_widget_set_sensitive (color_frame, bg_applier_render_color_p (set->appliers[0], set->prefs));
}
else if (!strcmp (key, BG_PREFERENCES_COLOR_SHADING_TYPE))
{
update_color_widget_labels_and_visibility (set, gconf_value_get_string (value));
}
}
/* Set up the property editors in the dialog. This also loads the preferences
* and sets up the callbacks.
*/
static void
setup_dialog (GladeXML *dialog, GConfChangeSet *changeset, ApplierSet *set)
{
GObject *peditor;
GConfClient *client;
gchar *color_option;
/* Override the enabled setting to make sure background is enabled */
client = gconf_client_get_default ();
gconf_client_set_bool (client, BG_PREFERENCES_DRAW_BACKGROUND, TRUE, NULL);
/* We need to be able to retrieve the color frame in
callbacks */
g_object_set_data (G_OBJECT (set->prefs), "color-frame", WID ("color_vbox"));
g_object_set_data (G_OBJECT (set->prefs), "color2-box", WID ("color2_box"));
g_object_set_data (G_OBJECT (set->prefs), "color1-label", WID("color1_label"));
g_object_set_data (G_OBJECT (set->prefs), "color2-label", WID("color2_label"));
peditor = gconf_peditor_new_select_menu_with_enum
(changeset, BG_PREFERENCES_COLOR_SHADING_TYPE, WID ("border_shading"), bg_preferences_orientation_get_type (), TRUE, NULL);
g_signal_connect (peditor, "value-changed", (GCallback) peditor_value_changed, set);
peditor = gconf_peditor_new_color
(changeset, BG_PREFERENCES_PRIMARY_COLOR, WID ("color1"), NULL);
g_signal_connect (peditor, "value-changed", (GCallback) peditor_value_changed, set);
peditor = gconf_peditor_new_color
(changeset, BG_PREFERENCES_SECONDARY_COLOR, WID ("color2"), NULL);
g_signal_connect (peditor, "value-changed", (GCallback) peditor_value_changed, set);
peditor = gconf_peditor_new_image
(changeset, BG_PREFERENCES_PICTURE_FILENAME, WID ("background_image_button"), NULL);
g_signal_connect (peditor, "value-changed", (GCallback) peditor_value_changed, set);
peditor = gconf_peditor_new_select_radio_with_enum
(changeset, BG_PREFERENCES_PICTURE_OPTIONS, gtk_radio_button_get_group (GTK_RADIO_BUTTON (WID ("radiobutton1"))), bg_preferences_wptype_get_type (), TRUE, NULL);
g_signal_connect (peditor, "value-changed", (GCallback) peditor_value_changed, set);
/* Make sure preferences get applied to the preview */
if (GTK_WIDGET_REALIZED (bg_applier_get_preview_widget (set->appliers[n_enum_vals - 1])))
applier_set_redraw (set);
else
g_signal_connect_after (G_OBJECT (bg_applier_get_preview_widget (set->appliers[n_enum_vals - 1])),
"realize", (GCallback) realize_cb, set);
color_option = gconf_client_get_string (gconf_client_get_default (),
BG_PREFERENCES_COLOR_SHADING_TYPE,
NULL);
update_color_widget_labels_and_visibility (set, color_option);
g_free (color_option);
}
/* Construct the dialog */
static GladeXML *
create_dialog (ApplierSet *set)
{
GtkWidget *widget;
GladeXML *dialog;
GSList *group;
int i;
const gchar *labels[] = { N_("_Wallpaper"), N_("C_entered"), N_("_Scaled"), N_("Stretc_hed"), N_("_No Picture") };
GtkWidget *label;
/* FIXME: What the hell is domain? */
dialog = glade_xml_new (GNOMECC_DATA_DIR "/interfaces/background-properties.glade", "prefs_widget", NULL);
widget = glade_xml_get_widget (dialog, "prefs_widget");
g_object_weak_ref (G_OBJECT (widget), (GWeakNotify) g_object_unref, dialog);
/* Set up the applier buttons */
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (WID ("radiobutton1")));
group = g_slist_copy (group);
group = g_slist_reverse (group);
for (i = 0; group && i < n_enum_vals; i++, group = group->next)
{
GtkWidget *w = GTK_WIDGET (group->data);
GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
gtk_widget_destroy (GTK_BIN (w)->child);
gtk_container_add (GTK_CONTAINER (w), vbox);
gtk_box_pack_start (GTK_BOX (vbox),
bg_applier_get_preview_widget (set->appliers[i]),
TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox),
gtk_label_new_with_mnemonic (gettext (labels[i])),
FALSE, FALSE, 0);
gtk_widget_show_all (vbox);
}
g_slist_free (group);
label = gtk_label_new_with_mnemonic (_("Select _picture:"));
gtk_frame_set_label_widget (GTK_FRAME (WID ("picture_frame")),
label);
gtk_label_set_mnemonic_widget (GTK_LABEL (label),
WID ("background_image_button"));
gtk_widget_show (label);
gtk_label_set_mnemonic_widget (GTK_LABEL (WID ("border_shading_label")),
WID ("border_shading"));
gtk_label_set_mnemonic_widget (GTK_LABEL (WID ("color1_label")),
WID ("color1"));
gtk_label_set_mnemonic_widget (GTK_LABEL (WID ("color2_label")),
WID ("color2"));
return dialog;
}
static void
cb_dialog_response (GtkDialog *dialog, gint response_id)
{
if (response_id == GTK_RESPONSE_HELP)
capplet_help (GTK_WINDOW (dialog),
"wgoscustdesk.xml",
"goscustdesk-7");
else
gtk_main_quit ();
}
/* Callback issued during drag movements */
static gboolean
drag_motion_cb (GtkWidget *widget, GdkDragContext *context,
gint x, gint y, guint time, gpointer data)
{
return FALSE;
}
/* Callback issued during drag leaves */
static void
drag_leave_cb (GtkWidget *widget, GdkDragContext *context,
guint time, gpointer data)
{
gtk_widget_queue_draw (widget);
}
/* Callback issued on actual drops. Attempts to load the file dropped. */
static void
drag_data_received_cb (GtkWidget *widget, GdkDragContext *context,
gint x, gint y,
GtkSelectionData *selection_data,
guint info, guint time, gpointer data)
{
GConfClient *client = gconf_client_get_default ();
ApplierSet *set = (ApplierSet*) data;
if (info == TARGET_URI_LIST ||
info == TARGET_BGIMAGE)
{
GList *uris;
g_print ("got %s\n", selection_data->data);
uris = gnome_vfs_uri_list_parse ((gchar *) selection_data->data);
/* Arbitrarily pick the first item */
if (uris != NULL && uris->data != NULL)
{
GnomeVFSURI *uri = (GnomeVFSURI *) uris->data;
GConfEntry *entry;
GConfValue *value = gconf_value_new (GCONF_VALUE_STRING);
gconf_value_set_string (value, gnome_vfs_uri_get_path (uri));
/* Hmm, should we bother with changeset here? */
gconf_client_set (client, BG_PREFERENCES_PICTURE_FILENAME, value, NULL);
gconf_client_suggest_sync (client, NULL);
/* this isn't emitted by the peditors,
* so we have to manually update */
/* FIXME: this can't be right!!!! -jrb */
entry = gconf_entry_new (BG_PREFERENCES_PICTURE_FILENAME, value);
bg_preferences_merge_entry (set->prefs, entry);
gconf_entry_free (entry);
gconf_value_free (value);
gconf_client_set_string (client, BG_PREFERENCES_PICTURE_OPTIONS, "wallpaper", NULL);
}
gnome_vfs_uri_list_free (uris);
} else if (info == TARGET_COLOR) {
guint16 *channels;
char *color_spec;
if (selection_data->length != 8 || selection_data->format != 16) {
return;
}
channels = (guint16 *) selection_data->data;
color_spec = g_strdup_printf ("#%02X%02X%02X", channels[0] >> 8, channels[1] >> 8, channels[2] >> 8);
gconf_client_set_string (client, BG_PREFERENCES_PICTURE_OPTIONS, "none", NULL);
gconf_client_set_string (client, BG_PREFERENCES_COLOR_SHADING_TYPE, "solid", NULL);
gconf_client_set_string (client, BG_PREFERENCES_PRIMARY_COLOR, color_spec, NULL);
g_free (color_spec);
} else if (info == TARGET_BGIMAGE) {
} else if (info == TARGET_URI_LIST) {
}
if (GTK_WIDGET_REALIZED (bg_applier_get_preview_widget (set->appliers[n_enum_vals - 1])))
applier_set_redraw (set);
}
int
main (int argc, char **argv)
{
GConfClient *client;
GladeXML *dialog;
GtkWidget *dialog_win;
ApplierSet *set;
GdkPixbuf *pixbuf;
static gboolean get_legacy;
static struct poptOption cap_options[] = {
{ "get-legacy", '\0', POPT_ARG_NONE, &get_legacy, 0,
N_("Retrieve and store legacy settings"), NULL },
{ NULL, '\0', 0, NULL, 0, NULL, NULL }
};
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
gnome_program_init ("gnome-background-properties", VERSION,
LIBGNOMEUI_MODULE, argc, argv,
GNOME_PARAM_POPT_TABLE, cap_options,
NULL);
activate_settings_daemon ();
client = gconf_client_get_default ();
gconf_client_add_dir (client, "/desktop/gnome/background", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
if (get_legacy) {
get_legacy_settings ();
} else {
set = applier_set_new ();
dialog = create_dialog (set);
setup_dialog (dialog, NULL, set);
dialog_win = gtk_dialog_new_with_buttons
(_("Background Preferences"), NULL, 0,
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog_win),
GTK_RESPONSE_CLOSE);
pixbuf = gdk_pixbuf_new_from_file (GNOMECC_DATA_DIR "/icons/background-capplet.png", NULL);
gtk_window_set_icon (GTK_WINDOW(dialog_win), pixbuf);
gdk_pixbuf_unref (pixbuf);
g_signal_connect (G_OBJECT (dialog_win),
"response",
G_CALLBACK (cb_dialog_response), NULL);
gtk_drag_dest_set (dialog_win, GTK_DEST_DEFAULT_ALL,
drop_types, n_drop_types,
GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE);
g_signal_connect (G_OBJECT (dialog_win), "drag-motion",
G_CALLBACK (drag_motion_cb), NULL);
g_signal_connect (G_OBJECT (dialog_win), "drag-leave",
G_CALLBACK (drag_leave_cb), NULL);
g_signal_connect (G_OBJECT (dialog_win), "drag-data-received",
G_CALLBACK (drag_data_received_cb),
set);
g_object_weak_ref (G_OBJECT (dialog_win), (GWeakNotify) applier_set_free, set);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_win)->vbox), WID ("prefs_widget"), TRUE, TRUE, GNOME_PAD_SMALL);
gtk_widget_show (dialog_win);
gtk_main ();
}
return 0;
}

View File

@@ -1,659 +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="GtkWindow" id="background_preference_window">
<property name="title" translatable="yes">Background 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">True</property>
<property name="destroy_with_parent">False</property>
<child>
<widget class="GtkNotebook" id="notebook1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="show_tabs">True</property>
<property name="show_border">True</property>
<property name="tab_pos">GTK_POS_TOP</property>
<property name="scrollable">False</property>
<property name="tab_hborder">2</property>
<property name="tab_vborder">2</property>
<property name="enable_popup">False</property>
<child>
<widget class="GtkVBox" id="prefs_widget">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkVBox" id="vbox9">
<property name="border_width">10</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHBox" id="hbox8">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">15</property>
<child>
<widget class="GtkFrame" id="picture_frame">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkButton" id="background_image_button">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">To set the background picture, drop an image or click to browse.</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<accessibility>
<atkproperty name="AtkObject::accessible_name" translatable="yes">Background Preview</atkproperty>
</accessibility>
<child>
<widget class="GtkVBox" id="vbox21">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkImage" id="background_image_preview">
<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>
<accessibility>
<atkproperty name="AtkObject::accessible_name" translatable="yes">Preview</atkproperty>
<atkproperty name="AtkObject::accessible_description" translatable="yes">A preview of the background picture.</atkproperty>
</accessibility>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="image_filename_label">
<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_CENTER</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>
<accessibility>
<atkproperty name="AtkObject::accessible_description" translatable="yes">The background picture's file name.</atkproperty>
</accessibility>
</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">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox15">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="label39">
<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_CENTER</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">True</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox17">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-dialog-info</property>
<property name="icon_size">6</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="label17">
<property name="visible">True</property>
<property name="label" translatable="yes">You can drag image files
into the window to set the
background picture.</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>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label38">
<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_CENTER</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">True</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>
<child>
<widget class="GtkVBox" id="color_vbox">
<property name="border_width">10</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="border_shading_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Picture bor_der:</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">7.45058e-09</property>
<property name="yalign">0.5</property>
<property name="xpad">3</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="hbox10">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkVBox" id="vbox23">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkOptionMenu" id="border_shading">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="history">0</property>
<child internal-child="menu">
<widget class="GtkMenu" id="convertwidget1">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="convertwidget2">
<property name="visible">True</property>
<property name="label" translatable="yes">Solid color</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="convertwidget3">
<property name="visible">True</property>
<property name="label" translatable="yes">Horizontal gradient</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="convertwidget4">
<property name="visible">True</property>
<property name="label" translatable="yes">Vertical gradient</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
</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">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="color_box">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">10</property>
<child>
<widget class="GtkLabel" id="label40">
<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_CENTER</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">True</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="color1_box">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">3</property>
<child>
<widget class="GtkLabel" id="color1_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Primary Color</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</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="GnomeColorPicker" id="color1">
<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>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="color2_box">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">3</property>
<child>
<widget class="GtkLabel" id="color2_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Secondary Color</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</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="GnomeColorPicker" id="color2">
<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>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</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>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame5">
<property name="border_width">10</property>
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkVBox" id="vbox14">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkHBox" id="hbox16">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">5</property>
<child>
<widget class="GtkRadioButton" id="radiobutton1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="no">radiobutton1</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">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="radiobutton2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="no">radiobutton2</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">False</property>
<property name="group">radiobutton1</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="radiobutton3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="no">radiobutton3</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">False</property>
<property name="group">radiobutton1</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="radiobutton4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="no">radiobutton4</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">False</property>
<property name="group">radiobutton1</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="radiobutton5">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="no">radiobutton5</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">False</property>
<property name="group">radiobutton1</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>
</child>
<child>
<widget class="GtkLabel" id="label41">
<property name="visible">True</property>
<property name="label" translatable="yes">Picture Options:</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="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
<property name="tab_fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label12">
<property name="visible">True</property>
<property name="label" translatable="no">E-Mail</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</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="type">tab</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@@ -1,653 +0,0 @@
<?xml version="1.0"?>
<GTK-Interface>
<project>
<name>Project2</name>
<program_name>project2</program_name>
<directory></directory>
<source_directory>src</source_directory>
<pixmaps_directory>pixmaps</pixmaps_directory>
<language>C</language>
<gnome_support>True</gnome_support>
<gettext_support>True</gettext_support>
</project>
<widget>
<class>GtkWindow</class>
<name>background_preference_window</name>
<title>Background Properties</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
<modal>False</modal>
<allow_shrink>False</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>False</auto_shrink>
<widget>
<class>GtkNotebook</class>
<name>notebook1</name>
<can_focus>True</can_focus>
<show_tabs>True</show_tabs>
<show_border>True</show_border>
<tab_pos>GTK_POS_TOP</tab_pos>
<scrollable>False</scrollable>
<tab_hborder>2</tab_hborder>
<tab_vborder>2</tab_vborder>
<popup_enable>False</popup_enable>
<widget>
<class>GtkVBox</class>
<name>background_preferences_widget</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkVBox</class>
<name>vbox9</name>
<border_width>10</border_width>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkHBox</class>
<name>hbox8</name>
<homogeneous>False</homogeneous>
<spacing>15</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkFrame</class>
<name>frame6</name>
<label>Picture:</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_NONE</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkButton</class>
<name>background_image_button</name>
<can_focus>True</can_focus>
<relief>GTK_RELIEF_NORMAL</relief>
<widget>
<class>GtkVBox</class>
<name>vbox21</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkPixmap</class>
<name>background_image_preview</name>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<build_insensitive>True</build_insensitive>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
<name>image_filename_label</name>
<label></label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GtkVBox</class>
<name>vbox15</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label39</name>
<label></label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
<name>label17</name>
<label>You can drag image files
into the window to set the
background picture.</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
<name>label38</name>
<label></label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GtkVBox</class>
<name>vbox22</name>
<border_width>10</border_width>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
<pack>GTK_PACK_END</pack>
</child>
<widget>
<class>GtkLabel</class>
<name>border_shading_label</name>
<label>Border the picture with a:</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>7.45058e-09</xalign>
<yalign>0.5</yalign>
<xpad>3</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkHBox</class>
<name>hbox10</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>vbox23</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkOptionMenu</class>
<name>border_shading</name>
<can_focus>True</can_focus>
<items>Solid Colour
Horizontal Gradient
Vertical Gradient
</items>
<initial_choice>0</initial_choice>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
<widget>
<class>GtkHBox</class>
<name>color_box</name>
<homogeneous>False</homogeneous>
<spacing>10</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label40</name>
<label></label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkHBox</class>
<name>color1_box</name>
<homogeneous>False</homogeneous>
<spacing>3</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>color1_label</name>
<label>Color 1</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GnomeColorPicker</class>
<name>color1</name>
<can_focus>True</can_focus>
<dither>True</dither>
<use_alpha>False</use_alpha>
<title>Pick a color</title>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
<widget>
<class>GtkHBox</class>
<name>color2_box</name>
<homogeneous>False</homogeneous>
<spacing>3</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>color2_label</name>
<label>Color 2</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GnomeColorPicker</class>
<name>color2</name>
<can_focus>True</can_focus>
<dither>True</dither>
<use_alpha>False</use_alpha>
<title>Pick a color</title>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GtkFrame</class>
<name>frame5</name>
<border_width>10</border_width>
<label>Picture Options:</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_NONE</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
<pack>GTK_PACK_END</pack>
</child>
<widget>
<class>GtkVBox</class>
<name>vbox14</name>
<homogeneous>False</homogeneous>
<spacing>2</spacing>
<widget>
<class>GtkHBox</class>
<name>hbox16</name>
<homogeneous>True</homogeneous>
<spacing>5</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkToggleButton</class>
<name>no_picture_toggle</name>
<can_focus>True</can_focus>
<relief>GTK_RELIEF_NORMAL</relief>
<active>False</active>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>no_picture_frame</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkLabel</class>
<name>label29</name>
<label>_No Picture</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
<pack>GTK_PACK_END</pack>
</child>
</widget>
</widget>
</widget>
<widget>
<class>GtkToggleButton</class>
<name>wallpaper_toggle</name>
<can_focus>True</can_focus>
<relief>GTK_RELIEF_NORMAL</relief>
<active>False</active>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>wallpaper_frame</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkLabel</class>
<name>label30</name>
<label>_Wallpaper</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
<pack>GTK_PACK_END</pack>
</child>
</widget>
</widget>
</widget>
<widget>
<class>GtkToggleButton</class>
<name>centered_toggle</name>
<can_focus>True</can_focus>
<relief>GTK_RELIEF_NORMAL</relief>
<active>False</active>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>centered_frame</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkLabel</class>
<name>label31</name>
<label>_Centered</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
<pack>GTK_PACK_END</pack>
</child>
</widget>
</widget>
</widget>
<widget>
<class>GtkToggleButton</class>
<name>scaled_toggle</name>
<can_focus>True</can_focus>
<relief>GTK_RELIEF_NORMAL</relief>
<active>False</active>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>scaled_frame</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkLabel</class>
<name>label32</name>
<label>_Scaled</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
<pack>GTK_PACK_END</pack>
</child>
</widget>
</widget>
</widget>
<widget>
<class>GtkToggleButton</class>
<name>stretched_toggle</name>
<can_focus>True</can_focus>
<relief>GTK_RELIEF_NORMAL</relief>
<active>False</active>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkVBox</class>
<name>stretched_frame</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkLabel</class>
<name>label33</name>
<label>S_tretched</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
<pack>GTK_PACK_END</pack>
</child>
</widget>
</widget>
</widget>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>label12</name>
<label>E-Mail</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>Placeholder</class>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>label13</name>
<label>Workspace 3</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>Placeholder</class>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>label14</name>
<label>Workspace 4</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
</GTK-Interface>

View File

@@ -1,71 +0,0 @@
<?xml version="1.0"?>
<bonobo-config>
<section path="main">
<entry name="wallpaper-type" type="ulong" value="2"/>
<entry name="color1">
<any>
<type name="Color" repo_id="IDL:Bonobo/Config/Color:1.0" tckind="15" length="0" sub_parts="4">
<subnames>
<name>r</name>
<name>g</name>
<name>b</name>
<name>a</name>
</subnames>
<subtypes>
<type tckind="7" length="0" sub_parts="0"/>
<type tckind="7" length="0" sub_parts="0"/>
<type tckind="7" length="0" sub_parts="0"/>
<type tckind="7" length="0" sub_parts="0"/>
</subtypes>
</type>
<value>
<value>0</value>
<value>0.0117189</value>
<value>0.156252</value>
<value>0</value>
</value>
</any>
</entry>
<entry name="color2">
<any>
<type name="Color" repo_id="IDL:Bonobo/Config/Color:1.0" tckind="15" length="0" sub_parts="4">
<subnames>
<name>r</name>
<name>g</name>
<name>b</name>
<name>a</name>
</subnames>
<subtypes>
<type tckind="7" length="0" sub_parts="0"/>
<type tckind="7" length="0" sub_parts="0"/>
<type tckind="7" length="0" sub_parts="0"/>
<type tckind="7" length="0" sub_parts="0"/>
</subtypes>
</type>
<value>
<value>0.00781262</value>
<value>0</value>
<value>0.996109</value>
<value>0</value>
</value>
</any>
</entry>
<entry name="orientation" type="ulong" value="1"/>
<entry name="wallpaper_filename">
<any>
<type name="FileName" repo_id="IDL:Bonobo/Config/FileName:1.0" tckind="21" length="0" sub_parts="1">
<subtypes>
<type tckind="18" length="0" sub_parts="0"/>
</subtypes>
</type>
<value>
<value>/usr/share/pixmaps/backgrounds/ximian/bluestripe.jpeg</value>
</value>
</any>
</entry>
<entry name="opacity" type="long" value="100"/>
<entry name="enabled" type="boolean" value="true"/>
<entry name="wallpaper_enabled" type="boolean" value="true"/>
<entry name="show-more-options" type="boolean" value="true"/>
</section>
</bonobo-config>

View File

@@ -1,8 +0,0 @@
[Desktop Entry]
_Name=Background
_Comment=Change the desktop background
Exec=gnome-background-properties
Icon=background-capplet.png
Terminal=0
Type=Application
Categories=Settings;Appearance;

View File

@@ -1,314 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* main.c
* Copyright (C) 2000 Helix Code, 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 <gtk/gtk.h>
#include <gnome.h>
#include <libgnomeui/gnome-window-icon.h>
#include <tree.h>
#include <parser.h>
#include <fcntl.h>
#include <glade/glade.h>
#include <capplet-widget.h>
#ifdef HAVE_XIMIAN_ARCHIVER
# include <ximian-archiver/archive.h>
# include <ximian-archiver/location.h>
#endif /* HAVE_XIMIAN_ARCHIVER */
#include "preferences.h"
#include "prefs-widget.h"
static Preferences *prefs;
static Preferences *old_prefs;
static PrefsWidget *prefs_widget;
static guint ok_handler_id;
static guint cancel_handler_id;
#ifdef HAVE_XIMIAN_ARCHIVER
static Archive *archive;
static gboolean outside_location;
static void
store_archive_data (void)
{
Location *location;
xmlDocPtr xml_doc;
if (capplet_get_location () == NULL)
location = archive_get_current_location (archive);
else
location = archive_get_location (archive,
capplet_get_location ());
xml_doc = preferences_write_xml (prefs);
location_store_xml (location, "background-properties-capplet",
xml_doc, STORE_MASK_PREVIOUS);
xmlFreeDoc (xml_doc);
archive_close (archive);
}
#endif /* HAVE_XIMIAN_ARCHIVER */
static void
ok_cb (GtkWidget *widget)
{
#ifdef HAVE_XIMIAN_ARCHIVER
if (!outside_location) {
preferences_save (prefs);
preferences_apply_now (prefs);
}
#else /* !HAVE_XIMIAN_ARCHIVER */
preferences_save (prefs);
preferences_apply_now (prefs);
#endif /* HAVE_XIMIAN_ARCHIVER */
gtk_signal_disconnect (GTK_OBJECT (prefs_widget), ok_handler_id);
gtk_signal_disconnect (GTK_OBJECT (prefs_widget), cancel_handler_id);
gtk_object_destroy (GTK_OBJECT (prefs_widget));
#ifdef HAVE_XIMIAN_ARCHIVER
store_archive_data ();
#endif /* HAVE_XIMIAN_ARCHIVER */
}
static void
cancel_cb (GtkWidget *widget)
{
#ifdef HAVE_XIMIAN_ARCHIVER
if (!outside_location) {
preferences_save (old_prefs);
preferences_apply_now (old_prefs);
}
#else /* !HAVE_XIMIAN_ARCHIVER */
preferences_save (prefs);
preferences_apply_now (prefs);
#endif /* HAVE_XIMIAN_ARCHIVER */
gtk_signal_disconnect (GTK_OBJECT (prefs_widget), ok_handler_id);
gtk_signal_disconnect (GTK_OBJECT (prefs_widget), cancel_handler_id);
gtk_object_destroy (GTK_OBJECT (prefs_widget));
}
static void
setup_capplet_widget (void)
{
preferences_freeze (prefs);
prefs_widget = PREFS_WIDGET (prefs_widget_new (prefs));
ok_handler_id =
gtk_signal_connect (GTK_OBJECT (prefs_widget), "ok",
GTK_SIGNAL_FUNC (ok_cb), NULL);
cancel_handler_id =
gtk_signal_connect (GTK_OBJECT (prefs_widget), "cancel",
GTK_SIGNAL_FUNC (cancel_cb), NULL);
gtk_widget_show_all (GTK_WIDGET (prefs_widget));
preferences_thaw (prefs);
}
#ifdef HAVE_XIMIAN_ARCHIVER
static void
do_get_xml (void)
{
Preferences *prefs;
xmlDocPtr doc;
prefs = PREFERENCES (preferences_new ());
preferences_load (prefs);
doc = preferences_write_xml (prefs);
xmlDocDump (stdout, doc);
gtk_object_destroy (GTK_OBJECT (prefs));
}
static void
do_set_xml (gboolean apply_settings)
{
xmlDocPtr doc;
char buffer[16384];
GString *doc_str;
int t = 0;
fflush (stdin);
fcntl (fileno (stdin), F_SETFL, 0);
doc_str = g_string_new ("");
while ((t = read (fileno (stdin), buffer, sizeof (buffer) - 1)) != 0) {
buffer[t] = '\0';
g_string_append (doc_str, buffer);
}
if (doc_str->len > 0) {
doc = xmlParseDoc (doc_str->str);
g_string_free (doc_str, TRUE);
if (doc != NULL) {
prefs = preferences_read_xml (doc);
if (prefs != NULL) {
if (apply_settings) {
preferences_save (prefs);
preferences_apply_now (prefs);
}
return;
}
else if (prefs != NULL) {
return;
}
xmlFreeDoc (doc);
}
} else {
g_critical ("No data to apply");
}
return;
}
#endif /* HAVE_XIMIAN_ARCHIVER */
static void
do_restore_from_defaults (void)
{
prefs = PREFERENCES (preferences_new ());
preferences_save (prefs);
preferences_apply_now (prefs);
}
int
main (int argc, char **argv)
{
GnomeClient *client;
GnomeClientFlags flags;
gint token, res;
gchar *restart_args[3];
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
glade_gnome_init ();
res = gnome_capplet_init ("background-properties-capplet",
VERSION, argc, argv, NULL,
0, NULL);
if (res < 0) {
g_error ("Could not initialize the capplet.");
}
else if (res == 3) {
#ifdef HAVE_XIMIAN_ARCHIVER
do_get_xml ();
#endif /* HAVE_XIMIAN_ARCHIVER */
return 0;
}
else if (res == 4) {
#ifdef HAVE_XIMIAN_ARCHIVER
do_set_xml (TRUE);
#endif /* HAVE_XIMIAN_ARCHIVER */
return 0;
}
else if (res == 5) {
do_restore_from_defaults ();
return 0;
}
client = gnome_master_client ();
flags = gnome_client_get_flags (client);
if (flags & GNOME_CLIENT_IS_CONNECTED) {
token = gnome_startup_acquire_token
("GNOME_BACKGROUND_PROPERTIES",
gnome_client_get_id (client));
if (token) {
gnome_client_set_priority (client, 20);
gnome_client_set_restart_style (client,
GNOME_RESTART_ANYWAY);
restart_args[0] = argv[0];
restart_args[1] = "--init-session-settings";
restart_args[2] = NULL;
gnome_client_set_restart_command (client, 2,
restart_args);
} else {
gnome_client_set_restart_style (client,
GNOME_RESTART_NEVER);
}
} else {
token = 1;
}
gnome_window_icon_set_default_from_file
(GNOMECC_ICONS_DIR"/gnome-ccbackground.png");
#ifdef HAVE_XIMIAN_ARCHIVER
archive = ARCHIVE (archive_load (FALSE));
if (capplet_get_location () != NULL &&
strcmp (capplet_get_location (),
archive_get_current_location_id (archive)))
{
outside_location = TRUE;
do_set_xml (FALSE);
if (prefs == NULL) return -1;
preferences_freeze (prefs);
} else {
outside_location = FALSE;
prefs = PREFERENCES (preferences_new ());
preferences_load (prefs);
}
if (!outside_location && (token || res == 1)) {
preferences_apply_now (prefs);
}
#else /* !HAVE_XIMIAN_ARCHIVER */
prefs = PREFERENCES (preferences_new ());
preferences_load (prefs);
if (token || res == 1)
preferences_apply_now (prefs);
#endif /* HAVE_XIMIAN_ARCHIVER */
if (!res) {
old_prefs = PREFERENCES (preferences_clone (prefs));
setup_capplet_widget ();
capplet_gtk_main ();
}
return 0;
}

View File

@@ -1,4 +0,0 @@
Makefile
Makefile.in
.deps
stamp-h.in

View File

@@ -1,21 +0,0 @@
<oaf_info>
<oaf_server iid="OAFIID:Bonobo_@SHORT_CAPPLET_NAME@_properties_Factory" type="exe"
location="@BINDIR@/@CAPPLET_BINARY_NAME@">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/ObjectFactory:1.0"/>
</oaf_attribute>
<oaf_attribute name="name" type="string" value="@SHORT_CAPPLET_NAME@ properties capplet factory"/>
</oaf_server>
<oaf_server iid="OAFIID:Bonobo_Control_Capplet_@SHORT_CAPPLET_NAME@_properties" type="factory"
location="OAFIID:Bonobo_@SHORT_CAPPLET_NAME@_properties_Factory">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/PropertyControl:1.0"/>
<item value="IDL:Bonobo/Unknown:1.0"/>
</oaf_attribute>
<oaf_attribute name="name" type="string" value="@SHORT_CAPPLET_NAME@ capplet"/>
</oaf_server>
</oaf_info>

View File

@@ -1,498 +0,0 @@
2002-06-21 Stephen Browne <stephen.browne@sun.com>
* wm-common.[ch] : added new files to expose
wm_common_get_current_window_manager and
wm_common_register_window_manager_change
2002-06-13 Jody Goldberg <jody@gnome.org>
* capplet-util.c (capplet_help) : Use the new utility.
(capplet_error_dialog) : split out into a new utility.
2002-06-17 Jody Goldberg <jody@gnome.org>
* Release 2.0.0
2002-05-28 Satyajit Kanungo <satyajit.kanungo@wipro.com>
* capplet-util.c : capplet_help () The Help directory is changed to
user-guide.
2002-05-26 Jody Goldberg <jody@gnome.org>
* capplet-util.c (capplet_help) : new utility.
2002-05-16 jacob berkman <jacob@ximian.com>
* gconf-property-editor.c (peditor_image_set_filename): if we
haven't been initting, don't pop up an error message. if we are,
set our image to GTK_STOCK_MISSING_IMAGE. fixes bug exposed by
fix for #76993
Tue May 14 12:08:17 2002 Jonathan Blandford <jrb@redhat.com>
* theme-common.c (theme_common_init): confirm that the ~/.themes/
directory exists.
2002-04-29 Rachel Hestilow <hestilow@ximian.com>
* file-transfer-dialog.c (file_transfer_dialog_update_cb):
Set dialog title to current phase.
2002-04-29 Rachel Hestilow <hestilow@ximian.com>
* file-transfer-dialog.[ch]: Added.
* Makefile.am: Compile file-transfer-dialog.[ch].
2002-04-19 Mark McLoughlin <mark@skynet.ie>
* gconf-property-editor.[ch]: (peditor_integer_value_changed),
(peditor_integer_widget_changed), (gconf_peditor_new_integer_valist),
(gconf_peditor_new_integer): implement GtkEntry based integer
peditor.
2002-04-21 Rachel Hestilow <hestilow@ximian.com>
* gconf-property-editor.c
(gconf_peditor_new_select_menu_with_enum,
gconf_peditor_new_enum_toggle,
gconf_peditor_new_select_radio_with_enum): Add in an explicit
'use_nick' parameter. Implicit guessing can break badly if
the gconf data gets corrupted.
(peditor_enum_int_from_string): Change use_nick to copy-by-value,
do not try to guess it.
(peditor_enum_conv_to_widget, guard_get_bool,
peditor_enum_toggle_conv_to_widget): Do not pass in use_nick
as a reference.
Thu Apr 18 17:56:25 2002 Jonathan Blandford <jrb@redhat.com>
* theme-common.c: Notify when the theme changes.
2002-04-18 Jody Goldberg <jody@gnome.org>
* activate-settings-daemon.c (static) : message dialogs must have
separators.
2002-04-10 Rachel Hestilow <hestilow@ximian.com>
* gconf-proprerty-editor.h: Add FontType enum, and a font_type
parameter to gconf_peditor_new_font.
* gconf-property-editor.c:
(peditor_font_value_changed): Call peditor_font_merge_setting
instead of setting the properties explicitly.
(peditor_font_widget_changed): Switch on font_type to determine
what to set for a GConfValue.
2002-03-28 Richard Hestilow <hestilow@ximian.com>
* gconf-property-editor.c (peditor_image_clicked_cb): Set
fsel to modal, it seems to fix a weird grabbing bug.
2003-03-26 Kjartan Maraas <kmaraas@gnome.org>
* activate-settings-daemon.c: Fix a string.
2002-03-25 Lauris Kaplinski <lauris@ximian.com>
* gconf-property-editor.c (gconf_peditor_widget_set_guard): Test for NULL
gconf value
2002-03-19 Richard Hestilow <hestilow@ximian.com>
* Makefile.am: Include libbackground (used for preview-file-selector).
Change into a libtool library so we can link against libbackground.
* gconf-property-editor.c:
(peditor_enum_int_from_string): Added argument use_nick; set to true
if the string was a nick.
(peditor_enum_string_from_int): Use nick only if use_nick is true.
(gconf_peditor_new_image): Added.
(gconf_peditor_new_select_radio_with_enum): Added.
(peditor_select_radio_value_changed): Reverse radio group.
(peditor_select_radio_widget_changed): Reverse radio group.
2002-03-17 Kjartan Maraas <kmaraas@gnome.org>
* activate-settings-daemon.c: Mark a string. #include <config.h>
2002-03-17 Jonathan Blandford <set EMAIL_ADDRESS environment variable>
reviewed by: <delete if not using a buddy>
* Makefile.am:
* theme-common.c: (themes_common_list_add_dir),
(theme_common_get_list), (theme_common_list_free):
* theme-common.h:
2002-03-14 Richard Hestilow <hestilow@ximian.com>
* gconf-property-editor.c:
(gconf_property_editor_new_option_menu_with_enum):
(gconf_property_editor_new_enum_toggle): Added.
(gconf_property_editor_new): Accept custom arguments from the
editor "subclass".
(gconf_property_editor_class_init): Add arguments "data"
and "data-free-cb", for custom "subclass" data.
(gconf_property_editor_finalize): Free custom data.
(*_new): Add NULL at the end of gconf_property_editor_new.
(guard_value_changed, peditor_widget_set_guard): Use the
enum->boolean mapping if the gconf value is a string.
2002-03-10 Seth Nickell <snickell@stanford.edu>
* Makefile.am:
* activate-settings-daemon.c: (popup_error_message),
(activate_settings_daemon):
* activate-settings-daemon.h:
Add new client interface for activating the settings daemon
if its not already running.
2002-02-27 Kjartan Maraas <kmaraas@gnome.org>
* capplet-util.c: s/PACKAGE/GETTEXT_PACKAGE/g
2002-02-12 Lauris Kaplinski <lauris@ximian.com>
* gconf-property-editor.c (peditor_font_value_changed): Kill warning
2002-02-10 Richard Hestilow <hestilow@ximian.com>
* gconf-property-editor.[ch]: Added font editor.
Sun Jan 6 02:52:59 2002 Jonathan Blandford <jrb@redhat.com>
* gconf-property-editor.c (peditor_select_radio_widget_changed):
avoid recursive loops by only setting the UI if we're active.
2002-01-05 Bradford Hovinen <hovinen@ximian.com>
* gconf-property-editor.c (peditor_*_value_changed): Only remove
from changeset if the changeset is non-NULL
2002-01-04 Bradford Hovinen <hovinen@ximian.com>
* gconf-property-editor.c (peditor_set_gconf_value):
Implement. Sets the GConf value either in the changeset, or if
changeset is NULL, directly
(peditor_*_widget_changed): Use peditor_set_gconf_value
(gconf_peditor_new_*): Don't complain if changeset is NULL
2001-12-20 Bradford Hovinen <hovinen@ximian.com>
* gconf-property-editor.c: Eliminate compiler warnings
* capplet-util.c: Eliminate compiler warnings
* gconf-property-editor.c (gconf_peditor_new): Fold the callback
back in; accept variable argument list with extra parameters
(gconf_peditor_new_filename): Return the property editor
(gconf_peditor_new_string_valist): Split this out
(gconf_peditor_new_string): Call _valist variant
(gconf_peditor_new*): Update
2001-12-19 Bradford Hovinen <hovinen@ximian.com>
* gconf-property-editor.c (gconf_peditor_new_float_range)
(gconf_peditor_new_int_range): Connect to value_changed signal Add
properties conv-{to|from}-widget-cb and use those for conversion
of values to and from the widget
(peditor_{int|float}_range_value_changed, friends): Combine into
peditor_numeric_*
(gconf_peditor_new): Implement. Factor out some common code from
the various type-specific constructors
(peditor_*_value_changed): Don't check if the value is the same as
what is already in the widget; it's not very important
(peditor_*_value_changed): Remove the key from the changeset
(gconf_peditor_new_*): Add g_return_val_if_fail macros
(gconf_peditor_widget_set_guard): Add g_return_if_fail macros
(gconf_value_float_to_int, gconf_value_int_to_float): Implement
(gconf_property_editor_set_prop): Store the callback in the
property editor proper
(gconf_peditor_new): Put initialization code in an idle handler
(peditor_string_value_changed): Free the value created from
conversion
(init_widget_cb): Return FALSE
(peditor_*_widget_changed): Just return if we are not fully
initialized
(init_widget_cb): Set initialized flag
(struct _GConfPropertyEditorPrivate): Add inited
* gconf-property-editor.c: Add ui-control property storing the
object (normally a widget) that controls the property; remove
object property and replace its function with ui-control
* capplet-util.c: Comment out most of this file
* gconf-property-editor.c (gconf_peditor_new_int_range): Convert
to ~_float_range
(gconf_peditor_new_float_range): Add callbacks for conversion
between widget's values and GConf values in the signature
(peditor_float_range_widget_changed): Issue callback, if
available, to convert from widget's values to GConf values
(peditor_float_range_value_changed): Vice verca above
(gconf_peditor_new_int_range, peditor_int_range_widget_changed)
(peditor_int_range_value_changed): Implement. Copy from float
versions
2001-12-18 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.h: Don't #include bonobo*.h
* gconf-property-editor.c (peditor_string_widget_changed): Use
actual signature for the changed signal Use gconf_client rather
than gconf_engine
(gconf_property_editor_set_prop): Use weak_ref rather than destroy
signal
(peditor_int_range_value_changed)
(peditor_int_range_widget_changed, gconf_peditor_new_int_range):
Implement
2001-12-17 Bradford Hovinen <hovinen@ximian.com>
* gconf-property-editor.c (peditor_color_value_changed): Use a
local stack variable for the color rather than a pointer. Duh.
(peditor_select_menu_widget_changed): Use
gtk_option_menu_get_history
(peditor_select_menu_widget_changed): Accept option_menu as
parameter
(gconf_peditor_new_select_menu): Connect changed signal rather
than activate signal on the menu items
(gconf_property_editor_get_key): Implement
(peditor_color_widget_changed): Use correct signature for the
signal handler
(peditor_select_menu_value_changed): Use
gtk_option_menu_set_history
(guard_value_changed, gconf_peditor_widget_set_guard): Implement
(peditor_string_widget_changed): Work correctly with multiple
callback signatures
(gconf_peditor_new_string): Use changed signal
2001-12-08 Bradford Hovinen <hovinen@ximian.com>
* gconf-property-editor.c (peditor_*_widget_changed): Don't call
gconf_value_free
2001-12-07 Bradford Hovinen <hovinen@ximian.com>
* gconf-property-editor.c (gconf_property_editor_class_init): Use
correct ordering of setup
(gconf_peditor_new_*): Terminate the parameter list passed to
g_object_new with NULL
(gconf_property_editor_class_init): Make the changeset property a
pointer
(gconf_property_editor_set_prop): Use g_value_get_object for the
destroy notify object
(peditor_*_value_changed): Make sure value is non-NULL
2001-11-03 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am (libcommon_a_SOURCES): Added gconf-property-editor.[ch]
2001-10-27 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (get_default_moniker): Switch to gconf: moniker
(capplet_init): Remove legacy file hack
2001-10-18 Bradford Hovinen <hovinen@ximian.com>
* Bonobo_Control_Capplet_generic.oaf.in: Update listener name
* capplet-util.c (create_control_cb): Use correct prefix for listener
2001-10-12 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (get_factory_name): Updated factory name to
reflect new, expanded roles
* Bonobo_Control_Capplet_generic.oaf.in: Create
2001-09-29 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (create_control_cb): Elimite reference counter --
it's not necessary
(create_control_cb): Make this a multi-factory so that we can
return the listener when needed
(capplet_init): Set up the listener here rather than in
get_control_cb; also remove the listener and unref the database
here
(quit_cb, real_quit_cb): Remove (thank the gods)
2001-09-28 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (get_default_moniker): Remove -control from the
end of the string as well as -capplet
(get_factory_name): Ditto
(get_property_name): Ditto
2001-09-24 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (legacy_is_modified): Improved error checking and
cleaned up the logic a bit
2001-09-14 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (set_moniker_cb): Don't call setup_cb after the
first time
2001-09-03 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (set_moniker_cb): Free the full moniker to
correct memory leak
(set_moniker_cb): Disconnect old signal handler
2001-08-20 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (get_default_moniker): Update moniker being used
2001-07-30 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (capplet_init): Don't sync if we need legacy
values
(capplet_init): Call setup_session_mgmt if --apply or
--init-session-settings was passed
2001-07-27 Bradford Hovinen <hovinen@ximian.com>
* RELEASE : 1.5.2
2001-07-26 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (capplet_init): Don't sync the database if
retrieving legacy setings before creating the factory
(create_control_cb): Create the config database ourselves
(pf_destroy_cb): Remove evil hackery
(get_control_cb): Ditto
(create_control_cb): Support multiple property control objects --
use a GtkObject called ref_obj to make sure the program quits when
there are no such objects left
(capplet_init): Pass default_moniker to factory callback;
release_unref the db ourselves
(get_control_cb): Support multiple controls; soak in global
control and widget variables
(legacy_is_modified): Remember to unref the property bag
(quit_cb): Allow being called more than once
(quit_cb): Unref ref_obj here
(create_control_cb): Eliminate second signal connection
(real_quit_cb): Free the pair structure
(all_done_cb): Implement. Just add gtk_main_quit to the idle
handler list
(create_control_cb): Connect destroy signal of ref_obj to
all_done_cb
2001-07-24 Richard Hestilow <hestilow@ximian.com>
* capplet-util.c (get_control_cb): Set control data on PropertyFrame
as part of evil hack.
(quit_cb): Work if called multiple times...also evil.
(pf_destroy_cb): unref the control...evil evil evil.
2001-07-24 Richard Hestilow <hestilow@ximian.com>
* capplet-util.c: Remove debugging cruft.
(capplet_init): Check for legacy with --init-session-settings too.
2001-07-24 Richard Hestilow <hestilow@ximian.com>
* capplet-util.[ch] (capplet_init): New argument of legacy files to
check for changes.
* capplet-util.c (legacy_is_modified): New function that checks
a legacy file against the archiver modification date.
(capplet_init): Pass legacy_files to legacy_is_modified, and sync
our database with the legacy one if one has been.
2001-07-24 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (real_quit_cb): Reenable disabled code
(quit_cb): Put the db an id objects in a pair structure and pass
that to the callback
(real_quit_cb): Extract the db and id objects from the pair
(create_control_cb): Set up listener for sync event rather than
change event
2001-07-23 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (set_moniker_cb): Set InvalidValue exception if
the program could not resolve the moniker
2001-07-20 Chema Celorio <chema@celorio.com>
* RELEASE : 1.5.0
2001-07-19 Richard Hestilow <hestilow@ximian.com>
* capplet-util.c (quit_cb): Add an idle handler to call the real
quit cb.
(real_quit_cb): Added, it is what quit_cb used to be.
2001-07-19 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (create_control_cb): Use a static variable for
the control and return NULL if the control was already created
2001-07-18 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (create_control_cb): Store listener id in
property control
(quit_cb): Remove listener before releasing database
(set_moniker_cb): Kill any existing db object in case the moniker
is set more than once
(set_moniker_cb): Connect destroy signal on pf to pf_destroy_cb
(pf_destroy_cb): Implement
2001-07-18 Richard Hestilow <hestilow@ximian.com>
* capplet-util.[ch]: Revert my last proxy-related change.
2001-07-18 Richard Hestilow <hestilow@ximian.com>
* capplet-util.h (CreateDialogFn): Add a PropertyBag argument so
capplet authors can hook up to the proxy.
* capplet-util.c (get_control_cb): Pass the proxy bag to setup_cb.
(capplet_init): Don't free default_moniker until after we print it.
2001-07-17 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (capplet_init): Support --init-session-settings
for compatibility reasons
(setup_session_mgmt): Implement. Make sure capplet runs the next
time the user logs in
(capplet_init): Call setup_session_mgmt for --get-legacy and
standard execution
(get_property_name): Implement. Return the property name
associated with the capplet
(set_moniker_cb): Use GTK_BIN (pf)->child rather than
bonobo_control_get_widget
(get_control_cb): Destroy the property control when the control or
the widget are destroyed
(quit_cb): Implement
(create_control_cb): Connect destroy signal of property control to
quit_cb
(get_factory_name):
(get_default_moniker):
(get_property_name): Use correct names when the full path was
specified for the executable
* Makefile.am (INCLUDES): Removed -DGLADE_DATADIR
* capplet-util.c (create_dialog_cb): Use create_widget_cb rather
than loading from Glade
(capplet_init): Accept CreateDialogFn and initialize
create_dialog_cb
(close_cb): Don't call gtk_object_destroy (dialog)
(get_control_cb): Rename from create_dialog_cb
2001-07-14 Carlos Perelló Marín <carlos@gnome-db.org>
* .cvsignore: ssshhhh
2001-07-13 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (create_dialog_cb): Return NULL in the case that
the control is already present

View File

@@ -1,23 +0,0 @@
EXTRA_DIST = ChangeLog wrapper-script.in Bonobo_Control_Capplet_generic.oaf.in
INCLUDES = \
-DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-DGNOME_ICONDIR=\""${prefix}/share/pixmaps"\" \
-DG_LOG_DOMAIN=\"capplet-common\" \
-I$(top_srcdir)/ \
-I$(top_srcdir)/libbackground \
@VFS_CAPPLET_CFLAGS@
noinst_LTLIBRARIES = libcommon.la
libcommon_la_SOURCES = \
activate-settings-daemon.c activate-settings-daemon.h \
capplet-util.c capplet-util.h \
gconf-property-editor.c gconf-property-editor.h \
gconf-property-editor-marshal.c gconf-property-editor-marshal.h \
file-transfer-dialog.c file-transfer-dialog.h \
theme-common.c theme-common.h \
wm-common.c wm-common.h
libcommon_la_LIBADD = $(top_builddir)/libbackground/libbackground.la

View File

@@ -1,58 +0,0 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <libbonobo.h>
#include <gtk/gtk.h>
#include "activate-settings-daemon.h"
/*#include "GNOME_SettingsDaemon.h"*/
static void popup_error_message ()
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING,
GTK_BUTTONS_OK, _("Unable to start the settings manager 'gnome-settings-daemon'.\n"
"Without the GNOME settings manager running, some preferences may not take effect. This could "
"indicate a problem with Bonobo, or a non-GNOME (e.g. KDE) settings manager may already "
"be active and conflicting with the GNOME settings manager."));
gtk_widget_show (dialog);
gtk_widget_destroy (dialog);
}
/* Returns FALSE if activation failed, else TRUE */
gboolean
activate_settings_daemon (void)
{
CORBA_Environment ev;
CORBA_Object object;
/*GNOME_SettingsDaemon corba_foo;*/
bonobo_init (NULL, NULL);
CORBA_exception_init (&ev);
object = bonobo_activation_activate_from_id ("OAFIID:GNOME_SettingsDaemon",
0, NULL, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
popup_error_message ();
return FALSE;
}
if (object == CORBA_OBJECT_NIL) {
popup_error_message ();
return FALSE;
}
/*bool = GNOME_SettingsDaemon_awake (corba_foo, "MyService", &ev);
printf ("bool is %d\n", bool);*/
return TRUE;
}

View File

@@ -1,9 +0,0 @@
#ifndef ACTIVATE_SETINGS_DAEMON
#define ACTIVATE_SETINGS_DAEMON
#include <glib.h>
/* Returns FALSE if activation failed, else TRUE */
gboolean activate_settings_daemon (void);
#endif

View File

@@ -1,70 +0,0 @@
#include <bonobo-conf/bonobo-property-editor.h>
#include <gtk/gtkrange.h>
#include <gtk/gtksignal.h>
#include <bonobo.h>
static void
changed_cb (GtkAdjustment *adj, BonoboPEditor *editor)
{
CORBA_Environment ev;
DynamicAny_DynAny dyn;
BonoboArg *arg;
gulong val;
CORBA_exception_init (&ev);
val = adj->value;
dyn = CORBA_ORB_create_basic_dyn_any (bonobo_orb (), TC_ulong, &ev);
DynamicAny_DynAny_insert_ulong (dyn, val, &ev);
if (BONOBO_EX (&ev) || dyn == NULL)
return;
arg = DynamicAny_DynAny_to_any (dyn, &ev);
bonobo_peditor_set_value (editor, arg, &ev);
bonobo_arg_release (arg);
CORBA_Object_release ((CORBA_Object) dyn, &ev);
CORBA_exception_free (&ev);
}
static void
adj_set_value_cb (BonoboPEditor *editor,
BonoboArg *value,
CORBA_Environment *ev)
{
GtkAdjustment *adj;
gulong v;
adj = gtk_range_get_adjustment (GTK_RANGE (bonobo_peditor_get_widget (editor)));
if (!bonobo_arg_type_is_equal (value->_type, TC_ulong, NULL))
return;
v = BONOBO_ARG_GET_GENERAL (value, TC_ulong, CORBA_unsigned_long, NULL);
gtk_signal_handler_block_by_func (GTK_OBJECT (adj), changed_cb,
editor);
gtk_adjustment_set_value (adj, v);
gtk_signal_handler_unblock_by_func (GTK_OBJECT (adj), changed_cb,
editor);
}
GtkObject* bonobo_peditor_range_construct (GtkWidget *widget)
{
BonoboPEditor *editor;
GtkAdjustment *adj;
g_return_val_if_fail (widget != NULL, NULL);
g_return_val_if_fail (GTK_IS_RANGE (widget), NULL);
editor = bonobo_peditor_construct (widget, adj_set_value_cb, TC_ulong);
adj = gtk_range_get_adjustment (GTK_RANGE (widget));
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
GTK_SIGNAL_FUNC (changed_cb), editor);
return GTK_OBJECT (editor);
}

View File

@@ -1,8 +0,0 @@
#ifndef __BONOBO_PROPERTY_RANGE_SCALE_H__
#define __BONOBO_PROPERTY_RANGE_SCALE_H__
#include <gtk/gtkwidget.h>
GtkObject* bonobo_peditor_range_construct (GtkWidget *widget);
#endif /* __BONOBO_PROPERTY_RANGE_SCALE_H__ */

View File

@@ -1,341 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* capplet-util.c
* 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <ctype.h>
/* For stat */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "capplet-util.h"
#if 0
/* apply_cb
*
* Callback issued when the user clicks "Apply" or "Ok". This function is
* responsible for making sure the current settings are properly saved.
*/
static void
apply_cb (BonoboPropertyControl *pc, Bonobo_PropertyControl_Action action)
{
if (action == Bonobo_PropertyControl_APPLY)
gconf_engine_commit_change_set (gconf_engine_get_default (),
changeset, TRUE, NULL);
}
/* properties_changed_cb
*
* Callback issued when some setting has changed
*/
static void
properties_changed_cb (GConfEngine *engine, guint cnxn_id, GConfEntry *entry, gpointer user_data)
{
if (apply_settings_cb != NULL)
apply_settings_cb ();
}
/* get_control_cb
*
* Callback to construct the main dialog box for this capplet; invoked by Bonobo
* whenever capplet activation is requested. Returns a BonoboObject representing
* the control that encapsulates the object.
*/
static BonoboObject *
get_control_cb (BonoboPropertyControl *property_control, gint page_number)
{
BonoboControl *control;
GtkWidget *widget;
widget = create_dialog_cb ();
if (widget == NULL)
return NULL;
control = bonobo_control_new (widget);
setup_property_editors_cb (widget, changeset);
bonobo_control_set_automerge (control, TRUE);
return BONOBO_OBJECT (control);
}
/* create_control_cb
*
* Small function to create the PropertyControl and return it.
*/
static BonoboObject *
create_control_cb (BonoboGenericFactory *factory, const gchar *component_id)
{
BonoboObject *obj;
BonoboPropertyControl *property_control;
static const gchar *prefix1 = "OAFIID:Bonobo_Control_Capplet_";
g_message ("%s: Enter", G_GNUC_FUNCTION);
if (!strncmp (component_id, prefix1, strlen (prefix1))) {
property_control = bonobo_property_control_new
((BonoboPropertyControlGetControlFn) get_control_cb, 1, NULL);
g_signal_connect (G_OBJECT (property_control), "action",
G_CALLBACK (apply_cb), NULL);
obj = BONOBO_OBJECT (property_control);
} else {
g_critical ("Not creating %s", component_id);
obj = NULL;
}
return obj;
}
/* get_factory_name
*
* Construct the OAF IID of the factory from the binary name
*/
static gchar *
get_factory_name (const gchar *binary)
{
gchar *s, *tmp, *tmp1, *res;
s = g_strdup (binary);
tmp = strrchr (s, '/');
if (tmp == NULL) tmp = s;
else tmp++;
if ((tmp1 = strstr (tmp, "-control")) != NULL) *tmp1 = '\0';
if ((tmp1 = strstr (tmp, "-capplet")) != NULL) *tmp1 = '\0';
while ((tmp1 = strchr (tmp, '-')) != NULL) *tmp1 = '_';
res = g_strconcat ("OAFIID:Bonobo_", tmp, "_Factory", NULL);
g_free (s);
return res;
}
/* get_property_name
*
* Get the property name associated with this capplet
*/
static gchar *
get_property_name (const gchar *binary)
{
gchar *s, *tmp, *tmp1, *res;
s = g_strdup (binary);
tmp = strrchr (s, '/');
if (tmp == NULL) tmp = s;
else tmp++;
if ((tmp1 = strstr (tmp, "-control")) != NULL) *tmp1 = '\0';
if ((tmp1 = strstr (tmp, "-capplet")) != NULL) *tmp1 = '\0';
for (tmp1 = tmp; *tmp1 != '\0'; tmp1++) {
*tmp1 = toupper (*tmp1);
if (*tmp1 == '-') *tmp1 = '_';
}
res = g_strconcat ("GNOME_", tmp, NULL);
g_free (s);
return res;
}
#endif
/* setup_session_mgmt
*
* Make sure the capplet launches and applies its settings next time the user
* logs in
*/
void
setup_session_mgmt (const gchar *binary_name)
{
/* Disabled. I never really understood this code anyway, and I am absolutely
* unclear about how to port it to GNOME 2.0 */
#if 0
GnomeClient *client;
GnomeClientFlags flags;
gint token;
gchar *restart_args[3];
gchar *prop_name;
g_return_if_fail (binary_name != NULL);
client = gnome_master_client ();
flags = gnome_client_get_flags (client);
if (flags & GNOME_CLIENT_IS_CONNECTED) {
prop_name = get_property_name (binary_name);
token = gnome_startup_acquire_token
(prop_name, gnome_client_get_id (client));
g_free (prop_name);
if (token) {
gnome_client_set_priority (client, 20);
gnome_client_set_restart_style
(client, GNOME_RESTART_ANYWAY);
restart_args[0] = g_strdup (binary_name);
restart_args[1] = "--init-session-settings";
restart_args[2] = NULL;
gnome_client_set_restart_command
(client, 2, restart_args);
g_free (restart_args[0]);
} else {
gnome_client_set_restart_style
(client, GNOME_RESTART_NEVER);
}
}
#endif
}
#if 0
/* capplet_init -- see documentation in capplet-util.h
*/
void
capplet_init (int argc,
char **argv,
ApplySettingsFn apply_fn,
CreateDialogFn create_dialog_fn,
SetupPropertyEditorsFn setup_fn,
GetLegacySettingsFn get_legacy_fn)
{
gchar *factory_iid;
BonoboGenericFactory *factory;
static gboolean apply_only;
static gboolean get_legacy;
static struct poptOption cap_options[] = {
{ "apply", '\0', POPT_ARG_NONE, &apply_only, 0,
N_("Just apply settings and quit"), NULL },
{ "init-session-settings", '\0', POPT_ARG_NONE, &apply_only, 0,
N_("Just apply settings and quit"), NULL },
{ "get-legacy", '\0', POPT_ARG_NONE, &get_legacy, 0,
N_("Retrieve and store legacy settings"), NULL },
{ NULL, '\0', 0, NULL, 0, NULL, NULL }
};
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
gnome_program_init (argv[0], VERSION, LIBGNOMEUI_MODULE, argc, argv,
GNOME_PARAM_POPT_TABLE, cap_options,
NULL);
if (!bonobo_init (&argc, argv))
g_error ("Cannot initialize bonobo");
if (apply_only && apply_fn != NULL) {
setup_session_mgmt (argv[0]);
apply_fn ();
}
else if (get_legacy && get_legacy_fn != NULL) {
setup_session_mgmt (argv[0]);
get_legacy_fn ();
} else {
setup_session_mgmt (argv[0]);
create_dialog_cb = create_dialog_fn;
apply_settings_cb = apply_fn;
setup_property_editors_cb = setup_fn;
factory_iid = get_factory_name (argv[0]);
factory = bonobo_generic_factory_new
(factory_iid, (BonoboFactoryCallback) create_control_cb, NULL);
g_free (factory_iid);
bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));
changeset = gconf_change_set_new ();
bonobo_main ();
gconf_change_set_unref (changeset);
}
}
#endif
/**
* capplet_error_dialog :
*
* @parent :
* @msg : already translated.
* @err :
*
*/
void
capplet_error_dialog (GtkWindow *parent, char const *msg, GError *err)
{
if (err != NULL) {
GtkWidget *dialog;
dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
msg, err->message);
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_error_free (err);
}
}
/**
* capplet_help :
* @parent :
* @helpfile :
* @section :
*
* A quick utility routine to display help for capplets, and handle errors in a
* Havoc happy way.
**/
void
capplet_help (GtkWindow *parent, char const *helpfile, char const *section)
{
GError *error = NULL;
g_return_if_fail (helpfile != NULL);
g_return_if_fail (section != NULL);
gnome_help_display_desktop (NULL,
"user-guide",
helpfile, section, &error);
if (error != NULL)
capplet_error_dialog (parent,
_("There was an error displaying help: %s"),
error);
}

View File

@@ -1,96 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* capplet-util.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 __CAPPLET_UTIL_H
#define __CAPPLET_UTIL_H
#include <gnome.h>
#include <gconf/gconf.h>
#include <gconf/gconf-changeset.h>
/* Macros to make certain repetitive tasks a bit easier */
/* Print a debugging message */
#define DEBUG_MSG(str, ...) \
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "(%d:%s) " str, \
getpid (), G_GNUC_FUNCTION, __VA_ARGS__)
/* Retrieve a widget from the Glade object */
#define WID(s) glade_xml_get_widget (dialog, s)
/* Copy a setting from the legacy gnome-config settings to the ConfigDatabase */
#define COPY_FROM_LEGACY(type, key, legacy_key) \
val_##type = gnome_config_get_##type##_with_default (legacy_key, &def); \
\
if (!def) \
gconf_client_set_##type (client, key, val_##type, NULL);
/* Callback to apply the settings in the given database */
typedef void (*ApplySettingsFn) (void);
/* Callback to set up the dialog proper */
typedef GtkWidget *(*CreateDialogFn) (void);
/* Callback to set up property editors for the dialog */
typedef void (*SetupPropertyEditorsFn) (GtkWidget *dialog, GConfChangeSet *changeset);
/* Callback to retrieve legacy settings and store them in the new configuration
* database */
typedef void (*GetLegacySettingsFn) (void);
/* Set up the session management so that this capplet will apply its
* settings on every startup
*/
void setup_session_mgmt (const gchar *binary_name);
/* Wrapper function for the entire capplet. This handles all initialization and
* runs the capplet for you. Just supply the appropriate callbacks and your argc
* and argv from main()
*
* This function makes several assumptions, requiring that all capplets follow a
* particular convention. In particular, suppose the name of the capplet binary
* is foo-properties-capplet. Then:
*
* - The factory IID is Bonobo_Control_Capplet_foo_properties_Factory
* - The default configuration moniker is archiver:foo-properties
*
* Following this convention yields capplets that are more uniform and thus
* easier to maintain, and simplifies the interfaces quite a bit. All capplet in
* this package are required to follow this convention.
*/
void capplet_init (int argc,
gchar **argv,
ApplySettingsFn apply_fn,
CreateDialogFn create_dialog_fn,
SetupPropertyEditorsFn setup_property_editors_fn,
GetLegacySettingsFn get_legacy_settings_fn);
void capplet_error_dialog (GtkWindow *parent, char const *msg, GError *err);
void capplet_help (GtkWindow *parent, char const *helpfile, char const *section);
#endif /* __CAPPLET_UTIL_H */

View File

@@ -1,420 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* file-transfer-dialog.c
* Copyright (C) 2002 Ximian, Inc.
*
* Written by Rachel Hestilow <hestilow@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 "file-transfer-dialog.h"
#include <libgnomevfs/gnome-vfs-async-ops.h>
#include <libgnome/libgnome.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkprogressbar.h>
#include <gtk/gtkstock.h>
#include <limits.h>
enum
{
PROP_0,
PROP_FROM_URI,
PROP_TO_URI,
PROP_FRACTION_COMPLETE,
PROP_NTH_URI,
PROP_TOTAL_URIS
};
enum
{
CANCEL,
DONE,
LAST_SIGNAL
};
guint file_transfer_dialog_signals[LAST_SIGNAL] = {0, };
struct _FileTransferDialogPrivate
{
GtkWidget *progress;
GtkWidget *status;
GtkWidget *num_files;
GtkWidget *current;
GtkWidget *from;
GtkWidget *to;
guint nth;
guint total;
GnomeVFSAsyncHandle *handle;
};
static GObjectClass *parent_class;
static void
file_transfer_dialog_cancel (FileTransferDialog *dlg)
{
if (dlg->priv->handle)
{
gnome_vfs_async_cancel (dlg->priv->handle);
dlg->priv->handle = NULL;
}
}
static void
file_transfer_dialog_finalize (GObject *obj)
{
FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (obj);
g_free (dlg->priv);
if (parent_class->finalize)
parent_class->finalize (G_OBJECT (dlg));
}
static void
file_transfer_dialog_update_num_files (FileTransferDialog *dlg)
{
gchar *str = g_strdup_printf (_("%i of %i"),
dlg->priv->nth, dlg->priv->total);
gtk_label_set_text (GTK_LABEL (dlg->priv->num_files), str);
g_free (str);
}
static void
file_transfer_dialog_response (GtkDialog *dlg, gint response_id)
{
g_signal_emit (G_OBJECT (dlg),
file_transfer_dialog_signals[CANCEL], 0, NULL);
}
static void
file_transfer_dialog_set_prop (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (object);
gchar *str;
gchar *base;
switch (prop_id)
{
case PROP_FROM_URI:
base = g_path_get_basename (g_value_get_string (value));
str = g_strdup_printf (_("Transferring: %s"), base);
gtk_label_set_text (GTK_LABEL (dlg->priv->current),
str);
g_free (base);
g_free (str);
base = g_path_get_dirname (g_value_get_string (value));
str = g_strdup_printf (_("From: %s"), base);
gtk_label_set_text (GTK_LABEL (dlg->priv->from),
str);
g_free (base);
g_free (str);
break;
case PROP_TO_URI:
base = g_path_get_dirname (g_value_get_string (value));
str = g_strdup_printf (_("To: %s"), base);
gtk_label_set_text (GTK_LABEL (dlg->priv->to),
str);
g_free (base);
g_free (str);
break;
case PROP_FRACTION_COMPLETE:
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (dlg->priv->progress), g_value_get_double (value));
break;
case PROP_NTH_URI:
dlg->priv->nth = g_value_get_uint (value);
file_transfer_dialog_update_num_files (dlg);
break;
case PROP_TOTAL_URIS:
dlg->priv->total = g_value_get_uint (value);
file_transfer_dialog_update_num_files (dlg);
break;
}
}
static void
file_transfer_dialog_get_prop (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (object);
switch (prop_id)
{
case PROP_NTH_URI:
g_value_set_uint (value, dlg->priv->nth);
break;
case PROP_TOTAL_URIS:
g_value_set_uint (value, dlg->priv->total);
break;
}
}
static void
file_transfer_dialog_class_init (FileTransferDialogClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
klass->cancel = file_transfer_dialog_cancel;
object_class->finalize = file_transfer_dialog_finalize;
object_class->get_property = file_transfer_dialog_get_prop;
object_class->set_property = file_transfer_dialog_set_prop;
GTK_DIALOG_CLASS (klass)->response = file_transfer_dialog_response;
g_object_class_install_property
(object_class, PROP_FROM_URI,
g_param_spec_string ("from_uri",
_("From URI"),
_("URI currently transferring from"),
NULL,
G_PARAM_READWRITE));
g_object_class_install_property
(object_class, PROP_TO_URI,
g_param_spec_string ("to_uri",
_("To URI"),
_("URI currently transferring to"),
NULL,
G_PARAM_WRITABLE));
g_object_class_install_property
(object_class, PROP_FRACTION_COMPLETE,
g_param_spec_double ("fraction_complete",
_("Fraction completed"),
_("Fraction of transfer currently completed"),
0, 1, 0,
G_PARAM_WRITABLE));
g_object_class_install_property
(object_class, PROP_NTH_URI,
g_param_spec_uint ("nth_uri",
_("Current URI index"),
_("Current URI index - starts from 1"),
1, INT_MAX, 1,
G_PARAM_READWRITE));
g_object_class_install_property
(object_class, PROP_TOTAL_URIS,
g_param_spec_uint ("total_uris",
_("Total URIs"),
_("Total number of URIs"),
1, INT_MAX, 1,
G_PARAM_READWRITE));
file_transfer_dialog_signals[CANCEL] =
g_signal_new ("cancel",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (FileTransferDialogClass, cancel),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
file_transfer_dialog_signals[DONE] =
g_signal_new ("done",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FileTransferDialogClass, done),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
parent_class =
G_OBJECT_CLASS (g_type_class_ref (GTK_TYPE_DIALOG));
}
static void
file_transfer_dialog_init (FileTransferDialog *dlg)
{
GtkWidget *hbox;
dlg->priv = g_new0 (FileTransferDialogPrivate, 1);
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->vbox),
4);
gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 4);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
hbox, FALSE, FALSE, 0);
dlg->priv->status = gtk_label_new ("");
gtk_label_set_justify (GTK_LABEL (dlg->priv->status),
GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->status), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (hbox),
dlg->priv->status, TRUE, TRUE, 0);
dlg->priv->num_files = gtk_label_new ("");
gtk_label_set_justify (GTK_LABEL (dlg->priv->num_files),
GTK_JUSTIFY_RIGHT);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->num_files), 1.0, 0.5);
gtk_box_pack_start (GTK_BOX (hbox),
dlg->priv->num_files, TRUE, TRUE, 0);
dlg->priv->progress = gtk_progress_bar_new ();
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
dlg->priv->progress, FALSE, FALSE, 0);
dlg->priv->current = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
dlg->priv->current, FALSE, FALSE, 0);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->current), 0.0, 0.5);
dlg->priv->from = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
dlg->priv->from, FALSE, FALSE, 0);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->from), 0.0, 0.5);
dlg->priv->to = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
dlg->priv->to, FALSE, FALSE, 0);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->to), 0.0, 0.5);
gtk_dialog_add_button (GTK_DIALOG (dlg),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
gtk_widget_show_all (GTK_DIALOG (dlg)->vbox);
}
GType
file_transfer_dialog_get_type (void)
{
static GType file_transfer_dialog_type = 0;
if (!file_transfer_dialog_type)
{
static GTypeInfo file_transfer_dialog_info =
{
sizeof (FileTransferDialogClass),
NULL, /* GBaseInitFunc */
NULL, /* GBaseFinalizeFunc */
(GClassInitFunc) file_transfer_dialog_class_init,
NULL, /* GClassFinalizeFunc */
NULL, /* data */
sizeof (FileTransferDialog),
0, /* n_preallocs */
(GInstanceInitFunc) file_transfer_dialog_init,
NULL
};
file_transfer_dialog_type =
g_type_register_static (GTK_TYPE_DIALOG,
"FileTransferDialog",
&file_transfer_dialog_info,
0);
}
return file_transfer_dialog_type;
}
GtkWidget*
file_transfer_dialog_new (void)
{
return GTK_WIDGET (g_object_new (file_transfer_dialog_get_type (),
NULL));
}
static int
file_transfer_dialog_update_cb (GnomeVFSAsyncHandle *handle,
GnomeVFSXferProgressInfo *info,
gpointer data)
{
FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (data);
if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR)
return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
if (info->source_name)
g_object_set (G_OBJECT (dlg),
"from_uri", info->source_name,
NULL);
if (info->target_name)
g_object_set (G_OBJECT (dlg),
"to_uri", info->target_name,
NULL);
if (info->bytes_total)
g_object_set (G_OBJECT (dlg),
"fraction_complete", (double) info->total_bytes_copied / (double) info->bytes_total,
NULL);
if (info->file_index && info->files_total)
g_object_set (G_OBJECT (dlg),
"nth_uri", info->file_index,
"total_uris", info->files_total,
NULL);
switch (info->phase)
{
case GNOME_VFS_XFER_PHASE_INITIAL:
gtk_label_set_text (GTK_LABEL (dlg->priv->status),
_("Connecting..."));
gtk_window_set_title (GTK_WINDOW (dlg),
_("Connecting..."));
break;
case GNOME_VFS_XFER_PHASE_READYTOGO:
case GNOME_VFS_XFER_PHASE_OPENSOURCE:
gtk_label_set_text (GTK_LABEL (dlg->priv->status),
_("Downloading..."));
gtk_window_set_title (GTK_WINDOW (dlg),
_("Downloading..."));
break;
case GNOME_VFS_XFER_PHASE_COMPLETED:
g_signal_emit (G_OBJECT (dlg),
file_transfer_dialog_signals[DONE],
0, NULL);
return 0;
default:
break;
}
return 1;
}
GnomeVFSResult
file_transfer_dialog_wrap_async_xfer (FileTransferDialog *dlg,
GList *source_uri_list,
GList *target_uri_list,
GnomeVFSXferOptions xfer_options,
GnomeVFSXferErrorMode error_mode,
GnomeVFSXferOverwriteMode overwrite_mode,
int priority)
{
g_return_val_if_fail (IS_FILE_TRANSFER_DIALOG (dlg),
GNOME_VFS_ERROR_BAD_PARAMETERS);
return gnome_vfs_async_xfer (&dlg->priv->handle,
source_uri_list,
target_uri_list,
xfer_options,
error_mode,
overwrite_mode,
priority,
file_transfer_dialog_update_cb,
dlg,
NULL,
NULL
);
}

View File

@@ -1,69 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* file-transfer-dialog.h
* Copyright (C) 2002 Ximian, Inc.
*
* Written by Rachel Hestilow <hestilow@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 __FILE_TRANSFER_DIALOG_H__
#define __FILE_TRANSFER_DIALOG_H__
#include <gtk/gtkdialog.h>
#include <libgnomevfs/gnome-vfs-xfer.h>
G_BEGIN_DECLS
#define FILE_TRANSFER_DIALOG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, file_transfer_dialog_get_type (), FileTransferDialog)
#define FILE_TRANSFER_DIALOG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, file_transfer_dialog_get_type (), FileTransferDialogClass)
#define IS_FILE_TRANSFER_DIALOG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, file_transfer_dialog_get_type ())
typedef struct _FileTransferDialog FileTransferDialog;
typedef struct _FileTransferDialogClass FileTransferDialogClass;
typedef struct _FileTransferDialogPrivate FileTransferDialogPrivate;
struct _FileTransferDialog
{
GtkDialog dialog;
FileTransferDialogPrivate *priv;
};
struct _FileTransferDialogClass
{
GtkDialogClass parent_class;
void (*cancel) (FileTransferDialog *dlg);
void (*done) (FileTransferDialog *dlg);
};
GType file_transfer_dialog_get_type (void);
GtkWidget* file_transfer_dialog_new (void);
GnomeVFSResult file_transfer_dialog_wrap_async_xfer (FileTransferDialog *dlg,
GList *source_uri_list,
GList *target_uri_list,
GnomeVFSXferOptions xfer_options,
GnomeVFSXferErrorMode error_mode,
GnomeVFSXferOverwriteMode overwrite_mode,
int priority);
G_END_DECLS
#endif /* __FILE_TRANSFER_DIALOG_H__ */

View File

@@ -1,41 +0,0 @@
#include <glib.h>
#include <glib-object.h>
#include "gconf-property-editor-marshal.h"
/* VOID:STRING,POINTER (peditor-marshal.list:25) */
void
gconf_property_editor_marshal_VOID__STRING_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data)
{
typedef void (*GMarshalFunc_VOID__STRING_POINTER) (gpointer data1,
gpointer arg_1,
gpointer arg_2,
gpointer data2);
register GMarshalFunc_VOID__STRING_POINTER callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
g_return_if_fail (n_param_values == 3);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_VOID__STRING_POINTER) (marshal_data ? marshal_data : cc->callback);
callback (data1,
(char*) g_value_get_string (param_values + 1),
g_value_get_pointer (param_values + 2),
data2);
}

View File

@@ -1,15 +0,0 @@
#include <gobject/gmarshal.h>
G_BEGIN_DECLS
/* VOID:STRING,POINTER (peditor-marshal.list:25) */
extern void gconf_property_editor_marshal_VOID__STRING_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data);
G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@@ -1,163 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* gconf-property-editor.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 __GCONF_PROPERTY_EDITOR_H
#define __GCONF_PROPERTY_EDITOR_H
#include <gnome.h>
#include <gconf/gconf-client.h>
#include <gconf/gconf-changeset.h>
G_BEGIN_DECLS
#define GCONF_PROPERTY_EDITOR(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, gconf_property_editor_get_type (), GConfPropertyEditor)
#define GCONF_PROPERTY_EDITOR_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, gconf_property_editor_get_type (), GConfPropertyEditorClass)
#define IS_GCONF_PROPERTY_EDITOR(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gconf_property_editor_get_type ())
typedef struct _GConfPropertyEditor GConfPropertyEditor;
typedef struct _GConfPropertyEditorClass GConfPropertyEditorClass;
typedef struct _GConfPropertyEditorPrivate GConfPropertyEditorPrivate;
typedef GConfValue *(*GConfPEditorValueConvFn) (GConfPropertyEditor *peditor, const GConfValue *);
typedef int (*GConfPEditorGetValueFn) (GConfPropertyEditor *peditor, gpointer data);
typedef enum
{
PEDITOR_FONT_NAME,
PEDITOR_FONT_SIZE,
PEDITOR_FONT_COMBINED
} GConfPEditorFontType;
struct _GConfPropertyEditor
{
GObject parent;
GConfPropertyEditorPrivate *p;
};
struct _GConfPropertyEditorClass
{
GObjectClass g_object_class;
void (*value_changed) (GConfPropertyEditor *peditor, gchar *key, GConfValue *value);
};
GType gconf_property_editor_get_type (void);
const gchar *gconf_property_editor_get_key (GConfPropertyEditor *peditor);
GObject *gconf_peditor_new_boolean (GConfChangeSet *changeset,
gchar *key,
GtkWidget *checkbox,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_enum_toggle (GConfChangeSet *changeset,
gchar *key,
GtkWidget *checkbox,
GType enum_type,
GConfPEditorGetValueFn val_true_fn,
guint val_false,
gboolean use_nick,
gpointer data,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_integer (GConfChangeSet *changeset,
gchar *key,
GtkWidget *entry,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_string (GConfChangeSet *changeset,
gchar *key,
GtkWidget *entry,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_filename (GConfChangeSet *changeset,
gchar *key,
GtkWidget *file_entry,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_color (GConfChangeSet *changeset,
gchar *key,
GtkWidget *color_entry,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_select_menu (GConfChangeSet *changeset,
gchar *key,
GtkWidget *option_menu,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_select_menu_with_enum (GConfChangeSet *changeset,
gchar *key,
GtkWidget *option_menu,
GType enum_type,
gboolean use_nick,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_select_radio (GConfChangeSet *changeset,
gchar *key,
GSList *radio_group,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_select_radio_with_enum (GConfChangeSet *changeset,
gchar *key,
GSList *radio_group,
GType enum_type,
gboolean use_nick,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_numeric_range (GConfChangeSet *changeset,
gchar *key,
GtkWidget *range,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_font (GConfChangeSet *changeset,
gchar *key,
GtkWidget *font_picker,
GConfPEditorFontType font_type,
gchar *first_property_name,
...);
GObject *gconf_peditor_new_image (GConfChangeSet *changeset,
gchar *key,
GtkWidget *button,
gchar *first_property,
...);
void gconf_peditor_widget_set_guard (GConfPropertyEditor *peditor,
GtkWidget *widget);
GConfValue *gconf_value_int_to_float (const GConfValue *value);
GConfValue *gconf_value_float_to_int (const GConfValue *value);
G_END_DECLS
#endif /* __GCONF_PROPERTY_EDITOR_H */

View File

@@ -1,229 +0,0 @@
#include <config.h>
#include <gnome.h>
#include <glade/glade.h>
#include <gconf/gconf-client.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <glib-object.h>
#include "theme-common.h"
static void theme_info_free (ThemeInfo *info);
typedef struct _ThemeCallbackData
{
GFunc func;
gpointer data;
} ThemeCallbackData;
GList *theme_list = NULL;
GList *callbacks = NULL;
const gchar *suffix = "gtk-2.0";
const gchar *key_suffix = "gtk-2.0-key";
static ThemeInfo *
find_theme_info_by_dir (const gchar *theme_dir)
{
GList *list;
for (list = theme_list; list; list = list->next)
{
ThemeInfo *info = list->data;
if (! strcmp (info->path, theme_dir))
return info;
}
return NULL;
}
static void
update_theme_dir (const gchar *theme_dir)
{
ThemeInfo *info = NULL;
gboolean changed = FALSE;
gboolean has_gtk = FALSE;
gboolean has_keybinding = FALSE;
gchar *tmp;
tmp = g_build_filename (theme_dir, suffix, NULL);
if (g_file_test (tmp, G_FILE_TEST_IS_DIR))
{
has_gtk = TRUE;
}
g_free (tmp);
tmp = g_build_filename (theme_dir, key_suffix, NULL);
if (g_file_test (tmp, G_FILE_TEST_IS_DIR))
{
has_keybinding = TRUE;
}
g_free (tmp);
info = find_theme_info_by_dir (theme_dir);
if (info)
{
if (!has_gtk && ! has_keybinding)
{
theme_list = g_list_remove (theme_list, info);
theme_info_free (info);
changed = TRUE;
}
else if ((info->has_keybinding != has_keybinding) ||
(info->has_gtk != has_gtk))
{
info->has_keybinding = has_keybinding;
info->has_gtk = has_gtk;
changed = TRUE;
}
}
else
{
if (has_gtk || has_keybinding)
{
info = g_new0 (ThemeInfo, 1);
info->path = g_strdup (theme_dir);
info->name = g_strdup (strrchr (theme_dir, '/') + 1);
info->has_gtk = has_gtk;
info->has_keybinding = has_keybinding;
theme_list = g_list_prepend (theme_list, info);
changed = TRUE;
}
}
if (changed)
{
GList *list;
for (list = callbacks; list; list = list->next)
{
ThemeCallbackData *callback_data = list->data;
(* callback_data->func) ((gpointer)theme_dir, callback_data->data);
}
}
}
static void
top_theme_dir_changed_callback (GnomeVFSMonitorHandle *handle,
const gchar *monitor_uri,
const gchar *info_uri,
GnomeVFSMonitorEventType event_type,
gpointer user_data)
{
switch (event_type)
{
case GNOME_VFS_MONITOR_EVENT_CHANGED:
case GNOME_VFS_MONITOR_EVENT_CREATED:
case GNOME_VFS_MONITOR_EVENT_DELETED:
if (!strncmp (info_uri, "file://", strlen ("file://")))
update_theme_dir (info_uri + strlen ("file://"));
else
update_theme_dir (info_uri);
break;
default:
break;
}
}
static void
themes_common_list_add_dir (const char *dirname)
{
GnomeVFSMonitorHandle *handle = NULL;
DIR *dir;
struct dirent *de;
g_return_if_fail (dirname != NULL);
dir = opendir (dirname);
gnome_vfs_monitor_add (&handle,
dirname,
GNOME_VFS_MONITOR_DIRECTORY,
top_theme_dir_changed_callback,
NULL);
if (!dir)
return;
while ((de = readdir (dir)))
{
char *tmp;
if (de->d_name[0] == '.')
continue;
tmp = g_build_filename (dirname, de->d_name, NULL);
update_theme_dir (tmp);
g_free (tmp);
}
closedir (dir);
}
void
theme_common_init (void)
{
static gboolean initted = FALSE;
gchar *dir;
GnomeVFSURI *uri;
if (initted)
return;
initted = TRUE;
dir = g_build_filename (g_get_home_dir (), ".themes", NULL);
/* Make sure it exists */
uri = gnome_vfs_uri_new (dir);
if (!gnome_vfs_uri_exists (uri))
gnome_vfs_make_directory_for_uri (uri, 0775);
gnome_vfs_uri_unref (uri);
themes_common_list_add_dir (dir);
g_free (dir);
dir = gtk_rc_get_theme_dir ();
themes_common_list_add_dir (dir);
g_free (dir);
}
GList *
theme_common_get_list (void)
{
theme_common_init ();
return theme_list;
}
void
theme_common_register_theme_change (GFunc func,
gpointer data)
{
ThemeCallbackData *callback_data;
callback_data = g_new0 (ThemeCallbackData, 1);
callback_data->func = func;
callback_data->data = data;
callbacks = g_list_prepend (callbacks, callback_data);
}
static void
theme_info_free (ThemeInfo *info)
{
g_free (info->path);
g_free (info->name);
g_free (info);
}

View File

@@ -1,24 +0,0 @@
#ifndef THEME_COMMON_H
#define THEME_COMMON_H
#include <glib.h>
typedef struct _ThemeInfo ThemeInfo;
struct _ThemeInfo
{
gchar *path;
gchar *name;
guint has_gtk : 1;
guint has_keybinding : 1;
guint user_writable : 1;
};
void theme_common_init (void);
GList *theme_common_get_list (void);
void theme_common_register_theme_change (GFunc func,
gpointer data);
#endif /* THEME_COMMON_H */

View File

@@ -1,149 +0,0 @@
#include <X11/Xatom.h>
#include <gdk/gdkx.h>
#include <gdk/gdk.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include "wm-common.h"
typedef struct _WMCallbackData
{
GFunc func;
gpointer data;
} WMCallbackData;
/* Our WM Window */
static Window wm_window = None;
char*
wm_common_get_current_window_manager (void)
{
Atom utf8_string, atom, type;
int result;
char *retval;
int format;
gulong nitems;
gulong bytes_after;
guchar *val;
if (wm_window == None)
return WM_COMMON_UNKNOWN;
utf8_string = XInternAtom (GDK_DISPLAY (), "UTF8_STRING", False);
atom = XInternAtom (GDK_DISPLAY (), "_NET_WM_NAME", False);
gdk_error_trap_push ();
result = XGetWindowProperty (GDK_DISPLAY (),
wm_window,
atom,
0, G_MAXLONG,
False, utf8_string,
&type, &format, &nitems,
&bytes_after, (guchar **)&val);
if (gdk_error_trap_pop () || result != Success)
return WM_COMMON_UNKNOWN;
if (type != utf8_string ||
format !=8 ||
nitems == 0)
{
if (val)
XFree (val);
return WM_COMMON_UNKNOWN;
}
if (!g_utf8_validate (val, nitems, NULL))
{
XFree (val);
return WM_COMMON_UNKNOWN;
}
retval = g_strndup (val, nitems);
XFree (val);
return retval;
}
static void
update_wm_window (void)
{
Window *xwindow;
Atom type;
gint format;
gulong nitems;
gulong bytes_after;
XGetWindowProperty (GDK_DISPLAY (), GDK_ROOT_WINDOW (),
XInternAtom (GDK_DISPLAY (), "_NET_SUPPORTING_WM_CHECK", False),
0, G_MAXLONG, False, XA_WINDOW, &type, &format,
&nitems, &bytes_after, (guchar **) &xwindow);
if (type != XA_WINDOW)
{
wm_window = None;
return;
}
gdk_error_trap_push ();
XSelectInput (GDK_DISPLAY (), *xwindow, StructureNotifyMask | PropertyChangeMask);
XSync (GDK_DISPLAY (), False);
if (gdk_error_trap_pop ())
{
XFree (xwindow);
wm_window = None;
return;
}
wm_window = *xwindow;
XFree (xwindow);
}
static GdkFilterReturn
wm_window_event_filter (GdkXEvent *xev,
GdkEvent *event,
gpointer data)
{
WMCallbackData *ncb_data = (WMCallbackData*) data;
XEvent *xevent = (XEvent *)xev;
if ((xevent->type == DestroyNotify &&
wm_window != None && xevent->xany.window == wm_window) ||
(xevent->type == PropertyNotify &&
xevent->xany.window == GDK_ROOT_WINDOW () &&
xevent->xproperty.atom == (XInternAtom (GDK_DISPLAY (), "_NET_SUPPORTING_WM_CHECK", False))) ||
(xevent->type == PropertyNotify &&
wm_window != None && xevent->xany.window == wm_window &&
xevent->xproperty.atom == (XInternAtom (GDK_DISPLAY (), "_NET_WM_NAME", False))))
{
update_wm_window ();
(* ncb_data->func) ((gpointer)wm_common_get_current_window_manager(),
ncb_data->data);
}
return GDK_FILTER_CONTINUE;
}
void
wm_common_register_window_manager_change (GFunc func,
gpointer data)
{
WMCallbackData *ncb_data;
ncb_data = g_new0 (WMCallbackData, 1);
ncb_data->func = func;
ncb_data->data = data;
gdk_window_add_filter (NULL, wm_window_event_filter, ncb_data);
update_wm_window ();
XSelectInput (GDK_DISPLAY (), GDK_ROOT_WINDOW (), PropertyChangeMask);
XSync (GDK_DISPLAY (), False);
}

View File

@@ -1,13 +0,0 @@
#ifndef WM_COMMON_H
#define WM_COMMON_H
#define WM_COMMON_METACITY "Metacity"
#define WM_COMMON_SAWFISH "Sawfish"
#define WM_COMMON_UNKNOWN "Unknown"
gchar *wm_common_get_current_window_manager (void);
void wm_common_register_window_manager_change (GFunc func,
gpointer data);
#endif /* WM_COMMON_H */

View File

@@ -1,9 +0,0 @@
#!/bin/sh
if test "x$#" = "x0"
then
@BINDIR@/gnomecc --run-capplet @CAPPLET_NAME@
else
@BINDIR@/@CAPPLET_NAME@-control $@
fi

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