[libchamplain] Introduce ChamplainLayer - a base class of all layers



commit dcb5fb15ca055e5c25218fcaa309f9db235b5303
Author: JiÅ?í Techet <techet gmail com>
Date:   Sun Jan 30 14:52:14 2011 +0100

    Introduce ChamplainLayer - a base class of all layers

 champlain/Makefile.am              |    2 +
 champlain/champlain-layer.c        |   61 +++++++++++++++++++++++++
 champlain/champlain-layer.h        |   72 +++++++++++++++++++++++++++++
 champlain/champlain-marker-layer.c |   29 ++++++++----
 champlain/champlain-marker-layer.h |    8 +--
 champlain/champlain-view.c         |   88 +++---------------------------------
 champlain/champlain-view.h         |   11 +---
 champlain/champlain.h              |    1 +
 demos/animated-marker.c            |    2 +-
 demos/launcher-gtk.c               |    9 ++--
 demos/launcher.c                   |    9 ++--
 demos/polygons.c                   |    4 +-
 demos/url-marker.c                 |    2 +-
 13 files changed, 182 insertions(+), 116 deletions(-)
---
diff --git a/champlain/Makefile.am b/champlain/Makefile.am
index e81153d..c573d1e 100644
--- a/champlain/Makefile.am
+++ b/champlain/Makefile.am
@@ -16,6 +16,7 @@ libchamplain_headers_public = 				\
 	$(srcdir)/champlain-defines.h			\
 	$(srcdir)/champlain-point.h			\
 	$(srcdir)/champlain-view.h			\
+	$(srcdir)/champlain-layer.h 			\
 	$(srcdir)/champlain-marker-layer.h 			\
 	$(srcdir)/champlain-marker.h		\
 	$(srcdir)/champlain-label.h			\
@@ -51,6 +52,7 @@ libchamplain_sources =					\
 	$(memphis_sources)				\
 	$(srcdir)/champlain-debug.c 			\
 	$(srcdir)/champlain-view.c 			\
+	$(srcdir)/champlain-layer.c 			\
 	$(srcdir)/champlain-marker-layer.c 			\
 	$(srcdir)/champlain-marker.c 		\
 	$(srcdir)/champlain-label.c 			\
diff --git a/champlain/champlain-layer.c b/champlain/champlain-layer.c
new file mode 100644
index 0000000..2bff295
--- /dev/null
+++ b/champlain/champlain-layer.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 Jiri Techet <techet gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "champlain-layer.h"
+
+G_DEFINE_TYPE (ChamplainLayer, champlain_layer, CLUTTER_TYPE_GROUP)
+
+static void
+champlain_layer_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (champlain_layer_parent_class)->dispose (object);
+}
+
+
+static void
+champlain_layer_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (champlain_layer_parent_class)->finalize (object);
+}
+
+
+static void
+champlain_layer_class_init (ChamplainLayerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = champlain_layer_finalize;
+  object_class->dispose = champlain_layer_dispose;
+
+  klass->set_view = NULL;
+}
+
+
+void champlain_layer_set_view (ChamplainLayer *layer,
+    ChamplainView *view)
+{
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
+
+  CHAMPLAIN_LAYER_GET_CLASS (layer)->set_view (layer, view);
+}
+
+
+static void
+champlain_layer_init (ChamplainLayer *self)
+{
+}
diff --git a/champlain/champlain-layer.h b/champlain/champlain-layer.h
new file mode 100644
index 0000000..6100b2c
--- /dev/null
+++ b/champlain/champlain-layer.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 Jiri Techet <techet gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (__CHAMPLAIN_CHAMPLAIN_H_INSIDE__) && !defined (CHAMPLAIN_COMPILATION)
+#error "Only <champlain/champlain.h> can be included directly."
+#endif
+
+#ifndef __CHAMPLAIN_LAYER_H__
+#define __CHAMPLAIN_LAYER_H__
+
+#include <clutter/clutter.h>
+#include <champlain/champlain-defines.h>
+
+G_BEGIN_DECLS
+
+#define CHAMPLAIN_TYPE_LAYER champlain_layer_get_type ()
+
+#define CHAMPLAIN_LAYER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHAMPLAIN_TYPE_LAYER, ChamplainLayer))
+
+#define CHAMPLAIN_LAYER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), CHAMPLAIN_TYPE_LAYER, ChamplainLayerClass))
+
+#define CHAMPLAIN_IS_LAYER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHAMPLAIN_TYPE_LAYER))
+
+#define CHAMPLAIN_IS_LAYER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), CHAMPLAIN_TYPE_LAYER))
+
+#define CHAMPLAIN_LAYER_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), CHAMPLAIN_TYPE_LAYER, ChamplainLayerClass))
+
+typedef struct _ChamplainLayer ChamplainLayer;
+typedef struct _ChamplainLayerClass ChamplainLayerClass;
+
+struct _ChamplainLayer
+{
+  ClutterGroup parent;
+};
+
+struct _ChamplainLayerClass
+{
+  ClutterGroupClass parent_class;
+
+  void (*set_view)(ChamplainLayer *layer,
+      ChamplainView *view);
+};
+
+GType champlain_layer_get_type (void);
+
+
+void champlain_layer_set_view (ChamplainLayer *layer,
+    ChamplainView *view);
+
+G_END_DECLS
+
+#endif /* __CHAMPLAIN_LAYER_H__ */
diff --git a/champlain/champlain-marker-layer.c b/champlain/champlain-marker-layer.c
index 0542bac..70279e4 100644
--- a/champlain/champlain-marker-layer.c
+++ b/champlain/champlain-marker-layer.c
@@ -39,7 +39,7 @@
 #include <clutter/clutter.h>
 #include <glib.h>
 
