Compare commits
4 Commits
NAUTILUS_2
...
thumbnail-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67d8e0481c | ||
|
|
177c7e8a21 | ||
|
|
c8fa009b68 | ||
|
|
16de89cf4f |
36
.cvsignore
@@ -1,36 +0,0 @@
|
||||
ABOUT-NLS
|
||||
.new.ltmain.sh
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.cache
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
configure.scan
|
||||
intl
|
||||
libtool
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
install-sh
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
version.h
|
||||
intl
|
||||
macros
|
||||
INSTALL
|
||||
control-center.spec
|
||||
my_control_center_idl
|
||||
*.tar.gz
|
||||
Gnome.directory
|
||||
intltool-*
|
||||
confdefs.h
|
||||
libgswitchit
|
||||
libsound
|
||||
340
COPYING
@@ -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.
|
||||
@@ -1,2 +0,0 @@
|
||||
Email: jody@gnome.org
|
||||
Email: jrb@gnome.org
|
||||
27
Makefile.am
@@ -1,27 +0,0 @@
|
||||
SUBDIRS = po libsounds libbackground libwindow-settings libgswitchit gnome-settings-daemon capplets control-center vfs-methods idl schemas typing-break
|
||||
|
||||
#I removed the root-manager for now
|
||||
#
|
||||
# it generated this error :
|
||||
# root-manager.c:55:31: security/pam_appl.h: No such file or directory
|
||||
# while compiling. I guess we need to check for pam or something
|
||||
# in the configure.in file. Since we are not using it now, i will
|
||||
# remove it from the default build. Chema
|
||||
|
||||
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
|
||||
124
NEWS
@@ -1,124 +0,0 @@
|
||||
gnome-control-center 2.5.4
|
||||
|
||||
Dennis Cranston :
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=133715
|
||||
* Improve layout of display capplet
|
||||
|
||||
Alexander Winston :
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=133214
|
||||
* quote the AC_DEFUN properly
|
||||
|
||||
Jody :
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=124064
|
||||
* Add a test for ngettext
|
||||
* Delete some of the unused file cluttering the tree
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=134446
|
||||
* Trivial string consistency adjustment
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=128164
|
||||
* Handle sorted trees
|
||||
* Fix incorrect string in gnome-settings-daemon
|
||||
|
||||
Muktha Narayan :
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=124032
|
||||
* Do not popup the logout dialog when the close button (X)
|
||||
|
||||
Jan Arne Petersen :
|
||||
* Move a few capplets to the new file selector
|
||||
|
||||
Padraig O'Briain :
|
||||
* Fix the ATK relations for the file-type capplet
|
||||
|
||||
Julio M. Merino Vidal :
|
||||
* Make fontilus and themus respect the gconf install settings
|
||||
|
||||
Rodney Dawes:
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=134171
|
||||
* Fix transtions for titles of colour pickers.
|
||||
|
||||
Kaushal Kumar:
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=109091
|
||||
* Warn before deleting a type
|
||||
|
||||
Richard Hult:
|
||||
* Improve Dr Wright.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
gnome-control-center 2.5.1
|
||||
|
||||
Jody:
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=125899
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=125970
|
||||
* Fix the build and configure on older X servers.
|
||||
* Use icon themes
|
||||
|
||||
Sergey:
|
||||
* Merge gswitchit into gnome-settings-daemon and keyboard capplet
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
gnome-control-center 2.5.0
|
||||
|
||||
Jody:
|
||||
* Add libxklavier and prep for inclusion of gswitchit's
|
||||
xkb-properties-capplet
|
||||
* http://bugzilla.gnome.org/show_bug.cgi?id=120842 [HIGification broke accessx]
|
||||
* http://bugzilla.gnome.org/show_bug.cgi?id=106489 [protect against gconf failure]
|
||||
* http://bugzilla.gnome.org/show_bug.cgi?id=124513 [Handle TruColor Displays]
|
||||
* http://bugzilla.gnome.org/show_bug.cgi?id=116710 [smarter maximum dpi]
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
gnome-control-center 2.1.6
|
||||
|
||||
Jody:
|
||||
* gnome-keyboard-properties.c (accessibility_button_clicked) : fix
|
||||
minor typo that disables the error dialog in the event of failure.
|
||||
|
||||
Jonathan:
|
||||
* gnome-theme-info.c : Rewrite. Now working
|
||||
* gnome-theme-manager : Fix lots of bugs. Use the rewrite.
|
||||
|
||||
gnome-control-center 2.1.0.2
|
||||
|
||||
Jody:
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=93211
|
||||
* disable edit button when selecting mime catagory
|
||||
* Tidy labels and accelerators in file-type edit dialogs
|
||||
|
||||
Michael:
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=91535
|
||||
* Don't start esd just to stop it
|
||||
|
||||
Iain Holmes:
|
||||
* Add an image size label for background capplet.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
gnome-control-center 2.1.0.1
|
||||
|
||||
Jody:
|
||||
* Some minor ui tweaks for accessx.
|
||||
* Some aix portabiltiy patches
|
||||
* fix accelerators for ui-properties capplet.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
gnome-control-center 2.0.1
|
||||
|
||||
Chema:
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=86018
|
||||
* Only assign the filename to the label if the file is valid.
|
||||
|
||||
GMan:
|
||||
* Fix titles to use 'preferences' rather than 'properties'
|
||||
|
||||
Jody:
|
||||
* Clean up the handling of custom applications in mime type capplet.
|
||||
* Supply some decent defaults for new mime types.
|
||||
* Implement Background capplet UI recommendations.
|
||||
* Implement Font capplet UI recommendations.
|
||||
* Reorganize the AccessX UI.
|
||||
* Fix cmd line args for file-type capplet.
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=84014
|
||||
* Handle Drag-n-Drop of uris with escaped characters.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
First split version of this package
|
||||
62
README
@@ -1,62 +0,0 @@
|
||||
GNOME Control Center
|
||||
====================
|
||||
|
||||
Requirements -
|
||||
|
||||
intltool >= 0.21
|
||||
gtk+ >= 2.3.0
|
||||
gconf >= 2.0.0
|
||||
libgnome >= 2.0.0
|
||||
libgnomeui >= 2.0.0
|
||||
libglade >= 2.0.0
|
||||
libbonobo >= 2.0.0
|
||||
libbonoboui >= 2.0.0
|
||||
libgnomevfs >= 2.0.0
|
||||
gnome-desktop >= 2.0.0
|
||||
gnome-icon-theme >= 1.1.3
|
||||
|
||||
Installation -
|
||||
|
||||
See the file 'INSTALL'
|
||||
|
||||
How to report bugs -
|
||||
|
||||
Bugs should be reported to the GNOME bug tracking system under the product
|
||||
control-center. It is available at http://bugzilla.gnome.org.
|
||||
|
||||
In the report please include the following information -
|
||||
|
||||
Operating system and version
|
||||
For Linux, version of the C library
|
||||
How to reproduce the bug if possible
|
||||
If the bug was a crash, include the exact text that was printed out
|
||||
A stacktrace where possible [see below]
|
||||
|
||||
How to get a stack trace -
|
||||
|
||||
If the crash is reproducible, it is possible to get a stack trace and
|
||||
attach it to the bug report. The following steps are used to obtain a
|
||||
stack trace -
|
||||
|
||||
Run the program in gdb [the GNU debugger] or any other debugger
|
||||
ie. gdb gnome-calculator
|
||||
Start the program
|
||||
ie. (gdb) run
|
||||
Reproduce the crash and the program will exit to the gdb prompt
|
||||
Get the back trace
|
||||
ie. (gdb) bt
|
||||
|
||||
Once you have the backtrace, copy and paste this either into the
|
||||
'Comments' field or attach a file with it included.
|
||||
|
||||
|
||||
Patches -
|
||||
|
||||
Patches should be submitted to bugzilla.gnome.org or emailed to one of
|
||||
the people listed in the MAINTAINERS file. If using bugzilla, attach
|
||||
the patch to a new bug report [or preferably, check to see if there is
|
||||
already a bug report that corresponds to your patch]. Bug reports
|
||||
containing patches should include the 'PATCH' keyword.
|
||||
|
||||
Patches should be created using the unified diff form.
|
||||
ie. cvs diff -u file-to-be-patched.c > patch.diff
|
||||
105
TODO
@@ -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
|
||||
|
||||
|
||||
|
||||
19
TODO.xml
@@ -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>
|
||||
164
acinclude.m4
@@ -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, µ) != 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
|
||||
])
|
||||
@@ -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
|
||||
@@ -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>
|
||||
1060
archiver/ChangeLog
@@ -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
|
||||
@@ -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
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__ */
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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@"
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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.
|
||||
1889
archiver/location.c
@@ -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 */
|
||||
384
archiver/main.c
@@ -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;
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
2004-02-13 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.3
|
||||
|
||||
2004-01-14 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.2
|
||||
|
||||
2003-12-30 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.1.1
|
||||
|
||||
2003-12-30 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.1
|
||||
|
||||
2003-10-28 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.0
|
||||
|
||||
2003-07-07 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.4
|
||||
|
||||
2003-06-24 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.3
|
||||
|
||||
2003-05-07 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.1
|
||||
|
||||
Tue Feb 4 17:09:18 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* Release 2.2.0.1
|
||||
|
||||
Tue Jan 21 01:15:14 2003 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* Release 2.2.0
|
||||
|
||||
Thu Jan 16 02:41:09 2003 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* Release 2.1.7
|
||||
|
||||
2003-01-10 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.6
|
||||
|
||||
2002-12-18 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.5
|
||||
|
||||
2002-11-23 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.3
|
||||
|
||||
2002-11-02 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.2
|
||||
|
||||
2002-10-21 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.1
|
||||
|
||||
2002-10-01 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.0.1
|
||||
|
||||
2002-08-21 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.0
|
||||
|
||||
2002-06-17 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.0.0
|
||||
|
||||
2001-07-27 Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
* RELEASE : 1.5.2
|
||||
|
||||
2001-07-20 Chema Celorio <chema@celorio.com>
|
||||
|
||||
* RELEASE : 1.5.0
|
||||
|
||||
2001-05-24 Arturo Espinosa Aldama <arturo@ximian.com>
|
||||
|
||||
* 0.5 RELEASE
|
||||
|
||||
2001-05-09 Arturo Espinosa Aldama <arturo@ximian.com>
|
||||
|
||||
* 0.4 RELEASE
|
||||
|
||||
2001-02-20 Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
* test-3.sh: Created
|
||||
* test-2.sh: Removed parts dealing with partial containment
|
||||
|
||||
2001-02-19 Bradford Hovinen <hovinen@ximian.com>
|
||||
|
||||
* Added test-1.sh and test-2.sh, the first two tests in the test suite
|
||||
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
113
archiver/util.c
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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.
|
||||
45
autogen.sh
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile.in
|
||||
Makefile
|
||||
@@ -1,20 +0,0 @@
|
||||
always_built_SUBDIRS = \
|
||||
common accessibility \
|
||||
default-applications desktop-links font \
|
||||
background keyboard mouse sound \
|
||||
file-types theme-switcher ui-properties \
|
||||
keybindings network windows
|
||||
|
||||
if HAVE_RANDR
|
||||
randr_SUBDIRS = display
|
||||
else
|
||||
randr_SUBDIRS =
|
||||
endif
|
||||
|
||||
SUBDIRS = $(always_built_SUBDIRS) $(randr_SUBDIRS)
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
$(always_built_SUBDIRS) display
|
||||
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -1 +0,0 @@
|
||||
SUBDIRS = keyboard at-properties
|
||||
@@ -1,4 +0,0 @@
|
||||
*.desktop
|
||||
Makefile
|
||||
Makefile.in
|
||||
gnome-at-properties
|
||||
@@ -1,58 +0,0 @@
|
||||
2003-11-27 Muktha <muktha.narayan@wipro.com>
|
||||
|
||||
* main.c: Do not popup the logout dialog when the close button (X) of
|
||||
window manager is clicked. Fixes bug #124032.
|
||||
|
||||
2004-02-13 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.3
|
||||
|
||||
2004-01-14 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.2
|
||||
|
||||
2003-12-30 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.1.1
|
||||
|
||||
2003-12-30 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.1
|
||||
|
||||
2003-10-28 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.0
|
||||
|
||||
2003-08-01 Dennis Cranston <dennis_cranston at yahoo com>
|
||||
|
||||
* at-enable-dialog.glade: Patch to add two more pixels of spacing
|
||||
between action area and vbox of preferences dialog.
|
||||
|
||||
Fri Aug 1 14:28:52 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* main.c (init_startup_state): remove markup tags from translated
|
||||
strings, #118801.
|
||||
|
||||
2003-07-18 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* main.c: Add a check to confirm that the AT's are installed. Add
|
||||
a warning message if they are not. Change widget naming scheme.
|
||||
|
||||
* at-enable-dialog.glade: Change widget naming scheme.
|
||||
|
||||
2003-07-16 Dennis Cranston <dennis_cranston at yahoo com>
|
||||
|
||||
* at-enable-dialog.glade: Make close the default button.
|
||||
|
||||
2003-07-16 Dennis Cranston <dennis_cranston at yahoo com>
|
||||
|
||||
* at-enable-dialog.glade: Adjust widget padding and remove
|
||||
separator per HIG.
|
||||
|
||||
2003-07-07 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.4
|
||||
|
||||
2003-07-01 Daniel Baeyens <daniel.baeyens@hispalinux.es>
|
||||
* capplets/accessibility/at-properties/at-enable-dialog.glade:
|
||||
"Assistive" is misspelled.
|
||||
@@ -1,29 +0,0 @@
|
||||
bin_PROGRAMS = gnome-at-properties
|
||||
|
||||
gnome_at_properties_LDADD = $(AT_CAPPLET_LIBS) $(top_builddir)/capplets/common/libcommon.la
|
||||
gnome_at_properties_SOURCES = \
|
||||
main.c \
|
||||
at-startup-session.h \
|
||||
at-startup-session.c
|
||||
gnome_at_properties_LDFLAGS = -export-dynamic
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
desktopdir = $(GNOMECC_DESKTOP_DIR)
|
||||
Desktop_in_files = at-properties.desktop.in
|
||||
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
|
||||
|
||||
pixmapdir = $(GNOMECC_PIXMAPS_DIR)
|
||||
pixmap_DATA = \
|
||||
at-startup.png \
|
||||
at-support.png
|
||||
|
||||
gladedir = $(GNOMECC_GLADE_DIR)
|
||||
glade_DATA = at-enable-dialog.glade
|
||||
|
||||
INCLUDES = $(AT_CAPPLET_CFLAGS) \
|
||||
$(GNOMECC_CAPPLETS_CFLAGS) \
|
||||
-DGLADEDIR=\""$(gladedir)"\" \
|
||||
-DPIXMAPDIR=\""$(pixmapdir)"\"
|
||||
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES)
|
||||
EXTRA_DIST = $(glade_DATA) $(pixmap_DATA) $(Desktop_in_files)
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
@@ -1,465 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<glade-interface>
|
||||
<requires lib="gnome"/>
|
||||
|
||||
<widget class="GtkDialog" id="at_properties_dialog">
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Assistive Technology Preferences</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">2</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="at_help_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-help</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="response_id">-11</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="at_close_logout_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="response_id">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment3">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">2</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImage" id="at_close_and_logout_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Close and _Log Out</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="at_close_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="response_id">-7</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="border_width">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">18</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="at_support_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Support</b></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">12</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImage" id="at_enable_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="at_enable_toggle">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">_Enable assistive technologies</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="at_warning_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><small><i><b>Note:</b> Changes to this setting will not take effect until you next log in.</i></small></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="at_applications_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox7">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Applications</b></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">12</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImage" id="at_applications_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="at_applications_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Start these assistive technologies every time you log in:</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">6</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="at_screenreader_toggle">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">_Screenreader</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="at_magnifier_toggle">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">_Magnifier</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="at_keyboard_toggle">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">_On-screen keyboard</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHSeparator" id="at_applications_hseparator">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="at_applications_warning_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
||||
@@ -1,13 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
_Name=Assistive Technology Support
|
||||
_Comment=Enable support for GNOME assistive technologies at login
|
||||
Exec=gnome-at-properties
|
||||
Icon=gnome-settings-accessibility-technologies
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;Settings;Accessibility;
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=control-center
|
||||
X-GNOME-Bugzilla-Component=Assistive Technology Support
|
||||
@@ -1,160 +0,0 @@
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <glib-object.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
|
||||
#include "at-startup-session.h"
|
||||
|
||||
#define AT_STARTUP_KEY "/desktop/gnome/accessibility/startup/exec_ats"
|
||||
|
||||
#define GNOPERNICUS_MAGNIFIER_KEY "/apps/gnopernicus/srcore/mag_active"
|
||||
#define GNOPERNICUS_SPEECH_KEY "/apps/gnopernicus/srcore/sp_active"
|
||||
#define GNOPERNICUS_BRAILLE_KEY "/apps/gnopernicus/srcore/br_active"
|
||||
|
||||
static AtStartupState at_startup_state_recent;
|
||||
|
||||
static GSList *
|
||||
at_startup_get_list (GConfClient *client)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GSList *at_list = gconf_client_get_list (client, AT_STARTUP_KEY, GCONF_VALUE_STRING, &error);
|
||||
if (error) {
|
||||
g_warning ("Error getting value of " AT_STARTUP_KEY ": %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
return at_list;
|
||||
}
|
||||
|
||||
gint
|
||||
at_startup_string_compare (gconstpointer s1, gconstpointer s2)
|
||||
{
|
||||
if (s1 && s2) {
|
||||
return strcmp (s1, s2);
|
||||
}
|
||||
else
|
||||
return (s2-s1);
|
||||
}
|
||||
|
||||
static GSList *
|
||||
at_startup_list_add (GSList *list, const gchar *exec_name)
|
||||
{
|
||||
GSList *l = g_slist_find_custom (list, exec_name, at_startup_string_compare);
|
||||
if (!l) {
|
||||
list = g_slist_append (list, g_strdup (exec_name));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static GSList *
|
||||
at_startup_list_remove (GSList *list, const gchar *exec_name)
|
||||
{
|
||||
GSList *l = g_slist_find_custom (list, exec_name, at_startup_string_compare);
|
||||
if (l) {
|
||||
g_free (l->data);
|
||||
list = g_slist_delete_link (list, l);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void
|
||||
at_startup_state_init (AtStartupState *startup_state)
|
||||
{
|
||||
gboolean mag_active, speech_active, braille_active;
|
||||
GSList *l;
|
||||
GConfClient *client = gconf_client_get_default ();
|
||||
GSList *at_list = at_startup_get_list (client);
|
||||
gchar *prog;
|
||||
|
||||
for (l = at_list; l; l = l->next) {
|
||||
gchar *exec_name = (char *) l->data;
|
||||
if (exec_name && !strcmp (exec_name, "gnopernicus")) {
|
||||
braille_active = gconf_client_get_bool (client,
|
||||
GNOPERNICUS_BRAILLE_KEY,
|
||||
NULL);
|
||||
mag_active = gconf_client_get_bool (client,
|
||||
GNOPERNICUS_MAGNIFIER_KEY,
|
||||
NULL);
|
||||
speech_active = gconf_client_get_bool (client,
|
||||
GNOPERNICUS_SPEECH_KEY,
|
||||
NULL);
|
||||
|
||||
startup_state->enabled.screenreader = (braille_active || speech_active);
|
||||
startup_state->enabled.magnifier = mag_active;
|
||||
}
|
||||
else if (exec_name && !strcmp(exec_name, "gok")) {
|
||||
startup_state->enabled.osk = TRUE;
|
||||
}
|
||||
g_free (exec_name);
|
||||
}
|
||||
|
||||
g_slist_free (at_list);
|
||||
g_object_unref (client);
|
||||
at_startup_state_recent.flags = startup_state->flags;
|
||||
|
||||
prog = g_find_program_in_path ("gok");
|
||||
if (prog != NULL) {
|
||||
startup_state->enabled.osk_installed = TRUE;
|
||||
g_free (prog);
|
||||
} else {
|
||||
startup_state->enabled.osk_installed = FALSE;
|
||||
}
|
||||
|
||||
prog = g_find_program_in_path ("gnopernicus");
|
||||
if (prog != NULL) {
|
||||
startup_state->enabled.magnifier_installed = TRUE;
|
||||
startup_state->enabled.screenreader_installed = TRUE;
|
||||
g_free (prog);
|
||||
} else {
|
||||
startup_state->enabled.magnifier_installed = FALSE;
|
||||
startup_state->enabled.screenreader_installed = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
at_startup_state_update (AtStartupState *startup_state)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GConfClient *client = gconf_client_get_default ();
|
||||
GSList *at_list = at_startup_get_list (client);
|
||||
|
||||
if (startup_state->enabled.screenreader != at_startup_state_recent.enabled.screenreader) {
|
||||
gconf_client_set_bool (client, GNOPERNICUS_SPEECH_KEY,
|
||||
startup_state->enabled.screenreader, NULL);
|
||||
gconf_client_set_bool (client, GNOPERNICUS_BRAILLE_KEY,
|
||||
startup_state->enabled.screenreader, NULL);
|
||||
}
|
||||
|
||||
if (startup_state->enabled.magnifier != at_startup_state_recent.enabled.magnifier) {
|
||||
gconf_client_set_bool (client, GNOPERNICUS_MAGNIFIER_KEY,
|
||||
startup_state->enabled.magnifier, NULL);
|
||||
}
|
||||
|
||||
if (startup_state->enabled.screenreader || startup_state->enabled.magnifier) {
|
||||
if (!(at_startup_state_recent.enabled.screenreader ||
|
||||
at_startup_state_recent.enabled.magnifier))
|
||||
/* new state includes SR or magnifier, initial one did not */
|
||||
at_list = at_startup_list_add (at_list, "gnopernicus");
|
||||
}
|
||||
else {
|
||||
if (at_startup_state_recent.enabled.screenreader ||
|
||||
at_startup_state_recent.enabled.magnifier)
|
||||
at_list = at_startup_list_remove (at_list, "gnopernicus");
|
||||
}
|
||||
if (startup_state->enabled.osk) {
|
||||
if (!at_startup_state_recent.enabled.osk)
|
||||
at_list = at_startup_list_add (at_list, "gok");
|
||||
}
|
||||
else {
|
||||
if (at_startup_state_recent.enabled.osk)
|
||||
at_list = at_startup_list_remove (at_list, "gok");
|
||||
}
|
||||
if (at_startup_state_recent.flags != startup_state->flags) {
|
||||
at_startup_state_recent.flags = startup_state->flags;
|
||||
gconf_client_set_list (client, AT_STARTUP_KEY, GCONF_VALUE_STRING, at_list, &error);
|
||||
}
|
||||
g_object_unref (client);
|
||||
g_slist_free (at_list);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <config.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef union {
|
||||
guint flags;
|
||||
struct {
|
||||
guint support:1;
|
||||
guint osk:1;
|
||||
guint magnifier:1;
|
||||
guint screenreader:1;
|
||||
guint osk_installed:1;
|
||||
guint magnifier_installed:1;
|
||||
guint screenreader_installed:1;
|
||||
} enabled;
|
||||
} AtStartupState;
|
||||
|
||||
void at_startup_state_init (AtStartupState *startup_state);
|
||||
|
||||
void at_startup_state_update (AtStartupState *startup_state);
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
@@ -1,296 +0,0 @@
|
||||
#include <config.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
#include <glade/glade.h>
|
||||
|
||||
#include "capplet-util.h"
|
||||
#include "gconf-property-editor.h"
|
||||
#include "activate-settings-daemon.h"
|
||||
#include "at-startup-session.h"
|
||||
|
||||
#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility"
|
||||
#define ACCESSIBILITY_KEY_DIR "/desktop/gnome/interface"
|
||||
#define AT_STARTUP_DIR "/desktop/gnome/accessibility/startup"
|
||||
#define AT_STARTUP_KEY "/desktop/gnome/accessibility/startup/exec_ats"
|
||||
#define SR_PREFS_DIR "/apps/gnopernicus/srcore"
|
||||
|
||||
static AtStartupState at_startup_state, at_startup_state_initial;
|
||||
|
||||
static void
|
||||
init_startup_state (GladeXML *dialog)
|
||||
{
|
||||
GConfClient *client = gconf_client_get_default ();
|
||||
|
||||
at_startup_state.flags = (gconf_client_get_bool (client,
|
||||
ACCESSIBILITY_KEY,
|
||||
NULL)) ? 1 : 0;
|
||||
|
||||
at_startup_state_init (&at_startup_state);
|
||||
|
||||
at_startup_state_initial.flags = at_startup_state.flags;
|
||||
g_object_unref (client);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_keyboard_toggle")),
|
||||
at_startup_state.enabled.osk);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_screenreader_toggle")),
|
||||
at_startup_state.enabled.screenreader);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_magnifier_toggle")),
|
||||
at_startup_state.enabled.magnifier);
|
||||
|
||||
gtk_widget_set_sensitive (WID ("at_keyboard_toggle"),
|
||||
at_startup_state.enabled.osk_installed);
|
||||
gtk_widget_set_sensitive (WID ("at_screenreader_toggle"),
|
||||
at_startup_state.enabled.screenreader_installed);
|
||||
gtk_widget_set_sensitive (WID ("at_magnifier_toggle"),
|
||||
at_startup_state.enabled.magnifier_installed);
|
||||
|
||||
if (at_startup_state.enabled.osk_installed &&
|
||||
at_startup_state.enabled.screenreader_installed &&
|
||||
at_startup_state.enabled.magnifier_installed) {
|
||||
gtk_widget_hide (WID ("at_applications_warning_label"));
|
||||
gtk_widget_hide (WID ("at_applications_hseparator"));
|
||||
} else {
|
||||
gchar *warning_label;
|
||||
|
||||
gtk_widget_show (WID ("at_applications_warning_label"));
|
||||
gtk_widget_show (WID ("at_applications_hseparator"));
|
||||
if (!at_startup_state.enabled.osk_installed &&
|
||||
!(at_startup_state.enabled.screenreader_installed ||
|
||||
at_startup_state.enabled.magnifier_installed)) {
|
||||
warning_label = g_strdup_printf ("<i>%s</i>", _("No Assistive Technology is available on your system. The 'gok' package must be installed in order to get on-screen keyboard support, and the 'gnopernicus' package must be installed for screenreading and magnifying capabilities."));
|
||||
} else if (!at_startup_state.enabled.osk_installed) {
|
||||
warning_label = g_strdup_printf ("<i>%s</i>", _("Not all available assistive technologies are installed on your system. The 'gok' package must be installed in order to get on-screen keyboard support."));
|
||||
} else {
|
||||
warning_label = g_strdup_printf ("<i>%s</i>", _("Not all available assistive technologies are installed on your system. The 'gnopernicus' package must be installed for screenreading and magnifying capabilities."));
|
||||
}
|
||||
gtk_label_set_markup (GTK_LABEL (WID ("at_applications_warning_label")), warning_label);
|
||||
g_free (warning_label);
|
||||
}
|
||||
}
|
||||
|
||||
static GladeXML *
|
||||
create_dialog (void)
|
||||
{
|
||||
GladeXML *dialog;
|
||||
|
||||
dialog = glade_xml_new (GLADEDIR "/at-enable-dialog.glade", "at_properties_dialog", NULL);
|
||||
|
||||
gtk_image_set_from_stock (GTK_IMAGE (WID ("at_close_and_logout_image")),
|
||||
GTK_STOCK_QUIT, GTK_ICON_SIZE_BUTTON);
|
||||
|
||||
gtk_image_set_from_file (GTK_IMAGE (WID ("at_enable_image")),
|
||||
PIXMAPDIR "/at-support.png");
|
||||
|
||||
gtk_image_set_from_file (GTK_IMAGE (WID ("at_applications_image")),
|
||||
PIXMAPDIR "/at-startup.png");
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
static void
|
||||
cb_dialog_response (GtkDialog *dialog, gint response_id)
|
||||
{
|
||||
GnomeClient *client;
|
||||
if (response_id == GTK_RESPONSE_HELP)
|
||||
capplet_help (GTK_WINDOW (dialog),
|
||||
"foo.xml",
|
||||
"bar");
|
||||
else if (response_id == GTK_RESPONSE_CLOSE || response_id == GTK_RESPONSE_DELETE_EVENT)
|
||||
gtk_main_quit ();
|
||||
else {
|
||||
g_message ("CLOSE AND LOGOUT!");
|
||||
if (!(client = gnome_master_client ())) {
|
||||
|
||||
gtk_main_quit ();
|
||||
}
|
||||
gnome_client_request_save (client, GNOME_SAVE_GLOBAL, TRUE,
|
||||
GNOME_INTERACT_ANY, FALSE, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
close_logout_update (GladeXML *dialog)
|
||||
{
|
||||
GConfClient *client = gconf_client_get_default ();
|
||||
gboolean has_changed =
|
||||
(at_startup_state.flags != at_startup_state_initial.flags) &&
|
||||
gconf_client_get_bool (client, ACCESSIBILITY_KEY, NULL);
|
||||
|
||||
gtk_widget_set_sensitive (WID ("at_close_logout_button"), has_changed);
|
||||
g_object_unref (client);
|
||||
}
|
||||
|
||||
static void
|
||||
at_startup_toggled (GtkToggleButton *toggle_button,
|
||||
GladeXML *dialog)
|
||||
{
|
||||
if (toggle_button == GTK_TOGGLE_BUTTON (WID ("at_keyboard_toggle"))) {
|
||||
at_startup_state.enabled.osk = gtk_toggle_button_get_active (toggle_button);
|
||||
}
|
||||
else if (toggle_button == GTK_TOGGLE_BUTTON (WID ("at_magnifier_toggle"))) {
|
||||
at_startup_state.enabled.magnifier = gtk_toggle_button_get_active (toggle_button);
|
||||
}
|
||||
else if (toggle_button == GTK_TOGGLE_BUTTON (WID ("at_screenreader_toggle"))) {
|
||||
at_startup_state.enabled.screenreader = gtk_toggle_button_get_active (toggle_button);
|
||||
}
|
||||
|
||||
at_startup_state_update (&at_startup_state);
|
||||
close_logout_update (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
at_enable_toggled (GtkToggleButton *toggle_button,
|
||||
GladeXML *dialog)
|
||||
{
|
||||
GConfClient *client = gconf_client_get_default ();
|
||||
gboolean is_enabled = gtk_toggle_button_get_active (toggle_button);
|
||||
|
||||
gconf_client_set_bool (client, ACCESSIBILITY_KEY,
|
||||
is_enabled,
|
||||
NULL);
|
||||
at_startup_state.enabled.support = is_enabled;
|
||||
g_object_unref (client);
|
||||
}
|
||||
|
||||
static void
|
||||
at_startup_update_ui (GConfClient *client,
|
||||
GladeXML *dialog)
|
||||
{
|
||||
at_startup_state_init (&at_startup_state);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_keyboard_toggle")),
|
||||
at_startup_state.enabled.osk);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_screenreader_toggle")),
|
||||
at_startup_state.enabled.screenreader);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_magnifier_toggle")),
|
||||
at_startup_state.enabled.magnifier);
|
||||
}
|
||||
|
||||
static void
|
||||
at_enable_update (GConfClient *client,
|
||||
GladeXML *dialog)
|
||||
{
|
||||
gboolean is_enabled = gconf_client_get_bool (client, ACCESSIBILITY_KEY, NULL);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_enable_toggle")),
|
||||
is_enabled);
|
||||
|
||||
gtk_widget_set_sensitive (WID ("at_applications_frame"), is_enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
at_startup_changed (GConfClient *client,
|
||||
guint cnxn_id,
|
||||
GConfEntry *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
at_startup_state_init (&at_startup_state);
|
||||
at_startup_update_ui (client, user_data);
|
||||
close_logout_update (user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
at_enable_changed (GConfClient *client,
|
||||
guint cnxn_id,
|
||||
GConfEntry *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
at_enable_update (client, user_data);
|
||||
close_logout_update (user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_dialog (GladeXML *dialog)
|
||||
{
|
||||
GConfClient *client;
|
||||
GtkWidget *widget;
|
||||
GObject *peditor;
|
||||
|
||||
client = gconf_client_get_default ();
|
||||
|
||||
gconf_client_add_dir (client, ACCESSIBILITY_KEY_DIR,
|
||||
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
|
||||
|
||||
widget = WID ("at_enable_toggle");
|
||||
g_signal_connect (widget, "toggled",
|
||||
G_CALLBACK (at_enable_toggled),
|
||||
dialog);
|
||||
|
||||
peditor = gconf_peditor_new_boolean (NULL, ACCESSIBILITY_KEY,
|
||||
widget,
|
||||
NULL);
|
||||
|
||||
at_enable_update (client, dialog);
|
||||
|
||||
gconf_client_notify_add (client, ACCESSIBILITY_KEY_DIR,
|
||||
at_enable_changed,
|
||||
dialog, NULL, NULL);
|
||||
|
||||
gconf_client_add_dir (client, AT_STARTUP_DIR,
|
||||
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
|
||||
|
||||
gconf_client_add_dir (client, SR_PREFS_DIR,
|
||||
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
|
||||
|
||||
gconf_client_notify_add (client, AT_STARTUP_DIR,
|
||||
at_startup_changed,
|
||||
dialog, NULL, NULL);
|
||||
|
||||
gconf_client_notify_add (client, SR_PREFS_DIR,
|
||||
at_startup_changed,
|
||||
dialog, NULL, NULL);
|
||||
|
||||
widget = WID ("at_keyboard_toggle");
|
||||
|
||||
g_signal_connect (widget, "toggled",
|
||||
G_CALLBACK (at_startup_toggled),
|
||||
dialog);
|
||||
|
||||
widget = WID ("at_magnifier_toggle");
|
||||
g_signal_connect (widget, "toggled",
|
||||
G_CALLBACK (at_startup_toggled),
|
||||
dialog);
|
||||
|
||||
widget = WID ("at_screenreader_toggle");
|
||||
g_signal_connect (widget, "toggled",
|
||||
G_CALLBACK (at_startup_toggled),
|
||||
dialog);
|
||||
|
||||
widget = WID ("at_properties_dialog");
|
||||
capplet_set_icon (widget, "at-enable-capplet.png");
|
||||
|
||||
g_signal_connect (G_OBJECT (widget),
|
||||
"response",
|
||||
G_CALLBACK (cb_dialog_response), NULL);
|
||||
|
||||
gtk_widget_show (widget);
|
||||
|
||||
g_object_unref (client);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GladeXML *dialog;
|
||||
|
||||
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
textdomain (GETTEXT_PACKAGE);
|
||||
|
||||
gnome_program_init ("gnome-at-properties", VERSION,
|
||||
LIBGNOMEUI_MODULE, argc, argv,
|
||||
GNOME_PARAM_APP_DATADIR, GNOMECC_DATA_DIR,
|
||||
NULL);
|
||||
|
||||
activate_settings_daemon ();
|
||||
|
||||
dialog = create_dialog ();
|
||||
|
||||
init_startup_state (dialog);
|
||||
|
||||
setup_dialog (dialog);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
*.gladep
|
||||
*.glade.bak
|
||||
gnome-accessibility-keyboard-properties
|
||||
accessibility-keyboard.desktop
|
||||
@@ -1,343 +0,0 @@
|
||||
2004-02-16 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c (cb_load_CDE_file) : Add a kludge to set
|
||||
the vertical size based on the monitor size until the filesel can do
|
||||
a better job of doing it itself.
|
||||
|
||||
2003-12-07 Jan Arne Petersen <jpetersen@uni-bonn.de>
|
||||
|
||||
* accessibility-keyboard.c: (load_CDE_file),
|
||||
(fchooser_handle_response), (cb_load_CDE_file): replace
|
||||
GtkFileSelection with GtkFileChooser.
|
||||
|
||||
2004-02-13 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.3
|
||||
|
||||
2004-02-12 Mark McLoughlin <mark@skynet.ie>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c: (dialog_response): Update
|
||||
help link to point to user-guide.xml
|
||||
|
||||
2004-01-14 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.2
|
||||
|
||||
2003-12-30 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.1.1
|
||||
|
||||
2003-12-30 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.1
|
||||
|
||||
2003-11-18 Padraig O'Briain <padraig.obriain@sun.com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade: Add atk relations.
|
||||
Fixes bug #126718
|
||||
|
||||
2003-11-03 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=120842
|
||||
* gnome-accessibility-keyboard-properties.c : older xservers require
|
||||
X11/Xlib.h too, its not sun specific.
|
||||
|
||||
2003-10-28 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.0
|
||||
|
||||
2003-10-28 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=120842
|
||||
* gnome-accessibility-keyboard-properties.glade : Remove bone headed
|
||||
spitting of checkbox and label.
|
||||
* accessibility-keyboard.c (setup_toggles) : It was probably done so
|
||||
that the headers could be made bold.
|
||||
|
||||
Mon Aug 11 11:55:49 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade: Patch from Elijah
|
||||
Newren <newren@math.utah.edu> to bring the possible repeat range
|
||||
in sync with the keyboard capplet.
|
||||
|
||||
2003-08-01 Dennis Cranston <dennis_cranston at yahoo com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade: Patch to add
|
||||
two more pixels of spacing between action area and vbox of
|
||||
preferences dialog.
|
||||
|
||||
2003-07-24 Pasupathi Duraisamy <pasupathi.duraisamy@wipro.com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade:
|
||||
Allow only numeric values in spinbutton.
|
||||
Fixes bugzilla bug# 118175
|
||||
|
||||
2003-07-17 Dennis Cranston <dennis_cranston at yahoo com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade,
|
||||
accessibility-keyboard.c: HIG fixes for ui-review bug
|
||||
report #98915.
|
||||
|
||||
2003-07-16 Dennis Cranston <dennis_cranston at yahoo com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade: Adjust widget
|
||||
padding to make dialog a little more HIG compliant.
|
||||
|
||||
2003-07-07 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.4
|
||||
|
||||
2003-06-24 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.3
|
||||
|
||||
2003-05-07 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.1
|
||||
|
||||
2003-05-05 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c: Merge fix
|
||||
for bug #110266.
|
||||
|
||||
2003-04-30 Alex Duggan <aldug@astrolinux.com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c: use appropriate
|
||||
window border icon.
|
||||
|
||||
2003-04-30 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c: Fix build
|
||||
on Solaris. Fixes bug #106196.
|
||||
|
||||
2003-02-21 Calum Benson <calum.benson@sun.com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade:
|
||||
HIG-ified frames and labels.
|
||||
|
||||
Tue Feb 4 17:09:18 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* Release 2.2.0.1
|
||||
|
||||
Tue Jan 21 01:15:14 2003 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* Release 2.2.0
|
||||
|
||||
Thu Jan 16 02:41:09 2003 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* Release 2.1.7
|
||||
|
||||
2003-01-10 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.6
|
||||
|
||||
2003-01-08 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=96483
|
||||
* accessibility-keyboard.c : sigh. The defaults apparently need to be
|
||||
0 too.
|
||||
|
||||
2003-01-08 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=96484
|
||||
* accessibility-keyboard.c : make 0 min for slow and bounce
|
||||
|
||||
2003-01-07 Abel Cheung <maddog@linux.org.hk>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c (xkb_enabled): Fix typo
|
||||
in error msg dialog.
|
||||
|
||||
2002-12-18 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.5
|
||||
|
||||
2002-11-23 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.3
|
||||
|
||||
2002-11-13 Pasupathi Duraisamy <pasupathi.duraisamy@wipro.com>
|
||||
|
||||
* accessibility-keyboard.c : Tweaked the incremental values
|
||||
of spin button to 10. Fixes #95511
|
||||
|
||||
2002-11-02 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.2
|
||||
|
||||
2002-11-02 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c : Merge in Calum's new layout
|
||||
* gnome-accessibility-keyboard-properties.glade : ditto.
|
||||
|
||||
2002-10-21 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.1
|
||||
|
||||
2002-10-11 Balamurali Viswanathan <balamurali.viswanathan@wipro.com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c (xkb_enabled): Dismiss
|
||||
the XKB extensions warning dialog. Fixes #95069
|
||||
|
||||
2002-10-01 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.0.1
|
||||
|
||||
2002-09-26 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade : add ellipsis for CDE
|
||||
import and Repeat key buttons.
|
||||
|
||||
2002-09-25 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade : remove spaces before
|
||||
colons and fix the title.
|
||||
|
||||
2002-09-24 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c (load_CDE_file) : blah the
|
||||
XrmGetFileDatabase is implementation specific in its handling of
|
||||
invalid files. Add a hack that if the imported file did not contain
|
||||
any resources it was invalid.
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade : add mnemonic_widget
|
||||
for mousekeys_init_delay_title. Remove the atkrelations for things
|
||||
with mnemonic_widget.
|
||||
|
||||
2002-09-11 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade : Fix conflicting
|
||||
accelerators.
|
||||
|
||||
* accessibility-keyboard.c (setup_dialog) : connect the simple items
|
||||
before the master.
|
||||
(cb_master_enable_toggle) : desensitize the subfeature content if the
|
||||
master switch is disabled.
|
||||
|
||||
2002-09-09 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c (main) : add a warning if
|
||||
xkb is not available.
|
||||
|
||||
2002-09-09 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c : on 2nd thought lets disable the 'beep on
|
||||
feature change' if the master switch is off.
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=92488
|
||||
* gnome-accessibility-keyboard-properties.glade : tweak accelerators
|
||||
|
||||
2002-09-09 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=90936
|
||||
* gnome-accessibility-keyboard-properties.glade : Add mnemonic_widget
|
||||
assignments and fix a typo.
|
||||
|
||||
2002-08-28 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=91854
|
||||
* accessibility-keyboard.c : the max slow key delay is 500ms.
|
||||
We clamp that in the settings daemon. Fix the ui to reflect that.
|
||||
|
||||
2002-08-21 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.0
|
||||
|
||||
2002-08-19 Ross Burton <ross@burtonini.com>
|
||||
|
||||
* accessibility-keyboard.desktop.in: Fix the desktop file so that
|
||||
it validates.
|
||||
|
||||
2002-08-05 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade : Restore the master
|
||||
toggle.
|
||||
|
||||
* accessibility-keyboard.c (setup_dialog) : support the master toggle.
|
||||
(cb_master_enable_toggle) : new.
|
||||
|
||||
2002-08-01 jacob berkman <jacob@ximian.com>
|
||||
|
||||
* accessibility-keyboard.c (setup_accessX_dialog): fix widget name
|
||||
for the keyboard capplet button
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c (dialog_response):
|
||||
don't quit when the import accessx button is clicked (#89358)
|
||||
|
||||
2002-06-21 Satyajit Kanungo <satyajit.kanungo@wipro.com>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c :
|
||||
Changed the help link to point to the correct document (#85895)
|
||||
|
||||
2002-06-10 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c : tweak the layout as requested and adjust
|
||||
the max slowkey delay to 500 to avoid losing the keyboard due to some
|
||||
sort of an X problem.
|
||||
|
||||
2002-06-17 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.0.0
|
||||
|
||||
Sun May 26 11:44:41 2002 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c (main): use APPID
|
||||
instead of argv[0]
|
||||
|
||||
2002-05-08 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.c (dialog_response) : fix
|
||||
path to help.
|
||||
|
||||
2002-04-24 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c : adjust the defaults.
|
||||
|
||||
2002-04-18 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c (setup_accessX_dialog) : Use 'clicked'
|
||||
rather than 'activated' for the file sel.
|
||||
|
||||
2002-04-10 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade2 (</) : slim down the
|
||||
tooltips.
|
||||
|
||||
Wed Apr 10 18:02:29 2002 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* accessibility-keyboard.desktop.in (Exec): s/gnome2/gnome
|
||||
|
||||
2002-03-30 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gnome-accessibility-keyboard-properties.glade2 : rename Sample -> Text
|
||||
because that makes more sense.
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=76315
|
||||
* accessibility-keyboard.desktop.in : rename from AccessX -> Keyboard
|
||||
|
||||
2002-03-29 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c (setup_dialog) : spelling error.
|
||||
(CONFIG_ROOT) : fix spelling error in the schema.
|
||||
|
||||
2002-03-29 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c : tweak the mouse key slider ranges
|
||||
max_speed : 100 pixels every 10 msec is plenty fast Limit things to
|
||||
1..100 default 10 step 5
|
||||
accel_time : 10..5000 default 300 step 100
|
||||
init_delay : 10..5000 default 300 step 100
|
||||
|
||||
2002-03-28 jacob berkman <jacob@ximian.com>
|
||||
|
||||
* accessibility-keyboard.c: on solaris Xresource.h sez /* You must
|
||||
include <X11/Xlib.h> before including this file */
|
||||
|
||||
2002-03-25 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* accessibility-keyboard.c (setup_accessX_dialog) : Only load the
|
||||
necessary toplevel widget in the non-dialog case.
|
||||
(setup_dialog) : pass as_dialog to the sub-init routines.
|
||||
(setup_images) : only load widgets appropriate for the current state.
|
||||
(setup_ranges) : ditto, and be more vocal about invalid glade.
|
||||
(setup_simple_toggles) : ditto.
|
||||
(setup_toggles) : ditto.
|
||||
@@ -1,36 +0,0 @@
|
||||
noinst_LIBRARIES = libaccessibility-keyboard.a
|
||||
|
||||
libaccessibility_keyboard_a_SOURCES = \
|
||||
accessibility-keyboard.c \
|
||||
accessibility-keyboard.h
|
||||
|
||||
# in case we need to forward port the sun accessX extension
|
||||
# AccessXcomm.c
|
||||
|
||||
bin_PROGRAMS = gnome-accessibility-keyboard-properties
|
||||
|
||||
gnome_accessibility_keyboard_properties_SOURCES = gnome-accessibility-keyboard-properties.c
|
||||
gnome_accessibility_keyboard_properties_LDADD = \
|
||||
libaccessibility-keyboard.a $(GNOMECC_CAPPLETS_LIBS)
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
pixmapdir = $(GNOMECC_PIXMAPS_DIR)
|
||||
pixmap_DATA = \
|
||||
accessibility-keyboard-togglekey.png \
|
||||
accessibility-keyboard-mousekey.png \
|
||||
accessibility-keyboard-slowkey.png \
|
||||
accessibility-keyboard-stickykey.png \
|
||||
accessibility-keyboard-bouncekey.png
|
||||
|
||||
Gladedir = $(GNOMECC_GLADE_DIR)
|
||||
Glade_DATA = gnome-accessibility-keyboard-properties.glade
|
||||
|
||||
desktopdir = $(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) $(Desktop_in_files) $(pixmap_DATA)
|
||||
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
@@ -1,474 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* accessibility-keyboard.c
|
||||
* Copyright (C) 2002 Ximian, Inc.
|
||||
*
|
||||
* Written by: Jody Goldberg <jody@gnome.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <gnome.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
#include <glade/glade.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xresource.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "capplet-util.h"
|
||||
#include "capplet-stock-icons.h"
|
||||
#include "gconf-property-editor.h"
|
||||
#include "activate-settings-daemon.h"
|
||||
|
||||
#define CONFIG_ROOT "/desktop/gnome/accessibility/keyboard"
|
||||
|
||||
static struct {
|
||||
char const * const checkbox;
|
||||
char const * const image;
|
||||
char const * const image_file;
|
||||
char const * const gconf_key;
|
||||
char const * const content [3];
|
||||
gboolean always_enabled;
|
||||
} const features [] = {
|
||||
{ "repeatkeys_enable", "repeatkeys_image", KEYBOARD_REPEAT,
|
||||
"/desktop/gnome/peripherals/keyboard/repeat",
|
||||
{ "repeatkeys_table", NULL, NULL }, TRUE },
|
||||
{ "bouncekeys_enable", "bouncekeys_image", ACCESSX_KEYBOARD_BOUNCE,
|
||||
CONFIG_ROOT "/bouncekeys_enable",
|
||||
{ "bouncekey_table", NULL, NULL }, FALSE },
|
||||
{ "slowkeys_enable", "slowkeys_image", ACCESSX_KEYBOARD_SLOW,
|
||||
CONFIG_ROOT "/slowkeys_enable",
|
||||
{ "slowkeys_table", NULL, NULL }, FALSE },
|
||||
{ "mousekeys_enable", "mousekeys_image", ACCESSX_KEYBOARD_MOUSE,
|
||||
CONFIG_ROOT "/mousekeys_enable",
|
||||
{ "mousekeys_table", NULL, NULL }, FALSE },
|
||||
{ "stickykeys_enable", "stickykeys_image", ACCESSX_KEYBOARD_STICK,
|
||||
CONFIG_ROOT "/stickykeys_enable",
|
||||
{ "stickeykeys_table", NULL, NULL }, FALSE },
|
||||
{ "togglekeys_enable", "togglekeys_image", ACCESSX_KEYBOARD_TOGGLE,
|
||||
CONFIG_ROOT "/togglekeys_enable",
|
||||
{ NULL, NULL, NULL }, FALSE },
|
||||
{ "timeout_enable", NULL, NULL,
|
||||
CONFIG_ROOT "/timeout_enable",
|
||||
{ "timeout_slide", "timeout_spin", "timeout_label" }, FALSE },
|
||||
{ "feature_state_change_beep", NULL, NULL,
|
||||
CONFIG_ROOT "/feature_state_change_beep",
|
||||
{ NULL, NULL, NULL }, FALSE }
|
||||
};
|
||||
|
||||
static struct {
|
||||
char const * const slide;
|
||||
char const * const spin;
|
||||
int default_val;
|
||||
int min_val;
|
||||
int max_val;
|
||||
int step_size;
|
||||
char const * const gconf_key;
|
||||
} const ranges [] = {
|
||||
{ "repeatkeys_delay_slide", "repeatkeys_delay_spin", 500, 100, 1500, 10,
|
||||
"/desktop/gnome/peripherals/keyboard/delay" },
|
||||
{ "repeatkeys_rate_slide", "repeatkeys_rate_spin", 90, 10, 110, 10,
|
||||
"/desktop/gnome/peripherals/keyboard/rate" },
|
||||
{ "bouncekeys_delay_slide", "bouncekeys_delay_spin", 0, 0, 900, 10,
|
||||
CONFIG_ROOT "/bouncekeys_delay" },
|
||||
{ "slowkeys_delay_slide", "slowkeys_delay_spin", 0, 0, 500, 10,
|
||||
CONFIG_ROOT "/slowkeys_delay" },
|
||||
/* WARNING anything larger than approx 512 seems to loose all keyboard input */
|
||||
{ "mousekeys_max_speed_slide", "mousekeys_max_speed_spin", 300, 10, 500, 10,
|
||||
CONFIG_ROOT "/mousekeys_max_speed" },
|
||||
{ "mousekeys_accel_time_slide", "mousekeys_accel_time_spin", 300, 10, 3000, 10,
|
||||
CONFIG_ROOT "/mousekeys_accel_time" },
|
||||
{ "mousekeys_init_delay_slide", "mousekeys_init_delay_spin", 300, 10, 5000, 10,
|
||||
CONFIG_ROOT "/mousekeys_init_delay" },
|
||||
{ "timeout_slide", "timeout_spin", 200, 10, 500, 10,
|
||||
CONFIG_ROOT "/timeout" },
|
||||
};
|
||||
|
||||
static void
|
||||
set_sensitive (GladeXML *dialog, char const *name, gboolean state)
|
||||
{
|
||||
if (name != NULL)
|
||||
gtk_widget_set_sensitive (WID (name), state);
|
||||
}
|
||||
|
||||
/**
|
||||
* cb_feature_toggled :
|
||||
*
|
||||
* NOTE : for this to work the toggle MUST be initialized to active in the
|
||||
* glade file. That way if the gconf setting is FALSE the toggle will fire.
|
||||
*/
|
||||
static void
|
||||
cb_feature_toggled (GtkToggleButton *btn, gpointer feature_index)
|
||||
{
|
||||
gboolean const state =
|
||||
(GTK_WIDGET_STATE (btn) != GTK_STATE_INSENSITIVE) &&
|
||||
gtk_toggle_button_get_active (btn);
|
||||
GladeXML *dialog = g_object_get_data (G_OBJECT (btn), "dialog");
|
||||
int feature, i;
|
||||
|
||||
g_return_if_fail (dialog != NULL);
|
||||
|
||||
feature = GPOINTER_TO_INT (feature_index);
|
||||
|
||||
if (features [feature].image != NULL)
|
||||
set_sensitive (dialog, features [feature].image, state);
|
||||
for (i = G_N_ELEMENTS (features [feature].content) ; i-- > 0 ; )
|
||||
set_sensitive (dialog, features [feature].content [i], state);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_toggles (GladeXML *dialog, GConfChangeSet *changeset)
|
||||
{
|
||||
GObject *peditor;
|
||||
GtkWidget *checkbox;
|
||||
GtkWidget *checkbox_label;
|
||||
int i = G_N_ELEMENTS (features);
|
||||
|
||||
while (i-- > 0) {
|
||||
checkbox = WID (features [i].checkbox);
|
||||
|
||||
g_return_if_fail (checkbox != NULL);
|
||||
|
||||
/* you can't do this from glade */
|
||||
checkbox_label = gtk_bin_get_child (GTK_BIN (checkbox));
|
||||
g_object_set (G_OBJECT (checkbox_label), "use_markup", TRUE, NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (checkbox), "dialog", dialog);
|
||||
g_signal_connect (G_OBJECT (checkbox),
|
||||
"toggled",
|
||||
G_CALLBACK (cb_feature_toggled), GINT_TO_POINTER (i));
|
||||
peditor = gconf_peditor_new_boolean (changeset,
|
||||
(gchar *)features [i].gconf_key, checkbox, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_simple_toggles (GladeXML *dialog, GConfChangeSet *changeset)
|
||||
{
|
||||
static struct {
|
||||
char const *gconf_key;
|
||||
char const *checkbox;
|
||||
} const simple_toggles [] = {
|
||||
{ CONFIG_ROOT "/bouncekeys_beep_reject", "bouncekeys_beep_reject" },
|
||||
|
||||
{ CONFIG_ROOT "/slowkeys_beep_press", "slowkeys_beep_press" },
|
||||
{ CONFIG_ROOT "/slowkeys_beep_accept", "slowkeys_beep_accept" },
|
||||
{ CONFIG_ROOT "/slowkeys_beep_reject", "slowkeys_beep_reject" },
|
||||
|
||||
{ CONFIG_ROOT "/stickykeys_two_key_off", "stickykeys_two_key_off" },
|
||||
{ CONFIG_ROOT "/stickykeys_modifier_beep", "stickykeys_modifier_beep" },
|
||||
};
|
||||
int i = G_N_ELEMENTS (simple_toggles);
|
||||
while (i-- > 0) {
|
||||
GtkWidget *w = WID (simple_toggles [i].checkbox);
|
||||
|
||||
g_return_if_fail (w != NULL);
|
||||
|
||||
gconf_peditor_new_boolean (changeset,
|
||||
(gchar *) simple_toggles [i].gconf_key,
|
||||
w, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_ranges (GladeXML *dialog, GConfChangeSet *changeset)
|
||||
{
|
||||
GObject *peditor;
|
||||
GtkWidget *slide, *spin;
|
||||
GtkAdjustment *adjustment;
|
||||
int i = G_N_ELEMENTS (ranges);
|
||||
|
||||
while (i-- > 0) {
|
||||
slide = WID (ranges [i].slide);
|
||||
spin = WID (ranges [i].spin);
|
||||
g_return_if_fail (slide != NULL);
|
||||
g_return_if_fail (spin != NULL);
|
||||
|
||||
adjustment = gtk_range_get_adjustment (GTK_RANGE (slide));
|
||||
|
||||
g_return_if_fail (adjustment != NULL);
|
||||
|
||||
adjustment->value = ranges [i].default_val;
|
||||
adjustment->lower = ranges [i].min_val;
|
||||
adjustment->upper = ranges [i].max_val + ranges [i].step_size;
|
||||
adjustment->step_increment = ranges [i].step_size;
|
||||
adjustment->page_increment = ranges [i].step_size;
|
||||
adjustment->page_size = ranges [i].step_size;
|
||||
|
||||
gtk_adjustment_changed (adjustment);
|
||||
gtk_spin_button_configure (GTK_SPIN_BUTTON (spin), adjustment,
|
||||
ranges [i].step_size, 0);
|
||||
peditor = gconf_peditor_new_numeric_range (changeset,
|
||||
(gchar *)ranges [i].gconf_key, slide,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_images (GladeXML *dialog)
|
||||
{
|
||||
int i = G_N_ELEMENTS (features);
|
||||
while (i-- > 0)
|
||||
if (features [i].image != NULL)
|
||||
gtk_image_set_from_stock (GTK_IMAGE (WID (features [i].image)),
|
||||
features [i].image_file,
|
||||
keyboard_capplet_icon_get_size ());
|
||||
}
|
||||
|
||||
static void
|
||||
cb_launch_mouse_capplet (GtkButton *button, GtkWidget *dialog)
|
||||
{
|
||||
GError *err = NULL;
|
||||
if (!g_spawn_command_line_async ("gnome-mouse-properties", &err))
|
||||
capplet_error_dialog (GTK_WINDOW (gtk_widget_get_toplevel (dialog)),
|
||||
_("There was an error launching the mouse preferences dialog: %s"),
|
||||
err);
|
||||
}
|
||||
|
||||
static void
|
||||
cb_master_enable_toggle (GtkToggleButton *btn, GladeXML *dialog)
|
||||
{
|
||||
int i = G_N_ELEMENTS (features);
|
||||
gboolean flag = gtk_toggle_button_get_active (btn);
|
||||
GtkWidget *w;
|
||||
|
||||
while (i-- > 0) {
|
||||
if (!features [i].always_enabled) {
|
||||
w = WID (features [i].checkbox);
|
||||
gtk_widget_set_sensitive (w, flag);
|
||||
cb_feature_toggled (GTK_TOGGLE_BUTTON (w), GINT_TO_POINTER (i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_dialog (GladeXML *dialog, GConfChangeSet *changeset)
|
||||
{
|
||||
GtkWidget *master_enable = WID ("master_enable");
|
||||
|
||||
capplet_init_stock_icons ();
|
||||
setup_images (dialog);
|
||||
setup_ranges (dialog, changeset);
|
||||
setup_toggles (dialog, changeset);
|
||||
setup_simple_toggles (dialog, changeset);
|
||||
|
||||
g_signal_connect (master_enable,
|
||||
"toggled",
|
||||
G_CALLBACK (cb_master_enable_toggle), dialog);
|
||||
gconf_peditor_new_boolean (changeset,
|
||||
CONFIG_ROOT "/enable",
|
||||
GTK_WIDGET (master_enable), NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
static gboolean
|
||||
xrm_get_bool (GConfClient *client, XrmDatabase *db, char const *gconf_key,
|
||||
char const *res_str, char const *class_str)
|
||||
{
|
||||
XrmValue resourceValue;
|
||||
char *res;
|
||||
|
||||
if (!XrmGetResource (*db, res_str, class_str, &res, &resourceValue))
|
||||
return FALSE;
|
||||
gconf_client_set_bool (client, gconf_key,
|
||||
!g_ascii_strcasecmp (resourceValue.addr, "True"), NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
xrm_get_int (GConfClient *client, XrmDatabase *db, char const *gconf_key,
|
||||
char const *res_str, char const *class_str, float scale)
|
||||
{
|
||||
XrmValue resourceValue;
|
||||
char *res;
|
||||
int value, log_scale;
|
||||
char resource [256];
|
||||
|
||||
snprintf (resource, sizeof (resource), "%s.value", res_str);
|
||||
if (!XrmGetResource (*db, resource, class_str, &res, &resourceValue))
|
||||
return FALSE;
|
||||
value = atoi (resourceValue.addr);
|
||||
|
||||
snprintf (resource, sizeof (resource), "%s.decimalPoints", res_str);
|
||||
if (!XrmGetResource (*db, resource, class_str, &res, &resourceValue))
|
||||
return FALSE;
|
||||
log_scale = atoi (resourceValue.addr);
|
||||
|
||||
while (log_scale-- > 0)
|
||||
scale /= 10.;
|
||||
|
||||
gconf_client_set_int (client, gconf_key, value, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* This loads the current users XKB settings from their file */
|
||||
static gboolean
|
||||
load_CDE_file (GtkFileChooser *fchooser)
|
||||
{
|
||||
char *file = gtk_file_chooser_get_filename (fchooser);
|
||||
GConfClient *client;
|
||||
XrmDatabase db;
|
||||
gboolean found = FALSE;
|
||||
|
||||
if (!(db = XrmGetFileDatabase (file))) {
|
||||
GtkWidget *warn = gtk_message_dialog_new (
|
||||
gtk_window_get_transient_for (GTK_WINDOW (fchooser)),
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
|
||||
_("Unable to import AccessX settings from file '%s'"),
|
||||
file);
|
||||
g_signal_connect (warn,
|
||||
"response",
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (warn);
|
||||
g_free (file);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
client = gconf_client_get_default ();
|
||||
gconf_client_set_bool (client, CONFIG_ROOT "/enable", TRUE, NULL);
|
||||
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/feature_state_change_beep",
|
||||
"*SoundOnOffToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/timeout_enable",
|
||||
"*TimeOutToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/stickykeys_enable",
|
||||
"*StickyKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/mousekeys_enable",
|
||||
"*MouseKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/togglekeys_enable",
|
||||
"*ToggleKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/slowkeys_enable",
|
||||
"*SlowKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/bouncekeys_enable",
|
||||
"*BounceKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/stickykeys_modifier_beep",
|
||||
"*StickyModSoundToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/stickykeys_two_key_off",
|
||||
"*StickyTwoKeysToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/slowkeys_beep_press",
|
||||
"*SlowKeysOnPressToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/slowkeys_beep_accept",
|
||||
"*SlowKeysOnAcceptToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
found |= xrm_get_int (client, &db, CONFIG_ROOT "/timeout",
|
||||
"*TimeOutScale", "AccessX*XmScale", 60);
|
||||
found |= xrm_get_int (client, &db, CONFIG_ROOT "/mousekeys_max_speed",
|
||||
"*MouseMaxSpeedScale", "AccessX*XmScale", 1);
|
||||
found |= xrm_get_int (client, &db, CONFIG_ROOT "/mousekeys_accel_time",
|
||||
"*MouseAccelScale", "AccessX*XmScale", 1);
|
||||
found |= xrm_get_int (client, &db, CONFIG_ROOT "/mousekeys_init_delay",
|
||||
"*MouseDelayScale", "AccessX*XmScale", 1);
|
||||
found |= xrm_get_int (client, &db, CONFIG_ROOT "/slowkeys_delay",
|
||||
"*KRGSlowKeysDelayScale", "AccessX*XmScale", 1000);
|
||||
found |= xrm_get_int (client, &db, CONFIG_ROOT "/bouncekeys_delay",
|
||||
"*KRGDebounceScale", "AccessX*XmScale", 1000);
|
||||
|
||||
/* Set the master enable flag last */
|
||||
found |= xrm_get_bool (client, &db, CONFIG_ROOT "/enable",
|
||||
"*EnableAccessXToggle.set", "AccessX*ToggleButtonGadget.XmCSet");
|
||||
|
||||
if (!found) {
|
||||
/* it would be nice to have a better message bu that would
|
||||
* break string freeze
|
||||
*/
|
||||
GtkWidget *warn = gtk_message_dialog_new (
|
||||
gtk_window_get_transient_for (GTK_WINDOW (fchooser)),
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
|
||||
_("Unable to import AccessX settings from file '%s'"),
|
||||
file);
|
||||
g_signal_connect (warn,
|
||||
"response",
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (warn);
|
||||
g_free (file);
|
||||
return FALSE;
|
||||
}
|
||||
g_free(file);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fchooser_handle_response (GtkFileChooser *fchooser, gint response, gpointer data)
|
||||
{
|
||||
char *file_name;
|
||||
|
||||
if (response == GTK_RESPONSE_OK) {
|
||||
file_name = gtk_file_chooser_get_filename (fchooser);
|
||||
|
||||
/* Change into directory if that's what user selected */
|
||||
if (g_file_test (file_name, G_FILE_TEST_IS_DIR))
|
||||
gtk_file_chooser_set_current_folder (fchooser, file_name);
|
||||
else if (load_CDE_file (fchooser))
|
||||
gtk_widget_destroy (GTK_WIDGET (fchooser));
|
||||
|
||||
g_free (file_name);
|
||||
} else {
|
||||
gtk_widget_destroy (GTK_WIDGET (fchooser));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cb_load_CDE_file (GtkButton *button, GtkWidget *dialog)
|
||||
{
|
||||
GtkFileChooser *fchooser = GTK_FILE_CHOOSER (
|
||||
gtk_file_chooser_dialog_new (_("Import Feature Settings File"),
|
||||
GTK_WINDOW (gtk_widget_get_toplevel (dialog)),
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
_("_Import"), GTK_RESPONSE_OK,
|
||||
NULL));
|
||||
|
||||
gtk_window_set_position (GTK_WINDOW (fchooser), GTK_WIN_POS_MOUSE);
|
||||
gtk_window_set_modal (GTK_WINDOW (fchooser), TRUE);
|
||||
g_signal_connect (G_OBJECT (fchooser),
|
||||
"response",
|
||||
G_CALLBACK (fchooser_handle_response), NULL);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (fchooser));
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
GtkWidget *
|
||||
setup_accessX_dialog (GConfChangeSet *changeset)
|
||||
{
|
||||
GConfClient *client;
|
||||
char const *toplevel_name = "accessX_dialog";
|
||||
GladeXML *dialog = glade_xml_new (GNOMECC_DATA_DIR
|
||||
"/interfaces/gnome-accessibility-keyboard-properties.glade",
|
||||
toplevel_name, NULL);
|
||||
GtkWidget *toplevel = WID (toplevel_name);
|
||||
|
||||
client = gconf_client_get_default ();
|
||||
gconf_client_add_dir (client, CONFIG_ROOT, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
|
||||
|
||||
setup_dialog (dialog, changeset);
|
||||
|
||||
g_signal_connect (G_OBJECT (WID ("load_CDE_file")),
|
||||
"clicked",
|
||||
G_CALLBACK (cb_load_CDE_file), toplevel);
|
||||
g_signal_connect (G_OBJECT (WID ("launch_mouse_capplet")),
|
||||
"clicked",
|
||||
G_CALLBACK (cb_launch_mouse_capplet), toplevel);
|
||||
|
||||
return toplevel;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
_Name=Keyboard
|
||||
_Comment=Set your keyboard accessibility preferences
|
||||
Exec=gnome-accessibility-keyboard-properties
|
||||
Icon=gnome-settings-accessibility-keyboard
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;Application;Settings;Accessibility;
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=control-center
|
||||
X-GNOME-Bugzilla-Component=Keyboard Accessibility
|
||||
@@ -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 */
|
||||
@@ -1,115 +0,0 @@
|
||||
/* -*- mode: c; style: linux -*- */
|
||||
|
||||
/* gnome-accessibility-keyboard-properties.c
|
||||
* Copyright (C) 2002 Ximian, Inc.
|
||||
*
|
||||
* Written by: Jody Goldberg <jody@gnome.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <gnome.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
|
||||
#include <capplet-util.h>
|
||||
#include <activate-settings-daemon.h>
|
||||
#include "accessibility-keyboard.h"
|
||||
|
||||
#ifdef HAVE_X11_EXTENSIONS_XKB_H
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/XKBlib.h>
|
||||
# include <X11/extensions/XKBstr.h>
|
||||
# include <gdk/gdk.h>
|
||||
# include <gdk/gdkx.h>
|
||||
|
||||
static void
|
||||
xkb_enabled (void)
|
||||
{
|
||||
gboolean have_xkb = FALSE;
|
||||
int opcode, errorBase, major, minor, xkbEventBase;
|
||||
|
||||
gdk_error_trap_push ();
|
||||
have_xkb = XkbQueryExtension (GDK_DISPLAY (),
|
||||
&opcode, &xkbEventBase, &errorBase, &major, &minor)
|
||||
&& XkbUseExtension (GDK_DISPLAY (), &major, &minor);
|
||||
XSync (GDK_DISPLAY (), FALSE);
|
||||
gdk_error_trap_pop ();
|
||||
|
||||
if (!have_xkb) {
|
||||
GtkWidget *warn = gtk_message_dialog_new (NULL, 0,
|
||||
GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
|
||||
_("This system does not seem to have the XKB extension. The keyboard accessibility features will not operate without it."));
|
||||
gtk_dialog_run (GTK_DIALOG (warn));
|
||||
gtk_widget_destroy (warn);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
dialog_response (GtkWidget *widget,
|
||||
gint response_id,
|
||||
GConfChangeSet *changeset)
|
||||
{
|
||||
switch (response_id) {
|
||||
case GTK_RESPONSE_HELP:
|
||||
capplet_help (GTK_WINDOW (widget),
|
||||
"user-guide.xml",
|
||||
"goscustaccess-6");
|
||||
break;
|
||||
case GTK_RESPONSE_DELETE_EVENT:
|
||||
case GTK_RESPONSE_CLOSE:
|
||||
gtk_main_quit ();
|
||||
break;
|
||||
default:
|
||||
/* Import CDE AccessX File */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GConfChangeSet *changeset;
|
||||
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
textdomain (GETTEXT_PACKAGE);
|
||||
|
||||
gnome_program_init ("gnome-accessibility-keyboard-properties", VERSION,
|
||||
LIBGNOMEUI_MODULE, argc, argv,
|
||||
GNOME_PARAM_APP_DATADIR, GNOMECC_DATA_DIR,
|
||||
NULL);
|
||||
activate_settings_daemon ();
|
||||
|
||||
#ifdef HAVE_X11_EXTENSIONS_XKB_H
|
||||
xkb_enabled ();
|
||||
#endif
|
||||
|
||||
changeset = NULL;
|
||||
dialog = setup_accessX_dialog (changeset);
|
||||
g_signal_connect (G_OBJECT (dialog),
|
||||
"response",
|
||||
G_CALLBACK (dialog_response), changeset);
|
||||
capplet_set_icon (dialog, "accessibility-keyboard-capplet.png");
|
||||
gtk_widget_show_all (dialog);
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,3 +1,48 @@
|
||||
2004-03-10 Rodney Dawes <dobey@ximian.com>
|
||||
|
||||
* gnome-wp-item.c (gnome_wp_item_get_thumbnail): Reload the thumbnail
|
||||
pixbuf after generating it with the thumbnail system, so that we get
|
||||
all of the pixbuf options set correctly
|
||||
|
||||
2004-03-10 Rodney Dawes <dobey@ximian.com>
|
||||
|
||||
* gnome-wp-capplet.c (wp_props_load_wallpaper): Update the description
|
||||
after getting the thumbnail, so we have the dimensions info
|
||||
(wallpaper_properties_init): TreeView is buggy, so we need to not set
|
||||
the vertical-separator style property for it
|
||||
* gnome-wp-item.c: Include <config.h> and <gnome.h> here
|
||||
(collect_save_options): Add a function to set all of the pixbuf options
|
||||
for the thumbnail pixbuf properly, so we can save them back out
|
||||
(gnome_wp_item_get_thumbnail): Get rid of the rw and rh variables
|
||||
Initialize all of the width/height variables to 0
|
||||
Add a new pixbuf variable for loading the original image to get the
|
||||
dimensions of it, so we can do thumbnailing more properly
|
||||
Use a LIST_IMAGE_WIDTH define, for the width of the images in the list
|
||||
Just return the bgpixbuf if we are creating the "No Wallpaper" thumb
|
||||
Save the thumbnail back out with the dimensions for the original image
|
||||
If our image is smaller than the list thumbnail, then just use 1.0 as
|
||||
the ratio for scaling the image for tiling/etc...
|
||||
Use the new API to do scaling inside the center/tile functions
|
||||
(gnome_wp_item_update_description): Put the original image dimensions
|
||||
in the image's description
|
||||
* gnome-wp-utils.[ch] (gnome_wp_pixbuf_tile):
|
||||
(gnome_wp_pixbuf_center): Add API to do the scaling inside these calls
|
||||
|
||||
2004-03-09 Rodney Dawes <dobey@ximian.com>
|
||||
|
||||
* gnome-wp-capplet.c (gnome_wp_scale_type_changed): Regenerate the
|
||||
thumbnail in the list when we change scaling type now
|
||||
(wallpaper_properties_init): Add GtkFileFilter support (needs love)
|
||||
* gnome-wp-item.c (gnome_wp_item_get_thumbnail): Fix up the code to
|
||||
generate the thumbnails for the list a bit, so that we have sexy
|
||||
thumbnails that look exactly like how the image would, on-screen
|
||||
* gnome-wp-item.h (GnomeWPItem): store the original image's width
|
||||
and height in the item, so we can avoid reopening the original image
|
||||
every time we generate the thumbnail, on systems where the thumbnail
|
||||
doesn't contain the appropriate information
|
||||
* gnome-wp-utils.c (gnome_wp_pixbuf_center): Fix up the code here to
|
||||
handle both alpha and non-alpha images, and center them appropriately
|
||||
|
||||
2004-03-04 Rodney Dawes <dobey@ximian.com>
|
||||
|
||||
* background-properties-capplet.c:
|
||||
|
||||
@@ -332,6 +332,7 @@ static void wp_props_load_wallpaper (gchar * key,
|
||||
gtk_list_store_append (GTK_LIST_STORE (capplet->model), &iter);
|
||||
|
||||
pixbuf = gnome_wp_item_get_thumbnail (item, capplet->thumbs);
|
||||
gnome_wp_item_update_description (item);
|
||||
|
||||
if (pixbuf != NULL) {
|
||||
gtk_list_store_set (GTK_LIST_STORE (capplet->model), &iter,
|
||||
@@ -525,6 +526,7 @@ static void wallpaper_properties_clicked (GtkWidget * dialog,
|
||||
static void gnome_wp_scale_type_changed (GtkMenuShell * shell,
|
||||
GnomeWPCapplet * capplet) {
|
||||
GnomeWPItem * item = NULL;
|
||||
GdkPixbuf * pixbuf;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel * model;
|
||||
GtkTreeSelection * selection;
|
||||
@@ -558,6 +560,11 @@ static void gnome_wp_scale_type_changed (GtkMenuShell * shell,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pixbuf = gnome_wp_item_get_thumbnail (item, capplet->thumbs);
|
||||
gtk_list_store_set (GTK_LIST_STORE (capplet->model), &iter,
|
||||
0, pixbuf,
|
||||
-1);
|
||||
g_object_unref (pixbuf);
|
||||
gconf_client_set_string (capplet->client, WP_OPTIONS_KEY,
|
||||
item->options, NULL);
|
||||
}
|
||||
@@ -1142,10 +1149,12 @@ static void wallpaper_properties_init (void) {
|
||||
GdkPixbuf * pixbuf;
|
||||
GdkCursor * cursor;
|
||||
gchar * icofile;
|
||||
#if GTK_CHECK_VERSION (2, 3, 0)
|
||||
GtkFileFilter * filter;
|
||||
#endif
|
||||
|
||||
gtk_rc_parse_string ("style \"wp-tree-defaults\" {\n"
|
||||
" GtkTreeView::horizontal-separator = 6\n"
|
||||
" GtkTreeView::vertical-separator = 6\n"
|
||||
"} widget_class \"*TreeView*\""
|
||||
" style \"wp-tree-defaults\"\n\n"
|
||||
"style \"wp-dialog-defaults\" {\n"
|
||||
@@ -1454,6 +1463,11 @@ static void wallpaper_properties_init (void) {
|
||||
NULL);
|
||||
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (capplet->filesel),
|
||||
TRUE);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_set_name (filter, _("Images"));
|
||||
gtk_file_filter_add_mime_type (filter, "image/*");
|
||||
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (capplet->filesel), filter);
|
||||
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (capplet->filesel), filter);
|
||||
#else
|
||||
capplet->filesel = gtk_file_selection_new (_("Add Wallpapers"));
|
||||
gtk_file_selection_set_select_multiple (GTK_FILE_SELECTION (capplet->filesel),
|
||||
|
||||
@@ -18,11 +18,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gnome-wp-item.h"
|
||||
#include "gnome-wp-utils.h"
|
||||
#include <config.h>
|
||||
|
||||
#include <gnome.h>
|
||||
#include <string.h>
|
||||
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
|
||||
|
||||
#include "gnome-wp-item.h"
|
||||
#include "gnome-wp-utils.h"
|
||||
|
||||
void gnome_wp_item_free (GnomeWPItem * item) {
|
||||
if (item == NULL) {
|
||||
return;
|
||||
@@ -49,38 +53,92 @@ void gnome_wp_item_free (GnomeWPItem * item) {
|
||||
item = NULL;
|
||||
}
|
||||
|
||||
static void collect_save_options (GdkPixbuf * pixbuf,
|
||||
gchar *** keys,
|
||||
gchar *** vals,
|
||||
gint width,
|
||||
gint height) {
|
||||
gchar ** options;
|
||||
gint n, count;
|
||||
|
||||
count = 0;
|
||||
|
||||
options = g_object_get_qdata (G_OBJECT (pixbuf),
|
||||
g_quark_from_static_string ("gdk_pixbuf_options"));
|
||||
if (options) {
|
||||
for (n = 0; options[2 * n]; n++) {
|
||||
++count;
|
||||
|
||||
*keys = g_realloc (*keys, sizeof (gchar *) * (count + 1));
|
||||
*vals = g_realloc (*vals, sizeof (gchar *) * (count + 1));
|
||||
|
||||
(*keys)[count - 1] = g_strdup (options[2 * n]);
|
||||
(*vals)[count - 1] = g_strdup (options[2 * n + 1]);
|
||||
|
||||
(*keys)[count] = NULL;
|
||||
(*vals)[count] = NULL;
|
||||
}
|
||||
}
|
||||
++count;
|
||||
|
||||
*keys = g_realloc (*keys, sizeof (gchar *) * (count + 1));
|
||||
*vals = g_realloc (*vals, sizeof (gchar *) * (count + 1));
|
||||
|
||||
(*keys)[count - 1] = g_strdup ("tEXt::Thumb::Image::Width");
|
||||
(*vals)[count - 1] = g_strdup_printf ("%d", width);
|
||||
|
||||
(*keys)[count] = NULL;
|
||||
(*vals)[count] = NULL;
|
||||
|
||||
++count;
|
||||
|
||||
*keys = g_realloc (*keys, sizeof (gchar *) * (count + 1));
|
||||
*vals = g_realloc (*vals, sizeof (gchar *) * (count + 1));
|
||||
|
||||
(*keys)[count - 1] = g_strdup ("tEXt::Thumb::Image::Height");
|
||||
(*vals)[count - 1] = g_strdup_printf ("%d", height);
|
||||
|
||||
(*keys)[count] = NULL;
|
||||
(*vals)[count] = NULL;
|
||||
}
|
||||
|
||||
#define LIST_IMAGE_WIDTH 64
|
||||
|
||||
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item,
|
||||
GnomeThumbnailFactory * thumbs) {
|
||||
GdkPixbuf * pixbuf, * bgpixbuf;
|
||||
GdkPixbuf * tmpbuf;
|
||||
GdkPixbuf * scaled = NULL;
|
||||
gint w, h, ratio;
|
||||
gint bw, bh;
|
||||
gint sw, sh, bw, bh, pw, ph, tw, th;
|
||||
gdouble ratio;
|
||||
|
||||
sw = sh = bw = bh = pw = ph = tw = th = 0;
|
||||
|
||||
/*
|
||||
Get the size of the screen and calculate our aspect ratio divisor
|
||||
We do this, so that images are thumbnailed as they would look on
|
||||
the screen in reality
|
||||
*/
|
||||
w = gdk_screen_get_width (gdk_screen_get_default ());
|
||||
h = gdk_screen_get_height (gdk_screen_get_default ());
|
||||
ratio = h / 48;
|
||||
bw = w / ratio;
|
||||
bh = h / ratio;
|
||||
sw = gdk_screen_get_width (gdk_screen_get_default ());
|
||||
sh = gdk_screen_get_height (gdk_screen_get_default ());
|
||||
ratio = (gdouble) sw / (gdouble) LIST_IMAGE_WIDTH;
|
||||
bw = sw / ratio;
|
||||
bh = sh / ratio;
|
||||
|
||||
/*
|
||||
Create the pixbuf for the background colors, which will show up for
|
||||
oddly sized images, smaller images that are centered, or alpha images
|
||||
*/
|
||||
if (!strcmp (item->shade_type, "solid")) {
|
||||
bgpixbuf = gnome_wp_pixbuf_new_solid (item->pcolor, w / ratio, h / ratio);
|
||||
bgpixbuf = gnome_wp_pixbuf_new_solid (item->pcolor, bw, bh);
|
||||
} else if (!strcmp (item->shade_type, "vertical-gradient")) {
|
||||
bgpixbuf = gnome_wp_pixbuf_new_gradient (GTK_ORIENTATION_VERTICAL,
|
||||
item->pcolor, item->scolor,
|
||||
w / ratio, h / ratio);
|
||||
bw, bh);
|
||||
} else {
|
||||
bgpixbuf = gnome_wp_pixbuf_new_gradient (GTK_ORIENTATION_HORIZONTAL,
|
||||
item->pcolor, item->scolor,
|
||||
w / ratio, h / ratio);
|
||||
bw, bh);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -93,7 +151,7 @@ GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item,
|
||||
g_file_test (item->fileinfo->thumburi, G_FILE_TEST_EXISTS)) {
|
||||
pixbuf = gdk_pixbuf_new_from_file (item->fileinfo->thumburi, NULL);
|
||||
} else if (!strcmp (item->filename, "(none)")) {
|
||||
pixbuf = gdk_pixbuf_copy (bgpixbuf);
|
||||
return bgpixbuf;
|
||||
} else {
|
||||
pixbuf = gnome_thumbnail_factory_generate_thumbnail (thumbs,
|
||||
gnome_vfs_escape_path_string (item->filename),
|
||||
@@ -101,50 +159,65 @@ GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item,
|
||||
gnome_thumbnail_factory_save_thumbnail (thumbs, pixbuf,
|
||||
gnome_vfs_escape_path_string (item->filename),
|
||||
item->fileinfo->mtime);
|
||||
g_object_unref (pixbuf);
|
||||
pixbuf = gdk_pixbuf_new_from_file (item->fileinfo->thumburi, NULL);
|
||||
}
|
||||
|
||||
if (pixbuf != NULL) {
|
||||
w = gdk_pixbuf_get_width (pixbuf);
|
||||
h = gdk_pixbuf_get_height (pixbuf);
|
||||
const gchar * w_val, * h_val;
|
||||
|
||||
/*
|
||||
Handle images large and small. We default to 1, since images smaller
|
||||
than 64x48 don't need to be scaled down, and the tiled thumbnails
|
||||
will look correct for really small pattern images
|
||||
*/
|
||||
if (h >= 48)
|
||||
ratio = h / 48;
|
||||
else if (w >= 64)
|
||||
ratio = w / 64;
|
||||
else
|
||||
ratio = 1;
|
||||
w_val = gdk_pixbuf_get_option (pixbuf, "tEXt::Thumb::Image::Width");
|
||||
h_val = gdk_pixbuf_get_option (pixbuf, "tEXt::Thumb::Image::Height");
|
||||
if (item->width <= 0 || item->height <= 0) {
|
||||
if (w_val && h_val) {
|
||||
item->width = atoi (w_val);
|
||||
item->height = atoi (h_val);
|
||||
} else {
|
||||
gchar ** keys = NULL;
|
||||
gchar ** vals = NULL;
|
||||
|
||||
scaled = gnome_thumbnail_scale_down_pixbuf (pixbuf, w / ratio, h / ratio);
|
||||
tmpbuf = gdk_pixbuf_new_from_file (item->filename, NULL);
|
||||
|
||||
item->width = gdk_pixbuf_get_width (tmpbuf);
|
||||
item->height = gdk_pixbuf_get_height (tmpbuf);
|
||||
|
||||
collect_save_options (pixbuf, &keys, &vals, item->width, item->height);
|
||||
gdk_pixbuf_savev (pixbuf, item->fileinfo->thumburi, "png",
|
||||
keys, vals, NULL);
|
||||
|
||||
g_object_unref (tmpbuf);
|
||||
g_strfreev (keys);
|
||||
g_strfreev (vals);
|
||||
}
|
||||
}
|
||||
|
||||
pw = gdk_pixbuf_get_width (pixbuf);
|
||||
ph = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
if (item->width <= bw && item->height <= bh)
|
||||
ratio = 1.0;
|
||||
|
||||
tw = item->width / ratio;
|
||||
th = item->height / ratio;
|
||||
|
||||
if (!strcmp (item->options, "wallpaper")) {
|
||||
w = gdk_pixbuf_get_width (scaled);
|
||||
h = gdk_pixbuf_get_height (scaled);
|
||||
|
||||
scaled = gnome_wp_pixbuf_tile (scaled, bgpixbuf);
|
||||
scaled = gnome_wp_pixbuf_tile (pixbuf, bgpixbuf, tw, th);
|
||||
} else if (!strcmp (item->options, "centered")) {
|
||||
w = gdk_pixbuf_get_width (scaled);
|
||||
h = gdk_pixbuf_get_height (scaled);
|
||||
|
||||
/*
|
||||
This is for alpha centered images like gnome-logo-transparent.jpg
|
||||
It's an ugly hack, that can potentially be removed when round() or
|
||||
something like it decides to work
|
||||
We scale it down again so that it looks proper, instead of the off-
|
||||
center look that seems to appear without this hack
|
||||
*/
|
||||
if (gdk_pixbuf_get_has_alpha (pixbuf) && (w > bw || h > bh))
|
||||
scaled = gnome_thumbnail_scale_down_pixbuf (scaled, w / 2, h / 2);
|
||||
|
||||
scaled = gnome_wp_pixbuf_center (scaled, bgpixbuf);
|
||||
scaled = gnome_wp_pixbuf_center (pixbuf, bgpixbuf, tw, th);
|
||||
} else if (!strcmp (item->options, "stretched")) {
|
||||
scaled = gnome_wp_pixbuf_center (pixbuf, bgpixbuf, bw, bh);
|
||||
} else if (!strcmp (item->options, "scaled")) {
|
||||
if ((gdouble) ph * (gdouble) bw > (gdouble) pw * (gdouble) bh) {
|
||||
tw = 0.5 + (gdouble) pw * (gdouble) bh / (gdouble) ph;
|
||||
th = bh;
|
||||
} else {
|
||||
th = 0.5 + (gdouble) ph * (gdouble) bw / (gdouble) pw;
|
||||
tw = bw;
|
||||
}
|
||||
scaled = gnome_wp_pixbuf_center (pixbuf, bgpixbuf, tw, th);
|
||||
}
|
||||
} else {
|
||||
scaled = gdk_pixbuf_copy (bgpixbuf);
|
||||
}
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
g_object_unref (bgpixbuf);
|
||||
|
||||
@@ -155,9 +228,12 @@ void gnome_wp_item_update_description (GnomeWPItem * item) {
|
||||
if (!strcmp (item->filename, "(none)")) {
|
||||
item->description = g_strdup_printf ("<b>%s</b>", item->name);
|
||||
} else {
|
||||
item->description = g_strdup_printf ("<b>%s</b>\n%s (%LuK)",
|
||||
item->description = g_strdup_printf ("<b>%s</b>\n"
|
||||
"%s %dx%d pixels (%LuK)",
|
||||
item->name,
|
||||
gnome_vfs_mime_get_description (item->fileinfo->mime_type),
|
||||
item->width,
|
||||
item->height,
|
||||
item->fileinfo->size / 1024);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,10 @@ struct _GnomeWPItem {
|
||||
|
||||
/* Did the user remove us? */
|
||||
gboolean deleted;
|
||||
|
||||
/* Width and Height of the original image */
|
||||
gint width;
|
||||
gint height;
|
||||
};
|
||||
|
||||
void gnome_wp_item_free (GnomeWPItem * item);
|
||||
|
||||
@@ -105,7 +105,10 @@ GdkPixbuf * gnome_wp_pixbuf_new_solid (GdkColor * color,
|
||||
}
|
||||
|
||||
GdkPixbuf * gnome_wp_pixbuf_tile (GdkPixbuf * src_pixbuf,
|
||||
GdkPixbuf * dest_pixbuf) {
|
||||
GdkPixbuf * dest_pixbuf,
|
||||
gint scaled_width,
|
||||
gint scaled_height) {
|
||||
GdkPixbuf * tmpbuf;
|
||||
gdouble cx, cy;
|
||||
gint dwidth, dheight;
|
||||
gint swidth, sheight;
|
||||
@@ -115,47 +118,81 @@ GdkPixbuf * gnome_wp_pixbuf_tile (GdkPixbuf * src_pixbuf,
|
||||
return gdk_pixbuf_copy (src_pixbuf);
|
||||
}
|
||||
|
||||
swidth = gdk_pixbuf_get_width (src_pixbuf);
|
||||
sheight = gdk_pixbuf_get_height (src_pixbuf);
|
||||
tmpbuf = gdk_pixbuf_scale_simple (src_pixbuf, scaled_width, scaled_height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
|
||||
swidth = gdk_pixbuf_get_width (tmpbuf);
|
||||
sheight = gdk_pixbuf_get_height (tmpbuf);
|
||||
|
||||
dwidth = gdk_pixbuf_get_width (dest_pixbuf);
|
||||
dheight = gdk_pixbuf_get_height (dest_pixbuf);
|
||||
|
||||
for (cy = 0; cy < dheight; cy += sheight) {
|
||||
for (cx = 0; cx < dwidth; cx += swidth) {
|
||||
gdk_pixbuf_composite (src_pixbuf, dest_pixbuf, cx, cy,
|
||||
gdk_pixbuf_composite (tmpbuf, dest_pixbuf, cx, cy,
|
||||
MIN (swidth, dwidth - cx),
|
||||
MIN (sheight, dheight - cy),
|
||||
cx, cy, 1.0, 1.0, GDK_INTERP_BILINEAR, alpha);
|
||||
cx, cy, 1.0, 1.0,
|
||||
GDK_INTERP_BILINEAR, alpha);
|
||||
}
|
||||
}
|
||||
g_object_unref (tmpbuf);
|
||||
|
||||
return gdk_pixbuf_copy (dest_pixbuf);
|
||||
}
|
||||
|
||||
GdkPixbuf * gnome_wp_pixbuf_center (GdkPixbuf * src_pixbuf,
|
||||
GdkPixbuf * dest_pixbuf) {
|
||||
gdouble cx, cy;
|
||||
GdkPixbuf * dest_pixbuf,
|
||||
gint scaled_width,
|
||||
gint scaled_height) {
|
||||
GdkPixbuf * tmpbuf;
|
||||
gint ox, oy, cx, cy;
|
||||
gint dwidth, dheight;
|
||||
gint swidth, sheight;
|
||||
gint cwidth, cheight;
|
||||
guint alpha = 255;
|
||||
|
||||
if (dest_pixbuf == NULL) {
|
||||
return gdk_pixbuf_copy (src_pixbuf);
|
||||
}
|
||||
|
||||
swidth = gdk_pixbuf_get_width (src_pixbuf);
|
||||
sheight = gdk_pixbuf_get_height (src_pixbuf);
|
||||
ox = cx = oy = cy = 0;
|
||||
|
||||
tmpbuf = gdk_pixbuf_scale_simple (src_pixbuf, scaled_width, scaled_height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
|
||||
swidth = gdk_pixbuf_get_width (tmpbuf);
|
||||
sheight = gdk_pixbuf_get_height (tmpbuf);
|
||||
|
||||
dwidth = gdk_pixbuf_get_width (dest_pixbuf);
|
||||
dheight = gdk_pixbuf_get_height (dest_pixbuf);
|
||||
|
||||
cx = (dwidth - swidth) / 2;
|
||||
cy = (dheight - sheight) / 2;
|
||||
if (dwidth > swidth) {
|
||||
ox = (dwidth - swidth) / 2;
|
||||
cx = 0;
|
||||
cwidth = swidth;
|
||||
} else {
|
||||
cx = (swidth - dwidth) / 2;
|
||||
oy = 0;
|
||||
cwidth = dwidth;
|
||||
}
|
||||
|
||||
gdk_pixbuf_composite (src_pixbuf, dest_pixbuf, cx, cy,
|
||||
swidth, sheight,
|
||||
cx, cy, 1.0, 1.0, GDK_INTERP_BILINEAR, alpha);
|
||||
if (dheight > sheight) {
|
||||
oy = ((dheight - sheight) / 2);
|
||||
cy = 0;
|
||||
cheight = sheight;
|
||||
} else {
|
||||
cy = (sheight - dheight) / 2;
|
||||
oy = 0;
|
||||
cheight = dheight;
|
||||
}
|
||||
|
||||
gdk_pixbuf_composite (tmpbuf, dest_pixbuf, ox, oy,
|
||||
cwidth, cheight,
|
||||
ox - cx, oy - cy, 1.0, 1.0,
|
||||
GDK_INTERP_BILINEAR, alpha);
|
||||
|
||||
g_object_unref (tmpbuf);
|
||||
return gdk_pixbuf_copy (dest_pixbuf);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,19 @@ GdkPixbuf * gnome_wp_pixbuf_new_gradient (GtkOrientation orientation,
|
||||
GdkColor * c1,
|
||||
GdkColor * c2,
|
||||
gint width, gint height);
|
||||
|
||||
GdkPixbuf * gnome_wp_pixbuf_new_solid (GdkColor * color,
|
||||
gint width, gint height);
|
||||
|
||||
GdkPixbuf * gnome_wp_pixbuf_tile (GdkPixbuf * src_pixbuf,
|
||||
GdkPixbuf * dest_pixbuf);
|
||||
GdkPixbuf * dest_pixbuf,
|
||||
gint scaled_width,
|
||||
gint scaled_height);
|
||||
|
||||
GdkPixbuf * gnome_wp_pixbuf_center (GdkPixbuf * src_pixbuf,
|
||||
GdkPixbuf * dest_pixbuf);
|
||||
GdkPixbuf * dest_pixbuf,
|
||||
gint scaled_width,
|
||||
gint scaled_height);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
gnome-theme-test
|
||||
stamp-h.in
|
||||
@@ -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>
|
||||
@@ -1,717 +0,0 @@
|
||||
2004-02-16 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gconf-property-editor.c (peditor_image_clicked_cb) : Use the monitor
|
||||
size kludge for the vertical size of the new file selector.
|
||||
|
||||
2003-12-07 Jan Arne Petersen <jpetersen@uni-bonn.de>
|
||||
|
||||
* gconf-property-editor.c: (peditor_image_set_filename),
|
||||
(peditor_image_chooser_response_cb),
|
||||
(peditor_image_chooser_update_preview_cb),
|
||||
(peditor_image_clicked_cb): replace
|
||||
PreviewFileSelection (GtkFileSelection) with GtkFileChooser, use new
|
||||
gdk_pixbuf_new_from_file_at_size method to load a scaled image.
|
||||
|
||||
2004-02-13 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.3
|
||||
|
||||
2004-01-14 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.2
|
||||
|
||||
2003-12-30 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.1.1
|
||||
|
||||
2003-12-30 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.1
|
||||
|
||||
2003-10-28 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.5.0
|
||||
|
||||
Thu Aug 7 15:23:08 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gconf-property-editor.c (gconf_property_editor_set_prop): damn
|
||||
it Jonathan. Save the @#*&$@# file before committing.
|
||||
|
||||
Mon Aug 4 14:35:22 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gconf-property-editor.c (gconf_property_editor_init): Reset the
|
||||
old connection when setting a new one, #116232
|
||||
|
||||
2003-07-07 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.4
|
||||
|
||||
2003-07-03 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* gconf-property-editor.c: (gconf_property_editor_finalize):
|
||||
Merge Anders' fix from stable.
|
||||
|
||||
2003-07-02 Mark McLoughlin <mark@skynet.ie>
|
||||
|
||||
Handle crashes of the thumbnailer child process a
|
||||
little more gracefully.
|
||||
|
||||
* theme-thumbnail.c:
|
||||
(generate_theme_thumbnail): if we get an EOF from
|
||||
the child close the pipe, return NULL and return
|
||||
NULL from any subsequent calls.
|
||||
(generate_theme_thumbnail_async): return NULL if
|
||||
the pipe has been closed.
|
||||
(theme_thumbnail_factory_init): set pipe descriptos
|
||||
to zero after closing them.
|
||||
|
||||
2003-06-24 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.3
|
||||
|
||||
2003-05-13 Andrew Sobala <aes@gnome.org>
|
||||
|
||||
* Makefile.am: build fixes for the below
|
||||
* gnome-theme-apply.c: pulled out from gnome-theme-manager.c
|
||||
* gnome-theme-apply.h: pulled out from gnome-theme-manager.c
|
||||
* theme-thumbnail.c: moved to libcommon
|
||||
* theme-thumbnail.h: moved to libcommon
|
||||
|
||||
2003-05-07 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.3.1
|
||||
|
||||
2003-05-01 Ross Burton <ross@burtonini.com>
|
||||
|
||||
* gnome-theme-info.c (real_add_top_theme_dir_monitor):
|
||||
Monitor directories and symbolic links instead of just
|
||||
directories. Fixes #111990.
|
||||
|
||||
2003-04-29 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* gconf-property-editor.c: (gconf_peditor_new): Plug a leak
|
||||
* gnome-theme-info.c: (top_theme_dir_changed),
|
||||
(top_icon_theme_dir_changed), (real_add_top_theme_dir_monitor):
|
||||
Plug leaks and fix invalid reads reported by valgrind.
|
||||
|
||||
2003-03-27 Andrew Sobala <aes@gnome.org>
|
||||
|
||||
* gnome-theme-info.c: (gnome_theme_read_meta_theme),
|
||||
(update_common_theme_dir_index):
|
||||
s/read_meta_theme/gnome_theme_read_meta_theme/; enable the reading of
|
||||
themes that just use [X-GNOME-Metatheme] without pretending to be a
|
||||
.desktop file
|
||||
* gnome-theme-info.h: exposed gnome_theme_read_meta_theme
|
||||
|
||||
Tue Feb 4 17:09:18 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* Release 2.2.0.1
|
||||
|
||||
2003-02-03 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* gnome-theme-info.c (read_meta_theme): Fix a glaring bug
|
||||
that caused the theme descriptions etc not to be localised.
|
||||
Fix from Dmitry G. Mastrukov <dmitry@taurussoft.org>. Fixes
|
||||
#104296
|
||||
|
||||
2003-01-27 Bastien Nocera <hadess@hadess.net>
|
||||
|
||||
* gnome-theme-test.c: (main): C ninety what ?
|
||||
|
||||
Tue Jan 21 01:15:14 2003 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* Release 2.2.0
|
||||
|
||||
Sun Jan 19 02:14:35 2003 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* gnome-theme-test.c (main): add more debugging output.
|
||||
|
||||
Thu Jan 16 15:51:33 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gnome-theme-test.c: new little test program for helping people
|
||||
debug their installation.
|
||||
|
||||
Thu Jan 16 02:41:09 2003 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* Release 2.1.7
|
||||
|
||||
Wed Jan 15 20:16:21 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gnome-theme-info.c (remove_data_from_hash_by_name): call
|
||||
correctly in all the right places.
|
||||
|
||||
Mon Jan 13 15:04:47 2003 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gnome-theme-info.c: rewrote to handle fam more correctly. Still
|
||||
a little broken in places, but much, much better than before.
|
||||
|
||||
2003-01-10 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.6
|
||||
|
||||
2002-12-28 Seth Nickell <snickell@stanford.edu>
|
||||
|
||||
* Makefile.am:
|
||||
* gnome-theme-info.c: (gnome_theme_info_init):
|
||||
|
||||
Update icon theme directory code so it looks in
|
||||
PREFIX/share/icons rather than PREFIX/share/theme,
|
||||
as per freedesktop icon spec.
|
||||
|
||||
2002-12-18 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.5
|
||||
|
||||
Fri Dec 6 16:13:54 2002 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gnome-theme-info.c (top_theme_dir_changed_callback): I know C.
|
||||
Really, I do.
|
||||
|
||||
2002-11-23 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.3
|
||||
|
||||
Tue Nov 5 15:48:33 2002 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* gnome-theme-info.c: Change the file format a bunch.
|
||||
|
||||
2002-11-02 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.2
|
||||
|
||||
Fri Nov 1 11:03:34 2002 Jonathan Blandford <jrb@gnome.org>
|
||||
|
||||
* gnome-theme-info.[ch]: Moved theme-common, and gave more
|
||||
features.
|
||||
|
||||
2002-10-21 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.1
|
||||
|
||||
2002-10-01 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.0.1
|
||||
|
||||
2002-08-21 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* Release 2.1.0
|
||||
|
||||
2002-07-16 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* gconf-property-editor.c (gconf_value_int_to_float) : add a peditor
|
||||
arg so that these can be used without wrappers.
|
||||
(gconf_value_float_to_int) : ditto.
|
||||
|
||||
2002-07-10 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* capplet-util.c (capplet_set_icon) : look in more places.
|
||||
|
||||
2002-07-02 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=86018
|
||||
* gconf-property-editor.c (peditor_image_set_filename) : Patch from
|
||||
Chema. We should only assign the filename to the label if the file
|
||||
is valid.
|
||||
|
||||
2002-06-27 Jody Goldberg <jody@gnome.org>
|
||||
|
||||
* capplet-util.c (capplet_set_icon) : new util.
|
||||
|
||||
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
|
||||
|
||||
@@ -1,42 +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\" \
|
||||
-DINSTALL_PREFIX=\"$(prefix)\" \
|
||||
-I$(top_srcdir)/libbackground \
|
||||
-I$(top_srcdir)/libwindow-settings \
|
||||
@VFS_CAPPLET_CFLAGS@ \
|
||||
@GNOME_DESKTOP_CFLAGS@ \
|
||||
@METACITY_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 \
|
||||
gnome-theme-info.c gnome-theme-info.h \
|
||||
wm-common.c wm-common.h \
|
||||
capplet-stock-icons.c capplet-stock-icons.h \
|
||||
theme-thumbnail.c theme-thumbnail.h \
|
||||
gnome-theme-apply.c gnome-theme-apply.h
|
||||
|
||||
libcommon_la_LIBADD = $(top_builddir)/libbackground/libbackground.la \
|
||||
$(top_builddir)/libwindow-settings/libgnome-window-settings.la \
|
||||
@METACITY_LIBS@ \
|
||||
@GNOME_DESKTOP_LIBS@
|
||||
|
||||
gnome_theme_test_SOURCES = \
|
||||
gnome-theme-test.c
|
||||
|
||||
gnome_theme_test_LDADD = \
|
||||
libcommon.la \
|
||||
$(GNOMECC_CAPPLETS_LIBS)
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
gnome-theme-test
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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__ */
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* capplet-stock-icons.c
|
||||
*
|
||||
* Copyright (C) 2002 Sun Microsystems, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Authors:
|
||||
* Rajkumar Sivasamy <rajkumar.siva@wipro.com>
|
||||
* Taken bits of code from panel-stock-icons.c, Thanks Mark <mark@skynet.ie>
|
||||
*/
|
||||
|
||||
#include <gtk/gtkstock.h>
|
||||
#include <gtk/gtkiconfactory.h>
|
||||
#include <gnome.h>
|
||||
|
||||
#include "capplet-stock-icons.h"
|
||||
|
||||
static GtkIconSize keyboard_capplet_icon_size = 0;
|
||||
static GtkIconSize mouse_capplet_icon_size = 0;
|
||||
static GtkIconSize mouse_capplet_dblclck_icon_size = 0;
|
||||
|
||||
GtkIconSize
|
||||
keyboard_capplet_icon_get_size (void)
|
||||
{
|
||||
return keyboard_capplet_icon_size;
|
||||
}
|
||||
|
||||
GtkIconSize
|
||||
mouse_capplet_icon_get_size (void)
|
||||
{
|
||||
return mouse_capplet_icon_size;
|
||||
}
|
||||
|
||||
GtkIconSize
|
||||
mouse_capplet_dblclck_icon_get_size (void)
|
||||
{
|
||||
return mouse_capplet_dblclck_icon_size;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *stock_id;
|
||||
char *name;
|
||||
} CappletStockIcon;
|
||||
|
||||
|
||||
static CappletStockIcon items [] = {
|
||||
{ KEYBOARD_REPEAT, "keyboard-repeat.png" },
|
||||
{ KEYBOARD_CURSOR, "keyboard-cursor.png" },
|
||||
{ KEYBOARD_VOLUME, "keyboard-volume.png" },
|
||||
{ KEYBOARD_BELL, "keyboard-bell.png" },
|
||||
{ ACCESSX_KEYBOARD_BOUNCE, "accessibility-keyboard-bouncekey.png"},
|
||||
{ ACCESSX_KEYBOARD_SLOW, "accessibility-keyboard-slowkey.png"},
|
||||
{ ACCESSX_KEYBOARD_MOUSE, "accessibility-keyboard-mousekey.png"},
|
||||
{ ACCESSX_KEYBOARD_STICK, "accessibility-keyboard-stickykey.png"},
|
||||
{ ACCESSX_KEYBOARD_TOGGLE, "accessibility-keyboard-togglekey.png"},
|
||||
{ MOUSE_DBLCLCK_MAYBE, "double-click-maybe.png"},
|
||||
{ MOUSE_DBLCLCK_ON, "double-click-on.png"},
|
||||
{ MOUSE_DBLCLCK_OFF, "double-click-off.png"},
|
||||
{ MOUSE_RIGHT_HANDED, "mouse-right.png"},
|
||||
{ MOUSE_LEFT_HANDED, "mouse-left.png"}
|
||||
};
|
||||
|
||||
static void
|
||||
capplet_register_stock_icons (GtkIconFactory *factory)
|
||||
{
|
||||
gint i;
|
||||
GtkIconSource *source;
|
||||
GnomeProgram *program;
|
||||
|
||||
source = gtk_icon_source_new ();
|
||||
program = gnome_program_get ();
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (items); ++i) {
|
||||
GtkIconSet *icon_set;
|
||||
char *filename;
|
||||
filename = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_PIXMAP, items[i].name, TRUE, NULL);
|
||||
|
||||
if (!filename) {
|
||||
g_warning (_("Unable to load capplet stock icon '%s'\n"), items[i].name);
|
||||
icon_set = gtk_icon_factory_lookup_default (GTK_STOCK_MISSING_IMAGE);
|
||||
gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
|
||||
continue;
|
||||
}
|
||||
|
||||
gtk_icon_source_set_filename (source, filename);
|
||||
g_free (filename);
|
||||
|
||||
icon_set = gtk_icon_set_new ();
|
||||
gtk_icon_set_add_source (icon_set, source);
|
||||
gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
|
||||
gtk_icon_set_unref (icon_set);
|
||||
}
|
||||
gtk_icon_source_free (source);
|
||||
}
|
||||
|
||||
void
|
||||
capplet_init_stock_icons (void)
|
||||
{
|
||||
GtkIconFactory *factory;
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = TRUE;
|
||||
|
||||
factory = gtk_icon_factory_new ();
|
||||
gtk_icon_factory_add_default (factory);
|
||||
capplet_register_stock_icons (factory);
|
||||
|
||||
keyboard_capplet_icon_size = gtk_icon_size_register ("keyboard-capplet",
|
||||
KEYBOARD_CAPPLET_DEFAULT_ICON_SIZE,
|
||||
KEYBOARD_CAPPLET_DEFAULT_ICON_SIZE);
|
||||
|
||||
mouse_capplet_icon_size = gtk_icon_size_register ("mouse-capplet",
|
||||
MOUSE_CAPPLET_DEFAULT_WIDTH,
|
||||
MOUSE_CAPPLET_DEFAULT_HEIGHT);
|
||||
|
||||
mouse_capplet_dblclck_icon_size = gtk_icon_size_register ("mouse-capplet-dblclck-icon",
|
||||
MOUSE_CAPPLET_DBLCLCK_ICON_SIZE,
|
||||
MOUSE_CAPPLET_DBLCLCK_ICON_SIZE);
|
||||
g_object_unref (factory);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* capplet-stock-icons.h
|
||||
*
|
||||
* Copyright (C) 2002 Sun Microsystems, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Authors:
|
||||
* Rajkumar Sivasamy <rajkumar.siva@wipro.com>
|
||||
* Taken bits of code from panel-stock-icons.h, Thanks Mark <mark@skynet.ie>
|
||||
*/
|
||||
|
||||
#ifndef __CAPPLET_STOCK_ICONS_H__
|
||||
#define __CAPPLET_STOCK_ICONS_H__
|
||||
|
||||
#include <glib/gmacros.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define KEYBOARD_CAPPLET_DEFAULT_ICON_SIZE 48
|
||||
#define MOUSE_CAPPLET_DEFAULT_WIDTH 120
|
||||
#define MOUSE_CAPPLET_DEFAULT_HEIGHT 100
|
||||
#define MOUSE_CAPPLET_DBLCLCK_ICON_SIZE 100
|
||||
|
||||
/* stock icons */
|
||||
#define KEYBOARD_REPEAT "keyboard-repeat"
|
||||
#define KEYBOARD_CURSOR "keyboard-cursor"
|
||||
#define KEYBOARD_VOLUME "keyboard-volume"
|
||||
#define KEYBOARD_BELL "keyboard-bell"
|
||||
#define ACCESSX_KEYBOARD_BOUNCE "accessibility-keyboard-bouncekey"
|
||||
#define ACCESSX_KEYBOARD_SLOW "accessibility-keyboard-slowkey"
|
||||
#define ACCESSX_KEYBOARD_MOUSE "accessibility-keyboard-mousekey"
|
||||
#define ACCESSX_KEYBOARD_STICK "accessibility-keyboard-stickykey"
|
||||
#define ACCESSX_KEYBOARD_TOGGLE "accessibility-keyboard-togglekey"
|
||||
#define MOUSE_DBLCLCK_MAYBE "mouse-dblclck-maybe"
|
||||
#define MOUSE_DBLCLCK_ON "mouse-dblclck-on"
|
||||
#define MOUSE_DBLCLCK_OFF "mouse-dblclck-off"
|
||||
#define MOUSE_RIGHT_HANDED "mouse-right-handed"
|
||||
#define MOUSE_LEFT_HANDED "mouse-left-handed"
|
||||
|
||||
void capplet_init_stock_icons (void);
|
||||
GtkIconSize keyboard_capplet_icon_get_size (void);
|
||||
GtkIconSize mouse_capplet_icon_get_size (void);
|
||||
GtkIconSize mouse_capplet_dblclck_icon_get_size (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CAPPLET_STOCK_ICONS_H__ */
|
||||
@@ -1,373 +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);
|
||||
}
|
||||
|
||||
/**
|
||||
* capplet_set_icon :
|
||||
* @window :
|
||||
* @file_name :
|
||||
*
|
||||
* A quick utility routine to avoid the cut-n-paste of bogus code
|
||||
* that caused several bugs.
|
||||
**/
|
||||
void
|
||||
capplet_set_icon (GtkWidget *window, char const *icon_file_name)
|
||||
{
|
||||
char *path;
|
||||
GdkPixbuf *icon_pixbuf;
|
||||
|
||||
path = g_strconcat (GNOMECC_DATA_DIR "/icons/", icon_file_name, NULL);
|
||||
icon_pixbuf = gdk_pixbuf_new_from_file (path, NULL);
|
||||
g_free (path);
|
||||
if (icon_pixbuf == NULL) {
|
||||
path = gnome_pixmap_file (icon_file_name);
|
||||
if (path != NULL) {
|
||||
icon_pixbuf = gdk_pixbuf_new_from_file (path, NULL);
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
if (icon_pixbuf != NULL) {
|
||||
gtk_window_set_icon (GTK_WINDOW (window), icon_pixbuf);
|
||||
g_object_unref (icon_pixbuf);
|
||||
}
|
||||
}
|
||||
@@ -1,105 +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 */
|
||||
|
||||
#ifdef G_HAVE_ISO_VARARGS
|
||||
# define DEBUG_MSG(str, ...) \
|
||||
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "(%d:%s) " str, \
|
||||
getpid (), G_GNUC_FUNCTION, __VA_ARGS__)
|
||||
#elif defined(G_HAVE_GNUC_VARARGS)
|
||||
# define DEBUG_MSG(str, args...) \
|
||||
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "(%d:%s) " str, \
|
||||
getpid (), G_GNUC_FUNCTION, args)
|
||||
#else
|
||||
# define DEBUG_MSG(str, args...)
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
void capplet_set_icon (GtkWidget *window, char const *icon_file_name);
|
||||
|
||||
#endif /* __CAPPLET_UTIL_H */
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||