Skip to content
Browse files

initial GPS support added

  • Loading branch information...
1 parent 464be59 commit bf310e44e90c9be6cf2a64224fdf962288f8e811 Duncan Cragg committed Apr 27, 2010
Showing with 330 additions and 76 deletions.
  1. +57 −56 SConscript.py
  2. +2 −1 accelerometer.cpp
  3. +0 −3 accelerometer.h
  4. +68 −0 gps.cpp
  5. +28 −0 gps.h
  6. +64 −0 javascript/gps.js
  7. +7 −1 phonegap-compressed.js
  8. +65 −0 phonegap.js
  9. +3 −1 phonegap.pro
  10. +4 −0 webview.cpp
  11. +2 −0 webview.h
  12. +11 −12 www-example/index.html
  13. +7 −1 www-example/phonegap.js
  14. +12 −1 www-example/webgldemo.js
View
113 SConscript.py
@@ -1,56 +1,57 @@
-import os
-from os.path import join, exists
-
-PHONEGAP_LIB = "phonegap.js"
-PHONEGAP_COMPRESSED = "phonegap-compressed.js"
-APPNAME = "PhoneGap"
-
-def CommandMakePhonegapJS(env, source, target):
-
- print target[0].path
- ft = open( target[0].path, 'wb' )
-
- for s in source:
- fs = open( s.path, 'rb')
- d = d = fs.read();
- while len(d) != 0:
- ft.write( d )
- d = fs.read();
-
- fs.close()
-
- ft.write( os.linesep )
-
- ft.close()
-
-jssources = [
- "phonegap.js",
- "device.js",
- "accelerometer.js",
- "gles2.js",
- "notification.js"
-]
-
-javascripts = []
-JSROOTPATH= "javascript"
-
-for js in jssources:
- maemolib = join( JSROOTPATH, js )
- if exists( maemolib ):
- javascripts.append( maemolib )
-
-Command( PHONEGAP_LIB, javascripts, CommandMakePhonegapJS )
-
-# Compress javascripts
-#compress = "java -jar ../util/yuicompressor-2.4.2.jar --charset UTF-8 -o $TARGET $SOURCE"
-
-from pylib import jsmin
-
-def CommandCompressJS(env, source, target):
- jsm = jsmin.JavascriptMinify()
- for s in source:
- for t in target:
- jsm.minify(open(s.path), open(t.path,'w'))
-
-Command( PHONEGAP_COMPRESSED, PHONEGAP_LIB, CommandCompressJS )
-
+import os
+from os.path import join, exists
+
+PHONEGAP_LIB = "phonegap.js"
+PHONEGAP_COMPRESSED = "phonegap-compressed.js"
+APPNAME = "PhoneGap"
+
+def CommandMakePhonegapJS(env, source, target):
+
+ print target[0].path
+ ft = open( target[0].path, 'wb' )
+
+ for s in source:
+ fs = open( s.path, 'rb')
+ d = d = fs.read();
+ while len(d) != 0:
+ ft.write( d )
+ d = fs.read();
+
+ fs.close()
+
+ ft.write( os.linesep )
+
+ ft.close()
+
+jssources = [
+ "phonegap.js",
+ "device.js",
+ "accelerometer.js",
+ "gps.js",
+ "gles2.js",
+ "notification.js"
+]
+
+javascripts = []
+JSROOTPATH= "javascript"
+
+for js in jssources:
+ maemolib = join( JSROOTPATH, js )
+ if exists( maemolib ):
+ javascripts.append( maemolib )
+
+Command( PHONEGAP_LIB, javascripts, CommandMakePhonegapJS )
+
+# Compress javascripts
+#compress = "java -jar ../util/yuicompressor-2.4.2.jar --charset UTF-8 -o $TARGET $SOURCE"
+
+from pylib import jsmin
+
+def CommandCompressJS(env, source, target):
+ jsm = jsmin.JavascriptMinify()
+ for s in source:
+ for t in target:
+ jsm.minify(open(s.path), open(t.path,'w'))
+
+Command( PHONEGAP_COMPRESSED, PHONEGAP_LIB, CommandCompressJS )
+
View
3 accelerometer.cpp
@@ -4,6 +4,8 @@
#include <QWebFrame>
#include <QWebPage>
+#include <dbus/dbus-glib.h>
+
#include "utils.h"
#include "accelerometer.h"
@@ -27,7 +29,6 @@ static void AccelerometerCallback(DBusGProxy *proxy, DBusGProxyCall *call, void
{
gchar *s1, *s2, *s3;
gint x, y, z;
- gchar facing = 0;
if (dbus_g_proxy_end_call (proxy, call, NULL,
G_TYPE_STRING, &s1,
View
3 accelerometer.h
@@ -6,9 +6,6 @@
// See Maemo API at: http://wiki.maemo.org/Accelerometers
-#include <dbus/dbus-glib.h>
-
-
class Accelerometer : public QObject
{
Q_OBJECT
View
68 gps.cpp
@@ -0,0 +1,68 @@
+
+#include <QtDebug>
+#include <QWebFrame>
+#include <QWebPage>
+
+#include <stdio.h>
+
+#include "utils.h"
+#include "gps.h"
+
+static QWebView *gWebView = NULL;
+
+static void on_gps_changed(LocationGPSDevice *device, gpointer data)
+{
+ printf("on_gps_changed\n");
+ if(!device) return;
+
+ if(device->fix && (device->fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET)){
+
+ printf("lat = %f, long = %f\n", device->fix->latitude, device->fix->longitude);
+ gfloat latitude = device->fix->latitude;
+ gfloat longitude = device->fix->longitude;
+
+ location_gpsd_control_stop((LocationGPSDControl *) data);
+
+ QString callback = QString("__PG_GPS_CALLBACK(%1,%2);").arg(latitude).arg(longitude);
+ gWebView->page()->mainFrame()->evaluateJavaScript(callback);
+ }
+}
+
+static void on_gps_error(LocationGPSDControl *control, LocationGPSDControlError error, gpointer data)
+{
+ printf("on_gps_error: %d %p %p\n", error, control, data);
+}
+
+static void on_gps_stop(LocationGPSDControl *control, gpointer data)
+{
+ printf("on_gps_stop %p %p\n", control, data);
+}
+
+GPS::GPS(QWebView *aWebView): iWebView(aWebView)
+{
+ gWebView = iWebView;
+
+ control = location_gpsd_control_get_default();
+ device = (LocationGPSDevice*)g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL);
+
+ g_object_set(G_OBJECT(control),
+ "preferred-method", LOCATION_METHOD_USER_SELECTED,
+ "preferred-interval", LOCATION_INTERVAL_5S,
+ NULL);
+
+ g_signal_connect(control, "error-verbose", G_CALLBACK(on_gps_error), 0);
+ g_signal_connect(device, "changed", G_CALLBACK(on_gps_changed), 0);
+ g_signal_connect(control, "gpsd-stopped", G_CALLBACK(on_gps_stop), 0);
+}
+
+GPS::~GPS()
+{
+ g_object_unref(device);
+ g_object_unref(control);
+}
+
+void GPS::get(){
+ printf("get: location_gpsd_control_start\n");
+ location_gpsd_control_start(control);
+}
+
View
28 gps.h
@@ -0,0 +1,28 @@
+#ifndef GPS_H
+#define GPS_H
+
+#include <location/location-gps-device.h>
+#include <location/location-gpsd-control.h>
+
+#include <QObject>
+#include <QWebView>
+
+class GPS : public QObject
+{
+ Q_OBJECT
+
+public:
+ GPS(QWebView*);
+ ~GPS();
+
+public slots:
+ void get();
+
+ private:
+
+ QWebView* iWebView;
+ LocationGPSDControl *control;
+ LocationGPSDevice *device;
+};
+
+#endif // GPS_H
View
64 javascript/gps.js
@@ -0,0 +1,64 @@
+
+/**
+ * This class provides access to device GPS data.
+ * @constructor
+ */
+function GPS() {
+ /**
+ * The last known coordinates.
+ */
+ this.lastCoordinates = null;
+}
+
+/**
+ * Asynchronously aquires the current GPS coordinates.
+ * @param {Function} successCallback The function to call when the
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the GPS data.
+ * @param {GPSOptions} options The options for getting the GPS data
+ * such as timeout.
+ */
+__PG_GPS_CALLBACK_USER = null;
+__PG_GPS_CALLBACK = function(latitude, longitude)
+{
+ var coords = { latitude:latitude, longitude:longitude, };
+ __PG_GPS_CALLBACK_USER(coords);
+ GPS.lastCoordinates = coords;
+}
+
+GPS.prototype.getCurrentCoordinates = function(successCallback, errorCallback, options) {
+ if (typeof successCallback == "function") {
+ _NativeGPS.get();
+ __PG_GPS_CALLBACK_USER = successCallback;
+ }
+}
+
+/**
+ * Asynchronously aquires the coordinates repeatedly at a given interval.
+ * @param {Function} successCallback The function to call each time the GPS
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the GPS data.
+ * @param {GPSOptions} options The options for getting the GPS data
+ * such as timeout.
+ */
+GPS.prototype.watchGPS = function(successCallback, errorCallback, options) {
+ this.getCurrentCoordinates(successCallback, errorCallback, options);
+ // TODO: add the interval id to a list so we can clear all watches
+ var frequency = (options != undefined)? options.frequency : 10000;
+ return setInterval(function() {
+ navigator.gps.getCurrentCoordinates(successCallback, errorCallback, options);
+ }, frequency);
+}
+
+/**
+ * Clears the specified GPS watch.
+ * @param {String} watchId The ID of the watch returned from #watchGPS.
+ */
+GPS.prototype.clearWatch = function(watchId) {
+ clearInterval(watchId);
+}
+
+if (typeof navigator.gps == "undefined") navigator.gps = new GPS();
+
View
8 phonegap-compressed.js
@@ -8,7 +8,13 @@ __PG_ACCELEROMETER_CALLBACK_USER=null;__PG_ACCELEROMETER_CALLBACK=function(x,y,z
Accelerometer.prototype.getCurrentAcceleration=function(successCallback,errorCallback,options){if(typeof successCallback=="function"){_NativeAccelerometer.get();__PG_ACCELEROMETER_CALLBACK_USER=successCallback;}}
Accelerometer.prototype.watchAcceleration=function(successCallback,errorCallback,options){this.getCurrentAcceleration(successCallback,errorCallback,options);var frequency=(options!=undefined)?options.frequency:10000;return setInterval(function(){navigator.accelerometer.getCurrentAcceleration(successCallback,errorCallback,options);},frequency);}
Accelerometer.prototype.clearWatch=function(watchId){clearInterval(watchId);}
-if(typeof navigator.accelerometer=="undefined")navigator.accelerometer=new Accelerometer();if(typeof _NativeGLES2!="undefined"){function GLES2(){}
+if(typeof navigator.accelerometer=="undefined")navigator.accelerometer=new Accelerometer();function GPS(){this.lastCoordinates=null;}
+__PG_GPS_CALLBACK_USER=null;__PG_GPS_CALLBACK=function(latitude,longitude)
+{var coords={latitude:latitude,longitude:longitude,};__PG_GPS_CALLBACK_USER(coords);GPS.lastCoordinates=coords;}
+GPS.prototype.getCurrentCoordinates=function(successCallback,errorCallback,options){if(typeof successCallback=="function"){_NativeGPS.get();__PG_GPS_CALLBACK_USER=successCallback;}}
+GPS.prototype.watchGPS=function(successCallback,errorCallback,options){this.getCurrentCoordinates(successCallback,errorCallback,options);var frequency=(options!=undefined)?options.frequency:10000;return setInterval(function(){navigator.gps.getCurrentCoordinates(successCallback,errorCallback,options);},frequency);}
+GPS.prototype.clearWatch=function(watchId){clearInterval(watchId);}
+if(typeof navigator.gps=="undefined")navigator.gps=new GPS();if(typeof _NativeGLES2!="undefined"){function GLES2(){}
GLES2.prototype.FRAGMENT_SHADER=_NativeGLES2.FRAGMENT_SHADER();GLES2.prototype.VERTEX_SHADER=_NativeGLES2.VERTEX_SHADER();GLES2.prototype.viewport=function(x,y,w,h){_NativeGLES2.viewport(x,y,w,h);}
GLES2.prototype.createShader=function(type){return _NativeGLES2.createShader(type);}
GLES2.prototype.pass=function(){_NativeGLES2.pass();}
View
65 phonegap.js
@@ -86,6 +86,71 @@ Accelerometer.prototype.clearWatch = function(watchId) {
if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer();
+
+/**
+ * This class provides access to device GPS data.
+ * @constructor
+ */
+function GPS() {
+ /**
+ * The last known coordinates.
+ */
+ this.lastCoordinates = null;
+}
+
+/**
+ * Asynchronously aquires the current GPS coordinates.
+ * @param {Function} successCallback The function to call when the
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the GPS data.
+ * @param {GPSOptions} options The options for getting the GPS data
+ * such as timeout.
+ */
+__PG_GPS_CALLBACK_USER = null;
+__PG_GPS_CALLBACK = function(latitude, longitude)
+{
+ var coords = { latitude:latitude, longitude:longitude, };
+ __PG_GPS_CALLBACK_USER(coords);
+ GPS.lastCoordinates = coords;
+}
+
+GPS.prototype.getCurrentCoordinates = function(successCallback, errorCallback, options) {
+ if (typeof successCallback == "function") {
+ _NativeGPS.get();
+ __PG_GPS_CALLBACK_USER = successCallback;
+ }
+}
+
+/**
+ * Asynchronously aquires the coordinates repeatedly at a given interval.
+ * @param {Function} successCallback The function to call each time the GPS
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error
+ * getting the GPS data.
+ * @param {GPSOptions} options The options for getting the GPS data
+ * such as timeout.
+ */
+GPS.prototype.watchGPS = function(successCallback, errorCallback, options) {
+ this.getCurrentCoordinates(successCallback, errorCallback, options);
+ // TODO: add the interval id to a list so we can clear all watches
+ var frequency = (options != undefined)? options.frequency : 10000;
+ return setInterval(function() {
+ navigator.gps.getCurrentCoordinates(successCallback, errorCallback, options);
+ }, frequency);
+}
+
+/**
+ * Clears the specified GPS watch.
+ * @param {String} watchId The ID of the watch returned from #watchGPS.
+ */
+GPS.prototype.clearWatch = function(watchId) {
+ clearInterval(watchId);
+}
+
+if (typeof navigator.gps == "undefined") navigator.gps = new GPS();
+
+
/**
* This class provides access to GL ES 2.0
*/
View
4 phonegap.pro
@@ -10,7 +10,7 @@ INCLUDEPATH += /usr/include/dbus-1.0/
INCLUDEPATH += /usr/include/glib-2.0/
INCLUDEPATH += .
-LIBS += -lX11 -lEGL -lGLESv2
+LIBS += -lX11 -lEGL -lGLESv2 -llocation
QMAKE_LFLAGS += -Wl,-rpath-link,/opt/qt4-maemo5/lib -Wl,-rpath,/opt/qt4-maemo5/lib
@@ -20,6 +20,7 @@ SOURCES += main.cpp NativeExample.cpp \
webview.cpp \
debug.cpp \
accelerometer.cpp \
+ gps.cpp \
gles2.cpp \
notification.cpp
QT += webkit
@@ -31,6 +32,7 @@ HEADERS += commandmanager.h \
utils.h \
debug.h \
accelerometer.h \
+ gps.h \
gles2.h \
notification.h
OTHER_FILES += index.html
View
4 webview.cpp
@@ -28,6 +28,9 @@ void WebView::initJavascript( )
iAccelerometer= new Accelerometer(this);
frame->addToJavaScriptWindowObject(s("_NativeAccelerometer"), iAccelerometer);
+ iGPS = new GPS(this);
+ frame->addToJavaScriptWindowObject(s("_NativeGPS"), iGPS);
+
iNotification = new Notification( );
frame->addToJavaScriptWindowObject(s("_NativeNotification"), iNotification);
@@ -48,6 +51,7 @@ WebView::~WebView()
delete iDeviceInfo;
delete iDebug;
delete iAccelerometer;
+ delete iGPS;
delete iNotification;
delete iGLES2;
}
View
2 webview.h
@@ -9,6 +9,7 @@
#include "deviceinfo.h"
#include "debug.h"
#include "accelerometer.h"
+#include "gps.h"
#include "notification.h"
#include "gles2.h"
@@ -31,6 +32,7 @@ public slots:
DeviceInfo *iDeviceInfo;
Debug *iDebug;
Accelerometer *iAccelerometer;
+ GPS *iGPS;
Notification *iNotification;
GLES2 *iGLES2;
};
View
23 www-example/index.html
@@ -32,25 +32,24 @@
</head>
<body id="stage" class="theme" onload="initDemo()">
<div id="Page1">
- <div id="info" class="Panel"> <table>
- <tr>
- <td> <h4>Platform: <span id="platform">&nbsp;</span></h4> </td>
- <td> <h4>Version: <span id="version">&nbsp;</span></h4> </td>
- </tr>
- <tr>
- <td colspan="2"> <h4>Device Name: <span id="devicename">&nbsp;</span></h4> </td>
- </tr>
- <tr>
- <td colspan="2"> <h4>UUID: <span id="uuid">&nbsp;</span></h4> </td>
- </tr>
- </table> </div>
+ <div id="info" class="Panel">
+ <h4>Platform: <span id="platform">&nbsp;</span></h4>
+ <h4>Version: <span id="version">&nbsp;</span></h4>
+ <h4>Device Name: <span id="devicename">&nbsp;</span></h4>
+ <h4>UUID: <span id="uuid">&nbsp;</span></h4>
+ </div>
<dl id="accel-data">
<dt>X:</dt><dd id="x">&nbsp;</dd>
<dt>Y:</dt><dd id="y">&nbsp;</dd>
<dt>Z:</dt><dd id="z">&nbsp;</dd>
</dl>
+ <dl id="gps-data">
+ <dt>Latitude: </dt><dd id="latitude">&nbsp;</dd>
+ <dt>Longitude: </dt><dd id="longitude">&nbsp;</dd>
+ </dl>
<a href="#" class="btn" onclick="deviceInfo();">Show Device Info</a>
<a href="#" class="btn large" onclick="watchAccel();">Watch Accelerometer</a>
+ <a href="#" class="btn large" onclick="showGPS();" >Show GPS Data</a>
<a href="#" class="btn" onclick="showAlert();" >Alert</a>
<a href="#" class="btn" onclick="beep();" >Beep</a>
<a href="#" class="btn" onclick="vibrate();" >Vibrate</a>
View
8 www-example/phonegap.js
@@ -8,7 +8,13 @@ __PG_ACCELEROMETER_CALLBACK_USER=null;__PG_ACCELEROMETER_CALLBACK=function(x,y,z
Accelerometer.prototype.getCurrentAcceleration=function(successCallback,errorCallback,options){if(typeof successCallback=="function"){_NativeAccelerometer.get();__PG_ACCELEROMETER_CALLBACK_USER=successCallback;}}
Accelerometer.prototype.watchAcceleration=function(successCallback,errorCallback,options){this.getCurrentAcceleration(successCallback,errorCallback,options);var frequency=(options!=undefined)?options.frequency:10000;return setInterval(function(){navigator.accelerometer.getCurrentAcceleration(successCallback,errorCallback,options);},frequency);}
Accelerometer.prototype.clearWatch=function(watchId){clearInterval(watchId);}
-if(typeof navigator.accelerometer=="undefined")navigator.accelerometer=new Accelerometer();if(typeof _NativeGLES2!="undefined"){function GLES2(){}
+if(typeof navigator.accelerometer=="undefined")navigator.accelerometer=new Accelerometer();function GPS(){this.lastCoordinates=null;}
+__PG_GPS_CALLBACK_USER=null;__PG_GPS_CALLBACK=function(latitude,longitude)
+{var coords={latitude:latitude,longitude:longitude,};__PG_GPS_CALLBACK_USER(coords);GPS.lastCoordinates=coords;}
+GPS.prototype.getCurrentCoordinates=function(successCallback,errorCallback,options){if(typeof successCallback=="function"){_NativeGPS.get();__PG_GPS_CALLBACK_USER=successCallback;}}
+GPS.prototype.watchGPS=function(successCallback,errorCallback,options){this.getCurrentCoordinates(successCallback,errorCallback,options);var frequency=(options!=undefined)?options.frequency:10000;return setInterval(function(){navigator.gps.getCurrentCoordinates(successCallback,errorCallback,options);},frequency);}
+GPS.prototype.clearWatch=function(watchId){clearInterval(watchId);}
+if(typeof navigator.gps=="undefined")navigator.gps=new GPS();if(typeof _NativeGLES2!="undefined"){function GLES2(){}
GLES2.prototype.FRAGMENT_SHADER=_NativeGLES2.FRAGMENT_SHADER();GLES2.prototype.VERTEX_SHADER=_NativeGLES2.VERTEX_SHADER();GLES2.prototype.viewport=function(x,y,w,h){_NativeGLES2.viewport(x,y,w,h);}
GLES2.prototype.createShader=function(type){return _NativeGLES2.createShader(type);}
GLES2.prototype.pass=function(){_NativeGLES2.pass();}
View
13 www-example/webgldemo.js
@@ -27,7 +27,18 @@ function watchAccel() {
var fail = function(){};
var opt = {};
opt.frequency = 500;
- timer = navigator.accelerometer.watchAcceleration(suc,fail,opt);
+ navigator.accelerometer.watchAcceleration(suc,fail,opt);
+}
+
+function showGPS() {
+ var suc = function(g){
+ document.getElementById('latitude' ).innerHTML = roundNumber(g.latitude, 6);
+ document.getElementById('longitude').innerHTML = roundNumber(g.longitude, 6);
+ };
+ var fail = function(){};
+ var opt = {};
+ opt.frequency = 10000;
+ navigator.gps.watchGPS(suc,fail,opt);
}
function roundNumber(num, dec) { return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); }

0 comments on commit bf310e4

Please sign in to comment.
Something went wrong with that request. Please try again.