francesco.dev...@mailoo.org writes:

> Also, in QX the option "rotate screen" does nothing, what should it do?

I have some theoretical patches for that (attached), but I haven't
offered them to Radek because I haven't really got QX working much at
all, and so I couldn't be sure if the QX rotation support was working.

The first attached patch is for the main QtMoko repository; the second
is for the Arora submodule.

Regards,
        Neil

>From 2cdb6f0b0e8393379670efe7e4aee6e89056995d Mon Sep 17 00:00:00 2001
From: Neil Jerram <n...@ossau.homelinux.net>
Date: Tue, 17 Jul 2012 22:55:15 +0200
Subject: [PATCH] Improve accelerometer library, and use it in Arora and QX
 for autorotation

---
 src/3rdparty/applications/arora                |    2 +-
 src/3rdparty/applications/qx/qbuild.pro        |    1 +
 src/3rdparty/applications/qx/rotate.cpp        |   76 ++++--------------------
 src/3rdparty/applications/qx/rotate.h          |    5 --
 src/3rdparty/games/qtmaze/form.cpp             |    2 +-
 src/libraries/accelerometer/accelerometers.cpp |   65 ++++++++++++++++----
 src/libraries/accelerometer/accelerometers.h   |    6 +-
 7 files changed, 72 insertions(+), 85 deletions(-)

diff --git a/src/3rdparty/applications/arora b/src/3rdparty/applications/arora
index 6fe8d25..c4938dc 160000
--- a/src/3rdparty/applications/arora
+++ b/src/3rdparty/applications/arora
@@ -1 +1 @@
-Subproject commit 6fe8d25fd36dbc29b5e6c479db1193e6523eeb7b
+Subproject commit c4938dce05b27426334cd32d594084fbd055880d
diff --git a/src/3rdparty/applications/qx/qbuild.pro b/src/3rdparty/applications/qx/qbuild.pro
index a22a561..3fbf3e7 100644
--- a/src/3rdparty/applications/qx/qbuild.pro
+++ b/src/3rdparty/applications/qx/qbuild.pro
@@ -4,6 +4,7 @@ TARGET=qx
 CONFIG+=qtopia
 LIBS+=-lX11 -lXtst
 DEFINES+=QTOPIA
+MODULES*=accelerometer
 
 # I18n info
 STRING_LANGUAGE=en_US
diff --git a/src/3rdparty/applications/qx/rotate.cpp b/src/3rdparty/applications/qx/rotate.cpp
index 52302d6..4463698 100644
--- a/src/3rdparty/applications/qx/rotate.cpp
+++ b/src/3rdparty/applications/qx/rotate.cpp
@@ -7,6 +7,8 @@
 
 #include <stdlib.h>
 
