Compare commits

...

4 Commits

Author SHA1 Message Date
Rodney Dawes
67d8e0481c Fix dates in ChangeLog for branch entries 2004-03-12 04:21:24 +00:00
Rodney Dawes
177c7e8a21 Reload the thumbnail pixbuf after generating it with the thumbnail system,
2004-02-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 22:17:53 +00:00
Rodney Dawes
c8fa009b68 Update the description after getting the thumbnail, so we have the
2004-02-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-10 20:30:53 +00:00
Rodney Dawes
16de89cf4f Regenerate the thumbnail in the list when we change scaling type now
2004-02-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-09 22:11:49 +00:00
674 changed files with 248 additions and 340140 deletions

View File

@@ -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

View File

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

340
COPYING
View File

@@ -1,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

3828
ChangeLog

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,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
View File

@@ -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
View File

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

105
TODO
View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@@ -1,94 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* archive.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __ARCHIVE_H
#define __ARCHIVE_H
#include <gnome.h>
#include "ConfigArchiver.h"
#include "location.h"
#include "backend-list.h"
#define ARCHIVE(obj) GTK_CHECK_CAST (obj, archive_get_type (), Archive)
#define ARCHIVE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, archive_get_type (), ArchiveClass)
#define IS_ARCHIVE(obj) GTK_CHECK_TYPE (obj, archive_get_type ())
typedef struct _ArchiveClass ArchiveClass;
struct _Archive
{
BonoboXObject object;
gchar *prefix;
GTree *locations;
gboolean is_global;
gchar *current_location_id;
BackendList *backend_list;
};
struct _ArchiveClass
{
BonoboXObjectClass parent;
POA_ConfigArchiver_Archive__epv epv;
};
GType archive_get_type (void);
gboolean archive_construct (Archive *archive,
gboolean is_new);
BonoboObject *archive_load (gboolean is_global);
void archive_close (Archive *archive);
Location *archive_get_location (Archive *archive,
const gchar *locid);
Location *archive_create_location (Archive *archive,
const gchar *locid,
const gchar *label,
Location *parent);
void archive_unregister_location (Archive *archive,
Location *location);
Location *archive_get_current_location (Archive *archive);
void archive_set_current_location (Archive *archive,
Location *location);
const gchar *archive_get_current_location_id (Archive *archive);
void archive_set_current_location_id (Archive *archive,
const gchar *locid);
const gchar *archive_get_prefix (Archive *archive);
gboolean archive_is_global (Archive *archive);
BackendList *archive_get_backend_list (Archive *archive);
GList *archive_get_child_locations (Archive *archive,
Location *parent);
#endif /* __ARCHIVE */

View File

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

View File

@@ -1,46 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* archiver-client.h
* Copyright (C) 2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __ARCHIVER_CLIENT_H
#define __ARCHIVER_CLIENT_H
#include <gnome.h>
#include <gnome-xml/tree.h>
#include <time.h>
#include "ConfigArchiver.h"
xmlDocPtr location_client_load_rollback_data (ConfigArchiver_Location location,
const struct tm *date,
guint steps,
const gchar *backend_id,
gboolean parent_chain,
CORBA_Environment *opt_ev);
void location_client_store_xml (ConfigArchiver_Location location,
const gchar *backend_id,
xmlDocPtr xml_doc,
ConfigArchiver_StoreType store_type,
CORBA_Environment *opt_ev);
#endif /* __ARCHIVER_CLIENT_H */

View File

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

View File

