<?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-12426107</id><updated>2011-07-31T02:31:19.825-07:00</updated><category term='concise'/><category term='grub_puts_'/><category term='grub'/><category term='gtk+ plugin module'/><category term='ogg'/><category term='usb'/><category term='encoding'/><category term='入门'/><category term='convert'/><category term='mp3'/><category term='快速'/><category term='tag'/><category term='rescue'/><category term='汇编语言'/><category term='简洁'/><category term='error'/><category term='recover'/><category term='assembly'/><category term='beginner'/><category term='charset'/><title type='text'>Spread The Words  口耳相传</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-12426107.post-3444293803450270966</id><published>2010-10-20T03:58:00.000-07:00</published><updated>2010-10-20T23:47:32.864-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='快速'/><category scheme='http://www.blogger.com/atom/ns#' term='汇编语言'/><category scheme='http://www.blogger.com/atom/ns#' term='concise'/><category scheme='http://www.blogger.com/atom/ns#' term='简洁'/><category scheme='http://www.blogger.com/atom/ns#' term='入门'/><category scheme='http://www.blogger.com/atom/ns#' term='beginner'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>Assembly Language book for beginner汇编语言入门书</title><content type='html'>推荐一本汇编语言入门的书：&lt;a href="http://www.drpaulcarter.com/pcasm/index.php"&gt;PC汇编语言 (PC Assembly Tutorial)&lt;/a&gt; ，推荐的原因不是说它写得多好，而是它写的相当简洁。&lt;br /&gt;&lt;br /&gt;中文翻译版 177 页，每页字不多。很适合没有耐心的C/C++程序员使用。花三天时间，每天几个小时就能轻松掌握了。看完就能用汇编加速C/C++程序，这三天太值了。&lt;br /&gt;&lt;br /&gt;而且内容叙述和例子的比例也很恰当，一边看，一边把例子敲一遍出来，脑力体力结合，人性化得很。&lt;br /&gt;&lt;br /&gt;中文版的翻译不多的几个细节表述的不清楚，要多想两遍，不过总体来说，非常清晰，容易理解。感谢原作者和翻译者。&lt;br /&gt;&lt;br /&gt;对于书里描述不清楚的地方，再配合著名的 &lt;a href="http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/www.artofasm.com/Linux/HTML/AoATOC.html"&gt;汇编的艺术(The Art of Assembly Language Programming) &lt;/a&gt;查找相应的指令解释来看，就补齐了。&lt;br /&gt;&lt;br /&gt;语言掌握后，更多的指令用法，就像查程序库API的用法一样，用到的时候翻汇编的艺术就可以了。&lt;br /&gt;&lt;br /&gt;汇编的艺术的问题在于太全了，丛头到尾，那么厚一本书，怎么看都看不下去。做为参考书，具体编程的时候查看，再深入研究还差不多，用来入门不合适。&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;I've spent 3 days to finish the Chinese version of &lt;a href="http://www.drpaulcarter.com/pcasm/index.php"&gt;PC Assembly Tutorial&lt;/a&gt;. After reading the book, one should be able to get start with accelerating C/C++ programs use assembly programming. It's very easy to follow and has the right amount of examples to get you feel the language.&lt;br /&gt;&lt;br /&gt;Highly recommend to C/C++ programmers who want to get start with the assembly language.&lt;br /&gt;&lt;br /&gt;The reason I recommend the book is that the book is very concise and easy to follow. There's only 177 pages with not too many words per page for the Chinese version. Of course any other language version will be a little longer since Chinese script is one of the most concise script in the world. But the point still stands.&lt;br /&gt;&lt;br /&gt;The book comes with translated version to several languages.&lt;br /&gt;&lt;br /&gt;On the other hand, the &lt;a href="http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/www.artofasm.com/Linux/HTML/AoATOC.html"&gt;Art of Assembly Language Programming&lt;/a&gt; is too comprehensive for beginners. I'd guess it's a good reference book for assembly programming but definitely not a good dive in book. At least I was not patient enough to finished it on several tries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-3444293803450270966?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.drpaulcarter.com/pcasm/index.php' title='Assembly Language book for beginner&lt;br/&gt;汇编语言入门书'/><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/3444293803450270966/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=3444293803450270966' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/3444293803450270966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/3444293803450270966'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2010/10/assembly-language-book-for-beginner.html' title='Assembly Language book for beginner&lt;br/&gt;汇编语言入门书'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-4103931405768303082</id><published>2010-05-02T07:33:00.000-07:00</published><updated>2010-05-02T07:55:30.523-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='charset'/><category scheme='http://www.blogger.com/atom/ns#' term='tag'/><category scheme='http://www.blogger.com/atom/ns#' term='ogg'/><category scheme='http://www.blogger.com/atom/ns#' term='encoding'/><category scheme='http://www.blogger.com/atom/ns#' term='mp3'/><category scheme='http://www.blogger.com/atom/ns#' term='convert'/><title type='text'>mp3 tag encoding/charset convert</title><content type='html'>So I was trying to convert id3 tags of some music files from Chinese GBK encoding to UTF-8 such that the &lt;a href="http://audacious-media-player.org/"&gt;Audacious&lt;/a&gt; can read the tags. Well, after thoroughly searching the web, I finally found one that is packaged on Debian/Linux.&lt;br /&gt;&lt;br /&gt;The program is called mid3conv. It's kinda of a demo script for the &lt;a href="http://code.google.com/p/mutagen/"&gt;python-mutagen &lt;/a&gt;package, hence the 'm' before the id3conv name.&lt;br /&gt;&lt;br /&gt;Apparently, the demo tools in the mutagen is not well advised. Those are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;mutagen-inspect (1)  - view Mutagen-supported audio tags&lt;/li&gt;&lt;li&gt;mutagen-pony (1)     - scan a collection of MP3 files&lt;/li&gt;&lt;li&gt;mid3iconv (1)        - convert ID3 tag encodings&lt;/li&gt;&lt;li&gt;mid3v2 (1)           - audio tag editor similar to 'id3v2'&lt;/li&gt;&lt;li&gt;moggsplit (1)        - split Ogg logical streams&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So if you want to convert some ID3 tags in legacy encoding or charset of CJK (Chinese/Japanese/Korean) in your mp3 files, try to install '&lt;span style="font-weight: bold;"&gt;python-mutage&lt;/span&gt;' and use the command line tool &lt;span style="font-weight: bold;"&gt;mid3conv&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-4103931405768303082?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/4103931405768303082/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=4103931405768303082' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/4103931405768303082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/4103931405768303082'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2010/05/mp3-tag-encodingcharset-convert.html' title='mp3 tag encoding/charset convert'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-5270927929957528975</id><published>2010-04-08T04:14:00.000-07:00</published><updated>2010-05-02T07:56:58.840-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grub'/><category scheme='http://www.blogger.com/atom/ns#' term='recover'/><category scheme='http://www.blogger.com/atom/ns#' term='grub_puts_'/><category scheme='http://www.blogger.com/atom/ns#' term='error'/><category scheme='http://www.blogger.com/atom/ns#' term='usb'/><category scheme='http://www.blogger.com/atom/ns#' term='rescue'/><title type='text'>Solve error: the symbol 'grub_puts_' not found</title><content type='html'>Everybody and their mom know that Grub2 (version 1.98 as of today) sucks. I got bitten by it twice in 2 grub upgrades on my Debian box.&lt;br /&gt;&lt;br /&gt;The latest one is the error: the symbol 'grub_puts_' not found.&lt;br /&gt;And a useless prompt: grub rescue&gt;&lt;br /&gt;&lt;br /&gt;After fooling around with all the tinycore linux, kubuntu livecd images, I found the easy way out.&lt;br /&gt;&lt;br /&gt;I just burned a &lt;a href="http://www.supergrubdisk.org/"&gt;Super Grub Disk&lt;/a&gt; and boot into my Debian with it using an old /boot/grub/menu.lst leftover from the grub 0.97 era.&lt;br /&gt;&lt;br /&gt;I have to use the 0.9799 version of the super grub disk since the latest grub2 compatible versions 1.30/1.21 images are not bootable at all.&lt;br /&gt;&lt;br /&gt;Once inside the Debian, do a&lt;br /&gt;&lt;pre&gt;    # grub-install /dev/sda&lt;/pre&gt;&lt;br /&gt;to put the grub back on my 1st hard drive. voila!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Yes, Debian forces this 1.98 version of grub2 onto users. Fuck whoever made that decision.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-5270927929957528975?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/5270927929957528975/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=5270927929957528975' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/5270927929957528975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/5270927929957528975'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2010/04/solve-error-symbol-grubputs-not-found.html' title='Solve error: the symbol &apos;grub_puts_&apos; not found'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-5675098955155565200</id><published>2009-01-13T19:12:00.000-08:00</published><updated>2009-01-13T19:31:36.773-08:00</updated><title type='text'>Using firebug console on chrome extensions</title><content type='html'>When working on a firefox extension, you cannot use firebug console.log directly from your XUL chrome/overlay.js because the console belongs to the document window but in XUL, you get a XUL window.&lt;br /&gt;&lt;br /&gt;The equivalent of a window in chrome overlay is the &lt;span style="font-weight: bold;"&gt;"content"&lt;/span&gt; but it is &lt;span style="font-style: italic;"&gt;XPCNativeWrapper&lt;/span&gt; wrapped which hide all the javascript methods of an Object. We need to unwrap the &lt;span style="font-weight: bold;"&gt;content&lt;/span&gt; first before we can get a console. So to get the console instance, you need this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;DEBUG=false;&lt;br /&gt;// Wrap firebug console.log&lt;br /&gt;function log() {&lt;br /&gt;   if (!DEBUG) return;&lt;br /&gt;   var console = content.wrappedJSObject.console;&lt;br /&gt;   if (console.firebug) {&lt;br /&gt; console.log.apply(console, arguments);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="https://developer.mozilla.org/en/Safely_accessing_content_DOM_from_chrome"&gt;Safely_accessing_content_DOM_from_chrome&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-5675098955155565200?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/5675098955155565200/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=5675098955155565200' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/5675098955155565200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/5675098955155565200'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2009/01/using-firebug-console-on-chrome.html' title='Using firebug console on chrome extensions'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-4470852046140467547</id><published>2008-06-09T19:05:00.000-07:00</published><updated>2008-06-09T19:25:23.326-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gtk+ plugin module'/><title type='text'>Load arbitary module to any gtk+ applications为任意 gtk+ 程序加载模块</title><content type='html'>gtk+ 图形库有一个特殊的环境变量，可以让你为&lt;span style="font-weight: bold;"&gt;任意的 gtk+ 程序&lt;/span&gt;加载模块，而不需要这个程序本身支持插件，或者扩展功能。只要在运行程序前，设定 &lt;a href="http://library.gnome.org/devel/gtk/unstable/gtk-running.html"&gt;GTK_MODULES&lt;/a&gt; 这个&lt;span style="font-weight: bold;"&gt;环境变量&lt;/span&gt;，让它指向所有需要加载的模块。而GTK_MODULES指定的模块，本身是符合 &lt;a href="http://library.gnome.org/devel/gtk/unstable/gtk-General.html#GtkModuleInitFunc"&gt;gtk 模块接口&lt;/a&gt; 的动态模块。&lt;br /&gt;&lt;br /&gt;You can load arbitrary gtk modules/plugins to &lt;span style="font-weight: bold;"&gt;any gtk+ application&lt;/span&gt; without the application explicitly support gtk modules. All you need to do is set the &lt;span style="font-weight: bold;"&gt;environment variable&lt;/span&gt; &lt;a href="http://library.gnome.org/devel/gtk/unstable/gtk-running.html"&gt;GTK_MODULES&lt;/a&gt; to all the modules or plugins you want to load before starting the application. The modules are dynamic libraries compliant &lt;a href="http://library.gnome.org/devel/gtk/unstable/gtk-General.html#GtkModuleInitFunc"&gt;gtk module API&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-4470852046140467547?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/4470852046140467547/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=4470852046140467547' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/4470852046140467547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/4470852046140467547'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2008/06/load-arbitary-module-to-gtk-application.html' title='Load arbitary module to any gtk+ applications&lt;br/&gt;为任意 gtk+ 程序加载模块'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-3676931902291451585</id><published>2006-10-07T03:28:00.000-07:00</published><updated>2006-10-07T03:45:58.713-07:00</updated><title type='text'>Mplayer Soft VolumeMplayer 的软件音量控制</title><content type='html'>最近才意识到 mplayer 是有软音量控制的，就是说它的音量改变或者静音可以不影响其他软件的音量。有时候边听音乐边用 mplayer 的时候会希望暂时关掉它的音量，以前它会直接把音卡的音量关了，音乐也别听了。现在意识到可以在启动的时候加 &lt;i&gt;-softvol&lt;/i&gt; 选项来使用软音量控制。这样静音的就只是 mplayer 本身，而不会影响到我的 &lt;em&gt;&lt;a href="http://www.sacredchao.net/quodlibet"&gt;QuodLibet&lt;/a&gt;&lt;/em&gt; 了。现在我把这个选项直接写到 &lt;em&gt;~/.mplayer/config&lt;/em&gt; 里了。&lt;br /&gt;&lt;br /&gt;Just realized that you could have soft volume control when using mplayer. It seems that the function was already there since 2004. Well, I only found it just now. Now I can mute mplayer while listen to music with my &lt;em&gt;&lt;a href="http://www.sacredchao.net/quodlibet"&gt;QuodLibet&lt;/a&gt;&lt;/em&gt;. The option is &lt;i&gt;-softvol&lt;/i&gt; for your curiosity.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-3676931902291451585?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/3676931902291451585/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=3676931902291451585' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/3676931902291451585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/3676931902291451585'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2006/10/mplayer-soft-volume-mplayer.html' title='Mplayer Soft Volume&lt;br/&gt;Mplayer 的软件音量控制'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-114525213991571554</id><published>2006-04-16T22:28:00.000-07:00</published><updated>2006-04-16T22:35:39.926-07:00</updated><title type='text'>转载一个UPnP流程的分析文章</title><content type='html'>看到一个关于UPnP中控制点操作流程的东西，觉得说的挺清楚。对UPnP概念的初步理解很有帮助，比网上大量的UPnP协定，描述要容易上手的多了。挺旧的一篇文章，2004年的。&lt;br /&gt;&lt;p/&gt;&lt;p/&gt;&lt;br /&gt;当然这是针对NAT穿透这种简单应用的流程描述，但是上手自然是越简单越好了。何况现在UPnP的应用大抵还是NAT穿透。&lt;br /&gt;&lt;p/&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://crmky.blogdriver.com/crmky/341068.html"&gt;UPnP中Control Point的基本流程&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-114525213991571554?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/114525213991571554/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=114525213991571554' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/114525213991571554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/114525213991571554'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2006/04/upnp.html' title='转载一个UPnP流程的分析文章'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-114446745697660879</id><published>2006-04-07T20:28:00.000-07:00</published><updated>2006-04-07T20:48:08.306-07:00</updated><title type='text'>Istanbul: Record desktop on Linux伊斯坦布尔：Linux下桌面录像</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://live.gnome.org/Istanbul"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://live.hujjat.org/istanbul-preferences.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;This is a gstreamer application writen in Python. It can be used to record desktop activities into a movie (Ogg Theora). &lt;br /&gt;&lt;p /&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;伊斯坦布尔是一款在Linux下记录桌面活动的程序。是用 Python + gstreamer 写的。结果存放在 Ogg Theora 格式的电影下。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://live.gnome.org/Istanbul"&gt;http://live.gnome.org/Istanbul&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-114446745697660879?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/114446745697660879/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=114446745697660879' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/114446745697660879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/114446745697660879'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2006/04/istanbul-record-desktop-on-linuxlinux.html' title='Istanbul: Record desktop on Linux&lt;br /&gt;伊斯坦布尔：Linux下桌面录像'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-114138471265014955</id><published>2006-03-03T03:02:00.000-08:00</published><updated>2006-04-07T20:50:23.053-07:00</updated><title type='text'>Put Chinese fonts in front of Japanese fonts in fontconfig中文字型优先，日文字型靠后</title><content type='html'>On Debian systems, when both Chinese and Japanese fonts are installed, the Japanese fonts will have the priority being used in front of the Chinese ones. The result is that the Serif and Sans-Serif fonts will be totally messed with ugly Japanese glyphs under a Chinese locale. You would think that fontconfig can select the right fonts accroding the current locale. :(&lt;br /&gt;&lt;p /&gt; &lt;p /&gt;&lt;br /&gt;&lt;br /&gt;The solution? Using a ~/.fonts.conf file to set Chinese font as the preferred one for Serif and Sans-Serif. Direct editing /etc/fonts/fonts.conf will has your settings reset on upgrade. For a system-wised customization, do it in /etc/fonts/local.conf, this is on a Debian box.&lt;p&gt;&lt;br /&gt;&lt;br /&gt;Another advantage on using ~/.fonts.conf is that you might have users using different locales (hint: Japanese) on the same box. You don't want to interfere with other people's fonts.&lt;p&gt;&lt;br /&gt;&lt;br /&gt;修改 ~/.fonts.conf 文件，提高中文字型在系统字型中的优先次序。&lt;br /&gt;简单来说，/etc/fonts/fonts.conf 会先加载我们的 ~/.fonts.conf ，然后才设定系统字型(Serif, Sans-Serif)的组合字型的优先次序。我们先设定了，系统的就在我们屁股后面了。&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;Use the following command to find out fonts that fontconfig knows:&lt;br/&gt;&lt;br /&gt;使用以下命令列出系统中的字型：&lt;br/&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;    $ fc-list&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p/&gt;&lt;p/&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE fontconfig SYSTEM "fonts.dtd"&amp;gt;&lt;br /&gt;&amp;lt;!-- ~/.fonts.conf file to configure user font access --&amp;gt;&lt;br /&gt;&amp;lt;fontconfig&amp;gt;&lt;br /&gt;    &amp;lt;alias&amp;gt;&lt;br /&gt; &amp;lt;family&amp;gt;serif&amp;lt;/family&amp;gt;&lt;br /&gt; &amp;lt;prefer&amp;gt;&lt;br /&gt;     &amp;lt;family&amp;gt;Bitstream Vera Serif&amp;lt;/family&amp;gt;&lt;br /&gt;     &amp;lt;family&amp;gt;AR PL ShanHeiSun Uni&amp;lt;/family&amp;gt;&lt;br /&gt;     &amp;lt;family&amp;gt;AR PL ShanHeiSun Uni MBE&amp;lt;/family&amp;gt;&lt;br /&gt; &amp;lt;/prefer&amp;gt;&lt;br /&gt;    &amp;lt;/alias&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;alias&amp;gt;&lt;br /&gt; &amp;lt;family&amp;gt;sans-serif&amp;lt;/family&amp;gt;&lt;br /&gt; &amp;lt;prefer&amp;gt;&lt;br /&gt;     &amp;lt;family&amp;gt;Bitstream Vera Sans&amp;lt;/family&amp;gt;&lt;br /&gt;     &amp;lt;family&amp;gt;AR PL ShanHeiSun Uni&amp;lt;/family&amp;gt;&lt;br /&gt;     &amp;lt;family&amp;gt;AR PL ShanHeiSun Uni MBE&amp;lt;/family&amp;gt;&lt;br /&gt; &amp;lt;/prefer&amp;gt;&lt;br /&gt;    &amp;lt;/alias&amp;gt;&lt;br /&gt;    &amp;lt;alias&amp;gt;&lt;br /&gt; &amp;lt;family&amp;gt;monospace&amp;lt;/family&amp;gt;&lt;br /&gt; &amp;lt;prefer&amp;gt;&lt;br /&gt;     &amp;lt;family&amp;gt;Bitstream Vera Sans Mono&amp;lt;/family&amp;gt;&lt;br /&gt;     &amp;lt;family&amp;gt;AR PL ShanHeiSun Uni&amp;lt;/family&amp;gt;&lt;br /&gt;     &amp;lt;family&amp;gt;AR PL ShanHeiSun Uni MBE&amp;lt;/family&amp;gt;&lt;br /&gt; &amp;lt;/prefer&amp;gt;&lt;br /&gt;    &amp;lt;/alias&amp;gt;&lt;br /&gt;&amp;lt;/fontconfig&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We put the Bitsteam serie fonts in front of our Chinese fonts because we don't want to see westen alphabetic glyphs from our Chinese fonts.&lt;br /&gt;&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-114138471265014955?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/114138471265014955/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=114138471265014955' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/114138471265014955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/114138471265014955'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2006/03/put-chinese-fonts-in-front-of-japanese.html' title='Put Chinese fonts in front of Japanese fonts in fontconfig&lt;br/&gt;中文字型优先，日文字型靠后'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111658945696692555</id><published>2005-05-20T04:10:00.000-07:00</published><updated>2005-05-20T04:44:16.976-07:00</updated><title type='text'>Python with Last-Modified-Time</title><content type='html'>Doing web programing sometime need to parse/create the &lt;em&gt;Last-Modified-Time&lt;/em&gt;, &lt;em&gt;Last-Modified-Since&lt;/em&gt;, or &lt;em&gt;Date&lt;/em&gt;... values in the RFC2822 format. And I always forget the format string. Here we go:&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;&gt;&gt;&gt; import time&lt;br /&gt;&gt;&gt;&gt; time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime())&lt;br /&gt;'Fri, 20 May 2005 11:08:40 GMT'&lt;br /&gt;&gt;&gt;&gt; t = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(time.time()))&lt;br /&gt;&gt;&gt;&gt; t&lt;br /&gt;'Fri, 20 May 2005 11:22:20 GMT'&lt;br /&gt;&gt;&gt;&gt; time.strptime(t, "%a, %d %b %Y %H:%M:%S GMT")&lt;br /&gt;(2005, 5, 20, 11, 22, 20, 4, 140, -1)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So what these tell us? Well, the format string is:&lt;br /&gt;&lt;pre class="code"&gt;&lt;strong&gt;"%a, %d %b %Y %H:%M:%S GMT"&lt;/strong&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's it. Yes, it is GMT time, no timezone there.&lt;p /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111658945696692555?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111658945696692555/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111658945696692555' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111658945696692555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111658945696692555'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/05/python-with-last-modified-time.html' title='Python with Last-Modified-Time'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111637983413224066</id><published>2005-05-17T18:20:00.000-07:00</published><updated>2005-05-17T18:36:04.756-07:00</updated><title type='text'>Scale Gstreamer Video with GTK+</title><content type='html'>改变 Gstreamer 视频在 gtk drawingarea 的大小，比例。&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;Spent days on how to let a gstreamer video sink know that the video window size was changed. Finally, I realized that I missed a line of code in totem that just did this.&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;In order to have the video in gstreamer respect the aspect ratio of a video, you have to put the video window (normally a gtk drawingarea) inside a gtk &lt;em&gt;aspectframe&lt;/em&gt;. However, after the aspectframe is resized to follow the video aspect ratio, you have to call &lt;em&gt;video_sink.expose()&lt;/em&gt; in order for the video sink to resize itself. I am using gstreamer python binding, of course. So many 'have to's that are not documented!&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;The expose() method is an method of interface &lt;em&gt;GstXOverlay&lt;/em&gt;. So any video sink that implements the interface should have a expose() method (gstream name is &lt;em&gt;gst_x_overlay_expose(xid)&lt;/em&gt;. Sucks, huh?)&lt;p /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111637983413224066?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111637983413224066/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111637983413224066' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111637983413224066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111637983413224066'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/05/scale-gstreamer-video-with-gtk.html' title='Scale Gstreamer Video with GTK+'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111631643047564906</id><published>2005-05-17T00:36:00.000-07:00</published><updated>2005-05-17T01:03:29.436-07:00</updated><title type='text'>Debian: Find programs? 寻找程序包？</title><content type='html'>Since I'm talking about Debian tricks, here is one more trick on dealing with debian packages:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Looking for program:&lt;/h2&gt;&lt;p /&gt;&lt;br /&gt;Sometime, people tell you to use a command to solve your problem, but you don't have this command on your system, what you do you?&lt;p /&gt;&lt;br /&gt;You can install &lt;em&gt;apt-file&lt;/em&gt; and run:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;user$ apt-file update&lt;br /&gt;user$ apt-file search command_name&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;"update" will download/update package lists from the apt servers. "search" will search a filename from all the packages on the apt servers, even for the files that you did not installed on your system.&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;想知道一个命令或者一个文件在哪个程序包里吗？比如别人让你跑一个程序，但是你发现你的系统里没有这个程序，怎么办？你可以安装 &lt;em&gt;apt-file&lt;/em&gt;这个程序，然后跑下面的命令：&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;user$ apt-file update&lt;br /&gt;user$ apt-file search command_name&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;"update" 让 apt-file 从网上下载和更新所有程序包的内容，"search"让它在程序包里搜索一个文件名，这个文件名所在的程序包有没有安装无所谓。当然这个功能其他的几个 deb/apt 应用程序也可能有，不过我几年前开始用这个，用着顺手，就没有发掘新的程序了。&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;当然，如果你装了 synaptic ，可能什么窍门都不用了，它全包了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111631643047564906?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111631643047564906/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111631643047564906' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111631643047564906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111631643047564906'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/05/debian-find-programs.html' title='Debian: Find programs? 寻找程序包？'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111631398520057166</id><published>2005-05-17T00:05:00.000-07:00</published><updated>2005-05-17T00:57:04.970-07:00</updated><title type='text'>Debian: Changelog before install? 升级前看看更新记录？</title><content type='html'>Before update a package on Debian, you might want to find out what have been changed in that package. Here is how I always do:&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;在 Debian 里升级一个程序包的时候，你可能会想知道这个包的最新的更新记录，看看它值不值得升级。有时候只是修改说明文件里的笔误，升级没意思。我一般这么做：&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;reportbug package:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;user$ aptitude changelog reportbug&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Yes, it is simple, but you might not know before I told you. And apt-listchanges is more powerful but it is an extra package to install.&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;虽然简单，我不说你却未必知道。apt-listchanges 更强大些，不过它得另装一个包。&lt;p /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111631398520057166?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111631398520057166/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111631398520057166' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111631398520057166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111631398520057166'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/05/debian-changelog-before-install.html' title='Debian: Changelog before install? 升级前看看更新记录？'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111586467854469625</id><published>2005-05-11T18:51:00.000-07:00</published><updated>2005-05-11T19:24:38.556-07:00</updated><title type='text'>Python with Gstreamer</title><content type='html'>OK, so what if we use python and the &lt;em&gt;playbin&lt;/em&gt; of gstreamer? Well, that can be done in a few lines:&lt;br /&gt;&lt;h2&gt; player.py&lt;/h2&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;#!/usr/bin/python&lt;br /&gt;import sys, os.path&lt;br /&gt;import pygtk; pygtk.require('2.0')&lt;br /&gt;import gtk&lt;br /&gt;import gst, gst.interfaces&lt;br /&gt;&lt;br /&gt;def cb_eos(kele, data):&lt;br /&gt;    gtk.main_quit()&lt;br /&gt;def cb_error(*args):&lt;br /&gt;    print args, args[2]&lt;br /&gt;&lt;br /&gt;class Control:&lt;br /&gt;    def __init__(self, playbin, vsink,da):&lt;br /&gt;        self.fullscreen = False&lt;br /&gt;        self.play = playbin&lt;br /&gt;        self.vsink = vsink&lt;br /&gt;        self.da = da&lt;br /&gt;    def key_release(self, widget, event, *args):&lt;br /&gt;        if event.string in ['p',  ' ']:&lt;br /&gt;            if self.play.get_state() == gst.STATE_PLAYING:&lt;br /&gt;                ret = self.play.set_state(gst.STATE_PAUSED)&lt;br /&gt;            else:&lt;br /&gt;                self.vsink.set_xwindow_id(self.da.window.xid)&lt;br /&gt;                ret = self.play.set_state(gst.STATE_PLAYING)&lt;br /&gt;        elif event.string == 's':&lt;br /&gt;            ret = self.play.set_state(gst.STATE_NULL)&lt;br /&gt;        elif event.string == 'q':&lt;br /&gt;            self.quit()&lt;br /&gt;        elif event.string == 'f':&lt;br /&gt;            if self.fullscreen:&lt;br /&gt;                widget.unfullscreen()&lt;br /&gt;            else:&lt;br /&gt;                widget.fullscreen()&lt;br /&gt;            self.fullscreen = not self.fullscreen&lt;br /&gt;    def quit(self, *args):&lt;br /&gt;        ret = self.play.set_state(gst.STATE_NULL)&lt;br /&gt;        gtk.main_quit()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def main():&lt;br /&gt;    fname = sys.argv[1]&lt;br /&gt;    absfname = os.path.abspath(fname)&lt;br /&gt;    uri = 'file://%s' % absfname&lt;br /&gt;&lt;br /&gt;    # Setup video/audio sink and playbin&lt;br /&gt;    vsink = gst.element_factory_make('xvimagesink')&lt;br /&gt;    asink = gst.element_factory_make('esdsink', 'asink')&lt;br /&gt;    playbin = gst.element_factory_make('playbin', 'playbin')&lt;br /&gt;    playbin.set_property('video-sink', vsink)&lt;br /&gt;    playbin.set_property('audio-sink', asink)&lt;br /&gt;    playbin.set_property('uri', uri)&lt;br /&gt;&lt;br /&gt;    playbin.connect('eos', cb_eos)&lt;br /&gt;    playbin.connect('error', cb_error)&lt;br /&gt;&lt;br /&gt;    win = gtk.Window(gtk.WINDOW_TOPLEVEL)&lt;br /&gt;    da = gtk.DrawingArea()&lt;br /&gt;    ctr = Control(playbin, vsink, da)&lt;br /&gt;    win.add(da)&lt;br /&gt;    win.connect('key-release-event', ctr.key_release)&lt;br /&gt;    win.connect('delete-event', ctr.quit)&lt;br /&gt;    win.show_all()&lt;br /&gt;    gtk.main()&lt;br /&gt;    playbin.set_state(gst.STATE_NULL)&lt;br /&gt;&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;    main()    &lt;br /&gt;# vim:ts=8:sw=4:expandtab&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can just type &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;player.py test.avi&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The key bindings are:&lt;br /&gt;&lt;table border="1" cellpadding="2"&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;p or space&lt;/td&gt;&lt;td&gt;&lt;strong&gt;P&lt;/strong&gt;lay/pause the movie&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;s&lt;/td&gt;&lt;td&gt;&lt;strong&gt;S&lt;/strong&gt;top the movie&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;f&lt;/td&gt;&lt;td&gt;&lt;strong&gt;F&lt;/strong&gt;ullscreen/un-fullscreen&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;q&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Q&lt;/strong&gt;uit the program.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;p /&gt;&lt;br /&gt;&lt;UL&gt;&lt;br /&gt;&lt;LI&gt;You have to &lt;em&gt;import gst.interfaces&lt;/em&gt; for many methods to exist, e.g. xvimagesink.set_xwindow_id().&lt;/LI&gt;&lt;br /&gt;&lt;LI&gt;It seems that the binding between gstreamer video window and gtk+ window have to happens later. That's why we &lt;em&gt;set_xwindow_id()&lt;/em&gt; before starting to play the movie.&lt;/LI&gt;&lt;br /&gt;&lt;LI&gt;You need to use a gtk.AspectFrame for keeping the aspect ratio of the movie.&lt;/LI&gt;&lt;br /&gt;&lt;/UL&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111586467854469625?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111586467854469625/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111586467854469625' title='2 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111586467854469625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111586467854469625'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/05/python-with-gstreamer.html' title='Python with Gstreamer'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111571337363048859</id><published>2005-05-10T00:24:00.000-07:00</published><updated>2005-05-10T01:59:27.986-07:00</updated><title type='text'>gstreamer lauch video!</title><content type='html'>OK, here after installed the gstreamer-ffmpeg on my Debian box from deb &lt;a href="http://debian.ressukka.net/"&gt;http://debian.ressukka.net/&lt;/a&gt; unstable/ , I have to test it. &lt;p /&gt;&lt;br /&gt;&lt;br /&gt;I use this gst-launch command for my test. First for this clip I have, I use mplayer to find out what the codecs were used. Well, it is a .avi with msmpeg4v2 video codec and mp3/mp2 mad audio codec. Since my mplayer already installed w32codecs, I'm all set. Now we are ready, here is the command I used to play the clip with gst-launch:&lt;br /&gt;&lt;UL&gt;&lt;LI&gt;&lt;br /&gt;&lt;br /&gt;gst-launch  filesrc location=test.avi ! ffdemux_avi name=demuxer ! {  queue ! ffdec_msmpeg4v2 ! ffcolorspace ! xvimagesink } { demuxer. ! queue ! mad ! esdsink }&lt;br /&gt;&lt;br /&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;br /&gt;&lt;br /&gt;Some notes:&lt;br /&gt;&lt;UL&gt;&lt;br /&gt;&lt;LI&gt;The elements used are:&lt;br /&gt;&lt;table border="1" cellpadding="2"&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;filesrc:&lt;/td&gt;&lt;td&gt; load video file from source.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;ffdemux_avi:&lt;/td&gt;&lt;td&gt; demux avi into streams, from the gstreamer-ffmpeg plugin.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;queue:&lt;/td&gt;&lt;td&gt; Since we want to play both video and audio, need to use threads for video and audio playing at the same time. queue is used to bridge a thread to other threads.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;ffdec_msmpeg4v2:&lt;/td&gt;&lt;td&gt; well, we want to play a msmpeg4v2 video.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;ffcolorspace:&lt;/td&gt;&lt;td&gt; convert the decoded video stream into something our video display can understand.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;xvimagesink:&lt;/td&gt;&lt;td&gt; we use xv as our video output devicde. Other options: sdlvideosink, ximagesink. Somehow, autovideosink don't work for me.&lt;/LI&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;mad:&lt;/td&gt;&lt;td&gt; this element handle mp3 audio codec.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;esdsink:&lt;/td&gt;&lt;td&gt; I use esd as audio output device. Of cause alsasink should work too, if it is not used by someone else.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;LI&gt;There are 2 threads as denoted by the curly bracket {...}. Since we want to play the video and audio at the sametime, we put them together using the blocks.&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;To make sure our audio links from the demuxer ffdemux_avi, we assign a name to that demuxer instant, "demux". At audio thread, we link it using the name "demux." to link with our audio decoder.&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;Notice the &lt;strong&gt;Dot-&amp;gt;.&lt;/strong&gt; after the "demux". Because this "demux" is not a real element, it is a ghost element, so we tell gst-lauch about this by putting a dot(.) after "demux".&lt;/LI&gt;&lt;br /&gt;&lt;/UL&gt;&lt;br /&gt;&lt;br /&gt;Wow, what a mess! How about make it simpler? We all know gstreamer can autodetect all those codecs. OK, the element that do the autodect is decodebin. So here we go:&lt;br /&gt;&lt;br /&gt;&lt;UL&gt;&lt;LI&gt;&lt;br /&gt;&lt;br /&gt;gst-launch  filesrc location=test.avi ! decodebin name=debin !  {  queue ! xvimagesink } { debin. ! queue ! esdsink }&lt;br /&gt;&lt;br /&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;br /&gt;&lt;br /&gt;That's it! We don't even need to know all the codecs things. The element "playbin" does not work for me because its video-sink/audio-sink properties only take &lt;em&gt;element &lt;strong&gt;objects&lt;/strong&gt;&lt;/em&gt; as paramenters. Cannot do that with gst-launch.&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;Gstreamer with gstreamer-ffmpeg and w32codecs are fun. &lt;p /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111571337363048859?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111571337363048859/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111571337363048859' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111571337363048859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111571337363048859'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/05/gstreamer-lauch-video.html' title='gstreamer lauch video!'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111562634648231820</id><published>2005-05-09T00:52:00.000-07:00</published><updated>2005-05-17T00:17:14.753-07:00</updated><title type='text'>Compile python code? 编译蟒蛇程序？</title><content type='html'>You cannot but there are ways to hide your python code by compiling part of your program. How about a C program with a main() and use python's C API? Well, &lt;a href="http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/"&gt;&lt;br /&gt;pyrex&lt;/a&gt; can do that.&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;All you have to do for a stand alone C program in Pyrex are: &lt;p /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;cdef extern from "Python.h":&lt;br /&gt;    void Py_Initialize()&lt;br /&gt;    void Py_Finalize()&lt;br /&gt;    void PySys_SetArgv(int argc, char *argv[])&lt;br /&gt;&lt;br /&gt;# Declare extension init function as a C function.&lt;br /&gt;cdef public void initdemo()&lt;br /&gt;&lt;br /&gt;# Define main() and declare it as "public"&lt;br /&gt;cdef public int main(int argc, char *argv[]):&lt;br /&gt;    Py_Initialize() # Init Python environment&lt;br /&gt;    PySys_SetArgv(argc, argv) # Fill in sys.argv&lt;br /&gt;    initdemo()      # Init our Pyrex generated main module.&lt;br /&gt;    # Do something here...&lt;br /&gt;    Py_Finalize()   # When done, clean up Python env.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;The following is a real example which actually do something. We use the re module to demostrate the power of python here:&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;demo.pyx:&lt;/strong&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;cdef extern from "Python.h":&lt;br /&gt;    void Py_Initialize()&lt;br /&gt;    void Py_Finalize()&lt;br /&gt;    void PySys_SetArgv(int argc, char *argv[])&lt;br /&gt;&lt;br /&gt;cdef extern from "stdio.h":&lt;br /&gt;    int printf(char *format, ...)&lt;br /&gt;&lt;br /&gt;cdef public void initdemo()&lt;br /&gt;&lt;br /&gt;def regex(msg):&lt;br /&gt;    import re&lt;br /&gt;    a = re.findall(r'as\w*', msg)&lt;br /&gt;    return a&lt;br /&gt;&lt;br /&gt;cdef public int main(int argc, char *argv[]):&lt;br /&gt;    Py_Initialize()&lt;br /&gt;    PySys_SetArgv(argc, argv)&lt;br /&gt;    initdemo()&lt;br /&gt;    msg = 'Jump it as high as an ass, asshole!'&lt;br /&gt;    print 'Searching "as" from "%s"' % msg&lt;br /&gt;    m = regex(msg)&lt;br /&gt;    for i in m:&lt;br /&gt;        print 'Match:', i&lt;br /&gt;&lt;br /&gt;    cdef int count&lt;br /&gt;    count = len(m)&lt;br /&gt;    printf("Total: %d\n", count)&lt;br /&gt;    Py_Finalize()&lt;br /&gt;&lt;br /&gt;# vim:ts=8:sw=4:expandtab&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Makefile:&lt;/strong&gt; Link with libpython.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;all: demo&lt;br /&gt;&lt;br /&gt;demo: demo.c&lt;br /&gt;        gcc -g -O2 -I/usr/include/python2.3 -lpython2.3 -o demo demo.c&lt;br /&gt;&lt;br /&gt;demo.c: demo.pyx&lt;br /&gt;        pyrexc demo.pyx&lt;br /&gt;&lt;br /&gt;.PHONY:&lt;br /&gt;        all&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p /&gt;&lt;br /&gt;Run ./demo now will show you how things go. We hide everything in demo.pyx now!&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;As you can see, every C function that is used inside .pyx need to be explicitly declared in a &lt;em&gt;cdef extern from "cheader.h":&lt;/em&gt; block. Other than that, Pyrex also cannot do list comprehension and generator. So do your generator or comprehension in a .py module and import to the .pyx.&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;And of cause if you don't write pure C inside .pyx, the resulting program will not be faster than a pure .py program.&lt;p /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111562634648231820?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111562634648231820/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111562634648231820' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111562634648231820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111562634648231820'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/05/compile-python-code.html' title='Compile python code? 编译蟒蛇程序？'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111491327064217326</id><published>2005-04-30T18:48:00.000-07:00</published><updated>2006-06-19T21:55:37.570-07:00</updated><title type='text'>GtkDrawingArea and GtkScrolledWindow</title><content type='html'>&lt;table&gt;&lt;tr&gt;&lt;td&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/826/1053/1600/GtkDrawingArea-screenshot2.3.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/826/1053/320/GtkDrawingArea-screenshot2.3.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;I saw some question asked about making &lt;a href="http://www.amazesoft.com/images/flashget.jpg"&gt;flashget like progress window&lt;/a&gt; in gtk+. It can be simply realized using DrawingArea. &lt;p /&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;Then there is also the problem of scrolling the DrawingArea inside a ScrolledWindow. Well, this is simple. Just put a Viewport b/w the DrawingArea and the ScrolledWindow. Then do a set_size_request on the DrawingArea.&lt;p /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;#!/usr/bin/python&lt;br /&gt;import pygtk&lt;br /&gt;pygtk.require('2.0')&lt;br /&gt;import gtk&lt;br /&gt;&lt;br /&gt;# 2 icons we use in our drawing area.&lt;br /&gt;PICTNAME1="gdraw1.png"&lt;br /&gt;PICTNAME2="gdraw2.png"&lt;br /&gt;def load(pix):&lt;br /&gt;    '''Load GUI'''&lt;br /&gt;    win = gtk.Window()&lt;br /&gt;    gdraw = gtk.DrawingArea()&lt;br /&gt;    sw = gtk.ScrolledWindow()&lt;br /&gt;    sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)&lt;br /&gt;    vp = gtk.Viewport()&lt;br /&gt;    sw.add(vp)&lt;br /&gt;    vp.add(gdraw)&lt;br /&gt;&lt;br /&gt;    win.add(sw)&lt;br /&gt;    win.resize(400, 200)&lt;br /&gt;    win.connect('delete-event', gtk.main_quit)&lt;br /&gt;    gdraw.connect('expose-event', expose_pix, pix)&lt;br /&gt;    win.show_all()&lt;br /&gt;&lt;br /&gt;def expose_pix(gdraw, event, pix):&lt;br /&gt;    '''At expose event, actual draw graph.'''&lt;br /&gt;    pix1, pix2 = pix&lt;br /&gt;    gc = gdraw.window.new_gc()&lt;br /&gt;    pw = pix1.get_width()&lt;br /&gt;    ph = pix1.get_height()&lt;br /&gt;    geo = gdraw.window.get_geometry()&lt;br /&gt;    gw, gh = geo[2:4]&lt;br /&gt;    dx = dy = 0&lt;br /&gt;&lt;br /&gt;    # Draw 100 pixbuf on DrawingArea&lt;br /&gt;    for i in range(100):&lt;br /&gt;        if dx + pw &gt; gw:&lt;br /&gt;            # Move down to the next line&lt;br /&gt;            dx = 0&lt;br /&gt;            dy += ph+1&lt;br /&gt;        if i % 7: # Draw a pix2 every 7 pix1&lt;br /&gt;            pixi = pix1&lt;br /&gt;        else:&lt;br /&gt;            pixi = pix2&lt;br /&gt;        gdraw.window.draw_pixbuf(gc, pixi, 0, 0, &lt;br /&gt;                                 dx, dy, pw, ph)&lt;br /&gt;        dx += pw+1&lt;br /&gt;    # Set the gdraw size request for Viewport &lt;br /&gt;    # to the height of our drawing.&lt;br /&gt;    gdraw.set_size_request(-1, dy+ph)&lt;br /&gt;&lt;br /&gt;def main():&lt;br /&gt;    pix1 = gtk.gdk.pixbuf_new_from_file(PICTNAME1)&lt;br /&gt;    pix2 = gtk.gdk.pixbuf_new_from_file(PICTNAME2)&lt;br /&gt;    load((pix1, pix2))&lt;br /&gt;    gtk.main()&lt;br /&gt;    &lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;    main()&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;Told you pygtk is very easy to program with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111491327064217326?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111491327064217326/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111491327064217326' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111491327064217326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111491327064217326'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/04/gtkdrawingarea-and-gtkscrolledwindow.html' title='GtkDrawingArea and GtkScrolledWindow'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111449297539238314</id><published>2005-04-25T22:05:00.000-07:00</published><updated>2005-04-27T02:49:26.456-07:00</updated><title type='text'>CoolStreaming on Linux?</title><content type='html'>Doing &lt;a href="http://www.winehq.com"&gt;wine&lt;/a&gt; + &lt;a href="http://www.coolstreaming.org"&gt;coolstreaming&lt;/a&gt; on Linux is smooth. Go Linux!! &lt;p /&gt;&lt;br /&gt;&lt;br /&gt;It's still proprietary but... It's not like writing an open source equivalent is hard. It's just that it is not easy to find reliable media sources. There! This's my excuse for using coolstreaming. :) &lt;p /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111449297539238314?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111449297539238314/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111449297539238314' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111449297539238314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111449297539238314'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/04/coolstreaming-on-linux.html' title='CoolStreaming on Linux?'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12426107.post-111444855810858484</id><published>2005-04-25T09:42:00.000-07:00</published><updated>2005-05-03T00:53:47.063-07:00</updated><title type='text'>Abit NF7-S2 board ethernet Linux driver.</title><content type='html'>The &lt;strong&gt;NF7-S2&lt;/strong&gt; board from &lt;strong&gt;Abit&lt;/strong&gt; has a buildin ethernet chip. This is a NForce2 board but they do not use Nvidia's NIC. The one I got has this &lt;strong&gt;ICPlus IP100A 10/100&lt;/strong&gt; ethernet chip on it. Found that out from &lt;a href="http://www.abit.com.cn/MotherBoard/SocketA/NF7-S2/driver.htm"&gt;Abit's China site&lt;/a&gt;. Of cause if you are not a Chinese, you are not gonna find it out because this piece of information won't appare on any other Abit sites. Anyway, Under Linux, lspci shows it as:&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Ethernet controller: &lt;strong&gt;Sundance&lt;/strong&gt; Technology Inc: Unknown device 0200 (rev 31)&lt;/em&gt;&lt;br /&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;So it is basically a &lt;strong&gt;Sundance&lt;/strong&gt; Ethernet Chip. It turns out that the Sundance driver come with Linux 2.6.11 does not work with the chip. I have to download the  &lt;a href="http://www.icplus.com.tw/driver-pp-IP100A.html"&gt;ICPlus IP100A Linux driver from ICPlus's own site&lt;/a&gt;.&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;After 'make all' and copy the sundance.ko (Why do they still call it sundance.ko?) to /lib/modules/2.6.11-01/kernel/drivers/net/ , "modprobe sundance". dah dah..., one more NIC on this box. :)&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;So now we know that one revision of Abit NF7 S2 mainboard use ICPlus IP100A ethernet chip which shows up as Sundance chip.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12426107-111444855810858484?l=bugbox.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bugbox.blogspot.com/feeds/111444855810858484/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12426107&amp;postID=111444855810858484' title='4 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111444855810858484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12426107/posts/default/111444855810858484'/><link rel='alternate' type='text/html' href='http://bugbox.blogspot.com/2005/04/abit-nf7-s2-board-ethernet-linux.html' title='Abit NF7-S2 board ethernet Linux driver.'/><author><name>Bug Filler</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>