+#include <accelerometers.h>
+
 /**
  * The acceleromer algorithms and code taken from omnewrotate-0.5.4
  * Copyright © 2008 Rui Miguel Silva Seabra <r...@1407.org>
@@ -55,9 +57,7 @@ RotateHelper::RotateHelper(QObject *parent, int dflg) : QObject(parent)
 	down = 0;
 	last_pos= -1;
 	current_pos = -1;
-	event3 = -1;
 	debug = dflg;
-	skip_zero = 1;
 	initial_rotation= -1;
 }
 
@@ -88,6 +88,9 @@ void RotateHelper::start(int timeinms)
 		stop();
 	}
 
+	// start accelerometer
+	accelerometer_start(timeinms, NULL, NULL);
+
 	// start up a single shot timer to check accelerometers
 	// it will be restarted each time
 	timer = new QTimer(this);
@@ -103,10 +106,8 @@ void RotateHelper::stop()
 		timer= NULL;
 	}
 
-	if(event3 != -1){
-		close(event3);
-		event3= -1;
-	}
+	// stop accelerometer
+	accelerometer_stop();
 }
 
 void rotate(int degree)
@@ -145,6 +146,10 @@ void RotateHelper::maybe_rotate(int deg)
 
 void RotateHelper::sample()
 {
+	x = 1000 * getacx();
+	y = 1000 * getacy();
+	z = 1000 * getacz();
+
 	if(packet_reader()){
 		int pos= define_position();
 		if(pos != last_pos)
@@ -218,66 +223,9 @@ int RotateHelper::define_position(void)
 	return current_pos;
 }
 
-
-int RotateHelper::read_packet()
-{
-	static struct input_event event_x, event_y, event_z, event_syn;
-	void *packet_memcpy_result = NULL;
-	int packet_size = sizeof(struct input_event);
-	int size_of_packet = 4 * packet_size;
-	int bytes_read = 0;
-	char packet[size_of_packet];
-
-	bytes_read = read(event3, packet, size_of_packet);
-
-	if (bytes_read < packet_size)
-	{
-		qWarning("RotateHelper: fread failed");
-		stop();
-		return -1;
-	}
-
-	/* obtain the full packet */
-	packet_memcpy_result = memcpy(&event_x,   packet,                   packet_size);
-	packet_memcpy_result = memcpy(&event_y,   packet +     packet_size, packet_size);
-	packet_memcpy_result = memcpy(&event_z,   packet + 2 * packet_size, packet_size);
-	packet_memcpy_result = memcpy(&event_syn, packet + 3 * packet_size, packet_size);
-
-	if(skip_zero && (event_x.value == 0 || event_y.value == 0 || event_z.value == 0))
-	{
-		//	qDebug("Bad packet!");
-		return(0);
-	}
-
-	if (event_syn.type == EV_SYN)
-	{
-		x = event_x.value;
-		y = event_y.value;
-		z = event_z.value;
-
-		return (1);
-	}
-	else
-		return (0);
-}
-
 bool RotateHelper::packet_reader()
 {
-	if(event3 == -1){
-		event3 = open(EVENT_PATH, O_RDONLY);
-
-		if (event3 < 0){
-			qWarning("Can't open '%s': %s\n", EVENT_PATH, strerror(errno));
-			return false;
-		}
-		qDebug("Opened: %s", EVENT_PATH);
-	}
-
-	while(read_packet() == 0);
-	
-	// qDebug("read packet");
-
-	return true;
+	return (x || y || z);
 }
 
 #else // QTOPIA
diff --git a/src/3rdparty/applications/qx/rotate.h b/src/3rdparty/applications/qx/rotate.h
index fdce73b..cfcc608 100644
--- a/src/3rdparty/applications/qx/rotate.h
+++ b/src/3rdparty/applications/qx/rotate.h
@@ -11,8 +11,6 @@
 
 #include <QTimer>
 
