减一天费四千的香港游

实在没有比记错航班时间更令人恼怒的事情了。我报名公司同事组织的香港自由行,原本时间是周四到周日的,后来时间改为周三到周六,组织者也数度发email通知大家,出发前一天还发了航班信息和出团通知,不过我都没有留意到时间提前了。周三那天还优哉游哉地在参加公司的培训。中午的时候收到同事在香港打来的电话,问我是否没有搭飞机,这才沉痛地了解到,是周三早晨的飞机。多谢同事们通知我,要不我第二天早上就傻乎乎地去机场了,呼呼...

赶紧和旅行社联系,看能否有办法补救。如果决定不去,机票和酒店的钱都退不了;如果搭第二天的飞机,单程机票每个人要近2000块,而且无法保证可以使用我之前的返程机票(据说是国际惯例,去程不用则返程取消)。最后和领导商量之后,决定还是去。

本来就比较紧的行程,现在又减去一天,就更紧张了。中午1点多到的酒店,下午先到天祥买了只超广角镜头(Sigma 12-24),然后准备到海港城的反斗玩具城去给小小买玩具,结果人家当天暂停营业。就去星光大道转了转,然后搭天星小轮去中环,四处问路到位于皇后大街中路的一家反斗玩具城分店,转了半天也没看到十分想买的。不知是否是最近休息欠佳,腰痛的厉害,而且前夜睡的很糟,所以8点多就回酒店了。

第二天睡了个懒觉,然后去海洋公园玩了小半天,看了看海洋剧场的海豚表演,觉得不比北京海洋馆的节目精彩。傍晚去太平山看夜景和杜莎夫人蜡像馆,等山顶缆车花了不少时间,等车的人很多,而且只有两节车厢。蜡像馆很精彩,山顶的风景也很棒。就是我的超广角太广了,取景角度太大,还是中焦段比较适合拍这种山顶的夜景。然后回中环,到兰桂坊转了转,发现完全不是我们两个的style,找地方吃了些东西然后回酒店。

第三天到SaSa买了些化妆品,然后继续到海港城的反斗玩具城,结果想要买的一款LEGO玩具没货,恰好路遇一位同好告诉我,铜锣湾的SOGO有特价,然后急急忙忙跑到那儿,采购了一番。老婆想买双运动鞋,不过SOGO打折的幅度比较差,决定去东涌的Outlet去看看,饭也来不及吃了,急急忙忙到那儿买了双鞋,然后折回青衣坐机场快线到机场。一路上祈祷航空公司能让我们上机,否则我们就准备去深圳了。到机场的时间刚好,也顺利办好了登记手续,终于松了一口气。最后就是搭机回京了。

下面是我拍的一些照片

OpenSolaris环保购物袋

这是公司为了庆祝OpenSolaris 2008.11发布,同时也作为新年礼物,发给我们员工的一个购物袋。帆布面料,做工扎实,贴心的小功能不少,真是让人爱不释手。要是公司多制作一些,允许员工另购,我肯定会多买几个,送给亲朋好友,呵呵。

what's the 'chash' in ips manifest?

chash: the sha1 hash of the compressed file.

While if you manually compress the file with gzip -n -9, you would find the sha1 value is still different with the one in the manifest file. By looking into ips/pkg's source code, it turns out that the head used in ips/pkg is a little different with the one gzip(1) generated,

-0000000 1f 8b 08 00 00 00 00 00 02 ff
+0000000 1f 8b 08 00 00 00 00 00 02 03

The last byte is to indicate the OS type, '03' stands for 'Unix', 'ff' means 'Unknown', refer to RFC1952. After you change the OS type to 'ff' in your manually compressed file, you would see the sha hash values are just the same.

localization and gettext in python