@@ -1,363 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* backend-list.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@ximian.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <parser.h>
#include <tree.h>
#include "backend-list.h"
enum {
ARG_0,
ARG_IS_GLOBAL
};
struct _BackendListPrivate
{
gboolean is_global;
gchar *filename;
GList *backend_ids;
};
#define BACKEND_LIST_FROM_SERVANT(servant) (BACKEND_LIST (bonobo_object_from_servant (servant)))
static BonoboXObjectClass *parent_class;
static void backend_list_init (BackendList *backend_list);
static void backend_list_class_init (BackendListClass *class);
static void backend_list_set_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void backend_list_get_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void backend_list_finalize (GtkObject *object);
static void do_load (BackendList *backend_list);
static void do_save (BackendList *backend_list);
/* CORBA interface methods */
static CORBA_boolean
impl_ConfigArchiver_BackendList_contains (PortableServer_Servant servant,
const CORBA_char *backend_id,
CORBA_Environment *ev)
{
return backend_list_contains (BACKEND_LIST_FROM_SERVANT (servant), backend_id);
}
static void
impl_ConfigArchiver_BackendList_add (PortableServer_Servant servant,
const CORBA_char *backend_id,
CORBA_Environment *ev)
{
backend_list_add (BACKEND_LIST_FROM_SERVANT (servant), backend_id);
}
static void
impl_ConfigArchiver_BackendList_remove (PortableServer_Servant servant,
const CORBA_char *backend_id,
CORBA_Environment *ev)
{
backend_list_remove (BACKEND_LIST_FROM_SERVANT (servant), backend_id);
}
static void
impl_ConfigArchiver_BackendList_save (PortableServer_Servant servant,
CORBA_Environment *ev)
{
backend_list_save (BACKEND_LIST_FROM_SERVANT (servant));
}
static ConfigArchiver_StringSeq *
impl_ConfigArchiver_BackendList__get_backends (PortableServer_Servant servant,
CORBA_Environment *ev)
{
ConfigArchiver_StringSeq *seq;
BackendList *backend_list = BACKEND_LIST_FROM_SERVANT (servant);
guint i = 0;
GList *node;
g_return_val_if_fail (backend_list != NULL, NULL);
g_return_val_if_fail (IS_BACKEND_LIST (backend_list), NULL);
seq = ConfigArchiver_StringSeq__alloc ();
seq->_length = g_list_length (backend_list->p->backend_ids);
seq->_buffer = CORBA_sequence_CORBA_string_allocbuf (seq->_length);
CORBA_sequence_set_release (seq, TRUE);
for (node = backend_list->p->backend_ids; node != NULL; node = node->next)
seq->_buffer[i++] = CORBA_string_dup (node->data);
return seq;
}
BONOBO_X_TYPE_FUNC_FULL (BackendList, ConfigArchiver_BackendList, BONOBO_X_OBJECT_TYPE, backend_list);
static void
backend_list_init (BackendList *backend_list)
{
backend_list->p = g_new0 (BackendListPrivate, 1);
}
static void
backend_list_class_init (BackendListClass *class)
{
GtkObjectClass *object_class;
gtk_object_add_arg_type ("BackendList::is-global",
GTK_TYPE_INT,
GTK_ARG_CONSTRUCT_ONLY | GTK_ARG_READWRITE,
ARG_IS_GLOBAL);
object_class = GTK_OBJECT_CLASS (class);
object_class->finalize = backend_list_finalize;
object_class->set_arg = backend_list_set_arg;
object_class->get_arg = backend_list_get_arg;
class->epv.contains = impl_ConfigArchiver_BackendList_contains;
class->epv.add = impl_ConfigArchiver_BackendList_add;
class->epv.remove = impl_ConfigArchiver_BackendList_remove;
class->epv.save = impl_ConfigArchiver_BackendList_save;
class->epv._get_backends = impl_ConfigArchiver_BackendList__get_backends;
parent_class = BONOBO_X_OBJECT_CLASS
(gtk_type_class (BONOBO_X_OBJECT_TYPE));
}
static void
backend_list_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
BackendList *backend_list;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_BACKEND_LIST (object));
backend_list = BACKEND_LIST (object);
switch (arg_id) {
case ARG_IS_GLOBAL:
backend_list->p->is_global = GTK_VALUE_INT (*arg);
backend_list->p->filename = backend_list->p->is_global ?
LOCATION_DIR "/default-global.xml" :
LOCATION_DIR "/default-user.xml";
do_load (backend_list);
break;
default:
g_warning ("Bad argument set");
break;
}
}
static void
backend_list_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
BackendList *backend_list;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_BACKEND_LIST (object));
backend_list = BACKEND_LIST (object);
switch (arg_id) {
case ARG_IS_GLOBAL:
GTK_VALUE_INT (*arg) = backend_list->p->is_global;
break;
default:
g_warning ("Bad argument get");
break;
}
}
static void
backend_list_finalize (GtkObject *object)
{
BackendList *backend_list;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_BACKEND_LIST (object));
backend_list = BACKEND_LIST (object);
g_list_foreach (backend_list->p->backend_ids, (GFunc) g_free, NULL);
g_list_free (backend_list->p->backend_ids);
g_free (backend_list->p);
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
BonoboObject *
backend_list_new (gboolean is_global)
{
return BONOBO_OBJECT
(gtk_object_new (backend_list_get_type (),
"is-global", is_global,
NULL));
}
gboolean
backend_list_contains (BackendList *backend_list, const gchar *backend_id)
{
GList *node;
g_return_val_if_fail (backend_list != NULL, FALSE);
g_return_val_if_fail (IS_BACKEND_LIST (backend_list), FALSE);
for (node = backend_list->p->backend_ids; node != NULL;
node = node->next)
if (!strcmp (node->data, backend_id))
return TRUE;
return FALSE;
}
/**
* backend_list_foreach:
* @backend_list:
* @callback:
* @data:
*
* Iterates through all the backends, invoking the callback given and aborting
* if any callback returns a nonzero value
*
* Return value: TRUE iff no callback issued a nonzero value, FALSE otherwise
**/
gboolean
backend_list_foreach (BackendList *backend_list, BackendCB callback,
gpointer data)
{
GList *node;
g_return_val_if_fail (backend_list != NULL, FALSE);
g_return_val_if_fail (IS_BACKEND_LIST (backend_list), FALSE);
g_return_val_if_fail (callback != NULL, FALSE);
for (node = backend_list->p->backend_ids; node; node = node->next)
if (callback (backend_list, node->data, data)) return FALSE;
return TRUE;
}
void
backend_list_add (BackendList *backend_list, const gchar *backend_id)
{
g_return_if_fail (backend_list != NULL);
g_return_if_fail (IS_BACKEND_LIST (backend_list));
g_return_if_fail (backend_id != NULL);
backend_list->p->backend_ids =
g_list_prepend (backend_list->p->backend_ids, g_strdup (backend_id));
}
void
backend_list_remove (BackendList *backend_list, const gchar *backend_id)
{
gchar *tmp;
GList *node;
g_return_if_fail (backend_list != NULL);
g_return_if_fail (IS_BACKEND_LIST (backend_list));
g_return_if_fail (backend_id != NULL);
tmp = g_strdup (backend_id);
node = g_list_find (backend_list->p->backend_ids, tmp);
backend_list->p->backend_ids =
g_list_remove_link (backend_list->p->backend_ids, node);
g_free (node->data);
g_free (tmp);
g_list_free_1 (node);
}
void
backend_list_save (BackendList *backend_list)
{
g_return_if_fail (backend_list != NULL);
g_return_if_fail (IS_BACKEND_LIST (backend_list));
do_save (backend_list);
}
static void
do_load (BackendList *backend_list)
{
xmlNodePtr root_node, node;
xmlDocPtr doc;
GList *list_tail = NULL;
gchar *contains_str;
doc = xmlParseFile (backend_list->p->filename);
if (doc == NULL) return;
root_node = xmlDocGetRootElement (doc);
for (node = root_node->childs; node; node = node->next) {
if (!strcmp (node->name, "contains")) {
contains_str = xmlGetProp (node, "backend");
if (contains_str != NULL) {
contains_str = g_strdup (contains_str);
list_tail = g_list_append (list_tail,
contains_str);
if (backend_list->p->backend_ids == NULL)
backend_list->p->backend_ids =
list_tail;
else
list_tail = list_tail->next;
} else {
g_warning ("Bad backends list: " \
"contains element with no " \
"backend attribute");
}
}
}
}
static void
do_save (BackendList *backend_list)
{
xmlNodePtr root_node, child_node;
xmlDocPtr doc;
GList *node;
doc = xmlNewDoc ("1.0");
root_node = xmlNewDocNode (doc, NULL, "location", NULL);
for (node = backend_list->p->backend_ids; node; node = node->next) {
child_node = xmlNewChild (root_node, NULL, "contains", NULL);
xmlNewProp (child_node, "backend", node->data);
}
xmlDocSetRootElement (doc, root_node);
xmlSaveFile (backend_list->p->filename, doc);
xmlFreeDoc (doc);
}

View File

@@ -1,78 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* backend-list.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@ximian.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __BACKEND_LIST_H
#define __BACKEND_LIST_H
#include <gnome.h>
#include <bonobo.h>
#include "ConfigArchiver.h"
BEGIN_GNOME_DECLS
#define BACKEND_LIST(obj) GTK_CHECK_CAST (obj, backend_list_get_type (), BackendList)
#define BACKEND_LIST_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, backend_list_get_type (), BackendListClass)
#define IS_BACKEND_LIST(obj) GTK_CHECK_TYPE (obj, backend_list_get_type ())
typedef struct _BackendList BackendList;
typedef struct _BackendListClass BackendListClass;
typedef struct _BackendListPrivate BackendListPrivate;
typedef gint (*BackendCB) (BackendList *, gchar *, gpointer);
struct _BackendList
{
BonoboXObject parent;
BackendListPrivate *p;
};
struct _BackendListClass
{
BonoboXObjectClass parent_class;
POA_ConfigArchiver_BackendList__epv epv;
};
GType backend_list_get_type (void);
BonoboObject *backend_list_new (gboolean is_global);
gboolean backend_list_contains (BackendList *backend_list,
const gchar *backend_id);
gboolean backend_list_foreach (BackendList *backend_list,
BackendCB callback,
gpointer data);
void backend_list_add (BackendList *backend_list,
const gchar *backend_id);
void backend_list_remove (BackendList *backend_list,
const gchar *backend_id);
void backend_list_save (BackendList *backend_list);
END_GNOME_DECLS
#endif /* __BACKEND_LIST_H */

View File

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

View File

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

View File

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

View File