-#define EVENT_PATH "/dev/input/event3"
-
 #ifdef QTOPIA
 
 /**
@@ -42,7 +40,6 @@ signals:
 	void maybe_rotate(int deg);
 	int neighbour(int value, int target, int neighbour);
 	int define_position(void);
-	int read_packet();
 	bool packet_reader();
 	
 	QTimer *timer;
@@ -62,10 +59,8 @@ signals:
 	int down;
 	int last_pos;
 	int current_pos;
-	int event3;
 	int debug;
 	int initial_rotation;
-	ushort skip_zero;
 };
 
 #else // QTOPIA
diff --git a/src/3rdparty/games/qtmaze/form.cpp b/src/3rdparty/games/qtmaze/form.cpp
index 71ebfce..f021414 100644
--- a/src/3rdparty/games/qtmaze/form.cpp
+++ b/src/3rdparty/games/qtmaze/form.cpp
@@ -854,7 +854,7 @@ Form::Form(QWidget *parent, Qt::WFlags f)
     info1_lbl->setText( "<font color=\"#e0bc70\" size=\"" FONT_SIZE "\">Touch the screen to continue</font>" );
 
     InitState();
-    accelerometer_start();
+    accelerometer_start(0, NULL, NULL);
 
     timer = new QTimer(this);
     connect(timer, SIGNAL(timeout()), this, SLOT(timerAction()));
diff --git a/src/libraries/accelerometer/accelerometers.cpp b/src/libraries/accelerometer/accelerometers.cpp
index d5f6681..0e22694 100644
--- a/src/libraries/accelerometer/accelerometers.cpp
+++ b/src/libraries/accelerometer/accelerometers.cpp
@@ -53,7 +53,17 @@
 #include "accelerometers.h"
 
 pthread_t thread;
-int finished=0;
+
+struct thread_data_t
+{
+  int finished;
+  useconds_t interval_us;
+  accelerometer_cb_t callback;
+  void *closure;
+};
+
+struct thread_data_t global_thread_data = { 0, 0, NULL, NULL };
+
 double acx=0,acy=0,acz=0;
 
 #ifdef QT_QWS_GTA04
@@ -154,6 +164,7 @@ int accelerometer_moo_gta04(AccelHandle *accel)
 	size_t rval;
 	fd_set fds;
 	struct timeval t;
+	int got_measurement = 0;
 
 	FD_ZERO(&fds);
 	FD_SET(accel->fd, &fds);
@@ -202,6 +213,7 @@ int accelerometer_moo_gta04(AccelHandle *accel)
 			accel->x = accel->lx;
 			accel->y = accel->ly;
 			accel->z = accel->lz;
+			got_measurement = 1;
 		}
 	}
 
@@ -222,7 +234,7 @@ int accelerometer_moo_gta04(AccelHandle *accel)
         if (acy<-1) acy=-1; if (acy>1) acy=1;
         //if (acz<-1) acz=-1; if (acz>1) acz=1;
 	
-	return 0;
+	return got_measurement;
 }
 
 int accelerometer_moo(AccelHandle *accel)
@@ -244,12 +256,24 @@ int accelerometer_moo(AccelHandle *accel)
 void* accel_work(void *data)
 {
 	AccelHandle *accel;
-        int *finished = (int*)data;
+	thread_data_t *my_thread_data = (thread_data_t *)data;
 
 	accel = accelerometer_open();
-	while ( !(*finished) ) {
-                accelerometer_moo(accel);
-                usleep(GET_DATA_INTERVAL);
+	while ( !(my_thread_data->finished) ) {
+
+		/* Call accelerometer_moo() until we have an
+		   acceleration measurement. */
+		while (!accelerometer_moo(accel))
+		  ;
+
+		/* If the library user specified a callback, call
+		   it. */
+		if (my_thread_data->callback)
+		  (*my_thread_data->callback)(my_thread_data->closure,
+					      acx, acy, acz);
+
+		/* Sleep before taking another measurement. */
+                usleep(my_thread_data->interval_us);
         }
 
 	accelerometer_shutdown(accel);
@@ -271,7 +295,7 @@ int pc_mode=0;
 /* The accelerometer work thread */
 void* accel_work(void *data)
 {
-        int *finished = (int*)data;
+	thread_data_t *my_thread_data = (thread_data_t *)data;
 
         int fd;
         if ((fd = open(JS_DEVICE_NEO, O_RDONLY)) < 0)
@@ -298,7 +322,7 @@ void* accel_work(void *data)
         axis = (int*)calloc(axes, sizeof(int));
         //button = (char*)calloc(buttons, sizeof(char));
 
-        while ( !(*finished) )
+        while ( !(my_thread_data->finished) )
         {
                 size_t rval;
                 fd_set fds;
@@ -346,7 +370,13 @@ void* accel_work(void *data)
                         /* No data */
                 }
 
-                usleep(GET_DATA_INTERVAL);
+		/* If the library user specified a callback, call
+		   it. */
+		if (my_thread_data->callback)
+		  (*my_thread_data->callback)(my_thread_data->closure,
+					      acx, acy, acz);
+
+                usleep(my_thread_data->interval_us);
         }
 
         close(fd);
@@ -356,15 +386,24 @@ void* accel_work(void *data)
 
 #endif
 
-void accelerometer_start()
+void accelerometer_start(int interval_ms,
+			 accelerometer_cb_t callback,
+			 void *closure)
 {
-	finished = 0;
-        pthread_create( &thread, NULL, accel_work, (void*)(&finished));
+	global_thread_data.finished = 0;
+	global_thread_data.interval_us = 1000 * interval_ms;
+	if (global_thread_data.interval_us < GET_DATA_INTERVAL)
+	{
+	  global_thread_data.interval_us = GET_DATA_INTERVAL;
+	}
+	global_thread_data.callback = callback;
+	global_thread_data.closure = closure;
+        pthread_create( &thread, NULL, accel_work, &global_thread_data);
 }
 
 void accelerometer_stop()
 {
-	finished = 1;
+	global_thread_data.finished = 1;
 	pthread_join(thread, NULL);
 }
 
