--- /dev/null
+/*
+ * MapWidget: Display a map
+ * Copyright (C) 2007 Kaj-Michael Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <glib/gstdio.h>
+#include <glib-object.h>
+#include "gtkmap.h"
+
+G_DEFINE_TYPE(GtkMap, gtk_map, GTK_TYPE_WIDGET);
+
+typedef struct _GtkMapPriv GtkMapPriv;
+
+struct _GtkMapPriv
+{
+PangoContext *context;
+PangoLayout *layout;
+PangoFontDescription *fontdesc;
+};
+
+#define GTK_MAP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_MAP, GtkMapPriv))
+
+#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 + _zoom))
+#define unit2tile(unit) ((unit) >> (8 + _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 + _zoom))
+#define unit2grid(unit) ((unit) >> (5 + _zoom))
+
+#define pixel2unit(pixel) ((pixel) << _zoom)
+#define unit2pixel(pixel) ((pixel) >> _zoom)
+#define pixel2zunit(pixel, zoom) ((pixel) << (zoom))
+
+#define unit2bufx(unit) (unit2pixel(unit) - tile2pixel(_base_tilex))
+#define bufx2unit(x) (pixel2unit(x) + tile2unit(_base_tilex))
+#define unit2bufy(unit) (unit2pixel(unit) - tile2pixel(_base_tiley))
+#define bufy2unit(y) (pixel2unit(y) + tile2unit(_base_tiley))
+
+#define unit2x(unit) (unit2pixel(unit) - tile2pixel(_base_tilex) - _offsetx)
+#define x2unit(x) (pixel2unit(x + _offsetx) + tile2unit(_base_tilex))
+#define unit2y(unit) (unit2pixel(unit) - tile2pixel(_base_tiley) - _offsety)
+#define y2unit(y) (pixel2unit(y + _offsety) + tile2unit(_base_tiley))
+
+#define leadx2unit(mgps) (mgps.unitx + (_lead_ratio) * pixel2unit(mgps.vel_offsetx))
+#define leady2unit(mgps) (mgps.unity + (0.6f*_lead_ratio)*pixel2unit(mgps.vel_offsety))
+
+static void gtk_map_finalize (GObject *object);
+static void gtk_map_size_request (GtkWidget *widget, GtkRequisition *requisition);
+static void gtk_map_size_allocate (GtkWidget *widget, GtkAllocation *allocate);
+static gboolean gtk_map_expose (GtkWidget *widget, GdkEventExpose *event);
+static void gtk_map_realize (GtkWidget *widget);
+static void gtk_map_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gtk_map_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static void
+gtk_map_class_init (GtkMapClass *class)
+{
+GObjectClass *object_class;
+GtkWidgetClass *widget_class;
+
+object_class = (GObjectClass*) class;
+widget_class = (GtkWidgetClass*) class;
+
+object_class->finalize = gtk_map_finalize;
+object_class->set_property = gtk_map_set_property;
+object_class->get_property = gtk_map_get_property;
+
+widget_class->size_request = gtk_map_size_request;
+widget_class->expose_event = gtk_map_expose;
+widget_class->realize = gtk_map_realize;
+widget_class->size_allocate = gtk_map_size_allocate;
+
+g_type_class_add_private (object_class, sizeof (GtkMapPriv));
+}
+
+static void
+gtk_map_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+GtkMap *map;
+g_return_if_fail(GTK_IS_MAP(object));
+map=GTK_MAP(object);
+switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+}
+}
+
+static void
+gtk_map_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+GtkMap *map;
+g_return_if_fail(GTK_IS_MAP(object));
+map=GTK_MAP(object);
+switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+}
+}
+
+static void
+gtk_map_init(GtkMap *map)
+{
+
+}
+
+GtkWidget*
+gtk_map_new(void)
+{
+GtkMap *map;
+GtkWidget *widget;
+
+map=gtk_type_new(gtk_map_get_type ());
+widget=GTK_WIDGET(map);
+map->heading=0;
+
+#if 0
+g_signal_connect(G_OBJECT(widget), "button_press_event", G_CALLBACK(gtk_map_cb_button_press), NULL);
+#endif
+
+return widget;
+}
+
+static void
+gtk_map_finalize(GObject *object)
+{
+GtkMap *map;
+
+g_return_if_fail(GTK_IS_MAP(object));
+map=GTK_MAP(object);
+
+if (GTK_WIDGET(object)->parent && GTK_WIDGET_MAPPED(object)) {
+ gtk_widget_unmap(GTK_WIDGET(object));
+}
+
+G_OBJECT_CLASS(gtk_map_parent_class)->finalize(object);
+}
+
+static void
+gtk_map_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+{
+GtkMap *map;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+map=GTK_MAP(widget);
+}
+
+static void
+gtk_map_size_request(GtkWidget *widget, GtkRequisition *requisition)
+{
+GtkMap *map;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+g_return_if_fail(requisition != NULL);
+
+map=GTK_MAP(widget);
+
+requisition->width=512;
+requisition->height=256;
+map->width=512;
+map->height=256;
+}
+
+static void
+gtk_map_realize (GtkWidget *widget)
+{
+GtkMap *map;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+map=GTK_MAP(widget);
+}
+
+static gboolean
+gtk_map_expose(GtkWidget *widget, GdkEventExpose *event)
+{
+GtkMap *map;
+
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+g_return_val_if_fail(event != NULL, FALSE);
+
+map=GTK_MAP(widget);
+
+return TRUE;
+}
+
+void
+gtk_map_refresh(GtkWidget *widget)
+{
+GtkMap *map;
+
+g_return_if_fail(GTK_IS_MAP(widget));
+
+map=GTK_MAP(widget);
+gtk_widget_queue_draw_area(widget, 0, 0, map->width, map->height);
+}
--- /dev/null
+/*
+ * MapWidget: Display a map
+ * Copyright (C) 2008 Kaj-Michael Lang
+ * Original non-widget map Copyright (C) 2006-2007 John Costigan.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_MAP_H__
+#define __GTK_MAP_H__
+
+#include <gtk/gtk.h>
+#include "path.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+ CENTER_WAS_LATLON = -2,
+ CENTER_WAS_LEAD = -1,
+ CENTER_MANUAL = 0,
+ CENTER_LEAD = 1,
+ CENTER_LATLON = 2
+} GtkMapCenterMode;
+
+#define GTK_MAP_TYPE (gtk_map_get_type ())
+#define GTK_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_MAP_TYPE, GtkMap))
+#define GTK_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_MAP_TYPE, GtkMapClass))
+#define GTK_IS_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_MAP_TYPE))
+
+#define GTK_MAP_TILE_SIZE_PIXELS (256)
+#define GTK_MAP_TILE_SIZE_P2 (8)
+#define GTK_MAP_WORLD_SIZE_UNITS(max_zoom) (2 << (max_zoom + TILE_SIZE_P2))
+
+/* Pans are done two "grids" at a time, or 64 pixels. */
+#define GTK_MAP_PAN_UNITS (grid2unit(2))
+
+#define GTK_MAP_MACRO_RECALC_CENTER(center_mode, center, mgps, center_unitx, center_unity) { \
+ switch(center_mode) { \
+ case CENTER_LEAD: \
+ center_unitx = leadx2unit(mgps); \
+ center_unity = leady2unit(mgps); \
+ break; \
+ case CENTER_LATLON: \
+ center_unitx = mgps.unitx; \
+ center_unity = mgps.unity; \
+ break; \
+ default: \
+ center_unitx = center.unitx; \
+ center_unity = center.unity; \
+ break; \
+ } \
+};
+
+#define GTK_MAP_RECALC_OFFSET(map, center) { \
+ map->offsetx = grid2pixel(unit2grid(center.unitx) - map->screen_grids_halfwidth - tile2grid(map->base_tilex)); \
+ map->offsety = grid2pixel(unit2grid(center.unity) - map->screen_grids_halfheight - tile2grid(map->base_tiley)); \
+}
+
+#define GTK_MAP_RECALC_FOCUS_BASE(map, sens) { \
+ map->focus.unitx = x2unit(map->screen_width_pixels * sens / 20); \
+ map->focus.unity = y2unit(map->screen_height_pixels * sens / 20); \
+}
+
+typedef struct _GtkMap GtkMap;
+typedef struct _GtkMapClass GtkMapClass;
+
+struct _GtkMap {
+ GtkDrawingArea widget;
+
+ GdkGC *gc_h;
+ GdkGC *gc_w;
+ GdkGC *gc_d;
+ guint width, height;
+ guint size;
+ guint xoffset, yoffset;
+
+ PangoContext *context;
+ PangoLayout *layout;
+ PangoFontDescription *fontdesc;
+
+ Point min_center;
+ Point max_center;
+ Point focus;
+
+ /** The "base tile" is the upper-left tile in the pixmap. */
+ guint base_tilex;
+ guint base_tiley;
+
+ Point center; /* current center location, X. */
+ GtkMapCenterMode center_mode;
+ guint lead_ratio;
+ guint center_ratio;
+
+ gfloat heading;
+ gfloat speed;
+
+ guint zoom; /* zoom level, from 0 to MAX_ZOOM. */
+
+ /** The "offset" defines the upper-left corner of the visible portion of the buffer pixmap. */
+ guint offsetx;
+ guint offsety;
+
+ /** CACHED SCREEN INFORMATION THAT IS DEPENDENT ON THE CURRENT VIEW. */
+ guint screen_grids_halfwidth;
+ guint screen_grids_halfheight;
+ guint screen_width_pixels;
+ guint screen_height_pixels;
+
+ guint focus_unitwidth;
+ guint focus_unitheight;
+ guint world_size_tiles;
+
+ gint show_paths;
+ gboolean show_scale;
+ gboolean show_velvec;
+ gboolean show_markers;
+
+ guint draw_width;
+
+ guint key_zoom_new;
+ guint key_zoom_timeout_sid;
+};
+
+struct _GtkMapClass {
+ GtkWidgetClass parent_class;
+};
+
+GType gtk_map_get_type(void);
+GtkWidget* gtk_map_new(void);
+void gtk_map_refresh(GtkWidget *widget);
+
+gboolean gtk_map_key_zoom_timeout(GtkWidget *map);
+
+gint gtk_map_zoom(gint zdir);
+guint gtk_map_get_zoom(GtkWidget *map);
+gboolean gtk_map_set_zoom(guint zoom);
+
+gboolean gtk_map_zoom_in(GtkWidget *map);
+gboolean gtk_map_zoom_out(GtkWidget *map);
+void gtk_map_set_autozoom(GtkWidget *map, gboolean az, gfloat speed);
+void gtk_map_render_path(Path *path, GdkGC ** gc);
+void gtk_map_pan(GtkWidget *map, gint delta_unitx, gint delta_unity);
+void gtk_map_move_mark(GtkWidget *map);
+void gtk_map_set_mark(GtkWidget *map);
+void gtk_map_render_data(GtkWidget *map);
+gboolean gtk_map_render_tile(GtkWidget *map, guint tilex, guint tiley, guint destx, guint desty, gboolean fast_fail);
+
+void gtk_map_render_waypoint(GtkWidget *map, guint x1, guint y1, GdkGC *gc);
+void gtk_map_render_paths(GtkWidget *map);
+void gtk_map_force_redraw(GtkWidget *map);
+void gtk_map_draw_position_icon(GtkWidget *map, Position *pos, const gchar *icon);
+GdkPixmap *gtk_map_pixmap_get(GtkWidget *map);
+
+void gtk_map_center_unit(GtkWidget *map, guint new_center_unitx, guint new_center_unity);
+void gtk_map_center_latlon(GtkWidget *map, gdouble lat, gdouble lon);
+
+gboolean gtk_map_goto_position(GtkWidget *map, Position *pos);
+gboolean gtk_map_update_location_from_center(GtkWidget *map);
+
+G_END_DECLS
+
+#endif /* __GTK_MAP_H__ */