Month: May 2010

Xfce: lightweight desktop environment for unix-like operating systems

Posted by – May 31, 2010


Refers to:

Xfce is a lightweight desktop environment for unix-like operating systems. It aims to be fast and lightweight, while still being visually appealing and user friendly.

Xfce embodies the traditional UNIX philosophy of modularity and re-usability. It consists of a number of components that provide the full functionality one can expect of a modern desktop environment. They are packaged separately and you can pick among the available packages to create the optimal personal working environment.

Another priority of Xfce is adhereance to standards, specifically those defined at

Xfce can be installed on several UNIX platforms. It is known to compile on Linux, NetBSD, FreeBSD, OpenBSD, Solaris, Cygwin and MacOS X, on x86, PPC, Sparc, Alpha…

The “Lightweight X11 Desktop Environment” is an extremely fast-performing and energy-saving desktop environment. Maintained by an international community of developers, it comes with a beautiful interface, multi-language support, standard keyboard short cuts and additional features like tabbed file browsing. LXDE uses less CPU and less RAM than other environments. It is especially designed for cloud computers with low hardware specifications, such as, netbooks, mobile devices (e.g. MIDs) or older computers. LXDE can be installed with many Linux distributions including Ubuntu, Debian and Fedora. It is the standard for Knoppix and lubuntu. LXDE also runs with OpenSolaris and BSD. LXDE provides a fast desktop experience; connecting easily with applications in the cloud. LXDE supports a wealth of programs that can be installed locally with Linux systems. The source code of LXDE is licensed partly under the terms of the the General Public License and partly under the LGPL.


Posted by – May 28, 2010

Refers to:

What is FreeImage?

FreeImage is an Open Source library project for developers who would like to support popular graphics image formats like PNG, BMP, JPEG, TIFF and others as needed by today’s multimedia applications. FreeImage is easy to use, fast, multithreading safe, compatible with all 32-bit versions of Windows, and cross-platform (works both with Linux and Mac OS X).

Thanks to it’s ANSI C interface, FreeImage is usable in many languages including C, C++, VB, C#, Delphi, Java and also in common scripting languages such as Perl, Python, PHP, TCL or Ruby.

The library comes in two versions: a binary DLL distribution that can be linked against any WIN32 C/C++ compiler and a source distribution. Workspace files for Microsoft VS.Net 2003 and VS.Net 2005 are provided, as well as makefiles for Linux and Mac OS X.

From january 2000 to july 2002, FreeImage was designed and mainly developed by Floris van den Berg. FreeImage is now maintained by Hervé Drolon.

FSF: Thanks for supporting free software!

Posted by – May 27, 2010

Thanks for supporting free software!

Support freedom

xpi packaging

Posted by – May 25, 2010

Referts to:如何製作_Firefox_擴充套件#.E6.92.B0.E5.AF.AB.E6.93.B4.E5.85.85.E5.A5.

Gnome Nanny, a Parental Control System for Linux

Posted by – May 25, 2010

Gnome Nanny, a Parental Control System for Linux

Refers to:

nanny logo

I am not in favour of monitored or filtered Internet at all. I love Internet the way it is and I hate if someone tries to censor it. But we have to admit that there is a lot of bad stuff on the Internet that you definitely don’t want little kids to come across. Gnome Nanny is a parental control system build for this purpose. Not just the websites, it can also be used to monitor and control the time spent on web or chatting.


  • You can easily control what the kids/users are doing on the computer.
  • How long a user can be using the compuer, browse the web, email and instant message.
  • You can decide the time of the day you want them to do these things.
  • You can even filter out the web pages seen by each of the user by blocking undesirable websites.
  • Its really easy to understand and configure.

The most recent version of Nanny available is 2.29.2. No stable version has been released yet.

Download and Install the Latest version of Nanny in Ubuntu

In order to install the latest development release in Ubuntu, you will have to install it using the ppa. You can find the PPA archive of Nanny here. Follow the instruction in this howto to install nanny in Ubuntu from the PPA. In case of any trouble, leave a comment.

Other distro users may install the source packages from their download page and give it a try.

After installation you can find it at System -> Administration -> Parental Control.

How to Configure Nanny

Understanding the working of Nanny is really easy. Its developers have worked pretty well to improve its usability. In the first glance, you will easily understand how to use it. You can find it in System -> Administration -> Parental control.

