]> err.no Git - mapper/blob - src/utils.h
Merge branch 'master' of git+ssh://tal.org/home/git/mapper
[mapper] / src / utils.h
1 /*
2  * This file is part of maemo-mapper
3  *
4  * Copyright (C) 2006-2007 John Costigan.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #ifndef _MAPPER_UTILS_H
22 #define _MAPPER_UTILS_H
23
24 #define _GNU_SOURCE
25
26 #define _(String) gettext(String)
27
28 #include <config.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <stddef.h>
34 #include <locale.h>
35 #include <math.h>
36 #include <errno.h>
37 #include <sys/wait.h>
38 #include <glib/gstdio.h>
39 #include <gtk/gtk.h>
40 #include <libgnomevfs/gnome-vfs.h>
41 #include <curl/multi.h>
42 #include <gconf/gconf-client.h>
43 #include <libxml/parser.h>
44
45 #include "mapper-types.h"
46
47 /****************************************************************************
48  * BELOW: DEFINES ***********************************************************
49  ****************************************************************************/
50
51 /* #define DEBUG */
52
53 #ifndef DEBUG
54 #define printf(...)
55 #endif
56
57 /* Set the below if to determine whether to get verbose output. */
58 #if 1
59 #define vprintf printf
60 #else
61 #define vprintf(...)
62 #endif
63
64 #define BOUND(x, a, b) { \
65     if((x) < (a)) \
66         (x) = (a); \
67     else if((x) > (b)) \
68         (x) = (b); \
69 }
70
71 #define PI   (3.14159265358979323846f)
72
73 #define MERCATOR_SPAN (-6.28318377773622f)
74 #define MERCATOR_TOP (3.14159188886811f)
75
76 #define SQR(s) ((s)*(s))
77
78 /** MAX_ZOOM defines the largest map zoom level we will download.
79  * (MAX_ZOOM - 1) is the largest map zoom level that the user can zoom to.
80  */
81 #define MAX_ZOOM 16
82
83 #define TILE_SIZE_PIXELS (256)
84 #define TILE_SIZE_P2 (8)
85
86 #ifdef WITH_DEVICE_770
87 #define BUF_WIDTH_TILES (4)
88 #define BUF_HEIGHT_TILES (3)
89 #define BUF_WIDTH_PIXELS (1024)
90 #define BUF_HEIGHT_PIXELS (768)
91 #else
92 #define BUF_WIDTH_TILES (8)
93 #define BUF_HEIGHT_TILES (8)
94 #define BUF_WIDTH_PIXELS (2048)
95 #define BUF_HEIGHT_PIXELS (2048)
96 #endif
97
98 #define ARRAY_CHUNK_SIZE (1024)
99 #define BUFFER_SIZE (2048)
100 #define WORLD_SIZE_UNITS (2 << (MAX_ZOOM + TILE_SIZE_P2))
101
102 #define tile2grid(tile) ((tile) << 3)
103 #define grid2tile(grid) ((grid) >> 3)
104 #define tile2pixel(tile) ((tile) << 8)
105 #define pixel2tile(pixel) ((pixel) >> 8)
106 #define tile2unit(tile) ((tile) << (8 + _zoom))
107 #define unit2tile(unit) ((unit) >> (8 + _zoom))
108 #define tile2zunit(tile, zoom) ((tile) << (8 + zoom))
109 #define unit2ztile(unit, zoom) ((unit) >> (8 + zoom))
110
111 #define grid2pixel(grid) ((grid) << 5)
112 #define pixel2grid(pixel) ((pixel) >> 5)
113 #define grid2unit(grid) ((grid) << (5 + _zoom))
114 #define unit2grid(unit) ((unit) >> (5 + _zoom))
115
116 #define pixel2unit(pixel) ((pixel) << _zoom)
117 #define unit2pixel(pixel) ((pixel) >> _zoom)
118 #define pixel2zunit(pixel, zoom) ((pixel) << (zoom))
119
120 #define unit2bufx(unit) (unit2pixel(unit) - tile2pixel(_base_tilex))
121 #define bufx2unit(x) (pixel2unit(x) + tile2unit(_base_tilex))
122 #define unit2bufy(unit) (unit2pixel(unit) - tile2pixel(_base_tiley))
123 #define bufy2unit(y) (pixel2unit(y) + tile2unit(_base_tiley))
124
125 #define unit2x(unit) (unit2pixel(unit) - tile2pixel(_base_tilex) - _offsetx)
126 #define x2unit(x) (pixel2unit(x + _offsetx) + tile2unit(_base_tilex))
127 #define unit2y(unit) (unit2pixel(unit) - tile2pixel(_base_tiley) - _offsety)
128 #define y2unit(y) (pixel2unit(y + _offsety) + tile2unit(_base_tiley))
129
130 #define leadx2unit() (_pos.unitx + (_lead_ratio) * pixel2unit(_vel_offsetx))
131 #define leady2unit() (_pos.unity + (0.6f*_lead_ratio)*pixel2unit(_vel_offsety))
132
133 /* Pans are done two "grids" at a time, or 64 pixels. */
134 #define PAN_UNITS (grid2unit(2))
135
136 #define INITIAL_DOWNLOAD_RETRIES (3)
137
138 #define MACRO_PARSE_INT(tofill, str) { \
139     gchar *error_check; \
140     (tofill) = strtol((str), &error_check, 10); \
141     if(error_check == (str)) \
142     { \
143         g_printerr("Line %d: Failed to parse string as int: %s\n", __LINE__, str); \
144         MACRO_BANNER_SHOW_INFO(_window, _("Invalid NMEA input from receiver!")); \
145         return; \
146     } \
147 }
148 #define MACRO_PARSE_FLOAT(tofill, str) { \
149     gchar *error_check; \
150     (tofill) = g_ascii_strtod((str), &error_check); \
151     if(error_check == (str)) \
152     { \
153         g_printerr("Failed to parse string as float: %s\n", str); \
154         MACRO_BANNER_SHOW_INFO(_window, _("Invalid NMEA input from receiver!")); \
155         return; \
156     } \
157 }
158
159 #define MACRO_RECALC_CENTER(center_unitx, center_unity) { \
160     switch(_center_mode) \
161     { \
162         case CENTER_LEAD: \
163             center_unitx = leadx2unit(); \
164             center_unity = leady2unit(); \
165             break; \
166         case CENTER_LATLON: \
167             center_unitx = _pos.unitx; \
168             center_unity = _pos.unity; \
169             break; \
170         default: \
171              center_unitx = _center.unitx; \
172              center_unity = _center.unity; \
173             ; \
174     } \
175 };
176
177 #define latlon2unit(lat, lon, unitx, unity) { \
178     gdouble tmp; \
179     unitx = (lon + 180.f) * (WORLD_SIZE_UNITS / 360.f) + 0.5f; \
180     tmp = sinf(lat * (PI / 180.f)); \
181     unity = 0.5f + (WORLD_SIZE_UNITS / MERCATOR_SPAN) \
182         * (logf((1.f + tmp) / (1.f - tmp)) * 0.5f - MERCATOR_TOP); \
183 }
184
185 #define unit2latlon(unitx, unity, lat, lon) { \
186     (lon) = ((unitx) * (360.f / WORLD_SIZE_UNITS)) - 180.f; \
187     (lat) = (360.f * (atanf(expf(((unity) \
188                                   * (MERCATOR_SPAN / WORLD_SIZE_UNITS)) \
189                      + MERCATOR_TOP)))) * (1.f / PI) - 90.f; \
190 }
191
192 #define MACRO_RECALC_OFFSET() { \
193     _offsetx = grid2pixel( \
194             unit2grid(_center.unitx) \
195             - _screen_grids_halfwidth \
196             - tile2grid(_base_tilex)); \
197     _offsety = grid2pixel( \
198             unit2grid(_center.unity) \
199             - _screen_grids_halfheight \
200             - tile2grid(_base_tiley)); \
201 }
202
203 #define MACRO_RECALC_FOCUS_BASE() { \
204     _focus.unitx = x2unit(_screen_width_pixels * _center_ratio / 20); \
205     _focus.unity = y2unit(_screen_height_pixels * _center_ratio / 20); \
206 }
207
208 #define MACRO_RECALC_FOCUS_SIZE() { \
209     _focus_unitwidth = pixel2unit( \
210             (10 - _center_ratio) * _screen_width_pixels / 10); \
211     _focus_unitheight = pixel2unit( \
212             (10 - _center_ratio) * _screen_height_pixels / 10); \
213 }
214
215 #define MACRO_RECALC_CENTER_BOUNDS() { \
216   _min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth)); \
217   _min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight)); \
218   _max_center.unitx = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfwidth) - 1;\
219   _max_center.unity = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfheight)- 1;\
220 }
221
222 #define MACRO_PATH_INIT(path) { \
223     (path).head = (path).tail = g_new(Point, ARRAY_CHUNK_SIZE); \
224     *((path).tail) = _point_null; \
225     (path).cap = (path).head + ARRAY_CHUNK_SIZE; \
226     (path).whead = g_new(WayPoint, ARRAY_CHUNK_SIZE); \
227     (path).wtail = (path).whead - 1; \
228     (path).wcap = (path).whead + ARRAY_CHUNK_SIZE; \
229 }
230
231 #define MACRO_PATH_FREE(path) if((path).head) { \
232     WayPoint *curr; \
233     g_free((path).head); \
234     (path).head = (path).tail = (path).cap = NULL; \
235     for(curr = (path).whead - 1; curr++ != (path).wtail; ) \
236         g_free(curr->desc); \
237     g_free((path).whead); \
238     (path).whead = (path).wtail = (path).wcap = NULL; \
239 }
240
241 #define MACRO_PATH_INCREMENT_TAIL(route) { \
242     if(++(route).tail == (route).cap) \
243         path_resize(&(route), (route).cap - (route).head + ARRAY_CHUNK_SIZE);\
244 }
245
246 #define MACRO_PATH_INCREMENT_WTAIL(route) { \
247     if(++(route).wtail == (route).wcap) \
248         path_wresize(&(route), \
249                 (route).wcap - (route).whead + ARRAY_CHUNK_SIZE); \
250 }
251
252 #define DISTANCE_SQUARED(a, b) \
253    ((guint64)((((gint64)(b).unitx)-(a).unitx)*(((gint64)(b).unitx)-(a).unitx))\
254   + (guint64)((((gint64)(b).unity)-(a).unity)*(((gint64)(b).unity)-(a).unity)))
255
256 #define MACRO_QUEUE_DRAW_AREA() \
257     gtk_widget_queue_draw_area( \
258             _map_widget, \
259             0, 0, \
260             _screen_width_pixels, \
261             _screen_height_pixels)
262
263 /* Render all on-map metadata an annotations, including POI and paths. */
264 #define MACRO_MAP_RENDER_DATA() { \
265     if(_show_poi) \
266         map_render_poi(); \
267     if(_show_tracks > 0) \
268         map_render_paths(); \
269 }
270
271 #ifdef WITH_OSSO
272 #define KEEP_DISPLAY_ON() { \
273     /* Note that the flag means keep on ONLY when fullscreen. */ \
274     if(_always_keep_on || _fullscreen) \
275     { \
276         osso_display_state_on(_osso); \
277         osso_display_blanking_pause(_osso); \
278     } \
279 }
280 #else
281 #define KEEP_DISPLAY_ON()
282 #endif
283
284 #define lat_format(A, B) deg_format(_degformat,(A), (B), 'S', 'N')
285 #define lon_format(A, B) deg_format(_degformat,(A), (B), 'W', 'E')
286
287 #define TRACKS_MASK 0x00000001
288 #define ROUTES_MASK 0x00000002
289
290 #define g_timeout_add(I, F, D) g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, \
291           (I), (F), (D), NULL)
292
293 #define MACRO_CURL_EASY_INIT(C) { \
294     C = curl_easy_init(); \
295     curl_easy_setopt(C, CURLOPT_NOPROGRESS, 1); \
296     curl_easy_setopt(C, CURLOPT_FOLLOWLOCATION, 1); \
297     curl_easy_setopt(C, CURLOPT_FAILONERROR, 1); \
298     curl_easy_setopt(C, CURLOPT_USERAGENT, \
299             "Mozilla/5.0 (X11; U; Linux i686; en-US; " \
300             "rv:1.8.0.4) Gecko/20060701 Firefox/1.5.0.4"); \
301     curl_easy_setopt(C, CURLOPT_TIMEOUT, 30); \
302     curl_easy_setopt(C, CURLOPT_CONNECTTIMEOUT, 10); \
303 }
304
305 #define MACRO_CURL_PROXY(C) { \
306 if (_http_proxy_host) { \
307         curl_easy_setopt(C, CURLOPT_PROXY, _http_proxy_host);\
308         if (_http_proxy_port) \
309                 curl_easy_setopt(C, CURLOPT_PROXYPORT, _http_proxy_port); \
310 } \
311 }
312
313 #ifdef WITH_HILDON
314 #define MACRO_BANNER_SHOW_INFO(A, S) { \
315     gchar *my_macro_buffer = g_strdup_printf("<span size='%s'>%s</span>", \
316             INFO_FONT_TEXT[_info_font_size], (S)); \
317     hildon_banner_show_information_with_markup(A, NULL, my_macro_buffer); \
318     g_free(my_macro_buffer); \
319 }
320 #else
321 #define MACRO_BANNER_SHOW_INFO(A, S) { hildon_banner_show_information(A, NULL, S); }
322 #endif
323
324 #define WRITE_STRING(string) { \
325     GnomeVFSResult vfs_result; \
326     GnomeVFSFileSize size; \
327     if(GNOME_VFS_OK != (vfs_result = gnome_vfs_write( \
328                     handle, (string), strlen((string)), &size))) \
329     { \
330         gchar buffer[BUFFER_SIZE]; \
331         snprintf(buffer, sizeof(buffer), \
332                 "%s:\n%s\n%s", _("Error while writing to file"), \
333                 _("File is incomplete."), \
334                 gnome_vfs_result_to_string(vfs_result)); \
335         popup_error(_window, buffer); \
336         return FALSE; \
337     } \
338 }
339
340 void sound_noise(void);
341 gint download_comparefunc(const ProgressUpdateInfo * a, const ProgressUpdateInfo * b, gpointer user_data);
342 void deg_format(DegFormat degformat, gdouble coor, gchar *scoor, gchar neg_char, gchar pos_char);
343 void integerize_data();
344
345 #endif