]> git.tdb.fi Git - ext/subsurface.git/blob - libdivecomputer.c
Flesh out the libdivecomputer interfaces some more
[ext/subsurface.git] / libdivecomputer.c
1 #include <stdio.h>
2 #include <gtk/gtk.h>
3
4 #include "dive.h"
5 #include "display.h"
6
7 /* libdivecomputer */
8 #include <device.h>
9 #include <suunto.h>
10 #include <reefnet.h>
11 #include <uwatec.h>
12 #include <oceanic.h>
13 #include <mares.h>
14 #include <hw.h>
15 #include <cressi.h>
16 #include <zeagle.h>
17 #include <atomics.h>
18 #include <utils.h>
19
20 static device_status_t device_open(const char *devname,
21         device_type_t type,
22         device_t **device)
23 {
24         switch (type) {
25         case DEVICE_TYPE_SUUNTO_SOLUTION:
26                 return suunto_solution_device_open(device, devname);
27
28         case DEVICE_TYPE_SUUNTO_EON:
29                 return suunto_eon_device_open(device, devname);
30
31         case DEVICE_TYPE_SUUNTO_VYPER:
32                 return suunto_vyper_device_open(device, devname);
33
34         case DEVICE_TYPE_SUUNTO_VYPER2:
35                 return suunto_vyper2_device_open(device, devname);
36
37         case DEVICE_TYPE_SUUNTO_D9:
38                 return suunto_d9_device_open(device, devname);
39
40         case DEVICE_TYPE_UWATEC_ALADIN:
41                 return uwatec_aladin_device_open(device, devname);
42
43         case DEVICE_TYPE_UWATEC_MEMOMOUSE:
44                 return uwatec_memomouse_device_open(device, devname);
45
46         case DEVICE_TYPE_UWATEC_SMART:
47                 return uwatec_smart_device_open(device);
48
49         case DEVICE_TYPE_REEFNET_SENSUS:
50                 return reefnet_sensus_device_open(device, devname);
51
52         case DEVICE_TYPE_REEFNET_SENSUSPRO:
53                 return reefnet_sensuspro_device_open(device, devname);
54
55         case DEVICE_TYPE_REEFNET_SENSUSULTRA:
56                 return reefnet_sensusultra_device_open(device, devname);
57
58         case DEVICE_TYPE_OCEANIC_VTPRO:
59                 return oceanic_vtpro_device_open(device, devname);
60
61         case DEVICE_TYPE_OCEANIC_VEO250:
62                 return oceanic_veo250_device_open(device, devname);
63
64         case DEVICE_TYPE_OCEANIC_ATOM2:
65                 return oceanic_atom2_device_open(device, devname);
66
67         case DEVICE_TYPE_MARES_NEMO:
68                 return mares_nemo_device_open(device, devname);
69
70         case DEVICE_TYPE_MARES_PUCK:
71                 return mares_puck_device_open(device, devname);
72
73         case DEVICE_TYPE_MARES_ICONHD:
74                 return mares_iconhd_device_open(device, devname);
75
76         case DEVICE_TYPE_HW_OSTC:
77                 return hw_ostc_device_open(device, devname);
78
79         case DEVICE_TYPE_CRESSI_EDY:
80                 return cressi_edy_device_open(device, devname);
81
82         case DEVICE_TYPE_ZEAGLE_N2ITION3:
83                 return zeagle_n2ition3_device_open(device, devname);
84
85         case DEVICE_TYPE_ATOMICS_COBALT:
86                 return atomics_cobalt_device_open(device);
87
88         default:
89                 return DEVICE_STATUS_ERROR;
90         }
91 }
92
93 static void error(const char *fmt, ...)
94 {
95         va_list args;
96         GError *error;
97
98         va_start(args, fmt);
99         error = g_error_new_valist(
100                 g_quark_from_string("divelog"),
101                 DIVE_ERROR_PARSE, fmt, args);
102         va_end(args);
103         report_error(error);
104         g_error_free(error);
105 }
106
107 static void
108 event_cb (device_t *device, device_event_t event, const void *data, void *userdata)
109 {
110 }
111
112 static int
113 cancel_cb (void *userdata)
114 {
115         return 0;
116 }
117
118 static void do_import(const char *computer, device_type_t type)
119 {
120         /* FIXME! Needs user input! */
121         const char *devname = "/dev/ttyUSB0";
122         device_t *device = NULL;
123         device_status_t rc;
124
125         rc = device_open(devname, type, &device);
126         if (rc != DEVICE_STATUS_SUCCESS) {
127                 error("Unable to open %s (%s)", computer, devname);
128                 return;
129         }
130
131         // Register the event handler.
132         int events = DEVICE_EVENT_WAITING | DEVICE_EVENT_PROGRESS | DEVICE_EVENT_DEVINFO | DEVICE_EVENT_CLOCK;
133         rc = device_set_events(device, events, event_cb, NULL);
134         if (rc != DEVICE_STATUS_SUCCESS) {
135                 error("Error registering the event handler.");
136                 device_close(device);
137                 return;
138         }
139
140         // Register the cancellation handler.
141         rc = device_set_cancel(device, cancel_cb, NULL);
142         if (rc != DEVICE_STATUS_SUCCESS) {
143                 error("Error registering the cancellation handler.");
144                 device_close(device);
145                 return;
146         }
147
148         error("No actual code yet for importing (%s: %s)", computer, devname);
149 }
150
151 /*
152  * Taken from 'example.c' in libdivecomputer.
153  *
154  * I really wish there was some way to just have
155  * libdivecomputer tell us what devices it supports,
156  * rather than have the application have to know..
157  */
158 struct device_list {
159         const char *name;
160         device_type_t type;
161 } device_list[] = {
162         { "Suunto Solution",    DEVICE_TYPE_SUUNTO_SOLUTION },
163         { "Suunto Eon",         DEVICE_TYPE_SUUNTO_EON },
164         { "Suunto Vyper",       DEVICE_TYPE_SUUNTO_VYPER },
165         { "Suunto Vyper Air",   DEVICE_TYPE_SUUNTO_VYPER2 },
166         { "Suunto D9",          DEVICE_TYPE_SUUNTO_D9 },
167         { "Uwatec Aladin",      DEVICE_TYPE_UWATEC_ALADIN },
168         { "Uwatec Memo Mouse",  DEVICE_TYPE_UWATEC_MEMOMOUSE },
169         { "Uwatec Smart",       DEVICE_TYPE_UWATEC_SMART },
170         { "ReefNet Sensus",     DEVICE_TYPE_REEFNET_SENSUS },
171         { "ReefNet Sensus Pro", DEVICE_TYPE_REEFNET_SENSUSPRO },
172         { "ReefNet Sensus Ultra",DEVICE_TYPE_REEFNET_SENSUSULTRA },
173         { "Oceanic VT Pro",     DEVICE_TYPE_OCEANIC_VTPRO },
174         { "Oceanic Veo250",     DEVICE_TYPE_OCEANIC_VEO250 },
175         { "Oceanic Atom 2",     DEVICE_TYPE_OCEANIC_ATOM2 },
176         { "Mares Nemo",         DEVICE_TYPE_MARES_NEMO },
177         { "Mares Puck",         DEVICE_TYPE_MARES_PUCK },
178         { "Mares Icon HD",      DEVICE_TYPE_MARES_ICONHD },
179         { "OSTC",               DEVICE_TYPE_HW_OSTC },
180         { "Cressi Edy",         DEVICE_TYPE_CRESSI_EDY },
181         { "Zeagle N2iTiON 3",   DEVICE_TYPE_ZEAGLE_N2ITION3 },
182         { "Atomics Cobalt",     DEVICE_TYPE_ATOMICS_COBALT },
183         { NULL }
184 };
185
186 static void fill_computer_list(GtkListStore *store)
187 {
188         GtkTreeIter iter;
189         struct device_list *list = device_list;
190
191         for (list = device_list ; list->name ; list++) {
192                 gtk_list_store_append(store, &iter);
193                 gtk_list_store_set(store, &iter,
194                         0, list->name,
195                         1, list->type,
196                         -1);
197         }
198 }
199
200 static GtkComboBox *dive_computer_selector(GtkWidget *dialog)
201 {
202         GtkWidget *hbox, *combo_box;
203         GtkListStore *model;
204         GtkCellRenderer *renderer;
205
206         hbox = gtk_hbox_new(FALSE, 6);
207         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
208
209         model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
210         fill_computer_list(model);
211
212         combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
213         gtk_box_pack_start(GTK_BOX(hbox), combo_box, FALSE, TRUE, 3);
214
215         renderer = gtk_cell_renderer_text_new();
216         gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), renderer, TRUE);
217         gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), renderer, "text", 0, NULL);
218
219         return GTK_COMBO_BOX(combo_box);
220 }
221
222 void import_dialog(GtkWidget *w, gpointer data)
223 {
224         int result;
225         GtkWidget *dialog;
226         GtkComboBox *computer;
227
228         dialog = gtk_dialog_new_with_buttons("Import from dive computer",
229                 GTK_WINDOW(main_window),
230                 GTK_DIALOG_DESTROY_WITH_PARENT,
231                 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
232                 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
233                 NULL);
234
235         computer = dive_computer_selector(dialog);
236
237         gtk_widget_show_all(dialog);
238         result = gtk_dialog_run(GTK_DIALOG(dialog));
239         switch (result) {
240                 int type;
241                 GtkTreeIter iter;
242                 GtkTreeModel *model;
243                 const char *comp;
244         case GTK_RESPONSE_ACCEPT:
245                 if (!gtk_combo_box_get_active_iter(computer, &iter))
246                         break;
247                 model = gtk_combo_box_get_model(computer);
248                 gtk_tree_model_get(model, &iter,
249                         0, &comp,
250                         1, &type,
251                         -1);
252                 do_import(comp, type);
253                 break;
254         default:
255                 break;
256         }
257         gtk_widget_destroy(dialog);
258 }
259