<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-12099183</id><updated>2011-11-28T08:26:57.733+08:00</updated><category term='linux'/><category term='audio'/><category term='jack'/><category term='dojo'/><category term='webpark'/><category term='xbmc'/><title type='text'>Living and Programming - YJPark's Blog</title><subtitle type='html'>A programmer, Interested in iOS dev, Linux, Python, Java, Mobile, Gadgets, Music, Playing Guitar, Photography...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-12099183.post-6947018088514937675</id><published>2010-04-27T18:38:00.001+08:00</published><updated>2010-04-27T18:44:54.581+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Using Trackball on Linux</title><content type='html'>I am having 3 monitors in my working setup, it help my productivity a lot and make me feels right, though moving long distance with mouse is quite painful, so I get a trackball for it (&lt;a href="http://us.kensington.com/html/16632.html"&gt;http://us.kensington.com/html/16632.html&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;It works great, it has drivers for windows and OS X, the navigation mode is quite good (in this mode, you can roll the trackball to scroll in the page), though it only support very few applications.&lt;br /&gt;&lt;br /&gt;On my Ubuntu system, after some tweak, it actually works better, here is what I did:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;xinput set-int-prop "Kensington Kensington Slimblade Trackball" "Evdev Wheel Emulation" 8 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;xinput set-int-prop "Kensington Kensington Slimblade Trackball" "Evdev Wheel Emulation Button" 8 8&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;xinput set-int-prop "Kensington Kensington Slimblade Trackball" "Evdev Wheel Emulation Axes" 8 6, 7, 4, 5&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;xinput set-button-map "Kensington Kensington Slimblade Trackball" 1 2 3 4 5 6 7 10 9 8 11 12&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;xinput set-int-prop "Kensington Kensington Slimblade Trackball" "Evdev Wheel Emulation Button Toggle" 8 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In current Ubuntu (mine is 9.10), there is no need to change setup in xorg.conf, the system just detected all the buttons of the trackball, the above lines are just for the navigation mode to work.&lt;br /&gt;&lt;br /&gt;You need to run these commands after start X server (there is a way to save the settings permanently, though I didn't try it). You can use "xinput list" to find the name of your device.&lt;br /&gt;&lt;br /&gt;The first line is telling the xinput system to enable the mouse wheel emulation (similar to the navigation mode)&lt;br /&gt;The second line is to use the upper-right button to trigger the navigation mode.&lt;br /&gt;the third line make it work for both vertical and horizontal scroll.&lt;br /&gt;The forth line remap the buttons a little bit, since firefox will use button 8 as back button, that's not what I want.&lt;br /&gt;The fifth line is a bit tricky, in the default implementation of current mouse wheel emulation, you need to hold the button for triggering the emulation (I think it's from the thinkpad's way of using the trackpoint), though for the trackball, it feels awkward if need to keep the navigation button pressed all the time, so I made a patch on it, then it works like under the OS X(one click to switch to navigation mode, another click back to normal mode, also clicking any other button in navigation mode will switch back to normal mode too).&lt;br /&gt;&lt;br /&gt;If you want to try the extra feature, you have to build it manually, the package name is xserver-xorg-input-evdev in ubuntu, or from git://anongit.freedesktop.org/git/xorg/driver/xf86-input-evdev&lt;br /&gt;&lt;br /&gt;patch for ubuntu's version (1:2.2.5-1ubuntu6): &lt;a href="https://sites.google.com/site/yjpark/downloads"&gt;https://sites.google.com/site/yjpark/downloads&lt;/a&gt; (ubuntu-9.10-toggle_button.diff)&lt;br /&gt;&lt;br /&gt;patch for latest version: &lt;a href="https://sites.google.com/site/yjpark/downloads"&gt;https://sites.google.com/site/yjpark/downloads&lt;/a&gt; (xf86-input-evdev-toggle_button.diff)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12099183-6947018088514937675?l=yjpark.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/6947018088514937675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12099183&amp;postID=6947018088514937675' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/6947018088514937675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/6947018088514937675'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/2010/04/using-trackball-on-linux.html' title='Using Trackball on Linux'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12099183.post-106642446371050177</id><published>2009-11-28T20:22:00.001+08:00</published><updated>2009-11-28T20:27:52.991+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='jack'/><category scheme='http://www.blogger.com/atom/ns#' term='xbmc'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><title type='text'>XBMC over Jack (Revisited)</title><content type='html'>I updated my ubuntu to karmic (9.10) lately, which works great, though my hacked version of XBMC cannot compile, after some hacks, it compiles fine, though gave me segment fault when starting. So I decided to take some time to install the current version of XBMC and apply my jack patch on it.&lt;br /&gt;&lt;br /&gt;This time I decide to use the version in PPA's karmic release instead the svn version (the previous one on svn was not very stable, crash now and then), first add xbmc and nvidia-vdpau repositories (xbmc depends on nvidia-190-libvdpau-dev, though I am still using 185 since the 190 version crash with tv-out, might goes to another post)&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;sudo add-apt-repository ppa:team-xbmc/ppa&lt;br /&gt;sudo add-apt-repository ppa:nvidia-vdpau/ppa&lt;/blockquote&gt;&lt;br /&gt;You still need to add the source part into apt source list, (add-apt-repository can get the key for you, which is convenient, wish it can support an option to add the source part too). Add this line to &lt;span style="font-family:courier new;"&gt;/etc/apt/sources.list.d/team-xbmc-ppa-karmic.list&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: courier new;"&gt;deb-src http://ppa.launchpad.net/team-xbmc/ppa/ubuntu karmic main&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Then install the needed libraries for building xbmc, and download the source codes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family: courier new;"&gt;sudo apt-get build-dep xbmc&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;apt-get source xbmc&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;sudo apt-get install libbio2jack0-dev libjack-dev libjack0.100.0-dev libjackasyn-dev&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;You should have the source codes ready after a while. As a comments in my previews post said, the audio interface was changed a little bit in the new xbmc source, though fortunately it's not a big change, so the previous patch can works just fine after some minor changes. get the patch from this address.&lt;br /&gt;*&lt;a href="https://sites.google.com/site/yjpark/downloads"&gt; https://sites.google.com/site/yjpark/downloads&lt;/a&gt;  (xbmc-9.11~beta1-jack.patch)&lt;br /&gt;&lt;br /&gt;patch -p0 &lt; xbmc-9.11~beta1-jack.patch&lt;br /&gt;&lt;br /&gt;Then do the normal configure, before make, please add "-ljack" into Makefile, (search the line LIBS=..., add it to the end of the line will be fine), after that make should work.&lt;br /&gt;&lt;br /&gt;One important thing to note, to make the audio matching video, you probably should change the delay constant in xbmc/cores/AudioRenderers/JackDirectSound.cpp.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family: courier new;"&gt;float CJackDirectSound::GetDelay()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  Update();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  return m_timePerPacket * (float)m_packetsSent + 0.4;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Just play an correct video file, adjust audio delay to make it sync, then add the value you used into the end of the return line will be ok (ahead means plus)&lt;br /&gt;&lt;br /&gt;Note: C++ library for Jack is from Jack_CPP (&lt;a href="http://x37v.info/jack_cpp/doc/index.html"&gt;http://x37v.info/jack_cpp/doc/index.html&lt;/a&gt;) (by Alex Norman, with pretty good documetation and examples, thanks again), I included the needed files in the patch, though suggest you to look at the documents on his site for more information.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's next&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Currently this is not working if enabling real time support in jackd, probably will do some research on this part.&lt;br /&gt;&lt;br /&gt;Also plan to find a way to deal with the ugly delay part, ideally can calculate the delay, if too hard, probably will retrieve the value from config, then won't need rebuild for it.&lt;br /&gt;&lt;br /&gt;And make the library detecting with the proper way, both in code and also in configure process (not a c/cpp programmer, so might need some time), then no manual change needed.&lt;br /&gt;&lt;br /&gt;If I can finish all these, then will try to commit the patch to xbmc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12099183-106642446371050177?l=yjpark.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/106642446371050177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12099183&amp;postID=106642446371050177' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/106642446371050177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/106642446371050177'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/2009/11/xbmc-over-jack-revisited.html' title='XBMC over Jack (Revisited)'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12099183.post-1722810016771158511</id><published>2009-11-18T14:48:00.003+08:00</published><updated>2009-11-25T18:09:54.106+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Install SVN 1.6.5 in Debain Etch</title><content type='html'>We still need to use Debian Etch for our project, I am running it through chroot on ubuntu, and also vmware on osx. it's default svn is 1.4, which cannot access the shared svn source folder (1.6.5 on both ubuntu 9.10 and osx 10.6.2), so here is the steps to install svn 1.6.5 on etch (sqlite in etch is too old to be used to compile svn 1.6.5, also I am not running svn repository in the chroot, so just ignore the warning of Berkeley DB)&lt;br /&gt;&lt;blockquote&gt;wget  http://www.sqlite.org/sqlite-amalgamation-3.6.13.tar.gz&lt;br /&gt;tar xzf sqlite-amalgamation-3.6.13.tar.gz&lt;br /&gt;wget http://subversion.tigris.org/downloads/subversion-1.6.5.tar.bz2&lt;br /&gt;tar xjf subversion-1.6.5.tar.bz2&lt;br /&gt;sudo apt-get install build-essential&lt;br /&gt;sudo apt-get install libapr1-dev&lt;br /&gt;sudo apt-get install libaprutil1-dev&lt;br /&gt;sudo apt-get install libneon26-dev&lt;br /&gt;cd subversion-1.6.5&lt;br /&gt;mkdir sqlite-amalgamation&lt;br /&gt;cp ../sqlite-3.6.13/sqlite3.c sqlite-amalgamation/&lt;br /&gt;./configure&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;/blockquote&gt;You may also want to upgrade pysvn to pysvn-1.7.1&lt;br /&gt;&lt;blockquote&gt;wget http://pysvn.barrys-emacs.org/source_kits/pysvn-1.7.1.tar.gz&lt;br /&gt;tar xzf pysvn-1.7.1.tar.gz&lt;br /&gt;cd pysvn-1.7.1/Source/&lt;br /&gt;python setup.py backport&lt;br /&gt;python setup.py configure&lt;br /&gt;make&lt;br /&gt;sudo cp pysvn/* /usr/lib/python2.4/site-packages/pysvn/&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12099183-1722810016771158511?l=yjpark.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/1722810016771158511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12099183&amp;postID=1722810016771158511' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/1722810016771158511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/1722810016771158511'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/2009/11/install-svn-165-in-debain-etch.html' title='Install SVN 1.6.5 in Debain Etch'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12099183.post-9028160875010008216</id><published>2009-07-31T19:01:00.006+08:00</published><updated>2009-12-01T19:37:24.091+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='jack'/><category scheme='http://www.blogger.com/atom/ns#' term='xbmc'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><title type='text'>XBMC over JACK</title><content type='html'>I have a XBox, which I use it watching video mostly, by installing XBMC (http://xbmc.org), it's the best media player IMO, though the very aged CPU cannot take H.264 or X.264 decode, it can only support MPEG2 HD, so after a while, I found out that it's not as useful as before.&lt;br /&gt;&lt;br /&gt;While now the XBMC is available on most platform: Windows, OS/X (Plex is better IMO, which is based on XBMC, http://www.plexapp.com/), and Linux.&lt;br /&gt;&lt;br /&gt;XBMC works fine on ubuntu through ALSA, though I am using JACK (http://jackaudio.org/) for better sound quality, so I have to stop JACK before start XBMC which is quite annoying.&lt;br /&gt;&lt;br /&gt;After some research on the web, I decide to implement JACK audio bridge for XBMC, which is quite easy, here is how I did it:&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;First, get the source code&lt;/h3&gt; * http://xbmc.org/development/svn/&lt;br /&gt;&lt;br /&gt;XBMC already has a flexible structure to support different audio interfaces, under linuxport/XBMC/xbmc/cores/AudioRenderers, there are a bunch of supported interfaces: ALSA, PulseAudio, Windows Direct sound.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Seconds, get the library&lt;/h3&gt;JACK comes with C library, it's asynchronus and need some time to learn it, did some research, found out there is a good C++ library at http://x37v.info/jack_cpp/doc/index.html (by Alex Norman, with pretty good documetation and examples, thanks a lot)&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Now, link them together&lt;/h3&gt;To make it simple, I just put all the files from jackcpp under AudioRenderers, then write a simple wrapper to let them talk with each other.&lt;br /&gt;&lt;br /&gt;There is a NullDirectSound.cpp there, which is a very good example to learn how to write a new interface.&lt;br /&gt;&lt;br /&gt;In AudioRendererFactory.cpp, a quick hacky way to use the JACK interface:&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="wiki"&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;--- AudioRendererFactory.cpp    (revision 19572)&lt;br /&gt;+++ AudioRendererFactory.cpp    (working copy)&lt;br /&gt;@@ -22,6 +22,7 @@&lt;br /&gt;#include "stdafx.h"&lt;br /&gt;#include "AudioRendererFactory.h"&lt;br /&gt;#include "NullDirectSound.h"&lt;br /&gt;+#include "JackDirectSound.h"&lt;br /&gt;&lt;br /&gt;#ifdef HAS_PULSEAUDIO&lt;br /&gt;#include "PulseAudioDirectSound.h"&lt;br /&gt;@@ -59,10 +60,14 @@&lt;br /&gt;{&lt;br /&gt; IAudioRenderer* audioSink = NULL;&lt;br /&gt;&lt;br /&gt;+//For Jack&lt;br /&gt;+  audioSink = new CJackDirectSound();&lt;br /&gt;+  ReturnOnValidInitialize();&lt;br /&gt;+&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Then create JackDirectSound.cpp and JackDirectSound.h (I just copied from NullDirectSound.cpp and NullDirectSound.h)&lt;br /&gt;&lt;br /&gt;if you see the diff from JackDirectSound.cpp and NullDirectSound.cpp, you will find out most of them are same except for the change of name, the only logic I added are these lines (full version below):&lt;br /&gt;&lt;br /&gt;In Initialize():&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre class="wiki"&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt; jackBuffer = new JackCpp::BlockingAudioIO("XBMC.Jack", iChannels, iChannels);&lt;br /&gt; jackBuffer-&gt;start();&lt;br /&gt; for(int i = 0; i &lt;&gt;connectToPhysical(i,i);&lt;br /&gt; }&lt;br /&gt;   m_uiChannels = iChannels;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;I am using blocking interface here, since it's very simple to use.&lt;br /&gt;&lt;br /&gt;In Deinitialize():&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre class="wiki"&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt; if (jackBuffer) {&lt;br /&gt;   for(int i = 0; i &lt;&gt;disconnectOutPort(i);&lt;br /&gt;   }&lt;br /&gt;   jackBuffer-&gt;close();&lt;br /&gt;   //TODO: Cannot delete jackBuffer, otherwise will crash.&lt;br /&gt;   //delete jackBuffer;&lt;br /&gt; }&lt;br /&gt; jackBuffer = 0;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;And in AddPackets():&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre class="wiki"&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt; CLog::Log(LOGERROR,"Jack.AddPackets() len=%d, add=%d", len, add);&lt;br /&gt;&lt;br /&gt; if (jackBuffer){&lt;br /&gt;   short* pSamples = (short*)data;&lt;br /&gt;   for (int i=0; i&lt; j =" 0;"&gt;write(j, (float) pSamples[i*m_uiChannels + j] / 32768.0);&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The logic to convert the data chunks here cause me some trouble, had to do some search and experiments before get the sound right, but before that some result sound were quite interesting.&lt;br /&gt;&lt;br /&gt;The last thing in GetDelay():&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre class="wiki"&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;return m_timePerPacket * (float)m_packetsSent + 0.325 + 0.075;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;To be honest, I don't know how to calculate the correct delay value here, this value here was the delay I found out on my machine, just try to play some movie, then try to match the audio to the video, then it's done. (I know, it's very hacky and not the right way, but since the constant value seems to solve my problem perfectly, don't feel pressure to dig into it anymore :) )&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Put everything together and make it&lt;/h3&gt;Now every thing is ready, you can set it up and make it.&lt;br /&gt;&lt;br /&gt;I suppose you have enough knowledge about how to compile XBMC on your system, this page http://xbmc.org/wiki/?title=Installing_XBMC_for_Linux has all the information you need.&lt;br /&gt;&lt;br /&gt;Modify linuxport/XBMC/xbmc/cores/AudioRenderers/Makefile.in to include the new files (both jack_cpp and my codes)&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre class="wiki"&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;--- Makefile.in    (revision 19572)&lt;br /&gt;+++ Makefile.in    (working copy)&lt;br /&gt;@@ -4,11 +4,17 @@&lt;br /&gt;&lt;br /&gt;ifeq ($(findstring osx,$(ARCH)), osx)&lt;br /&gt;SRCS = \&lt;br /&gt;+    jackaudioio.cpp \&lt;br /&gt;+    jackblockingaudioio.cpp \&lt;br /&gt;+    JackDirectSound.cpp \&lt;br /&gt;   NullDirectSound.cpp \&lt;br /&gt;   AudioRendererFactory.cpp \&lt;br /&gt;   PortaudioDirectSound.cpp&lt;br /&gt;else&lt;br /&gt;SRCS = \&lt;br /&gt;+    jackaudioio.cpp \&lt;br /&gt;+    jackblockingaudioio.cpp \&lt;br /&gt;+    JackDirectSound.cpp \&lt;br /&gt;   NullDirectSound.cpp \&lt;br /&gt;   AudioRendererFactory.cpp \&lt;br /&gt;   ALSADirectSound.cpp \&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;And also add jack lib into XBMC/Makefile, search for "-lasound" add "-ljack" the the same line. (Again, this is my hacky and improper way)&lt;br /&gt;&lt;br /&gt;Now you are ready to compile it and enjoy the two fantastic software working together!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Download the Patch:&lt;/h3&gt;&lt;br /&gt;&lt;a href="https://sites.google.com/site/yjpark/downloads"&gt;xbmc-jack.tgz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12099183-9028160875010008216?l=yjpark.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/9028160875010008216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12099183&amp;postID=9028160875010008216' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/9028160875010008216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/9028160875010008216'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/2009/07/xbmc-over-jack.html' title='XBMC over JACK'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12099183.post-7459547323951481635</id><published>2008-02-19T16:32:00.005+08:00</published><updated>2008-02-19T17:30:23.762+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><title type='text'>Better Audio Under Linux with TerraTec DMX6Fire (ICE1712 based)</title><content type='html'>&lt;h3&gt;Some background&lt;/h3&gt;&lt;div&gt;I've been using Linux as main OS for more than two years, here is my experience of the audio on linux so far.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;At the early stage of my linux usage, I spent some time to figure out how to use sound on linux, setup alsa, and use optical output (s/pdif) for better quality(the poor built-in sound card in the Desktop can produce pretty clean sound with this, but you need some device can accept optical in, I used an old minidisc player for that).&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;After switch to a Thinkpad t60 as my main development machine, I don't have optical output anymore, then I noticed that the sound quality was pretty poor with the default sound output, I didn't dig into that, just use my cell phone for music listening in work.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;I have a windows PC at home for a long time, the biggest reason is I have a good sound card on it (TerraTec DMX6Fire, cost me quite some money years before), and I have some musical software on windows. After not doing anything with the software for a few years, and feeling more and more comfortable with Linux, I decide to reinstall it with Ubuntu too, then leads to this article.&lt;/div&gt;&lt;h3&gt;The sound quality is ... POOL&lt;/h3&gt;&lt;div&gt;Ubuntu install pretty smooth on this machine, find all the hardware including the sound card, reboot correctly, and sound works, with a pretty bad poor quality, and the digital output(Both optical and coaxial) on the card stop working anymore, the sound quality from the analog out is terrible, very not clear, it's impossible to enjoy any music on this pretty cool sound card with the default configuration at all!&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;Since this is Linux and the hardware is already been recognized, I think it's just something related to the configuration, so I started to google around and try to fix this, cost me about two days so far, here is what I've learned from this.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:'Lucida Grande';font-size:12;"  &gt;* http://alsa.opensrc.org/index.php/Ice1712&lt;/span&gt;&lt;/div&gt;&lt;h3&gt;How to make it better&lt;/h3&gt;&lt;div&gt;The biggest reason to cause the messy sound is the configuration of the card, since it's a sort of professional class card, it's not as simple as most consumer card, need some setup to make it working in the right way, there is a graphics tool for ICE1712 based cards. it's name is &lt;b&gt;envy24control&lt;/b&gt; in package &lt;b&gt;alsa-tools-gui &lt;/b&gt;, for my card, I am using &lt;b&gt;"envy24control -p 8 -w 15" &lt;/b&gt;to start it, &lt;b&gt;"-p 8"&lt;/b&gt; means use 8 pcm outputs, &lt;b&gt;"-w 15"&lt;/b&gt; to make the window wider enough to show everything without a scrollbar.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;The most important here is to make the pcm channels as stereo, the cards has 10 mono channels, by default players will play sound to the first two channels as a stereo one, but if you didn't adjust the digital mixer correctly, you will hear mix-down mono sound which is pretty bad. so you should mute the right part of pcm output 1 and mute the left part of pcm output 2.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;If you have experience of using a hardware mixer, then this is much easier to understand, by allowing left/right control over each channel, you can adjust the pan value(left/right position) for it, but for stereo channels, you must set the mixer as stereo by pairing two mono channels.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;Then I can have rather clean stereo again, but the sound quality is still not very nice, it's much worse than using foobar2000 on windows with ASIO output with the same card. and the digital output is not working correctly yet. so I still have a lots works to do.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;h3&gt;How to get digital and make the sound quality even better&lt;/h3&gt;&lt;p&gt;Using envy24control to direct digital output from s/pdif out (on Patchbay/Router tab), can use iec958 as alsa output, but you need to make sure the internal clock is same with the sound you're playing, otherwise it will be too fast or too slow. you can use envy24control's Hardware Settings to change it.&lt;/p&gt;&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;Be careful about the combinations with Professional/Consumer and different clock rate, I found out that Professional+44100 and Consumer+48000 works best, other combinations will cause problems. (Noise on coaxial, or wrong clock display on my amplifier). My amplifier doesn't support higher clock rate, so I don't know how that works.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;There is a good post about ALSA's sample rate converter in dmix, and how to improve it, I followed it, feels that the sound is a bit better, but not very sure about the actual effect&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt; * http://www.hydrogenaudio.org/forums/index.php?showtopic=47591&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Then I decide to give JACK a try, according to it's website at http://jackaudio.org/&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; line-height: 17px;font-size:14;" &gt;&lt;blockquote&gt;JACK is a low-latency audio server, written for POSIX conformant operating systems such as GNU/Linux and Apple's OS X. It can connect a number of different applications to an audio device, as well as allowing them to share audio between themselves. Its clients can run in their own processes (ie. as normal applications), or can they can run within the JACK server (ie. as a "plugin").&lt;/blockquote&gt;&lt;blockquote&gt;JACK was designed from the ground up for professional audio work, and its design focuses on two key areas: synchronous execution of all clients, and low latency operation. &lt;/blockquote&gt;Sounds pretty good to me, and I found some guy saying that it's sound quality is pretty good on the web, after several hours of using it, I will say, it's a very cool and very good stuff, I will stick using it for a quite long time I think. The sound quality over JACK is noticeable better, make me very satisfied, and seems with JACK, can do low latency audio/midi/synth stuffs under Linux too (you can install some good musical software with package &lt;b&gt;ubuntustudio-audio&lt;/b&gt; and &lt;b&gt;ubuntustudio-audio-plugins&lt;/b&gt;), I haven't tried them yet, but some of them seems pretty nice. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-size:130%;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; line-height: 17px;font-size:14;" &gt;I will leave the JACK related stuffs in another post, includes some experiments about JACK, how to use ALSA over JACK.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12099183-7459547323951481635?l=yjpark.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/7459547323951481635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12099183&amp;postID=7459547323951481635' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/7459547323951481635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/7459547323951481635'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/2008/02/better-audio-under-linux-with-terratec.html' title='Better Audio Under Linux with TerraTec DMX6Fire (ICE1712 based)'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12099183.post-709685799588440299</id><published>2007-07-05T11:45:00.001+08:00</published><updated>2009-09-23T18:17:18.295+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webpark'/><title type='text'>Web park prototype release (See more than 1 pages in one tab)</title><content type='html'>Current I am using a relative big screen(22' widescreen LCD) which is at 1680X1050. It's pretty good, but it's hard to utilize it when surfing web, most web pages will only take a small part of the whole screen, for example a maximized firefox browsing google will look like this:&lt;br /&gt;&lt;div style="padding: 1em 0pt; text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dhmqwbpr_1439m78nd8" height="315" width="504" /&gt;&lt;/div&gt;I really don't like the blank area, so I develop a prototype for using the big screen more efficiently, currently it looks like this:&lt;br /&gt;&lt;div style="padding: 1em 0pt; text-align: left;"&gt;&lt;div style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dhmqwbpr_15f9hb6bc2" height="315" width="504" /&gt;&lt;/div&gt;&lt;br /&gt;As you can see, two different pages are shown together(it's configurable, if you have a really big screen, you can show more than 2 pages). and click on google's search result will load the page on it's right, so to me, means a lot of tab operations become needless.&lt;br /&gt;&lt;br /&gt;This project is currently in a very early stage, only have some basic functions, if you want to try it out, just visit &lt;a href="http://yjpark.3322.org/webpark"&gt;http://yjpark.org/webpark&lt;/a&gt;, click the left-top button to install an extension for firefox (It's needed to add hook to user's click)&lt;br /&gt;&lt;br /&gt;The second button is for login which is not implemented yet, the third can config how many pages you want to see in the window, the fourth can add a new page. on right side, each opened page will have a thumbnail(currently all same, will customize it in the future), you can click on it to switch(sub page will have no thumbnail, a sub page is the one which supposed to be on a new window, but with the extension, I can catch it and display it on right of the original page). the small buttons on top of each page can be used to maximize and close a page.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12099183-709685799588440299?l=yjpark.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/709685799588440299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12099183&amp;postID=709685799588440299' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/709685799588440299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/709685799588440299'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/2007/07/web-park-prototype-release.html' title='Web park prototype release (See more than 1 pages in one tab)'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12099183.post-8143458987819605507</id><published>2007-01-01T12:01:00.000+08:00</published><updated>2007-07-05T13:48:10.650+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dojo'/><title type='text'>Turbo dojo widgets</title><content type='html'>&lt;h3&gt;       Background&lt;a class="anchor" href="https://yjpark.3322.org/trac/wiki/DojoTurbo#Background" title="Link to this section"&gt;&lt;br /&gt;&lt;/a&gt;     &lt;/h3&gt;     &lt;p&gt; In our project, we chose dojo as the AJAX toolkits, we use dojo widget programmatically, it's easy to use and easy to extend, but dojo's widget has big performance problem in our project. &lt;/p&gt;     &lt;p&gt; In one page, we can have thousands of widgets, creating a widget in dojo is really slow, showing such a page needs like 20 minutes 100% CPU usage, it's far from acceptable, so I have to figure out some method to boost dojo dramatically. &lt;/p&gt;     &lt;p&gt; dojo's widget is very powerful, you can define attach points and connect events in the templates, then dojo will parse the templates and pick up all the custom tags and process on them, after reading some dojo source code, I found out that the template parsing is the most time consuming part in widget creations, it takes like 80-90% of the whole time, so I decided to try to optimize this part first. &lt;/p&gt;     &lt;p&gt; Every time creating a widget with dojo.widget.createWidget(), the template of that widget will be parsed, that is actually not needed, every kind of widget will have same template, so the result of the first parse can be cached, then it's not needed to parse the same template anymore. &lt;/p&gt;     &lt;p&gt; I've seen some one in dojo's maillist talking about cloning a widget, I think it's the same idea I have here, but I don't have enough time to actually patch dojo to have a faster widget creation, so I first do some work to help our project running fast with dojo. &lt;/p&gt;     &lt;p&gt;       &lt;i&gt;As I said before, our project create all the widgets in javascript, my turbo way only work in this scenario, if you want to use the widgets in html, this post can not help you.&lt;/i&gt;     &lt;/p&gt;     &lt;h3&gt;       My trick&lt;a class="anchor" href="https://yjpark.3322.org/trac/wiki/DojoTurbo#Mytrick" title="Link to this section"&gt;&lt;br /&gt;&lt;/a&gt;     &lt;/h3&gt;     &lt;p&gt;       common/turbo.js&lt;/p&gt;     &lt;blockquote&gt;     &lt;pre class="wiki"&gt;&lt;span style="font-size:78%;"&gt;dojo.provide("common.turbo");&lt;br /&gt;&lt;br /&gt;dojo.require("dojo.widget.*");&lt;br /&gt;dojo.require("dojo.widget.Manager");&lt;br /&gt;&lt;br /&gt;_cachedWidgets = {}&lt;br /&gt;&lt;br /&gt;common.turbo.createWidget = function(name, props, refNode, position){&lt;br /&gt;var prototype = _cachedWidgets[name];&lt;br /&gt;if (prototype == undefined){&lt;br /&gt; prototype = dojo.widget.createWidget(name, props, refNode, position);&lt;br /&gt; if (prototype["turboInit"] != undefined){&lt;br /&gt;     prototype.widgetType = name;&lt;br /&gt;     prototype.index = 0;&lt;br /&gt;     _cachedWidgets[name] = common.turbo.cloneWidget(prototype, {}, false);&lt;br /&gt;     prototype.turboInit();&lt;br /&gt; }else{&lt;br /&gt;     //alert(name);&lt;br /&gt; }&lt;br /&gt; return prototype;&lt;br /&gt;}&lt;br /&gt;var result = common.turbo.cloneWidget(prototype, props, true);&lt;br /&gt;if (refNode != null) refNode.parentNode.replaceChild(result.domNode, refNode);&lt;br /&gt;return result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;common.turbo.cloneWidget = function(prototype, props, init){&lt;br /&gt;var result = {};&lt;br /&gt;for (k in prototype) result[k] = prototype[k];&lt;br /&gt;for (k in props) result[k] = props[k];&lt;br /&gt;var widgetId = props["id"];&lt;br /&gt;result.index = ++prototype.index;&lt;br /&gt;if (widgetId != undefined){&lt;br /&gt; result.widgetId = widgetId;&lt;br /&gt;}else{&lt;br /&gt; result.widgetId = prototype.widgetType + "_" + result.index;&lt;br /&gt;}&lt;br /&gt;result.domNode = prototype.domNode.cloneNode(true);&lt;br /&gt;if (init) result.turboInit();&lt;br /&gt;dojo.widget.manager.add(result);&lt;br /&gt;return result;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;     &lt;/blockquote&gt;     &lt;p&gt; The logic here is simple, in our javascript code, we call common.turbo.createWidget() instead of dojo.widget.createWidget() to create a widget. &lt;/p&gt;     &lt;p&gt; In common.turbo.createWidget(), it will call dojo.widget.createWidget() to create the first widget, so I don't need to write code to parse template and can keep using most of dojo's power(will talk about the limitation later), then after got the widget created, we check whether it has a method named as turboInit(), if it does, then means this widget is one of our turbo widgets, then we can use common.turbo.cloneWidget() to get a clone and cache it, then if the same type of widget is needed in the future, the cached prototype can be used to make another clone, then we make sure dojo's slow widget creation will only happen once per type, that is acceptable. &lt;/p&gt;     &lt;p&gt;       Here is an example of turboed widget     &lt;/p&gt;     &lt;blockquote&gt;     &lt;pre class="wiki"&gt;&lt;span style="font-size:78%;"&gt;dojo.provide("common.widget.Button2");&lt;br /&gt;dojo.widget.manager.registerWidgetPackage("common.widget");&lt;br /&gt;&lt;br /&gt;dojo.require("dojo.widget.*");&lt;br /&gt;dojo.require("dojo.widget.Button");&lt;br /&gt;&lt;br /&gt;dojo.widget.defineWidget(&lt;br /&gt;"common.widget.Button2",&lt;br /&gt;dojo.widget.html.Button,&lt;br /&gt;{&lt;br /&gt; templateString: &lt;/span&gt;&lt;span style="font-size:78%;"&gt;'&amp;lt;div class="dojoButton" style="position:relative;"&amp;gt;'&lt;br /&gt;                     +  '&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;div class="dojoButtonContents" align=center '&lt;br /&gt; +  'dojoAttachPoint="containerNode" '&lt;br /&gt; +  'style="position:absolute;'&lt;br /&gt; +  'z-index:2;"&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;/div&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;'&lt;br /&gt;                     +  '&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;img dojoAttachPoint="leftImage" '&lt;br /&gt; +  'style="position:absolute;left:0px;"&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;'&lt;br /&gt;                     +  '&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;img dojoAttachPoint="centerImage" '&lt;br /&gt; +  'style="position:absolute;z-index:1;"&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;'&lt;br /&gt;                     +  '&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;img dojoAttachPoint="rightImage" '&lt;br /&gt; +  'style="position:absolute;top:0px;right:0px;"&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;'&lt;br /&gt;                   +'&amp;lt;/div&lt;/span&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;',&lt;br /&gt;&lt;br /&gt; turboInit: function(){&lt;br /&gt;     this.containerNode = this.domNode.childNodes[0];&lt;br /&gt;     this.leftImage = this.domNode.childNodes[1];&lt;br /&gt;     this.centerImage = this.domNode.childNodes[2];&lt;br /&gt;     this.rightImage = this.domNode.childNodes[3];&lt;br /&gt;&lt;br /&gt;     this.containerNode.innerHTML = this.caption;&lt;br /&gt;     this.sizeMyself();&lt;br /&gt;&lt;br /&gt;     dojo.event.connect(this.domNode, "onmouseup", this, this.onMouseUp);&lt;br /&gt;     dojo.event.connect(this.domNode, "onmousedown", this, this.onMouseDown);&lt;br /&gt;     dojo.event.connect(this.domNode, "onmouseover", this, this.onMouseOver);&lt;br /&gt;     dojo.event.connect(this.domNode, "onmouseout", this, this.onMouseOut);&lt;br /&gt;     dojo.event.connect(this.domNode, "onclick", this, this.buttonClick);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;     &lt;/blockquote&gt;     &lt;p&gt; This is a subclass of dojo.widget.html.Button, in turboInit(), it rebuild the dojoAttachPoint from domNode, and attach events. &lt;/p&gt;     &lt;p&gt;       The usage of Button2 is same with other widget, just use common.turbo.createWidget() to create it.     &lt;/p&gt;     &lt;p&gt; By using this simple technology, our ajax page is pretty fast now, the same page now only takes like 20-30 seconds in widget creation part. Then with some lazy loading tech, our project is fast enough now. &lt;/p&gt;     &lt;h3&gt;       The limitation of this approach&lt;a class="anchor" href="https://yjpark.3322.org/trac/wiki/DojoTurbo#Thelimitationofthisapproach" title="Link to this section"&gt;&lt;br /&gt;&lt;/a&gt;     &lt;/h3&gt;     &lt;p&gt; The dojoAttachPoint and dojoAttachEvent only works for the first widget, all cloned widgets needs to set them up in turboInit(), now for my own widget, I just don't use them in templates, in the case of changing a current widget like the example of Button2.js, I leave them in template and setup them up again in the turboInit() now. &lt;/p&gt;     &lt;p&gt; And for better perforamnce, I didn't call all the functions dojo calls when create a new widget, e.g. postMixInProperties() and postCreate(), it's easy to call them in common.widget.cloneWidget(), while in our project it's not needed. &lt;/p&gt;     &lt;p&gt; The simple clone in common.widget.cloneWidget() is not a deep one, I think this is better, you can choose deep copy some property of reinitialize it in turboInit(). &lt;/p&gt;     &lt;p&gt;       Not all properties needs to be copied, actually some of them may have wrong value after the copy.     &lt;/p&gt;     &lt;h3&gt;       Future work&lt;a class="anchor" href="https://yjpark.3322.org/trac/wiki/DojoTurbo#Futurework" title="Link to this section"&gt;&lt;br /&gt;&lt;/a&gt;     &lt;/h3&gt;     &lt;p&gt; As I said, if I add the similiar hack to dojo's framework, then it's possible to just make all template parsing cached for all type of widgets, and don't need the turboInit() trick. This may or may not be easy, if I got time, will try to figure it out. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12099183-8143458987819605507?l=yjpark.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/8143458987819605507/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12099183&amp;postID=8143458987819605507' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/8143458987819605507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/8143458987819605507'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/2007/07/turbo-dojo-widgets.html' title='Turbo dojo widgets'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12099183.post-4659576617555210572</id><published>2006-09-07T15:51:00.000+08:00</published><updated>2006-09-07T15:56:51.764+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Setup ssh to use public key authentication (without input password)</title><content type='html'>Under Linux, we use ssh and scp a lot, if you don't want to enter password everytime, here is how to set it to use public/private key for authorization.&lt;br /&gt;&lt;br /&gt;First you need to generate a public/private key pair to identify yourself, use 'ssh-keygen -t rsa'&lt;br /&gt;Then you need to add the generated public key to the remote host, here is how I do it&lt;br /&gt;&lt;br /&gt;At Local Machine&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;scp id_rsa.pub yjpark@exobox:&lt;br /&gt;ssh-add&lt;/blockquote&gt;&lt;/pre&gt;At Remote Machine:&lt;br /&gt;&lt;pre&gt;&lt;blockquote&gt;mkdir .ssh&lt;br /&gt;chmod 600 .ssh&lt;br /&gt;cd .ssh&lt;br /&gt;cat ../id_rsa.pub &gt;&gt; authorized_keys&lt;br /&gt;chmod 600 authorized_keys&lt;/blockquote&gt;&lt;/pre&gt;That's All&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;make sure that .ssh and authorized_keys is not accessed by anyone except the owner, otherwise it will not work&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12099183-4659576617555210572?l=yjpark.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/4659576617555210572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12099183&amp;postID=4659576617555210572' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/4659576617555210572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/4659576617555210572'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/2006/09/under-linux-we-use-ssh-and-scp-lot-if.html' title='Setup ssh to use public key authentication (without input password)'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12099183.post-4626244101477435113</id><published>2006-09-07T15:37:00.000+08:00</published><updated>2007-07-05T13:43:27.648+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>How to setup window's background color under Gnome</title><content type='html'>In current version of gnome, there is no tools for setting up background color of window, it's background setting only change desktop's background.&lt;br /&gt;&lt;br /&gt;I really don't like white background, I want the background gray, so I setup some applications's background manually, but some application do not have background color setting(e.g. some versions of Eclipse), and it's not a good way to do that, so I spent little time on it.&lt;br /&gt;&lt;br /&gt;First I tried some themes, some of them has gray background, while I don't like there colors setting, so what I need to do is to modify some themes to fit my requirement.&lt;br /&gt;&lt;br /&gt;In gnome's theme setting -&gt; Theme Details, you can choose different setting of Controls, window Border or Icons, window's background belongs to Controls, I picked up !LighthouseBlue as a base setting.&lt;br /&gt;&lt;br /&gt;The themes file are under /usr/share/themes, I only modified gtk-2.0/gtkrc&lt;br /&gt;&lt;blockquote  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;bg[NORMAL]       = "#D0D0D0"    //background color of window&lt;br /&gt;base[NORMAL]     = "#CCCCC0"    //background color or controls&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="down" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;br /&gt;That make me quite happy. I didn't find good tool for editing theme, there is a definition of the values:  &lt;a href="http://developer.gnome.org/doc/API/gtk/gtk-resource-files.html"&gt;&lt;span style="text-decoration: underline;"&gt;http://developer.gnome.org/doc/API/gtk/gtk-resource-files.html&lt;/span&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12099183-4626244101477435113?l=yjpark.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yjpark.blogspot.com/feeds/4626244101477435113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12099183&amp;postID=4626244101477435113' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/4626244101477435113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12099183/posts/default/4626244101477435113'/><link rel='alternate' type='text/html' href='http://yjpark.blogspot.com/2006/09/how-to-setup-windows-background-color.html' title='How to setup window&apos;s background color under Gnome'/><author><name>YJ Park</name><uri>http://www.blogger.com/profile/16389846513090342033</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp1.blogger.com/_EK6KtDReX9k/Rox__YpaPQI/AAAAAAAAAPc/5awAxjaJBb8/s320/yjpark_icon.jpg'/></author><thr:total>0</thr:total></entry></feed>