diff --git a/src/libraries/accelerometer/accelerometers.h b/src/libraries/accelerometer/accelerometers.h
index c69ce3f..fd25319 100644
--- a/src/libraries/accelerometer/accelerometers.h
+++ b/src/libraries/accelerometer/accelerometers.h
@@ -26,7 +26,11 @@
 
 #include <qtopiaglobal.h>
 
-QTOPIA_EXPORT void accelerometer_start();
+typedef void (*accelerometer_cb_t)(void *, double, double, double);
+
+QTOPIA_EXPORT void accelerometer_start(int interval_ms,
+				       accelerometer_cb_t callback,
+				       void *closure);
 QTOPIA_EXPORT void accelerometer_stop();
 
 /* On the GTA04, the values returned by the following are in units of
-- 
1.7.10.4

>From c4938dce05b27426334cd32d594084fbd055880d Mon Sep 17 00:00:00 2001
From: Neil Jerram <n...@ossau.homelinux.net>
Date: Tue, 17 Jul 2012 22:33:31 +0200
Subject: [PATCH] Use accelerometer library for autorotation

---
 src/qbuild.pro       |    1 +
 src/utils/rotate.cpp |  102 ++++++++++++--------------------------------------
 src/utils/rotate.h   |   13 +++----
 3 files changed, 31 insertions(+), 85 deletions(-)

diff --git a/src/qbuild.pro b/src/qbuild.pro
index 33f294e..4db82b6 100644
--- a/src/qbuild.pro
+++ b/src/qbuild.pro
@@ -3,6 +3,7 @@ TARGET = arora
 
 CONFIG += qtopia
 QT += webkit network
+MODULES*=accelerometer
 
 #DEFINES += QT_NO_CAST_FROM_ASCII
 DEFINES += QT_NO_UITOOLS
diff --git a/src/utils/rotate.cpp b/src/utils/rotate.cpp
index c5a82b7..32b0399 100644
--- a/src/utils/rotate.cpp
+++ b/src/utils/rotate.cpp
@@ -5,6 +5,8 @@
 
 #include <stdlib.h>
 
+#include <accelerometers.h>
+
 /**
  * The acceleromer algorithms and code taken from omnewrotate-0.5.4
  * Copyright © 2008 Rui Miguel Silva Seabra <r...@1407.org>
@@ -37,7 +39,6 @@
 
 RotateHelper::RotateHelper(QObject *parent, int dflg) : QObject(parent)
 {
-	timer= NULL;
 	x = 0;
 	y = 0;
 	z = 0;
@@ -51,9 +52,7 @@ RotateHelper::RotateHelper(QObject *parent, int dflg) : QObject(parent)
 	down = 0;
 	last_pos= -1;
 	current_pos = -1;
-	event3 = -1;
 	debug = dflg;
-	skip_zero = 1;
 	initial_rotation= -1;
 }
 
@@ -77,32 +76,16 @@ void RotateHelper::start(int timeinms)
 {
 	// remember where we were when we started
 	QValueSpaceItem vsiRot("/UI/Rotation/Current");
-    initial_rotation= vsiRot.value().toUInt();
-	
-	// don't allow multiple timers to run
-	if(timer != NULL){
-		stop();
-	}
+	initial_rotation= vsiRot.value().toUInt();
 
-	// start up a single shot timer to check accelerometers
-	// it will be restarted each time
-	timer = new QTimer(this);
-	connect(timer, SIGNAL(timeout()), this, SLOT(sample()));
-	timer->start(timeinms);
+	// start accelerometer
+	accelerometer_start(timeinms, RotateHelper::accel_callback, this);
 }
 
 void RotateHelper::stop()
 {
-	if(timer != NULL){
-		timer->stop();
-		delete timer;
-		timer= NULL;
-	}
-
-	if(event3 != -1){
-		close(event3);
-		event3= -1;
-	}
+	// stop accelerometer
+	accelerometer_stop();
 }
 
 // restore to whatever the rotation was when we started
@@ -204,64 +187,27 @@ int RotateHelper::define_position(void)
 	return current_pos;
 }
 
-
-int RotateHelper::read_packet()
+bool RotateHelper::packet_reader()
 {
-	static struct input_event event_x, event_y, event_z, event_syn;
-	void *packet_memcpy_result = NULL;
-	int packet_size = sizeof(struct input_event);
-	int size_of_packet = 4 * packet_size;
-	int bytes_read = 0;
-	char packet[size_of_packet];
-
-	bytes_read = read(event3, packet, size_of_packet);
-
-	if (bytes_read < packet_size)
-	{
-		qWarning("RotateHelper: fread failed");
-		stop();
-		return -1;
-	}
-
-	/* obtain the full packet */
-	packet_memcpy_result = memcpy(&event_x,   packet,                   packet_size);
-	packet_memcpy_result = memcpy(&event_y,   packet +     packet_size, packet_size);
-	packet_memcpy_result = memcpy(&event_z,   packet + 2 * packet_size, packet_size);
-	packet_memcpy_result = memcpy(&event_syn, packet + 3 * packet_size, packet_size);
-
-	if(skip_zero && (event_x.value == 0 || event_y.value == 0 || event_z.value == 0))
-	{
-		//	qDebug("Bad packet!");
-		return(0);
-	}
-
-	if (event_syn.type == EV_SYN)
-	{
-		x = event_x.value;
-		y = event_y.value;
-		z = event_z.value;
-
-		return (1);
-	}
-	else
-		return (0);
+	return (x || y || z);
 }
 
