Accelerometer support, v0.



Hi everyone,

This weekend on the train I was playing with the accelerometer on my
ThinkPad, and with F-Spot.  The result is the attached patch, which
autorotates the displayed picture when you tilt your laptop.

This is handy if you're showing pictures on your computer and you
encounter a portrait-orientation photo amidst many landscape photos;
simply tilt the computer and the picture tilts with it, using the entire
available screen space.  It's a great demo, too :-).

After building with this patch, on OpenSUSE simply run

        # modprobe hdaps
        
And then launch f-spot.  It should work from the regular image view or
the full-screen view.

Known issues:

- The rotate is a bit slow and weird.  I'm not sure why.  I'm hoping
someone else on this list will figure this out.

- The hdaps driver doesn't work on all ThinkPads, it seems.  Not sure
what the supported list is like.

Thanks to Larry who explained how to do some of this on the cell phone
from the train :-).

Enjoy,

Nat

Index: src/AsyncPixbufLoader.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/AsyncPixbufLoader.cs,v
retrieving revision 1.55
diff -u -r1.55 AsyncPixbufLoader.cs
--- src/AsyncPixbufLoader.cs	23 Mar 2006 04:38:53 -0000	1.55
+++ src/AsyncPixbufLoader.cs	3 Apr 2006 17:19:40 -0000
@@ -113,8 +113,10 @@
 			area_prepared = false;
 			damage = Gdk.Rectangle.Zero;
 
+			HDAPSOrientation ho = HDAPSOrientation.GetDefault ();
+
 			ImageFile img = ImageFile.Create (uri);
-			orientation = img.Orientation;
+			orientation = ho.GetViewOrientation (img.Orientation);
 
 			try {
 				thumb = new Gdk.Pixbuf (ThumbnailGenerator.ThumbnailPath (uri));
Index: src/HDAPSOrientation.cs
===================================================================
RCS file: src/HDAPSOrientation.cs
diff -N src/HDAPSOrientation.cs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/HDAPSOrientation.cs	3 Apr 2006 17:19:40 -0000
@@ -0,0 +1,130 @@
+using System;
+using System.IO;
+
+namespace FSpot {
+
+	public delegate void OrientationChangedHandler (object sender);
+
+	public class HDAPSOrientation {
+
+		//
+		// The singleton object
+		//
+
+		static HDAPSOrientation singleton = null;
+
+		public static HDAPSOrientation GetDefault ()
+		{
+			if (singleton == null)
+				singleton = new HDAPSOrientation ();
+
+			return singleton;
+		}
+
+		//
+		// The object proper
+		//
+
+		public event OrientationChangedHandler OrientationChanged;
+
+		public enum Orient {
+			Normal,
+			TiltClockwise,
+			TiltCounterclockwise,
+		}
+
+		private Orient current_orientation;
+
+		public Orient CurrentOrientation {
+			get {
+				return current_orientation;
+			}
+		}
+
+		uint timer;
+
+		public HDAPSOrientation ()
+		{
+			int x, y;
+
+			// Call once to set a baseline value.
+			// Hopefully the laptop is flat when this is
+			// called.
+			GetHDAPSCoords (out x, out y);
+
+			timer = GLib.Timeout.Add (500, new GLib.TimeoutHandler (CheckOrientation));
+		}
+
+		private bool CheckOrientation ()
+		{
+			Orient new_orient = GetScreenOrientation ();
+
+			if (new_orient != current_orientation) {
+				current_orientation = new_orient;
+
+				if (OrientationChanged != null)
+					OrientationChanged (this);
+
+				Console.WriteLine ("Laptop orientation changed...");
+			}
+
+			return true;
+		}
+
+		public Orient GetScreenOrientation ()
+		{
+			int x, y;
+
+			GetHDAPSCoords (out x, out y);
+
+			if (x > 100)
+				return Orient.TiltClockwise;
+
+			if (x < -100)
+				return Orient.TiltCounterclockwise;
+
+			return Orient.Normal;
+		}
+
+		public PixbufOrientation GetViewOrientation (PixbufOrientation po)
+		{
+			if (current_orientation == Orient.TiltCounterclockwise)
+				return PixbufUtils.Rotate90 (po);
+
+			if (current_orientation == Orient.TiltClockwise)
+				return PixbufUtils.Rotate270 (po);
+
+			return po;
+		}
+		
+		static int base_x = -1000; // initial nonsense value
+		static int base_y = -1000;
+
+		private void GetHDAPSCoords (out int x, out int y)
+		{
+			try {
+				using (Stream file = File.OpenRead ("/sys/devices/platform/hdaps/position")){
+					StreamReader sr = new StreamReader (file);
+
+					string s = sr.ReadLine ();
+					string [] ss = s.Substring (1, s.Length-2).Split (',');
+					x = int.Parse (ss [0]);
+					y = int.Parse (ss [1]);
+
+					if (base_x == -1000)
+						base_x = x;
+					if (base_y == -1000)
+						base_y = y;
+
+					x -= base_x;
+					y -= base_y;
+
+					return;
+				}
+			} catch (Exception e) {
+				x = 0;
+				y = 0;
+			}
+		}
+	}
+}
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/f-spot/src/Makefile.am,v
retrieving revision 1.62
diff -u -r1.62 Makefile.am
--- src/Makefile.am	26 Feb 2006 22:37:08 -0000	1.62
+++ src/Makefile.am	3 Apr 2006 17:19:40 -0000
@@ -38,6 +38,7 @@
 	$(srcdir)/Global.cs			\
 	$(srcdir)/GroupAdaptor.cs		\
 	$(srcdir)/GroupSelector.cs		\
+	$(srcdir)/HDAPSOrientation.cs		\
 	$(srcdir)/HigMessageDialog.cs		\
 	$(srcdir)/Histogram.cs			\
 	$(srcdir)/IBrowsableItem.cs		\
Index: src/PhotoImageView.cs
===================================================================
RCS file: /cvs/gnome/f-spot/src/PhotoImageView.cs,v
retrieving revision 1.65
diff -u -r1.65 PhotoImageView.cs
--- src/PhotoImageView.cs	22 Mar 2006 19:13:11 -0000	1.65
+++ src/PhotoImageView.cs	3 Apr 2006 17:19:40 -0000
@@ -15,7 +15,10 @@
 			loader.AreaUpdated += HandlePixbufAreaUpdated;
 			loader.AreaPrepared += HandlePixbufPrepared;
 			loader.Done += HandleDone;
-			
+
+			HDAPSOrientation o = HDAPSOrientation.GetDefault ();
+			o.OrientationChanged += HandleOrientationChanged;
+
 			this.SizeAllocated += HandleSizeAllocated;
 			this.KeyPressEvent += HandleKeyPressEvent;
 			this.ScrollEvent += HandleScrollEvent;
@@ -59,6 +62,11 @@
 		{
 			loader.LoadToDone ();
 			return this.Pixbuf;
+		}
+
+		public void HandleOrientationChanged (object sender)
+		{
+			Reload ();
 		}
 
 		public void Reload ()


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