2008年1月27日 星期日

lxpanel 以新的樣貌現身

Standard
經過幾天的撰寫,終於將一點成果 Commit 到 SVN 上了。lxpanel 從今天起,已經可以支援背景圖和文字顏色﹝目前文字顏色只對 dclock plugin 有作用﹞的設定,我也畫了一張圖﹝background.png﹞當預設背景,讓視覺效果增進了不少。 :P




這次 new feature 已知的問題,是 systray 還無法使用背景圖,雖然已經將 eggtraymanager 換成 GNOME-Panel 的 na-tray-manager,卻仍然解決不了這問題﹝真的花了很多的時間﹞。對此,我做了一些調整,讓 systray 的四周留白,使 systray 彷彿嵌入 panel 一般。不過這樣做是暫時的,只讓 systray 不會這麼突兀而已,這問題日後會再來慢慢解決。


修改過後的 lxpanel configurator




下一階段的工作,就是開始移植 fnetdaemon 和 fvolume 成 lxpanel plugin 了。

相信 LxDE 一定會越來越完整,勉勵自己繼續努力吧!

2008年1月23日 星期三

Frexhwd 0.1 終於發佈

Standard
半夜睡不著覺,煩悶湧上心頭,於是玩弄了一下 Blog 的版面設定,然後整理近兩個月來的垃圾。將去年底『Frexhwd 嬌小的硬體偵側程式』所提到的成果打包,並上傳到 SourceForge。其中包括了已轉換好的驅動程式對應表﹝NVIDIA New/Legacy *.xinf 和 Linux Kernel 2.6.23.9 pcimap﹞。

Frexhwd Project:
https://sourceforge.net/projects/frexhwd/

仔細看,其實 Source Code 並不多,比較重要的 Code 在之前文章也有貼出來過,反而比較花時間的是要將 NVIDIA New/Legacy Supported List 從網站上的 HTML 轉換成 *.xinf。

在實際使用狀況上,使用 Frexhwd 替代某些 LiveCD 上的 discover 或 Kudzu 後,運作很正常,而且經過些許調整後,還能夠讓系統自動選擇正確的 NVIDIA Driver/Library。

2008年1月20日 星期日

寒假迎春,事事愉快

Standard
好不容易期末考結束,開始放寒假了。預料這個迎春假期會過得很充實,除了繼續維護和開發 LXDE 之外,日前也在 IRC 上瘋狂的隨口決定趁休假實作一個玩具『OS Kernel』。

關心 LXDE 的朋友們最近應該都發現到了,在專案網站上出現了一行大紅色的『The project is NOT dead!』,我也是在前兩天才發現的。PCMan 張貼了一份聲明,內容說他有太多雜務﹝畢竟他是未來準醫生﹞,無法專心在程式的開發上,所以才會導致 LXDE 遲遲沒有 new release;而在今年度他更是沒有閒暇,所以將會暫時告別一段時間。

其實從去年底開始,在 IRC #Dot 就不時在討論誰要接手 PCMan 所維護的『PCManFM』,也有人熱心的暫代 PCMan 去嘗試維護 PCManFM 的問題,不過都因為時間問題,無法幫上太多的忙,導致一直沒有完整的定案。

現在放了寒假,我開始有多一點的時間,或許能幫忙維護 PCMan 所遺留下來的專案。當然 LXDE 就更不用說了,之前的『桌面改進計劃』將會繼續進行,如果可以,希望讓 LXDE 能夠盡快有一個 new release。最後也希望對桌面改進有興趣的人可以一同參與。

至於在寒假實作『Toy OS Kernel』這個意外的計劃,我可能會在感到煩躁的時候才開始進行,用來舒解一下情緒。目標是打造一個不嚴肅的 kernel。雖然已經不是第一次接觸 OS Design,不過過去只是簡單完成實作,實在是沒有更深入去探討 OS Design 的變化和美妙,因此將會趁著這次有多一些的研究。

讓我們盡情享受這美好的假期吧!
Enjoy Vacation and Hacking!

2008年1月9日 星期三

Golden-Section Search 黃金比例搜尋法

