maemo_mapper_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS) $(HILDON_CFLAGS) $(GNOME_VFS_CFLAGS) $(GCONF_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE_CFLAGS) $(CONIC_CFLAGS)
-maemo_mapper_LDADD = $(GTK_LIBS) $(OSSO_LIBS) $(HILDON_LIBS) $(GNOME_VFS_LIBS) $(GCONF_LIBS) $(LIBXML2_LIBS) $(SQLITE_LIBS) $(CONIC_LIBS) -lgdbm
+maemo_mapper_LDADD = $(GTK_LIBS) $(OSSO_LIBS) $(HILDON_LIBS) $(GNOME_VFS_LIBS) $(GCONF_LIBS) $(LIBXML2_LIBS) $(SQLITE_LIBS) $(CONIC_LIBS)
maemo_mapper_SOURCES = \
cmenu.c \
data.c \
+ dbus-ifc.c \
display.c \
gdk-pixbuf-rotate.c \
gps.c \
+ gpsbt.c \
gpx.c \
input.c \
main.c \
#ifndef MAEMO_MAPPER_CMENU
#define MAEMO_MAPPER_CMENU
-void cmenu_init();
+void cmenu_init(void);
#endif /* ifndef MAEMO_MAPPER_CMENU */
GpsSatelliteData _gps_sat[12];
gboolean _satdetails_on = FALSE;
+gboolean _is_first_time = FALSE;
+
/** VARIABLES FOR MAINTAINING STATE OF THE CURRENT VIEW. */
gint _screen_halfwidth_pixels = 0;
gint _screen_halfheight_pixels = 0;
-
/** The current track and route. */
Path _track;
Path _route;
extern GpsSatelliteData _gps_sat[12];
extern gboolean _satdetails_on;
+extern gboolean _is_first_time;
+
/** VARIABLES FOR MAINTAINING STATE OF THE CURRENT VIEW. */
--- /dev/null
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <libosso.h>
+#include <glib.h>
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "display.h"
+#include "dbus-ifc.h"
+
+static gint
+dbus_ifc_cb_default(const gchar *interface, const gchar *method,
+ GArray *args, gpointer data, osso_rpc_t *retval)
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if(!strcmp(method, "top_application"))
+ {
+ g_idle_add((GSourceFunc)window_present, NULL);
+ }
+
+ retval->type = DBUS_TYPE_INVALID;
+
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return OSSO_OK;
+}
+
+static gboolean
+dbus_ifc_set_view_center_idle(SetViewCenterArgs *args)
+{
+ Point center;
+ printf("%s(%f, %f, %d)\n", __PRETTY_FUNCTION__,
+ args->lat, args->lon, args->zoom);
+
+ latlon2unit(args->lat, args->lon, center.unitx, center.unity);
+
+ map_center_unit_full(center, args->zoom,
+ _center_mode > 0 && _center_rotate
+ ? _gps.heading : _next_map_rotate_angle);
+
+ g_free(args);
+
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+}
+
+static gint
+dbus_ifc_handle_set_view_center(GArray *args, osso_rpc_t *retval)
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
+ SetViewCenterArgs *svca = g_new(SetViewCenterArgs, 1);
+
+ /* Argument 1: double: latitude. */
+ if(args->len >= 1
+ && g_array_index(args, osso_rpc_t, 0).type == DBUS_TYPE_DOUBLE)
+ {
+ svca->lat = CLAMP(g_array_index(args, osso_rpc_t, 0).value.d,
+ -90.0, 90.0);
+ }
+ else
+ {
+ gdouble tmp;
+ unit2latlon(_center.unitx, _center.unity, svca->lat, tmp);
+ }
+
+ /* Argument 2: double: longitude. */
+ if(args->len >= 2
+ && g_array_index(args, osso_rpc_t, 1).type == DBUS_TYPE_DOUBLE)
+ {
+ svca->lon = CLAMP(g_array_index(args, osso_rpc_t, 1).value.d,
+ -180.0, 180.0);
+ }
+ else
+ {
+ gdouble tmp;
+ unit2latlon(_center.unitx, _center.unity, tmp, svca->lon);
+ }
+
+ /* Argument 2 (optional): int: zoom. */
+ if(args->len >= 3
+ && g_array_index(args, osso_rpc_t, 2).type == DBUS_TYPE_INT32)
+ {
+ svca->zoom = CLAMP(g_array_index(args, osso_rpc_t, 2).value.i,
+ MIN_ZOOM, MAX_ZOOM);
+ }
+ else
+ svca->zoom = _zoom;
+
+ g_idle_add((GSourceFunc)dbus_ifc_set_view_center_idle, svca);
+ retval->type = DBUS_TYPE_INVALID;
+
+ vprintf("%s(): return OSSO_OK\n", __PRETTY_FUNCTION__);
+ return OSSO_OK;
+}
+
+static gint
+dbus_ifc_controller(const gchar *interface, const gchar *method,
+ GArray *args, gpointer data, osso_rpc_t *retval)
+{
+ printf("%s(%s)\n", __PRETTY_FUNCTION__, method);
+
+ /* Method: set_view_center */
+ if(!strcmp(method, MM_DBUS_METHOD_SET_VIEW_CENTER))
+ return dbus_ifc_handle_set_view_center(args, retval);
+
+ vprintf("%s(): return OSSO_ERROR\n", __PRETTY_FUNCTION__);
+ return OSSO_ERROR;
+}
+
+void
+dbus_ifc_init()
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if(OSSO_OK != osso_rpc_set_default_cb_f(_osso, dbus_ifc_cb_default, NULL))
+ g_printerr("osso_rpc_set_default_cb_f failed.\n");
+
+ if(OSSO_OK != osso_rpc_set_cb_f(_osso, MM_DBUS_SERVICE,
+ MM_DBUS_PATH, MM_DBUS_INTERFACE, dbus_ifc_controller, NULL))
+ g_printerr("osso_rpc_set_cb_f failed.\n");
+
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
--- /dev/null
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_DBUS_H
+#define MAEMO_MAPPER_DBUS_H
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+
+#define MM_DBUS_SERVICE "com.gnuite.maemo_mapper"
+#define MM_DBUS_PATH "/com/gnuite/maemo_mapper"
+#define MM_DBUS_INTERFACE "com.gnuite.maemo_mapper"
+
+#define MM_DBUS_METHOD_SET_VIEW_CENTER "set_view_center"
+typedef struct _SetViewCenterArgs SetViewCenterArgs;
+struct _SetViewCenterArgs
+{
+ gdouble lat;
+ gdouble lon;
+ gint zoom; /* Optional - omit to keep zoom the same. */
+};
+
+void dbus_ifc_init(void);
+
+#endif /* ifndef MAEMO_MAPPER_GPS_H */
#define BUFFER_SIZE (2048)
+#define GPSD_PORT_DEFAULT (2947)
+
#define NUM_DOWNLOAD_THREADS (4)
#define MAX_PIXBUF_DUP_SIZE (137)
#define WORLD_SIZE_UNITS (2 << (MAX_ZOOM + TILE_SIZE_P2))
if(!been_here++)
{
/* Set connection state first, to avoid going into this if twice. */
- if(_gri.type == GPS_RCVR_NONE && _enable_gps)
+ if(_is_first_time)
{
GtkWidget *confirm;
if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
ossohelp_show(_osso, HELP_ID_INTRO, 0);
gtk_widget_destroy(confirm);
- if(settings_dialog())
+
+ /* Present the settings dialog. */
+ settings_dialog();
+ popup_error(_window,
+ _("OpenStreetMap.org provides public, free-to-use maps. "
+ "You can also download a sample set of repositories from "
+ " the internet by using the \"Download...\" button."));
+
+ /* Present the repository dialog. */
+ repoman_dialog();
+ confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
+ _("You will now see a blank screen. You can download"
+ " maps using the \"Manage Maps\" menu item in the"
+ " \"Maps\" menu. Or, press OK now to enable"
+ " Auto-Download."));
+ if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
{
- popup_error(_window,
- _("OpenStreetMap.org provides public, free-to-use maps. "
- "You can also download a sample set of repositories from "
- " the internet by using the \"Download...\" button."));
- repoman_dialog();
- if(_curr_repo->type != REPOTYPE_NONE)
- {
- confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
- _("You will now see a blank screen. You can download"
- " maps using the \"Manage Maps\" menu item in the"
- " \"Maps\" menu. Or, press OK to enable"
- " Auto-Download."));
- if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
- {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
- _menu_maps_auto_download_item), TRUE);
- }
- gtk_widget_destroy(confirm);
- }
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+ _menu_maps_auto_download_item), TRUE);
}
- else
- gtk_main_quit();
+ gtk_widget_destroy(confirm);
}
/* Connect to receiver. */
&&((unsigned)(_mark_bufy2 + _draw_width)
<= _screen_height_pixels+2*_draw_width)))
{
- printf("DRAWING\n");
- /* TODO: TEST THIS. */
gdk_draw_arc(
_map_widget->window,
_gps_state == RCVR_FIXED
void map_render_segment(GdkGC *gc_norm, GdkGC *gc_alt,
gint unitx1, gint unity1, gint unitx2, gint unity2);
-void map_render_paths();
+void map_render_paths(void);
-void update_gcs();
+void update_gcs(void);
-gboolean window_present();
+gboolean window_present(void);
void map_pan(gint delta_unitx, gint delta_unity);
-void map_move_mark();
+void map_move_mark(void);
void map_refresh_mark(gboolean force_redraw);
-void map_force_redraw();
+void map_force_redraw(void);
void map_center_unit_full(Point new_center, gint zoom, gint rotate_angle);
GnomeVFSHandle **handle_out, gint *size_out, gchar **dir, gchar **file,
GtkFileChooserAction chooser_action);
-void display_init();
+void display_init(void);
#endif /* ifndef MAEMO_MAPPER_DISPLAY_H */
G_BEGIN_DECLS
-gfloat* gdk_pixbuf_rotate_matrix_new ();
+gfloat* gdk_pixbuf_rotate_matrix_new (void);
void gdk_pixbuf_rotate_matrix_fill_for_rotation (gfloat* matrix,
gfloat angle);
void gdk_pixbuf_rotate_matrix_mult_number (gfloat* matrix,
#include <stdlib.h>
#include <string.h>
#include <math.h>
-#include <dbus/dbus-glib.h>
-#include <bt-dbus.h>
#include <hildon-widgets/hildon-note.h>
#include <hildon-widgets/hildon-banner.h>
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomevfs/gnome-vfs-inet-connection.h>
+#include <errno.h>
#include "types.h"
#include "data.h"
#include "display.h"
#include "gps.h"
+#include "gpsbt.h"
#include "path.h"
#include "util.h"
-
static volatile GThread *_gps_thread = NULL;
static GMutex *_gps_init_mutex = NULL;
static volatile gint _gps_rcvr_retry_count = 0;
-static DBusGProxy *_rfcomm_req_proxy = NULL;
static gint _gmtoffset = 0;
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
-void
-gps_init()
-{
- DBusGConnection *dbus_conn;
- GError *error = NULL;
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- _gps_init_mutex = g_mutex_new();
-
- /* Initialize D-Bus. */
- if(NULL == (dbus_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error)))
- {
- g_printerr("Failed to open connection to D-Bus: %s.\n",
- error->message);
- error = NULL;
- }
-
- if(NULL == (_rfcomm_req_proxy = dbus_g_proxy_new_for_name(
- dbus_conn,
- BTCOND_SERVICE,
- BTCOND_REQ_PATH,
- BTCOND_REQ_INTERFACE)))
- {
- g_printerr("Failed to open connection to %s.\n",
- BTCOND_REQ_INTERFACE);
- }
-
- /* set _gpsoffset */
- {
- time_t time1;
- struct tm time2;
- time1 = time(NULL);
- localtime_r(&time1, &time2);
- _gmtoffset = time2.tm_gmtoff;
- }
-
- vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-}
-
static gboolean
gps_handle_error_idle(gchar *error)
{
GtkWidget *confirm;
gchar buffer[BUFFER_SIZE];
+ /* Reset retry count. */
+ _gps_rcvr_retry_count = 0;
+
snprintf(buffer, sizeof(buffer), "%s\nRetry?", error);
confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
return FALSE;
}
-static gboolean
-gps_update_state_idle(gpointer data)
-{
- ConnState new_state = GPOINTER_TO_INT(data);
- printf("%s(%d)\n", __PRETTY_FUNCTION__, new_state);
-
- if(new_state < RCVR_FIXED)
- {
- if(_track.tail->unity)
- track_insert_break(FALSE);
- _speed_excess = FALSE;
- }
- set_conn_state(new_state);
-
- vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
- return FALSE;
-}
-
static gboolean
gps_parse_nmea_idle(gchar *nmea)
{
printf("%s(%s)\n", __PRETTY_FUNCTION__, nmea);
- if(_enable_gps && _gps_state > RCVR_DOWN)
+ if(_enable_gps && _gps_state >= RCVR_DOWN)
{
if(!strncmp(nmea + 3, "GSV", 3))
{
gps_display_details();
}
+ g_free(nmea);
+
vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
return FALSE;
}
gchar *buf_curr = buf;
gchar *buf_last = buf + sizeof(buf) - 1;
GnomeVFSFileSize bytes_read;
- GnomeVFSHandle *handle = NULL;
+ GnomeVFSResult vfs_result;
+ gchar *gpsd_host = NULL;
+ gint gpsd_port = 0;
GnomeVFSInetConnection *iconn = NULL;
GnomeVFSSocket *socket = NULL;
- GnomeVFSResult vfs_result;
GThread *my_thread = g_thread_self();
gboolean error = FALSE;
+ gpsbt_t gps_context;
+ gboolean is_context = FALSE;
+
printf("%s(%d)\n", __PRETTY_FUNCTION__, gri->type);
/* Lock/Unlock the mutex to ensure that _gps_thread is done being set. */
{
case GPS_RCVR_BT:
{
- /* We need to connect RFCOMM first. */
- gchar *bt_file = NULL;
- GError *err = NULL;
-
- if(!dbus_g_proxy_call(
- _rfcomm_req_proxy,
- BTCOND_RFCOMM_CONNECT_REQ,
- &err,
- G_TYPE_STRING, _gri.bt_mac, /* BDA of remote device */
- G_TYPE_STRING, "SPP", /* SDP profile, e.g. "DUN" */
- G_TYPE_BOOLEAN, TRUE, /* Automatic disconnect */
- G_TYPE_INVALID,
- G_TYPE_STRING, &bt_file,
- G_TYPE_INVALID)
- || GNOME_VFS_OK != (vfs_result = gnome_vfs_open(
- &handle, bt_file, GNOME_VFS_OPEN_READ)))
+ gchar errstr[BUFFER_SIZE] = "";
+ /* We need to start gpsd (via gpsbt) first. */
+ memset(&gps_context, 0, sizeof(gps_context));
+ errno = 0;
+ if(gpsbt_start(gri->bt_mac, 0, 0, 0, errstr, sizeof(errstr),
+ 0, &gps_context) < 0)
{
- if(err)
- {
- printf("Caught remote method exception %s: %s",
- dbus_g_error_get_name(err),
- err->message);
- }
- else
- {
- printf("GnomeVFS Error: %s\n",
- gnome_vfs_result_to_string(vfs_result));
- }
+ g_printerr("Error connecting to GPS receiver: (%d) %s (%s)\n",
+ errno, strerror(errno), errstr);
g_idle_add((GSourceFunc)gps_handle_error_idle,
g_strdup_printf("%s",
_("Error connecting to GPS receiver.")));
error = TRUE;
}
-
- g_free(bt_file);
+ else
+ {
+ /* Success. Set gpsd_host and gpsd_port. */
+ gpsd_host = "127.0.0.1";
+ gpsd_port = GPSD_PORT_DEFAULT;
+ is_context = TRUE;
+ }
break;
}
case GPS_RCVR_GPSD:
{
- /* Create a socket to interact with GPSD. */
- GTimeVal timeout = { 15, 0 };
- vfs_result = gnome_vfs_inet_connection_create(&iconn,
- gri->gpsd_host, gri->gpsd_port, NULL);
- if(vfs_result != GNOME_VFS_OK
- || NULL == (socket = gnome_vfs_inet_connection_to_socket(iconn))
- || GNOME_VFS_OK != (vfs_result = gnome_vfs_socket_set_timeout(
- socket, &timeout, NULL))
- || GNOME_VFS_OK != (vfs_result = gnome_vfs_socket_write(socket,
- "r\r\n", sizeof("r\r\n"), &bytes_read, NULL))
- || bytes_read != sizeof("r\r\n"))
- {
- g_idle_add((GSourceFunc)gps_handle_error_idle,
- g_strdup_printf("%s",
- _("Error connecting to GPSD.")));
- error = TRUE;
- }
+ /* Set gpsd_host and gpsd_port. */
+ gpsd_host = gri->gpsd_host;
+ gpsd_port = gri->gpsd_port;
break;
}
case GPS_RCVR_FILE:
{
- /* Open a handle to interact with a file. */
- vfs_result = gnome_vfs_open(&handle, gri->file_path,
- GNOME_VFS_OPEN_READ);
- if(vfs_result != GNOME_VFS_OK)
+ /* Use gpsmgr to create a GPSD that uses the file. */
+ gchar *gpsd_prog;
+ gchar *gpsd_ctrl_sock;
+ gchar *devs[2];
+ devs[0] = gri->file_path;
+ devs[1] = NULL;
+
+ /* Caller can override the name of the gpsd program and
+ * the used control socket. */
+ gpsd_prog = getenv("GPSD_PROG");
+ gpsd_ctrl_sock = getenv("GPSD_CTRL_SOCK");
+
+ if (!gpsd_prog)
+ gpsd_prog = "gpsd";
+
+ memset(&gps_context, 0, sizeof(gps_context));
+ errno = 0;
+ if(gpsmgr_start(gpsd_prog, devs, gpsd_ctrl_sock,
+ 0, 0, &gps_context.mgr) < 0)
{
+ g_printerr("Error opening GPS device: (%d) %s\n",
+ errno, strerror(errno));
g_idle_add((GSourceFunc)gps_handle_error_idle,
g_strdup_printf("%s",
- _("Error connecting to GPS receiver.")));
+ _("Error opening GPS device.")));
error = TRUE;
}
+ else
+ {
+ /* Success. Set gpsd_host and gpsd_port. */
+ gpsd_host = "127.0.0.1";
+ gpsd_port = GPSD_PORT_DEFAULT;
+ is_context = TRUE;
+ }
break;
}
default:
- ;
+ error = TRUE;
}
if(!error && my_thread == _gps_thread)
{
- g_idle_add((GSourceFunc)gps_update_state_idle, (void*)RCVR_UP);
- while(my_thread == _gps_thread)
+ gint tryno;
+
+ /* Attempt to connect to GPSD. */
+ for(tryno = 0; tryno < 10; tryno++)
{
- gchar *eol;
- if(gri->type == GPS_RCVR_GPSD)
+ /* Create a socket to interact with GPSD. */
+ GTimeVal timeout = { 10, 0 };
+
+ if(GNOME_VFS_OK != (vfs_result = gnome_vfs_inet_connection_create(
+ &iconn,
+ gri->type == GPS_RCVR_GPSD ? gri->gpsd_host
+ : "127.0.0.1",
+ gri->type == GPS_RCVR_GPSD ? gri->gpsd_port
+ : GPSD_PORT_DEFAULT,
+ NULL))
+ || NULL == (socket = gnome_vfs_inet_connection_to_socket(iconn))
+ || GNOME_VFS_OK != (vfs_result = gnome_vfs_socket_set_timeout(
+ socket, &timeout, NULL))
+ || GNOME_VFS_OK != (vfs_result = gnome_vfs_socket_write(socket,
+ "r+\r\n", sizeof("r+\r\n"), &bytes_read, NULL))
+ || bytes_read != sizeof("r+\r\n"))
{
- vfs_result = gnome_vfs_socket_read(
- socket,
- buf,
- buf_last - buf_curr,
- &bytes_read,
- NULL);
+ sleep(1);
}
else
- {
- vfs_result = gnome_vfs_read(
- handle,
- buf,
- buf_last - buf_curr,
- &bytes_read);
- }
+ break;
+ }
+
+ if(!iconn)
+ {
+ g_printerr("Error connecting to GPSD server: (%d) %s\n",
+ vfs_result, gnome_vfs_result_to_string(vfs_result));
+ g_idle_add((GSourceFunc)gps_handle_error_idle,
+ g_strdup_printf("%s",
+ _("Error connecting to GPSD server.")));
+ error = TRUE;
+ }
+ }
+
+ if(!error && my_thread == _gps_thread)
+ {
+ while(my_thread == _gps_thread)
+ {
+ gchar *eol;
+
+ vfs_result = gnome_vfs_socket_read(
+ socket,
+ buf,
+ buf_last - buf_curr,
+ &bytes_read,
+ NULL);
if(vfs_result != GNOME_VFS_OK)
{
break;
}
- /* Successful connection. Reset the retry counter. */
- _gps_rcvr_retry_count = 0;
-
/* Loop through the buffer and read each NMEA sentence. */
buf_curr += bytes_read;
*buf_curr = '\0'; /* append a \0 so we can read as string */
}
}
+ /* Error, or we're done reading GPS. */
+
/* Clean up. */
- if(handle)
- gnome_vfs_close(handle);
if(iconn)
gnome_vfs_inet_connection_free(iconn, NULL);
- if(!error)
+ if(is_context)
{
- g_idle_add((GSourceFunc)gps_update_state_idle,
- GINT_TO_POINTER(RCVR_OFF));
+ switch(gri->type)
+ {
+ case GPS_RCVR_BT:
+ gpsbt_stop(&gps_context);
+ break;
+
+ case GPS_RCVR_FILE:
+ gpsmgr_stop(&gps_context.mgr);
+ break;
+
+ default:
+ ;
+ }
}
+
gri_free(gri);
- printf("%s(): g_thread_exit(NULL)\n", __PRETTY_FUNCTION__);
- g_thread_exit(NULL);
+ printf("%s(): return\n", __PRETTY_FUNCTION__);
+ return;
}
/**
void
rcvr_disconnect()
{
- GError *error = NULL;
printf("%s()\n", __PRETTY_FUNCTION__);
_gps_thread = NULL;
- if(_gri.type == GPS_RCVR_BT && _rfcomm_req_proxy)
- {
- dbus_g_proxy_call(_rfcomm_req_proxy, BTCOND_RFCOMM_CANCEL_CONNECT_REQ,
- &error,
- G_TYPE_STRING, _gri.bt_mac,
- G_TYPE_STRING, "SPP",
- G_TYPE_INVALID,
- G_TYPE_INVALID);
- error = NULL;
- dbus_g_proxy_call(_rfcomm_req_proxy, BTCOND_RFCOMM_DISCONNECT_REQ,
- &error,
- G_TYPE_STRING, _gri.bt_mac,
- G_TYPE_STRING, "SPP",
- G_TYPE_INVALID,
- G_TYPE_INVALID);
- }
if(_window)
set_conn_state(RCVR_OFF);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
{
printf("%s(%d)\n", __PRETTY_FUNCTION__, _gps_state);
- if(_enable_gps && _gps_state == RCVR_OFF && _gri.type != GPS_RCVR_NONE)
+ if(_enable_gps && _gps_state == RCVR_OFF)
{
set_conn_state(RCVR_DOWN);
* start until _gps_thread is set. */
g_mutex_lock(_gps_init_mutex);
_gps_thread = g_thread_create((GThreadFunc)thread_read_nmea,
- gri_clone(&_gri), FALSE, NULL);
+ gri_clone(&_gri), TRUE, NULL); /* Joinable. */
g_mutex_unlock(_gps_init_mutex);
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
+void
+gps_init()
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ _gps_init_mutex = g_mutex_new();
+
+ /* Fix a stupid PATH bug in libgps. */
+ {
+ gchar *path_env = getenv("PATH");
+ gchar *new_path = g_strdup_printf("%s:%s", path_env, "/usr/sbin");
+ setenv("PATH", new_path, 1);
+ }
+
+ /* set _gpsoffset */
+ {
+ time_t time1;
+ struct tm time2;
+ time1 = time(NULL);
+ localtime_r(&time1, &time2);
+ _gmtoffset = time2.tm_gmtoff;
+ }
+
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+}
+
+void
+gps_destroy(gboolean last)
+{
+ static GThread* tmp = NULL;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if(!last)
+ {
+ if(_gps_thread)
+ {
+ tmp = (GThread*)_gps_thread;
+ _gps_thread = NULL;
+ }
+ }
+ else if(tmp)
+ g_thread_join(tmp);
+
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+}
+
void set_conn_state(ConnState new_conn_state);
-gboolean rcvr_connect();
-void rcvr_disconnect();
+gboolean rcvr_connect(void);
+void rcvr_disconnect(void);
-void reset_bluetooth();
+void reset_bluetooth(void);
-void gps_init();
+void gps_init(void);
+void gps_destroy(gboolean last);
#endif /* ifndef MAEMO_MAPPER_GPS_H */
--- /dev/null
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+GPS BT management API. The API is used by those applications that
+wish to use services provided by gps daemon i.e., they wish to receive
+GPS data from the daemon. See README file for more details.
+
+Copyright (C) 2006 Nokia Corporation. All rights reserved.
+
+Author: Jukka Rissanen <jukka.rissanen@nokia.com>
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+/* $Id:$ */
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <time.h>
+
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib.h>
+
+#include "gpsbt.h"
+
+/* Set following #if to 1 if you want to use automatic bt dev disconnect.
+ * This does not seem to work correctly currently (disconnects too fast)
+ */
+#if 0
+#define USE_AUTOMATIC_DISCONNECT
+#else
+#undef USE_AUTOMATIC_DISCONNECT
+#endif
+
+/* default control socket (not used by default) */
+#define CTRL_SOCK "/tmp/.gpsd_ctrl_sock"
+
+/* Note that 10 second timeout should not be lowered, because
+ * then there might be GPS device connection errors if there
+ * are multiple GPS devices that the user is using.
+ * E.g., if the timeout is set to 5 secs and there are three
+ * GPS devices that the user is using, it is possible that
+ * if the 1st device fails, the other devices might also fail
+ * if the timeout is lower than 10 secs.
+ */
+#if 0
+#define DEFAULT_TIMEOUT (1000*10) /* 10 second timeout (in ms) */
+#else
+#define DEFAULT_TIMEOUT (1000*60) /* 60 second timeout (in ms) */
+#endif
+
+/* BT dbus service location */
+#define BASE_PATH "/org/bluez"
+#define BASE_INTERFACE "org.bluez"
+#define ADAPTER_PATH BASE_PATH
+#define ADAPTER_INTERFACE BASE_INTERFACE ".Adapter"
+#define MANAGER_PATH BASE_PATH
+#define MANAGER_INTERFACE BASE_INTERFACE ".Manager"
+#define ERROR_INTERFACE BASE_INTERFACE ".Error"
+#define SECURITY_INTERFACE BASE_INTERFACE ".Security"
+#define RFCOMM_INTERFACE BASE_INTERFACE ".RFCOMM"
+#define BLUEZ_DBUS BASE_INTERFACE
+
+#define LIST_ADAPTERS "ListAdapters"
+#define LIST_BONDINGS "ListBondings"
+#define CREATE_BONDING "CreateBonding"
+#define GET_REMOTE_NAME "GetRemoteName"
+#define GET_REMOTE_SERVICE_CLASSES "GetRemoteServiceClasses"
+
+#define BTCOND_PATH "/com/nokia/btcond/request"
+#define BTCOND_BASE "com.nokia.btcond"
+#define BTCOND_INTERFACE BTCOND_BASE ".request"
+#define BTCOND_REQUEST BTCOND_INTERFACE
+#define BTCOND_CONNECT "rfcomm_connect"
+#define BTCOND_DISCONNECT "rfcomm_disconnect"
+#define BTCOND_DBUS BTCOND_BASE
+
+#define GPS_SERVICE_CLASS_STR "positioning"
+
+typedef struct {
+ char *adapter; /* do not free this, it is freed somewhere else */
+ char *bonding; /* allocated from heap, you must free this */
+} bonding_t;
+
+
+/* Not all gps bt devices set the positioning bit in service class to 1,
+ * so we need a way to figure out whether the device supports positioning
+ * or not. The array contains sub-string for devices that we know to
+ * support positioning. The sub-string will be matched against device
+ * remote name that we get using dbus GetRemoteName call. The name is
+ * fetched only if we have no BT device in the system that has the
+ * positioning bit activated. Note that the listed string is case
+ * sensitive.
+ */
+static const char const *gps_device_names[] = {
+ "HOLUX GR-", /* like Holux GR-231 or similar */
+ "Nokia LD-", /* for Nokia LD-1W, note that LD-3W has positioning bit set */
+ "GPS", /* Insmat BT-GPS-3244C8 or TomTom Wireless GPS MkII */
+ "i-Blue", /* i-Blue line of GPS receivers. */
+ 0 /* must be at the end */
+};
+
+
+/* ----------------------------------------------------------------------- */
+static int debug_level;
+
+#ifdef DEBUG
+#if (__GNUC__ > 2) && ((__GNUC__ > 3) || (__GNUC_MINOR__ > 2))
+#define PDEBUG(fmt...) do { \
+ if (debug_level) { \
+ struct timeval tv; \
+ gettimeofday(&tv, 0); \
+ printf("DEBUG[%d]:%ld.%ld:%s:%s():%d: ", \
+ getpid(), \
+ tv.tv_sec, tv.tv_usec, \
+ __FILE__, __FUNCTION__, __LINE__); \
+ printf(fmt); \
+ fflush(stdout); \
+ } \
+ }while(0)
+#else
+#define PDEBUG(fmt...) do { \
+ if (debug_level) { \
+ struct timeval tv; \
+ gettimeofday(&tv, 0); \
+ printf("DEBUG[%d]:%ld.%ld:%s:%s():%d: ", \
+ getpid(), \
+ tv.tv_sec, tv.tv_usec, \
+ __FILE__, __FUNCTION__, __LINE__); \
+ printf(##fmt); \
+ fflush(stdout); \
+ } \
+ }while(0)
+#endif
+#else
+#define PDEBUG(fmt...)
+#endif
+
+
+/* ----------------------------------------------------------------------- */
+static int check_device_name(char *name)
+{
+ int i=0, st=0;
+
+ while (gps_device_names[i]) {
+ if (strstr(name, gps_device_names[i])) {
+ st = 1;
+ break;
+ }
+ i++;
+ }
+
+ return st;
+}
+
+
+/* ----------------------------------------------------------------------- */
+static inline DBusGConnection *get_dbus_gconn(GError **error)
+{
+ DBusGConnection *conn;
+
+ conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, error);
+ return conn;
+}
+
+
+/* ----------------------------------------------------------------------- */
+static int set_error_msg(char *errbuf,
+ int errbuf_max_len,
+ char *msg,
+ ...)
+{
+ int st, len;
+ va_list args;
+
+ if (!errbuf) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(args, msg);
+ st = vsnprintf(errbuf, errbuf_max_len, msg, args);
+ va_end(args);
+
+ /* Remove \n if it is at the end of the line (so that caller can
+ * print the string as it wishes)
+ */
+ len = strlen(errbuf);
+ if (len>0 && errbuf[len-1]=='\n')
+ errbuf[len-1]='\0';
+
+ return st;
+}
+
+
+/* ----------------------------------------------------------------------- */
+extern int gpsbt_start(char *bda,
+ int our_debug_level,
+ int gpsd_debug_level,
+ short port,
+ char *error_buf,
+ int error_buf_max_len,
+ int timeout_ms,
+ gpsbt_t *ctx)
+{
+ int i, j, k, st, num_bondings = 0,
+ bonding_cnt = 0, num_classes = 0, num_rfcomms = 0,
+ num_posdev = 0;
+ GError *error = NULL;
+ DBusGConnection *bus = NULL;
+ DBusGProxy *proxy = NULL;
+ char **str_iter = NULL;
+ char **tmp_bondings = 0, **tmp_classes = 0;
+ char **adapters = 0;
+ char **rfcomms = 0;
+ bonding_t *bondings = 0; /* points to array of bonding_t */
+ bonding_t *posdev = 0; /* bondings with positioning bit on */
+ char *tmp;
+ char *onoff;
+ const char const *spp="SPP";
+ int timeout;
+ char *gpsd_prog;
+ char *gpsd_ctrl_sock;
+
+
+#if (__GNUC__ > 2) && ((__GNUC__ > 3) || (__GNUC_MINOR__ > 2))
+#define ERRSTR(fmt, args...) \
+ if (error_buf && error_buf_max_len>0) { \
+ set_error_msg(error_buf, error_buf_max_len, fmt, args); \
+ } else { \
+ PDEBUG(fmt, args); \
+ }
+#else
+#define ERRSTR(fmt, args...) \
+ if (error_buf && error_buf_max_len>0) { \
+ set_error_msg(error_buf, error_buf_max_len, fmt, ##args); \
+ } else { \
+ PDEBUG(fmt, ##args); \
+ }
+#endif
+
+ if (!ctx) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ debug_level = our_debug_level;
+
+ /* context & error needs to be clean */
+ memset(ctx, 0, sizeof(gpsmgr_t));
+
+ if (timeout_ms==0)
+ timeout = DEFAULT_TIMEOUT;
+ else if (timeout_ms < 0)
+ timeout = -1;
+ else
+ timeout = timeout_ms;
+
+ ctx->timeout = timeout;
+
+ /* Caller can override the name of the gpsd program and
+ * the used control socket.
+ */
+ gpsd_prog = getenv("GPSD_PROG");
+ gpsd_ctrl_sock = getenv("GPSD_CTRL_SOCK");
+
+ if (!gpsd_prog)
+ gpsd_prog = "gpsd";
+
+ if (!gpsd_ctrl_sock)
+ gpsd_ctrl_sock = CTRL_SOCK;
+
+ /* First find out what BT devices are paired with us, then figure out
+ * which one of those are GPS devices (positioning bit in class is
+ * set). If found, create a rfcommX device for GPS BT and pass that
+ * as a parameter when starting gpsd.
+ */
+
+ /* But first things first, if gpsd is already running then it is
+ * no point trying to find out the GPS BT devices because some program
+ * has already figured it out.
+ */
+ st = gpsmgr_is_gpsd_running(&ctx->mgr, NULL, GPSMGR_MODE_LOCK_IF_POSSIBLE);
+ if (st) {
+
+ if (st!=2) { /* gpsd is running, value 2 would mean that gpsd is not
+ * running but we have a lock acquired
+ */
+
+ st = gpsmgr_start(gpsd_prog, NULL, gpsd_ctrl_sock,
+ gpsd_debug_level, port, &ctx->mgr);
+ if (!st) {
+ /* everything is ok */
+ PDEBUG("%s already running, doing nothing\n",gpsd_prog);
+ goto OUT;
+ }
+
+ PDEBUG("gpsmgr_start() returned %d [%s, %d]\n",st,strerror(errno),errno);
+ /* Note, no exit or return here, let the API do its magic */
+ }
+ }
+
+
+ /* Use the dbus interface to get the BT information */
+
+ error = NULL;
+ bus = get_dbus_gconn(&error);
+ if (error) {
+ st = -1;
+ errno = ECONNREFUSED; /* close enough :) */
+ ERRSTR("%s", error->message);
+ PDEBUG("Cannot get reply message [%s]\n", error->message);
+ goto OUT;
+ }
+
+#define CHECK_ERROR(s,o,i,m,t) \
+ if (st<0) { \
+ ERRSTR("Cannot send msg (service=%s, object=%s, interface=%s, " \
+ "method=%s) [%s]\n", s, o, i, m, \
+ error.message ? error.message : "<no error msg>"); \
+ goto OUT; \
+ }
+
+
+ /* We need BT information only if the caller does not specify
+ * the BT address. If address is defined, it is assumed that
+ * it is already bonded and we just create RFCOMM connection
+ * to it.
+ */
+ if (!bda) {
+ proxy = dbus_g_proxy_new_for_name(bus,
+ BLUEZ_DBUS, MANAGER_PATH, MANAGER_INTERFACE);
+
+ error = NULL;
+ if(!dbus_g_proxy_call(proxy, LIST_ADAPTERS, &error, G_TYPE_INVALID,
+ G_TYPE_STRV, &adapters, G_TYPE_INVALID)
+ || error || !adapters || !*adapters || !**adapters) {
+ PDEBUG("No adapters found.\n");
+ st = -1;
+ goto OUT;
+ }
+ g_object_unref(proxy);
+
+ /* For each adapter, get bondings */
+ i = 0;
+ while (adapters[i]) {
+ proxy = dbus_g_proxy_new_for_name(bus,
+ BLUEZ_DBUS, adapters[i], ADAPTER_INTERFACE);
+
+ error = NULL;
+ if(!dbus_g_proxy_call(proxy, LIST_BONDINGS, &error, G_TYPE_INVALID,
+ G_TYPE_STRV, &tmp_bondings, G_TYPE_INVALID)
+ || error || !tmp_bondings || !*tmp_bondings || !**tmp_bondings) {
+ PDEBUG("Call to LIST_BONDINGS failed (error=%s, tmp_bondings[0]=%s\n",
+ error ? error->message : "<null>",
+ tmp_bondings ? tmp_bondings[0] : "<null>");
+ } else {
+ /* Count the bondings. */
+ for(num_bondings = 0, str_iter = tmp_bondings; *str_iter;
+ str_iter++, num_bondings++);
+
+ /* Allocate bondings array, note that we DO allocate one extra array
+ * element for marking end of array.
+ */
+ bondings = (bonding_t *)realloc(bondings,
+ (bonding_cnt+num_bondings+1)*sizeof(bonding_t));
+ if (!bondings) {
+ st = -1;
+ errno = ENOMEM;
+ goto OUT;
+ }
+ bondings[bonding_cnt+num_bondings].bonding=
+ bondings[bonding_cnt+num_bondings].adapter=NULL; /* just in case */
+
+
+ j = 0;
+ while (j<num_bondings && tmp_bondings[j]) {
+ bondings[bonding_cnt].bonding = strdup(tmp_bondings[j]);
+ free(tmp_bondings[j]);
+
+ bondings[bonding_cnt].adapter = adapters[i]; /* no allocation! */
+
+ PDEBUG("Bondings[%d]=%s (adapter=%s)\n", bonding_cnt,
+ bondings[bonding_cnt].bonding, bondings[bonding_cnt].adapter);
+
+ /* Get all remote service classes for this bonding. */
+ error = NULL;
+ if(dbus_g_proxy_call(proxy, GET_REMOTE_SERVICE_CLASSES, &error,
+ G_TYPE_STRING, bondings[bonding_cnt].bonding, G_TYPE_INVALID,
+ G_TYPE_STRV, &tmp_classes, G_TYPE_INVALID)
+ && !error && tmp_classes && *tmp_classes && **tmp_classes) {
+
+ k = 0;
+ while (tmp_classes[k]) {
+ if (!strcasecmp(tmp_classes[k], GPS_SERVICE_CLASS_STR)) {
+ /* match found, this device claims to be able to provide
+ * positioning data
+ */
+ posdev = (bonding_t *)realloc(posdev,
+ (num_posdev+1)*sizeof(bonding_t));
+ if (!posdev) {
+ st = -1;
+ errno = ENOMEM;
+ goto OUT;
+ }
+
+ posdev[num_posdev].bonding=strdup(
+ bondings[bonding_cnt].bonding);
+ posdev[num_posdev].adapter=bondings[bonding_cnt].adapter;
+ num_posdev++;
+ onoff = "ON";
+ } else {
+ onoff = "OFF";
+ }
+ PDEBUG("Addr=%s, Class[%d]=%s (adapter=%s), positioning bit %s\n",
+ bondings[bonding_cnt].bonding, k, tmp_classes[k],
+ bondings[bonding_cnt].adapter, onoff);
+ free(tmp_classes[k]);
+
+ k++;
+ }
+
+ free(tmp_classes);
+ tmp_classes=0;
+ }
+
+ num_classes = 0;
+ bonding_cnt++;
+ j++;
+ }
+ }
+
+ free(tmp_bondings);
+ tmp_bondings=0;
+ g_object_unref(proxy);
+ i++;
+ }
+
+#if 0
+#ifdef DEBUG
+ if (debug_level) {
+ int i=0;
+ if (bonding_cnt) {
+ PDEBUG("Bondings [%d]:\n", bonding_cnt);
+ while (bondings[i].bonding && i<bonding_cnt) {
+ PDEBUG("\t%s\n", bondings[i].bonding);
+ i++;
+ }
+ } else {
+ PDEBUG("No bondings exists.\n");
+ }
+ }
+#endif
+#endif
+
+ /* We have bonded devices but none has positioning bit set. Try
+ * to find out if any of the devices is known to be a BT device.
+ */
+ if (bonding_cnt>0 && num_posdev == 0) {
+
+ /* For each bonded device, get its name */
+ i = 0;
+ while (i<bonding_cnt && bondings[i].bonding) {
+ proxy = dbus_g_proxy_new_for_name(bus,
+ BLUEZ_DBUS, bondings[i].adapter, ADAPTER_INTERFACE);
+
+ tmp = NULL;
+ error = NULL;
+ if(dbus_g_proxy_call(proxy, GET_REMOTE_NAME, &error,
+ G_TYPE_STRING, bondings[i].bonding, G_TYPE_INVALID,
+ G_TYPE_STRING, &tmp, G_TYPE_INVALID)
+ && !error && tmp && *tmp) {
+ PDEBUG("Checking device name: %s\n", tmp);
+ if (check_device_name(tmp)) {
+
+ /* Found a GPS device */
+ posdev = (bonding_t *)realloc(posdev, (num_posdev+1)*sizeof(bonding_t));
+ if (!posdev) {
+ st = -1;
+ errno = ENOMEM;
+ goto OUT;
+ }
+
+ posdev[num_posdev].bonding=strdup(bondings[i].bonding);
+ posdev[num_posdev].adapter=bondings[i].adapter;
+ num_posdev++;
+
+ PDEBUG("Addr=%s, (adapter=%s), Name=\"%s\"\n",
+ bondings[i].bonding, bondings[i].adapter, tmp);
+ }
+ }
+ g_object_unref(proxy);
+ i++;
+ }
+ }
+
+
+ } else { /* if (!bda) */
+
+ /* Caller supplied BT address so use it */
+ num_posdev = 1;
+ posdev = calloc(1, sizeof(bonding_t *));
+ if (!posdev) {
+ st = -1;
+ errno = ENOMEM;
+ goto OUT;
+ }
+ posdev[0].bonding = strdup(bda);
+
+ /* Adapter information is not needed */
+ posdev[0].adapter = "<not avail>";
+ }
+
+
+ /* For each bondend BT GPS device, try to create rfcomm */
+ for (i=0; i<num_posdev; i++) {
+ /* Note that bluez does not provide this interface (its defined but not
+ * yet implemented) so we use btcond for creating rfcomm device(s)
+ */
+ proxy = dbus_g_proxy_new_for_name(bus,
+ BTCOND_DBUS, BTCOND_PATH, BTCOND_INTERFACE);
+
+ error = NULL;
+ tmp = NULL;
+ if(!dbus_g_proxy_call(proxy, BTCOND_CONNECT, &error,
+ G_TYPE_STRING, posdev[i].bonding,
+ G_TYPE_STRING, spp,
+#ifdef USE_AUTOMATIC_DISCONNECT
+ G_TYPE_BOOLEAN, TRUE, /* automatic disconnect (does not work, the system disconnects too fast) */
+#else
+ G_TYPE_BOOLEAN, FALSE, /* no automatic disconnect (this seems to work ok) */
+#endif
+ G_TYPE_INVALID,
+ G_TYPE_STRING, &tmp,
+ G_TYPE_INVALID)
+ || error || !tmp || !*tmp) {
+ PDEBUG("dbus_g_proxy_call returned an error: (error=(%d,%s), tmp=%s\n",
+ error ? error->code : -1,
+ error ? error->message : "<null>",
+ tmp ? tmp : "<null>");
+
+ /* No error if already connected */
+ if (error && !strstr(error->message,
+ "com.nokia.btcond.error.connected")) {
+
+ ERROR:
+ ERRSTR("Cannot send msg (service=%s, object=%s, interface=%s, "
+ "method=%s) [%s]\n",
+ BTCOND_DBUS,
+ BTCOND_PATH,
+ BTCOND_INTERFACE,
+ BTCOND_CONNECT,
+ error->message ? error->message : "<no error msg>");
+ continue;
+
+ } else if(!tmp || !*tmp) {
+
+ /* hack: rfcommX device name is at the end of error message */
+ char *last_space = strstr(error->message, " rfcomm");
+ if (!last_space) {
+ goto ERROR;
+ }
+
+ g_free(tmp);
+ tmp = g_strdup_printf("/dev/%s", last_space+1);
+ }
+ }
+ g_object_unref(proxy);
+
+ if (tmp && tmp[0]) {
+ rfcomms = (char **)realloc(rfcomms, (num_rfcomms+1)*sizeof(char *));
+ if (!rfcomms) {
+ st = -1;
+ errno = ENOMEM;
+ goto OUT;
+ }
+ rfcomms[num_rfcomms] = tmp;
+ num_rfcomms++;
+
+ PDEBUG("BT addr=%s, RFCOMM %s now exists (adapter=%s)\n", posdev[i].bonding, tmp, posdev[i].adapter);
+
+ tmp = NULL;
+ }
+ else {
+ g_free(tmp);
+ }
+ }
+
+ if (num_rfcomms==0) {
+ /* serial device creation failed */
+ ERRSTR("No rfcomm %s\n", "created");
+ st = -1;
+ errno = EINVAL;
+
+ } else {
+
+ /* Add null at the end */
+ rfcomms = (char **)realloc(rfcomms, (num_rfcomms+1)*sizeof(char *));
+ if (!rfcomms) {
+ st = -1;
+ errno = ENOMEM;
+
+ } else {
+
+ rfcomms[num_rfcomms] = NULL;
+
+#ifndef USE_AUTOMATIC_DISCONNECT
+ ctx->rfcomms = rfcomms; /* freed in gpsbt_stop() */
+#endif
+
+ /* Just start the beast (to be done if everything is ok) */
+ st = gpsmgr_start(gpsd_prog, rfcomms, gpsd_ctrl_sock, gpsd_debug_level, port, &ctx->mgr);
+ if (!st) {
+ /* everything is ok */
+ goto OUT;
+ }
+ }
+ }
+
+ OUT:
+ if (adapters) {
+ g_strfreev(adapters);
+ }
+
+ if (posdev) {
+ for (i=0; i<num_posdev; i++) {
+ if (posdev[i].bonding) {
+ free(posdev[i].bonding);
+ memset(&posdev[i], 0, sizeof(bonding_t)); /* just in case */
+ }
+ }
+ free(posdev);
+ posdev = 0;
+ }
+
+ if (bondings) {
+ for (i=0; i<num_bondings; i++) {
+ if (bondings[i].bonding) {
+ free(bondings[i].bonding);
+ memset(&bondings[i], 0, sizeof(bonding_t)); /* just in case */
+ }
+ }
+ free(bondings);
+ bondings = 0;
+ }
+
+#ifdef USE_AUTOMATIC_DISCONNECT
+ if (rfcomms) {
+ for (i=0; i<num_rfcomms; i++) {
+ if (rfcomms[i]) {
+ free(rfcomms[i]);
+ rfcomms[i]=0;
+ }
+ }
+ free(rfcomms);
+ rfcomms = 0;
+ }
+#endif
+
+ if (bus) {
+ dbus_g_connection_unref(bus);
+ }
+
+ return st;
+}
+
+
+/* ----------------------------------------------------------------------- */
+extern int gpsbt_stop(gpsbt_t *ctx)
+{
+ int st;
+
+ if (!ctx) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ st = gpsmgr_stop(&ctx->mgr);
+
+
+#ifndef USE_AUTOMATIC_DISCONNECT
+ /* We need to disconnect from rfcomm device */
+ if (ctx->rfcomms) {
+ int i = 0;
+ int skip_dbus = 0;
+ DBusGConnection *bus = NULL;
+ DBusGProxy *proxy = NULL;
+ GError *error = NULL;
+
+ bus = get_dbus_gconn(&error);
+ if (!bus) {
+ errno = ECONNREFUSED; /* close enough :) */
+ PDEBUG("Cannot get reply message [%s]\n", error->message);
+ skip_dbus = 1;
+ }
+
+ if (!skip_dbus) {
+ /* Make sure there is no other user for gpsd, if there is then
+ * we must not delete rfcomm devices. The st==0 would mean that
+ * we are the only one using the dev.
+ */
+ if (st>0) {
+ skip_dbus = 1;
+ PDEBUG("Skipping rfcomm device deletion as we are not the only location user\n");
+ }
+ }
+
+ while (ctx->rfcomms[i]) {
+
+ if (!skip_dbus) {
+ /* Disconnect the device */
+ proxy = dbus_g_proxy_new_for_name(bus,
+ BTCOND_DBUS, BTCOND_PATH, BTCOND_INTERFACE);
+ error = NULL;
+ if(!dbus_g_proxy_call(proxy, BTCOND_DISCONNECT, &error,
+ G_TYPE_STRING, ctx->rfcomms[i], G_TYPE_INVALID, G_TYPE_INVALID)
+ || error){
+ PDEBUG("Cannot send msg (service=%s, object=%s, interface=%s, "
+ "method=%s) [%s]\n",
+ BTCOND_DBUS,
+ BTCOND_PATH,
+ BTCOND_INTERFACE,
+ BTCOND_DISCONNECT,
+ error->message ? error->message : "<no error msg>");
+ }
+ g_object_unref(proxy);
+ }
+
+ free(ctx->rfcomms[i]);
+ ctx->rfcomms[i]=0;
+ i++;
+ }
+
+ if (bus) {
+ dbus_g_connection_unref(bus);
+ }
+
+ free(ctx->rfcomms);
+ ctx->rfcomms = 0;
+ }
+#endif /* automatic disconnect */
+
+ return st;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+GPS BT management API. The API is used by those applications that
+wish to use services provided by gps daemon i.e., they wish to receive
+GPS data from the daemon. See README file for more details.
+
+Copyright (C) 2006 Nokia Corporation. All rights reserved.
+
+Author: Jukka Rissanen <jukka.rissanen@nokia.com>
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+/* $Id:$ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <gpsmgr.h>
+
+#ifndef gpsbt_included
+#define gpsbt_included
+
+/* Internal context information */
+typedef struct {
+ gpsmgr_t mgr;
+ char **rfcomms; /* what devices where found (null terminated array),
+ * not used if compiled with USE_AUTOMATIC_DISCONNECT
+ * (see gpsbt.c for details)
+ */
+ int timeout; /* timeout for dbus messages */
+} gpsbt_t;
+
+
+/* Start function finds out the available GPS BT devices and starts
+ * the gpsd if it is not running. If no GPS BT devices are found, then
+ * an error is returned.
+ *
+ * Parameters:
+ * bda
+ * BT address of the GPS device, normally this is left
+ * to null but if this API cannot find a suitable GPS
+ * BT device, the application can ask the BT device
+ * from the user and supply the address here.
+ *
+ * debug_level
+ * debug level (set to 0 to use the default)
+ *
+ * gpsd_debug_level
+ * gpsd debug level (set to 0 to use the default)
+ *
+ * port
+ * gpsd port (set to 0 to use the default (2947))
+ *
+ * error_buf
+ * user supplied error buffer (optional), if there is an error
+ * the API puts error message to this buffer
+ *
+ * error_buf_max_len
+ * max length of the error buffer, set to 0 if error
+ * message is not needed in caller program
+ *
+ * timeout_ms
+ * timeout (in ms) when waiting dbus replies, set to 0 to use
+ * the library default (5 seconds), if set to <0 then use
+ * the dbus default (whatever that is).
+ *
+ * ctx
+ * caller must allocate and clear this struct before call
+ *
+ * Returns:
+ * <0 : error, check errno for more details
+ * 0 : ok
+ *
+ * Example:
+ * The default call would be
+ * gpsbt_start(NULL, 0, 0, 0, &ctx);
+ *
+ * If the GPSD_PROG environment variable is defined, then it is used
+ * when starting the program, otherwise "gpsd" will be used as a program
+ * name. This way you can override the program name and/or path if necessary.
+ *
+ * If the GPSD_CTRL_SOCK environment variable is defined, then it is used
+ * as a location to gpsd control socket, otherwise the default control socket
+ * is /tmp/.gpsd_ctrl_sock
+ */
+
+extern int gpsbt_start(char *bda,
+ int debug_level,
+ int gpsd_debug_level,
+ short port,
+ char *error_buf,
+ int error_buf_max_len,
+ int timeout_ms,
+ gpsbt_t *ctx);
+
+
+/* Stop function stops the gpsd if it was running and nobody
+ * was using it.
+ *
+ * Parameters:
+ * ctx : context returned by gpsbt_start()
+ *
+ * Returns:
+ * <0 : error, check errno for more details
+ * 0 : ok
+ *
+ */
+
+extern int gpsbt_stop(gpsbt_t *ctx);
+
+#endif /* gpsbt_included */
#ifndef MAEMO_MAPPER_INPUT_H
#define MAEMO_MAPPER_INPUT_H
-void input_init();
+void input_init(void);
#endif /* ifndef MAEMO_MAPPER_INPUT_H */
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <dbus/dbus-glib.h>
#include <hildon-widgets/hildon-program.h>
#include <hildon-widgets/hildon-banner.h>
#include <gconf/gconf-client.h>
#include "defines.h"
#include "cmenu.h"
+#include "dbus-ifc.h"
#include "display.h"
#include "gps.h"
#include "gpx.h"
/* _program and widgets have already been destroyed. */
_window = NULL;
- rcvr_disconnect();
+ gps_destroy(FALSE);
path_destroy();
#endif
}
+ gps_destroy(TRUE);
+
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
SPEED_LOCATION_ENUM_TEXT[SPEED_LOCATION_BOTTOM_RIGHT] = _("Bottom-Right");
SPEED_LOCATION_ENUM_TEXT[SPEED_LOCATION_BOTTOM_LEFT] = _("Bottom-Left");
- GPS_RCVR_ENUM_TEXT[GPS_RCVR_NONE] = _("None");
GPS_RCVR_ENUM_TEXT[GPS_RCVR_BT] = _("Bluetooth");
GPS_RCVR_ENUM_TEXT[GPS_RCVR_GPSD] = _("GPSD");
GPS_RCVR_ENUM_TEXT[GPS_RCVR_FILE] = _("File");
input_init();
poi_db_connect();
display_init();
+ dbus_ifc_init();
/* If present, attempt to load the file specified on the command line. */
if(argc > 1)
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
-static gint
-dbus_cb_default(const gchar *interface, const gchar *method,
- GArray *arguments, gpointer data, osso_rpc_t *retval)
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- if(!strcmp(method, "top_application"))
- g_idle_add((GSourceFunc)window_present, NULL);
-
- retval->type = DBUS_TYPE_INVALID;
-
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
- return OSSO_OK;
-}
-
static gboolean
osso_cb_hw_state_idle(osso_hw_state_t *state)
{
/* Init Gnome-VFS. */
gnome_vfs_init();
- maemo_mapper_init(argc, argv);
-
- if(OSSO_OK != osso_rpc_set_default_cb_f(_osso, dbus_cb_default, NULL))
+#ifdef DEBUG
+ /* This is just some helpful DBUS testing code. */
+ if(argc >= 3)
{
- g_printerr("osso_rpc_set_default_cb_f failed.\n");
- return 1;
+ /* Try to set the center to a new lat/lon. */
+ GError *error = NULL;
+ gchar *error_check;
+ gdouble lat, lon;
+ DBusGConnection *bus;
+ DBusGProxy *proxy;
+
+ bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+ if(!bus || error)
+ {
+ g_printerr("Error: %s\n", error->message);
+ return -1;
+ }
+
+ proxy = dbus_g_proxy_new_for_name(bus,
+ MM_DBUS_SERVICE, MM_DBUS_PATH, MM_DBUS_INTERFACE);
+
+ lat = g_ascii_strtod((argv[1]), &error_check);
+ if(error_check == argv[1])
+ {
+ g_printerr("Failed to parse string as float: %s\n", argv[1]);
+ return 1;
+ }
+
+ lon = g_ascii_strtod((argv[2]), &error_check);
+ if(error_check == argv[2])
+ {
+ g_printerr("Failed to parse string as float: %s\n", argv[2]);
+ return 2;
+ }
+
+ error = NULL;
+ if(argc >= 4)
+ {
+ /* We are specifying a zoom. */
+ gint zoom;
+
+ zoom = g_ascii_strtod((argv[3]), &error_check);
+ if(error_check == argv[3])
+ {
+ g_printerr("Failed to parse string as integer: %s\n", argv[3]);
+ return 3;
+ }
+ if(!dbus_g_proxy_call(proxy, MM_DBUS_METHOD_SET_VIEW_CENTER,&error,
+ G_TYPE_DOUBLE, lat, G_TYPE_DOUBLE, lon,
+ G_TYPE_INT, zoom, G_TYPE_INVALID,
+ G_TYPE_INVALID)
+ || error)
+ {
+ g_printerr("Error: %s\n", error->message);
+ return 4;
+ }
+ }
+ else
+ {
+ /* Not specifying a zoom. */
+ if(!dbus_g_proxy_call(proxy, MM_DBUS_METHOD_SET_VIEW_CENTER, &error,
+ G_TYPE_DOUBLE, lat, G_TYPE_DOUBLE, lon, G_TYPE_INVALID,
+ G_TYPE_INVALID)
+ || error)
+ {
+ g_printerr("Error: %s\n", error->message);
+ return -2;
+ }
+ }
+
+ g_object_unref(proxy);
+ dbus_g_connection_unref(bus);
+
+ return 0;
}
+#endif
+
+ maemo_mapper_init(argc, argv);
gtk_main();
gint main(gint argc, gchar *argv[]);
-void conic_recommend_connected();
-void conic_ensure_connected();
+void conic_recommend_connected(void);
+void conic_ensure_connected(void);
#endif /* ifndef MAEMO_MAPPER_MAIN_H */
if(++_num_downloads == 20 && !_download_banner)
g_idle_add((GSourceFunc)mapdb_initiate_update_banner_idle, NULL);
- if(_num_downloads <= NUM_DOWNLOAD_THREADS)
+ /* This doesn't need to be thread-safe. Extras in the pool don't
+ * really make a difference. */
+ if(g_thread_pool_get_num_threads(_mut_thread_pool)
+ < g_thread_pool_get_max_threads(_mut_thread_pool))
g_thread_pool_push(_mut_thread_pool, (gpointer)1, NULL);
}
guint mut_exists_hashfunc(const MapUpdateTask *a);
gboolean mut_exists_equalfunc(const MapUpdateTask *a, const MapUpdateTask *b);
gint mut_priority_comparefunc(const MapUpdateTask *a, const MapUpdateTask *b);
-gboolean thread_proc_mut();
+gboolean thread_proc_mut(void);
-gboolean repoman_dialog();
+gboolean repoman_dialog(void);
-gboolean mapman_dialog();
+gboolean mapman_dialog(void);
#endif /* ifndef MAEMO_MAPPER_MAPS_H */
if((_enable_gps = gtk_check_menu_item_get_active(
GTK_CHECK_MENU_ITEM(_menu_enable_gps_item))))
- {
- if(_gri.type != GPS_RCVR_NONE)
- {
- rcvr_connect();
- }
- else
- {
- popup_error(_window,
- _("Cannot enable GPS until a GPS receiver "
- "is set up in the Settings dialog box."));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), FALSE);
- }
- }
+ rcvr_connect();
else
- {
rcvr_disconnect();
- }
+
map_move_mark();
gps_show_info();
gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item), _enable_gps);
= gtk_check_menu_item_new_with_label(_("Auto-Download")));
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(_menu_maps_auto_download_item),_auto_download);
- menu_maps_add_repos(_curr_repo);
+ menu_maps_add_repos();
gtk_menu_append(menu, gtk_separator_menu_item_new());
gboolean menu_cb_view_goto_nextway(GtkMenuItem *item);
gboolean menu_cb_view_goto_nearpoi(GtkMenuItem *item);
-void menu_maps_remove_repos();
-void menu_maps_add_repos();
-void menu_init();
+void menu_maps_remove_repos(void);
+void menu_maps_add_repos(void);
+void menu_init(void);
#endif /* ifndef MAEMO_MAPPER_MENU_H */
void path_resize(Path *path, gint size);
void path_wresize(Path *path, gint wsize);
-void path_save_route_to_db();
+void path_save_route_to_db(void);
-void route_find_nearest_point();
+void route_find_nearest_point(void);
gboolean route_show_distance_to(Point *point);
-void route_show_distance_to_next();
-void route_show_distance_to_last();
+void route_show_distance_to_next(void);
+void route_show_distance_to_last(void);
-void track_show_distance_from_last();
-void track_show_distance_from_first();
+void track_show_distance_from_last(void);
+void track_show_distance_from_first(void);
gboolean track_add(time_t time, gboolean newly_fixed);
-void track_clear();
+void track_clear(void);
void track_insert_break(gboolean temporary);
-void path_reset_route();
+void path_reset_route(void);
-void cancel_autoroute();
+void cancel_autoroute(void);
WayPoint * find_nearest_waypoint(gint unitx, gint unity);
gboolean route_download(gchar *to);
void route_add_way_dialog(gint unitx, gint unity);
-WayPoint* path_get_next_way();
+WayPoint* path_get_next_way(void);
-void path_init();
-void path_destroy();
+void path_init(void);
+void path_destroy(void);
#endif /* ifndef MAEMO_MAPPER_PATH_H */
#ifndef MAEMO_MAPPER_POI_H
#define MAEMO_MAPPER_POI_H
-void poi_db_connect();
+void poi_db_connect(void);
gboolean get_nearest_poi(gint unitx, gint unity, PoiInfo *poi);
gboolean poi_download_dialog(gint unitx, gint unity);
gboolean poi_browse_dialog(gint unitx, gint unity);
-void map_render_poi();
+void map_render_poi(void);
-void poi_destroy();
+void poi_destroy(void);
#endif /* ifndef MAEMO_MAPPER_POI_H */
#include <string.h>
#include <math.h>
#include <osso-helplib.h>
+#include <dbus/dbus-glib.h>
#include <bt-dbus.h>
#include <hildon-widgets/hildon-note.h>
#include <hildon-widgets/hildon-color-button.h>
#include <hildon-widgets/hildon-file-chooser-dialog.h>
#include <hildon-widgets/hildon-number-editor.h>
#include <hildon-widgets/hildon-banner.h>
+#include <hildon-widgets/hildon-input-mode-hint.h>
#include <gconf/gconf-client.h>
#include "types.h"
#include "data.h"
#include "defines.h"
+#include "gps.h"
#include "display.h"
#include "gdk-pixbuf-rotate.h"
#include "maps.h"
#include "settings.h"
#include "util.h"
+typedef struct _ScanInfo ScanInfo;
+struct _ScanInfo {
+ GtkWidget *settings_dialog;
+ GtkWidget *txt_gps_bt_mac;
+ GtkWidget *scan_dialog;
+ GtkWidget *banner;
+ GtkListStore *store;
+ gint sid;
+ DBusGConnection *bus;
+ DBusGProxy *req_proxy;
+ DBusGProxy *sig_proxy;
+};
+
+typedef struct _KeysDialogInfo KeysDialogInfo;
+struct _KeysDialogInfo {
+ GtkWidget *cmb[CUSTOM_KEY_ENUM_COUNT];
+};
+
+typedef struct _ColorsDialogInfo ColorsDialogInfo;
+struct _ColorsDialogInfo {
+ GtkWidget *col[COLORABLE_ENUM_COUNT];
+};
+
+
/**
* Save all configuration data to GCONF.
*/
scan_start_search(ScanInfo *scan_info)
{
GError *error = NULL;
- DBusGConnection *dbus_conn;
printf("%s()\n", __PRETTY_FUNCTION__);
/* Initialize D-Bus. */
- if(NULL == (dbus_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error)))
+ if(NULL == (scan_info->bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error)))
{
g_printerr("Failed to open connection to D-Bus: %s.\n",
error->message);
return 1;
}
- if(NULL == (scan_info->req_proxy = dbus_g_proxy_new_for_name(dbus_conn,
+ if(NULL == (scan_info->req_proxy =dbus_g_proxy_new_for_name(scan_info->bus,
BTSEARCH_SERVICE,
BTSEARCH_REQ_PATH,
BTSEARCH_REQ_INTERFACE)))
return 2;
}
- if(NULL == (scan_info->sig_proxy = dbus_g_proxy_new_for_name(dbus_conn,
+ if(NULL == (scan_info->sig_proxy =dbus_g_proxy_new_for_name(scan_info->bus,
BTSEARCH_SERVICE,
BTSEARCH_SIG_PATH,
BTSEARCH_SIG_INTERFACE)))
gtk_widget_destroy(dialog);
/* Clean up D-Bus. */
- dbus_g_proxy_call(scan_info->req_proxy, BTSEARCH_STOP_SEARCH_REQ,
- &error, G_TYPE_INVALID, G_TYPE_INVALID);
- g_object_unref(scan_info->req_proxy);
- g_object_unref(scan_info->sig_proxy);
+ if(scan_info->req_proxy)
+ {
+ dbus_g_proxy_call(scan_info->req_proxy, BTSEARCH_STOP_SEARCH_REQ,
+ &error, G_TYPE_INVALID, G_TYPE_INVALID);
+ g_object_unref(scan_info->req_proxy);
+ scan_info->req_proxy = NULL;
+ }
+ if(scan_info->sig_proxy)
+ {
+ g_object_unref(scan_info->sig_proxy);
+ scan_info->sig_proxy = NULL;
+ }
+ if(scan_info->bus)
+ {
+ dbus_g_connection_unref(scan_info->bus);
+ scan_info->bus = NULL;
+ }
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
/* Receiver MAC Address. */
gtk_table_attach(GTK_TABLE(table),
rad_gps_bt = gtk_radio_button_new_with_label(
- NULL, _("MAC Address")),
+ NULL, _("Bluetooth")),
0, 1, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
gtk_box_pack_start(GTK_BOX(hbox),
txt_gps_bt_mac = gtk_entry_new(),
TRUE, TRUE, 0);
+ g_object_set(G_OBJECT(txt_gps_bt_mac), HILDON_AUTOCAP, FALSE, NULL);
gtk_box_pack_start(GTK_BOX(hbox),
btn_scan = gtk_button_new_with_label(_("Scan...")),
FALSE, FALSE, 0);
- /* GPSD Hostname and Port. */
+ /* File Path (RFComm). */
gtk_table_attach(GTK_TABLE(table),
- rad_gps_gpsd = gtk_radio_button_new_with_label_from_widget(
- GTK_RADIO_BUTTON(rad_gps_bt), _("GPSD Host")),
+ rad_gps_file = gtk_radio_button_new_with_label_from_widget(
+ GTK_RADIO_BUTTON(rad_gps_bt), _("File Path")),
0, 1, 1, 2, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
hbox = gtk_hbox_new(FALSE, 4),
1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_box_pack_start(GTK_BOX(hbox),
- txt_gps_gpsd_host = gtk_entry_new(),
+ txt_gps_file_path = gtk_entry_new(),
TRUE, TRUE, 0);
+ g_object_set(G_OBJECT(txt_gps_file_path), HILDON_AUTOCAP, FALSE, NULL);
gtk_box_pack_start(GTK_BOX(hbox),
- label = gtk_label_new(_("Port")),
- FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox),
- num_gps_gpsd_port = hildon_number_editor_new(1, 65535),
+ btn_browse_gps = gtk_button_new_with_label(_("Browse...")),
FALSE, FALSE, 0);
- /* File Path (RFComm). */
+ /* GPSD Hostname and Port. */
gtk_table_attach(GTK_TABLE(table),
- rad_gps_file = gtk_radio_button_new_with_label_from_widget(
- GTK_RADIO_BUTTON(rad_gps_bt), _("File Path")),
+ rad_gps_gpsd = gtk_radio_button_new_with_label_from_widget(
+ GTK_RADIO_BUTTON(rad_gps_bt), _("GPSD Host")),
0, 1, 2, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
hbox = gtk_hbox_new(FALSE, 4),
1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_box_pack_start(GTK_BOX(hbox),
- txt_gps_file_path = gtk_entry_new(),
+ txt_gps_gpsd_host = gtk_entry_new(),
TRUE, TRUE, 0);
+ g_object_set(G_OBJECT(txt_gps_gpsd_host), HILDON_AUTOCAP, FALSE, NULL);
gtk_box_pack_start(GTK_BOX(hbox),
- btn_browse_gps = gtk_button_new_with_label(_("Browse...")),
+ label = gtk_label_new(_("Port")),
+ FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ num_gps_gpsd_port = hildon_number_editor_new(1, 65535),
FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox),
txt_poi_db = gtk_entry_new(),
TRUE, TRUE, 0);
+ g_object_set(G_OBJECT(txt_poi_db), HILDON_AUTOCAP, FALSE, NULL);
gtk_box_pack_start(GTK_BOX(hbox),
btn_browse_poi = gtk_button_new_with_label(_("Browse...")),
FALSE, FALSE, 0);
num_poi_zoom = hildon_number_editor_new(0, MAX_ZOOM));
/* Connect signals. */
+ memset(&scan_info, 0, sizeof(scan_info));
scan_info.settings_dialog = dialog;
scan_info.txt_gps_bt_mac = txt_gps_bt_mac;
g_signal_connect(G_OBJECT(btn_scan), "clicked",
{
GpsRcvrType new_grtype;
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_gpsd))
+ && !*gtk_entry_get_text(GTK_ENTRY(txt_gps_gpsd_host)))
+ {
+ popup_error(dialog, _("Please specify a GPSD hostname."));
+ continue;
+ }
+
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_file))
+ && !*gtk_entry_get_text(GTK_ENTRY(txt_gps_file_path)))
+ {
+ popup_error(dialog, _("Please specify a GPS file pathname."));
+ continue;
+ }
+
/* Set _gri.bt_mac if necessary. */
if(!*gtk_entry_get_text(GTK_ENTRY(txt_gps_bt_mac)))
{
}
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_bt)))
- new_grtype = _gri.bt_mac ? GPS_RCVR_BT : GPS_RCVR_NONE;
+ new_grtype = GPS_RCVR_BT;
else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_gpsd)))
- new_grtype = _gri.gpsd_host ? GPS_RCVR_GPSD : GPS_RCVR_NONE;
+ new_grtype = GPS_RCVR_GPSD;
else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_file)))
- new_grtype = _gri.file_path ? GPS_RCVR_FILE : GPS_RCVR_NONE;
+ new_grtype = GPS_RCVR_FILE;
else
- new_grtype = GPS_RCVR_NONE;
+ new_grtype = GPS_RCVR_BT;
if(new_grtype != _gri.type)
{
rcvr_changed = TRUE;
}
- if(_gri.type != GPS_RCVR_NONE)
- {
- gtk_widget_set_sensitive(
- GTK_WIDGET(_menu_gps_details_item), FALSE);
- }
- else
- {
- if(_enable_gps)
- {
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), FALSE);
- popup_error(dialog, _("No GPS Receiver provided.\n"
- "GPS will be disabled."));
- rcvr_changed = TRUE;
- gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item),
- FALSE);
- gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item),
- FALSE);
- }
- }
-
_center_ratio = hildon_controlbar_get_value(
HILDON_CONTROLBAR(num_center_ratio));
_gri.bt_mac = gconf_client_get_string(
gconf_client, GCONF_KEY_GPS_BT_MAC, NULL);
- /* Get GPSD Host. Default is NULL. */
+ /* Get GPSD Host. Default is localhost. */
_gri.gpsd_host = gconf_client_get_string(
gconf_client, GCONF_KEY_GPS_GPSD_HOST, NULL);
+ if(!_gri.gpsd_host)
+ _gri.gpsd_host = g_strdup("127.0.0.1");
- /* Get GPSD Port. Default is 2947. */
+ /* Get GPSD Port. Default is GPSD_PORT_DEFAULT (2947). */
if(!(_gri.gpsd_port = gconf_client_get_int(
gconf_client, GCONF_KEY_GPS_GPSD_PORT, NULL)))
- _gri.gpsd_port = 2947;
+ _gri.gpsd_port = GPSD_PORT_DEFAULT;
- /* Get File Path. Default is NULL. */
+ /* Get File Path. Default is /dev/pgps. */
_gri.file_path = gconf_client_get_string(
gconf_client, GCONF_KEY_GPS_FILE_PATH, NULL);
+ if(!_gri.file_path)
+ _gri.file_path = g_strdup("/dev/pgps");
/* Get Auto-Download. Default is FALSE. */
_auto_download = gconf_client_get_bool(gconf_client,
gconf_value_free(value);
}
else
+ {
+ _is_first_time = TRUE;
center_lat = _gps.lat;
+ }
/* Get last saved longitude. Default is last saved longitude. */
value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LON, NULL);
#ifndef MAEMO_MAPPER_SETTINGS_H
#define MAEMO_MAPPER_SETTINGS_H
-#include <dbus/dbus-glib.h>
-
-typedef struct _ScanInfo ScanInfo;
-struct _ScanInfo {
- GtkWidget *settings_dialog;
- GtkWidget *txt_gps_bt_mac;
- GtkWidget *scan_dialog;
- GtkWidget *banner;
- GtkListStore *store;
- gint sid;
- DBusGProxy *req_proxy;
- DBusGProxy *sig_proxy;
-};
-
-typedef struct _KeysDialogInfo KeysDialogInfo;
-struct _KeysDialogInfo {
- GtkWidget *cmb[CUSTOM_KEY_ENUM_COUNT];
-};
-
-typedef struct _ColorsDialogInfo ColorsDialogInfo;
-struct _ColorsDialogInfo {
- GtkWidget *col[COLORABLE_ENUM_COUNT];
-};
-
-
RepoData* settings_parse_repo(gchar *str);
-void settings_init();
-void settings_save();
+void settings_init(void);
+void settings_save(void);
-gboolean settings_dialog();
+gboolean settings_dialog(void);
#endif /* ifndef MAEMO_MAPPER_SETTINGS_H */
typedef enum
{
- GPS_RCVR_NONE,
GPS_RCVR_BT,
GPS_RCVR_GPSD,
GPS_RCVR_FILE,
void force_min_visible_bars(HildonControlbar *control_bar, gint num_bars);
-gboolean banner_reset();
+gboolean banner_reset(void);
void deg_format(gdouble coor, gchar *scoor, gchar neg_char, gchar pos_char);