While we are waiting for an autotools generated Makefile, this should allow
people to build that don't have osm-gps-map.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In order to be able to work with Gtk3 introspection all the APIs had to be
renamed. Instead of quartz_application... and gtk_osxapplication... all the API
functions are now name gtkosx_application...
This will break the build for people who haven't upgraded to the latest - but
supporting both would be unspeakably ugly.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The planner interactively responds to changes to the GFlow and GFhigh in
the dialog and calculates an appropriate profile. If there is a previous
dive within the 48 hours prior to this dive then its saturation is
correctly taken into account if the gradient factors are changed - so if
they are aggressively lowered it is possible to start the dive with
already an existing ceiling (simply increase the surface interval to 'fix'
that).
Once the plan is accepted the GF values are reset to the current
preferences. This can cause the ceiling in the plot to change and the deco
stops to no longer match the ceiling - but that's a logical consequence of
the ability to change a temporary copy of GFlow/GFhigh during the planning
process and not the actual preferences (which would be counter intuitive,
I think).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Commit 293126257b20 ("Mark divelist as changed if user accepts planned
dive") had the correct commit message but an incorrect implementation.
This moves the mark_divelist_changed() call into the GTK_RESPONSE_ACCEPT
clause where it belongs.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The previous flag didn't work on Windows somehow. I guess Photoshop
added some headers that GdkPixbuf didn't like. I've reconverted it
with ImageMagick, which made the file less than half the size. Bonus!
Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This adds the "Show in map" menu entry to the divelist only if we
actually have a location to show.
Of course, having some way to visually see whether we have a GPS
location even before we show the menu would probably be good. Maybe a
marker in the "location" string or something. But in the meanwhile, at
least we don't have that menu entry if we have nothing to show.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This adds a "Show in map" entry in the dive list context menu. It will
zoom to the dive location if it exists, otherwise the full map will be
displayed.
I've also switched map tiles from OpenStreetMap to Google Maps just to
show off that we can.
Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If there's no weightsystem description, as in most imported
dives, print a literal "unknown" instead of null pointer
or blank.
Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When the user clicks OK in the dive planner and the dive is added to the
divelist the divelist needs to be marked as changed so Subsurface prompts
the user to save the file before quitting.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This works on the assumption that the diver uses the deco SAC rate while
on a calculated deco stop and the bottom SAC rate during the rest of the
dive (including the time they move from deco stop to deco stop).
This is making the planning function mostly useful for open circuit
diving.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This makes it easy to print out a dive plan - it's simply stored in the
notes of the simulated dive we create.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This just provides the infrastructure to enter the data, nothing is
calculated, yet.
This adds a new get_thousandths() helper function so we can enter
information of the 'mili-' type as decimal values. So things like
"14.5 l/min" or "0.75 cuft/min" are parsed correctly and converted
into a ml value.
In the process of implementing that I also fixed a bug introduced in
commit ab7aecf16e ("Simplify dive planning code") which broke the
get_tenth() function.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This patch removes the need for the "string" pressurebuf in planner.c.
It also adds a unit to the partial pressures displayed in the mouse
overlay which are always displayed in bar.
BTW: Has anyone seen a pO2 shown in PSI?
Signed-off-by: Jan Schubert <Jan.Schubert@GMX.li>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Subsurface follows the lead of most divecomputers to use times without
timezone - so all times are implicitly assumed to be local time of the
dive location; so in order to give the current time in that way we
actually need to add the timezone offset.
Instead of relying on OS specific members of struct tm we use the glib
timezone functions to get the timezone offset for us. Of course, the
function used to do this is only in glib 2.26 or newer, which once again
means that Debian stable won't be supported. But since that doesn't build
other parts of Subsurface, either, I think I'll live with that.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The previous patch in this series adds the function
subsurface_launch_for_uri(), which has to be called from the about
dialog instead of the default function for the URI calls to work
on Windows - i.e. opening links from the dialog.
gtk_about_dialog_set_url_hook() is a deprecated method, but seems
to be the only reasonable way to make the override between GTK 2.20 -
2.24 possible. The "activate-link" signal is recomended instead,
but is not portable for GTK bellow 2.24.
An alternative would be to somehow hack into the GtkAboutDialog
and override the callback for each clickable link.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
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>
display-gtk.h has a check if gdkkeysyms-compat.h or gdkkeysyms.h
has to be used. In gps.c, from such as "GDK_Up" has to be used,
so that this file compiles on older GTK.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This patch centralizes the definition for surface pressure, oxygen in
air, (re)defines all such values as plain integers and adapts calculations.
It eliminates 11 (!) occurrences of definitions for surface pressure and
also a few for oxygen in air.
It also rewrites the calculation for EAD, END and EADD using the new
definitons, harmonizing it for OC and CC and fixes a bug for EADD OC
calculation.
And finally it removes the unneeded variable entry_ead in gtk-gui.c.
Jan
Signed-off-by: Jan Schubert <Jan.Schubert@GMX.li>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Previously we calculate the ceiling at every single second, using the
interpolated depth but then only *save* the ceiling at the points where we
have a profile event (the whole deco_allowed_depth() function doesn't
change any state, so we can just drop it entirely at points that we aren't
going to save)
Why is it incorrect? I'll try to walk through my understanding of it, by
switching things around a bit.
- the whole "minimum tissue tolerance" thing could equally well be
rewritten to be about "maximum ceiling". And that's easier to think
about (since it's what we actually show), so let's do that.
- so turning "min_pressure" into "max_ceiling", doing the whole
comparison inside the loop means is that we are calculating the
maximum ceiling value for the duration of the last sample. And then
instead of visualizing the ceiling AT THE TIME OF MAXIMUM CEILING, we
visualize that maximal ceiling value AT THE TIME OF THE SAMPLE.
End result: we visualize the ceiling at the wrong time. We visualize
what was *a* ceiling somewhere in between that sample and the previous
one, but we then assign that value to the time of the sample itself.
So it ends up having random odd effects.
And that also explains why you only see the effect during the ascent.
During the descent, the max ceiling will be at the end of our
linearization of the sampling, which is - surprise surprise - the position
of the sample itself. So we end up seeing the right ceiling at the right
time while descending. So the visualization matches the math.
But during desaturation, the maximum ceiling is not at the end of the
sample period, it's at the beginning. So the whole "max ceiling" thing has
basically turned what should be a smooth graph into something that
approaches being a step-wise graph at each sample. Ergo: a ripple.
And doing the "max_ceiling during the sample interval" thing may sound
like the safe thing to do, but the thing is, that really *is* a false
sense of safety. The ceiling value is *not* what we compute. The ceiling
value is just a visualization of what we computed. Playing games with it
can only make the visualization of the real data worse, not better.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Previously we would simply show the first dive in the divelist - which
worked fine in the default sort by trip setting and assuming that there
are no dives from the future in the divelist.
With this commit we actually find the correct dive in the divelist and
select it instead. If you sort by depth you will see the dive move around
in the divelist, but it will stay selected and visible in the profile.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The loop would actually get entered for dive 0 and try to compare things
with dive -1. Which of course fails.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Previously the code in init_decompression() would mindlessly walk back the
dive_table until it found a gap of at least 48h and take all those dives
into consideration when calculating tissue saturation. This goes horribly
wrong if you load dives from two divers into the same data file.
With this commit things will still turn out correctly, as long as the
dives are in separate trips in for each of the divers. So with this I can
load both Linus' and my divelog and things stay sane even on our shared
dive trips.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
- MOD: Maximum Operation Depth based on a configurable limit
- EAD: Equivalent Air Depth considering N2 and (!) O2 narcotic
- END: Equivalent Nitrogen (Narcotic) Depth considering just N2 narcotic
(ignoring O2)
- EADD: Equivalent Air Density Depth
Please note that some people and even diving organisations have opposite
definitions for EAD and END. Considering A stands for Air, lets choose the
above. And considering N for Nitrogen it also fits in this scheme.
This patch moves N2_IN_AIR from deco.c to dive.h as this is already used
in several places and might be useful for future use also. It also
respecifies N2_IN_AIR to a more correct value of 78,084%, the former one
also included all other gases than oxygen appearing in air. If someone
needs to use the former value it would be more correct to use 1-O2_IN_AIR
instead.
Signed-off-by: Jan Schubert / Jan.Schubert@GMX.li
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The max Y value of the partial pressure graph grid tends to be way too
high when only pO2 or pHe is enabled.
Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
With Pierre-Yves' commit with a map widget, here are a couple of example
GPS locations from my own dives.
Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
For each dive recorded, place their GPS coordinates onto a map using the
OSM-GPS-MAP library.
This map is accessible via the "log" menu or the shortcut ctrl+M (M as map).
We check for the GPS coordinates "0, 0" which are the default when we do not
have real GPS coordinates set.
[Dirk Hohndel: fixed int/float math confusion, fixed some whitespace and
coding style issues, cleaned up some comments, added a
missing cast to prevent a compiler warning]
Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>
Signed-Off-By: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
.. 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>
Testing the new "don't even bother saving default values" showed that the
default values for the deco gradient factors were undefined.
Or rather, they were over-defined.
We had defaults for the UI (30 and 75 for GFlow/GFhigh respectively - the
config ones are in percent), *and* we had defaults in deco.c for the deco
code itself (0.35 and 0.75 respectively - in deco.c they are represented
as fractions, not percent).
And if the config entries had never been written, and were assumed to be
the defaults, the UI code thought the defaults were 30/75, but they had
never been *set* to those defaults, so actual default calculations
silently used the 35/75 in deco.c, which is very confusing (you could go
to the preferences page, see the 30/75 there, and it would not actually
match th evalues used for computation).
Of course, with an old config file that saves even default entries, you'd
never see that if you ever changed anything in the preferences, because
you'd always have explicit gflow/high values. But now it's much easier to
see the conflicting default values.
Fix it by just always using the UI defaults (or set values) to set the
actual deco values.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Loading an xml file with dive computer information without any
preexisting nickname data would try to "remember" that NULL nickname.
Causing a SIGSEGV if there was no nickname information.
The bug was introduced by commit ec38d3708d ("Move device_info handling
into a new 'device.c' file") when I inadvertently removed a bit too much
code. It actually wants to remember a missing DC nickname as an empty one.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This does the "don't save defaults" for numeric values too.
Also, move the preferences loading/saving to a new "prefs.c" file.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
A new file download-dialog.c now contains all code related
to the download dialog, which was previously defined in gtk-gui.c.
Also, a new file callbacks-gtk.h now has two macros
OPTIONCALLBACK, UNITCALLBACK shared only between
download-dialog.c and gtk-gui.c.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
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>
This makes it explicit what the default preferences are, so that we can
more easily avoid unnecessarily saving default settings. It also makes
imperial metrics the default for the US (Burma and Liberia always get
forgotten!)
Right now we tend to be somewhat confused about defaults. We do have
them, but then even if something has a default value, we tend to write
it out to the config file. Which is not just unnecessary, but makes it
really hard to see after-the-fact whether the user actually wanted that
*specific* value, or whether they just wanted the default behavior.
So this prepares for having explicit configuration for when we want
something different than the defaults.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
.. 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>
This moves the point where GF_low applies up which implies that at all
shallower depth (i.e. during deco) a lower GF results which makes the deco
longer compared to the previous implementation.
Of course, "GF_low" applies at first deco stop is a bit tricky since the
depth of the first deco stop again depends on GF_low, i.e. there is
another equation to solve. You can do this by inverting the equation for
the ambient pressure and use GF_low as the gradient factor. This yields
amb = (b * M_value_corrected - GF_low * a * b) / ((1-b) * GF_low + b)
Signed-off-by: Robert C. Helling helling@atdotde.de
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
It turns out that the serial number returned by libdivecomputer isn't
really the serial number as interpreted by the vendor. Those tend to be
strings, but libdivecomputer gives us a 32bit number.
Some experimenting showed that for the Suunto devies tested the serial
number is encoded in that 32bit number:
It so happens that the Suunto serial number strings are strings that have
all numbers, but they aren't *one* number. They are four bytes
representing two numbers each, and the "23500027" string is actually the
four bytes 23 50 00 27 (0x17 0x32 0x00 0x1b). And libdivecomputer has
incorrectly parsed those four bytes as one number, not as the encoded
serial number string it is. So the value 389152795 is actually hex
0x1732001b, which is 0x17 0x32 0x00 0x1b, which is - 23 50 00 27.
This should be done by libdivecomputer, but hey, in the meantime this at
least shows the concept. And helps test the XML save/restore code.
It depends on the two patches that create the whole "device.c"
infrastructure, of course. With this, my dive file ends up having the
settings section look like this:
<divecomputerid model='Suunto Vyper Air' deviceid='d4629110'
serial='01201094' firmware='1.1.22'/>
<divecomputerid model='Suunto HelO2' deviceid='995dd566'
serial='23500027' firmware='1.0.4'/>
where the format of the firmware version is something I guessed at,
but it was the obvious choice (again, it's byte-based, I'm ignoring
the high byte that is zero for both of my Suuntos).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The legacy nickname wrappers (that use the device_info structure) are
left in gtk-gui.c. We can slowly start moving away from them, we don't
want to start exporting that thing as some kind of generic interface.
This isn't a pure code movement - because we leave the legacy interfaces
alone, there are a few new interfaces in device.c (like "create a new
device_info entry") that were embedded into the legacy "create nickname"
code, and needed to be abstracted out.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We'll start recording more than just nicknames in it, like serial
numbers and firmware version etc. Start off just renaming it, and
re-ordering the members to reflect how the nickname is not the primary
issue.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We have several places where we interpolate the depth based on two
samples and the time between them. Some of them use floating point, some
of them don't, some of them meant to do it but didn't.
Just use a common helper function for it. I seriously doubt the floating
point here really matters, since doing it in integers is not going to
overflow unless we're interpolating between two samples that are hours
apart at hundreds of meters of depth, but hey, it gives that rounding to
the nearest millimeter. Which I'm sure matters.
Anyway, we can probably just get rid of the rounding and the floating
point math, but it won't really hurt either, so at least do it
consistently.
The interpolation could be for other things than just depth, but we
probably don't have anything else we'd want to interpolate. But make the
function naming generic just in case.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This change ended up being quite a bit bigger than expected as it
uncovered a number of bugs in the existing code.
The planner now handles gas changes correctly by creating (and later
parsing) events in the simulated divecomputer. At the end of the dive
specified in the input form the algorithm starts with the deepest
interesting depth: either the first stop below our ceiling or the deepest
depth at which we can change gases. It then traverses all the stop and all
the gas change depth and at each stage ensures that we are allowed to
ascend further before going on.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
An entry with no time is considered special and not considered when
constructing the profile.
This should allow us to add support for two different ways of adding
information about available gas:
changedepth 0 gasmix
0 0 gasmix @ po2
The first syntax basically says "during the ascent, switch to this gas at
this depth.
The second one says "switch to this gas once the pO2 allows for it"
Neither of these are implemented, yet, but this commit is necessary in
order for the rest of the code to ignore entries with a time field of 0.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In commit d163a68ac69e "Clean up the rewritten deco.c" I apparently made
one more change than I intended - I changed the last deco stop back to 3m
instead of allowing the smooth mode to go all the way back to 0 without
any discrete steps.
This fixes that mistake.
Reported-by: Robert C. Helling <helling@lmu.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit makes sure we have a reasonable default surface pressure (we
need an input field for that).
It also adjusts the debug level settings so that compiling this with
make CLCFLAGS=-DDEBUG_PLAN=3
will print out an almost usable dive plan.
This is of course still lacking air consumption calculations and will show
deco stops that we just transit through (if the ceiling lifts far enough
during the transition to an intended stop that this stop can be skipped;
this sometimes happens for the first stop (haven't seen it for a later
one). But it's better than nothing, I guess.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We may want to make this configurable, but I haven't seen any software
that doesn't do deco stops in full minutes.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The existing code incorrectly started all calculation at the depth at the
end of the first segment. So if you went to 50m in 5min in your first
segment, you incorrectly got 5 minutes at 50m (instead of a progression
from 0 to 50m, over 5 minutes).
This commit fixes that and now gives us planned dives that then match what
is shown in the profile.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This shouldn't change the the actual stops we do or the travel time how we
get there, but it makes the code more logical. From the end depth of the
planned dive we have ONE transition to the first stop depth (which may be
the surface). And then for every stop we (potentially) have a wait and
travel to the next stop.
Once we are in the while loop, we know that we are at a stop level, so
there is no point to keep checking if we first need to transition to the
stop.
It does create one additional improvement: if we don't need any stops at
all, then we don't transition to the first stop and then from there to the
surface. We do it in one step. The overall profile / traveltime remains
the same, we just drop one intermediate sample on the way.
This also improves a few ugly (and in one case, wrong) debug statements.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>