tag:blogger.com,1999:blog-61451408795207858702024-02-20T01:26:01.090+01:00thp on Maemothphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.comBlogger167125tag:blogger.com,1999:blog-6145140879520785870.post-67714840941387104152023-02-15T22:55:00.001+01:002023-02-15T22:55:47.777+01:00The Maemulator: Running a certain 2009 tech demo on modern Linux<p>Want to revisit 2009's N900 tech demo but you got rid of your old toys long ago or don't want to bother digging them out of your desk drawer? <a href="https://thp.io/2023/maemulator/" target="_blank">The Maemulator</a> to the rescue! It uses QEMU user-space emulation and some LD_PRELOAD magic + other in-process trickery to get it working on any modern Linux machine that has an OpenGL driver. Add multi-sample anti-aliasing, anisotropic filtering, higher resolutions, keyboard input and various fixes, and you are all set for a few minutes of fun distraction.</p><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8HX3Ejw0z-QH-fPpEzT88yeeacRrPgjJ8_ZBRliqoEoMo_sA5NxBjJM7uJqEu5xK0g687ToEhD6fk30adqjNLrmXMW5oen5ylWEN0AH2VGTEbH555d0h0OXqKIAJbNjqMd5jODMXwrxULYgVDWOS-AbYx47PEkc0EBMxcbw5eh8bRz3Gpk5mLkiau/s2560/FojwhFDXsAAeAc7.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1440" data-original-width="2560" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8HX3Ejw0z-QH-fPpEzT88yeeacRrPgjJ8_ZBRliqoEoMo_sA5NxBjJM7uJqEu5xK0g687ToEhD6fk30adqjNLrmXMW5oen5ylWEN0AH2VGTEbH555d0h0OXqKIAJbNjqMd5jODMXwrxULYgVDWOS-AbYx47PEkc0EBMxcbw5eh8bRz3Gpk5mLkiau/w640-h360/FojwhFDXsAAeAc7.jpeg" width="640" /></a></div><br /><p></p>thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-40479677178485430582021-07-01T10:05:00.002+02:002021-07-01T10:05:33.364+02:00Loonies 8192 now for Maemo 4 (N800) and MeeGo 1.2 Harmattan (N9)<p>As part of a summer clean-up of the desk drawers, I pulled out the N800 and N9 and ported my game <a href="https://thp.io/2018/loonies8192/" target="_blank">Loonies 8192</a> to these devices. Since those are "proper" Linux devices, one can compile things directly on-device (just install gcc from the SDK repos), and with SSH, it's easy to type on a real keyboard.</p><p>Anyway, you can install the game via the landing pages:</p><p>For the N800, make sure "maemo Extras" is enabled so it will find libsdl1.2 if it's not already installed. Head over to <b>https://loonies.thp.io/n800/</b> on the device and download the deb, it will be installed by Application manager.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg620hvfMKZElo1rBVPwI01srsT3udd64WrnWOoA5CHWQbueiG9yOYI3GKmfIRcZf_3Zq8hVTJcrE1Q1uESG1bxfZyTVmCYBHmx2uemCGve9yQxqZddTLE9ukn7nL_F2LfJDOzlrU9OQjQ/s800/IMG_5485.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="521" data-original-width="800" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg620hvfMKZElo1rBVPwI01srsT3udd64WrnWOoA5CHWQbueiG9yOYI3GKmfIRcZf_3Zq8hVTJcrE1Q1uESG1bxfZyTVmCYBHmx2uemCGve9yQxqZddTLE9ukn7nL_F2LfJDOzlrU9OQjQ/s320/IMG_5485.jpeg" width="320" /></a></div><p>For the N9, make sure you have n9repomirror installed (again, so libsdl1.2 can be installed if necessary). Enable third party applications in Settings, Applications, Installations. Then head over to <b>https://loonies.thp.io/n9/</b> on the device and download the deb, selecting after the download is finished will ask you to install it.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxtczl4tpQ2q4beAfawspIFFwTFj90Dhcx9fmWF3uPZSJ3pWivcvRxPAgQJ88dnSXmS_NxCIiqnFWl9oRZm8iTddfdLWypQnjxUL9sfPExVyycd57DmFTcTJbzaNF5mQ0FxylHhU4zkW0/s500/IMG_5479.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="324" data-original-width="500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxtczl4tpQ2q4beAfawspIFFwTFj90Dhcx9fmWF3uPZSJ3pWivcvRxPAgQJ88dnSXmS_NxCIiqnFWl9oRZm8iTddfdLWypQnjxUL9sfPExVyycd57DmFTcTJbzaNF5mQ0FxylHhU4zkW0/s320/IMG_5479.jpeg" width="320" /></a></div><p>The N9 version is also <a href="https://openrepos.net/content/thp/loonies-8192" target="_blank">available on openrepos.net</a>.</p><p>And don't forget that the game is also available for DOS, various consoles and handheld consoles as well as on Windows. All of the builds are <a href="https://thp.itch.io/loonies-8192" target="_blank">available on itch.io</a>.</p>thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-33608597976874977972021-02-11T07:41:00.003+01:002021-02-11T07:58:48.315+01:00reBounce - softfp-to-hardfp LD_PRELOAD hack for Bounce on N9<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSDUpDmKA0p5F0wESAPMuN17hlZdyjBITrYRfFwrOcfwETEDED71kZOVeF4IzlzFD5TtwKEcH7WVpoJt4_TlW9J8wbbtFx5UmQ70BerJmxajgJUSCKgH_09lPQmBFBytFLaeyz1uvdqIQ/s1733/Image.jpeg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1078" data-original-width="1733" height="313" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSDUpDmKA0p5F0wESAPMuN17hlZdyjBITrYRfFwrOcfwETEDED71kZOVeF4IzlzFD5TtwKEcH7WVpoJt4_TlW9J8wbbtFx5UmQ70BerJmxajgJUSCKgH_09lPQmBFBytFLaeyz1uvdqIQ/w503-h313/Image.jpeg" width="503" /></a></div><p>This depends on <a href="https://www.youtube.com/watch?v=V6JfxdWg0HI">Bounce</a> (the N900 .deb) and SDL 1.2 being installed. Google "<a href="https://coderus.openrepos.net/n900mirror/downloads.maemo.nokia.com/fremantle/apps/">bounce_1.0.0_armel.deb</a>" for the former, and use <a href="n9repomirror">n9repomirror</a> for the latter.</p><div>This is available on OpenRepos: <a href="https://openrepos.net/content/thp/rebounce">https://openrepos.net/content/thp/rebounce</a></div><div>Also on TMO: <a href="https://talk.maemo.org/showthread.php?t=101160">https://talk.maemo.org/showthread.php?t=101160</a></div><div>Also on Twitter: <a href="https://twitter.com/thp4/status/1359758278620758019">https://twitter.com/thp4/status/1359758278620758019</a></div><div><br /></div><div>Source code (copy'n'paste this into a file named "rebounce.c", then run it using your shell):</div><div><br /></div><div><p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#if <span style="color: #1c00cf;">0</span></p>
<p style="background-color: white; color: #0f68a0; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">gcc<span color="rgba(0, 0, 0, 0.85)"> -</span>Os<span color="rgba(0, 0, 0, 0.85)"> -</span>shared<span color="rgba(0, 0, 0, 0.85)"> -</span>fPIC<span color="rgba(0, 0, 0, 0.85)"> -</span>lSDL<span color="rgba(0, 0, 0, 0.85)"> -</span>o<span color="rgba(0, 0, 0, 0.85)"> </span>librebounce<span color="rgba(0, 0, 0, 0.85)">.</span>so<span color="rgba(0, 0, 0, 0.85)"> </span>rebounce<span color="rgba(0, 0, 0, 0.85)">.</span>c</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #0f68a0;">LD_PRELOAD</span>=$(pwd)/librebounce.so /opt/bounce/bin/bounce</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">exit <span style="color: #1c00cf;">0</span></p>
<p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#endif</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(93, 108, 121, 0.35); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">/**</p>
<p style="background-color: white; color: #5d6c79; font-family: "Helvetica Neue"; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(93, 108, 121, 0.35)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> *</span><span color="rgba(0, 0, 0, 0.85)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> </span>reBounce -- softfp-to-hardfp LD_PRELOAD hack for Bounce on N9</p>
<p style="background-color: white; color: rgba(93, 108, 121, 0.35); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> *</p>
<p style="background-color: white; color: #5d6c79; font-family: "Helvetica Neue"; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(93, 108, 121, 0.35)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> *</span><span color="rgba(0, 0, 0, 0.85)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> </span>Bounce was a really nice 2009 tech demo on the N900. This</p>
<p style="background-color: white; color: #5d6c79; font-family: "Helvetica Neue"; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(93, 108, 121, 0.35)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> *</span><span color="rgba(0, 0, 0, 0.85)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> </span>makes this tech demo work on an N9 by translating the calls</p>
<p style="background-color: white; color: #5d6c79; font-family: "Helvetica Neue"; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(93, 108, 121, 0.35)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> *</span><span color="rgba(0, 0, 0, 0.85)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> </span>that use floating point arguments to the hardfp ABI. It also</p>
<p style="background-color: white; color: #5d6c79; font-family: "Helvetica Neue"; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(93, 108, 121, 0.35)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> *</span><span color="rgba(0, 0, 0, 0.85)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> </span>fixes input using SDL1.2 to get sensor values from sensorfw.</p>
<p style="background-color: white; color: rgba(93, 108, 121, 0.35); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> *</p>
<p style="background-color: white; color: #5d6c79; font-family: "Helvetica Neue"; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(93, 108, 121, 0.35)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> *</span><span color="rgba(0, 0, 0, 0.85)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> </span>Known issues: Audio is muted on startup until mute is toggled.</p>
<p style="background-color: white; color: rgba(93, 108, 121, 0.35); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> *</p>
<p style="background-color: white; color: #5d6c79; font-family: "Helvetica Neue"; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(93, 108, 121, 0.35)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> *</span><span color="rgba(0, 0, 0, 0.85)" style="font-family: Menlo; font-stretch: normal; line-height: normal;"> </span>2021-02-11 Thomas Perl <m@thp.io></p>
<p style="background-color: white; color: rgba(93, 108, 121, 0.35); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> *<span style="color: #5d6c79; font-family: "Helvetica Neue"; font-stretch: normal; line-height: normal;">*/</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#define _GNU_SOURCE</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#include <span style="color: #c41a16;"><stdio.h></span></p>
<p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#include <span style="color: #c41a16;"><dlfcn.h></span></p>
<p style="background-color: white; color: #c41a16; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #643820;">#include </span><pthread.h></p>
<p style="background-color: white; color: #c41a16; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #643820;">#include </span><SDL/SDL.h></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#define SFP __attribute__((pcs(<span style="color: #c41a16;">"aapcs"</span>)))</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><b>typedef</b><span color="rgba(0, 0, 0, 0.85)"> </span><b>unsigned</b><span color="rgba(0, 0, 0, 0.85)"> </span><b>int</b><span color="rgba(0, 0, 0, 0.85)"> GLuint;</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><b>static</b><span color="rgba(0, 0, 0, 0.85)"> </span><b>void</b><span color="rgba(0, 0, 0, 0.85)"> *</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #0f68a0;">sensor_thread</span>(<span style="color: #9b2393;"><b>void</b></span> *user_data)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">{</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> SDL_Joystick *accelerometer = SDL_JoystickOpen(<span style="color: #1c00cf;">0</span>);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>while</b></span> (<span style="color: #1c00cf;">1</span>) {</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> SDL_JoystickUpdate();</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>float</b></span> x = <span style="color: #1c00cf;">0.053888f</span> * SDL_JoystickGetAxis(accelerometer, <span style="color: #1c00cf;">0</span>);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>float</b></span> y = <span style="color: #1c00cf;">0.053888f</span> * SDL_JoystickGetAxis(accelerometer, <span style="color: #1c00cf;">1</span>);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>float</b></span> z = <span style="color: #1c00cf;">0.053888f</span> * SDL_JoystickGetAxis(accelerometer, <span style="color: #1c00cf;">2</span>);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #c41a16; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> FILE *out = fopen(</span>"/dev/shm/bounce.sensor.tmp"<span color="rgba(0, 0, 0, 0.85)">, </span>"wb"<span color="rgba(0, 0, 0, 0.85)">);</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> fprintf(out, <span style="color: #c41a16;">"%f %f %f\n"</span>, -y, x, z);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> fclose(out);</p>
<p style="background-color: white; color: #c41a16; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> rename(</span>"/dev/shm/bounce.sensor.tmp"<span color="rgba(0, 0, 0, 0.85)">, </span>"/dev/shm/bounce.sensor"<span color="rgba(0, 0, 0, 0.85)">);</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> SDL_Delay(<span style="color: #1c00cf;">10</span>);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><b>return</b><span color="rgba(0, 0, 0, 0.85)"> </span><b>NULL</b><span color="rgba(0, 0, 0, 0.85)">;</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #0f68a0; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">FILE<span color="rgba(0, 0, 0, 0.85)"> *</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #0f68a0;">fopen</span>(<span style="color: #9b2393;"><b>const</b></span> <span style="color: #9b2393;"><b>char</b></span> *filename, <span style="color: #9b2393;"><b>const</b></span> <span style="color: #9b2393;"><b>char</b></span> *mode)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">{</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> FILE *(*fopen_orig)(<span style="color: #9b2393;"><b>const</b></span> <span style="color: #9b2393;"><b>char</b></span> *, <span style="color: #9b2393;"><b>const</b></span> <span style="color: #9b2393;"><b>char</b></span> *) = dlsym(RTLD_NEXT, <span style="color: #c41a16;">"fopen"</span>);</p>
<p style="background-color: white; color: #c41a16; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #9b2393;"><b>if</b></span><span color="rgba(0, 0, 0, 0.85)"> (strcmp(filename, </span>"/sys/class/i2c-adapter/i2c-3/3-001d/coord"<span color="rgba(0, 0, 0, 0.85)">) == </span><span style="color: #1c00cf;">0</span><span color="rgba(0, 0, 0, 0.85)">) {</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>static</b></span> <span style="color: #9b2393;"><b>int</b></span> sensor_inited = <span style="color: #1c00cf;">0</span>;</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>if</b></span> (!sensor_inited) {</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> sensor_inited = <span style="color: #1c00cf;">1</span>;</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> pthread_t thread;</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> pthread_create(&thread, <span style="color: #9b2393;"><b>NULL</b></span>, sensor_thread, <span style="color: #9b2393;"><b>NULL</b></span>);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #c41a16; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span color="rgba(0, 0, 0, 0.85)"> filename = </span>"/dev/shm/bounce.sensor"<span color="rgba(0, 0, 0, 0.85)">;</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> }</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>return</b></span> fopen_orig(filename, mode);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#define f_f(name) float SFP name(float x) { return ((float (*)(float))dlsym(RTLD_NEXT, #name))(x); }</p>
<p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#define d_d(name) double SFP name(double x) { return ((double (*)(double))dlsym(RTLD_NEXT, #name))(x); }</p>
<p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#define f_ff(name) float SFP name(float x, float y) { return ((float (*)(float, float))dlsym(RTLD_NEXT, #name))(x, y); }</p>
<p style="background-color: white; color: #643820; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">#define d_dd(name) double SFP name(double x, double y) { return ((double (*)(double, double))dlsym(RTLD_NEXT, #name))(x, y); }</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #0f68a0;">f_f</span>(sinhf) f_f(coshf) <span style="color: #0f68a0;">f_f</span>(tanhf) f_f(asinf) <span style="color: #0f68a0;">f_f</span>(acosf) f_f(atanf) <span style="color: #0f68a0;">f_f</span>(sinf) f_f(cosf) <span style="color: #0f68a0;">f_f</span>(tanf) f_f(expf) <span style="color: #0f68a0;">f_f</span>(logf)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">f_f(log10f) <span style="color: #0f68a0;">f_f</span>(ceilf) f_f(floorf) <span style="color: #0f68a0;">d_d</span>(log) d_d(sin) <span style="color: #0f68a0;">f_ff</span>(atan2f) f_ff(fmodf) <span style="color: #0f68a0;">d_dd</span>(atan2) d_dd(pow) <span style="color: #0f68a0;">d_dd</span>(fmod)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><b>double</b><span color="rgba(0, 0, 0, 0.85)"> SFP</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">frexp(<span style="color: #9b2393;"><b>double</b></span> value, <span style="color: #9b2393;"><b>int</b></span> *exp)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">{</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>return</b></span> ((<span style="color: #9b2393;"><b>double</b></span> (*)(<span style="color: #9b2393;"><b>double</b></span>, <span style="color: #9b2393;"><b>int</b></span> *))dlsym(RTLD_NEXT, <span style="color: #c41a16;">"frexp"</span>))(value, exp);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><b>double</b><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #0f68a0;">SFP</span></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #0f68a0;">ldexp</span><span color="rgba(0, 0, 0, 0.85)">(</span><b>double</b><span color="rgba(0, 0, 0, 0.85)"> x, </span><b>int</b><span color="rgba(0, 0, 0, 0.85)"> n)</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">{</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>return</b></span> ((<span style="color: #9b2393;"><b>double</b></span> (*)(<span style="color: #9b2393;"><b>double</b></span>, <span style="color: #9b2393;"><b>int</b></span>))dlsym(RTLD_NEXT, <span style="color: #c41a16;">"ldexp"</span>))(x, n);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><b>double</b><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #0f68a0;">SFP</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #0f68a0;">modf</span>(<span style="color: #9b2393;"><b>double</b></span> value, <span style="color: #9b2393;"><b>double</b></span> *iptr)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">{</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> <span style="color: #9b2393;"><b>return</b></span> ((<span style="color: #9b2393;"><b>double</b></span> (*)(<span style="color: #9b2393;"><b>double</b></span>, <span style="color: #9b2393;"><b>double</b></span> *))dlsym(RTLD_NEXT, <span style="color: #c41a16;">"modf"</span>))(value, iptr);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><b>void</b><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #0f68a0;">SFP</span></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #0f68a0;">glClearColor</span><span color="rgba(0, 0, 0, 0.85)">(</span><b>float</b><span color="rgba(0, 0, 0, 0.85)"> r, </span><b>float</b><span color="rgba(0, 0, 0, 0.85)"> g, </span><b>float</b><span color="rgba(0, 0, 0, 0.85)"> b, </span><b>float</b><span color="rgba(0, 0, 0, 0.85)"> a)</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">{</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> ((<span style="color: #9b2393;"><b>void</b></span> (*)(<span style="color: #9b2393;"><b>float</b></span>, <span style="color: #9b2393;"><b>float</b></span>, <span style="color: #9b2393;"><b>float</b></span>, <span style="color: #9b2393;"><b>float</b></span>))dlsym(RTLD_NEXT, <span style="color: #c41a16;">"glClearColor"</span>))(r, g, b, a);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><b>void</b><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #0f68a0;">SFP</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #0f68a0;">glUniform4f</span>(GLuint location, <span style="color: #9b2393;"><b>float</b></span> v0, <span style="color: #9b2393;"><b>float</b></span> v1, <span style="color: #9b2393;"><b>float</b></span> v2, <span style="color: #9b2393;"><b>float</b></span> v3)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">{</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> ((<span style="color: #9b2393;"><b>void</b></span> (*)(GLuint, <span style="color: #9b2393;"><b>float</b></span>, <span style="color: #9b2393;"><b>float</b></span>, <span style="color: #9b2393;"><b>float</b></span>, <span style="color: #9b2393;"><b>float</b></span>))dlsym(RTLD_NEXT, <span style="color: #c41a16;">"glUniform4f"</span>))(location, v0, v1, v2, v3);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 14px;"><br /></p>
<p style="background-color: white; color: #9b2393; font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><b>void</b><span color="rgba(0, 0, 0, 0.85)"> </span><span style="color: #0f68a0;">SFP</span></p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"><span style="color: #0f68a0;">glUniform1f</span>(GLuint location, <span style="color: #9b2393;"><b>float</b></span> v0)</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">{</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;"> ((<span style="color: #9b2393;"><b>void</b></span> (*)(GLuint, <span style="color: #9b2393;"><b>float</b></span>))dlsym(RTLD_NEXT, <span style="color: #c41a16;">"glUniform1f"</span>))(location, v0);</p>
<p style="background-color: white; color: rgba(0, 0, 0, 0.85); font-family: Menlo; font-size: 12px; font-stretch: normal; line-height: normal; margin: 0px;">}</p></div><div><br /></div>thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-70267553451720284842015-01-29T18:40:00.001+01:002015-01-29T18:40:17.042+01:00Running Debian sid on Sailfish OSThis assumes you have a Debian/Ubuntu host computer on which to run debootstrap. Theoretically you can run this on the device, but it's not as easy as on Harmattan (where you can just install the debootstrap package. On the host, run the first init and create a tarball:
<pre>
sudo debootstrap --arch armhf --foreign sid sid
sudo tar czvf sid.tgz -C sid .
du -sh sid.tgz
# 98M sid.tgz
scp sid.tgz nemo@192.168.2.15:
</pre>
To unpack the chroot tarball:
<pre>
ssh nemo@192.168.2.15
devel-su
# password
mkdir sid
cd sid
tar xvf ../sid.tgz
chroot /home/nemo/sid/ /debootstrap/debootstrap --second-stage
chroot /home/nemo/sid/ apt-get clean
echo "deb http://http.debian.net/debian sid main" \
>/home/nemo/sid/etc/apt/source.list
</pre>
To enter the chroot:
<pre>
ssh nemo@192.168.2.15
devel-su
# password
mount --bind /proc /home/nemo/sid/proc
mount --bind /sys /home/nemo/sid/sys
mount --bind /dev /home/nemo/sid/dev
mount --bind /dev/pts /home/nemo/sid/dev/pts
cp /etc/resolv.conf /home/nemo/sid/etc/
chroot /home/nemo/sid/
apt-get update
</pre>thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-14328431636404418392014-04-19T18:03:00.000+02:002014-04-19T18:05:41.803+02:00My N9 apps and games now self-hosted and on openrepos.netAs the versions of my apps on Nokia Store grow more and more outdated, I've decided to remove the apps from there and instead self-host them on my web page and/or put them on <a href="https://openrepos.net/">OpenRepos.net</a> instead. A <a href="http://store.ovi.com/publisher/Thomas+Perl">handful of apps</a> stay on Nokia Store; those are mostly S40 apps or apps for which a Symbian version also exists.<br />
<br />
Here's a list of my N9 apps that you can now get for free ("deb download" is as of posting this, for new versions visit the webpage or openrepos.net):<br />
<ul>
<li>Billboard Standby Screen (<a href="http://thp.io/2012/billboard/">web page</a>, <a href="http://thp.io/2012/billboard/billboard_1.1.1_armel.deb">deb download</a>, <a href="https://openrepos.net/content/thp/billboard-standby-screen">openrepos.net</a>)</li>
<li>Volume+ As Camera Button (<a href="http://thp.io/2012/camerra/">web page</a>, <a href="http://thp.io/2012/camerra/camerra_1.5.0.deb">deb download</a>, <a href="https://openrepos.net/content/thp/volume-camera-button">openrepos.net</a>)</li>
<li>Headset Camera Button (<a href="http://thp.io/2013/headsetcamera/">web page</a>, <a href="http://thp.io/2013/headsetcamera/headsetcamera_1.0.0.deb">deb download</a>, <a href="https://openrepos.net/content/thp/headset-camera-button">openrepos.net</a>)</li>
<li>Personal Web Server (<a href="http://thp.io/2012/serverr/">web page</a>, <a href="http://thp.io/2012/serverr/serverr_1.0.0.deb">deb download</a>, <a href="https://openrepos.net/content/thp/personal-web-server">openrepos.net</a>)</li>
<li>Mustr (<a href="http://thp.io/2012/mustr/">web page</a>, <a href="http://thp.io/2012/mustr/mustr_1.0.2_armel.deb">deb download</a>, <a href="https://openrepos.net/content/thp/mustr">openrepos.net</a>) </li>
<li>gPodder (<a href="http://gpodder.org/">web page</a>, <a href="http://gpodder.org/releases/gpodder_3.6.1_harmattan.deb">deb download</a>, <a href="https://openrepos.net/content/thp/gpodder-harmattan">openrepos.net</a>)</li>
</ul>
And here's a list of my N9 games that you can now get for free (again, "deb download" is as of posting this; new versions on the webpage or openrepos.net):<br />
<ul>
<li>qw The Game (<a href="http://thp.io/2010/qw/">web page</a>, <a href="https://openrepos.net/content/thp/qw-game">openrepos.net</a>)</li>
<li>Tennix! Redux Demo (<a href="http://thp.io/2011/tennix/">web page</a>, <a href="http://thp.io/2011/tennix/tennix_2.0.0_armel.deb">deb download</a>, <a href="https://openrepos.net/content/thp/tennix-redux-demo">openrepos.net</a>)</li>
<li>Petals (<a href="http://thp.io/2013/petals/">web page</a>, <a href="http://thp.io/2013/petals/petals_1.0.1_armel.deb">deb download</a>, <a href="https://openrepos.net/content/thp/petals">openrepos.net</a>)</li>
<li>Brain Party (<a href="http://thp.io/2012/brainparty/">web page</a>, <a href="https://openrepos.net/content/thp/brain-party">openrepos.net</a>)</li>
<li>Numpty Physics (<a href="http://thp.io/2012/numptyphysics/">web page</a>, <a href="https://openrepos.net/content/thp/numpty-physics">openrepos.net</a>)</li>
<li>Plonk (<a href="http://thp.io/2011/plonk/">web page</a>, <a href="https://openrepos.net/content/thp/plonk">openrepos.net</a>)</li>
<li>chro.mono (<a href="http://thp.io/2013/chromono/">web page</a>, <a href="http://thp.io/2013/chromono/chromono_1.0.0_armel.deb">deb download</a>, <a href="https://openrepos.net/content/thp/chromono">openrepos.net</a>)</li>
</ul>
Of these, the "greatest hits" and most useful apps/most fun games are (in my opinion): <b>Billboard</b>, <b>Volume+ As Camera Button</b> and <b>chro.mono</b>, but also give <b>qw The Game</b> and <b>Petals</b> a try :)<br />
<br />
A <a href="https://openrepos.net/user/155/programs">list of all my apps on OpenRepos.net</a> is also available.<br />
<br />
Please note that unless otherwise noted, do not copy the .deb files and distribute them yourself, please always link to the project webpage (the page, not the file) or the openrepos.net page - this makes sure users can always download the latest version and from a known-good source (always be careful when downloading and installing .debs from random webpages). For end users who want to stay up to date and install the packages comfortably, <a href="https://openrepos.net/content/basil/warehouse">the Warehouse client</a> for OpenRepos.net is recommended.<br />
<br />
For some of these apps (not games) that are not open source yet, I plan to clean up and publish the source at some point in the future, so interested developers can have a look, add features and/or port it to new platforms. thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-25814061970134770452014-03-15T11:07:00.000+01:002014-03-15T11:07:36.405+01:00gPodder 4.0.0 for Sailfish OS releasedWhile we're supplying N9 users with fresh releases of gPodder 3 regularly (the latest version, 3.6.1, has been <a href="http://blog.gpodder.org/2014/03/gpodder-361-little-orphan-airplane.html">released last week</a>, and the update is available on <a href="http://gpodder.org/downloads">gpodder.org/downloads</a>), of course we've also been busy working on a newer, Qt 5 and <a href="http://thp.io/2011/pyotherside/">PyOtherSide</a>-based version of gPodder. After weeks of testing, I think it's good enough for a first release now, so let's <a href="http://blog.gpodder.org/2014/03/gpodder-400-iffy-kiffy-izzy-oh-released.html">warmly welcome</a> gPodder 4.0.0 to the world of Sailfish apps. You can download it and its dependencies from the <a href="http://gpodder.org/downloads">gPodder downloads page</a>.<br />
<br />
If you haven't read last year's <a href="http://thpmaemo.blogspot.co.at/2013/07/the-way-forward-with-python-on-qt-5.html">article about Python and Qt 5</a>, now might be a good time to do so. PyOtherSide is a much more minimalistic approach to Python bindings, and - in my obviously biased opinion - works better for gluing together a QML UI with a Python backend. In fact, it lends itself to clearly splitting the frontend from the backend, and with the "asynchronous by default" design, you have to work really hard to block your UI thread with long-running Python code (or multithreaded Python code that's waiting for the <a href="http://en.wikipedia.org/wiki/Global_Interpreter_Lock">GIL</a> to be released). PyOtherSide these days is also <a href="http://pyotherside.readthedocs.org/en/latest/">well-documented</a>, and some early annoyances and bugs have been fixed with recent releases in February. In combination with Qt 5 and Python 3, it works well on OS X, Blackberry 10, Linux, Sailfish OS and Windows. With Qt 5.2 having official support for Android, and a Python 3 port being available, it's only a matter of time before PyOtherSide lands on Android.<br />
<br />
For all Sailfish OS users out there: Until the next Sailfish OS update, you might have to install some dependencies before gPodder will correctly start up, these are:<br />
<ol>
<li><a href="http://repo.merproject.org/obs/home:/thp:/gpodder/latest_armv7hl/armv7hl/libpython3_3m1_0-3.3.5-1.6.1.armv7hl.rpm">libpython3</a> (the Python 3 interpreter)</li>
<li><a href="http://repo.merproject.org/obs/home:/thp:/gpodder/latest_armv7hl/armv7hl/python3-base-3.3.5-1.6.1.armv7hl.rpm">python3-base</a> (the Python 3 standard library)</li>
<li><a href="http://repo.merproject.org/obs/home:/thp:/gpodder/latest_armv7hl/armv7hl/pyotherside-qml-plugin-python3-qt5-1.2.0-1.5.3.armv7hl.rpm">pyotherside</a> (the Qt 5-Python3 bindings)</li>
</ol>
As these links point to the current version in OBS, they will break once one of these packages is updated. In this case, just look into the <a href="http://repo.merproject.org/obs/home:/thp:/gpodder/latest_armv7hl/armv7hl/">home:thp:gpodder armv7hl repository</a> for the latest versions of these packages. With the next Sailfish OS update, recent-enough packages of PyOtherSide should be in the repositories, so you don't need to install the dependencies manually.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com4tag:blogger.com,1999:blog-6145140879520785870.post-32787349482294473522013-07-18T16:41:00.000+02:002013-07-18T16:41:05.230+02:00The way forward with Python on Qt 5 (with a bit of history)As you have probably heard on Twitter from the official Jolla account, <a href="https://twitter.com/JollaHQ/status/356034168351756290">the first Jolla will ship with Wayland</a>. In that discussion, some worries are brought up about Python support with Qt 5. Here are my personal thoughts of how I see mobile Python development moving forward with the new technology. So first some background information:<br />
<br />If you want to write Python applications on a mobile platform, you usually need some way to interface with the native graphical toolkit. On Maemo 4 and Maemo 5, this was done via PyGTK and some additional bindings for the Hildon UI elements. PyGTK is licensed under the terms of the GNU LGPL, so you could use it to develop open and closed source applications.<br />
<br />
When MeeGo 1.2 Harmattan (the system running on the N9) came up, the toolkit with which third party application developers wrote their applications changed from Gtk to Qt (or to be more precise, QML). Just like pure Gtk didn't provide all the UI elements for mobile (and therefore Hildon was used on top of Gtk), pure QML provided very little, and so Qt Quick Components were used for the Harmattan user interface (that includes things like buttons, toolbars, menus, dialogs, etc...). These could only be used from QML, so you had to use QML if you wanted your application to look anything like native (ignoring the MeeGo Touch Framework here, as it wasn't really used for third party apps, with the notable exception of <a href="https://gitorious.org/qtbook/sociality-mtf">sociality-mtf</a>).<br />
<br />
With Qt and QML being the new toolkit of choice, Python developers needed a different "bridge" to go from the Python world to the toolkit world. <a href="https://en.wikipedia.org/wiki/PyQt">PyQt</a> already existed for some time then, it had two license options: GNU GPL (basically requiring all your code that uses PyQt to also become GPL'd) and commercial. As the <a href="https://en.wikipedia.org/wiki/PySide">Wikipedia article of PySide</a> says, after Nokia failed to reach an agreement with Riverbank Computing (the developers of PyQt) to change the license to LGPL, they started their own Python bindings named "PySide", which are licensed under the terms of the GNU LGPL. There's a <a href="http://qt-project.org/wiki/Differences_Between_PySide_and_PyQt">wiki page with PySide-PyQt differences</a> on the Qt Wiki.<br />
<br />
As MeeGo at Nokia was ramped down, the core team of PySide had less and less time to spend on improving it. PySide is still kept up to date (the latest release is from July 9, 2013), and it already supports Python 3, but nobody has yet ported it to Qt 5. The most recent post I found about PySide and Qt 5 from one of the core developers was <a href="https://groups.google.com/forum/#!topic/pyside/tFexVyqP6tM">from November 2011</a>. For using Python with Qt 5, there are two possibilities at the moment: Use PyQt under the terms of the GNU GPL, or get a commercial PyQt license. Another option to get LGPL'd bindings would be to add support for Qt 5 to PySide, but that needs somebody to adapt PySide to work with Qt 5.<br />
<br />
But let's step back a little now. In my experience with writing Python applications for mobile operating systems (starting with Maemo 4 all the way to MeeGo 1.2 Harmattan), there are really two parts: The frontend, which is specified in terms of whatever the toolkit of the day happens to be, and the backend, which (in case of Python applications) is written in Python.<br />
<br />
In Qt 5 / QtQuick, the user interface language is QML, which includes a declarative language and JavaScript for scripting. Writing QtQuick applications with Python doesn't mean replacing JavaScript, it means replacing the "backend" - code that would usually be written in C++ and take care of storage and communication. In fact, as QML grew more powerful over the years, you had to "go down to the C++ level" (or Python in our case) less often. And compared to imperative user interfaces (where you still go through your tree of UI widgets with code and then set some button text to some value), in declarative user interfaces the backend really only provides services to the frontend (that button gets the label from the backend in this way, and when the data in the backend changes, so does the button's text).<br />
<br />
So, what we really need is a way to provide services to the QML UI by using Python. There's no need for having access to all classes in all Qt modules - even in Qt4 / PySide times, the classes that I used most often were QApplication (for the event loop), QDeclarativeView (for displaying the QML UI) and QObject (for providing signals and slots to interface the backend to the view). Things like access to the contacts database or GPS location can usually be done directly from QML (and displayed there) - it might be that you don't even need to have that data in your backend (and if you do, the UI can for example send the phone number of the contact "down to" the Python backend for further processing).<br />
<br />
But before I'll tell you where I think mobile Python development should be heading, let's bring up yet another disadvantage of using PySide (probably applies to PyQt as well) for mobile applications: Startup time and responsiveness. Startup time is slow, because PySide libraries are big (they are - at least on the N9 - bigger than the Qt libraries they are binding), and the dynamic linker has to resolve all Qt symbols at load time instead of just the ones you end up using. Instead of seeing the QML UI right away, your application first has to load up the Python interpreter, then load up the PySide modules and other modules and then finally load and display the QML UI. And because of Python's <a href="https://en.wikipedia.org/wiki/Global_Interpreter_Lock">Global Interpreter Lock</a>, function calls from QML to Python will make the UI block and not be totally responsive, even if you are using threads.<br />
<br />
So, in my opinion, mobile Python applications with Qt 5 have to be fast to load, lightweight and responsive. Fast to load can be achieved by making sure the libraries that get loaded are small, and that ideally the QML UI can already be displayed before the Python interpreter is even loaded and/or initialized. Lightweight can be achieved by not binding <a href="https://qt-project.org/doc/qt-5.1/qtdoc/classes.html">all the Qt classes</a>, but only the ones you really need for creating QML applications. And responsive can be achieved by making sure that the interface between QML and Python is asynchronous, so the UI never blocks even if Python is working hard in the background to fulfill the requests of the user interface.<br />
<br />
I currently have a prototype running on Python 3.3 (Python 2.6 and 2.7 is also supported still, but for me, this is a great opportunity to migrate some of my old code to Python 3, and new code should be written in Python 3, because, as you know, <a href="https://github.com/thp/python2sucks">Python 2 sucks</a>) and Qt 5 (I've just ported it to Qt 5 today, but it runs just as well on Qt 4 - with all the advantages like startup time and asynchronousness still being valid). In some unscientific tests that I carried out a few weeks ago, I've brought down startup time of gPodder on the N9 down from ~ 12 seconds (using Python 2 and PySide) to ~ 3 seconds (using Python 3.3 and the lightweight "PyOtherSide" approach). No code release yet, as this is tailored towards my gPodder experiment right now and has many things hardcoded, but once I clean it up (maybe as a QML plugin) and define the API in more detail, I plan to release it.<br />
<br />
In the mean time, here are some (relatively old) videos of PyOtherSide running with Python 3 and Qt 4 on <a href="http://www.youtube.com/watch?v=iqphTKirkKw">MeeGo Harmattan</a>, <a href="http://www.youtube.com/watch?v=mh7aKo02tGQ">Blackberry 10</a> and <a href="http://www.youtube.com/watch?v=KOMCgVVkvIE">Android</a> (so yes, it is portable).thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com3tag:blogger.com,1999:blog-6145140879520785870.post-51604571292005446022013-05-16T11:00:00.000+02:002013-05-16T11:00:05.133+02:00Behind the Scenes: Headset Camera app for the N9The logical step after the "<a href="http://thp.io/2012/camerra/">Volume+ as Camera Button</a>" app (<a href="http://store.ovi.com/content/252565">Nokia Store link</a>) for the N9 is another app that allows you to take photos while not touching your N9 at all. While time-triggered photos are fun, remote-triggered photos are.. erm.. "funner"? So what kind of remote "buttons" can we easily get on the N9? The remote control button on the headset is both "remote" and a "button". Also, as seen in <a href="http://wiki.gpodder.org/wiki/Panucci">Panucci</a> and <a href="http://gpodder.org/">gPodder</a> versions since the N900, Bluetooth headset buttons can also be queried by applications. So what do we get by combining remote control and photo taking? The <a href="https://thp.io/2013/headsetcamera/">Headset Camera</a> app (<a href="http://store.ovi.com/content/355515">Nokia Store link</a>) for the N9! Or - for the visual reader - this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://thp.io/2013/headsetcamera/screenshot1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://thp.io/2013/headsetcamera/screenshot1.jpg" width="320" /></a></div>
<br />
<br />
If you want to integrate such features into your own app, the code for querying the headset buttons is readily available in the gPodder source tree (<a href="https://github.com/gpodder/gpodder/blob/master/src/gpodder/qmlui/helper.py">src/gpodder/qmlui/helper.py</a>):<br />
<pre>import dbus
class MediaButtonsHandler(QtCore.QObject):
def __init__(self):
QtCore.QObject.__init__(self)
headset_path = '/org/freedesktop/Hal/devices/computer_logicaldev_input_0'
headset_path2 = '/org/freedesktop/Hal/devices/computer_logicaldev_input'
system_bus = dbus.SystemBus()
system_bus.add_signal_receiver(self.handle_button, 'Condition',
'org.freedesktop.Hal.Device', None, headset_path)
system_bus.add_signal_receiver(self.handle_button, 'Condition',
'org.freedesktop.Hal.Device', None, headset_path2)
def handle_button(self, signal, button):
if signal == 'ButtonPressed':
if button in ('play-cd', 'phone'):
self.playPressed.emit()
elif button == 'pause-cd':
self.pausePressed.emit()
elif button == 'previous-song':
self.previousPressed.emit()
elif button == 'next-song':
self.nextPressed.emit()
playPressed = QtCore.Signal()
pausePressed = QtCore.Signal()
previousPressed = QtCore.Signal()
nextPressed = QtCore.Signal()
</pre>
<span style="font-family: "Courier New",Courier,monospace;">MediaButtonsHandler</span> is already a QObject subclass, so you can easily expose an instance of this class to your QDeclarativeView <span style="font-family: "Courier New",Courier,monospace;">rootContext()</span> and connect to the signals in QML (such a "headset button handler" might actually be a good candidate for inclusion into <a href="https://github.com/nemomobile/nemo-qml-plugins">nemo-qml-plugins</a> in Sailfish OS and Nemo Mobile?). As it's really just using the Python D-Bus bindings to get property changes from Hal devices, the code above should be easy (read: trivial) to port from Python to Qt/C++. Be aware that you need to connect to both <span style="font-family: "Courier New",Courier,monospace;">.../computer_logicaldev_input_0</span> and <span style="font-family: "Courier New",Courier,monospace;">.../computer_logicaldev_input</span>, which can both exist if you have a cable headset and a Bluetooth headset connected at the same time.<br />
<br />
You can <a href="http://store.ovi.com/content/355515">get the Headset Camera App</a> for the N9 in Nokia Store now, there is also <a href="http://youtu.be/nboCvWMoKyk">a video on YouTube showing the app</a>. Or start integrating headset button features into your own app or scripts by adapting the code above. One use case that comes to mind is using the previous/next buttons on a Bluetooth headset to control a photo slideshow on the N9 connected to TV-Out. Enjoy :)thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-87147687474448755772013-05-14T20:28:00.000+02:002013-05-14T20:28:00.526+02:00HTML5 Web Apps on Mobile DevicesGet out your Buzzword Bingo cards, we're talking HTML5. And Canvas2D. And WebGL. See? Check them off and then continue reading. So, while <a href="http://thpmaemo.blogspot.com/2013/05/petals-for-harmattan-pure-qt4qt5-jsqml.html">writing "native" apps using JavaScript</a> is definitely possible and works great with QML, some games are just simple enough (or want to have a broad enough audience) to warrant writing everything in HTML5.<br />
<br />
This might also be a good time to check off XmlHttpRequest on your BB card, even if none of the following games use it - you might want to use it in your applications or game for things such as server-side stored high scores.<br />
<br />
As far as Maemo and MeeGo is concerned, you might want to try out some of these games (especially the WebGL variant of <a href="http://pyug.at/PyWeek/2012-09">One Whale Trip</a>) in Fennec (aka Mobile Firefox - get it for: <a href="http://store.ovi.com/content/26002">N900</a>, <a href="http://store.ovi.com/content/257468">N950/N9</a>, <a href="http://thp.io/2013/maemo/nemo-fennec.html">Nemo Mobile</a>). <br />
<br />
<a href="https://thp.io/2013/colorlines/">Color Lines</a>: This one simply uses Canvas2D, and works nicely on all mobile browsers that I tested - Maemo, MeeGo, Android, WP7.5, BB Playbook, iOS. Comes in at about 650 lines of rather well-documented JavaScript, and could easily be ported to use QML as a renderer if need be (it would be good to have a QML Plug-In that provides a JavaScript context + (a subset of) the Canvas2D API - without using WebKit (cross that off, too), that is). Also, the N900's stock browser has performance problems rendering this, while on the same device in Fennec it's quite playable.<br />
<br />
<a href="https://thp.io/2013/circle1d/html-canvas/">Circle1D</a>: This is a straight Python-to-JavaScript port of <a href="http://thp.io/2013/circle1d/">a lame 2D "Physics" Engine</a>. It's kept very (read: very, very) simple, and collision detection could be done in a nicer way, but the inefficiency of it provides a nice benchmark for comparing JavaScript engine performance (I'm sure you can find "engine performance" on your bingo card as well) on mobile devices. The N900's default browser can't handle it at all, but Fennec can at least render/simulate it, albeit slowly. <br />
<br />
<a href="https://thp.io/2013/onewhaletrip/">One Whale Trip</a>: This game actually started out as a <a href="http://pyug.at/PyWeek/2012-09">Python game for PyWeek</a> last September, which was also <a href="http://talk.maemo.org/showthread.php?t=89372">ported to the N950/N9</a>, but as a test for trying out WebGL, I decided to port it from Python/PyGame to JavaScript/Canvas2D and then to WebGL (the Python version also contains two renderers - a "blitting" one using PyGame surfaces, and an OpenGL one using OpenGL [ES 2 on mobile]). The Canvas2D version works again in all modern mobile browsers (same as above), the WebGL only works on browsers supporting WebGL, for example Fennec/Firefox on both the N900 (even though very slowly) and not in any of the stock browsers (even not the one on the N9). As WebGL is "roughly" the same as OpenGL ES 2.x, one could imagine sharing at least shader programs for a possible C++-or-JavaScript cross-platform application.<br />
<br />
So yeah, for smaller applications and/or games, HTML5 is definitely an option. In <a href="https://developer.mozilla.org/en/docs/Mozilla/Firefox_OS">Firefox OS</a>, your HTML5 web app will - also with WebGL - work and integrate nicely as "native" app. If you also want to create "native" applications (maybe after finishing the HTML5 version), consider encapsulating your JavaScript code so that you can re-use it in QML code, or (in case of WebGL apps), at least design the rendering part of your application in such a way that the code/architecture and shader programs can be shared with a C++ port of your existing HTML5 app.<br />
<br />
Another option that's worth considering: Writing a compatiblity application layer that can load (specially-crafted) WebGL subset applications and display them on a fullscreen SDL-(or Qt)-provided window. Applications written in this WebGL subset could then be deployed on the web as HTML5 application or "natively" running on top of a JavaScript engine only. I'd call that "<span style="font-family: "Courier New",Courier,monospace;">webglenv</span>", and no, I haven't written it yet.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-20584606978785454722013-05-12T11:30:00.000+02:002013-05-12T11:30:01.005+02:00Petals for Harmattan - A pure Qt4/Qt5 JS/QML puzzle gameNext up in my list of things I did in the last weeks/months and never blogged about is <a href="https://thp.io/2013/petals/">Petals</a> (<a href="http://store.ovi.com/content/363292">Nokia Store link</a>), a "<i>beautiful, brain-teasing puzzle game for 1-4 players</i>" if the game's website is to be believed (I would like to think it is...). As always, there's some technical details about the porting and creation of this game. While another recent game (<a href="http://thp.io/2013/tetrepetete/">Tetrepetete</a>) has been done on a low level (C++ using no frameworks, and interfacing with multiple front-ends directly, including an OpenGL ES frontend, a <a href="http://youtu.be/g6AMngkwbsQ">console-based ncurses frontend</a>(!) as well as a <a href="http://youtu.be/Zf3uVGKKJW8">server-sent events/XHR/Canvas2D-based HTML5 frontend</a>(!!)), this one is approaching things from a very high level: JavaScript.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://thp.io/2013/petals/squareshot_a.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://thp.io/2013/petals/squareshot_a.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://thp.io/2013/petals/">Petals</a>: A puzzle game written in pure JavaScript and QML</td></tr>
</tbody></table>
The gameplay logic of the game is implemented in pure JavaScript (without any QML dependencies), so it could easily be ported to, say, HTML5, but for integration reasons, QML seemed like the better choice for a release on the N9/Harmattan. Also, writing things in JavaScript wouldn't preclude a console-based frontend using nodejs and <a href="https://github.com/mscdex/node-ncurses">node-ncurses</a> from happening should the need arise (making the flowers look good in ASCII art would be the challenge there - or cheating by using <a href="http://caca.zoy.org/wiki/libcaca">libcaca</a>). Ok, ok - stop cursing, I'll stop talking about curses (cue laugh track).<br />
<br />
Writing pure QML applications has the advantage of easing porting to Qt 5. While QtQuick 1.1 still exists on Qt 5 (and is <a href="http://blog.qt.digia.com/blog/2013/04/15/evolution-of-the-qml-engine-part-1/">the only QML option at the moment</a> if you are also targetting iOS), QtQuick 2.0 is usually the better choice for performance reasons.<br />
<br />
In my case, the changes necessary to port from QtQuick 1.1 to QtQuick 2.0 were:<br />
<ul>
<li>Change "<span style="font-family: "Courier New",Courier,monospace;">import QtQuick 1.1</span>" to "<span style="font-family: "Courier New",Courier,monospace;">import QtQuick 2.0</span>" (<span style="font-family: "Courier New",Courier,monospace;"><a href="http://linux.die.net/man/1/sed">sed</a>(1)</span> helps here)</li>
<li>Instead of assigning a JavaScript function to a property to create a dynamic property binding (<span style="font-family: "Courier New",Courier,monospace;">item.someprop = function() { return otheritem.otherprop * 3.0; }</span>), this function has to be wrapped in a call to Qt.binding() in Qt 5 (see "<a href="http://qt-project.org/doc/qt-5.0/qtqml/qtqml-syntax-propertybinding.html">Creating Property Bindings from JavaScript</a>" in the Qt 5 docs)</li>
<li>Instead of using SQL Local Storage directly as in QtQuick 1.1, use <a href="http://qt-project.org/doc/qt-5.0/qtquick/qmlmodule-qtquick-localstorage2-qtquick-localstorage-2.html">QtQuick.LocalStorage 2.0</a>, which you can still do in your .js files - <a href="http://kunalmaemo.blogspot.com/2013/03/using-localstorage-api-from-javascipt.html">use ".import" as described in this blog post</a></li>
<li>In your C++ launcher (in case you need one), <span style="font-family: "Courier New",Courier,monospace;">QApplication</span> becomes <span style="font-family: "Courier New",Courier,monospace;">QGuiApplication</span>, and <span style="font-family: "Courier New",Courier,monospace;">QDeclarativeView</span> becomes <span style="font-family: "Courier New",Courier,monospace;">QQuickView</span></li>
<li>Use "<span style="font-family: "Courier New",Courier,monospace;">QT += quick qml</span>" instead of "<span style="font-family: "Courier New",Courier,monospace;">QT += declarative</span>" in your qmake project file</li>
</ul>
And that's basically it. Of course, as this is a full-screen game with custom UI, no platform-specific components (such as <a href="http://harmattan-dev.nokia.com/docs/library/html/qt-components/qt-components.html">Harmattan Components</a> or <a href="https://sailfishos.org/sailfish-silica/">Sailfish Silica</a>) are used, so porting is a bit easier there (no need to "wait" for specific components to be compatible with QtQuick 2.0, which might realistically not happen at all for Harmattan Components). More screenshots of Petals and download links for multiple platforms can be found on the <a href="https://thp.io/2013/petals/">Petals Website</a>.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-31248048699982267012013-05-08T19:20:00.001+02:002013-05-08T19:20:58.185+02:00Upcoming: Billboard 1.0.9 for Nokia N9Turns out I haven't posted here for two months, so here we go again: <a href="http://thp.io/2012/billboard/">Billboard</a>, your favorite low-power mode standby screen will soon receive a new update - version 1.0.9 has been uploaded to Nokia Store QA two days ago, and should hopefully pass QA and be available as an update in the next few days. This release brings a few major under-the-hood improvements and small bugfixes:<br />
<ul>
<li>Fixed MeeCast icon (in 1.0.8, you can already use <span style="font-family: "Courier New",Courier,monospace;"><<{meecast-icon-src}>></span>)</li>
<li>New formatter that allows you to <a href="http://www.flickr.com/photos/thp4/8619724556">nest {} expressions</a> used for adding dynamic content</li>
<li> Optional <a href="http://www.flickr.com/photos/thp4/8655275610">image dithering</a> (using <span style="font-family: "Courier New",Courier,monospace;">#</span> after the filename) for better colors in low power mode</li>
</ul>
With the new formatter, you can now output {} expressions in your scripts so that they get replaced, and similarly pass {} expressions as parameters to your scripts (for example to modify them in some way before displaying). This should allow for even more customization, some examples of what users have been doing on their N9 standby screen can be seen in the <a href="http://talk.maemo.org/showthread.php?t=84507">Billboard Standby Screen support thread</a> on talk.maemo.org.<br />
<br />
If you are looking for additional ways to tweak and enhance your Billboard-on-N9 experience, have a look at <a href="https://github.com/harmattan/billboard-scripts">billboard-scripts</a>, a growing collection of Shell and Python scripts that provide even more ways of customizing your standby screen.<br />
<br />
If you haven't purchased Billboard from Nokia Store yet, you can <a href="http://store.ovi.com/content/279408">get the current version now</a> for your N9, and get the upgrade to 1.0.9 as soon as it's available. If you are already a happy user, watch your application updates in the next few days, and get the new version.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-45776180601311890872013-03-05T21:19:00.002+01:002013-03-05T21:19:44.493+01:00Porting Harmattan Apps to Sailfish Silica (and back)So the <a href="https://sailfishos.org/develop.html">Sailfish SDK</a> was released last week, and as explained in the <a href="http://thpmaemo.blogspot.co.at/2013/03/how-to-try-out-gpodder-in-sailfish-os.html">last blog post</a>, <a href="http://gpodder.org/">gPodder</a> is already running on <a href="https://sailfishos.org/sailfish-silica/">Sailfish Silica Components</a>. Of course, this has only been possible because Silica is quite similar in API design to Harmattan Qt Components (whenever I write "Harmattan" in this blog post, I usually talk about Harmattan Qt components, and whenever I write "Sailfish" it usually means "Sailfish Silica Components"). But of course porting "from" Harmattan "to" Sailfish with no way back would be kind of annoying - either Harmattan gets dropped, or somebody has to maintain two codebases, something I'd rather avoid. So, just like in "good old" Maemo 4 and Maemo 5 times, the goal here is to convert a Harmattan-only codebase to Harmattan-and-Sailfish, so that both can be maintained in the same codebase and improvements to Harmattan benefit the Sailfish port and vice versa.<br />
<br />
In fact, while porting gPodder from Harmattan to Sailfish, it reminded me of porting from Maemo 4 to Maemo 5 - same toolkit (then Gtk+, now Qt/QML), similar extensions (then Hildon, now Components) but different concepts (then <a href="http://wiki.maemo.org/PyMaemo/Using_Python_in_Maemo#Changing_to_HildonWindow_menu_bar">normal menus</a> in Maemo 4 vs. <a href="http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Human_Interface_Guidelines/View_Menu">HildonAppMenu</a> in Maemo 5, now toolbars and <a href="http://dfilebrowser.deuteros.es/node/5">context menus</a> in Harmattan vs. <a href="http://www.flickr.com/photos/thp4/8514960057/">pulley menus</a> in Silica).<br />
<br />
Obviously, as gPodder is written in Python here, this applies mostly to PySide-based applications, but the real difference is in the QML (there's really <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/src/gpodder/qmlui/__init__.py#L1042">only one short snippet</a> in the Python code that decides which QML import path to use). The approach taken is somewhat simliar to what the Jolla guys have been presenting at <a href="http://thpmaemo.blogspot.co.at/2013/02/fosdem-2013.html">FOSDEM 2013</a>, but I don't recall everything and have tailored the approach to better fit my workflow.<br />
<br />
Before we start, be sure to know that qt-components is in the Sailfish Emulator (once you install it via "zypper in qt-components" as root), so that could be a shortcut for quick porting exercises and as an interim solution. <br />
<br />
For starters, I've cleaned up gPodder's QML UI to make better use of Qt Components (historically, gPodder's QML UI was started at a time where Harmattan Qt Components were not even out or announced, so <a href="http://maemo.org/profile/view/wazd/">wazd</a> and me <a href="http://thpmaemo.blogspot.co.at/2011/02/gpodderqml-status-with-screenshot-and.html">came up with our own style</a> - yes, that's pre-feb11 even!). So, instead of custom transitions and state management, everything is a <a href="http://harmattan-dev.nokia.com/docs/library/html/qt-components/qt-components-meego-page.html">Page</a>, and transitions happen via the <a href="http://harmattan-dev.nokia.com/docs/library/html/qt-components/qt-components-meego-pagestack.html">PageStack</a> (the Silica equivalents are also called <a href="https://sailfishos.org/sailfish-silica/qml-sailfishsilica-page.html">Page</a> and <a href="https://sailfishos.org/sailfish-silica/qml-sailfishsilica-pagestack.html">PageStack</a>). So, assuming you only have pages and so on, you could theoretically already use this or that depending on which platform you are on. Unfortunately, QML doesn't have conditional imports or something like that, so we have to add some abstraction layer.<br />
<br />
Here's the basic idea:<br />
<ol>
<li>Create a new "Components" set - I'm calling mine "org.gpodder.qmlui"</li>
<li>You define which items your components have, and a common API</li>
<li>You implement your components twice: Once for Harmattan, once for Sailfish</li>
<li>At runtime (or even compile time if you would want that) you decide which set of components you use</li>
<li>Your application GUI code only imports QtQuick, maybe QtMultimediaKit (if you need it - it's available on both platforms) and your custom components (org.gpodder.qmlui in my case)</li>
</ol>
Just in case you are already running to the <a href="http://github.com/gpodder/gpodder">gPodder Git repo</a> now to check it out, here's a short disclaimer: The UI isn't fully ported yet, so there's still a few remaining "com.nokia.meego" (Harmattan Qt Components) imports in my QML UI, but that's just temporary until I have found a good replacement for things like <a href="http://harmattan-dev.nokia.com/docs/library/html/qt-components/qt-components-meego-sheet.html">Sheet</a> and <a href="http://harmattan-dev.nokia.com/docs/library/html/qt-components/qt-components-meego-multiselectiondialog.html">MultiSelectionDialog</a> in Silica.<br />
<br />
My custom components at this time look like this:<br />
<ul>
<li><a href="https://github.com/gpodder/gpodder/tree/gpodder-3.5.0/share/gpodder/ui/qml/harmattan/org/gpodder/qmlui">Harmattan implementation</a> of org.gpodder.qmlui (as of gPodder 3.5.0)</li>
<li><a href="https://github.com/gpodder/gpodder/tree/gpodder-3.5.0/share/gpodder/ui/qml/sailfish/org/gpodder/qmlui">Sailfish implementation</a> of org.gpodder.qmlui (as of gPodder 3.5.0)</li>
</ul>
Most of these are just thin wrappers around the "native" components on the target platform. For example, WindowWindow.qml (<a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/harmattan/org/gpodder/qmlui/WindowWindow.qml">harmattan</a>, <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/sailfish/org/gpodder/qmlui/WindowWindow.qml">sailfish</a>) is just a wrapper for PageStackWindow (on Harmattan) and ApplicationWindow (on Sailfish). Where I said "import com.nokia.meego 1.0" and "PageStackWindow {}" previously, I now say "import org.gpodder.qmlui 1.0" and "WindowWindow {}". In the case of the Harmattan implementation, this is just the same as before, but on Sailfish, an ApplicationWindow will be used.<br />
<br />
Other wrappers just deal with API differences. For example, ScrollDecorator exists in both Harmattan and Sailfish, but in Harmattan the property is called "flickableItem" and on Sailfish it's "flickable". So my ScrollScroll (<a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/harmattan/org/gpodder/qmlui/ScrollScroll.qml">harmattan</a>, <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/sailfish/org/gpodder/qmlui/ScrollScroll.qml">sailfish</a> - also, noticed a naming pattern there? ;) takes care of hiding the differences, and I just use "flickable" on a ScrollScroll, and it will do The Right Thing on the platform it's currently running on.<br />
<br />
When the API is the same (e.g. for Button), you still need to create pass-through components because of the different import path: Button (<a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/harmattan/org/gpodder/qmlui/Button.qml">harmattan</a>, <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/sailfish/org/gpodder/qmlui/Button.qml">sailfish</a>).<br />
<br />
But there's also some more elaborate differences. For example, I want to have menus - a toolbar menu on Harmattan and a pulley menu on Sailfish. So I defined a very simple <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/Action.qml">Action</a> (I'd be surprised if such a component doesn't already exist, but I didn't find one when I wasn't looking (sic)) that basically has a text and some signal attached to it. In my application code, I define actions as a property on my PagePage (which is a Page with some special code to transform actions into whatever the platform representation is). See <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/main_default.qml#L27">the main page actions</a> for an example. The ActionMenu (<a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/harmattan/org/gpodder/qmlui/ActionMenu.qml">harmattan</a>, <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/sailfish/org/gpodder/qmlui/ActionMenu.qml">sailfish</a>) then takes care of creating a ContextMenu (Harmattan) or PullDownMenu (Sailfish) and PagePage (<a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/harmattan/org/gpodder/qmlui/PagePage.qml">harmattan</a>, <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/sailfish/org/gpodder/qmlui/PagePage.qml">sailfish</a>) takes care of creating a toolbar on Harmattan and forwarding a reference to the listview to which the PullDownMenu should be attached to (in Harmattan, I still need to pass the listview there, but it's not used).<br />
<br />
The same customization also happens for the ListList (<a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/harmattan/org/gpodder/qmlui/ListList.qml">harmattan</a>, <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/sailfish/org/gpodder/qmlui/ListList.qml">sailfish</a>), which is a ListView (Harmattan) or SilicaListView (Sailfish), but also takes care of displaying a header (which still needs to be styled correctly on Sailfish) if the platform requires it.<br />
<br />
Once you've created your custom set of components, you have to create a <a href="https://github.com/gpodder/gpodder/blob/gpodder-3.5.0/share/gpodder/ui/qml/harmattan/org/gpodder/qmlui/qmldir">qmldir</a> file that lists the components available and in which version of the components they are available. Read up on <a href="http://qt-project.org/doc/qt-4.8/qdeclarativemodules.html">Declarative Modules</a> in the official documentation.<br />
<br />
So there you have it. One QML codebase, two UX targets that are well-integrated. You can see the results in the just-released gPodder 3.5.0, which is more Harmattan-ish on the N9 than before (although some items have moved from the toolbar into the menu for simplicity reasons, and I actually think it's cleaner now) and also looks and feels quite native on Sailfish (it's not done yet, and I'm sure the UI will evolve and adapt once Silica gets more mature and we see more Sailfish apps).<br />
<br />
What I'd like to see in the Sailfish SDK: Different Ambiance backgrounds
(darker, brighter, different hues) so that developers like me can test
if their apps look good atop more than just the nice blue default
background.<br />
<br />
As a last hint (I couldn't find that in the API docs, but in the component gallery): Sailfish Silica's <a href="https://sailfishos.org/sailfish-silica/qml-sailfishsilica-label.html">Label</a> Component has a "truncationMode" property. If you set it to "TruncationMode.Fade", you never want to see elided text again, because it looks so sexy! :)thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com3tag:blogger.com,1999:blog-6145140879520785870.post-15090180159252742852013-03-02T15:46:00.003+01:002013-03-02T16:14:27.732+01:00How to try out gPodder in the Sailfish OS EmulatorYou might have seen this one coming: gPodder is <a href="http://flic.kr/thp4/sets/72157632881495048/">already</a> <a href="http://youtu.be/ysXB_ZfilDI">working</a> on Sailfish OS. If you want to try it out in the emulator yourself (no MP3 playback due to missing codecs, and some parts of the UI have not yet been ported), <a href="https://sailfishos.org/develop-installation-article.html">install the Sailfish SDK</a> and start the emulator (thanks to the interpreted'ness of Python, we don't have to care about cross-compiling at this point). Then, SSH into the emulator as user "nemo" (I'm purposefully vague here - if you can't <a href="https://twitter.com/thp4/status/306167698998587392">figure out</a> how to SSH into the emulator, then you probably shouldn't be trying it out at this point).<br />
<br />
From the "nemo" user, become root (use "su -", root password is "nemo") and then install some dependencies:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">zypper in python-pyside git qt-components</span><br />
<br />
With that in place, go back to the "nemo" user and get gPodder from Git:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">git clone git://github.com/gpodder/gpodder.git</span><br />
<br />
Then, cd into the Git checkout and start it as usual:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">cd gpodder</span><br />
<span style="font-family: "Courier New",Courier,monospace;">python tools/localdepends.py </span><br />
<span style="font-family: "Courier New",Courier,monospace;">bin/gpodder</span><br />
<br />
Again, you don't have to do any installation or compilation steps for gPodder - it will work straight out of a Git checkout (that's how I use it all the time). If you "export" the Emulator as appliance in VirtualBox and then "import" it on a different machine, you can even work with this nicely on Mac OS X and Windows. The fact that the emulator is just another Mer installation also means that you can install a compiler and -devel packages for quick development and testing. Vim 7.3 is already installed, I only wish <a href="http://www.zsh.org/">zsh</a> was also available in the Mer repos :)thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-6019837644907381622013-02-19T12:36:00.003+01:002013-02-19T12:39:41.978+01:00MP3 playback in Nemo Mobile on the N950If you've been playing with <a href="https://wiki.merproject.org/wiki/Nemo">Nemo Mobile</a> on your N950 recently, and wanted to do more than just swipe around the Lipstick UI, you might have noticed that while there's a music player app, it can't playback MP3 files (OGG files seem to work fine). This is a quick'n'dirty log of what I had to do to get MP3s playing (I've checked in the repos for something similar, but couldn't find it):<br />
<br />
First, install the Mer Platform SDK: <br />
<a href="https://wiki.merproject.org/wiki/Platform_SDK">https://wiki.merproject.org/wiki/Platform_SDK</a><br />
<br />
Then, get SB2 (for armv7hl, as this is what Nemo-on-N950 uses):<br />
<a href="https://wiki.merproject.org/wiki/Platform_SDK#Compiling_with_the_SDK">https://wiki.merproject.org/wiki/Platform_SDK#Compiling_with_the_SDK</a><br />
<br />
Then, set everything up so you can use "nemo-n950" as target with sb2:<br />
<a href="https://wiki.merproject.org/wiki/Platform_SDK_and_SB2">https://wiki.merproject.org/wiki/Platform_SDK_and_SB2</a><br />
<br />
Install build dependencies (you might need more than these, use "zypper se <packagename>" to search for package names):</packagename><br />
<span style="font-family: "Courier New",Courier,monospace;">sb2 -t nemo-n950 -m sdk-install -R zypper in gstreamer-devel gst-plugins-base-devel gst-plugins-bad-free-devel gstreamer-tools orc-devel zlib-devel</span><br />
<br />
Get the gst-ffmpeg sources (use version 0.10.11, due to <a href="https://bugzilla.gnome.org/show_bug.cgi?id=655238">bug 655238</a>):<br />
<a href="http://gstreamer.freedesktop.org/src/gst-ffmpeg/">http://gstreamer.freedesktop.org/src/gst-ffmpeg/</a><br />
<br />
Extract the sources, then do:<br />
<span style="font-family: "Courier New",Courier,monospace;">sb2 -t nemo-n950 ./configure --prefix=/usr</span><br />
<span style="font-family: "Courier New",Courier,monospace;">sb2 -t nemo-n950 make</span><br />
<span style="font-family: "Courier New",Courier,monospace;">mkdir tmp </span><br />
<span style="font-family: "Courier New",Courier,monospace;">DESTDIR=$(pwd)/tmp/ sb2 -t nemo-n950 make install</span><br />
<span style="font-family: "Courier New",Courier,monospace;">cd tmp/</span><br />
<span style="font-family: "Courier New",Courier,monospace;">scp -r . root@192.168.2.15:/</span><br />
<br />
The last step obviously assumes that your device is connected and <a href="https://wiki.merproject.org/wiki/Nemo/USBNetworking">USB networking</a> is properly set up. And then we hear somebody say "Well, but why not package it properly?". Ok. Take <a href="http://thp.io/2013/maemo/gst-ffmpeg.spec">this modified gst-ffmpeg.spec</a> file (based on gst-ffmpeg.spec already included in the sources). Then build a package using:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">mb build -t nemo-n950 gst-ffmpeg.spec</span><br />
<br />
This will leave you with <b>gst-ffmpeg-0.10.11-1.armv7hl.rpm</b> in <i>~/rpmbuild/RPMS/armv7hl</i> which you can then <span style="font-family: "Courier New",Courier,monospace;">scp</span> and <span style="font-family: "Courier New",Courier,monospace;">rpm -i</span> to your device.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-31595732905517936582013-02-07T14:57:00.000+01:002013-02-07T14:57:38.995+01:00FOSDEM 2013I attended <a href="https://fosdem.org/2013/">FOSDEM 2013</a> in Brussels, Belgium last weekend. It was my first FOSDEM, and as such, I was quite positively surprised about the location/setting (big University with too many rooms and tracks to visit them all) and reach of the event (open source projects from every different corner you can imagine).<br />
<br />
It was also nice to catch up with old friends from Maemo/MeeGo times like <a href="http://flors.wordpress.com/">Quim</a>, but at the same time it was impossible to say hi to everybody, as the location is so big, the event only lasts two days and everything is quite hectic and crowded. Still, I managed to meet community celebrities like <a href="http://rzr.free.fr/">rzr</a> (of <a href="https://build.pub.meego.com/project/show?project=home%3Arzr%3Aharmattan">Harmattan Community Repository</a> fame) and <a href="http://e-yes.livejournal.com/">e-yes</a> (of <a href="http://forum.nitdroid.com/">Nitdroid</a>-on-N9 fame) in person at the event, which was really nice.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm9.staticflickr.com/8372/8448608982_482c5ea20e.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://farm9.staticflickr.com/8372/8448608982_482c5ea20e.jpg" width="320" /></a></div>
<br />
Apart from meeting people and having a good time in Downtown Belgium (<a href="http://www.flickr.com/photos/thp4/8448613970/">so many beers to choose from</a>), Jolla Mobile was also present at the event, and I managed to attend two talks (<a href="http://www.flickr.com/photos/thp4/8447523633/">QML App Development</a> and <a href="http://www.flickr.com/photos/thp4/8447518889/">Porting Nemo to new Hardware</a>), where I found out about <a href="http://www.flickr.com/photos/thp4/8448611814/">Sailfish.Silica 1.0</a> (Jolla's Own Version of Qt Components), and <a href="http://www.flickr.com/photos/thp4/8448611516/">Open Source Components of Jolla</a> (really good to see Sailfish Silica open source'd and also good to see maliit and contextkit used as middleware).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm9.staticflickr.com/8086/8447516971_c1b4868432.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://farm9.staticflickr.com/8086/8447516971_c1b4868432.jpg" width="320" /></a></div>
<br />
The <a href="http://www.flickr.com/photos/thp4/sets/72157632697647004/">photos of the weekend</a>, including a quick sightseeing tour on Monday as well as your <a href="http://www.flickr.com/photos/thp4/8447516269/">usual</a> <a href="http://www.flickr.com/photos/thp4/8447516697/">dose</a> <a href="http://www.flickr.com/photos/thp4/8447509545/">of</a> <a href="http://www.flickr.com/photos/thp4/8447526679/">food</a> <a href="http://www.flickr.com/photos/thp4/8448612838/">porn</a> can be <a href="http://www.flickr.com/photos/thp4/sets/72157632697647004/">found on Flickr</a>.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-22024637798913354022013-01-29T22:39:00.000+01:002013-01-29T22:40:05.653+01:00Tetrepetete, SMS Backup and apkenv updatesWhew, January is pretty much over already, and there haven't been any updates here. So this means here's a short cumulative update of what's happened over the last few weeks:<br />
<br />
<b>Tetrepetete</b><br />
If you are not afraid of falling blocks, and don't mind the lack of colors, give <a href="http://thp.io/2013/tetrepetete/">Tetrepetete</a> a try. Not to be confused with a game of a totally different name, this game brings falling blocks of 4 to your N900 and N950/N9. While the full color version is still not available as such, the free greyscale version is up for grabs as .deb on the website. Including a cameo appearance by That Rabbit from <a href="http://thp.io/2010/trg/">That Rabbit Game</a> for no good reason. Play or <a href="http://talk.maemo.org/showthread.php?t=88700">discuss</a>. Or be productive. Or something. <br />
<br />
<b>SMS Backup GUI</b><br />
Instead of rolling my own solution from scratch, I found the wonderful <a href="https://github.com/wwwjfy/MeegoSMSBackupRestore">MeegoSMSBackupRestore</a> project by <a href="http://blog.wwwjfy.net/">Tony Wang</a>, which is a command-line tool for Harmattan devices to backup and restore SMS messages (as if that wasn't clear from the application name..). It was missing a GUI, so I've added one. The <a href="http://talk.maemo.org/showpost.php?p=1318414&postcount=115">announcement</a> and <a href="http://thp.io/2013/maemo/smsbackuprestore_0.3.1_armel.deb">download</a>, as well as the Debian source package (<a href="http://thp.io/2013/maemo/smsbackuprestore_0.3.1.dsc">.dsc</a>, <a href="http://thp.io/2013/maemo/smsbackuprestore_0.3.1.tar.gz">.tar.gz</a>) are available from an Internet near you. Feel like Git? We <a href="https://github.com/harmattan/MeegoSMSBackupRestore">have you covered</a> as well.<br />
<br />
<b>apkenv updates</b><br />
If you haven't been watching the <a href="https://github.com/thp/apkenv">apkenv Git repo</a> closely (I know you haven't), you might have missed the <a href="https://github.com/thp/apkenv/pull/5">Pandora port</a> by crowriot, which - while not being directly useful to Maemo/MeeGo users as such - also brought improvements to the Cut the Rope module, which <a href="http://youtu.be/XSh65fT-3Ds">somehow works now</a>. To be <a href="http://talk.maemo.org/showthread.php?t=87496">discussed at talk.maemo.org</a>, and patches (as always) welcome.<br />
<br />
In other (totally unrelated) news, the <a href="http://thp.io/2012/thesis/">thesis</a> is done (yay!).thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-19138629533780760052012-12-23T19:03:00.000+01:002012-12-23T19:03:42.632+01:00gPodder 3.4.0 for MeeGo 1.2 HarmattanAs promised, following the 2.20.3 <a href="http://thpmaemo.blogspot.com/2012/12/gpodder-2203-for-maemo-4-and-maemo-5.html">release for Maemo 4 and Maemo 5</a>, a new version of gPodder 3 <a href="http://blog.gpodder.org/2012/12/gpodder-340-quiet-earth-released.html">has been released today</a>. This release brings some new improvements to the QML UI that should make scrolling in the episode list faster, as well as align a bit more with the <a href="http://harmattan-dev.nokia.com/docs/ux/">Harmattan UX Guidelines</a>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://farm9.staticflickr.com/8211/8300073223_f10be13038_n.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://farm9.staticflickr.com/8211/8300073223_f10be13038_n.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">gPodder 3.4.0 running on MeeGo 1.2 Harmattan (N9)</td></tr>
</tbody></table>
As always, updated packages will be available via <a href="http://store.ovi.com/content/148264">Nokia Store</a> once the QA process has finished. As there have been problems with apps.formeego.org recently (3.3.0 isn't even out of the staging area yet, after 3 months), we now provide a package of gPodder for MeeGo 1.2 Harmattan on <a href="http://gpodder.org/downloads">gpodder.org/downloads</a> for those who want to avoid or can't use Nokia Store (you have to enable packages from unknown sources, and you might have to uninstall the previous version if it came from Nokia Store or Apps For MeeGo due to the Aegis security policy). The source and packaging is available in the "harmattan" branch in <a href="http://gpodder.org/wiki/Git">Git</a>, as has always been the case.<br />
<br />
I hope you like the new UI changes. If you are missing the feed update button in the lower left corner, try "pull to refresh" on the podcast list (this avoids accidental updates when pressing the back button twice). I'd like to create a nicer "pull to refresh" implementation, but the limitations of Qt 4's QML Flickable prevent me from creating a better one (if you have a better implementation than <a href="https://github.com/gpodder/gpodder/blob/master/share/gpodder/ui/qml/PullDownHandle.qml">gPodder's PullDownHandle</a>, I'd love to hear from you). Scrolling the episode list should now also be faster (than before), and some unnecessary animations were removed in the process.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-38292778270831309612012-12-23T00:35:00.000+01:002012-12-23T00:35:17.583+01:00gPodder 2.20.3 for Maemo 4 and Maemo 5A <a href="http://blog.gpodder.org/2012/12/gpodder-2203-odd-pod-released.html">new release</a> of gPodder 2.x for Maemo 4 (aka Diablo, N800 + N810) and Maemo 5 (aka Fremantle, N900) is out, fixing YouTube-related issues (again ;).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://farm9.staticflickr.com/8211/8298685370_5bc08049d4.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="179" src="http://farm9.staticflickr.com/8211/8298685370_5bc08049d4.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">gPodder 2.20.3 running on Maemo 4 (N810)</td></tr>
</tbody></table>
Packages have been <a href="http://maemo.org/packages/view/gpodder/">uploaded</a> to Maemo Extras, but as people have reported problems with the autobuilder, and as maemo.org seems to be moving these days, anyway (to the <a href="http://hildonfoundation.org/">Hildon Foundation</a>, apparently), we also provide for the first time since.. well, since a very long time I guess.. binary .deb packages for gPodder on Maemo 4 and Maemo 5 :)<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://farm9.staticflickr.com/8219/8297644685_6990a98d8d.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="http://farm9.staticflickr.com/8219/8297644685_6990a98d8d.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">gPodder 2.20.3 running on Maemo 5 (N900)</td></tr>
</tbody></table>
You can find the download links on the <a href="http://gpodder.org/downloads">gPodder download page</a> - you can directly download gPodder 2.20.3 from the web browser in both OS versions, and choose to open the .deb file with the Application Manager. Be sure to choose the right package for your device (N8x0 users choose the Maemo 4 version, N900 users choose the Maemo 5 version). Enjoy :) Next up: A new release of gPodder 3.x for Harmattan. Soon!thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-30447398321957608242012-12-13T14:06:00.000+01:002012-12-13T14:06:08.055+01:00Billboard 1.0.7 available in Nokia StoreA new version of <a href="http://thp.io/2012/billboard/">Billboard</a>, the standby screen customizing app for the N9 has been released and is now <a href="http://store.ovi.com/content/279408">available from Nokia Store</a>. It brings some nifty features such as in-line color customization, a battery bar and a battery icon:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm9.staticflickr.com/8059/8264688373_862a4e6376.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://farm9.staticflickr.com/8059/8264688373_862a4e6376.jpg" width="180" /></a></div>
<br />
The full ChangeLog is available on the <a href="http://thp.io/2012/billboard/">Billboard website</a>.<br />
Questions and feedback can be left in the <a href="http://talk.maemo.org/showthread.php?t=84507">support thread on TMO</a>.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-22196711311517886502012-11-20T18:41:00.000+01:002012-11-20T18:41:43.085+01:00apkenv 42.1.0 source code releaseThe <a href="http://thp.io/2012/apkenv/">compatibility layer for applications packed as .apk</a> (that are running natively and use OpenGL ES) has seen its <a href="http://github.com/thp/apkenv/">source code released</a> yesterday. Supports Maemo 5 (Fremantle) and MeeGo 1.2 (Harmattan), which means your N900, N950 and N9 are covered. Documentation is provided in the source, and the <a href="https://github.com/harmattan/apkenv-wrapper-generator">wrapper generator scripts</a> are also released. Looking forward to contributions and new modules from the community. Details can be found on the <a href="http://thp.io/2012/apkenv/">apkenv website</a>.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-59257438935421439922012-11-13T11:09:00.000+01:002012-11-13T11:09:14.000+01:00The quick way to USB tethering via SSH on your N9Here's something obvious (and I'm sure it has been discussed before, I just can't find the link right now), but it might be helpful if you haven't played around with SSH much yet, and your Wi-Fi Hotspot isn't working (the case for me right now). The goal is to get an internet connection over your N9/N950 from a PC (tested with Linux, expected to work with OS X and probably also works on Windows - on Windows you might need something like <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">PuTTY</a>).<br />
<ol>
<li>Enable developer mode on your device</li>
<li>Connect your device to your computer via USB</li>
<li>Select "SDK mode" when asked for the USB connection type </li>
<li>Use the SDK connection utility, and select USB connection</li>
<li>Note the password displayed in the "Connectivity Details" screen </li>
<li>On your computer, use "ssh -D 9898 developer@192.168.2.15"</li>
<li>Accept the host key question, and enter the password from step 5</li>
<li>You should be greeted by a Busybox prompt "/home/developer $" - leave that open in the terminal window in the background</li>
<li>At this point, a SOCKS proxy server is running on port 9898, and you can use it in any applications supporting a SOCKS proxy (there are even utilities like <a href="http://linux.die.net/man/1/socksify">socksify</a>(1) (Debian package: <a href="http://packages.debian.org/sid/dante-client">dante-client</a>) that make generic network applications work through a SOCKS proxy)</li>
<li>To use it in Firefox, go to Edit - Preferences - Advanced - Network - Settings..., then choose "Manual proxy configuration" and set "SOCKS Host:" to localhost and port to 9898 (be sure to disable the proxy again when you want to browse via a normal Wi-Fi/Ethernet connection)</li>
</ol>
Instead of doing steps 4 and 5, you can set up a permanent password for your "user" account on the N9, and even set up a SSH key on the N9 to avoid having to enter the password. You can make step 6 simpler by adding an entry to your ~/.ssh/config file (on your host) - see <a href="http://linux.die.net/man/5/ssh_config">ssh_config</a>(5) for details:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">Host n9proxy</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> HostName 192.168.2.15</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> User developer</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> DynamicForward 9898</span><br />
<br />
After that, a "ssh n9proxy" (possibly followed by the developer password) is all you need to set up the proxy. This method is arguably easier (and definitely safer) than using the Wi-Fi hotspot, and instead of using up battery on your N9, it gets charged via the USB port while you are using it.<br />
<br />
By the way: You will have to manually connect your N9 to your mobile internet connection, this won't happen automatically.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com2tag:blogger.com,1999:blog-6145140879520785870.post-24098143222788177602012-10-23T16:07:00.000+02:002012-10-23T16:07:33.576+02:00Dalvik "Hello World" on Harmattan (in a chroot)Here's a quick and boring tutorial on how to get a Java "Hello World" application running on the Dalvik VM of Nitdroid within Harmattan. This requires the Nitdroid Open Mode Kernel (might or might not work with Inception), all Nitdroid files and a bit of patience. This might brick your device or worse, and require a reflash at best. As you can see from the screenshot below, it's not that exciting ;) <br />
<ol>
<li>If you want to avoid the Open Mode Warning on each boot, <a href="http://talk.maemo.org/showpost.php?p=1281191&postcount=25">remove the disclaimer from the cal area</a> (this can only be done while in closed mode, as the cal area becomes read-only when flashing open mode until closed mode is re-flashed. This is also the reason why you can't set a device lock code in open mode - the lock code is saved in the cal area) - this is an optional step, and just a cosmetic fix.</li>
<li>Flash the <a href="http://forum.nitdroid.com/index.php?topic=90.0">Nitdroid Open Mode Kernel</a> (be sure to read the "Known limitations" on that post) - this works both on the N950 and N9.</li>
<li>Boot into Harmattan open mode and <a href="http://forum.nitdroid.com/index.php?topic=127.0">replace the preinit script</a> to allow booting into Nitdroid (again, read and understand the warnings on that post)</li>
<li>Then, <a href="http://forum.nitdroid.com/index.php?topic=493.0">download a Nitdroid tarball</a> (the latest is <a href="http://forum.nitdroid.com/index.php?topic=601.0">alpha 5</a>, but I had better luck with <a href="http://forum.nitdroid.com/index.php?topic=493.0">alpha 4</a>) and extract it to /home/nitdroid/ - the post explains the steps in great detail, including the kernel flashing and preinit replacement</li>
<li>Reboot into Nitdroid (this might be optional, but do it just to check if your Nitdroid installation is working)</li>
<li>Reboot into Harmattan again - the following commands are all carried out as root user inside Harmattan (using "<span style="font-family: "Courier New",Courier,monospace;">devel-su</span>")</li>
<li>Bind mount /dev/ and /sys/ into Nitdroid:<br /><span style="font-family: "Courier New",Courier,monospace;">mount --bind /dev/ /home/nitdroid/dev/<br />mount --bind /sys/ /home/nitdroid/sys/</span></li>
<li>chroot into the Nitdroid hierarchy:<br /><span style="font-family: "Courier New",Courier,monospace;">/usr/sbin/chroot /home/nitdroid/</span></li>
<li>Set some environment variables (not all of them might be needed, you can find them in "setup the global environment" of init.rc -- save these commands into "setupenv.sh" or something in /home/nitdroid/ and save yourself some typing):<br /><span style="font-family: "Courier New",Courier,monospace;">export PATH=/system/bin:/system/xbin:/usr/sbin:/usr/bin:/sbin:/bin<br />export LD_LIBRARY_PATH=/system/lib<br />export ANDROID_BOOTLOGO=1<br />export ANDROID_ROOT=/system<br />export ANDROID_ASSETS=/system/app<br />export ANDROID_DATA=/data<br />export EXTERNAL_STORAGE=/mnt/sdcard<br />export ASEC_MOUNTPOINT=/mnt/asec<br />export LOOP_MOUNTPOINT=/mnt/obb<br />export BOOTCLASSPATH=/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/sys</span></li>
<li>Start the Dalvik VM:<br /><span style="font-family: "Courier New",Courier,monospace;">/ # /system/bin/dalvikvm <br />Dalvik VM requires a class name</span></li>
</ol>
Ok, great - 10 steps to start the Dalvik VM, but I promised a Hello World. For that, you need the Android SDK (and the corresponding Java JDK) and follow the "<a href="http://www.milk.com/kodebase/dalvik-docs-mirror/docs/hello-world.html">Basic Dalvik VM Invocation</a>" instructions (steps 1 to 6 on your host computer, from step 6 on your Harmattan device):<br />
<ol>
<li>With your favorite editor (mine is vim), create a file "Foo.java" with the following content:<br /><span style="font-family: "Courier New",Courier,monospace;">public class Foo {<br /> public static void main(String [] args) {<br /> System.out.println("Hello, world");<br /> }<br />}</span></li>
<li>Compile it:<br /><span style="font-family: "Courier New",Courier,monospace;">javac Foo.java</span></li>
<li>Use the "dx" utility (from the Android SDK) to package the Foo.class (generated by javac) into a .jar<br /><span style="font-family: "Courier New",Courier,monospace;">dx --dex --output=foo.jar Foo.class</span></li>
<li>Bonus exercise: "less" the foo.jar file to see its contents:<br /><span style="font-family: "Courier New",Courier,monospace;">% less foo.jar<br /><span style="font-size: xx-small;">Archive: foo.jar<br /> Length Method Size Cmpr Date Time CRC-32 Name<br />-------- ------ ------- ---- ---------- ----- -------- ----<br /> 72 Defl:N 70 3% 2012-10-23 15:51 1294a38f META-INF/MANIFEST.MF<br /> 732 Defl:N 404 45% 2012-10-23 15:51 b6e3654e classes.dex<br />-------- ------- --- -------<br /> 804 474 41% 2 files</span></span></li>
<li>Copy this over to your Harmattan device (assuming USB Networking + Developer Mode + "user" access, "developer" should also work):<br /><span style="font-family: "Courier New",Courier,monospace;">scp foo.jar user@192.168.2.15:</span></li>
<li>SSH into your Harmattan device, become root (devel-su) and copy the .jar file into the Nitdroid hierarchy:<br /><span style="font-family: "Courier New",Courier,monospace;">cp /home/user/foo.jar /home/nitdroid/</span></li>
<li>chroot into Nitdroid again and set up the environment (see above)</li>
<li>Finally, run Dalvik VM, telling it to run the class "Foo" and using a classpath of "foo.jar":<br /><span style="font-family: "Courier New",Courier,monospace;">/ # /system/bin/dalvikvm -cp foo.jar Foo</span></li>
<li>...</li>
<li><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhykTS-2DCzbdvlwnncx2buaeYRtiSkjGM7a2RLWCDIbNr8CJ1yurafrLU_Zo-fzGJpH-vlFy2UPLuJ5PxZ0wqvuuZGtl5bAxOqFJ8ugTu9kcgie4OMSyMA-6QX2XGAZwSwmKH-u7IFW5U/s1600/2012-10-23_16-06-29.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhykTS-2DCzbdvlwnncx2buaeYRtiSkjGM7a2RLWCDIbNr8CJ1yurafrLU_Zo-fzGJpH-vlFy2UPLuJ5PxZ0wqvuuZGtl5bAxOqFJ8ugTu9kcgie4OMSyMA-6QX2XGAZwSwmKH-u7IFW5U/s320/2012-10-23_16-06-29.png" width="320" /></a></li>
</ol>
thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com3tag:blogger.com,1999:blog-6145140879520785870.post-8327180039260670642012-09-24T15:14:00.000+02:002012-09-24T15:14:09.589+02:00gPodder 2.20.2 for Maemo 4/5, gPodder 3.3.0 for MeeGo 1.2 Harmattan<a href="http://blog.gpodder.org/2012/09/gpodder-2202-uniblab-released.html">gPodder 2.20.2</a> has been released today, and <a href="http://blog.gpodder.org/2012/09/gpodder-330-intermission-released.html">gPodder 3.3.0</a> has also been released. Version 2.20.2 is for users of Maemo 4 (N800/N810) and Maemo 5 (N900) and version 3.3.0 is for MeeGo 1.2 Harmattan users (N950/N9).<br />
<br />
The reason why another 2.x release comes out at this point in time is because YouTube downloading was broken by another website change recently, and of course we don't want to leave our good old Maemo users without their daily YouTube video fix. A full list of changes for Maemo 4 and 5 can be found in the <a href="http://blog.gpodder.org/2012/09/gpodder-2202-uniblab-released.html">2.20.2 release announcement</a>.<br />
<br />
Version 3.3.0 for MeeGo 1.2 Harmattan brings some nice features like download resuming, filters for unfinished files, scroll position improvements and display of the publish date and file size in the shownotes. Of course, 3.3.0 also includes the YouTube download fix. A full list of changes can be found in the <a href="http://blog.gpodder.org/2012/09/gpodder-330-intermission-released.html">3.3.0 release annoucement</a>.<br />
<br />
As a side note, Maemo 5 support has now been completely removed from the master branch as of 3.3.0 (it has never been officially supported, but you could kind of run in on the N900 with some motivation and work). N900 users really wanting to use gPodder 3 should use it on <a href="https://wiki.merproject.org/wiki/Nemo/Installing#Nokia_N900">Nemo Mobile</a>, supporting gPodder 3 and its QML UI in Maemo 5 is just too much work, and the time working on gPodder is better spent improving the Harmattan version and making sure that the 2.x branch doesn't break.<br />
<br />
Here's the run-down of the release status for various versions and targets:<br />
<br />
gPodder 2.20.2 is <a href="http://maemo.org/packages/package_instance/view/fremantle_extras-testing_free_armel/gpodder/2.20.2-1/">ready for testing</a> in Extras-Testing for Maemo 5 Fremantle.<br />gPodder 2.20.2 is already in Extras for Maemo 4 Diablo.<br />gPodder 3.3.0 has been uploaded to Nokia Store QA for MeeGo 1.2 Harmattan.<br />gPodder 3.3.0 has also been uploaded to the MeeGo Community OBS.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-55035516461823382202012-09-24T12:38:00.001+02:002012-09-24T12:39:33.811+02:00HOWTO: Set up a Maemo 5 Scratchbox SDK VM (and upload packages)I've somehow lost my good old "MaemoSDK" VirtualBox VM, so while I'm setting up the new VM, here are the instructions in case I or somebody else needs to do that again.<br />
<br />
The goal: To have a nice VM (more lightweight than the <a href="http://maemovmware.garage.maemo.org/2nd_edition/">Maemo SDK VMs</a> offered online) that one can SSH into and build packages for Maemo 4 and Maemo 5:<br />
<ol>
<li>Get the Debian <a href="http://cdimage.debian.org/debian-cd/6.0.5/i386/iso-cd/debian-6.0.5-i386-netinst.iso">i386 netinst CD image</a> from <a href="http://www.debian.org/CD/netinst/">http://www.debian.org/CD/netinst/</a></li>
<li>Create a new VirtualBox VM (Name: MaemoSDK, Operating System: Linux, Version: Debian) - the default size (8 GB) should be okay, less is also okay</li>
<li>Go to Settings, Storage, IDE Controller, select the .iso you downloaded in step 1</li>
<li>Power up the VM, select "Install" in the menu</li>
<li>Set the hostname to "maemosdk"</li>
<li>Use an empty root password (you can use "sudo" from your user)</li>
<li>Full name for the new user: Maemo Developer</li>
<li>Username for the new user: user</li>
<li>Password for the new user: maemo</li>
<li>Use the default options for partitioning, and wait until the base system is installed</li>
<li>Select the "SSH Server" option when the Debian Installer offers it</li>
<li>Install GRUB into the MBR of the VM </li>
<li>Go to the <a href="http://www.developer.nokia.com/info/sw.nokia.com/id/c05693a1-265c-4c7f-a389-fc227db4c465/Maemo_5_SDK.html">Maemo 5 SDK Download Page</a> on Nokia Developer</li>
<li>From the SDK Download page, get the Scratchbox installer script (maemo-scratchbox-install_5.0.sh) and the SDK installer script (maemo-sdk-install_5.0.sh):<pre id="line1">http://repository.maemo.org/stable/5.0/maemo-scratchbox-install_5.0.sh</pre>
<pre id="line1">http://repository.maemo.org/stable/5.0/maemo-sdk-install_5.0.sh </pre>
</li>
<li>Login to your new VM, then wget the two scripts above</li>
<li>sudo sh maemo-scratchbox-install_5.0.sh</li>
<li>sudo sh maemo-scratchbox-install_5.0.sh -u user</li>
<li>Log out and log back in again </li>
<li>sh maemo-sdk-install_5.0.sh</li>
<li>When asked, I chose Full + Development packages, but feel free to chose a more minimal variant (in that case, you might have to install -dev packages later on as build-dependencies)</li>
</ol>
You can also read up on how to <a href="http://thpmaemo.blogspot.co.at/2010/10/ssh-agent-forwarding-in-scratchbox.html">set up SSH agent forwarding</a> in the VM, so that you don't need to store your SSH key on the SDK VM.<br />
<br />
As for building gPodder from source in this SDK, here are the instructions:<br />
<ol>
<li>scratchbox</li>
<li>vi /etc/apt/sources.list # then add these entries:<br /> deb http://repository.maemo.org/extras-devel fremantle free non-free<br />deb-src http://repository.maemo.org/extras-devel fremantle free</li>
<li>fakeroot apt-get install python2.5 python-feedparser python-mygpoclient python-dev maemo-optify</li>
<li>git clone git://github.com/gpodder/gpodder.git</li>
<li>cd gpodder</li>
<li>git checkout origin/maemo-5</li>
<li>dpkg-buildpackage -rfakeroot -S -sa -I.git -i.git # for the source upload</li>
<li>dpkg-buildpackage -rfakeroot -b # for the binary to test locally</li>
</ol>
You can also build the Maemo 4 (N800/N810) package by replacing "maemo-5" with "maemo-4" in the "git checkout" command. <br />
<br />
To get files out of the SDK without setting up fancy SSH stuff, you can also just use netcat (on the target: nc -l 9999 | tar xzv, on the source: tar czv /path/to/files/ | nc a.b.c.d 9999).<br />
<br />
To upload files to Maemo Extras, follow the instructions at <a href="http://wiki.maemo.org/Uploading_to_Extras">Uploading to Extras</a>.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0tag:blogger.com,1999:blog-6145140879520785870.post-18188109630100299072012-09-02T10:59:00.000+02:002012-09-02T10:59:38.770+02:00Numpty Physics 0.3.3 for Harmattan is hereAnother project that has been on the back burner for a while is the <a href="http://talk.maemo.org/showthread.php?t=85050">new NumptyPhysics port</a> to Harmattan ("new" because Aapo has <a href="http://forum.meego.com/showthread.php?t=4224">ported it once before</a>). One of the most important bug fixes (avoiding the multi-touch drawing error) has been committed a month ago, and<br />
<br />
So, this weekend, Numpty Physics 0.3.3 <a href="http://talk.maemo.org/showpost.php?p=1258775&postcount=19">has been released</a>. This version includes some basic Harmattan integration work (single-instance, swipe lock integration, pause-in-background, squircle-style icon by
<span id="postmenu_1249610"><a href="http://talk.maemo.org/member.php?u=61100">flopjoke</a></span>, ...) that will - hopefully - allow the application to also go into Nokia Store as free app (as Apps For MeeGo is still down).<br />
<br />
NumptyPhysics is available as <a href="https://github.com/downloads/harmattan/numptyphysics/numptyphysics_0.3.3_armel.deb">download on Github</a>, or you can wait until it gets approved by Nokia Store QA and install it via the client. It's yet another project that used the <a href="http://talk.maemo.org/showthread.php?t=84333">shared "harmattan" organization</a> on Github: <a href="https://github.com/harmattan/numptyphysics">https://github.com/harmattan/numptyphysics</a> - feel free to improve the code and send pull requests :) Also, please report any integration issues or minor things that could be improved for Harmattan integration on the bug tracker.thphttp://www.blogger.com/profile/04893729285856691511noreply@blogger.com0