]> err.no Git - mapper/commitdiff
Some map display/download fixes and code cleaning:
authorKaj-Michael Lang <milang@angel.tal.org>
Sun, 14 Oct 2007 15:36:17 +0000 (18:36 +0300)
committerKaj-Michael Lang <milang@angel.tal.org>
Sun, 14 Oct 2007 15:36:17 +0000 (18:36 +0300)
- Re-download over one week old tiles if autodownload is enabled.
- Don't draw POIs and track when dragging

src/map.c

index 23996b4cbce153ec3c3fa3f05c56809a4219a639..e8b073deb39c3b725e500bff4f14f8ef149f54f1 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -57,7 +57,7 @@ CenterMode _center_mode = CENTER_LEAD;
 static guint press[2] = { 0, 0 };
 static guint release[2] = { 0, 0 };
 static guint before[2] = { 0, 0 };
-static guint _id = 0;
+static guint map_drag_id = 0;
 
 /** VARIABLES FOR ACCESSING THE LOCATION/BOUNDS OF THE CURRENT MARK. */
 static gint _mark_x1;
@@ -80,6 +80,9 @@ struct _map_tile_rdata {
        guint destx, desty;
 };
 
+/* Tile max age, 1 week */
+#define TILE_MAX_AGE (604800)
+
 void map_render_paths();
 void map_force_redraw();
 static void map_update_location(gint x, gint y, gboolean force);