-bool RotateHelper::packet_reader()
+void RotateHelper::accel_sample(double acx,
+				double acy,
+				double acz)
 {
-	if(event3 == -1){
-		event3 = open(EVENT_PATH, O_RDONLY);
-
-		if (event3 < 0){
-			qWarning("Can't open '%s': %s\n", EVENT_PATH, strerror(errno));
-			return false;
-		}
-		qDebug("Opened: %s", EVENT_PATH);
-	}
+	x = 1000 * acx;
+	y = 1000 * acy;
+	z = 1000 * acz;
 
-	while(read_packet() == 0);
-	
-	// qDebug("read packet");
+	sample();
+}
 
-	return true;
+void RotateHelper::accel_callback(void *closure,
+				  double acx,
+				  double acy,
+				  double acz)
+{
+  RotateHelper *rotHelper = (RotateHelper *)closure;
+  rotHelper->accel_sample(acx, acy, acz);
 }
diff --git a/src/utils/rotate.h b/src/utils/rotate.h
index 30957a1..792cbba 100644
--- a/src/utils/rotate.h
+++ b/src/utils/rotate.h
@@ -11,8 +11,6 @@
 
 #include <QTimer>
 
-#define EVENT_PATH "/dev/input/event3"
-
 
 /**
  * Detects the orientation of the device, and will rotate the screen
@@ -30,6 +28,7 @@ class RotateHelper : public QObject
 	void stop();
 	void restore();
 	bool isLandscape();
+	void accel_sample(double acx, double acy, double acz);
 
  private slots:
 	void sample();
@@ -41,10 +40,7 @@ signals:
 	void maybe_rotate(int deg);
 	int neighbour(int value, int target, int neighbour);
 	int define_position(void);
-	int read_packet();
 	bool packet_reader();
-	
-	QTimer *timer;
 
 	enum Orientation {UP=0, RIGHT=90, DOWN=180, LEFT=270};
 
@@ -61,9 +57,12 @@ signals:
 	int down;
 	int last_pos;
 	int current_pos;
-	int event3;
 	int debug;
 	int initial_rotation;
-	ushort skip_zero;
+
+	static void accel_callback(void *closure,
+				   double acx,
+				   double acy,
+				   double acz);
 };
 #endif
-- 
1.7.10.4

_______________________________________________
Openmoko community mailing list
community@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/community

Reply via email to