電影流水帳(2009/5/1~2009/5/11)

要報稅了…最近看薪資單時,發現公司沒幫我預扣所得稅了…

  • 愛情故事(IMDB, Wikipedia)。很清純、很淡的故事,情節有點老套,三個同窗互有情愫的故事,最後以阿Ling掛掉,Rex 試著與留學四年回來的小臻交往作終。女主角江若琳文詠珊都很正,裡面還有看到外婆鄭佩佩,猛然想起她在唐伯虎點秋香裡的演出…,對了,片裡的江若琳有些神似Janet 謝怡芬
  • Bella(IMDB, Wikipedia),中譯:美麗.人生。帶有淡淡悲傷的故事,是足球明星的男主角因為沒注意,造成小女孩死掉,後來入獄,出獄之後為哥哥當餐廳廚師。某天,餐廳裡的某個女侍遲到,被當餐廳經理的哥哥開除,男主角想幫助她,於是展開這段故事,最後結局有些隱誨,但看得出來是女侍將孩子生了下來交由男主角撫養,並立下未來見面的約定。

Linux I2C 與 AD71471

AD71471 的 Device address 是 0x58,Linux driver 在處理這個時,其實會自行左移一位,因此,在 I2C_SLAVE_FORCE 的 ioctl 裡,應該是要傳 0x2c。這邊因為我暈頭,把 0x58>>1 算成 0x4c,導致我搞了好一陣子,直到 M 同事指正以後,才弄對。

再來,AD71471 在做讀寫時,Register address 與 data 都是 2 bytes,而 i2ctools 裡,處理 Register address 都只傳 1 byte(I2C_SMBUS),因此不適用在 AD71471 上。我把 Linux kernel i2c-core.c 裡的 code 翻出來改寫,改用 I2C_RDWR 來處理:

bool Write( uint16_t address, uint16_t value ) {
int res=0;
struct i2c_rdwr_ioctl_data msg_rdwr;
char msgbuf0[I2C_SMBUS_BLOCK_MAX+4];
char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
struct i2c_msg msg[1] = { { _address, 0, 4, msgbuf0 } };
uint8_t* pAddr = (uint8_t*)&address;
uint8_t* pValue = (uint8_t*)&value;
msg_rdwr.msgs = &msg[0];
msg_rdwr.nmsgs = 1; // write // read = 2
// 因為 little endian,所以要作調整
msgbuf0[0] = *(pAddr+1);
msgbuf0[1] = *(pAddr+0);
msgbuf0[2] = *(pValue+1); // (1)
msgbuf0[3] = *(pValue+0);
res = ioctl( _file, I2C_RDWR, &msg_rdwr );
usleep(10000);
return true;
}
bool Read( uint16_t address, uint16_t& data ) {
int res=0;
struct i2c_rdwr_ioctl_data msg_rdwr;
char msgbuf0[I2C_SMBUS_BLOCK_MAX+2];
char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]={0};
struct i2c_msg msg[2] = { { _address, 0, 2, msgbuf0 },
{ _address, I2C_M_RD, 2, msgbuf1 }
};
uint8_t* pAddr = (uint8_t*)&address;
msg_rdwr.msgs = &msg[0];
msg_rdwr.nmsgs = 1; // read = 2
// 因為 little endian,所以要作調整
msgbuf0[0] = *(pAddr+1);
msgbuf0[1] = *(pAddr+0);
res = ioctl( _file, I2C_RDWR, &msg_rdwr );
usleep(10000);
msg_rdwr.msgs = &msg[1];
msg_rdwr.nmsgs = 1; // read = 2
res = ioctl( _file, I2C_RDWR, &msg_rdwr ); #ifdef DEBUG
data = msgbuf1[0] | (msgbuf1[1] << 8);
return true;
}
int main( int argc, char* argv[] )
{
int data=0;
Read( 0x17, data );
printf("data=%d\n", data );
// 這邊其實不好,實際上寫 0x0052會比較清楚,這邊必須寫 0x5200,因為我在 Write() 裡有作對調,參看(1)
Write( 0x00, 0x5200 );
}

GtkDrawingArea 與 gtk_widget_set_events()

GtkDrawingArea 預設是不收 button_press_event 跟 key_press_event 的,所以要使用 gtk_widget_set_events() 告訴 GtkDrawingArea 要接收才行。