@@ -120,7 +123,8 @@ return TRUE;
 static void 
 map_draw_mark()
 {
-gdk_draw_arc(_map_widget->window, _conn_state == RCVR_FIXED ? _gc[COLORABLE_MARK] : _gc[COLORABLE_MARK_OLD], FALSE,
+gdk_draw_arc(_map_widget->window, 
+       _conn_state == RCVR_FIXED ? _gc[COLORABLE_MARK] : _gc[COLORABLE_MARK_OLD], FALSE,
      _mark_x1 - _draw_width, _mark_y1 - _draw_width, 
        2 * _draw_width, 2 * _draw_width, 0, 360 * 64);
 gdk_draw_line(_map_widget->window,
@@ -153,51 +157,52 @@ _mark_height = abs(_mark_y1 - _mark_y2) + (4 * _draw_width);
 static void
 map_pixbuf_scale_inplace(GdkPixbuf * pixbuf, guint ratio_p2, guint src_x, guint src_y)
 {
-       guint dest_x = 0, dest_y = 0, dest_dim = TILE_SIZE_PIXELS;
-       guint rowstride = gdk_pixbuf_get_rowstride(pixbuf);
-       guint n_channels = gdk_pixbuf_get_n_channels(pixbuf);
-       guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);
-
-       /* Sweep through the entire dest area, copying as necessary, but
-        * DO NOT OVERWRITE THE SOURCE AREA.  We'll copy it afterward. */
-       do {
-               guint src_dim = dest_dim >> ratio_p2;
-               guint src_endx = src_x - dest_x + src_dim;
-               gint x, y;
-
-               for (y = dest_dim - 1; y >= 0; y--) {
-                       guint src_offset_y, dest_offset_y;
-
-                       src_offset_y = (src_y + (y >> ratio_p2)) * rowstride;
-                       dest_offset_y = (dest_y + y) * rowstride;
-                       x = dest_dim - 1;
-
-                       if ((unsigned)(dest_y + y - src_y) < src_dim && (unsigned)(dest_x + x - src_x) < src_dim)
-                               x -= src_dim;
+guint dest_x = 0, dest_y = 0, dest_dim = TILE_SIZE_PIXELS;
+guint rowstride = gdk_pixbuf_get_rowstride(pixbuf);
+guint n_channels = gdk_pixbuf_get_n_channels(pixbuf);
+guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);
 
-                       for (; x >= 0; x--) {
-                               guint src_offset, dest_offset, i;
+/* Sweep through the entire dest area, copying as necessary, but
+ * DO NOT OVERWRITE THE SOURCE AREA.  We'll copy it afterward. */
+do {
+       guint src_dim = dest_dim >> ratio_p2;
+       guint src_endx = src_x - dest_x + src_dim;
+       gint x, y;
 
-                               src_offset = src_offset_y + (src_x + (x >> ratio_p2)) * n_channels;
-                               dest_offset = dest_offset_y + (dest_x + x) * n_channels;
+       for (y = dest_dim - 1; y >= 0; y--) {
+               guint src_offset_y, dest_offset_y;
 
-                               pixels[dest_offset] = pixels[src_offset];
-                               for (i = n_channels - 1; i; i--)
-                                       pixels[dest_offset + i] = pixels[src_offset + i];
+               src_offset_y = (src_y + (y >> ratio_p2)) * rowstride;
+               dest_offset_y = (dest_y + y) * rowstride;
+               x = dest_dim - 1;
 
-                               if ((unsigned)(dest_y + y - src_y) < src_dim && x == src_endx)
-                                       x -= src_dim;
-                       }
+               if ((unsigned)(dest_y + y - src_y) < src_dim && (unsigned)(dest_x + x - src_x) < src_dim)
+                       x -= src_dim;
+
+               for (; x >= 0; x--) {
+                       guint src_offset, dest_offset, i;
+
+                       src_offset = src_offset_y + (src_x + (x >> ratio_p2)) * n_channels;
+                       dest_offset = dest_offset_y + (dest_x + x) * n_channels;
+
+                       pixels[dest_offset] = pixels[src_offset];
+                       for (i = n_channels - 1; i; i--)
+                               pixels[dest_offset + i] = pixels[src_offset + i];
+
+                       if ((unsigned)(dest_y + y - src_y) < src_dim && x == src_endx)
+                               x -= src_dim;
                }
-               /* Reuse src_dim and src_endx to store new src_x and src_y. */
-               src_dim = src_x + ((src_x - dest_x) >> ratio_p2);
-               src_endx = src_y + ((src_y - dest_y) >> ratio_p2);
-               dest_x = src_x;
-               dest_y = src_y;
-               src_x = src_dim;
-               src_y = src_endx;
        }
-       while ((dest_dim >>= ratio_p2) > 1);
+
+       /* Reuse src_dim and src_endx to store new src_x and src_y. */
+       src_dim = src_x + ((src_x - dest_x) >> ratio_p2);
+       src_endx = src_y + ((src_y - dest_y) >> ratio_p2);
+       dest_x = src_x;
+       dest_y = src_y;
+       src_x = src_dim;
+       src_y = src_endx;
+}
+while ((dest_dim >>= ratio_p2) > 1);
 }
 
 /**
@@ -220,40 +225,60 @@ g_object_unref(pixbuf);
 return mpixbuf;
 }
 
+static GdkPixbuf *
+map_tile_load(guint tilex, guint tiley, gint zoff, gboolean download)
+{
+GdkPixbuf *pixbuf;
+GError *error = NULL;
+gchar buffer[BUFFER_SIZE];
+struct stat tstat;
+gint se;
+
+snprintf(buffer, sizeof(buffer), "%s/%u/%u/%u.jpg", _curr_repo->cache_dir, _zoom + zoff, (tilex >> zoff), (tiley >> zoff));
+
+pixbuf=gdk_pixbuf_new_from_file(buffer, &error);
+if (error || !pixbuf) {
+       g_unlink(buffer);
+
+       if (_auto_download && _curr_repo->type != REPOTYPE_NONE && !((_zoom + zoff - (_curr_repo->double_size ? 1 : 0)) % _curr_repo->dl_zoom_steps)) {
+               if (download)
+                       map_initiate_download(tilex >> zoff, tiley >> zoff, _zoom + zoff, -INITIAL_DOWNLOAD_RETRIES);
+       }
+
+       return NULL;
+}
+
+/* Check tile age, if file date is ower a week old, redownload if autodownload enabled */
+se=stat(buffer, &tstat);
+if (se==0) {
+       time_t t;
+       t=time(NULL);
+       if (t-tstat.st_mtime>TILE_MAX_AGE) {
+               if (_auto_download && _curr_repo->type != REPOTYPE_NONE && !((_zoom + zoff - (_curr_repo->double_size ? 1 : 0)) % _curr_repo->dl_zoom_steps)) {
+                       if (download) {
+                               g_printf("Tile: %s is old, re-downloading\n", buffer);
+                               map_initiate_download(tilex >> zoff, tiley >> zoff, _zoom + zoff, -INITIAL_DOWNLOAD_RETRIES);
+                       }
+               }
+       }
+}
+
+return pixbuf;
+}
+
 void
 map_render_tile(guint tilex, guint tiley, guint destx, guint desty, gboolean fast_fail)
 {
-GdkPixbuf *pixbuf = NULL;
-gchar buffer[BUFFER_SIZE];
-GError *error = NULL;
+GdkPixbuf *pixbuf=NULL;
 gint zoff;
 
-if (tilex < _world_size_tiles && tiley < _world_size_tiles) {
+if (tilex<_world_size_tiles && tiley<_world_size_tiles) {
        /* The tile is possible. */
-       for (zoff = (_curr_repo->double_size ? 1 : 0);
-            !pixbuf && (_zoom + zoff) <= MAX_ZOOM
-            && zoff <= TILE_SIZE_P2; zoff += 1) {
-               snprintf(buffer, sizeof(buffer), "%s/%u/%u/%u.jpg",
-                        _curr_repo->cache_dir, _zoom + zoff,
-                        (tilex >> zoff), (tiley >> zoff));
-
-               pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
-               if (error || !pixbuf) {
-                       /* Delete so we try again some other day. */
-                       g_unlink(buffer);       
-                       pixbuf = NULL;
-                       error = NULL;
-
-                       /* Download, if we should. */
-                       if (_auto_download && _curr_repo->type != REPOTYPE_NONE &&
-                           !((_zoom + zoff - (_curr_repo->double_size ? 1 : 0)) % _curr_repo->dl_zoom_steps)) {
-                               if (!fast_fail)
-                                       map_initiate_download(tilex >> zoff,
-                                                             tiley >> zoff,
-                                                             _zoom + zoff,
-                                                             -INITIAL_DOWNLOAD_RETRIES);
-                               fast_fail = TRUE;
-                       }
+       for (zoff = (_curr_repo->double_size ? 1 : 0); !pixbuf && (_zoom + zoff) <= MAX_ZOOM && zoff <= TILE_SIZE_P2; zoff += 1) {
+               pixbuf=map_tile_load(tilex, tiley, zoff, !fast_fail);
+               if (!pixbuf) {
+                       if (!fast_fail)
+                               fast_fail=TRUE;
                } else {
                        /* Check if we need to trim. */
                        if (gdk_pixbuf_get_width(pixbuf) != TILE_SIZE_PIXELS || gdk_pixbuf_get_height(pixbuf) != TILE_SIZE_PIXELS)
@@ -270,16 +295,11 @@ if (tilex < _world_size_tiles && tiley < _world_size_tiles) {
 }
 
 if (pixbuf) {
-       gdk_draw_pixbuf(_map_pixmap,
-                       _gc[COLORABLE_MARK],
-                       pixbuf, 0, 0, destx, desty,
-                       TILE_SIZE_PIXELS, TILE_SIZE_PIXELS,
-                       GDK_RGB_DITHER_NONE, 0, 0);
+       gdk_draw_pixbuf(_map_pixmap, _gc[COLORABLE_MARK], pixbuf, 0, 0, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS, GDK_RGB_DITHER_NONE, 0, 0);
        g_object_unref(pixbuf);
-} else {
-       gdk_draw_rectangle(_map_pixmap, _map_widget->style->black_gc,
-                          TRUE, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
+       return;
 }
+gdk_draw_rectangle(_map_pixmap, _map_widget->style->black_gc, TRUE, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
 }
 
 gboolean 
@@ -295,12 +315,16 @@ return FALSE;
 void
 map_render_data(void)
 {
+/* Don't update if dragging, too much lag */
+if (map_drag_id>0)
+       return;
+
+if (_home.valid)
+       map_draw_position_icon(&_home);
 if(_show_poi)
        map_render_poi();
-if(_show_tracks > 0)
+if(_show_tracks>0)
        map_render_paths();
-if (_home.valid)
-       map_draw_position_icon(&_home);
 }
 
 /**
@@ -675,170 +699,162 @@ map_render_paths()
                map_render_path(&_track, _gc + COLORABLE_TRACK);
 }
 
+/**
+ * 
+ *
+ */
 static 
-gboolean map_follow_move(GtkWidget * widget, GdkEventMotion * event)
+gboolean map_follow_move(GtkWidget *widget, GdkEventMotion *event)
 {
-       gint xx, yy;
-       GdkModifierType state;
-       guint unitx, unity;
-       guint cx, cy;
-
-       if (event->is_hint) {
-               gdk_window_get_pointer(event->window, &xx, &yy, &state);
-               state = event->state;
-       } else {
-               xx = event->x;
-               yy = event->y;
-               state = event->state;
-       }
+GdkModifierType state;
+gint xx, yy;
+guint unitx, unity;
+guint cx, cy;
+
+if (event->is_hint) {
+       gdk_window_get_pointer(event->window, &xx, &yy, &state);
+       state = event->state;
+} else {
+       xx = event->x;
+       yy = event->y;
+       state = event->state;
+}
 
-       unitx = x2unit((gint) (xx - before[0]));
-       unity = y2unit((gint) (yy - before[1]));
-       cx = unit2x(_center.unitx);
-       cy = unit2y(_center.unity);
+unitx = x2unit((gint) (xx - before[0]));
+unity = y2unit((gint) (yy - before[1]));
+cx = unit2x(_center.unitx);
+cy = unit2y(_center.unity);
 
-       map_center_unit(x2unit((gint) (cx - (xx - before[0]))),
-                       y2unit((gint) (cy - (yy - before[1]))));
+map_center_unit(x2unit((gint) (cx - (xx - before[0]))),        y2unit((gint) (cy - (yy - before[1]))));
 
-       before[0] = xx;
-       before[1] = yy;
-       return FALSE;
+before[0] = xx;
+before[1] = yy;
+return FALSE;
 }
 
 gboolean 
 map_key_zoom_timeout()
 {
-       if (_key_zoom_new < _zoom) {
-               /* We're currently zooming in (_zoom is decreasing). */
-               guint test = _key_zoom_new - _curr_repo->view_zoom_steps;
-               if (test < MAX_ZOOM)
-                       _key_zoom_new = test;
-               else
-                       return FALSE;
-       } else {
-               /* We're currently zooming out (_zoom is increasing). */
-               guint test = _key_zoom_new + _curr_repo->view_zoom_steps;
-               if (test < MAX_ZOOM)
-                       _key_zoom_new = test;
-               else
-                       return FALSE;
-       }
+if (_key_zoom_new < _zoom) {
+       /* We're currently zooming in (_zoom is decreasing). */
+       guint test = _key_zoom_new - _curr_repo->view_zoom_steps;
+       if (test < MAX_ZOOM)
+               _key_zoom_new = test;
+       else
+               return FALSE;
+} else {
+       /* We're currently zooming out (_zoom is increasing). */
+       guint test = _key_zoom_new + _curr_repo->view_zoom_steps;
+       if (test < MAX_ZOOM)
+               _key_zoom_new = test;
+       else
+               return FALSE;
+}
 
-       /* We can zoom more - tell them how much they're zooming. */
-       {
-               gchar buffer[32];
-               snprintf(buffer, sizeof(buffer), "%s %d", _("Zoom to Level"), _key_zoom_new);
-               MACRO_BANNER_SHOW_INFO(_window, buffer);
-       }
-       return TRUE;
+/* We can zoom more - tell them how much they're zooming. */
+{
+       gchar buffer[32];
+       snprintf(buffer, sizeof(buffer), "%s %d", _("Zoom to Level"), _key_zoom_new);
+       MACRO_BANNER_SHOW_INFO(_window, buffer);
+}
+return TRUE;
 }
 
 void 
 map_scale_draw(GdkEventExpose *event)
 {
-       gdk_rectangle_intersect(&event->area, &_scale_rect, &event->area);
-
-       if (event->area.width && event->area.height) {
-               gdk_draw_rectangle(_map_widget->window,
-                                  _map_widget->style->
-                                  bg_gc[GTK_WIDGET_STATE(_map_widget)],
-                                  TRUE, _scale_rect.x, _scale_rect.y,
-                                  _scale_rect.width,
-                                  _scale_rect.height);
-               gdk_draw_rectangle(_map_widget->window,
-                                  _map_widget->style->
-                                  fg_gc[GTK_WIDGET_STATE(_map_widget)],
-                                  FALSE, _scale_rect.x, _scale_rect.y,
-                                  _scale_rect.width,
-                                  _scale_rect.height);
-
-               /* Now calculate and draw the distance. */
-               {
-                       gchar buffer[16];
-                       gdouble distance;
-                       gdouble lat1, lon1, lat2, lon2;
-                       gint width;
-
-                       unit2latlon(_center.unitx - pixel2unit(SCALE_WIDTH / 2 - 4),
-                                   _center.unity, lat1, lon1);
-                       unit2latlon(_center.unitx + pixel2unit(SCALE_WIDTH / 2 - 4),
-                                   _center.unity, lat2, lon2);
-                       distance = calculate_distance(lat1, lon1, lat2, lon2) * UNITS_CONVERT[_units];
-
-                       if (distance < 1.f)
-                               snprintf(buffer, sizeof(buffer),
-                                        "%0.2f %s", distance,
-                                        UNITS_TEXT[_units]);
-                       else if (distance < 10.f)
-                               snprintf(buffer, sizeof(buffer),
-                                        "%0.1f %s", distance,
-                                        UNITS_TEXT[_units]);
-                       else
-                               snprintf(buffer, sizeof(buffer),
-                                        "%0.f %s", distance,
-                                        UNITS_TEXT[_units]);
-
-                       pango_layout_set_text(_scale_layout, buffer, -1);
-                       pango_layout_get_pixel_size(_scale_layout, &width, NULL);
-
-                       /* Draw the layout itself. */
-                       gdk_draw_layout(_map_widget->window,
-                                       _map_widget->style->
-                                       fg_gc[GTK_WIDGET_STATE
-                                             (_map_widget)],
-                                       _scale_rect.x +
-                                       (_scale_rect.width - width) / 2,
-                                       _scale_rect.y, _scale_layout);
-
-                       /* Draw little hashes on the ends. */
-                       gdk_draw_line(_map_widget->window,
-                                     _map_widget->style->
-                                     fg_gc[GTK_WIDGET_STATE
-                                           (_map_widget)],
-                                     _scale_rect.x + 4,
-                                     _scale_rect.y +
-                                     _scale_rect.height / 2 - 4,
-                                     _scale_rect.x + 4,
-                                     _scale_rect.y +
-                                     _scale_rect.height / 2 + 4);
-                       gdk_draw_line(_map_widget->window,
-                                     _map_widget->style->
-                                     fg_gc[GTK_WIDGET_STATE
-                                           (_map_widget)],
-                                     _scale_rect.x + 4,
-                                     _scale_rect.y +
-                                     _scale_rect.height / 2,
-                                     _scale_rect.x +
-                                     (_scale_rect.width - width) / 2 -
-                                     4,
-                                     _scale_rect.y +
-                                     _scale_rect.height / 2);
-                       gdk_draw_line(_map_widget->window,
-                                     _map_widget->style->
-                                     fg_gc[GTK_WIDGET_STATE
-                                           (_map_widget)],
-                                     _scale_rect.x +
-                                     _scale_rect.width - 4,
-                                     _scale_rect.y +
-                                     _scale_rect.height / 2 - 4,
-                                     _scale_rect.x +
-                                     _scale_rect.width - 4,
-                                     _scale_rect.y +
-                                     _scale_rect.height / 2 + 4);
-                       gdk_draw_line(_map_widget->window,
-                                     _map_widget->style->
-                                     fg_gc[GTK_WIDGET_STATE
-                                           (_map_widget)],
-                                     _scale_rect.x +
-                                     _scale_rect.width - 4,
-                                     _scale_rect.y +
-                                     _scale_rect.height / 2,
-                                     _scale_rect.x +
-                                     (_scale_rect.width + width) / 2 +
-                                     4,
-                                     _scale_rect.y +
-                                     _scale_rect.height / 2);
-               }
+gchar buffer[16];
+gdouble distance;
+gdouble lat1, lon1, lat2, lon2;
+gint width;
+
+gdk_rectangle_intersect(&event->area, &_scale_rect, &event->area);
+
+if (event->area.width && event->area.height) {
+       gdk_draw_rectangle(_map_widget->window,
+                          _map_widget->style->
+                          bg_gc[GTK_WIDGET_STATE(_map_widget)],
+                          TRUE, _scale_rect.x, _scale_rect.y,
+                          _scale_rect.width,
+                          _scale_rect.height);
+       gdk_draw_rectangle(_map_widget->window,
+                          _map_widget->style->
+                          fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                          FALSE, _scale_rect.x, _scale_rect.y,
+                          _scale_rect.width,
+                          _scale_rect.height);
+
+       /* Now calculate and draw the distance. */
+       unit2latlon(_center.unitx - pixel2unit(SCALE_WIDTH / 2 - 4), _center.unity, lat1, lon1);
+       unit2latlon(_center.unitx + pixel2unit(SCALE_WIDTH / 2 - 4), _center.unity, lat2, lon2);
+       distance = calculate_distance(lat1, lon1, lat2, lon2) * UNITS_CONVERT[_units];
+
+       if (distance < 1.f)
+                       snprintf(buffer, sizeof(buffer),
+                                "%0.2f %s", distance,
+                                UNITS_TEXT[_units]);
+       else if (distance < 10.f)
+               snprintf(buffer, sizeof(buffer),
+                        "%0.1f %s", distance,
+                        UNITS_TEXT[_units]);
+       else
+               snprintf(buffer, sizeof(buffer),
+                        "%0.f %s", distance,
+                        UNITS_TEXT[_units]);
+
+       pango_layout_set_text(_scale_layout, buffer, -1);
+       pango_layout_get_pixel_size(_scale_layout, &width, NULL);
+
+       /* Draw the layout itself. */
+       gdk_draw_layout(_map_widget->window,
+                       _map_widget->style->
+                       fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                       _scale_rect.x +
+                       (_scale_rect.width - width) / 2,
+                       _scale_rect.y, _scale_layout);
+
+       /* Draw little hashes on the ends. */
+       gdk_draw_line(_map_widget->window,
+                     _map_widget->style->
+                     fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                     _scale_rect.x + 4,
+                     _scale_rect.y +
+                     _scale_rect.height / 2 - 4,
+                     _scale_rect.x + 4,
+                     _scale_rect.y +
+                     _scale_rect.height / 2 + 4);
+       gdk_draw_line(_map_widget->window,
+                     _map_widget->style->
+                     fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                     _scale_rect.x + 4,
+                     _scale_rect.y +
+                     _scale_rect.height / 2,
+                     _scale_rect.x +
+                     (_scale_rect.width - width) / 2 - 4,
+                     _scale_rect.y +
+                     _scale_rect.height / 2);
+       gdk_draw_line(_map_widget->window,
+                     _map_widget->style->
+                     fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                     _scale_rect.x +
+                     _scale_rect.width - 4,
+                     _scale_rect.y +
+                     _scale_rect.height / 2 - 4,
+                     _scale_rect.x +
+                     _scale_rect.width - 4,
+                     _scale_rect.y +
+                     _scale_rect.height / 2 + 4);
+       gdk_draw_line(_map_widget->window,
+                     _map_widget->style->
+                     fg_gc[GTK_WIDGET_STATE(_map_widget)],
+                     _scale_rect.x +
+                     _scale_rect.width - 4,
+                     _scale_rect.y +
+                     _scale_rect.height / 2,
+                     _scale_rect.x +
+                     (_scale_rect.width + width) / 2 + 4,
+                     _scale_rect.y +
+                     _scale_rect.height / 2);
        }
 }
 
@@ -949,7 +965,7 @@ if (!s && !mp && !sp) {
 } else {
        /* oh, fun */
        snprintf(buffer, sizeof(buffer), "%s%s%s%s%s%s%s%s%s%s", 
-       s ? s->name ? s->name : _("unknown") : "?",
+       s ? s->name ? s->name : "" : "",
        s ? s->ref ? ", " : "" : "",
        s ? s->ref ? s->ref : "" : "",
        s ? s->int_ref ? " (" : "" : "",
@@ -1025,91 +1041,90 @@ if (event->direction == GDK_SCROLL_UP) {
 return FALSE;
 }
 
+static void
+map_drag_start(gint x,gint y)
+{
+press[0] = x;
+press[1] = y;
+before[0] = press[0];
+before[1] = press[1];
+map_drag_id=g_signal_connect(G_OBJECT(_map_widget), "motion_notify_event", G_CALLBACK(map_follow_move), NULL);
+}
+
+static void
+map_drag_stop(gint x, gint y)
+{
+release[0]=x;
+release[1]=y;
+g_signal_handler_disconnect(G_OBJECT(_map_widget), map_drag_id);
+press[0]=0;
+press[1]=0;
+release[0]=0;
+release[1]=0;
+before[0]=0;
+before[1]=0;
+map_drag_id=0;
+}
+
 gboolean 
 map_cb_button_press(GtkWidget * widget, GdkEventButton * event)
 {
-       _cmenu_position_x = event->x + 0.5;
-       _cmenu_position_y = event->y + 0.5;
-
-       switch (event->button) {
-       case 1:
-               if (event->type == GDK_2BUTTON_PRESS) {
-                       map_set_zoom(_zoom - 1);
-                       return FALSE;
-               }
-               if (event->type == GDK_3BUTTON_PRESS)
-                       return FALSE;
-               break;
-       case 2:
-               press[0] = event->x;
-               press[1] = event->y;
-               before[0] = press[0];
-               before[1] = press[1];
-
-               _id = g_signal_connect(G_OBJECT(_map_widget),
-                                    "motion_notify_event",
-                                    G_CALLBACK(map_follow_move), NULL);
-               break;
-       case 3:
+_cmenu_position_x = event->x + 0.5;
+_cmenu_position_y = event->y + 0.5;
+
+switch (event->button) {
+case 1:
+       if (event->type==GDK_2BUTTON_PRESS) {
+               map_set_zoom(_zoom - 1);
+               return FALSE;
+       }
+       if (event->type==GDK_3BUTTON_PRESS)
+               return FALSE;
+break;
+case 2:
+       map_drag_start(event->x, event->y);
+break;
+case 3:
 #ifndef WITH_HILDON
-               gtk_menu_popup(GTK_MENU(_menu_map), NULL, NULL, NULL, NULL,
-                              event->button, gtk_get_current_event_time());
+       gtk_menu_popup(GTK_MENU(_menu_map), NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time());
 #endif
-               break;
-       }
-
-       /* Return FALSE to allow context menu to work. */
-       return FALSE;
+break;
+}
+/* Return FALSE to allow context menu to work. */
+return FALSE;
 }
 
 gboolean 
-map_cb_button_release(GtkWidget * widget, GdkEventButton * event)
+map_cb_button_release(GtkWidget *widget, GdkEventButton *event)
 {
 switch (event->button) {
-       case 1:
-               if (_center_mode > 0)
-                       set_action_activate("autocenter_none", TRUE);
-
-               switch (map_mode) {
-               case MAP_MODE_DRAW_TRACK:
-                       map_draw_track(event->x, event->y);
-               break;
-               case MAP_MODE_DRAW_ROUTE:
-                       map_draw_route(event->x, event->y);
-               break;
-               case MAP_MODE_SET_ROUTE_FROM:
-               case MAP_MODE_SET_ROUTE_POINT:
-               case MAP_MODE_SET_ROUTE_TO:
-               break;
-               }
-
-#if 0
-               ux = x2unit((gint) (event->x + 0.5));
-               uy = y2unit((gint) (event->y + 0.5));
-               map_update_location(ux, uy);
-#else
-               g_idle_add((GSourceFunc)map_update_location_from_center, NULL);
-#endif
-
-               map_center_unit(x2unit((gint) (event->x + 0.5)),
-                               y2unit((gint) (event->y + 0.5)));
-
-               break;
-       case 2:
-               release[0] = event->x;
-               release[1] = event->y;
-
-               g_signal_handler_disconnect(G_OBJECT(_map_widget), _id);
-
-               press[0] = 0;
-               press[1] = 0;
-               release[0] = 0;
-               release[1] = 0;
-               before[0] = 0;
-               before[1] = 0;
-               break;
-       case 3:
-               break;
+case 1:
+       if (_center_mode>0)
+               set_action_activate("autocenter_none", TRUE);
+
+       switch (map_mode) {
+       case MAP_MODE_DRAW_TRACK:
+               map_draw_track(event->x, event->y);
+       break;
+       case MAP_MODE_DRAW_ROUTE:
+               map_draw_route(event->x, event->y);
+       break;
+       case MAP_MODE_SET_ROUTE_FROM:
+       case MAP_MODE_SET_ROUTE_POINT:
+       case MAP_MODE_SET_ROUTE_TO:
+       break;
+       default:
+       break;
+       }
+       g_idle_add((GSourceFunc)map_update_location_from_center, NULL);
+       map_center_unit(x2unit((gint) (event->x + 0.5)), y2unit((gint) (event->y + 0.5)));
+break;
+case 2:
+       map_drag_stop(event->x, event->y);
+       map_render_data();      
+break;
+case 3:
+break;
 }
 
 /* Return FALSE to avoid context menu (if it hasn't popped up already). */