Contents of /trunk/src/osm-gps-map-osd-classic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 77 - (hide annotations)
Tue Aug 25 12:49:03 2009 UTC (14 years, 8 months ago) by harbaum
File MIME type: text/plain
File size: 14502 byte(s)
osm-map path, gps etc. adjustements
1 harbaum 71 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */
2     /* vim:set et sw=4 ts=4 cino=t0,(0: */
3 harbaum 70 /*
4     * Copyright (C) Till Harbaum 2009 <till@harbaum.org>
5     *
6     * osm-gps-map is free software: you can redistribute it and/or modify it
7     * under the terms of the GNU General Public License as published by the
8     * Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10     *
11     * osm-gps-map is distributed in the hope that it will be useful, but
12     * WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14     * See the 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, see <http://www.gnu.org/licenses/>.
18     */
19    
20 harbaum 73 #include "config.h"
21     #include <stdlib.h> // abs
22     #include <math.h> // M_PI
23 harbaum 70
24 harbaum 71 /* parameters that can be overwritten from the config file: */
25 harbaum 77 /* OSD_DIAMETER */
26     /* OSD_X, OSD_Y */
27 harbaum 71
28     #ifndef USE_CAIRO
29     #error "OSD control display lacks a non-cairo implementation!"
30 harbaum 70 #endif
31    
32 harbaum 71 #include <cairo.h>
33    
34     #include "osm-gps-map.h"
35 harbaum 73 #include "osm-gps-map-osd-classic.h"
36 harbaum 71
37 harbaum 70 //the osd controls
38     typedef struct {
39 harbaum 74 /* the offscreen representation of the OSD */
40     cairo_surface_t *overlay;
41 harbaum 70 } osd_priv_t;
42    
43     /* position and extent of bounding box */
44 harbaum 77 #ifndef OSD_X
45 harbaum 70 #define OSD_X (10)
46 harbaum 77 #endif
47    
48     #ifndef OSD_Y
49 harbaum 70 #define OSD_Y (10)
50 harbaum 77 #endif
51 harbaum 70
52     /* parameters of the direction shape */
53 harbaum 77 #ifndef OSD_DIAMETER
54 harbaum 70 #define D_RAD (30) // diameter of dpad
55     #else
56 harbaum 77 #define D_RAD (OSD_DIAMETER)
57 harbaum 70 #endif
58     #define D_TIP (4*D_RAD/5) // distance of arrow tip from dpad center
59     #define D_LEN (D_RAD/4) // length of arrow
60     #define D_WID (D_LEN) // width of arrow
61    
62     /* parameters of the "zoom" pad */
63     #define Z_STEP (D_RAD/4) // distance between dpad and zoom
64     #define Z_RAD (D_RAD/2) // radius of "caps" of zoom bar
65    
66 harbaum 74 #ifdef OSD_SHADOW_ENABLE
67 harbaum 70 /* shadow also depends on control size */
68     #define OSD_SHADOW (D_RAD/6)
69 harbaum 74 #else
70     #define OSD_SHADOW (0)
71     #endif
72 harbaum 70
73 harbaum 77 /* normally the GPS button is in the center of the dpad. if there's */
74     /* no dpad it will go into the zoom area */
75     #if defined(OSD_GPS_BUTTON) && defined(OSD_NO_DPAD)
76     #define Z_GPS 1
77     #else
78     #define Z_GPS 0
79     #endif
80    
81 harbaum 70 /* total width and height of controls incl. shadow */
82 harbaum 77 #define OSD_W (2*D_RAD + OSD_SHADOW + Z_GPS * 2 * Z_RAD)
83     #if !Z_GPS
84 harbaum 70 #define OSD_H (2*D_RAD + Z_STEP + 2*Z_RAD + OSD_SHADOW)
85 harbaum 77 #else
86     #define OSD_H (2*Z_RAD + OSD_SHADOW)
87     #endif
88 harbaum 70
89 harbaum 74 #ifdef OSD_SHADOW_ENABLE
90 harbaum 70 #define OSD_LBL_SHADOW (OSD_SHADOW/2)
91 harbaum 74 #endif
92 harbaum 70
93 harbaum 77 #define Z_TOP ((1-Z_GPS) * (2 * D_RAD + Z_STEP))
94    
95 harbaum 70 #define Z_MID (Z_TOP + Z_RAD)
96     #define Z_BOT (Z_MID + Z_RAD)
97     #define Z_LEFT (Z_RAD)
98 harbaum 77 #define Z_RIGHT (2 * D_RAD - Z_RAD + Z_GPS * 2 * Z_RAD)
99     #define Z_CENTER ((Z_RIGHT + Z_LEFT)/2)
100 harbaum 70
101     /* create the cairo shape used for the zoom buttons */
102     static void
103 harbaum 71 osm_gps_map_osd_zoom_shape(cairo_t *cr, gint x, gint y)
104     {
105 harbaum 70 cairo_move_to (cr, x+Z_LEFT, y+Z_TOP);
106     cairo_line_to (cr, x+Z_RIGHT, y+Z_TOP);
107     cairo_arc (cr, x+Z_RIGHT, y+Z_MID, Z_RAD, -M_PI/2, M_PI/2);
108     cairo_line_to (cr, x+Z_LEFT, y+Z_BOT);
109     cairo_arc (cr, x+Z_LEFT, y+Z_MID, Z_RAD, M_PI/2, -M_PI/2);
110     }
111    
112 harbaum 76 #ifndef OSD_NO_DPAD
113 harbaum 70 /* create the cairo shape used for the dpad */
114     static void
115 harbaum 71 osm_gps_map_osd_dpad_shape(cairo_t *cr, gint x, gint y)
116     {
117 harbaum 70 cairo_arc (cr, x+D_RAD, y+D_RAD, D_RAD, 0, 2 * M_PI);
118     }
119 harbaum 76 #endif
120 harbaum 70
121     static gboolean
122     osm_gps_map_in_circle(gint x, gint y, gint cx, gint cy, gint rad)
123     {
124     return( pow(cx - x, 2) + pow(cy - y, 2) < rad * rad);
125     }
126    
127 harbaum 76 #ifndef OSD_NO_DPAD
128 harbaum 70 /* check whether x/y is within the dpad */
129     static osd_button_t
130     osm_gps_map_osd_check_dpad(gint x, gint y)
131     {
132     /* within entire dpad circle */
133 harbaum 77 if( osm_gps_map_in_circle(x, y, D_RAD, D_RAD, D_RAD))
134 harbaum 70 {
135     /* convert into position relative to dpads centre */
136 harbaum 77 x -= D_RAD;
137     y -= D_RAD;
138 harbaum 70
139 harbaum 76 #ifdef OSD_GPS_BUTTON
140 harbaum 70 /* check for dpad center goes here! */
141     if( osm_gps_map_in_circle(x, y, 0, 0, D_RAD/3))
142     return OSD_GPS;
143 harbaum 76 #endif
144 harbaum 70
145     if( y < 0 && abs(x) < abs(y))
146     return OSD_UP;
147    
148     if( y > 0 && abs(x) < abs(y))
149     return OSD_DOWN;
150    
151     if( x < 0 && abs(y) < abs(x))
152     return OSD_LEFT;
153    
154     if( x > 0 && abs(y) < abs(x))
155     return OSD_RIGHT;
156    
157     return OSD_BG;
158     }
159     return OSD_NONE;
160     }
161 harbaum 76 #endif
162 harbaum 70
163     /* check whether x/y is within the zoom pads */
164     static osd_button_t
165     osm_gps_map_osd_check_zoom(gint x, gint y) {
166 harbaum 77 if( x > 0 && x < OSD_W && y > Z_TOP && y < Z_BOT) {
167 harbaum 70
168     /* within circle around (-) label */
169 harbaum 77 if( osm_gps_map_in_circle(x, y, Z_LEFT, Z_MID, Z_RAD))
170 harbaum 70 return OSD_OUT;
171    
172 harbaum 77 /* within circle around (+) label */
173     if( osm_gps_map_in_circle(x, y, Z_RIGHT, Z_MID, Z_RAD))
174     return OSD_IN;
175    
176     #if Z_GPS == 1
177     /* within square around center */
178     if( x > Z_CENTER - Z_RAD && x < Z_CENTER + Z_RAD)
179     return OSD_GPS;
180     #endif
181    
182 harbaum 70 /* between center of (-) button and center of entire zoom control area */
183 harbaum 77 if(x > OSD_LEFT && x < D_RAD)
184 harbaum 70 return OSD_OUT;
185    
186     /* between center of (+) button and center of entire zoom control area */
187 harbaum 77 if(x < OSD_RIGHT && x > D_RAD)
188 harbaum 70 return OSD_IN;
189     }
190    
191     return OSD_NONE;
192     }
193    
194     static osd_button_t
195 harbaum 77 osm_gps_map_osd_check(osm_gps_map_osd_t *osd, gint x, gint y) {
196 harbaum 70 osd_button_t but = OSD_NONE;
197    
198 harbaum 77 x -= OSD_X;
199     y -= OSD_Y;
200    
201     if(OSD_X < 0)
202     x -= (osd->widget->allocation.width - OSD_W);
203    
204     if(OSD_Y < 0)
205     y -= (osd->widget->allocation.height - OSD_H);
206    
207 harbaum 70 /* first do a rough test for the OSD area. */
208     /* this is just to avoid an unnecessary detailed test */
209 harbaum 77 if(x > 0 && x < OSD_W && y > 0 && y < OSD_H) {
210 harbaum 76 #ifndef OSD_NO_DPAD
211 harbaum 70 but = osm_gps_map_osd_check_dpad(x, y);
212 harbaum 76 #endif
213 harbaum 70
214     if(but == OSD_NONE)
215     but = osm_gps_map_osd_check_zoom(x, y);
216     }
217    
218     return but;
219     }
220    
221 harbaum 74 #ifdef OSD_SHADOW_ENABLE
222 harbaum 70 static void
223     osm_gps_map_osd_shape_shadow(cairo_t *cr) {
224     cairo_set_source_rgba (cr, 0, 0, 0, 0.2);
225     cairo_fill (cr);
226     cairo_stroke (cr);
227     }
228 harbaum 74 #endif
229 harbaum 70
230 harbaum 74 #ifndef OSD_COLOR
231     /* if no color has been specified we just use the gdks default colors */
232 harbaum 70 static void
233 harbaum 74 osm_gps_map_osd_shape(cairo_t *cr, GdkColor *bg, GdkColor *fg) {
234     gdk_cairo_set_source_color(cr, bg);
235     cairo_fill_preserve (cr);
236     gdk_cairo_set_source_color(cr, fg);
237     cairo_set_line_width (cr, 1);
238     cairo_stroke (cr);
239     }
240     #else
241     static void
242 harbaum 70 osm_gps_map_osd_shape(cairo_t *cr) {
243 harbaum 74 cairo_set_source_rgb (cr, OSD_COLOR_BG);
244 harbaum 70 cairo_fill_preserve (cr);
245     cairo_set_source_rgb (cr, OSD_COLOR);
246     cairo_set_line_width (cr, 1);
247     cairo_stroke (cr);
248     }
249 harbaum 74 #endif
250 harbaum 70
251 harbaum 76 #ifndef OSD_NO_DPAD
252 harbaum 70 static void
253     osm_gps_map_osd_dpad_labels(cairo_t *cr, gint x, gint y) {
254     /* move reference to dpad center */
255     x += D_RAD;
256     y += D_RAD;
257    
258     const static gint offset[][3][2] = {
259     /* left arrow/triangle */
260     { { -D_TIP+D_LEN, -D_WID }, { -D_LEN, D_WID }, { +D_LEN, D_WID } },
261     /* right arrow/triangle */
262     { { +D_TIP-D_LEN, -D_WID }, { +D_LEN, D_WID }, { -D_LEN, D_WID } },
263     /* top arrow/triangle */
264     { { -D_WID, -D_TIP+D_LEN }, { D_WID, -D_LEN }, { D_WID, +D_LEN } },
265     /* bottom arrow/triangle */
266     { { -D_WID, +D_TIP-D_LEN }, { D_WID, +D_LEN }, { D_WID, -D_LEN } }
267     };
268    
269     int i;
270     for(i=0;i<4;i++) {
271     cairo_move_to (cr, x + offset[i][0][0], y + offset[i][0][1]);
272     cairo_rel_line_to (cr, offset[i][1][0], offset[i][1][1]);
273     cairo_rel_line_to (cr, offset[i][2][0], offset[i][2][1]);
274     }
275     }
276 harbaum 76 #endif
277 harbaum 70
278 harbaum 76 #ifdef OSD_GPS_BUTTON
279     /* draw the satellite dish icon in the center of the dpad */
280 harbaum 77 #define GPS_V0 (D_RAD/7)
281 harbaum 70 #define GPS_V1 (D_RAD/10)
282     #define GPS_V2 (D_RAD/5)
283    
284     /* draw a satellite receiver dish */
285 harbaum 77 /* this is either drawn in the center of the dpad (if present) */
286     /* or in the middle of the zoom area */
287 harbaum 70 static void
288     osm_gps_map_osd_dpad_gps(cairo_t *cr, gint x, gint y) {
289     /* move reference to dpad center */
290 harbaum 77 x += (1-Z_GPS) * D_RAD + Z_GPS * Z_RAD * 3;
291     y += (1-Z_GPS) * D_RAD + Z_GPS * Z_RAD + GPS_V0;
292 harbaum 70
293     cairo_move_to (cr, x-GPS_V0, y+GPS_V0);
294     cairo_rel_line_to (cr, +GPS_V0, -GPS_V0);
295     cairo_rel_line_to (cr, +GPS_V0, +GPS_V0);
296     cairo_close_path (cr);
297    
298     cairo_move_to (cr, x+GPS_V1-GPS_V2, y-2*GPS_V2);
299     cairo_curve_to (cr, x-GPS_V2, y, x+GPS_V1, y+GPS_V1, x+GPS_V1+GPS_V2, y);
300     cairo_close_path (cr);
301    
302     x += GPS_V1;
303     cairo_move_to (cr, x, y-GPS_V2);
304     cairo_rel_line_to (cr, +GPS_V1, -GPS_V1);
305     }
306 harbaum 76 #endif
307 harbaum 70
308     #define Z_LEN (2*Z_RAD/3)
309    
310     static void
311     osm_gps_map_osd_zoom_labels(cairo_t *cr, gint x, gint y) {
312     cairo_move_to (cr, x + Z_LEFT - Z_LEN, y + Z_MID);
313     cairo_line_to (cr, x + Z_LEFT + Z_LEN, y + Z_MID);
314    
315     cairo_move_to (cr, x + Z_RIGHT, y + Z_MID - Z_LEN);
316     cairo_line_to (cr, x + Z_RIGHT, y + Z_MID + Z_LEN);
317     cairo_move_to (cr, x + Z_RIGHT - Z_LEN, y + Z_MID);
318     cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID);
319     }
320    
321 harbaum 74 #ifndef OSD_COLOR
322     /* if no color has been specified we just use the gdks default colors */
323 harbaum 70 static void
324 harbaum 74 osm_gps_map_osd_labels(cairo_t *cr, gint width, gboolean enabled,
325     GdkColor *fg, GdkColor *disabled) {
326     if(enabled) gdk_cairo_set_source_color(cr, fg);
327     else gdk_cairo_set_source_color(cr, disabled);
328     cairo_set_line_width (cr, width);
329     cairo_stroke (cr);
330     }
331     #else
332     static void
333 harbaum 70 osm_gps_map_osd_labels(cairo_t *cr, gint width, gboolean enabled) {
334     if(enabled) cairo_set_source_rgb (cr, OSD_COLOR);
335     else cairo_set_source_rgb (cr, OSD_COLOR_DISABLED);
336     cairo_set_line_width (cr, width);
337     cairo_stroke (cr);
338     }
339 harbaum 74 #endif
340 harbaum 70
341 harbaum 74 #ifdef OSD_SHADOW_ENABLE
342 harbaum 70 static void
343     osm_gps_map_osd_labels_shadow(cairo_t *cr, gint width, gboolean enabled) {
344     cairo_set_source_rgba (cr, 0, 0, 0, enabled?0.3:0.15);
345     cairo_set_line_width (cr, width);
346     cairo_stroke (cr);
347     }
348 harbaum 74 #endif
349 harbaum 70
350     static void
351 harbaum 73 osm_gps_map_osd_render(osm_gps_map_osd_t *osd) {
352     osd_priv_t *priv = (osd_priv_t*)osd->priv;
353 harbaum 70
354     /* first fill with transparency */
355 harbaum 73 cairo_t *cr = cairo_create(priv->overlay);
356 harbaum 70 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
357     cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0);
358     cairo_paint(cr);
359    
360 harbaum 77 #ifndef OSD_COLOR
361     GdkColor bg = GTK_WIDGET(osd->widget)->style->bg[GTK_STATE_NORMAL];
362     GdkColor fg = GTK_WIDGET(osd->widget)->style->fg[GTK_STATE_NORMAL];
363     GdkColor da = GTK_WIDGET(osd->widget)->style->fg[GTK_STATE_INSENSITIVE];
364     #endif
365    
366 harbaum 70 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
367    
368     /* --------- draw zoom and dpad shape shadow ----------- */
369     gint x = 0, y = 0;
370    
371 harbaum 74 #ifdef OSD_SHADOW_ENABLE
372 harbaum 70 osm_gps_map_osd_zoom_shape(cr, x + OSD_SHADOW, y + OSD_SHADOW);
373     osm_gps_map_osd_shape_shadow(cr);
374 harbaum 76 #ifndef OSD_NO_DPAD
375 harbaum 70 osm_gps_map_osd_dpad_shape(cr, x + OSD_SHADOW, y + OSD_SHADOW);
376     osm_gps_map_osd_shape_shadow(cr);
377 harbaum 74 #endif
378 harbaum 76 #endif
379 harbaum 70
380     /* --------- draw zoom and dpad shape ----------- */
381    
382     osm_gps_map_osd_zoom_shape(cr, x, y);
383 harbaum 74 #ifndef OSD_COLOR
384 harbaum 77 osm_gps_map_osd_shape(cr, &bg, &fg);
385 harbaum 74 #else
386 harbaum 70 osm_gps_map_osd_shape(cr);
387 harbaum 74 #endif
388 harbaum 76 #ifndef OSD_NO_DPAD
389 harbaum 70 osm_gps_map_osd_dpad_shape(cr, x, y);
390 harbaum 74 #ifndef OSD_COLOR
391 harbaum 77 osm_gps_map_osd_shape(cr, &bg, &fg);
392 harbaum 74 #else
393 harbaum 70 osm_gps_map_osd_shape(cr);
394 harbaum 74 #endif
395 harbaum 76 #endif
396 harbaum 70
397     /* --------- draw zoom and dpad labels --------- */
398    
399 harbaum 74 #ifdef OSD_SHADOW_ENABLE
400 harbaum 70 osm_gps_map_osd_zoom_labels(cr, x + OSD_LBL_SHADOW, y + OSD_LBL_SHADOW);
401 harbaum 76 #ifndef OSD_NO_DPAD
402 harbaum 70 osm_gps_map_osd_dpad_labels(cr, x + OSD_LBL_SHADOW, y + OSD_LBL_SHADOW);
403 harbaum 76 #endif
404 harbaum 70 osm_gps_map_osd_labels_shadow(cr, Z_RAD/3, TRUE);
405 harbaum 76 #ifdef OSD_GPS_BUTTON
406 harbaum 70 osm_gps_map_osd_dpad_gps(cr, x + OSD_LBL_SHADOW, y + OSD_LBL_SHADOW);
407 harbaum 73 osm_gps_map_osd_labels_shadow(cr, Z_RAD/6, osd->cb != NULL);
408 harbaum 74 #endif
409 harbaum 76 #endif
410 harbaum 70
411     osm_gps_map_osd_zoom_labels(cr, x, y);
412 harbaum 76 #ifndef OSD_NO_DPAD
413 harbaum 70 osm_gps_map_osd_dpad_labels(cr, x, y);
414 harbaum 76 #endif
415 harbaum 74 #ifndef OSD_COLOR
416 harbaum 77 osm_gps_map_osd_labels(cr, Z_RAD/3, TRUE, &fg, &da);
417 harbaum 74 #else
418 harbaum 70 osm_gps_map_osd_labels(cr, Z_RAD/3, TRUE);
419 harbaum 74 #endif
420 harbaum 76 #ifdef OSD_GPS_BUTTON
421 harbaum 70 osm_gps_map_osd_dpad_gps(cr, x, y);
422 harbaum 74 #ifndef OSD_COLOR
423 harbaum 77 osm_gps_map_osd_labels(cr, Z_RAD/6, osd->cb != NULL, &fg, &da);
424 harbaum 74 #else
425 harbaum 73 osm_gps_map_osd_labels(cr, Z_RAD/6, osd->cb != NULL);
426 harbaum 74 #endif
427 harbaum 76 #endif
428 harbaum 70
429     cairo_destroy(cr);
430     }
431    
432     static void
433 harbaum 75 osm_gps_map_osd_draw(osm_gps_map_osd_t *osd, GdkDrawable *drawable)
434 harbaum 70 {
435 harbaum 73 osd_priv_t *priv = (osd_priv_t*)osd->priv;
436 harbaum 70
437     /* OSD itself uses some off-screen rendering, so check if the */
438     /* offscreen buffer is present and create it if not */
439 harbaum 73 if(!priv->overlay) {
440 harbaum 70 /* create overlay ... */
441 harbaum 73 priv->overlay =
442 harbaum 70 cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_W, OSD_H);
443     /* ... and render it */
444 harbaum 73 osm_gps_map_osd_render(osd);
445 harbaum 70 }
446    
447     // now draw this onto the original context
448 harbaum 75 cairo_t *cr = gdk_cairo_create(drawable);
449 harbaum 77
450     int x = OSD_X, y = OSD_Y;
451     if(OSD_X < 0)
452     x = osd->widget->allocation.width - OSD_W + OSD_X;
453    
454     if(OSD_Y < 0)
455     y = osd->widget->allocation.height - OSD_H + OSD_Y;
456    
457     cairo_set_source_surface(cr, priv->overlay, x, y);
458 harbaum 70 cairo_paint(cr);
459     cairo_destroy(cr);
460     }
461    
462     static void
463 harbaum 73 osm_gps_map_osd_free(osm_gps_map_osd_t *osd)
464 harbaum 70 {
465 harbaum 73 osd_priv_t *priv = (osd_priv_t *)(osd->priv);
466 harbaum 70
467 harbaum 73 if (priv->overlay)
468     cairo_surface_destroy(priv->overlay);
469 harbaum 70
470 harbaum 73 g_free(priv);
471     }
472    
473     static osm_gps_map_osd_t osd_classic = {
474     .draw = osm_gps_map_osd_draw,
475     .check = osm_gps_map_osd_check,
476     .render = osm_gps_map_osd_render,
477     .free = osm_gps_map_osd_free,
478    
479     .cb = NULL,
480     .data = NULL,
481    
482     .priv = NULL
483     };
484    
485     /* this is the only function that's externally visible */
486     void
487     osm_gps_map_osd_classic_init(OsmGpsMap *map)
488     {
489     osd_priv_t *priv = osd_classic.priv = g_new0(osd_priv_t, 1);
490    
491     osd_classic.priv = priv;
492    
493     osm_gps_map_register_osd(map, &osd_classic);
494     }
495    
496 harbaum 76 #ifdef OSD_GPS_BUTTON
497 harbaum 74 /* below are osd specific functions which aren't used by osm-gps-map */
498     /* but instead are to be used by the main application */
499 harbaum 76 void osm_gps_map_osd_enable_gps (OsmGpsMap *map, OsmGpsMapOsdCallback cb,
500     gpointer data) {
501 harbaum 73 osm_gps_map_osd_t *osd = osm_gps_map_osd_get(map);
502    
503     g_return_if_fail (osd);
504    
505     osd->cb = cb;
506     osd->data = data;
507    
508 harbaum 70 /* this may have changed the state of the gps button */
509     /* we thus re-render the overlay */
510 harbaum 73 osd->render(osd);
511 harbaum 70
512 harbaum 73 osm_gps_map_redraw(map);
513 harbaum 70 }
514 harbaum 76 #endif