Standard
依朋友們的要求,我實作了黃金比例搜尋法(Golden-Section Search) 的程式,用來尋找一個 f(x) 的最小值。這程式非常的簡短,是短短時間內寫出來的,所以並沒有考慮到效能、流程優化的部份,就像是 x 在某些狀況可以直接沿用到下次的 x1 或 x2,不需要將 x1、 x2 完全重新計算的這部份也是值得去探討的。

原始程式碼:

#include <stdio.h>
#include <math.h>

#define F(x) ((pow(x,2)/10)-2*sin(x))

void main()
{
int i, n;
double range_min = 0;
double range_max = 4;
double d, x1, x2;

printf("Number of lines:");
scanf("%d", &n);

printf("i xl f(xl) x2 f(x2) x1 f(x1) xu f(xu) d\n");
for (i=1;i<=n;i++) {
d = 0.61803*(range_max - range_min);
x1 = range_min + d;
x2 = range_max - d;
printf("%d %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f\n", i,
range_min, F(range_min),
x2, F(x2),
x1, F(x1),
range_max, F(range_max),
d);
if (F(x2)>F(x1)) { /* 取右邊 */
range_min = x2;
x2 = x1;
} else { /* 取左邊 */
range_max = x1;
x1 = x2;
}
}


後記

談到程式優化的話題雖扯遠了,但我們不可以忽略掉它,因為這是一個專業程式人員該時時省思的課題。程式優化的層面很廣,除了流程上的優化,更還有考慮到硬體結構的優化改進。最近就正在整理一些關於優化程式的議題:如何更有效率的運用 CPU 暫存器,運用更少的指令和時鐘(Clock)完成任務等。

更多從優化衍生出來的議題,如透過組合語言(Asembly)去了解 CPU 等硬體的運作,並了解 C 語言或各種 Low-level library 對應的 CPU 指令效能,都是很值得我們去研究的。所以,分析各種高階語言與 ASM、CPU command 的關係這部份,在有時間的時候我也會整理出來。

2008年1月7日 星期一

實作 ALSA 主音量控制

Standard
OSS 已經成為歷史,今天的 ALSA 幾乎成為了所有 Linux 的音效驅動的標準規格。兩者相較之下,ALSA 新增了太多數不清的專業功能和特色,也難怪玩具般的 OSS 會敗陣下來。對研發人員來說,從 OSS 過渡到 ALSA 的困擾,就是聲音控制程式的 sourcecode 複雜度變高了。

以下是操弄 ALSA Library 的簡單範例:
#include <stdio.h>
#include <alsa/asoundlib.h>

int main(void)
{
int unmute, chn;
int al, ar;
snd_mixer_t *mixer;
snd_mixer_elem_t *master_element;

snd_mixer_open(&mixer, 0);
snd_mixer_attach(mixer, "default");
snd_mixer_selem_register(mixer, NULL, NULL);
snd_mixer_load(mixer);

/* 取得第一個 element,也就是 Master */
master_element = snd_mixer_first_elem(mixer);
/* 設定音量的範圍 0 ~ 100 */
snd_mixer_selem_set_playback_volume_range(master_element, 0, 100);

/* 取得 Master 是否靜音 */
snd_mixer_selem_get_playback_switch(master_element, 0, &unmute);
if (unmute)
printf("Master is Unmute.\n");
else
printf("Master is Mute.\n");

/* 取得左右聲道的音量 */
snd_mixer_selem_get_playback_volume(master_element, SND_MIXER_SCHN_FRONT_LEFT, &al);
snd_mixer_selem_get_playback_volume(master_element, SND_MIXER_SCHN_FRONT_RIGHT, &ar);
/* 兩聲道相加除以二求平均音量 */
printf("Master volume is %d\n", (al + ar) >> 1);

/* 設定 Master 音量 */
snd_mixer_selem_set_playback_volume(master_element, SND_MIXER_SCHN_FRONT_LEFT, 99);
snd_mixer_selem_set_playback_volume(master_element, SND_MIXER_SCHN_FRONT_RIGHT, 99);

/* 將 Master 切換為靜音 */
for (chn=0;chn<=SND_MIXER_SCHN_LAST;chn++) {
snd_mixer_selem_set_playback_switch(master_element, chn, 0);
}

/* 將 Master 切換為非靜音 */
for (chn=0;chn<=SND_MIXER_SCHN_LAST;chn++) {
snd_mixer_selem_set_playback_switch(master_element, chn, 1);
}
return 0;
}


比起 OSS 存取 /dev/mixer 的做法,ALSA 的確是複雜多了,但是仔細深入後會發現,這些複雜都是必要且有跡可循。

2008年1月6日 星期日

[lxpanel] 重新設計的 netstatus 和 volume plugin

Standard
關於 Linux Desktop 的改良計劃如期進展中,現在打算從 LxDE 的 lxpanel 開始著手。在使用和觀察後,發現 lxpanel 在 plugin 的部分其實有些問題,其中一個就是所有 plugin 和 lxpanel 共用 process 所產生的後遺症:假如其中一個 plugin 出問題,將可能導致整個 panel crash。除此之外,原先 volume plugin 也是需要重新設計的,因為原本的控制是採用 OSS 的方式,與目前主流的 ALSA 不一樣,在某些晶片上甚至會當掉。

為了怕一次改太多改壞掉﹝雖然 jserv 叫我隨意破壞 XD﹞,在重新撰寫 plugin 的工作還沒完成之前,暫時將新寫的 plugin 獨立成單一程式,不會納入 lxpanel 中。目前新設計的 plugins 包括了 fnetdaemon 和 fvolume﹝暫時取的代號﹞,用來取代 lxpanel 原有的 netstatus 與 volume plugin,以下是 half screenshot:



為什麼說是 half screenshot ?因為這張圖有一半是合成的,除了 systray 上的圖示之外,黑色的 panel 是合成上去的﹝笑﹞。當然背景圖已經畫好﹝不然怎麼合成?﹞,就只差改寫 lxpanel 部份程式,拭目以待吧!

2008年1月4日 星期五

取得網路裝置(NETDEVICE)的系統訊息

Standard
之前提到正在開發的 Network Status Daemon ,其監控 netdevice 的部份已經完成,從 System Tray 上可以看到現在的網路傳送接收狀態、是否有插上網路線、IP位置等等。其中除了讀取/proc/net/dev 來取得封包流量,還有許多針對 netdevice 的 ioctl() 實作。

這是一個檢查網路裝置是否已經被 ifconfig bring up 的例子:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>

void main(void)
{
struct ifreq ifr;
int sockfd;

sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&ifr, sizeof(ifr));
strcpy(ifr.ifr_name, "eth0");

ioctl(sockfd, SIOCGIFFLAGS, &ifr);
/*
ifr_flags 的各項旗標和說明:
IFF_UP 裝置正在運作
IFF_BROADCAST 有效的廣播位址
IFF_DEBUG Debug 標誌
IFF_LOOPBACK 這是 Loopback 裝置
IFF_POINTOPOINT 這是點到點的網路裝置介面
IFF_RUNNING 資源已分配
IFF_NOARP 無arp協議,沒有設置第二層目的地址
IFF_PROMISC 介面為雜湊(promiscuous)模式
IFF_NOTRAILERS 避免使用 trailer
IFF_ALLMULTI 接收所有群組廣播(multicast)封包資料
IFF_MASTER 主負載平衡群(bundle)
IFF_SLAVE 從負載平衡群(bundle)
IFF_MULTICAST 支持群組廣播(multicast)
IFF_PORTSEL 可以通過 ifmap 選擇 media 類型
IFF_AUTOMEDIA 自動選擇 media
IFF_DYNAMIC 裝置介面關閉時丟棄地址
*/
if (ifr.ifr_flags & IFF_UP) {
printf("eth0 is up!");
}
close(sockfd);
}


