Commit graph

52 commits

Author SHA1 Message Date
Thiago Macieira
dbdf50d03c Fix compilation with libzip < 0.10
Signed-off-by: Thiago Macieira <thiago@macieira.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-12-20 09:53:05 -08:00
Lubomir I. Ivanov
f487953ad3 Files: add wrappers for certain open() methods
Due to filepath encoding issues on win32 we need
wrappers for:
- open()
- fopen()
- opendir()
- zip_open() (this is readonly on win32)

Patch only declares/defines the wrappers
in dive.h, windows.c, linux.c, macos.c.

Suggestions-by: Thiago Macieira <thiago@macieira.org>
Suggestions-by: Jef Driesen <jefdriesen@telenet.be>
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-12-19 07:28:20 -08:00
Lubomir I. Ivanov
0b5b671dd9 windows.c: use the USERNAME enviroment variable
system_default_filename():
Use USERNAME, which should work for Windows XP and above.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-10-09 07:21:04 -07:00
Lubomir I. Ivanov
218c0956e2 main.cpp: remove usage of subsurface_command_line_*
subsurface_command_line_* are now redundant as Qt
should handle the command line argument parsing on Windows
for which these functions where mainly used and where NOP
for other OS.

main.cpp also receives a couple of small changes to use:
QCoreApplication::arguments()
to obtain the list of expanded arguments and parse those
instead.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-10-08 06:26:03 -07:00
Dirk Hohndel
4e6dd75d11 Remove feature checking
We needed this in Gtk version as we were using a system font to show the
stars and that was missing on some ancient Windows versions. With the Qt
version we actually draw the stars so this has become obsolete.