@@ -1,222 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* cluster-location.c
* Copyright (C) 2000 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@helixcode.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "cluster.h"
#include "cluster-location.h"
typedef struct _pair_t pair_t;
enum {
ARG_0,
ARG_SAMPLE
};
struct _ClusterLocationPrivate
{
/* Private data members */
};
struct _pair_t
{
gpointer a, b;
};
static LocationClass *parent_class;
static void cluster_location_init (ClusterLocation *cluster_location);
static void cluster_location_class_init (ClusterLocationClass *class);
static void cluster_location_set_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void cluster_location_get_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void cluster_location_finalize (GtkObject *object);
static gboolean cluster_location_do_rollback (Location *location,
gchar *backend_id,
xmlDocPtr doc);
static gboolean host_cb (Cluster *cluster,
gchar *hostname,
pair_t *pair);
GType
cluster_location_get_type (void)
{
static GType cluster_location_type = 0;
if (!cluster_location_type) {
GtkTypeInfo cluster_location_info = {
"ClusterLocation",
sizeof (ClusterLocation),
sizeof (ClusterLocationClass),
(GtkClassInitFunc) cluster_location_class_init,
(GtkObjectInitFunc) cluster_location_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL
};
cluster_location_type =
gtk_type_unique (location_get_type (),
&cluster_location_info);
}
return cluster_location_type;
}
static void
cluster_location_init (ClusterLocation *cluster_location)
{
cluster_location->p = g_new0 (ClusterLocationPrivate, 1);
}
static void
cluster_location_class_init (ClusterLocationClass *class)
{
GtkObjectClass *object_class;
LocationClass *location_class;
gtk_object_add_arg_type ("ClusterLocation::sample",
GTK_TYPE_POINTER,
GTK_ARG_READWRITE,
ARG_SAMPLE);
object_class = GTK_OBJECT_CLASS (class);
object_class->finalize = cluster_location_finalize;
object_class->set_arg = cluster_location_set_arg;
object_class->get_arg = cluster_location_get_arg;
location_class = LOCATION_CLASS (class);
location_class->do_rollback = cluster_location_do_rollback;
parent_class = LOCATION_CLASS
(gtk_type_class (location_get_type ()));
}
static void
cluster_location_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
ClusterLocation *cluster_location;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER_LOCATION (object));
cluster_location = CLUSTER_LOCATION (object);
switch (arg_id) {
case ARG_SAMPLE:
break;
default:
g_warning ("Bad argument set");
break;
}
}
static void
cluster_location_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
ClusterLocation *cluster_location;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER_LOCATION (object));
cluster_location = CLUSTER_LOCATION (object);
switch (arg_id) {
case ARG_SAMPLE:
break;
default:
g_warning ("Bad argument get");
break;
}
}
static void
cluster_location_finalize (GtkObject *object)
{
ClusterLocation *cluster_location;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER_LOCATION (object));
cluster_location = CLUSTER_LOCATION (object);
g_free (cluster_location->p);
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
GtkObject *
cluster_location_new (void)
{
return gtk_object_new (cluster_location_get_type (),
NULL);
}
static gboolean
cluster_location_do_rollback (Location *location, gchar *backend_id,
xmlDocPtr doc)
{
Cluster *cluster;
pair_t pair;
g_return_val_if_fail (location != NULL, FALSE);
g_return_val_if_fail (IS_CLUSTER_LOCATION (location), FALSE);
g_return_val_if_fail (backend_id != NULL, FALSE);
g_return_val_if_fail (doc != NULL, FALSE);
gtk_object_get (GTK_OBJECT (location), "archive", &cluster, NULL);
pair.a = doc;
pair.b = backend_id;
cluster_foreach_host (cluster, (ClusterHostCB) host_cb, &pair);
return TRUE;
}
static gboolean
host_cb (Cluster *cluster, gchar *hostname, pair_t *pair)
{
xmlDocPtr doc;
gchar *backend_id, *command;
FILE *output;
doc = pair->a;
backend_id = pair->b;
command = g_strconcat ("ssh ", hostname, " ", backend_id, " --set",
NULL);
output = popen (command, "w");
xmlDocDump (output, doc);
pclose (output);
g_free (command);
return FALSE;
}

View File

@@ -1,59 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* cluster-location.h
* Copyright (C) 2000 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@helixcode.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __CLUSTER_LOCATION_H
#define __CLUSTER_LOCATION_H
#include <gnome.h>
#include "location.h"
BEGIN_GNOME_DECLS
#define CLUSTER_LOCATION(obj) GTK_CHECK_CAST (obj, cluster_location_get_type (), ClusterLocation)
#define CLUSTER_LOCATION_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cluster_location_get_type (), ClusterLocationClass)
#define IS_CLUSTER_LOCATION(obj) GTK_CHECK_TYPE (obj, cluster_location_get_type ())
typedef struct _ClusterLocation ClusterLocation;
typedef struct _ClusterLocationClass ClusterLocationClass;
typedef struct _ClusterLocationPrivate ClusterLocationPrivate;
struct _ClusterLocation
{
Location parent;
ClusterLocationPrivate *p;
};
struct _ClusterLocationClass
{
LocationClass location_class;
};
GType cluster_location_get_type (void);
GtkObject *cluster_location_new (void);
END_GNOME_DECLS
#endif /* __CLUSTER_LOCATION_H */

View File

@@ -1,437 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* cluster.c
* Copyright (C) 2000 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@helixcode.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <parser.h>
#include "cluster.h"
enum {
ARG_0,
ARG_SAMPLE
};
typedef struct _SlaveHost SlaveHost;
struct _SlaveHost
{
gchar *hostname;
};
struct _ClusterPrivate
{
GList *slave_hosts;
};
static ArchiveClass *parent_class;
static void cluster_init (Cluster *cluster);
static void cluster_class_init (ClusterClass *class);
static void cluster_set_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void cluster_get_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void cluster_destroy (GtkObject *object);
static void cluster_finalize (GtkObject *object);
static gboolean cluster_construct (Cluster *cluster,
gboolean is_new);
static gboolean load_metadata (Cluster *cluster);
static void save_metadata (Cluster *cluster);
static void cluster_add_slave_host (Cluster *cluster,
SlaveHost *slave_host);
static void cluster_remove_slave_host (Cluster *cluster,
SlaveHost *slave_host);
static SlaveHost *find_slave_host (Cluster *cluster,
gchar *hostname);
static gchar *get_metadata_filename (Cluster *cluster);
static SlaveHost *slave_host_new (gchar *hostname);
static SlaveHost *slave_host_read_xml (xmlNodePtr node);
static xmlNodePtr slave_host_write_xml (SlaveHost *host);
GType
cluster_get_type (void)
{
static GType cluster_type = 0;
if (!cluster_type) {
GtkTypeInfo cluster_info = {
"Cluster",
sizeof (Cluster),
sizeof (ClusterClass),
(GtkClassInitFunc) cluster_class_init,
(GtkObjectInitFunc) cluster_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL
};
cluster_type =
gtk_type_unique (archive_get_type (),
&cluster_info);
}
return cluster_type;
}
static void
cluster_init (Cluster *cluster)
{
cluster->p = g_new0 (ClusterPrivate, 1);
}
static void
cluster_class_init (ClusterClass *class)
{
GtkObjectClass *object_class;
gtk_object_add_arg_type ("Cluster::sample",
GTK_TYPE_POINTER,
GTK_ARG_READWRITE,
ARG_SAMPLE);
object_class = GTK_OBJECT_CLASS (class);
object_class->destroy = cluster_destroy;
object_class->finalize = cluster_finalize;
object_class->set_arg = cluster_set_arg;
object_class->get_arg = cluster_get_arg;
parent_class = ARCHIVE_CLASS
(gtk_type_class (archive_get_type ()));
}
static void
cluster_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
Cluster *cluster;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER (object));
cluster = CLUSTER (object);
switch (arg_id) {
case ARG_SAMPLE:
break;
default:
g_warning ("Bad argument set");
break;
}
}
static void
cluster_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
Cluster *cluster;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER (object));
cluster = CLUSTER (object);
switch (arg_id) {
case ARG_SAMPLE:
break;
default:
g_warning ("Bad argument get");
break;
}
}
static void
cluster_destroy (GtkObject *object)
{
Cluster *cluster;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER (object));
cluster = CLUSTER (object);
save_metadata (cluster);
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
cluster_finalize (GtkObject *object)
{
Cluster *cluster;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_CLUSTER (object));
cluster = CLUSTER (object);
g_free (cluster->p);
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
GtkObject *
cluster_new (gchar *prefix)
{
GtkObject *object;
object = gtk_object_new (cluster_get_type (),
"prefix", prefix,
"is-global", TRUE,
NULL);
if (cluster_construct (CLUSTER (object), TRUE) == FALSE) {
gtk_object_destroy (object);
return NULL;
}
return object;
}
GtkObject *
cluster_load (gchar *prefix)
{
GtkObject *object;
object = gtk_object_new (cluster_get_type (),
"prefix", prefix,
"is-global", TRUE,
NULL);
if (cluster_construct (CLUSTER (object), FALSE) == FALSE) {
gtk_object_destroy (object);
return NULL;
}
return object;
}
void
cluster_foreach_host (Cluster *cluster, ClusterHostCB callback, gpointer data)
{
GList *node;
SlaveHost *host;
g_return_if_fail (cluster != NULL);
g_return_if_fail (IS_CLUSTER (cluster));
g_return_if_fail (callback != NULL);
for (node = cluster->p->slave_hosts; node; node = node->next) {
host = node->data;
if (callback (cluster, host->hostname, data)) break;
}
}
void
cluster_add_host (Cluster *cluster, gchar *hostname)
{
g_return_if_fail (cluster != NULL);
g_return_if_fail (IS_CLUSTER (cluster));
g_return_if_fail (hostname != NULL);
cluster_add_slave_host (cluster, slave_host_new (hostname));
}
void
cluster_remove_host (Cluster *cluster, gchar *hostname)
{
g_return_if_fail (cluster != NULL);
g_return_if_fail (IS_CLUSTER (cluster));
g_return_if_fail (hostname != NULL);
cluster_remove_slave_host (cluster,
find_slave_host (cluster, hostname));
}
static gboolean
cluster_construct (Cluster *cluster, gboolean is_new)
{
if (archive_construct (ARCHIVE (cluster), is_new) == FALSE)
return FALSE;
if (!is_new) {
if (load_metadata (cluster) == FALSE)
return FALSE;
}
return TRUE;
}
/* Loads the metadata associated with the cluster; returns TRUE on success and
* FALSE on failure
*/
static gboolean
load_metadata (Cluster *cluster)
{
xmlDocPtr doc;
xmlNodePtr root_node, node;
gchar *filename;
SlaveHost *new_host;
filename = get_metadata_filename (cluster);
doc = xmlParseFile (filename);
g_free (filename);
if (doc == NULL) return FALSE;
root_node = xmlDocGetRootElement (doc);
if (strcmp (root_node->name, "cluster")) {
xmlFreeDoc (doc);
return FALSE;
}
for (node = root_node->childs; node != NULL; node = node->next) {
if (!strcmp (node->name, "host")) {
new_host = slave_host_read_xml (node);
if (new_host != NULL)
cluster_add_slave_host (cluster, new_host);
}
}
xmlFreeDoc (doc);
return TRUE;
}
static void
save_metadata (Cluster *cluster)
{
xmlDocPtr doc;
xmlNodePtr root_node;
GList *list_node;
gchar *filename;
doc = xmlNewDoc ("1.0");
root_node = xmlNewDocNode (doc, NULL, "cluster", NULL);
for (list_node = cluster->p->slave_hosts; list_node != NULL;
list_node = list_node->next)
{
xmlAddChild (root_node,
slave_host_write_xml (list_node->data));
}
xmlDocSetRootElement (doc, root_node);
filename = get_metadata_filename (cluster);
xmlSaveFile (filename, doc);
g_free (filename);
}
/* Adds a slave host to the list of slave hosts for this cluster */
static void
cluster_add_slave_host (Cluster *cluster, SlaveHost *slave_host)
{
if (slave_host == NULL) return;
cluster->p->slave_hosts =
g_list_append (cluster->p->slave_hosts, slave_host);
}
static void
cluster_remove_slave_host (Cluster *cluster, SlaveHost *slave_host)
{
if (slave_host == NULL) return;
cluster->p->slave_hosts =
g_list_remove (cluster->p->slave_hosts, slave_host);
}
static SlaveHost *
find_slave_host (Cluster *cluster, gchar *hostname)
{
SlaveHost *host;
GList *node;
g_return_val_if_fail (hostname != NULL, NULL);
for (node = cluster->p->slave_hosts; node != NULL; node = node->next) {
host = node->data;
if (!strcmp (host->hostname, hostname))
return host;
}
return NULL;
}
/* Returns the filename of the metadata file (should be freed after use) */
static gchar *
get_metadata_filename (Cluster *cluster)
{
return g_concat_dir_and_file
(archive_get_prefix (ARCHIVE (cluster)), "cluster.xml");
}
/* Constructs a new slave host structure */
static SlaveHost *
slave_host_new (gchar *hostname)
{
SlaveHost *new_host;
new_host = g_new0 (SlaveHost, 1);
new_host->hostname = g_strdup (hostname);
return new_host;
}
/* Constructs a new slave host structure from an XML node */
static SlaveHost *
slave_host_read_xml (xmlNodePtr node)
{
gchar *hostname;
hostname = xmlGetProp (node, "name");
if (hostname != NULL)
return slave_host_new (hostname);
else
return NULL;
}
/* Constructs an XML node for the slave host */
static xmlNodePtr
slave_host_write_xml (SlaveHost *host)
{
xmlNodePtr node;
node = xmlNewNode (NULL, "host");
xmlNewProp (node, "name", host->hostname);
return node;
}