-G_DEFINE_TYPE (ChamplainMarkerLayer, champlain_marker_layer, CLUTTER_TYPE_GROUP)
+G_DEFINE_TYPE (ChamplainMarkerLayer, champlain_marker_layer, CHAMPLAIN_TYPE_LAYER)
 
 #define GET_PRIVATE(obj)    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CHAMPLAIN_TYPE_MARKER_LAYER, ChamplainMarkerLayerPrivate))
 
@@ -90,6 +90,9 @@ static void marker_highlighted_cb (ChamplainMarker *marker,
     
 static void redraw_polygon (ChamplainMarkerLayer *layer);
 
+static void set_view (ChamplainLayer *layer,
+    ChamplainView *view);
+
 
 static void
 champlain_marker_layer_get_property (GObject *object,
@@ -205,7 +208,7 @@ champlain_marker_layer_dispose (GObject *object)
   
   if (priv->view != NULL)
     {
-      champlain_marker_layer_set_view (self, NULL);
+      set_view (CHAMPLAIN_LAYER (self), NULL);
     }
 
   G_OBJECT_CLASS (champlain_marker_layer_parent_class)->dispose (object);
@@ -229,6 +232,7 @@ static void
 champlain_marker_layer_class_init (ChamplainMarkerLayerClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ChamplainLayerClass *layer_class = CHAMPLAIN_LAYER_CLASS (klass);
 
   g_type_class_add_private (klass, sizeof (ChamplainMarkerLayerPrivate));
   
@@ -237,6 +241,8 @@ champlain_marker_layer_class_init (ChamplainMarkerLayerClass *klass)
   object_class->get_property = champlain_marker_layer_get_property;
   object_class->set_property = champlain_marker_layer_set_property;
   
+  layer_class->set_view = set_view;
+  
   /**
    * ChamplainMarkerLayer:selection-mode:
    *
@@ -936,19 +942,22 @@ redraw_polygon_cb (G_GNUC_UNUSED GObject *gobject,
 }
 
 
-void champlain_marker_layer_set_view (ChamplainMarkerLayer *layer,
+static void 
+set_view (ChamplainLayer *layer,
     ChamplainView *view)
 {
   g_return_if_fail (CHAMPLAIN_IS_MARKER_LAYER (layer) && (CHAMPLAIN_IS_VIEW (view) || view == NULL));
   
-  if (layer->priv->view != NULL)
+  ChamplainMarkerLayer *marker_layer = CHAMPLAIN_MARKER_LAYER (layer);
+  
+  if (marker_layer->priv->view != NULL)
     {
-      g_signal_handlers_disconnect_by_func (layer->priv->view,
-        G_CALLBACK (relocate_cb), layer);
-      g_object_unref (layer->priv->view);
+      g_signal_handlers_disconnect_by_func (marker_layer->priv->view,
+        G_CALLBACK (relocate_cb), marker_layer);
+      g_object_unref (marker_layer->priv->view);
     }
   
-  layer->priv->view = view;
+  marker_layer->priv->view = view;
 
   if (view != NULL)
     {
@@ -960,8 +969,8 @@ void champlain_marker_layer_set_view (ChamplainMarkerLayer *layer,
       g_signal_connect (view, "notify::latitude",
         G_CALLBACK (redraw_polygon_cb), layer);
         
-      relocate (layer);
-      redraw_polygon (layer);
+      relocate (marker_layer);
+      redraw_polygon (marker_layer);
     }
 }
 
diff --git a/champlain/champlain-marker-layer.h b/champlain/champlain-marker-layer.h
index c87c5ed..63c9ab1 100644
--- a/champlain/champlain-marker-layer.h
+++ b/champlain/champlain-marker-layer.h
@@ -25,6 +25,7 @@
 
 #include <champlain/champlain-defines.h>
 #include <champlain/champlain-marker.h>
+#include <champlain/champlain-layer.h>
 
 #include <glib-object.h>
 #include <clutter/clutter.h>
@@ -70,14 +71,14 @@ typedef enum
 
 struct _ChamplainMarkerLayer
 {
-  ClutterGroup parent;
+  ChamplainLayer parent;
   
   ChamplainMarkerLayerPrivate *priv;
 };
 
 struct _ChamplainMarkerLayerClass
 {
-  ClutterGroupClass parent_class;
+  ChamplainLayerClass parent_class;
 };
 
 GType champlain_marker_layer_get_type (void);
@@ -89,9 +90,6 @@ void champlain_marker_layer_add_marker (ChamplainMarkerLayer *layer,
 void champlain_marker_layer_remove_marker (ChamplainMarkerLayer *layer,
     ChamplainMarker *marker);
 
-void champlain_marker_layer_set_view (ChamplainMarkerLayer *layer,
-    ChamplainView *view);
-
 void champlain_marker_layer_animate_in_all_markers (ChamplainMarkerLayer *layer);
 void champlain_marker_layer_animate_out_all_markers (ChamplainMarkerLayer *layer);
 
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 6efb477..c1f8974 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -42,8 +42,7 @@
  * an error occurs during download, an error tile will be displayed.
  *
  * The button-press-event and button-release-event signals are emitted each
- * time a mouse button is pressed on the @view.  Coordinates can be converted
- * with #champlain_view_get_coords_from_event.
+ * time a mouse button is pressed on the @view.  
  */
 
 #include "config.h"
@@ -1440,7 +1439,8 @@ finger_scroll_button_press_cb (G_GNUC_UNUSED ClutterActor *actor,
     {
       gdouble lon, lat;
 
-      champlain_view_get_coords_from_event (view, (ClutterEvent *) event, &lat, &lon);
+      lon = champlain_view_x_to_longitude (view, event->x);
+      lat = champlain_view_y_to_latitude (view, event->y);
 
       champlain_view_stop_go_to (view);
 
@@ -1990,7 +1990,7 @@ champlain_view_set_max_zoom_level (ChamplainView *view,
  */
 void
 champlain_view_add_layer (ChamplainView *view,
-    ChamplainMarkerLayer *layer)
+    ChamplainLayer *layer)
 {
   DEBUG_LOG ()
 
@@ -1999,7 +1999,7 @@ champlain_view_add_layer (ChamplainView *view,
   
   clutter_container_add_actor (CLUTTER_CONTAINER (view->priv->user_layers),
       CLUTTER_ACTOR (layer));
-  champlain_marker_layer_set_view (layer, view);
+  champlain_layer_set_view (layer, view);
   clutter_actor_raise_top (CLUTTER_ACTOR (layer));
 }
 
@@ -2015,94 +2015,20 @@ champlain_view_add_layer (ChamplainView *view,
  */
 void
 champlain_view_remove_layer (ChamplainView *view,
-    ChamplainMarkerLayer *layer)
+    ChamplainLayer *layer)
 {
   DEBUG_LOG ()
 
   g_return_if_fail (CHAMPLAIN_IS_VIEW (view));
   g_return_if_fail (CHAMPLAIN_IS_MARKER_LAYER (layer));
 
-  champlain_marker_layer_set_view (layer, NULL);      
+  champlain_layer_set_view (layer, NULL);      
 
   clutter_container_remove_actor (CLUTTER_CONTAINER (view->priv->user_layers),
       CLUTTER_ACTOR (layer));
 }
 
 
-/**
- * champlain_view_get_coords_from_event:
- * @view: a #ChamplainView
- * @event: a #ClutterEvent
- * @lat: (out): a variable where to put the latitude of the event
- * @lon: (out): a variable where to put the longitude of the event
- *
- * Gets coordinates from button-press-event and button-release-event signals.
- *
- * Returns: the latitude, longitude coordinates for the given ClutterEvent.
- *
- * Since: 0.2.8
- */
-gboolean
-champlain_view_get_coords_from_event (ChamplainView *view,
-    ClutterEvent *event,
-    gdouble *lat,
-    gdouble *lon)
-{
-  DEBUG_LOG ()
-
-  g_return_val_if_fail (CHAMPLAIN_IS_VIEW (view), FALSE);
-  /* Apparently there isn a more precise test */
-  g_return_val_if_fail (event, FALSE);
-
-  guint x, y;
-
-  switch (clutter_event_type (event))
-    {
-    case CLUTTER_BUTTON_PRESS:
-    case CLUTTER_BUTTON_RELEASE:
-      {
-        ClutterButtonEvent *e = (ClutterButtonEvent *) event;
-        x = e->x;
-        y = e->y;
-      }
-      break;
-
-    case CLUTTER_SCROLL:
-      {
-        ClutterScrollEvent *e = (ClutterScrollEvent *) event;
-        x = e->x;
-        y = e->y;
-      }
-      break;
-
-    case CLUTTER_MOTION:
-      {
-        ClutterMotionEvent *e = (ClutterMotionEvent *) event;
-        x = e->x;
-        y = e->y;
-      }
-      break;
-
-    case CLUTTER_ENTER:
-    case CLUTTER_LEAVE:
-      {
-        ClutterCrossingEvent *e = (ClutterCrossingEvent *) event;
-        x = e->x;
-        y = e->y;
-      }
-      break;
-
-    default:
-      return FALSE;
-    }
-
-  *lon = champlain_view_x_to_longitude (view, x);
-  *lat = champlain_view_y_to_latitude (view, y);
-  
-  return TRUE;
-}
-
-
 gdouble
 champlain_view_x_to_longitude (ChamplainView *view,
     gdouble x)
diff --git a/champlain/champlain-view.h b/champlain/champlain-view.h
index 5bb7a41..4b0d98c 100644
--- a/champlain/champlain-view.h
+++ b/champlain/champlain-view.h
@@ -25,7 +25,7 @@
 #define CHAMPLAIN_VIEW_H
 
 #include <champlain/champlain-defines.h>
-#include <champlain/champlain-marker-layer.h>
+#include <champlain/champlain-layer.h>
 #include <champlain/champlain-map-source.h>
 
 #include <glib.h>
@@ -142,14 +142,9 @@ void champlain_view_set_zoom_on_double_click (ChamplainView *view,
     gboolean value);
 
 void champlain_view_add_layer (ChamplainView *view,
-    ChamplainMarkerLayer *layer);
+    ChamplainLayer *layer);
 void champlain_view_remove_layer (ChamplainView *view,
-    ChamplainMarkerLayer *layer);
-
-gboolean champlain_view_get_coords_from_event (ChamplainView *view,
-    ClutterEvent *event,
-    gdouble *lat,
-    gdouble *lon);
+    ChamplainLayer *layer);
 
 
 gint champlain_view_get_zoom_level (ChamplainView *view);
diff --git a/champlain/champlain.h b/champlain/champlain.h
index 2eda294..d4a9324 100644
--- a/champlain/champlain.h
+++ b/champlain/champlain.h
@@ -29,6 +29,7 @@
 #include "champlain/champlain-enum-types.h"
 #include "champlain/champlain-version.h"
 
+#include "champlain/champlain-layer.h"
 #include "champlain/champlain-marker-layer.h"
 #include "champlain/champlain-point.h"
 #include "champlain/champlain-marker.h"
diff --git a/demos/animated-marker.c b/demos/animated-marker.c
index 933f50e..b79a47c 100644
--- a/demos/animated-marker.c
+++ b/demos/animated-marker.c
@@ -137,7 +137,7 @@ main (int argc, char *argv[])
   /* Create the marker layer */
   layer = champlain_marker_layer_new_full (CHAMPLAIN_SELECTION_SINGLE);
   clutter_actor_show (CLUTTER_ACTOR (layer));
-  champlain_view_add_layer (CHAMPLAIN_VIEW (actor), layer);
+  champlain_view_add_layer (CHAMPLAIN_VIEW (actor), CHAMPLAIN_LAYER (layer));
 
   /* Create a marker */
   marker = create_marker ();
diff --git a/demos/launcher-gtk.c b/demos/launcher-gtk.c
index 2d0f6e0..e2f8b24 100644
--- a/demos/launcher-gtk.c
+++ b/demos/launcher-gtk.c
@@ -62,11 +62,12 @@ toggle_layer (GtkToggleButton *widget,
 
 
 gboolean
-mouse_click_cb (ClutterActor *actor, ClutterEvent *event, gpointer data)
+mouse_click_cb (ClutterActor *actor, ClutterButtonEvent *event, ChamplainView *view)
 {
   gdouble lat, lon;
 
-  champlain_view_get_coords_from_event (CHAMPLAIN_VIEW (data), event, &lat, &lon);
+  lon = champlain_view_x_to_longitude (view, event->x);
+  lat = champlain_view_y_to_latitude (view, event->y);
   g_print ("Mouse click at: %f  %f\n", lat, lon);
 
   return TRUE;
@@ -257,7 +258,7 @@ main (int argc,
   champlain_view_center_on (CHAMPLAIN_VIEW (view), 45.466, -73.75);
 
   layer = create_marker_layer (view);
-  champlain_view_add_layer (view, layer);
+  champlain_view_add_layer (view, CHAMPLAIN_LAYER (layer));
 
   polygon = champlain_marker_layer_new_full (CHAMPLAIN_SELECTION_NONE);
   /* Cheap approx of Highway 10 */
@@ -273,7 +274,7 @@ main (int argc,
   champlain_marker_layer_set_polygon_stroke_width (polygon, 5.0);
   champlain_marker_layer_hide_all_markers (polygon);
   champlain_marker_layer_hide_polygon (polygon);
-  champlain_view_add_layer (view, polygon);
+  champlain_view_add_layer (view, CHAMPLAIN_LAYER (polygon));
 
   gtk_widget_set_size_request (widget, 640, 480);
 
diff --git a/demos/launcher.c b/demos/launcher.c
index 089a50a..2f31734 100644
--- a/demos/launcher.c
+++ b/demos/launcher.c
@@ -31,9 +31,10 @@ map_view_button_release_cb (G_GNUC_UNUSED ClutterActor *actor,
   if (event->button != 1 || event->click_count > 1)
     return FALSE;
 
-  if (champlain_view_get_coords_from_event (view, (ClutterEvent *) event, &lat,
-          &lon))
-    g_print ("Map clicked at %f, %f \n", lat, lon);
+  lon = champlain_view_x_to_longitude (view, event->x);
+  lat = champlain_view_y_to_latitude (view, event->y);
+
+  g_print ("Map clicked at %f, %f \n", lat, lon);
 
   return TRUE;
 }
@@ -130,7 +131,7 @@ main (int argc,
 
   /* Create the markers and marker layer */
   layer = create_marker_layer (CHAMPLAIN_VIEW (actor));
-  champlain_view_add_layer (CHAMPLAIN_VIEW (actor), layer);
+  champlain_view_add_layer (CHAMPLAIN_VIEW (actor), CHAMPLAIN_LAYER (layer));
 
   /* Connect to the click event */
   clutter_actor_set_reactive (actor, TRUE);
diff --git a/demos/polygons.c b/demos/polygons.c
index 7228bb1..f48d988 100644
--- a/demos/polygons.c
+++ b/demos/polygons.c
@@ -136,7 +136,7 @@ main (int argc,
   champlain_marker_layer_set_polygon_stroke_width (layer, 5.0);
   champlain_marker_layer_hide_all_markers (layer);
   champlain_marker_layer_show_polygon (layer);
-  champlain_view_add_layer (CHAMPLAIN_VIEW (actor), layer);
+  champlain_view_add_layer (CHAMPLAIN_VIEW (actor), CHAMPLAIN_LAYER (layer));
 
   /* draw a polygon */
   layer = champlain_marker_layer_new_full (CHAMPLAIN_SELECTION_NONE);
@@ -149,7 +149,7 @@ main (int argc,
   g_object_set (layer, "fill", TRUE, NULL);
   champlain_marker_layer_hide_all_markers (layer);
   champlain_marker_layer_show_polygon (layer);
-  champlain_view_add_layer (CHAMPLAIN_VIEW (actor), layer);
+  champlain_view_add_layer (CHAMPLAIN_VIEW (actor), CHAMPLAIN_LAYER (layer));
 
   /* Finish initialising the map view */
   g_object_set (G_OBJECT (actor), "zoom-level", 8,
diff --git a/demos/url-marker.c b/demos/url-marker.c
index 55a03eb..1cf6bc4 100644
--- a/demos/url-marker.c
+++ b/demos/url-marker.c
@@ -257,7 +257,7 @@ main (int argc, char *argv[])
 
   /* Create the markers and marker layer */
   layer = champlain_marker_layer_new_full (CHAMPLAIN_SELECTION_SINGLE);
-  champlain_view_add_layer (CHAMPLAIN_VIEW (view), layer);
+  champlain_view_add_layer (CHAMPLAIN_VIEW (view), CHAMPLAIN_LAYER (layer));
   session = soup_session_async_new ();
   create_marker_from_url (layer, session, 48.218611, 17.146397,
       "http://hexten.net/cpan-faces/potyl.jpg";);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]