Suggested-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-10-07 09:39:25 -07:00
Dirk Hohndel
475e058d40 Make Windows cross compile again
But this is broken as the utf8/utf16 conversions in windows.c are gone
without glib.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-10-06 21:04:25 -07:00
Dirk Hohndel
34db6dc2be Delete code and files that are no longer used
Most of this is Gtk related, some of it is helpers that we don't need
anymore. I love the diffstat.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-10-06 17:32:50 -07:00
Henrik Brautaset Aronsen
4d0b6e698a Changes to make the glib-removal-hack branch build on MacOSX
Tested with the Homebrew packaging system

Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-10-06 10:42:32 -07:00
Dirk Hohndel
a7ceb695f5 Fix Windows compile
When submitting commit 8f33b81de0f9 ("implement device probe in C"),
Danilo explicitly asked me to make sure this compiles / works on Windows
and Mac - and I promptly forgot to do so. Robert fixed the Mac build, this
now at least compiles under Windows (but it's still untested).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-09-17 07:58:29 -04:00
Danilo Cesar Lemes de Paula
a8d33f80b0 implement device probe in C
It's an attempt to build auto-completion for the dive-computers
based on unpublished code inside libdivecomputer[1]

[1] -
http://git.libdivecomputer.org/?p=libdivecomputer.git;a=commitdiff;h=d44053a99435fb9fc1f408fb3f1629a54c938afc

Signed-off-by: Danilo Cesar Lemes de Paula <danilo.eu@gmail.com>
2013-09-16 22:40:47 -03:00
Dirk Hohndel
060e5c764c Matching build fixes for cross built Windows
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-05-03 13:34:55 -07:00
Henrik Brautaset Aronsen
f2ab8f42ee Match subsurface_get_conf* in windows/macos.c with linux.c
The signatures for subsurface_get_conf* in windows.c and macos.c
was slightly different from those in linux.c, which broke the
build (at least on Mac).

Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-04-01 10:01:01 -07:00
Alberto Mardegan
578d633d01 Have some C++ file in the project
Rename gtk-gui.c to qt-gui.cpp, and make the necessary changes so that
the project still builds.

Signed-off-by: Alberto Mardegan <mardy@users.sourceforge.net>
2013-04-01 16:03:59 +03:00
Lubomir I. Ivanov
30e10183ca windows.c: Use a zeroed buffer when retrieving the module path
There is a small API note on GetModuleFileName(), which says:
"Windows XP: The string is truncated to nSize characters
and is not null-terminated."

Which means that on XP it will be only safe if we pass a zeroed
buffer to it, otherwise the next call to wcsrchr (which is
a strchr for wchar_t) may not find a relative terminating \0 in
the buffer, returning a wrong pointer and resulting in a corrupted
string.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-03-05 12:27:32 -08:00
Lubomir I. Ivanov
4cd222eae7 windows.c: Change the current process path to the module path
When an executable is started on Windows, it has a "Working
directory". This directory for a program shortcut stored on the
Desktop can be different than the actual executable directory.
This also applies if a shell extension is registered to that
executable (in the case of Subsurface that could be a .DLD file).

When another process simply "executes" a file with a certain extension
(e.g. when you double click on a .DLD file), a method ShellExecute
is called, which without explicit parameters sets the "Working
directory" to the .DLD file directory. This can be a bit of a trouble
if the executed module depends on relative paths (e.g. ./xslt, ./share).

To solve that we obtain our module full path and filename using
GetModuleFileName(), strip the filename from it (e.g. subsurface.exe)
and then pass the resulted string to SetCurrentDirectory(), which
updates the "Working directory".

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-03-05 12:04:26 -08:00
Lubomir I. Ivanov
3443abea72 windows.c: Fix broken subsurface_unset_conf()
windows.c has be revisited so many times, yet just now I've noticed
that we aren't deleting/unsetting a configuration value ever.
What has went strangely unnoticed is that subsurface_unset_conf()
needs RegDeleteValue instead of RegDeleteKey. "keys" in the Windows
registry are like folders which contain files (or "values").
So in this case we need to delete a "file" and not a "folder" using
RegDeleteValue().

This ended up  being a problem with the new prefs.c logic, where there
is a check if a config value is the default value and then it will be
unset/deleted.

There was potential for a crash, where a NULL value can reach
pango_font_description_from_string() for the divelist font.
It also wasn't possible to change the divelist font back to the default font
(e.g. Sans 8), once a different font was selected.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-03-02 08:45:42 -08:00
Lubomir I. Ivanov
c3b3ab9af7 windows.c: use ANSI for subsurface_unset_conf()
We may not write config variables with UTF-8 characters so the wchar_t
conversation in subsurface_unset_conf() is not needed.

This patch also attempts to improve subsurface_get_conf_bool()
and subsurface_get_conf_int() or better consitentcy with the other OS
files. For both functions return -1 if config key is not found.
Previouosly there was a check for that in  function get_from_registry().

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-03-01 08:01:31 -08:00
Lubomir I. Ivanov
0fc089c669 windows.c: Added support for "int" configuration storage
This patch addes body to the functions subsurface_get_conf_int()
and subsurface_set_conf_int().

It also makes some small changes:
- subsurface_get_conf_bool() now uses subsurface_get_conf_int()
- for retrieving DWORDS we would only need RegQueryValueEx,
thus the wchar_t conversations aren't really needed, unless
we start storing integers in keys with UTF-8 characters in the name.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-02-28 19:56:37 -08:00
Amit Chaudhuri
d742d7b391 Remember window size
This commit has gone through a few iterations and I trimmed it down to
what I consider the "conservative minimum" - so this only stores window
size, not window position. And in my mind that's the more relevant part,
anyway. Have your window manager position the window at a "smart" spot on
your screen...

Signed-off-by: Amit Chaudhuri <amit.k.chaudhuri@gmail.com>
Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-02-28 15:36:27 -08:00
Lubomir I. Ivanov
2af818bf91 Fixed some memory leaks in windows.c and main.c
windows.c:subsurface_gettext_domainpath():
- memory at pointer returned from g_win32_getlocale() should be released

main.c:setup_system_prefs()
- it seems all calls to <os_file>:system_default_filename()
return a pre-allocated buffer, therefore we don't need to call strdup()
on the result itself.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-02-09 11:38:51 -08:00
Dirk Hohndel
e3a8ed5183 Massive cleanup
Mostly coding style and whitespace changes plus making lots of functions
static that have no need to be extern. This also helped find a bit of code
that is actually no longer used.

This should have absolutely no functional impact - all changes should be
purely cosmetic. But it removes a bunch of lines of code and makes the
rest easier to read.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-30 08:31:53 +11:00
Dirk Hohndel
3f261f56f3 Remove some unnecessary variable initializations
Not really bugs, just wasted. They clutter up the output of static
analysis with cppcheck.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-25 16:28:37 -08:00
Lubomir I. Ivanov
ff5a8b0650 windows.c: Add unicode support in subsurface_launch_for_uri()
subsurface_launch_for_uri() requires unicode support, using
ShellExecuteW() and also the passed UTF-8 buffer has to be translated
to UTF-16 beforehand. Once the ShellExecuteW() is done we release
the UTF-16 allocation.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-25 07:29:26 -08:00
Lubomir I. Ivanov
678fffdcf4 Added the OS dependent function subsurface_launch_for_uri()
Opening URI addresses from Subsurface does not work on Windows using
the latest GTK bundle from the Gnome website. The reason lies in GIO
and GLib and how it obtains assigned applications for protocols and MIME
types.

While gtk_show_uri() should be viable for both linux.c and macos.c,
in windows.c ShellExecute() is used, which provides proper support
for the URI calls.

subsurface_launch_for_uri() returns TRUE on success.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 08:51:32 -08:00
Linus Torvalds
6a10700ca5 Add default filename and divelist font to prefs structure
.. and add the usual logic to not save the default values.

This also simplifies the initial system-specific setup of both of these:
since we have defaults for all the preferences that get set up at
startup, we can just initialize those defaults to the system-specific
fonts then and there.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-11 17:46:00 -08:00
Dirk Hohndel
6c0289daa0 Fix Windows build
Just making the code in the last commit (cross) compile on Windows.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-10 20:40:04 -08:00
Linus Torvalds
8dea49ffe2 Clean up preference saving code
The old code (on purpose) didn't try to differentiate "nonexisting
boolean configuration" with "existing boolean configuration set to
false", which is problematic if we optimize the saving to not save
default preferences at all.

Which this does.

So in addition to the logic to know about default preferences, this has
to change the interfaces for the PREF_BOOL reading code so that you can
tell the difference between "no value" and "false".

And since the previous calling convention was an abomination of doing
pointer casting and having case-statements for the config types, change
that while at it.  Both from a usage perspective *and* from a back-end
perspective it is actually much simpler to just have different functions
for the string vs boolean config read/write versions.  The OSX versions
in particular end up being one-liners.

(The GConf library is a nightmare, and doesn't seem to have any way to
know whether a boolean value exists or not, so you have to read it as a
GConfVal and then turn it into a gboolean rather than just get the "oh,
it didn't exist" as an error value).

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-10 20:30:54 -08:00
Linus Torvalds
868a2cc090 Split up preference data structure definition into 'pref.h'
.. and rename the badly named 'output_units/input_units' variables.

We used to have this confusing thing where we had two different units
(input vs output) that *look* like they are mirror images, but in fact
"output_units" was the user units, and "input_units" are the XML parsing
units.

So this renames them to be clearer.  "output_units" is now just "units"
(it's the units a user would ever see), and "input_units" is now
"xml_parsing_units" and set by the XML file parsers to reflect the units
of the parsed file.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-10 20:30:32 -08:00
Dirk Hohndel
ee5c31d292 Show drive name after the drive letter on Windows
In the device selector when downloading from a divecomputer add the drive
name that we have been looking for (so far that's only "UEMISSDA") to the
drive letter - this should make it easier for people to figure out why
there is a drive letter offered as an option.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-31 16:51:04 -07:00
Lubomir I. Ivanov
ab8af0bdeb windows.c: added device retrieval from subsurface_fill_device_list()
subsurface_fill_device_list() now goes trough the list of registry
entries in the SERIALCOMM key and adds all present values (such as
COM1, COM2) to a GtkListStore. Once done the function compares
all logic drive label to a static list of known DC labels,
such a 'UEMISSDA', which is the only present one at the moment
and adds any matching drive letters (e.g. C:\, H:\) to the list store
as well.

If no serial ports were added or no matching logical drives were found
the function simply adds a default entry named "COM1".

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2012-10-29 13:16:46 -07:00
Dirk Hohndel
2de6f79635 Improve the dive computer device selection
We try to identify devices that are connected and their matching device
names (and mount paths in the case of the Uemis Zurich). Those are
presented as a drop down menu to choose from. The user can still override
this by simply entering a different device / path name.

On Windows this is not functional. How do I find out which drive letter
corresponds to the USB device named "UEMISSDA"? Similarly we need code
that finds serial ports that are present. For now we once again default
to COM3 (so this isn't a step back, but of course it's far from what we
want).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-27 21:12:14 -07:00
Lubomir I. Ivanov
5b3e480be3 Added a function to check if specific OS features are available
linux.c, macos.c, windows.c now contain
subsurface_os_feature_available() that can accept an enum type
os_feature_t defined in dive.h.

The function can be useful to check if a specific global feature
is available on a certain OS version.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-19 21:14:00 -07:00
Dirk Hohndel
834825f406 Find translation files on Linux after Subsurface was installed
So far we only looked in the a local subdirectory, but once Subsurface has
been installed, we don't need to change the search path for translation
files anymore.

Fixes #2

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-18 14:30:45 -07:00
Dirk Hohndel
a9f3655d1a Improved packaging for Windows
This commit adds an install-cross-windows target to the Makefile that
creates a staging directory for us under packaging/windows that contains
the required .mo files. This currently fails for the Norwegian translation
because of the no_NO.UTF-8 vs nb issue - right now we just use the first
component of our own localization filename to find the matching Windows
localization and that fails.

The subsurface.nsi file is updated accordingly and this now appears to
create working installers with sane paths for the localization files.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-16 04:08:33 -07:00
Dirk Hohndel
f97f75f961 Set locale under Windows
This is mostly a quick hack to be able to test localization under Windows.
It seems to work fine under Windows 7

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-15 16:32:11 -07:00
Henrik Brautaset Aronsen
ef039c9d32 Support for gettext in MacOSX application bundle
The MacOSX applications bundle needs to be told where to bind the
text domain from.

Also copy the gettext .mo files in the install-macosx target.

[Dirk Hohndel: minor change in main(): move the path declaration to
               the beginning of the function]

Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-15 09:36:30 -07:00
Dirk Hohndel
1a6cf2f128 Fix potential crash when attempting to free default font
Before setting a new font we try to free the existing font. Sadly if no
config value is set for the default font, we assign a string literal.
Which of course means that subsurface dumps core when trying to free it.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-07 20:57:24 +09:00
Lubomir I. Ivanov
3e7780e7cd Added unicode support for the configuration entries on Windows
windows.c:

Windows's registry (which is technically a filesystem) uses UTF-16
for its "keys". This forces us to convert each of our UTF-8 (GLib, GTK)
configuration entries if we want to store special characters. To do that
we use the RegQueryValueExW() and do some conversation around
the function call itself.

The opposite happens when we require a UTF-16 value to be read from the
registry and converted to UTF-8 in subsurface_set_conf().

An addition to this patch is a somehow expandable buffer in
windows.c: subsurface_get_conf(). We increase the size of the buffer
in chunks of 64 bytes, until RegQueryValueExW() is able to write to it
(as suggested by the WINAPI documentation).

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-05 23:44:54 +09:00
Lubomir I. Ivanov
f928be5061 Provide a method to use unicode command line arguments on Windows
For unicode command line characters Windows uses UTF-16, while Glib
and GTK use UTF-8. To solve that we retrieve the command line
via __wgetmainargs() and use g_utf16_to_utf8() to convert each argument.

The used method should support wildcards passed as arguments
(e.g. *.xml).

Two new, OS abstracted functions appear in linux.c (NOP), macos.c (NOP),
windows.c:

subsurface_command_line_init(...)
subsurface_command_line_exit(...)

which are being called in main()

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-10-04 03:12:19 -07:00
Dirk Hohndel
7148dea827 Once again improve existing filename handling
Several potential problems.
- we could end up dereferencing exiting_filename when it was NULL
- we could free the default_filename by mistake -
  subsurface_default_filename always needs to return a copy of it
- closing the existing file before opening a new one repopulated the
  existing_filename with the default filename - preventing the opened
  file to become the new existing filename

Also, make existing filename a const char * and make file_open have the
same sensible default folder behavior as the other file related functions.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-09-17 21:03:30 -04:00
Dirk Hohndel
b73f29fea3 First cut of adding a default file name
The default file name is OS specific and tries to follow the customs on
each of the OSs. It can be configured through the preferences dialog.

On MacOS we get a strange warning which appears to be a well documented
Gtk bug on MacOS.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-09-09 17:38:01 -07:00
Lubomir I. Ivanov
cf475114f6 set subsurface_flush_conf() to no-op in wondows.c
flushing the entire registry is not required on windows. simply
closing the registry key when done would suffice.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-05-05 10:00:10 -07:00
Linus Torvalds
725e4582d9 Don't close config file when changing preferences
On Linux and MacOS the subsurface_close_conf() doesn't really close the
config file (it flushes writes on MacOS), but on Windows it does
actually close the registry hkey.

Which is bad, if you change the settings multiple times - we assume that
the config file is open the whole time.

So add a "subsurface_flush_conf()" function, and call *that* when
changing configuration parameters.  And call the close function only at
the very end.

Alternatively, maybe we should just open the config file separately
every time. I don't much care, maybe somebody else does.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-05-02 10:03:48 -07:00
Dirk Hohndel
513df18f50 Even more Mac-i-ness
Move the About and Preferences menu item to the App menu.
Switch the accelerator key to be Meta (i.e., Command) instead of Control

This required a bit of restructuring of the code, but it's all for a good
cause.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-01-03 07:25:35 -08:00
Dirk Hohndel
605e063203 Turn subsurface into a real Mac application
To do this a few things needed to move into the os specific files, but the
overall change is fairly small and the difference on the Mac is amazing.

Subsurface now becomes a Mac app with Mac toolbar and useful default
fonts.

Changed the CFBundleIdentifier to be the reverse DNS of the subsurface
site (sadly, 'torvalds' is not yet a TLD).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2012-01-01 14:01:38 -08:00
Dirk Hohndel
565736a471 Make icon file name OS helper function
This way we can load the correct icon on the Mac without ugly hacks in the
OS independent code.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2011-12-28 15:57:36 -08:00
Dirk Hohndel
0a9e5aa735 Return is not a function
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2011-12-14 20:53:25 -08:00
Dirk Hohndel
4b77a5def6 Add reasonable default device names for divecomputer import
So far we hard coded /dev/ttyUSB0 - which is a good starting point in
Linux but not so useful on Windows or MacOS. This was now moved into one
of our OS helper functions with (somewhat) reasonable defaults.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2011-12-13 20:34:56 -08:00
Dirk Hohndel
192713680e Add more typecasts for Windows`
This is based on an older patch by Lubomir I. Ivanov <neolit123@gmail.com>
which no longer applies due to the refactoring of the registry setting
code.

It takes care of all of the casts between actual C types and the Windows
specific types that the Windows API functions expect. It also adds some
comments to the overloading of "value" in our subsurface_set_conf function.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2011-11-25 20:19:58 -08:00
Dirk Hohndel
d2654d4951 Fix the Windows preferences support
Now that I can test Windows binaries again, the bugs were rather easy to
spot. Because of the different flow of the opening, writing and closing of
the registry key my first attempt got things wrong - we simply always
create the key with all access rights; if it exists Windows will just open
it for us. The second bug was a cut'n'paste error.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2011-11-25 19:48:53 -08:00