With these bars(click them), you can select which part of the day you want a particular service to be active. Different services are mentioned in separate tabs. Just check the option above to activate any option.

Nanny’s Web Content Filtering System

If you want to control the websites that can be accessed you can easily do that by maintaining lists of allowed and blocked sites. Check the enable web filtering box in the web browser tab and click configure.

You can even download the list of blacklisted websites from internet and ofcouse manual addition is available.

Limitations of Nanny

Nanny is a pretty good software and probably the only Parental control system for Linux I know. But it connects the tasks with the respective applicaitons e.g. pidgin with chatting, thunderbird with emails and browser with web surfing. This seems logical but now a days each of these activities are possible on the browser. You can’t expect a 10-12 year old kid to use a mail client . There are tons of social networking sites out there that can keep him “busy”. Although my point seems a little vague here because you can manage and control websites the user can access using Nanny’s web content filtering system.

Another thing I noticed was the applists mentioned in /etc/nanny/applists. It is probably the list of applicaitons supported by Nanny. As of now, or as mentioned in my list, it supports only 3 browsers epiphany, firefox and konqueror. Since, browsing is the most important thing to be censored and monitored here, Nanny should add support for more browsers.

Input Method Framework(输入方法框架)

Posted by – May 21, 2010

Moblin项目 — 输入方法框架:
Refers to:


本项目旨在向 Clutter 提供一个 Input Method Context Framework ,借助它可以扩展现有的输入方法以支持 moblin2 上的 Clutter 。



l  一个 clutter-imcontext 库,用于向Clutter添加 IMContext 框架

l  SCIM桥的一个客户端模块,用于在 Clutter 应用程序中支持SCIM

l  针对 scim-bridge 和 scim- panel的功能增强

l  一个针对IBus的客户端模块,用于在 Clutter 应用程序中启用 IBus

l  一个针对 IBus 的新面板,用于使用虚拟键盘进行输入


目前, 上主要有两种相关的源代码git树:

l  ClutterIMContext:

它是来自 GtkIMContext 的一个端口,具有一些功能增强,比如:自动显示/隐藏cb。还将不断向其中加入更多功能。

l  scim-panel-vkb-gtk:

此包向scim提供另一个 gtk面板以及一个安装模块,以选择要使用的面板。此包的主要目标是向一个面板提供嵌入带有原始输入方法UI的虚拟键盘的能力。因此,不具备硬件键盘的 MID类设备可以通过VKB轻松地使用输入方法。

l  scim-bridge

为了支持 ClutterIMContext ,还为 scim-bridge 编写了一个客户端模块。目前,用于 scim-bridge 的补丁仍然在 Moblin2 repo 中维护,而在单独的git树中找不到该补丁。

l  ibus-client-clutter:

这是为 IBus 编写的一个客户端模块。您可以查看我们的文档,从中找到关于在 Moblin2 上使用 IBus 的更多细节。


要获得关于在 Moblin2 上使用输入方法和如何通过输入方法来支持 Clutter 应用程序的更多信息,请查看我们的文档。


由于 SCIM 现在缺乏维护,本项目的未来开发工作将逐渐把重点转移到 IBus 支持上。

scim 的演示屏幕截图

下面的屏幕截图演示了在嵌入了SCIM和 Matchbox-Keyboard 的情况下,在应用程序中输入文本的情形。




Posted by – May 18, 2010

Refers to:


Posted by – May 18, 2010


Refers to:

Qt程序是事件驱动的, 程序的每个动作都是由幕后某个事件所触发. Qt事件的类型很多, 常见的qt的事件如下:
键盘事件: 按键按下和松开.
鼠标事件: 鼠标移动,鼠标按键的按下和松开.
拖放事件: 用鼠标进行拖放.
滚轮事件: 鼠标滚轮滚动.
绘屏事件: 重绘屏幕的某些部分.
定时事件: 定时器到时.
焦点事件: 键盘焦点移动.
进入和离开事件: 鼠标移入widget之内,或是移出.
移动事件: widget的位置改变.
大小改变事件: widget的大小改变.
显示和隐藏事件: widget显示和隐藏.
窗口事件: 窗口是否为当前窗口.