View File

@@ -1,71 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* cluster.h
* Copyright (C) 2000 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@helixcode.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __CLUSTER_H
#define __CLUSTER_H
#include <gnome.h>
#include "archive.h"
BEGIN_GNOME_DECLS
#define CLUSTER(obj) GTK_CHECK_CAST (obj, cluster_get_type (), Cluster)
#define CLUSTER_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cluster_get_type (), ClusterClass)
#define IS_CLUSTER(obj) GTK_CHECK_TYPE (obj, cluster_get_type ())
typedef struct _Cluster Cluster;
typedef struct _ClusterClass ClusterClass;
typedef struct _ClusterPrivate ClusterPrivate;
typedef gboolean (*ClusterHostCB) (Cluster *, gchar *, gpointer);
struct _Cluster
{
Archive parent;
ClusterPrivate *p;
};
struct _ClusterClass
{
ArchiveClass archive_class;
};
GType cluster_get_type (void);
GtkObject *cluster_new (gchar *prefix);
GtkObject *cluster_load (gchar *prefix);
void cluster_foreach_host (Cluster *cluster,
ClusterHostCB callback,
gpointer data);
void cluster_add_host (Cluster *cluster,
gchar *hostname);
void cluster_remove_host (Cluster *cluster,
gchar *hostname);
END_GNOME_DECLS
#endif /* __CLUSTER_H */

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,90 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* config-log.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __CONFIG_LOG_H
#define __CONFIG_LOG_H
#include <gnome.h>
#include <stdio.h>
#include <time.h>
#define CONFIG_LOG(obj) GTK_CHECK_CAST (obj, config_log_get_type (), ConfigLog)
#define CONFIG_LOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, config_log_get_type (), ConfigLogClass)
#define IS_CONFIG_LOG(obj) GTK_CHECK_TYPE (obj, config_log_get_type ())
typedef struct _ConfigLog ConfigLog;
typedef struct _ConfigLogClass ConfigLogClass;
typedef struct _ConfigLogPrivate ConfigLogPrivate;
typedef struct _Location Location;
typedef gint (*ConfigLogIteratorCB) (ConfigLog *, gint, gchar *,
struct tm *, gpointer);
typedef void (*GarbageCollectCB) (ConfigLog *, gchar *, gint, gpointer);
struct _ConfigLog
{
GtkObject object;
ConfigLogPrivate *p;
};
struct _ConfigLogClass
{
GtkObjectClass parent;
};
GType config_log_get_type (void);
GtkObject *config_log_open (Location *location);
void config_log_delete (ConfigLog *config_log);
gint config_log_get_rollback_id_for_date (ConfigLog *config_log,
struct tm *date,
const gchar *backend_id);
gint config_log_get_rollback_id_by_steps (ConfigLog *config_log,
guint steps,
const gchar *backend_id);
const gchar *config_log_get_backend_id_for_id (ConfigLog *config_log,
gint id);
const struct tm *config_log_get_date_for_id (ConfigLog *config_log,
gint id);
gint config_log_write_entry (ConfigLog *config_log,
const gchar *backend_id,
gboolean is_default_data);
void config_log_iterate (ConfigLog *config_log,
ConfigLogIteratorCB callback,
gpointer data);
void config_log_reset_filenames (ConfigLog *config_log);
void config_log_reload (ConfigLog *config_log);
void config_log_garbage_collect (ConfigLog *config_log,
gchar *backend_id,
GarbageCollectCB callback,
gpointer data);
#endif /* __CONFIG_LOG */

View File