這個,我是去 Google Code Search 找來的,雖然 devhelp 可以查指令,但沒有範例,還是很難猜到怎麼用。

#include <gdk/gdkkeysyms.h> // 定義按鍵值的 header
static gboolean press_event( GtkWidget* widget, GdkEventButton* event, gpointer data )
{
if( debug )
g_print("press_event: x=%f y=%f button=%d\n", event->x, event->y, event->button );
if( event->button==1 )  { // left
}
}
static gboolean key_event( GtkWidget* widget, GdkEventKey* event )
{
if( debug )
g_print( "event->keyval=%d event->state=%d\n", event->keyval, event->state );
switch (event->keyval) {
// 省略...
}
return TRUE;
}
int main( int argc, char* argv[] )
{
// 省略一萬行...
g_signal_connect( drawing_area, "button_press_event", G_CALLBACK( press_event ), NULL );
g_signal_connect( drawing_area, "key_press_event", G_CALLBACK( key_event ), NULL );
// 要接收 button_press_event 跟 key_press_event 喔~
gtk_widget_set_events( drawing_area, gtk_widget_get_events(drawing_area) | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK );
// 省略兩萬行...
}

gtk 載入並顯示圖片

實際上是用 GDK+GtkDrawingArea 來畫,所以在下面的程式片斷,你會看到我宣告了 GtkDrawingArea 並且實作了 GtkDrawingArea 的 expose 事件。
GDK 支援的圖片格式很多,常見的 jpg、png、bmp 都沒問題。

static gboolean expose_event( GtkWidget* widget, GdkEventExpose* event, gpointer data )
{
GError* error=NULL;
int width=widget->allocation.width, height=widget->allocation.height;
GdkPixbuf* buf=gdk_pixbuf_new_from_file_at_scale( "your_photo.jpg", &error );
if( buf==NULL )
g_print("load fail.\n" );
else
{
bufWidth = gdk_pixbuf_get_width( buf );
bufHeight = gdk_pixbuf_get_height( buf );
gdk_draw_pixbuf( widget->window, NULL, buf, 0, 0, 0, 0,
(width>bufWidth?bufWidth:width), (height>bufHeight?bufHeight:height),
GDK_RGB_DITHER_NORMAL, 0, 0 );
g_object_unref( buf );
}
}
int main( int argc, char* argv[])
{
GtkWidget* drawing_area=NULL;
// 省略一萬行
g_signal_connect( G_OBJECT(drawing_area), "expose_event", G_CALLBACK( expose_event ), NULL );
// 再省略兩萬行...
}

電影流水帳(2009/4/25~2009/4/30)

進度緩慢,今年搞不好沒機會達到百片…

  • Bolt(IMDB, Wikipedia),中譯:雷霆戰狗。很棒的故事,你可以參考朱大的文章,大家都需要熱情,才能勇敢的繼續走下去!!
  • Taken(IMDB, Wikipedia),中譯:即刻救援。很熱血的片,節奏緊湊,看到最後在船上浴血奮戰時,差點停止呼吸,很擔心導演來個爸爸救到人結果卻死在女兒懷裡的悲傷場面~不過最後並沒有這麼灑狗血。不過出外旅行的時候真的要小心,不要笨笨的把自己底細通通都說出來,免得遭來橫禍,片中女兒的朋友就是這樣子,才被決定為下手目標的。

gdb 連到遠端 gdbserver 的指令

遠端先把 gdbserver 啟動,並指定 ip:port,例如:gdbserver 192.168.11.1:10000 hello
那麼本地端在啟動 gdb 以後,就可以用以下指令連到遠端:target remote 192.168.11.1:10000
再以 symbol-file 載入有除錯資訊的檔案,就可以進行 debug 了。

電影流水帳(2009/4/21~2009/4/24)

連這篇看完的一起算,截至目前為止,已經看了 23 片…

  • 公主復仇記(IMDB)。故事前半稍嫌沉悶,從偷鑰匙的冒險開始慢慢走向高潮,最後蠻令人跌破眼鏡的,的確有止嗝之效。兩個女人才是主角,吳念祖在這部戲裡只是個配角。
  • 神槍手。我放棄了,用 Google 找不到像樣的網址可以連結。故事本身來說是很不錯的,但是我覺得有幾點不好,一個是為什麼要舖方克明老婆的梗出來,卻又沒有任何交代??再者就是最後的大亂鬥,為什麼警方的高層會腦殘地讓整隊人去送死,然後草草結束??後半的整體感覺是破碎的,缺乏一致性。但對凌靖(黃曉明)的這塊,我覺得就描寫的不錯~他根本就是第一男主角啊~