Qt 的事件和Qt中的signal不一样. 后者通常用来”使用”widget, 而前者用来”实现” widget. 比如一个按钮, 我们使用这个按钮的时候, 我们只关心他clicked()的signal, 至于这个按钮如何接收处理鼠标事件,再发射这个信号,我们是不用关心的. 但是如果我们要重载一个按钮的时候,我们就要面对event了. 比如我们可以改变它的行为,在鼠标按键按下的时候(mouse press event) 就触发clicked()的signal而不是通常在释放的( mouse release event)时候.

2. 事件产生和处理流程

2.1 事件的产生

一种是系统产生的;通常是window system把从系统得到的消息,比如鼠标按键,键盘按键等, 放入系统的消息队列中. Qt事件循环的时候读取这些事件,转化为QEvent,再依次处理.

一种是由Qt应用程序程序自身产生的.程序产生事件有两种方式, 一种是调用QApplication::postEvent(). 例如QWidget::update()函数,当需要重新绘制屏幕时,程序调用update()函数,new出来一个paintEvent,调用 QApplication::postEvent(),将其放入Qt的消息队列中,等待依次被处理. 另一种方式是调用sendEvent()函数. 这时候事件不会放入队列, 而是直接被派发和处理, QWidget::repaint()函数用的就是这种方式.

// 自定义事件的时候讲述: 需要注意的时, 这两个函数的使用方法不大一样, 一个是new, 一个是….

2.2 事件的调度
两种调度方式,一种是同步的, 一种是异步.

Qt的事件循环是异步的,当调用QApplication::exec()时,就进入了事件循环. 该循环可以简化的描述为如下的代码:

while ( !app_exit_loop )
while( !postedEvents ) { processPostedEvents() }
while( !qwsEvnts ){ qwsProcessEvents();   }
while( !postedEvents ) { processPostedEvents() }


先处理Qt事件队列中的事件, 直至为空. 再处理系统消息队列中的消息, 直至为空, 在处理系统消息的时候会产生新的Qt事件, 需要对其再次进行处理.

调用QApplication::sendEvent的时候, 消息会立即被处理,是同步的. 实际上QApplication::sendEvent()是通过调用QApplication::notify(), 直接进入了事件的派发和处理环节.

2.3 事件的派发和处理
首先说明Qt中事件过滤器的概念. 事件过滤器是Qt中一个独特的事件处理机制, 功能强大而且使用起来灵活方便. 通过它, 可以让一个对象侦听拦截另外一个对象的事件. 事件过滤器是这样实现的: 在所有Qt对象的基类: QObject中有一个类型为QObjectList的成员变量,名字为eventFilters,当某个QObjec (qobjA)给另一个QObject (qobjB)安装了事件过滤器之后, qobjB会把qobjA的指针保存在eventFilters中. 在qobjB处理事件之前,会先去检查eventFilters列表, 如果非空, 就先调用列表中对象的eventFilter()函数. 一个对象可以给多个对象安装过滤器. 同样, 一个对象能同时被安装多个过滤器, 在事件到达之后, 这些过滤器以安装次序的反序被调用. 事件过滤器函数( eventFilter() ) 返回值是bool型, 如果返回true, 则表示该事件已经被处理完毕, Qt将直接返回, 进行下一事件的处理; 如果返回false, 事件将接着被送往剩下的事件过滤器或是目标对象进行处理.

Qt中,事件的派发是从 QApplication::notify() 开始的, 因为QAppliction也是继承自QObject, 所以先检查QAppliation对象, 如果有事件过滤器安装在qApp上, 先调用这些事件过滤器. 接下来QApplication::notify() 会过滤或合并一些事件(比如失效widget的鼠标事件会被过滤掉, 而同一区域重复的绘图事件会被合并). 之后,事件被送到reciver::event() 处理.

同样, 在reciver::event()中, 先检查有无事件过滤器安装在reciever上. 若有, 则调用之. 接下来,根据QEvent的类型, 调用相应的特定事件处理函数. 一些常见的事件都有特定事件处理函数, 比如:mousePressEvent(), focusOutEvent(), resizeEvent(), paintEvent(), resizeEvent()等等. 在实际应用中, 经常需要重载这些特定事件处理函数在处理事件. 但对于那些不常见的事件, 是没有相对应的特定事件处理函数的. 如果要处理这些事件, 就需要使用别的办法, 比如重载event() 函数, 或是安装事件过滤器.


2.4 事件的转发