@@ -1,54 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* config-manager.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@ximian.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include <glade/glade.h>
#include "config-manager-dialog.h"
int
main (int argc, char **argv)
{
GtkWidget *dialog;
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
gnome_init ("config-manager", VERSION, argc, argv);
glade_gnome_init ();
dialog = config_manager_dialog_new (CM_DIALOG_USER_ONLY);
gtk_widget_show (dialog);
gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
gtk_main_quit, NULL);
gtk_main ();
return 0;
}

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,144 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* location.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __LOCATION_H
#define __LOCATION_H
#include <gnome.h>
#include <tree.h>
#include <bonobo.h>
#include "ConfigArchiver.h"
#include "config-log.h"
#define LOCATION(obj) GTK_CHECK_CAST (obj, location_get_type (), Location)
#define LOCATION_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, location_get_type (), LocationClass)
#define IS_LOCATION(obj) GTK_CHECK_TYPE (obj, location_get_type ())
typedef struct _LocationClass LocationClass;
typedef struct _LocationPrivate LocationPrivate;
typedef struct _Archive Archive;
typedef ConfigArchiver_ContainmentType ContainmentType;
typedef ConfigArchiver_StoreType StoreType;
typedef int (*LocationBackendCB) (Location *, gchar *, gpointer);
struct _Location
{
BonoboXObject object;
LocationPrivate *p;
};
struct _LocationClass
{
BonoboXObjectClass parent;
POA_ConfigArchiver_Location__epv epv;
gboolean (*do_rollback) (Location *location,
gchar *backend_id,
xmlDocPtr xml_doc);
};
GType location_get_type (void);
BonoboObject *location_new (Archive *archive,
const gchar *locid,
const gchar *label,
Location *parent);
BonoboObject *location_open (Archive *archive,
const gchar *locid);
void location_delete (Location *location);
gchar *location_get_storage_filename (Location *location,
const gchar *backend_id,
gboolean is_default);
gchar *location_get_rollback_filename (Location *location,
struct tm *date,
gint steps,
const gchar *backend_id,
gboolean parent_chain);
void location_storage_complete (Location *location,
const gchar *filename);
gint location_store (Location *location,
gchar *backend_id,
FILE *input,
ConfigArchiver_StoreType store_type);
void location_store_xml (Location *location,
gchar *backend_id,
xmlDocPtr xml_doc,
ConfigArchiver_StoreType store_type);
void location_rollback_backends_to (Location *location,
struct tm *date,
gint steps,
GList *backends,
gboolean parent_chain);
const struct tm *location_get_modification_time (Location *location,
const gchar *backend_id);
ContainmentType location_contains (Location *location,
const gchar *backend_id);
gint location_add_backend (Location *location,
const gchar *backend_id,
ContainmentType type);
void location_remove_backend (Location *location,
const gchar *backend_id);
void location_foreach_backend (Location *location,
LocationBackendCB callback,
gpointer data);
GList *location_find_path_from_common_parent (Location *location,
Location *location2);
Location *location_get_parent (Location *location);
const gchar *location_get_path (Location *location);
const gchar *location_get_label (Location *location);
const gchar *location_get_id (Location *location);
void location_set_id (Location *location,
const gchar *locid);
gint location_store_full_snapshot (Location *location);
GList *location_get_changed_backends (Location *location,
Location *location1);
gboolean location_does_backend_change (Location *location,
Location *location1,
const gchar *backend_id);
ConfigLog *location_get_config_log (Location *location);
void location_garbage_collect (Location *location);
gboolean location_is_deleted (const Location *location);
#endif /* __LOCATION */

View File

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

View File

@@ -1,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

View File

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

View File

@@ -1,187 +0,0 @@
#!/bin/sh
#
# test-1.sh
# Copyright (C) 2001 Ximian, Inc.
# Written by Bradford Hovinen <hovinen@ximian.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#
# Test suite, part I
#
# Given an archive to work with (global or per-user):
#
# - Destroy the entire archive forcibly (rm -rf)
# - Store backend data in the archive
# - Check to see that a new archive has been created with default
# location "Default", and that the data have been properly stored
# there
XIMIAN_ARCHIVER=${XIMIAN_ARCHIVER:-'../ximian-archiver'}
function get_unused_tmpfile () {
tmp_file_no=0
while [ -e "/tmp/$1-$tmp_file_no" ]; do
let 'tmp_file_no=tmp_file_no+1'
done
echo "/tmp/$1-$tmp_file_no";
}
function run_command () {
if [ "x$use_gdb" == "xyes" ]; then
commands_file=`get_unused_tmpfile gdb-commands-file`
echo "set args $extra_args $@" >$commands_file
gdb ../.libs/lt-ximian-archiver -x $commands_file
else
echo "Running archiver program with the following command line:"
echo $XIMIAN_ARCHIVER $extra_args $@
$XIMIAN_ARCHIVER $extra_args $@
echo
fi
}
if [ "x$1" == "x" ]; then
echo "Usage: test-1.sh --global|--per-user [--gdb]"
exit 1
fi
for test_option; do
case "$test_option" in
--global)
extra_args="--global"
archive_dir=/usr/share/ximian-config
;;
--per-user)
extra_args=""
archive_dir=$HOME/.gnome/ximian-config
;;
--gdb)
use_gdb=yes
;;
*)
echo "Usage: test-1.sh --global|--per-user [--gdb]"
exit 1
esac
done
if [ -d $archive_dir ]; then
mv $archive_dir "$archive_dir-backup"
fi
##############################################################################
# Test proper
##############################################################################
archiver_test_data_file=`get_unused_tmpfile ximian-archiver-test-data`;
cat >$archiver_test_data_file <<EOF
<?xml version="1.0"?>
<background-properties>
<bg-color1>#111128</bg-color1>
<bg-color2>#796dff</bg-color2>
<enabled/>
<wallpaper/>
<gradient/>
<orientation>vertical</orientation>
<wallpaper-type>0</wallpaper-type>
<wallpaper-filename>/home/hovinen/media/Propaganda/Vol3/9a.jpg</wallpaper-filename>
<wallpaper-sel-path>./</wallpaper-sel-path>
<auto-apply/>
<adjust-opacity/>
<opacity>172</opacity>
</background-properties>
EOF
run_command --store --backend=background-properties-capplet \
<$archiver_test_data_file
##############################################################################
# Results check
##############################################################################
echo -n "Checking whether default location was created properly..."
if [ -d "$archive_dir/default" ]; then
echo "yes -- good"
else
echo "no -- error"
fi
echo -n "Checking whether the XML data snapshot was created..."
if [ -f "$archive_dir/default/00000000.xml" ]; then
echo "yes -- good"
else
echo "no -- error"
fi
echo -n "Checking whether the XML data match the XML data given..."
differences_file=`get_unused_tmpfile differences`
diff -u $archive_dir/default/00000000.xml $archiver_test_data_file \
>$differences_file
if [ ! -s $differences_file ]; then
echo "yes -- good"
else
echo "no -- error"
echo "Differences are as follows:"
cat $differences_file
echo
fi
rm -f $differences_file
echo -n "Checking if the config log data are correct..."
config_log_id=`awk '{print $1}' $archive_dir/default/config.log`
config_log_backend=`awk '{print $4}' $archive_dir/default/config.log`
if [ "x$config_log_id" == "x00000000" -a \
"x$config_log_backend" == "xbackground-properties-capplet" ]; then
echo "yes -- good"
else
echo "no -- error"
echo "Config log is as follows:"
cat $archive_dir/default/config.log
echo
fi
##############################################################################
# Putting the results together
##############################################################################
rm -f $archiver_test_data_file
results_dir="ximian-config-results-`date +%Y%m%d`"
results_dir=`get_unused_tmpfile $results_dir`
mkdir $results_dir
(cd $archive_dir && tar cf - *) | (cd $results_dir && tar xf -)
rm -rf $archive_dir
if [ -d "$archive_dir-backup" ]; then
mv "$archive_dir-backup" $archive_dir
fi
echo
echo "Test complete"
echo "Resulting archive data in $results_dir"

View File

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

View File

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

View File