import gettext
'''
gettext module will use the encoding specified in Content-Type header for
Gnu mo files, and convert the message strings to unicode. Here you could
sepcify the *output* encoding to others.
'''
gettext.bind_textdomain_codeset('gedit', codeset='UTF-8')
'''
gettext module will try to retrieve messages from /usr/share/locale by
default, otherwise you need to explicitly set it.
'''
gettext.bindtextdomain ('gedit', '/usr/share/locale')
_ = lambda msg: gettext.dgettext ('gedit', msg)
N_ = lambda msg: msg
print _("Save")

迷上LEGO

给儿子买了两个LEGO的小玩具车之后,对拼插玩具有了很大的兴趣。昨天给儿子买了一大盒COGO的拼插玩具(国内的品牌,便宜了不少,不过品质也相差不少)。一开始以为它像之前买的两个LEGO小车一般拼接很简单,结果打开包装就傻眼了,都是很碎的小片儿。拼第一个黄色悍马车,着实费了很大的力气。后来老婆一起帮忙,进度快了许多。后来发现,老婆比我还着迷,我本来想拼完两辆车就歇了,她却不辞辛苦把后面的几个造型都拼了出来。下面是我们忙碌了一晚上的劳动成果:

看看这些LEGO的杰作吧,真是令人叹为观止!

Drawing on the full screen of X Window

There are several ways to draw strokes on the full screen of X Window,

  1. Using the SHAPE extension, while it's very time consuming to calculate the bitmask when you draw complex curves. Not sure if libxosd works better.
  2. Using Composite overlay window, looks like a wonderful solution, but it maybe occupied by a compositing manager (like Compiz), so your painting might be corrupted when compiz redrawing a window. While you could still create a "always-on-top" window for compositing, which requires a window manager supports freedesktop's standards, refer to libaosd.
  3. Creating an off-screen pixmap for root window and painting on that, then using XCopyArea(3X11) to copy the result image to root with a "full-screen" GC (whose GCSubwindowMode is IncludeInferiors). If you want some funcy effects, use RENDER extension to create a Picture for root (with the attribute subwindow_mode as IncludeInferiors), then composite on it. The performance is good, and has no side-effects when working with a compositing manager.

To get the global mouse event, you could use XEVIE, though currently it may report some warnings like "Xlib: sequence lost (...) in reply type 0x6!", when catching pointer events. However it does not support multiple clients. A better option probably is to use RECORD extension. And last, using XGrabPointer(3X11) in some circumstances (like the right button is pressed for a while) to grab the mouse, so that the mouse movement would not affect the running apps on the screen.

P.S., as Alan pointed out in the comments, "You should not rely on XEvIE - it hasn't been maintained in several years, and has been removed by the X.Org community in the upcoming Xorg
server 1.6 release.
"

Hidden=true?

If user removed a startup item (like iiim) via gnome-session-properties(1), when the item is checked, a customized .desktop file would be saved in $HOME/.config/autostart, with both "X-GNOME-Autostart-enabled" and "Hidden" entries are "true". And on next login, the removed item would not be started by gnome-session(1).

The term "Hidden" is quite confusing, from the "Desktop Entry Specification" and "Desktop Application Autostart Specification" standards from freedesktop.org, we could see it actually means "Deleted",

Hidden should have been called Deleted. It means the user deleted (at his level) something that was present (at an upper level, e.g. in the system dirs)...

When the .desktop file has the Hidden key set to true, the .desktop file MUST be ignored...

Specify the init and fini routines for an object

/* On Solaris Platform */
#pragma init (fct[,fct])
#pragma fini (fct[,fct])
/* On Linux Platform */
void __attribute__ ((__constructor__)) fct (void){...}
void __attribute__ ((__destructor__))  fct (void){...}

As I tested, Gcc 4.4.x on Ubuntu only supports the later form. While on Solaris, either SunStudio or Gcc (only 3.4.3 is available currently) supports both of them.

While there is a little different between SunStudio and Gcc, in case we declared two functions (let's say f1, f2) with attribute __constructor__, the call sequence would be f1 then f2 with SunStudio, but f2 then f1 with Gcc. However, the call sequence for 'destructors' is just the same -- f1 then f2.