对于某些类别的事件, 如果在整个事件的派发过程结束后还没有被处理, 那么这个事件将会向上转发给它的父widget, 直到最顶层窗口. 如图所示, 事件最先发送给QCheckBox, 如果QCheckBox没有处理, 那么由QGroupBox接着处理, 如果QGroupBox没有处理, 再送到QDialog, 因为QDialog已经是最顶层widget, 所以如果QDialog不处理, QEvent将停止转发.       如何判断一个事件是否被处理了呢? Qt中和事件相关的函数通过两种方式相互通信. QApplication::notify(), QObject::eventFilter(), QObject::event() 通过返回bool值来表示是否已处理. “真”表示已经处理, “假”表示事件需要继续传递. 另一种是调用QEvent::ignore() 或 QEvent::accept() 对事件进行标识. 这种方式只用于event() 函数和特定事件处理函数之间的沟通. 而且只有用在某些类别事件上是有意义的, 这些事件就是上面提到的那些会被转发的事件, 包括: 鼠标, 滚轮, 按键等事件.
3. 实际运用

根据对Qt事件机制的分析, 我们可以得到5种级别的事件过滤,处理办法. 以功能从弱到强, 排列如下:

3.1 重载特定事件处理函数.
最常见的事件处理办法就是重载象mousePressEvent(), keyPressEvent(), paintEvent() 这样的特定事件处理函数. 以按键事件为例, 一个典型的处理函数如下:

void imageView::keyPressEvent(QKeyEvent * event)
switch (event->key()) {
case Key_Plus:
case Key_Minus:
case Key_Left:
// …

通过重载event()函数,我们可以在事件被特定的事件处理函数处理之前(象keyPressEvent())处理它. 比如, 当我们想改变tab键的默认动作时,一般要重载这个函数. 在处理一些不常见的事件(比如:LayoutDirectionChange)时,evnet()也很有用,因为这些函数没有相应的特定事件处理函数. 当我们重载event()函数时, 需要调用父类的event()函数来处理我们不需要处理或是不清楚如何处理的事件.

下面这个例子演示了如何重载event()函数, 改变Tab键的默认动作: (默认的是键盘焦点移动到下一个控件上. )

bool CodeEditor::event(QEvent * event)
if (event->type() == QEvent::KeyPress)
QKeyEvent *keyEvent = (QKeyEvent *) event;
if (keyEvent->key() == Key_Tab)
return true;
return QWidget::event(event);

3.3 在Qt对象上安装事件过滤器.

安装事件过滤器有两个步骤: (假设要用A来监视过滤B的事件)
首先调用B的installEventFilter( const QOject *obj ), 以A的指针作为参数. 这样所有发往B的事件都将先由A的eventFilter()处理.
然后, A要重载QObject::eventFilter()函数, 在eventFilter() 中书写对事件进行处理的代码.
用这种方法改写上面的例子: (假设我们将CodeEditor 放在MainWidget中)

CodeEditor * ce = new CodeEditor( this, “code editor”);
ce->installEventFilter( this );

bool MainWidget::eventFilter( QOject * target , QEvent * event )
if( target == ce )
if( event->type() == QEvent::KeyPress )
QKeyEvent *ke = (QKeyEvent *) event;
if( ke->key() == Key_Tab )
return true;
return false;

3.4 给QAppliction对象安装事件过滤器.
一旦我们给qApp(每个程序中唯一的QApplication对象)装上过滤器,那么所有的事件在发往任何其他的过滤器时,都要先经过当前这个 eventFilter(). 在debug的时候,这个办法就非常有用, 也常常被用来处理失效了的widget的鼠标事件,通常这些事件会被QApplication::notify()丢掉. ( 在QApplication::notify() 中, 是先调用qApp的过滤器, 再对事件进行分析, 以决定是否合并或丢弃)

3.5 继承QApplication类,并重载notify()函数.

Qt是用QApplication::notify()函数来分发事件的.想要在任何事件过滤器查看任何事件之前先得到这些事件,重载这个函数是唯一的办法. 通常来说事件过滤器更好用一些, 因为不需要去继承QApplication类. 而且可以给QApplication对象安装任意个数的事件过滤器, 相比之下, notify()函数只有一个.

Calling Qt Functions From Unix Signal Handlers

Posted by – May 18, 2010

Home · All Classes · All Functions · Overviews

Calling Qt Functions From Unix Signal Handlers

Refers to:
You can’t call Qt functions from Unix signal handlers. The standard POSIX rule applies: You can only call async-signal-safe functions from signal handlers. See Signal Actions for the complete list of functions you can call from Unix signal handlers.

But don’t despair, there is a way to use Unix signal handlers with Qt. The strategy is to have your Unix signal handler do something that will eventually cause a Qt signal to be emitted, and then you simply return from your Unix signal handler. Back in your Qt program, that Qt signal gets emitted and then received by your Qt slot function, where you can safely do whatever Qt stuff you weren’t allowed to do in the Unix signal handler.

One simple way to make this happen is to declare a socket pair in your class for each Unix signal you want to handle. The socket pairs are declared as static data members. You also create a QSocketNotifier to monitor the read end of each socket pair, declare your Unix signal handlers to be static class methods, and declare a slot function corresponding to each of your Unix signal handlers. In this example, we intend to handle both the SIGHUP and SIGTERM signals. Note: You should read the socketpair(2) and the sigaction(2) man pages before plowing through the following code snippets.

class MyDaemon : public QObject

MyDaemon(QObject *parent = 0, const char *name = 0);

// Unix signal handlers.
static void hupSignalHandler(int unused);
static void termSignalHandler(int unused);

public slots:
// Qt signal handlers.
void handleSigHup();
void handleSigTerm();

static int sighupFd[2];
static int sigtermFd[2];

QSocketNotifier *snHup;
QSocketNotifier *snTerm;

In the MyDaemon constructor, use the socketpair(2) function to initialize each file descriptor pair, and then create the QSocketNotifier to monitor the read end of each pair. The activated() signal of each QSocketNotifier is connected to the appropriate slot function, which effectively converts the Unix signal to the QSocketNotifier::activated() signal.

MyDaemon::MyDaemon(QObject *parent, const char *name)
: QObject(parent,name)
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sighupFd))
qFatal("Couldn’t create HUP socketpair");

