]> err.no Git - mapper/blobdiff - src/gtkmap.c
GpsBluez: cleanups
[mapper] / src / gtkmap.c
index 14661da693efd6182512e09225bce5934dfc5b83..e4d9c10375aacf3b40fa76ce26c3474231b4d396 100644 (file)
@@ -70,6 +70,8 @@ struct _GtkMapPriv
        cairo_t *ct;
 #endif
 
+       GtkMenu *menu;
+
        PangoContext *context;
        PangoLayout *layout;
        PangoFontDescription *fontdesc;
@@ -82,30 +84,32 @@ struct _GtkMapPriv
        PangoLayout *scale_layout;
        PangoFontDescription *scale_font;
 
-       GdkGC *gc_h;
-       GdkGC *gc_w;
-       GdkGC *gc_d;
+       GdkGC *gc_track;
+       GdkGC *gc_route;
+       GdkGC *gc_waypoint;
+       GdkGC *gc_break;
+
+       GdkGC *gc_mark;
+       GdkGC *gc_velvec;
 
        GdkGC *speed_gc1;
        GdkGC *speed_gc2;
        GdkGC *speed_gc;
 
+       /* OpenGL data */
+#ifdef WITH_GL
+       GdkGLConfig* gl_config;
+#endif
+       gboolean gl;
+
        GdkRectangle scale_rect;
 
        RepoData *curr_repo;
 
        GTimer *timer;
        ImageCache *icache;
-       GList *markers;
 
-       /* OpenGL data */
-#ifdef WITH_GL
-       GdkGLConfig* gl_config;
-#endif
-       gboolean gl;
-
-       GdkGC *gc_mark;
-       GdkGC *gc_velvec;
+       GSList *markers;
 
        /* Cached Location dot x,y values */
        gint mark_x1;
@@ -115,7 +119,6 @@ struct _GtkMapPriv
        GdkRectangle mark_rect;
 
        GtkMapCenterMode center_mode;
-
        Point center;
        Point min_center;
        Point max_center;
@@ -162,26 +165,46 @@ struct _GtkMapPriv
        gboolean show_location;
        gboolean show_velvec;
        gboolean show_markers;
+       gboolean show_speed;
+       gboolean click_to_center;
+       gboolean zoom_in_on_2button;
+       gboolean rotate_view;
+       gfloat rotate_angle;
 
        guint draw_width;
 
+       gboolean button_down;
+       gint mouse_x;
+       gint mouse_y;
+       gdouble mouse_lat;
+       gdouble mouse_lon;
+
        gboolean fast_render;
 
        guint key_zoom_new;
        guint key_zoom_timeout_sid;
+
+       /* Paths */
+       GSList *paths;                  /* A list with paths to draw (tracks, routes, friends) */
+       Path *current_track;    /* Pointer to main track */
+       Path *current_route;    /* Pointer to main route */
 };
 
 #define tile2grid(tile) ((tile) << 3)
 #define grid2tile(grid) ((grid) >> 3)
+
 #define tile2pixel(tile) ((tile) << 8)
 #define pixel2tile(pixel) ((pixel) >> 8)
+
 #define tile2unit(tile) ((tile) << (8 + priv->zoom))
 #define unit2tile(unit) ((unit) >> (8 + priv->zoom))
+
 #define tile2zunit(tile, zoom) ((tile) << (8 + zoom))
 #define unit2ztile(unit, zoom) ((unit) >> (8 + zoom))
 
 #define grid2pixel(grid) ((grid) << 5)
 #define pixel2grid(pixel) ((pixel) >> 5)
+
 #define grid2unit(grid) ((grid) << (5 + priv->zoom))
 #define unit2grid(unit) ((unit) >> (5 + priv->zoom))
 
@@ -226,10 +249,14 @@ static void gtk_map_size_request(GtkWidget *widget, GtkRequisition *requisition)
 static void gtk_map_size_allocate(GtkWidget *widget, GtkAllocation *allocate);
 static void gtk_map_realize(GtkWidget *widget);
 static gboolean gtk_map_expose(GtkWidget *widget, GdkEventExpose *event);