@@ -1,113 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* util.c
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
/* Read a fixed-digit number from a string, advancing the string
* pointer. Return TRUE if the extraction was successful, FALSE if
* there was no number to extract or if the number was too short.
*/
gboolean
extract_number (char **str, int *number, int digits)
{
char buf[64];
if (!isdigit (**str)) return FALSE;
if (digits > 63) digits = 63;
strncpy (buf, *str, digits);
buf[digits] = '\0';
*number = atoi (buf);
if (strlen (buf) < digits) return FALSE;
*str += digits;
return TRUE;
}
struct tm *
parse_date (char *str)
{
struct tm *date;
gboolean ok;
gint value;
ok = extract_number (&str, &value, 4);
if (!ok) return NULL;
date = g_new (struct tm, 1);
date->tm_isdst = 0;
date->tm_year = value - 1900;
date->tm_mon = 11;
date->tm_mday = 31;
date->tm_hour = 23;
date->tm_min = 59;
date->tm_sec = 59;
if (extract_number (&str, &value, 2))
date->tm_mon = value - 1;
else
return date;
if (extract_number (&str, &value, 2))
date->tm_mday = value;
else
return date;
if (extract_number (&str, &value, 2))
date->tm_hour = value;
else
return date;
if (extract_number (&str, &value, 2))
date->tm_min = value;
else
return date;
if (extract_number (&str, &value, 2))
date->tm_sec = value;
#ifdef __USE_BSD
date->tm_zone = "GMT";
date->tm_gmtoff = 0;
#endif
return date;
}
struct tm *
dup_date (const struct tm *date)
{
struct tm *date1;
date1 = g_new (struct tm, 1);
memcpy (date1, date, sizeof (struct tm));
return date1;
}

View File

@@ -1,51 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* util.h
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Written by Bradford Hovinen (hovinen@ximian.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __UTIL_H
#define __UTIL_H
#include <time.h>
#include <glib.h>
/* Uncomment this if you want debugs: */
#define DEBUG_ME_MORE
#ifdef DEBUG_ME_MORE
# ifdef __GNUC__
# define DEBUG_MSG(str, args...) \
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "(%d:%s) " str, \
getpid (), __FUNCTION__ , ## args)
# else
# define DEBUG_MSG(str, args...)
# endif
#else
/* This was redefined here because it was messing with the frontend->backend
* talk. Arturo */
# define DEBUG_MSG(str, args...)
#endif
gboolean extract_number (char **str, int *number, int digits);
struct tm *parse_date (char *str);
struct tm *dup_date (const struct tm *date);
#endif /* __UTIL_H */

View File

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

View File

@@ -1,45 +0,0 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
PKG_NAME="control-center"
(test -f $srcdir/configure.in \
&& test -f $srcdir/autogen.sh \
&& test -d $srcdir/control-center) || {
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
echo " top-level $PKG_NAME directory"
exit 1
}
DIE=0
rm -f .using-gnome-libs-package
# This is a bit complicated here since we can't use gnome-config yet.
# It'll be easier after switching to pkg-config since we can then
# use pkg-config to find the gnome-autogen.sh script.
gnome_autogen=
gnome_datadir=
ifs_save="$IFS"; IFS=":"
for dir in $PATH ; do
test -z "$dir" && dir=.
if test -f $dir/gnome-autogen.sh ; then
gnome_autogen="$dir/gnome-autogen.sh"
gnome_datadir=`echo $dir | sed -e 's,/bin$,/share,'`
break
fi
done
IFS="$ifs_save"
if test -z "$gnome_autogen" ; then
echo "You need to install the gnome-common module and make"
echo "sure the gnome-autogen.sh script is in your \$PATH."
exit 1
fi
GNOME_DATADIR="$gnome_datadir" USE_GNOME2_MACROS=1 . $gnome_autogen

View File

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

View File

@@ -1,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

View File

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

View File

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

View File

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

View File

@@ -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.

View File

@@ -1,29 +0,0 @@
bin_PROGRAMS = gnome-at-properties
gnome_at_properties_LDADD = $(AT_CAPPLET_LIBS) $(top_builddir)/capplets/common/libcommon.la
gnome_at_properties_SOURCES = \
main.c \
at-startup-session.h \
at-startup-session.c
gnome_at_properties_LDFLAGS = -export-dynamic
@INTLTOOL_DESKTOP_RULE@
desktopdir = $(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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

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

View File

@@ -1,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

View File

@@ -1,160 +0,0 @@
#include <config.h>
#include <string.h>
#include <glib-object.h>
#include <gconf/gconf-client.h>
#include "at-startup-session.h"
#define AT_STARTUP_KEY "/desktop/gnome/accessibility/startup/exec_ats"
#define GNOPERNICUS_MAGNIFIER_KEY "/apps/gnopernicus/srcore/mag_active"
#define GNOPERNICUS_SPEECH_KEY "/apps/gnopernicus/srcore/sp_active"
#define GNOPERNICUS_BRAILLE_KEY "/apps/gnopernicus/srcore/br_active"
static AtStartupState at_startup_state_recent;
static GSList *
at_startup_get_list (GConfClient *client)
{
GError *error = NULL;
GSList *at_list = gconf_client_get_list (client, AT_STARTUP_KEY, GCONF_VALUE_STRING, &error);
if (error) {
g_warning ("Error getting value of " AT_STARTUP_KEY ": %s", error->message);
g_error_free (error);
return NULL;
}
return at_list;
}
gint
at_startup_string_compare (gconstpointer s1, gconstpointer s2)
{
if (s1 && s2) {
return strcmp (s1, s2);
}
else
return (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);
}

View File

@@ -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);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,296 +0,0 @@
#include <config.h>
#include <gtk/gtk.h>
#include <gconf/gconf-client.h>
#include <glade/glade.h>
#include "capplet-util.h"
#include "gconf-property-editor.h"
#include "activate-settings-daemon.h"
#include "at-startup-session.h"
#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility"
#define ACCESSIBILITY_KEY_DIR "/desktop/gnome/interface"
#define AT_STARTUP_DIR "/desktop/gnome/accessibility/startup"
#define AT_STARTUP_KEY "/desktop/gnome/accessibility/startup/exec_ats"
#define SR_PREFS_DIR "/apps/gnopernicus/srcore"
static AtStartupState at_startup_state, at_startup_state_initial;
static void
init_startup_state (GladeXML *dialog)
{
GConfClient *client = gconf_client_get_default ();
at_startup_state.flags = (gconf_client_get_bool (client,
ACCESSIBILITY_KEY,
NULL)) ? 1 : 0;
at_startup_state_init (&at_startup_state);
at_startup_state_initial.flags = at_startup_state.flags;
g_object_unref (client);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_keyboard_toggle")),
at_startup_state.enabled.osk);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_screenreader_toggle")),
at_startup_state.enabled.screenreader);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("at_magnifier_toggle")),
at_startup_state.enabled.magnifier);
gtk_widget_set_sensitive (WID ("at_keyboard_toggle"),
at_startup_state.enabled.osk_installed);
gtk_widget_set_sensitive (WID ("at_screenreader_toggle"),
at_startup_state.enabled.screenreader_installed);
gtk_widget_set_sensitive (WID ("at_magnifier_toggle"),
at_startup_state.enabled.magnifier_installed);
if (at_startup_state.enabled.osk_installed &&
at_startup_state.enabled.screenreader_installed &&
at_startup_state.enabled.magnifier_installed) {
gtk_widget_hide (WID ("at_applications_warning_label"));
gtk_widget_hide (WID ("at_applications_hseparator"));
} else {
gchar *warning_label;
gtk_widget_show (WID ("at_applications_warning_label"));
gtk_widget_show (WID ("at_applications_hseparator"));
if (!at_startup_state.enabled.osk_installed &&
!(at_startup_state.enabled.screenreader_installed ||
at_startup_state.enabled.magnifier_installed)) {
warning_label = g_strdup_printf ("<i>%s</i>", _("No Assistive Technology is available on your system. The 'gok' package must be installed in order to get on-screen keyboard support, and the 'gnopernicus' package must be installed for screenreading and magnifying capabilities."));
} else if (!at_startup_state.enabled.osk_installed) {
warning_label = g_strdup_printf ("<i>%s</i>", _("Not all available assistive technologies are installed on your system. The 'gok' package must be installed in order to get on-screen keyboard support."));
} else {
warning_label = g_strdup_printf ("<i>%s</i>", _("Not all available assistive technologies are installed on your system. The 'gnopernicus' package must be installed for screenreading and magnifying capabilities."));
}
gtk_label_set_markup (GTK_LABEL (WID ("at_applications_warning_label")), warning_label);
g_free (warning_label);
}
}
static GladeXML *
create_dialog (void)
{
GladeXML *dialog;
dialog = glade_xml_new (GLADEDIR "/at-enable-dialog.glade", "at_properties_dialog", NULL);
gtk_image_set_from_stock (GTK_IMAGE (WID ("at_close_and_logout_image")),
GTK_STOCK_QUIT, GTK_ICON_SIZE_BUTTON);
gtk_image_set_from_file (GTK_IMAGE (WID ("at_enable_image")),
PIXMAPDIR "/at-support.png");
gtk_image_set_from_file (GTK_IMAGE (WID ("at_applications_image")),
PIXMAPDIR "/at-startup.png");
return dialog;
}
static void
cb_dialog_response (GtkDialog *dialog, gint response_id)
{
GnomeClient *client;
if (response_id == GTK_RESPONSE_HELP)
capplet_help (GTK_WINDOW (dialog),
"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;
}

View File

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

View File

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

View File

@@ -1,36 +0,0 @@
noinst_LIBRARIES = libaccessibility-keyboard.a
libaccessibility_keyboard_a_SOURCES = \
accessibility-keyboard.c \
accessibility-keyboard.h
# in case we need to forward port the sun accessX extension
# AccessXcomm.c
bin_PROGRAMS = gnome-accessibility-keyboard-properties
gnome_accessibility_keyboard_properties_SOURCES = gnome-accessibility-keyboard-properties.c
gnome_accessibility_keyboard_properties_LDADD = \
libaccessibility-keyboard.a $(GNOMECC_CAPPLETS_LIBS)
@INTLTOOL_DESKTOP_RULE@
pixmapdir = $(GNOMECC_PIXMAPS_DIR)
pixmap_DATA = \
accessibility-keyboard-togglekey.png \
accessibility-keyboard-mousekey.png \
accessibility-keyboard-slowkey.png \
accessibility-keyboard-stickykey.png \
accessibility-keyboard-bouncekey.png
Gladedir = $(GNOMECC_GLADE_DIR)
Glade_DATA = gnome-accessibility-keyboard-properties.glade
desktopdir = $(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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,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;
}

View File

@@ -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

View File

@@ -1,32 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* accessibility-keyboard.c
* Copyright (C) 2002 Ximian, Inc.
*
* Written by: Jody Goldberg <jody@gnome.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef GNOME_ACCESSIBILITY_KEYBOARD_H
#define GNOME_ACCESSIBILITY_KEYBOARD_H
#include <gconf/gconf-changeset.h>
#include <gtk/gtkwidget.h>
GtkWidget *setup_accessX_dialog (GConfChangeSet *changeset);
#endif /* GNOME_ACCESSIBILITY_KEYBOARD_H */

View File

@@ -1,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;
}