if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigtermFd))
qFatal("Couldn’t create TERM socketpair");
snHup = new QSocketNotifier(sighupFd[1], QSocketNotifier::Read, this);
connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup()));
snTerm = new QSocketNotifier(sigtermFd[1], QSocketNotifier::Read, this);
connect(snTerm, SIGNAL(activated(int)), this, SLOT(handleSigTerm()));


Somewhere else in your startup code, you install your Unix signal handlers with sigaction(2)

static int setup_unix_signal_handlers()
struct sigaction hup, term;

hup.sa_handler = MyDaemon::hupSignalHandler;
hup.sa_flags = 0;
hup.sa_flags |= SA_RESTART;

if (sigaction(SIGHUP, &hup, 0) > 0)
return 1;

term.sa_handler = MyDaemon::termSignalHandler;
term.sa_flags |= SA_RESTART;

if (sigaction(SIGTERM, &term, 0) > 0)
return 2;

return 0;

In your Unix signal handlers, you write a byte to the write end of a socket pair and return. This will cause the corresponding QSocketNotifier to emit its activated() signal, which will in turn cause the appropriate Qt slot function to run.

void MyDaemon::hupSignalHandler(int)
char a = 1;
::write(sighupFd[0], &a, sizeof(a));

void MyDaemon::termSignalHandler(int)
char a = 1;
::write(sigtermFd[0], &a, sizeof(a));

In the slot functions connected to the QSocketNotifier::activated() signals, you read the byte. Now you are safely back in Qt with your signal, and you can do all the Qt stuff you weren’tr allowed to do in the Unix signal handler.

void MyDaemon::handleSigTerm()
char tmp;
::read(sigtermFd[1], &tmp, sizeof(tmp));

// do Qt stuff


void MyDaemon::handleSigHup()
char tmp;
::read(sighupFd[1], &tmp, sizeof(tmp));

// do Qt stuff


Diagram Editor

Posted by – May 13, 2010

Ubuntu Diagram Editor:

Refers to:

Diagram Software for the rest of us!

With Gliffy online diagram software, you can easily create professional-quality flowcharts, diagrams, floor plans, technical drawings, and more.

Our online diagram editor makes it easier than ever to create great looking drawings.

1). Can edit diagram files suffixs with .dia
2). Can export dia file as a png file
3). Can draw UML diagram.

To install:
sudo apt-get install dia