-static gboolean gtk_map_configure(GtkWidget *widget, GdkEventConfigure *event);
 
 static void gtk_map_scale_draw(GtkWidget *widget, GdkEventExpose *event);
 static void gtk_map_mark_draw(GtkWidget *widget, GdkEventExpose *event);
+static void gtk_map_speed_draw(GtkWidget *widget, GdkEventExpose *event);
+
+static void gtk_map_render_buffer(GtkWidget *widget, GdkEventExpose *event);
+static void gtk_map_render_markers(GtkWidget *widget, GdkEventExpose *event);
+static void gtk_map_render_paths(GtkWidget *widget, GdkEventExpose *event);
 
 static gboolean gtk_map_update_buffer_size(GtkWidget *widget, gint new_width, gint new_height);
 static void gtk_map_update_size(GtkWidget *widget, gint width, gint height);
@@ -240,6 +267,8 @@ static void gtk_map_get_property(GObject *object, guint prop_id, GValue *value,
 static gboolean gtk_map_button_press_cb(GtkWidget *widget, GdkEventButton *event);
 static gboolean gtk_map_button_release_cb(GtkWidget *widget, GdkEventButton *event);
 static gboolean gtk_map_scroll_event_cb(GtkWidget *widget, GdkEventScroll *event); 
+static gboolean gtk_map_motion_notify_cb(GtkWidget *widget, GdkEventMotion *event, gpointer data);
+
 
 /* Signal IDs */
 enum {
@@ -380,6 +409,13 @@ priv->show_velvec=TRUE;
 priv->show_markers=TRUE;
 priv->show_location=TRUE;
 
+priv->button_down=FALSE;
+priv->click_to_center=FALSE;
+priv->zoom_in_on_2button=FALSE;
+
+priv->rotate_angle=M_PI;
+priv->rotate_view=FALSE;
+
 priv->gl=FALSE;
 priv->buffer=NULL;
 }
@@ -456,7 +492,7 @@ priv=GTK_MAP_GET_PRIVATE(map);
 tw=GTK_MAP_TILE_SIZE_PIXELS*((width/GTK_MAP_TILE_SIZE_PIXELS)+2);
 th=GTK_MAP_TILE_SIZE_PIXELS*((height/GTK_MAP_TILE_SIZE_PIXELS)+2);
 
-gtk_map_update_buffer_size(GTK_MAP(widget), tw, th);
+gtk_map_update_buffer_size(widget, tw, th);
 if (!priv->buffer) {
        return;
 }
@@ -510,11 +546,8 @@ g_return_if_fail(requisition != NULL);
        
 map=GTK_MAP(widget);
 
-g_debug("GTKMAP: Size request");
-
 requisition->width=GTK_MAP_TILE_SIZE_PIXELS/2;
 requisition->height=GTK_MAP_TILE_SIZE_PIXELS/2;
-/* gtk_map_update_size(widget, requisition->width, requisition->height); */
 }
 
 static gboolean
@@ -590,18 +623,11 @@ if (priv->gl_config) {
     g_print("OpenGL version: %s\n", glGetString (GL_VERSION));
     g_print("OpenGL vendor: %s\n", glGetString (GL_VENDOR));
     g_print("OpenGL renderer: %s\n", glGetString (GL_RENDERER));
-       gtk_widget_set_gl_capability(widget->window, priv->gl_config, NULL, TRUE, GDK_GL_RGBA_TYPE);
+       gtk_widget_set_gl_capability(widget, priv->gl_config, NULL, TRUE, GDK_GL_RGBA_TYPE);
        priv->gl=TRUE;
 }
 #endif
 
