X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/657bb8fc94acd80433435209eedb03a80189aeb9..9e4fdfe4455bace71d5b7cceb3988b8dfc48964a:/src/viklayer.c diff --git a/src/viklayer.c b/src/viklayer.c index 1cd70cbe..1f30ca2a 100644 --- a/src/viklayer.c +++ b/src/viklayer.c @@ -3,6 +3,7 @@ * * Copyright (C) 2005, Alex Foobarian * Copyright (C) 2003-2007, Evan Battaglia + * Copyright (C) 2013, Rob Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,6 +42,9 @@ extern VikLayerInterface vik_coord_layer_interface; extern VikLayerInterface vik_georef_layer_interface; extern VikLayerInterface vik_gps_layer_interface; extern VikLayerInterface vik_dem_layer_interface; +#ifdef HAVE_LIBMAPNIK +extern VikLayerInterface vik_mapnik_layer_interface; +#endif enum { VL_UPDATE_SIGNAL, @@ -92,10 +96,15 @@ static gboolean idle_draw ( VikLayer *vl ) void vik_layer_emit_update ( VikLayer *vl ) { if ( vl->visible && vl->realized ) { + GThread *thread = vik_window_get_thread ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vl)) ); + if ( !thread ) + // Do nothing + return; + vik_window_set_redraw_trigger(vl); // Only ever draw when there is time to do so - if ( g_thread_self() != vik_window_get_thread (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vl))) ) + if ( g_thread_self() != thread ) // Drawing requested from another (background) thread, so handle via the gdk thread method gdk_threads_add_idle ( (GSourceFunc) idle_draw, vl ); else @@ -130,6 +139,9 @@ static VikLayerInterface *vik_layer_interfaces[VIK_LAYER_NUM_TYPES] = { &vik_gps_layer_interface, &vik_maps_layer_interface, &vik_dem_layer_interface, +#ifdef HAVE_LIBMAPNIK + &vik_mapnik_layer_interface, +#endif }; VikLayerInterface *vik_layer_get_interface ( VikLayerTypeEnum type ) @@ -202,7 +214,14 @@ const gchar *vik_layer_get_name ( VikLayer *l ) return l->name; } -VikLayer *vik_layer_create ( VikLayerTypeEnum type, gpointer vp, GtkWindow *w, gboolean interactive ) +time_t vik_layer_get_timestamp ( VikLayer *vl ) +{ + if ( vik_layer_interfaces[vl->type]->get_timestamp ) + return vik_layer_interfaces[vl->type]->get_timestamp ( vl ); + return 0; +} + +VikLayer *vik_layer_create ( VikLayerTypeEnum type, VikViewport *vp, gboolean interactive ) { VikLayer *new_layer = NULL; g_assert ( type < VIK_LAYER_NUM_TYPES ); @@ -227,18 +246,18 @@ VikLayer *vik_layer_create ( VikLayerTypeEnum type, gpointer vp, GtkWindow *w, g } /* returns TRUE if OK was pressed */ -gboolean vik_layer_properties ( VikLayer *layer, gpointer vp ) +gboolean vik_layer_properties ( VikLayer *layer, VikViewport *vp ) { if ( vik_layer_interfaces[layer->type]->properties ) return vik_layer_interfaces[layer->type]->properties ( layer, vp ); return vik_layer_properties_factory ( layer, vp ); } -void vik_layer_draw ( VikLayer *l, gpointer data ) +void vik_layer_draw ( VikLayer *l, VikViewport *vp ) { if ( l->visible ) if ( vik_layer_interfaces[l->type]->draw ) - vik_layer_interfaces[l->type]->draw ( l, data ); + vik_layer_interfaces[l->type]->draw ( l, vp ); } void vik_layer_change_coord_mode ( VikLayer *l, VikCoordMode mode ) @@ -248,7 +267,7 @@ void vik_layer_change_coord_mode ( VikLayer *l, VikCoordMode mode ) } typedef struct { - gint layer_type; + VikLayerTypeEnum layer_type; gint len; guint8 data[0]; } header_t; @@ -284,8 +303,11 @@ void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen ) g_byte_array_append ( b, (guint8 *)&len, sizeof(len) ); \ g_byte_array_append ( b, (guint8 *)(obj), len ); + // Store the internal properties first + vlm_append(&vl->visible, sizeof(vl->visible)); vlm_append(vl->name, strlen(vl->name)); + // Now the actual parameters if ( params && get_param ) { VikLayerParamData d; @@ -296,10 +318,16 @@ void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen ) d = get_param(vl, i, FALSE); switch ( params[i].type ) { - case VIK_LAYER_PARAM_STRING: - vlm_append(d.s, strlen(d.s)); - break; - + case VIK_LAYER_PARAM_STRING: + // Remember need braces as these are macro calls, not single statement functions! + if ( d.s ) { + vlm_append(d.s, strlen(d.s)); + } + else { + // Need to insert empty string otherwise the unmarshall will get confused + vlm_append("", 0); + } + break; /* print out the string list in the array */ case VIK_LAYER_PARAM_STRING_LIST: { GList *list = d.sl; @@ -342,13 +370,13 @@ void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, Vik #define vlm_read(obj) \ memcpy((obj), b+sizeof(gint), vlm_size); \ b += sizeof(gint) + vlm_size; - + + vlm_read(&vl->visible); + s = g_malloc(vlm_size + 1); s[vlm_size]=0; vlm_read(s); - vik_layer_rename(vl, s); - g_free(s); if ( params && set_param ) @@ -525,7 +553,8 @@ static gboolean vik_layer_properties_factory ( VikLayer *vl, VikViewport *vp ) vl, vp, (gpointer) vik_layer_interfaces[vl->type]->get_param, - vl) ) { + vl, + (gpointer) vik_layer_interfaces[vl->type]->change_param ) ) { case 0: case 3: return FALSE; @@ -624,6 +653,8 @@ VikLayerTypedParamData *vik_layer_data_typed_param_copy_from_string ( VikLayerPa */ void vik_layer_set_defaults ( VikLayer *vl, VikViewport *vvp ) { + // Sneaky initialize of the viewport value here + vl->vvp = vvp; VikLayerInterface *vli = vik_layer_get_interface ( vl->type ); const gchar *layer_name = vli->fixed_layer_name; VikLayerParamData data; @@ -636,7 +667,7 @@ void vik_layer_set_defaults ( VikLayer *vl, VikViewport *vvp ) // only DEM files uses this currently if ( vli->params[i].type != VIK_LAYER_PARAM_STRING_LIST ) { data = a_layer_defaults_get ( layer_name, vli->params[i].name, vli->params[i].type ); - vik_layer_set_param ( vl, i, data, vvp, FALSE ); + vik_layer_set_param ( vl, i, data, vvp, TRUE ); // Possibly come from a file } } }