結構 struct ifreq 的定義如下:
struct ifreq
{
char ifr_name[IFNAMSIZ]; /* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char * ifr_data;
};
}


ioctl() 可以操作的標誌如下:
SIOCGIFNAME
SIOCGIFINDEX
SIOCGIFFLAGS, SIOCSIFFLAGS
SIOCGIFMETRIC, SIOCSIFMETRIC
SIOCGIFMTU, SIOCSIFMTU
SIOCGIFHWADDR, SIOCSIFHWADDR
SIOCSIFHWBROADCAST
SIOCGIFMAP, SIOCSIFMAP
SIOCADDMULTI, SIOCDELMULTI
SIOCGIFTXQLEN, SIOCSIFTXQLEN
SIOCSIFNAME
SIOCGIFCONF


詳細說明可參考 Manpage of NETDEVICE 或是從這取得相關說明:
http://www.linuxinfor.com/english/man7/netdevice.html

2008年1月2日 星期三

使用 GtkStatusIcon 實作 System Tray

Standard
孤陋寡聞的我,一直都還在用 libegg EggTrayIcon 去撰寫 System Tray。由於過去寫的程式通常只是顯示一個 Icon 在 System Tray Bar 上,所以長久以來也沒有碰到什麼問題。直到這兩天在設計 Network Status 的 Display on System Tray時,才發現 EggTrayIcon 缺少一些重要的功能。查明後,才知道必須使用 libegg 的 EggStatusIcon 等其他 Functions 去實作那些功能。

得到答案本該是很開心的,但非常不幸的,同時也在 libegg 的 CVS 裡,得知了 libegg 已停止開發的消息﹝消息還是 2006 年的!﹞。文中說到了因為 Gtk-2.10 以後,規範了一個標準的 GtkStatusIcon Widget 去實作 System Tray,導致 libegg 便不再有存在的必要性,因此不再繼續維護下去。

關於 GtkStatusIcon 的詳細說明文件,可以在【 GNOME Documentation Libaray -- GTK+ Reference Manual 】找到,有興趣的人可以去參考參考。

就單純的 Hello World Program 來說,用 GtkStatusIcon Widget 去實作 System Tray 非常容易,下面是一個簡單的範例:
#include <gtk/gtk.h>

int main(int argc, char **argv) {
GtkStatusIcon *tray_icon;

gtk_init(&argc, &argv);
tray_icon = gtk_status_icon_new();
gtk_status_icon_set_from_file(tray_icon, "/tmp/trayicon.png");
gtk_status_icon_set_tooltip(tray_icon, "Hello Tray Icon!!");
gtk_status_icon_set_visible(tray_icon, TRUE);
gtk_main();

return 0;
}

另外順便也展示一下最近正在嘗試撰寫的 Network Status Daemon,其中的 System Tray 的實作就是使用 GtkStatusIcon 達成的 :P計劃把網路裝置的設定介面和 Wireless 的 Scanning APs/Select AP 等功能做一次大整合,可能會參考 MS Windows 裡 Network Device Systray 的行為來設計。因為目前為止,覺得 MS 在這部份的 Design 還算不錯,相較 GNOME 、 KDE 等環境之下,G or K 的 Design 就很令人畏懼 :(

註:不知道 ICON 的感覺還行不行?我畫了個半天呢!大家給我一點意見吧!Orz

2008年1月1日 星期二

本年度新的目標和展望

Standard
首先,讓我們開心迎接 2008 年的到來。個人本年度的目標和展望如下:
  1. 更進一步研究 Linux Kernel 的相關細節和技術
  2. Hacking X11 及相關延伸規範設計
  3. 實作和閱讀更多 Operating System Kernel 實驗想法
  4. 充實更多 3D 及影像處理方面的技術
  5. 嚴苛的挑剔目前 Linux 桌面環境各種對於一般用戶在使用上的缺點,並擬訂計劃改進修正。
  6. 計劃性的惡搞
  7. 更少的睡眠,更多的 Hacking :P

今年度大致的目標就這樣了,一時也想不到太多。﹝其實是怕訂太多做不到﹞﹝笑﹞

關於改進桌面環境的部份,將以使用上的感覺為第一優先考量,所以無論原程式技術或架構有多好,只要帶來一般使用者的不便,就當做是爛東西改造或計劃性重寫。﹝以我周遭的眾多電腦『天才』為試驗白老鼠XD﹞