-#if 0
-g_signal_connect(G_OBJECT(map), "button_press_event", G_CALLBACK(map_cb_button_press), NULL);
-g_signal_connect(G_OBJECT(map), "button_release_event",G_CALLBACK(map_cb_button_release), NULL);
-#endif
-
-g_signal_connect(G_OBJECT(map), "scroll_event",  G_CALLBACK(gtk_map_scroll_event_cb), NULL);
-
 priv->scale_context=gtk_widget_get_pango_context(widget);
 priv->scale_layout=pango_layout_new(priv->scale_context);
 priv->scale_font=pango_font_description_new();
@@ -622,6 +648,30 @@ color.green=0x1000;
 color.blue=0;
 gdk_gc_set_rgb_fg_color(priv->speed_gc2, &color);
 
+priv->gc_track=gdk_gc_new(widget->window);
+color.red=0xffff;
+color.green=0;
+color.blue=0;
+gdk_gc_set_rgb_fg_color(priv->gc_track, &color);
+
+priv->gc_route=gdk_gc_new(widget->window);
+color.red=0;
+color.green=0xffff;
+color.blue=0;
+gdk_gc_set_rgb_fg_color(priv->gc_route, &color);
+
+priv->gc_waypoint=gdk_gc_new(widget->window);
+color.red=0xffff;
+color.green=0xffff;
+color.blue=0;
+gdk_gc_set_rgb_fg_color(priv->gc_waypoint, &color);
+
+priv->gc_break=gdk_gc_new(widget->window);
+color.red=0xffff;
+color.green=0;
+color.blue=0xffff;
+gdk_gc_set_rgb_fg_color(priv->gc_break, &color);
+
 priv->speed_context=gtk_widget_get_pango_context(widget);
 priv->speed_layout=pango_layout_new(priv->speed_context);
 priv->speed_font=pango_font_description_new();
@@ -629,13 +679,56 @@ pango_font_description_set_size(priv->speed_font, 48 * PANGO_SCALE);
 pango_layout_set_font_description(priv->speed_layout, priv->speed_font);
 pango_layout_set_alignment(priv->speed_layout, PANGO_ALIGN_LEFT);
 
-#if 0
-g_signal_connect(G_OBJECT(widget), "button_press_event", G_CALLBACK(gtk_map_press_cb), NULL);
-#endif
+g_signal_connect(G_OBJECT(map), "button_press_event", G_CALLBACK(gtk_map_button_press_cb), NULL);
+g_signal_connect(G_OBJECT(map), "button_release_event",G_CALLBACK(gtk_map_button_release_cb), NULL);
+g_signal_connect(G_OBJECT(map), "scroll_event",  G_CALLBACK(gtk_map_scroll_event_cb), NULL);
+g_signal_connect(G_OBJECT(map), "motion_notify_event", G_CALLBACK(gtk_map_motion_notify_cb), NULL);
 
 gtk_widget_queue_resize(widget);
 }
 