View File

@@ -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:

View File

@@ -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),

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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

View File

@@ -1,5 +0,0 @@
Makefile
Makefile.in
.deps
gnome-theme-test
stamp-h.in

View File

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

View File

@@ -1,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

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,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);
}

View File

@@ -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__ */

View File

@@ -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);
}
}

View File

@@ -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 */

View File

@@ -1,420 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* file-transfer-dialog.c
* Copyright (C) 2002 Ximian, Inc.
*
* Written by Rachel Hestilow <hestilow@ximian.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "file-transfer-dialog.h"
#include <libgnomevfs/gnome-vfs-async-ops.h>
#include <libgnome/libgnome.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkprogressbar.h>
#include <gtk/gtkstock.h>
#include <limits.h>
enum
{
PROP_0,
PROP_FROM_URI,
PROP_TO_URI,
PROP_FRACTION_COMPLETE,
PROP_NTH_URI,
PROP_TOTAL_URIS
};
enum
{
CANCEL,
DONE,
LAST_SIGNAL
};
guint file_transfer_dialog_signals[LAST_SIGNAL] = {0, };
struct _FileTransferDialogPrivate
{
GtkWidget *progress;
GtkWidget *status;
GtkWidget *num_files;
GtkWidget *current;
GtkWidget *from;
GtkWidget *to;
guint nth;
guint total;
GnomeVFSAsyncHandle *handle;
};
static GObjectClass *parent_class;
static void
file_transfer_dialog_cancel (FileTransferDialog *dlg)
{
if (dlg->priv->handle)
{
gnome_vfs_async_cancel (dlg->priv->handle);
dlg->priv->handle = NULL;
}
}
static void
file_transfer_dialog_finalize (GObject *obj)
{
FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (obj);
g_free (dlg->priv);
if (parent_class->finalize)
parent_class->finalize (G_OBJECT (dlg));
}
static void
file_transfer_dialog_update_num_files (FileTransferDialog *dlg)
{
gchar *str = g_strdup_printf (_("%i of %i"),
dlg->priv->nth, dlg->priv->total);
gtk_label_set_text (GTK_LABEL (dlg->priv->num_files), str);
g_free (str);
}
static void
file_transfer_dialog_response (GtkDialog *dlg, gint response_id)
{
g_signal_emit (G_OBJECT (dlg),
file_transfer_dialog_signals[CANCEL], 0, NULL);
}
static void
file_transfer_dialog_set_prop (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (object);
gchar *str;
gchar *base;
switch (prop_id)
{
case PROP_FROM_URI:
base = g_path_get_basename (g_value_get_string (value));
str = g_strdup_printf (_("Transferring: %s"), base);
gtk_label_set_text (GTK_LABEL (dlg->priv->current),
str);
g_free (base);
g_free (str);
base = g_path_get_dirname (g_value_get_string (value));
str = g_strdup_printf (_("From: %s"), base);
gtk_label_set_text (GTK_LABEL (dlg->priv->from),
str);
g_free (base);
g_free (str);
break;
case PROP_TO_URI:
base = g_path_get_dirname (g_value_get_string (value));
str = g_strdup_printf (_("To: %s"), base);
gtk_label_set_text (GTK_LABEL (dlg->priv->to),
str);
g_free (base);
g_free (str);
break;
case PROP_FRACTION_COMPLETE:
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (dlg->priv->progress), g_value_get_double (value));
break;
case PROP_NTH_URI:
dlg->priv->nth = g_value_get_uint (value);
file_transfer_dialog_update_num_files (dlg);
break;
case PROP_TOTAL_URIS:
dlg->priv->total = g_value_get_uint (value);
file_transfer_dialog_update_num_files (dlg);
break;
}
}
static void
file_transfer_dialog_get_prop (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (object);
switch (prop_id)
{
case PROP_NTH_URI:
g_value_set_uint (value, dlg->priv->nth);
break;
case PROP_TOTAL_URIS:
g_value_set_uint (value, dlg->priv->total);
break;
}
}
static void
file_transfer_dialog_class_init (FileTransferDialogClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
klass->cancel = file_transfer_dialog_cancel;
object_class->finalize = file_transfer_dialog_finalize;
object_class->get_property = file_transfer_dialog_get_prop;
object_class->set_property = file_transfer_dialog_set_prop;
GTK_DIALOG_CLASS (klass)->response = file_transfer_dialog_response;
g_object_class_install_property
(object_class, PROP_FROM_URI,
g_param_spec_string ("from_uri",
_("From URI"),
_("URI currently transferring from"),
NULL,
G_PARAM_READWRITE));
g_object_class_install_property
(object_class, PROP_TO_URI,
g_param_spec_string ("to_uri",
_("To URI"),
_("URI currently transferring to"),
NULL,
G_PARAM_WRITABLE));
g_object_class_install_property
(object_class, PROP_FRACTION_COMPLETE,
g_param_spec_double ("fraction_complete",
_("Fraction completed"),
_("Fraction of transfer currently completed"),
0, 1, 0,
G_PARAM_WRITABLE));
g_object_class_install_property
(object_class, PROP_NTH_URI,
g_param_spec_uint ("nth_uri",
_("Current URI index"),
_("Current URI index - starts from 1"),
1, INT_MAX, 1,
G_PARAM_READWRITE));
g_object_class_install_property
(object_class, PROP_TOTAL_URIS,
g_param_spec_uint ("total_uris",
_("Total URIs"),
_("Total number of URIs"),
1, INT_MAX, 1,
G_PARAM_READWRITE));
file_transfer_dialog_signals[CANCEL] =
g_signal_new ("cancel",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (FileTransferDialogClass, cancel),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
file_transfer_dialog_signals[DONE] =
g_signal_new ("done",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FileTransferDialogClass, done),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
parent_class =
G_OBJECT_CLASS (g_type_class_ref (GTK_TYPE_DIALOG));
}
static void
file_transfer_dialog_init (FileTransferDialog *dlg)
{
GtkWidget *hbox;
dlg->priv = g_new0 (FileTransferDialogPrivate, 1);
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->vbox),
4);
gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 4);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
hbox, FALSE, FALSE, 0);
dlg->priv->status = gtk_label_new ("");
gtk_label_set_justify (GTK_LABEL (dlg->priv->status),
GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->status), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (hbox),
dlg->priv->status, TRUE, TRUE, 0);
dlg->priv->num_files = gtk_label_new ("");
gtk_label_set_justify (GTK_LABEL (dlg->priv->num_files),
GTK_JUSTIFY_RIGHT);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->num_files), 1.0, 0.5);
gtk_box_pack_start (GTK_BOX (hbox),
dlg->priv->num_files, TRUE, TRUE, 0);
dlg->priv->progress = gtk_progress_bar_new ();
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
dlg->priv->progress, FALSE, FALSE, 0);
dlg->priv->current = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
dlg->priv->current, FALSE, FALSE, 0);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->current), 0.0, 0.5);
dlg->priv->from = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
dlg->priv->from, FALSE, FALSE, 0);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->from), 0.0, 0.5);
dlg->priv->to = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
dlg->priv->to, FALSE, FALSE, 0);
gtk_misc_set_alignment (GTK_MISC (dlg->priv->to), 0.0, 0.5);
gtk_dialog_add_button (GTK_DIALOG (dlg),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
gtk_widget_show_all (GTK_DIALOG (dlg)->vbox);
}
GType
file_transfer_dialog_get_type (void)
{
static GType file_transfer_dialog_type = 0;
if (!file_transfer_dialog_type)
{
static GTypeInfo file_transfer_dialog_info =
{
sizeof (FileTransferDialogClass),
NULL, /* GBaseInitFunc */
NULL, /* GBaseFinalizeFunc */
(GClassInitFunc) file_transfer_dialog_class_init,
NULL, /* GClassFinalizeFunc */
NULL, /* data */
sizeof (FileTransferDialog),
0, /* n_preallocs */
(GInstanceInitFunc) file_transfer_dialog_init,
NULL
};
file_transfer_dialog_type =
g_type_register_static (GTK_TYPE_DIALOG,
"FileTransferDialog",
&file_transfer_dialog_info,
0);
}
return file_transfer_dialog_type;
}
GtkWidget*
file_transfer_dialog_new (void)
{
return GTK_WIDGET (g_object_new (file_transfer_dialog_get_type (),
NULL));
}
static int
file_transfer_dialog_update_cb (GnomeVFSAsyncHandle *handle,
GnomeVFSXferProgressInfo *info,
gpointer data)
{
FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (data);
if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR)
return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
if (info->source_name)
g_object_set (G_OBJECT (dlg),
"from_uri", info->source_name,
NULL);
if (info->target_name)
g_object_set (G_OBJECT (dlg),
"to_uri", info->target_name,
NULL);
if (info->bytes_total)
g_object_set (G_OBJECT (dlg),
"fraction_complete", (double) info->total_bytes_copied / (double) info->bytes_total,
NULL);
if (info->file_index && info->files_total)
g_object_set (G_OBJECT (dlg),
"nth_uri", info->file_index,
"total_uris", info->files_total,
NULL);
switch (info->phase)
{
case GNOME_VFS_XFER_PHASE_INITIAL:
gtk_label_set_text (GTK_LABEL (dlg->priv->status),
_("Connecting..."));
gtk_window_set_title (GTK_WINDOW (dlg),
_("Connecting..."));
break;
case GNOME_VFS_XFER_PHASE_READYTOGO:
case GNOME_VFS_XFER_PHASE_OPENSOURCE:
gtk_label_set_text (GTK_LABEL (dlg->priv->status),
_("Downloading..."));
gtk_window_set_title (GTK_WINDOW (dlg),
_("Downloading..."));
break;
case GNOME_VFS_XFER_PHASE_COMPLETED:
g_signal_emit (G_OBJECT (dlg),
file_transfer_dialog_signals[DONE],
0, NULL);
return 0;
default:
break;
}
return 1;
}
GnomeVFSResult
file_transfer_dialog_wrap_async_xfer (FileTransferDialog *dlg,
GList *source_uri_list,
GList *target_uri_list,
GnomeVFSXferOptions xfer_options,
GnomeVFSXferErrorMode error_mode,
GnomeVFSXferOverwriteMode overwrite_mode,
int priority)
{
g_return_val_if_fail (IS_FILE_TRANSFER_DIALOG (dlg),
GNOME_VFS_ERROR_BAD_PARAMETERS);
return gnome_vfs_async_xfer (&dlg->priv->handle,
source_uri_list,
target_uri_list,
xfer_options,
error_mode,
overwrite_mode,
priority,
file_transfer_dialog_update_cb,
dlg,
NULL,
NULL
);
}