ecryptfsd

ecryptfs-utils 裡的 ecryptfsd 可以透過 netlink 或 misc 方式與 kernel 的 ecryptfs module 溝通,Ubuntu 有修改過 kernel 的 ecryptfs ,讓 ecryptfsd 以 misc 的方式溝通。
而我,就卡在這裡搞了好久,因為我始終用 kernel 的預設值,也就是 netlink 的方式。
照理來說,netlink 應該也是可以才對,只是在 ecryptfsd 裡有段 code(嚴格來說應該是 libecryptfs.so),在以 sendto 送出封包以後,檢查回傳值,如果大於 0 ,就當作錯誤。你可以查一下 sendto 函式的說明,裡面清楚地寫了,當傳送成功,會回傳 sendto() 所送出的 byte 數。ecryptfsd 以 sendto 送出了 16 bytes,收也收到了 16 bytes,這樣應該是要當作成功,但程式裡卻視為失敗。
我不知道修正這裡以後還會遇到什麼問題,所以我決定很鴕鳥地去改用 ubuntu 的 kernel …

電影流水帳(2009/3/28~2009/4/20)

這幾年好萊塢都在努力尋找新題材,除了重拍以外,還有找漫畫跟電玩的故事。不知道Dragonball好不好看…

  • Dan in Real Life(IMDB, Wikipedia),中譯:老爸行不行。由Steve CarellJuliette Binoche主演,故事的前半其實很有趣,男主角不小心邂逅的 100% 女人,居然是弟弟要帶回家跟家族認識的女朋友,於是發生了很多衝突,到這邊,我都覺得很不錯,只是到最後來了一個快樂的 ending,顯得有點突兀。
  • The Spirit(IMDB, Wikipedia),中譯:閃靈俠。視覺風格跟我沒緣看的Sin City很相似,都是以強烈的色彩來凸顯劇情,看過 IMDB,才知道是同一個導演拍的。故事還可以。Scarlett Johansson扮演的角色跟怪怪的主角-The spirit 尤其有趣~而Eva Mendes在片裡把她的好身材完全展現,超正~
  • Fast & Furious 4(IMDB, Wikipedia),中譯:玩命關頭4。女主角很正,但故事就乏善可陳…沒什麼好說的。
  • INKHEART(IMDB, Wikipedia),中譯:墨水心。相較於哈利波特系列電影,差了些,或許原著小說會比較精彩,但我沒看過小說,無從比較起。台灣有出中譯本,而且還有好幾個版本…等明年去圖書館借…
  • The day The earth stood still(IMDB, Wikipedia),中譯:當地球停止轉動。這部片子其實是重拍 1951 年的版本:The Day the Earth Stood Still。女主角是很正的Jennifer Connelly,她是1970 年生的…只比我大五歲…而且還是童星,7歲就開始演戲了…;而男主角Keanu Reeves實在是很適合這種角色…裡面的小男孩則是 Will Smith 的兒子,我看了好一會才認出來。嚴格來說,我覺得拍得並不好,不過特效倒是還可以。5x分的時候有一段以普通話(漢語)的對話,很令人發噱~。

直接設定密碼免提示輸入

用 passwd 設定密碼是免不了要回答提示問題的,有方法可以省掉嗎?
如果可以省掉,在大量設定密碼的情況下會很方便。

方法說穿了很簡單,先用 mkpasswd 產生密碼,再用 usermod 來變更使用者密碼。
以下節錄自 call useradd and passwd through no prompt script – LinuxQuestions.org

#!/bin/bash
## Set a default password and perform a password reset
l_user=$1
if [ "$l_user" != "" ]
then
l_password="Reset"
l_encrypted_pass=$(mkpasswd -s --hash=md5 ${l_password})
echo "/usr/sbin/usermod -p ${l_encrypted_pass} ${l_user}"
fi

感恩啦!本來已經想用 sed/awk 去硬改 passwd/shadow 檔案了說…