+static void 
+gtk_map_render_buffer(GtkWidget *widget, GdkEventExpose *event)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+g_return_if_fail(event != NULL);
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+if (!priv->buffer)
+       return
+
+g_debug("GTKMAP: expose (%d, %d)-(%d, %d)", event->area.x, event->area.y, event->area.width, event->area.height);
+g_debug("GTKMAP: expose (%d, %d)", event->area.x + priv->offsetx, event->area.y + priv->offsety);
+g_debug("GTKMAP: expose (%d, %d)", unit2x(priv->center.unitx), unit2y(priv->center.unity));
+
+#ifdef WITH_CAIROa
+cairo_save(priv->ct);
+cairo_rectangle(priv->ct, event->area.x, event->area.y, event->area.width, event->area.height);
+cairo_clip(priv->ct);
+#if 0
+if (priv->rotate_view) {
+       cairo_translate(priv->ct, (gdouble)-unit2x(priv->center.unitx), (gdouble)-unit2y(priv->center.unity) );
+       cairo_rotate(priv->ct, (gdouble)priv->rotate_angle);
+       cairo_translate(priv->ct, (gdouble)unit2x(priv->center.unitx), (gdouble)unit2y(priv->center.unity) );
+}
+#endif
+cairo_translate(priv->ct, -(event->area.x+priv->offsetx), -(event->area.y+priv->offsety));
+gdk_cairo_set_source_pixmap(priv->ct, priv->buffer, event->area.x, event->area.y);
+cairo_set_operator (priv->ct, CAIRO_OPERATOR_SOURCE);
+cairo_paint(priv->ct);
+cairo_restore(priv->ct);
+#else
+gdk_draw_drawable(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], priv->buffer,
+       event->area.x + priv->offsetx, event->area.y + priv->offsety,
+       event->area.x, event->area.y, event->area.width, event->area.height);
+#endif
+}
+
 static gboolean
 gtk_map_expose(GtkWidget *widget, GdkEventExpose *event)
 {
@@ -652,22 +745,16 @@ priv=GTK_MAP_GET_PRIVATE(map);
 priv->ct=gdk_cairo_create(widget->window);
 #endif
 
-g_debug("GTKMAP: expose (%d, %d)-(%d, %d)", event->area.x, event->area.y, event->area.width, event->area.height);
-
-if (priv->buffer)
-       gdk_draw_drawable(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], priv->buffer,
-               event->area.x + priv->offsetx, event->area.y + priv->offsety,
-               event->area.x, event->area.y, event->area.width, event->area.height);
+gtk_map_render_buffer(widget, event);
 
-#if 0
-gtk_map_paths_draw(widget, event);
+if (priv->show_paths!=0)
+       gtk_map_render_paths(widget, event);
 
 if (priv->show_markers)
-       gtk_map_markers_draw(widget, event);
+       gtk_map_render_markers(widget, event);
 
 if (priv->show_speed)
        gtk_map_speed_draw(widget, event);
-#endif
 
 if (priv->show_location)
        gtk_map_mark_draw(widget, event);
@@ -683,6 +770,151 @@ priv->ct=NULL;
 return TRUE;
 }
 