View File

@@ -1,69 +0,0 @@
/* -*- mode: c; style: linux -*- */
/* file-transfer-dialog.h
* Copyright (C) 2002 Ximian, Inc.
*
* Written by Rachel Hestilow <hestilow@ximian.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __FILE_TRANSFER_DIALOG_H__
#define __FILE_TRANSFER_DIALOG_H__
#include <gtk/gtkdialog.h>
#include <libgnomevfs/gnome-vfs-xfer.h>
G_BEGIN_DECLS
#define FILE_TRANSFER_DIALOG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, file_transfer_dialog_get_type (), FileTransferDialog)
#define FILE_TRANSFER_DIALOG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, file_transfer_dialog_get_type (), FileTransferDialogClass)
#define IS_FILE_TRANSFER_DIALOG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, file_transfer_dialog_get_type ())
typedef struct _FileTransferDialog FileTransferDialog;
typedef struct _FileTransferDialogClass FileTransferDialogClass;
typedef struct _FileTransferDialogPrivate FileTransferDialogPrivate;
struct _FileTransferDialog
{
GtkDialog dialog;
FileTransferDialogPrivate *priv;
};
struct _FileTransferDialogClass
{
GtkDialogClass parent_class;
void (*cancel) (FileTransferDialog *dlg);
void (*done) (FileTransferDialog *dlg);
};
GType file_transfer_dialog_get_type (void);
GtkWidget* file_transfer_dialog_new (void);
GnomeVFSResult file_transfer_dialog_wrap_async_xfer (FileTransferDialog *dlg,
GList *source_uri_list,
GList *target_uri_list,
GnomeVFSXferOptions xfer_options,
GnomeVFSXferErrorMode error_mode,
GnomeVFSXferOverwriteMode overwrite_mode,
int priority);
G_END_DECLS
#endif /* __FILE_TRANSFER_DIALOG_H__ */

View File

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

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