+static void 
+gtk_map_render_markers(GtkWidget *widget, GdkEventExpose *event)
+{
+
+}
+
+static void
+gtk_map_render_waypoint(GtkWidget *widget, guint x1, guint y1)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+GdkGC *gc;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+gc=priv->gc_waypoint;
+
+if ((x1 > priv->buf_width_pixels) || (y1 > priv->buf_height_pixels))
+       return;
+gdk_draw_arc(widget->window, gc, FALSE, x1 - priv->draw_width, y1 - priv->draw_width, 2 * priv->draw_width, 2 * priv->draw_width, 0, 360 * 64);
+}
+
+static void
+gtk_map_render_path_segment(GtkWidget *widget, guint unitx1, guint unity1, guint unitx2, guint unity2)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+GdkGC *gc;
+gint x1, y1, x2, y2;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+x1=unit2bufx(unitx1);
+y1=unit2bufy(unity1);
+x2=unit2bufx(unitx2);
+y2=unit2bufy(unity2);
+
+/* Make sure this line could possibly be visible. */
+if (!((x1 > priv->buf_width_pixels && x2 > priv->buf_width_pixels) || (x1 < 0 && x2 < 0)
+      || (y1 > priv->buf_height_pixels && y2 > priv->buf_height_pixels) || (y1 < 0 && y2 < 0))) {
+       gc=priv->gc_track;
+       gdk_draw_line(widget->window, gc, x1, y1, x2, y2);
+}
+}
+
+static void
+gtk_map_render_path(GtkWidget *widget, Path *path, GdkEventExpose *event)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+Point *curr;
+WayPoint *wcurr;
+
+g_return_if_fail(path);
+
+if (path->head==path->tail)
+       return;
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+for (curr = path->head, wcurr = path->whead; curr++ != path->tail;) {
+       /* Draw the line from (curr - 1) to (curr). */
+
+       gtk_map_render_path_segment(widget, curr[-1].unitx, curr[-1].unity, curr->unitx, curr->unity);
+       /* Now, check if curr is a waypoint. */
+       if (wcurr && wcurr <= path->wtail && wcurr->point == curr) {
+               guint x1 = unit2bufx(wcurr->point->unitx);
+               guint y1 = unit2bufy(wcurr->point->unity);
+
+               gtk_map_render_waypoint(widget, x1, y1);
+               wcurr++;
+       }
+}
+#if 0
+if (path->type==PATH_TYPE_ROUTE)
+       gtk_map_render_next_waypoint(widget, path);
+#endif
+}
+
+static void 
+gtk_map_render_paths(GtkWidget *widget, GdkEventExpose *event)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+GSList *iter;
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+/* No paths defined so return */
+if (!priv->paths)
+       return;
+
+for (iter=priv->paths; iter!=NULL; iter=iter->next) {
+       Path *p=(Path *)iter->data;
+
+       if ( (!(priv->show_paths & ROUTES_MASK) && p->type==PATH_TYPE_ROUTE) || 
+                       (!(priv->show_paths & TRACKS_MASK) && p->type==PATH_TYPE_ROUTE) )
+               continue;
+
+       gtk_map_render_path(widget, p, event);
+}
+}
+
+gboolean
+gtk_map_add_path(GtkWidget *widget, Path *path)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+g_return_val_if_fail(path, FALSE);
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+/* Don't allow duplicates */
+if (g_slist_find(priv->paths, path)!=NULL)
+       return FALSE;
+priv->paths=g_slist_append(priv->paths, path);
+return TRUE;
+}
+
+gboolean
+gtk_map_remove_path(GtkWidget *widget, Path *path)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+g_return_val_if_fail(path, FALSE);
+
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+priv->paths=g_slist_remove(priv->paths, path);
+return TRUE;
+}
+
 static void 
 gtk_map_mark_draw(GtkWidget *widget, GdkEventExpose *event)
 {
@@ -712,8 +944,8 @@ if (priv->show_velvec) {
        cairo_line_to(priv->ct, priv->mark_x2, priv->mark_y2);
        cairo_restore(priv->ct);
 }
-cairo_restore(priv->ct);
 cairo_stroke(priv->ct);
+cairo_restore(priv->ct);
 #else
 gdk_draw_arc(widget->window, priv->gc_mark, FALSE,
        priv->mark_x1 - priv->draw_width,
@@ -788,6 +1020,7 @@ else
 g_debug("SCALE: %s", buffer);
 
 #ifdef WITH_CAIRO
+cairo_save(priv->ct);
 cairo_rectangle(priv->ct, priv->scale_rect.x, priv->scale_rect.y, priv->scale_rect.width, priv->scale_rect.height);
 cairo_set_source_rgba(priv->ct, 1, 1, 1, 0.65);
 cairo_fill_preserve(priv->ct);
@@ -818,6 +1051,7 @@ cairo_move_to(priv->ct, priv->scale_rect.x + priv->scale_rect.width - SCALE_PADD
 cairo_line_to(priv->ct, priv->scale_rect.x + (priv->scale_rect.width + width) / 2 + SCALE_PADDING, priv->scale_rect.y + priv->scale_rect.height / 2);
 
 cairo_stroke(priv->ct);
+cairo_restore(priv->ct);
 #else
 gdk_draw_line(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
            priv->scale_rect.x + SCALE_PADDING, priv->scale_rect.y + priv->scale_rect.height / 2 - SCALE_PADDING,
@@ -873,7 +1107,7 @@ if (priv->speed<0)
        return;
 
 g_snprintf(buffer, sizeof(buffer), "%0.0f %s", priv->speed * priv->units_conv, priv->units_str);
-map_information_text(10, 10, priv->speed_gc, buffer);
+gtk_map_information_text(widget, 10, 10, priv->speed_gc, buffer);
 }
 
 void
@@ -1078,7 +1312,7 @@ gdk_draw_rectangle(priv->buffer,
 return TRUE;
 }
 
-gboolean
+void
 gtk_map_set_center(GtkWidget *widget, guint unitx, guint unity)
 {
 GtkMap *map;
@@ -1172,6 +1406,15 @@ gtk_map_refresh(widget);
 g_signal_emit(widget, gtk_map_signals[MAP_LOCATION_CHANGED], 0, priv->zoom);
 }
 
+void
+gtk_map_set_center_latlon(GtkWidget *widget, gdouble lat, gdouble lon)
+{
+guint unitx, unity;
+
+latlon2unit(lat, lon, unitx, unity);
+gtk_map_set_center(widget, unitx, unity);
+}
+
 void
 gtk_map_pan(GtkWidget *widget, gint delta_x, gint delta_y)
 {
@@ -1185,7 +1428,7 @@ priv=GTK_MAP_GET_PRIVATE(map);
 gtk_map_set_center(widget, priv->center.unitx + delta_x*GTK_MAP_PAN_UNITS, priv->center.unity + delta_y*GTK_MAP_PAN_UNITS);
 }
 
-static void
+void
 gtk_map_refresh(GtkWidget *widget)
 {
 GtkMap *map;
@@ -1318,6 +1561,10 @@ if (cache_size>512)
 image_cache_set_size(priv->icache, cache_size);
 }
 
+/******************************************************************************/
+/* Internal widget callback handlers                                          */
+/******************************************************************************/
+
 /**
  * Mouse scroller zoom in/out callback
  */
@@ -1327,7 +1574,7 @@ gtk_map_scroll_event_cb(GtkWidget *widget, GdkEventScroll *event)
 GtkMap *map;
 GtkMapPriv *priv;
 
-g_return_if_fail(GTK_IS_MAP(widget));
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
 
 map=GTK_MAP(widget);
 priv=GTK_MAP_GET_PRIVATE(map);
@@ -1336,3 +1583,80 @@ if (priv->zoom_to_mouse)
        gtk_map_set_center(widget, x2unit((gint) (event->x + 0.5)), y2unit((gint) (event->y + 0.5)));
 return FALSE;
 }
+
+static gboolean 
+gtk_map_motion_notify_cb(GtkWidget *widget, GdkEventMotion *event, gpointer data)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+priv->mouse_x=(gint)event->x;
+priv->mouse_y=(gint)event->y;
+unit2latlon(x2unit((gint) (event->x+0.5)), y2unit((gint) (event->y+0.5)), priv->mouse_lat, priv->mouse_lon);
+
+g_debug("MOUSE: %d,%d (%f,%f)", priv->mouse_x, priv->mouse_y, priv->mouse_lat, priv->mouse_lon);
+
+return FALSE;
+}
+
+static gboolean
+gtk_map_button_press_cb(GtkWidget *widget, GdkEventButton *event)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+switch (event->button) {
+case 1:
+       priv->button_down=TRUE;
+       if (priv->click_to_center) {
+               gtk_map_set_center(widget, x2unit((gint) (event->x+0.5)), y2unit((gint) (event->y+0.5)));
+               return FALSE;
+       } else if (event->type==GDK_2BUTTON_PRESS) {
+               gtk_map_set_center(widget, x2unit((gint) (event->x+0.5)), y2unit((gint) (event->y+0.5)));
+               if (priv->zoom_in_on_2button)
+                       gtk_map_zoom_in(widget);
+               return FALSE;
+       }
+break;
+case 2:
+
+break;
+case 3:
+       if (priv->menu)
+               gtk_menu_popup(GTK_MENU(priv->menu), NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time());
+break;
+}
+return FALSE;
+}
+
+static gboolean
+gtk_map_button_release_cb(GtkWidget *widget, GdkEventButton *event)
+{
+GtkMap *map;
+GtkMapPriv *priv;
+
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+
+switch (event->button) {
+case 1:
+       priv->button_down=FALSE;
+break;
+case 2:
+
+break;
+case 3:
+
+break;
+}
+return FALSE;
+}