2009年5月12日星期二

完全用Xlib写的时钟程序


我不多说了,请看代码:

//编译参数:gcc -o X11helloworld X11helloworld.c -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lm

#include
#include
#include
#include
#include
#include // for signal()
#include // struct itimeral. setitimer()
#include //数学函数库

#define DUMP_ERR printf

//设为全局
Display *display;
Window win;

static void draw(Display *display,Window win,GC gc,int width,int height);

void printMsg(int);

int main()
{
int screennum;
int width;
int height;
Atom protocols;

const char *strdraw = "hello World";

GC gc;
//打开显示 没有指明打开哪个显示时使用环境变量中的DESPLAY
display = XOpenDisplay(NULL);
if( !display ){
DUMP_ERR("call XOpenDisplay(%s) fail\n",XDisplayName(NULL));
return 1;
}

//得到系统当前的屏幕 (如果使用虚拟屏幕的话 一般会有几个)
// get default screen
screennum = DefaultScreen(display);
//根据屏幕的大小决定窗口的大小
width = DisplayWidth(display,screennum)/4;
height = width;

//创建窗口
// create window
win = XCreateSimpleWindow(display,
RootWindow(display,screennum),
0,0,width,height,3,
BlackPixel(display,screennum),
WhitePixel(display,screennum));

//增加这个代码是捕获程序退出事件
protocols = XInternAtom(display,"WM_DELETE_WINDOW", True);
XSetWMProtocols(display, win, &protocols, 1);

//选择窗口关心的事件
// select event
XSelectInput(display,win,
ExposureMask|KeyPressMask
|ButtonPressMask|StructureNotifyMask);

//创建GC(图形上下文)
// create gc
{
unsigned long valuemask = 0;
XGCValues values;
gc = XCreateGC(display,win,valuemask,&values);
}

// 映射窗口 只有map后窗口才会在屏幕上显示
// show window
XMapWindow(display,win);

//设置定时器
int res = 0;
// Register printMsg to SIGALRM
signal(SIGALRM, printMsg);

struct itimerval tick;
// Initialize struct
memset(&tick, 0, sizeof(tick));

// Timeout to run function first time
tick.it_value.tv_sec = 1; // sec
tick.it_value.tv_usec = 0; // micro sec.
// Interval time to run function
tick.it_interval.tv_sec = 1;
tick.it_interval.tv_usec = 0;
// Set timer, ITIMER_REAL : real-time to decrease timer,
// send SIGALRM when timeout
res = setitimer(ITIMER_REAL, &tick, NULL);
if (res) {
printf("Set timer failed!!\n");
}

//进入事件循环
// event loop
while(1){
XEvent event;
XNextEvent(display,&event); // 读一个事件

switch(event.type){
case Expose: // expose window 显示事件
if( event.xexpose.count != 0) break;
draw(display,win,gc,width,height);
//XDrawString(display,win,gc,10,10,
//strdraw,strlen(strdraw));
break;

case ConfigureNotify: // when the window’s size change
width = event.xconfigure.width;
height = event.xconfigure.height;
break;
case ClientMessage :
if(event.xclient.data.l[0] == protocols){
DUMP_ERR("recv destroy notify\n");
XFreeGC(display,gc);
XDestroyWindow(display, win);
XCloseDisplay(display);
}
return 0;
default:
break;
}
}
}

// 使用changeGC修改属性的代码 只有valuemask被设置的属性才会根据XCGValues里面的值进行修改
static void set_gc_values(Display *display,GC gc)
{
XGCValues values;
values.line_width = 2;
values.line_style = LineSolid;
values.cap_style = CapRound;
values.join_style = JoinRound;

XChangeGC(display,gc,GCLineWidth|GCLineStyle,//|GCCapStyle|GCFillStyle,
&values);
}

// 画画的代码
static void draw(Display *display,Window win,GC gc,int width,int height)
{
XClearWindow(display,win);

//画一个圆
XDrawArc(display,win,gc,(width-height)/2+height/16,height/16,height/16*14,height/16*14,0,360*64);
//获取系统时间
long ct;
struct tm *currtime;
ct=time(&ct);
currtime=(struct tm *)localtime(&ct);
//计算表针位置,从alltraxclock.c里抄来的。
int second_hand_x = (int) (sin((currtime->tm_sec * 3.14159 * 2) / 60) * (height/16*5));
int second_hand_y = (int) (cos((currtime->tm_sec * 3.14159 * 2) / 60) * (height/16*5));
int big_hand_x = (int) (sin((currtime->tm_min * 3.14159 * 2) / 60) * (height/16*4));
int big_hand_y = (int) (cos((currtime->tm_min * 3.14159 * 2) / 60) * (height/16*4));
//计算时针的时候,要把分钟也加上。
int little_hand_x = (int) (sin(((currtime->tm_hour+currtime->tm_min/60.0) * 3.14159 * 2) / 12) * (height/16*3));
int little_hand_y = (int) (cos(((currtime->tm_hour+currtime->tm_min/60.0) * 3.14159 * 2) / 12) * (height/16*3));
//画一个表针
XDrawLine(display,win,gc,width/2,height/2,width/2+second_hand_x,height/2-second_hand_y);
XDrawLine(display,win,gc,width/2,height/2,width/2+big_hand_x,height/2-big_hand_y);
XDrawLine(display,win,gc,width/2,height/2,width/2+little_hand_x,height/2-little_hand_y);
printf("%d:%d\n",width,height);
}

void printMsg(int num) {
//让窗口重画
XEvent event;
memset(&event,0,sizeof(XEvent));
event.type=Expose;
XSendEvent(display,win,True,0x0,&event);
XFlush(display);
//获取系统时间
long ct;
struct tm *currtime;
ct=time(&ct);
currtime=(struct tm *)localtime(&ct);
printf("%d:%d:%d\n",currtime->tm_hour,currtime->tm_min,currtime->tm_sec);
}

大家有不清楚的地方,请去网上搜索,因为我写出这个程序已经很勉强了,有好多地方我是猜着写的。

2009年5月4日星期一

成龙 击缶 二人转

我怎么也不会想到,成龙会发出“中国人该管”的言论;我更没想到的是,国内的网站回复中,对于成龙的言论是一片赞扬之声,我现在才恍然大悟,原来中国人都是希望被管的。
虽然支持成龙的评论颇多,不过对于中国认为什么该被管、该被怎么管,却说不出个所以然来,只是不停地重复“挺你”、“顶你”、“说实话”之类的婴儿般的单调词汇。看来这些回复者只是些没脑子的蠢货!
不知道这些支持成龙的人,有没有过因为拍拍照片而被打?有没有过因为逛逛公园而被捉?有没有过因为写写博客而被判刑的经历?
有些人老拿三鹿奶粉说事儿,但在我看来,三鹿奶粉的元凶就是这个不自由的社会。如果检测机构能够自由的检测奶粉的质量,如果新闻部门能够自由的报道这一事件,就不会有那么多的孩子受害了。
(注:三鹿奶粉被定为免检产品,免检产品既不能受到质量监督的产品)
(注:有人猜测,三鹿奶粉的事情早被新闻媒体所知晓,但顾及会对奥运会有不好的影响,所以一直瞒而不报)
(注:2008年8月2日:据国务院调查组事后调查,河北省石家庄市政府此时曾接到三鹿集团有关“问题奶粉”的报告,但未在规定时间内上报省政府及其相关部门。)
(注:2008年8月8日:中国北京国家体育场举行北京2008年奥运会开幕式。)
(注:2008年8月24日:中国北京国家体育场举行北京2008年奥运会闭幕式。 )
(注:2008年9月9日:中国人民解放军第一医院已收治“14名婴儿同患肾结石”,“肾结石”奶粉事件逐渐为全国关注。)
有人说成龙爱国,不过我觉得,他所爱的国,是一个给他个人提供了很多好处的国,而不是一个真正的尊重普通民众的国,爱这样的一个国家有什么光荣的?

成龙最近的兴趣爱好越来越广泛了,除了攻击民主外,还迷上了“击缶”。
“击缶”原是贬义,但是他沾了北京奥运会的光,一下变成了中国文化的象征,官方也认同了这个说法。都和成龙一样,死不认错。
有意思的是,现在有些朋友站出来,向大家解释“击缶”的原意,就会招致大量的攻击,我觉得没有文化并不是什么丢人的事(我也没什么文化),没有文化还排斥文化就不能饶恕了。
成龙说过:“我最想和张艺谋合作,拍一部类似于《大红灯笼高高挂》的电影,我呢,就演一个老实巴交的农民。”当时听到这句话时真是让人不解,我不明白,成龙为什么会喜欢那样庸俗的电影呢?现在我找到答案了,成龙和张艺谋就是一对奴才!

我以前从没关注过张艺谋,只是偶尔听到一些关于他的评论和关于他的电影的评论,对他也没有什么好恶。不过自从看了他的电影《英雄》以后,我对他有了新的认识:流氓。
大家都知道,秦始皇是个杀人如麻的刽子手,他焚书坑儒,他杀人陪葬,他大修陵墓、大修长城,他视人命如草芥,自己却一次一次的远渡重洋,求长生不老药。
就是这样一个暴君,张艺谋不但为他歌功颂德,还把他写成了一个为了天下人的幸福,不得不杀人的一个英雄。或许成龙和张艺谋都很向往做秦始皇的子民吧,感受一下说错一句话就要掉脑袋的生活。

我们好像还拉掉一位和成龙、张艺谋关系密切的朋友,赵本山。
我觉得这三个人好像有些相同的地方,比如都对自己的配偶不忠,把这三个人凑在一起,正好可以成立一个“负心汉俱乐部”。
扯远了,说艺术,说艺术。
我比较喜欢成龙的电影,因为我在成龙的电影里可以看到许多反抗恶势力,助人为乐的故事情节,至少用动作片的标准来衡量,应该算是上乘之作。
张艺谋的一些纪录片风格的电影还是比较出色的,比如《秋菊打官司》、《一个都不能少》。
赵本山的小品中,有一个是反应公务接待铺张浪费的,我觉得不错。

好话到此为止,下面说正题,我觉得得这三个人做事有些“过”,说白了就是不知道自己有多大分量。
先说成龙,你对中国文化有多少了解?不知道就要用心去学,天天听着赵本山的二人转,看着张艺谋的英雄,敲着秦朝人的瓦罐是不会有出息的。评论艺术说明你无知,评论政治说明你无德,你走马观花般的看看新加坡、看看台湾、看看大陆,你就对各国人民的生活了如指掌了?一个到了哪里都前呼后拥的人,是没法了解我们的真实生活的。
再说张艺谋,拍纪录片的材料非要导演奥运会开幕式,还糟蹋了我们的歌剧、芭蕾舞。叫上几万人做一样的动作,那些搞传销的都会。
赵本山,总是喜欢拿一些粗俗的东西来取悦观众,不过平心而论,这不是赵本山的错,错在低俗的观众们。至少无不喜欢赵本山。

我觉得成龙就像一个商人,他先从自由的观众那里收购知名度,再利用这些知名度,从不自由的国度里捞去好处。
成龙已死,至少在我的心理是这样的。

2009年4月22日星期三

试用 Google O3D

今天看到了一些关于O3D的介绍,我对他挺感兴趣,就试着在linux下安装了一下,效果还不错。



O3D Home,能在线布置自己的屋子,这个不错,不过这个网站好象和Firefox 3.1 不太兼容,也许是我不会操作,也许是这各业面还没有完成,也许。。。总之,这个只能看,不能玩。



2D In O3D,其实这是一个很漂亮的动画,可惜我只能上传一张截图。



3D Checkers Game,这个是叫黑白棋吗?我不懂,这个好像还不能互动,也许是我不会玩吧?



Beach Deom,我这里只能看到一片汪洋大海,可是介绍上的图片是一副更漂亮的景色呀?运行时还弹出linux什么什么的提示,也许等正式的O3D推出后,我们就能看到更完整的画面了。



Hello Cube,一个旋转的立方体,在下面的地址栏里输入图片的地址,就可以更换立方体的贴图。



HUD 2D Overlay,好像是个城市的鸟瞰图,很漂亮。



Cameras and events,一个彩色的方块,可以旋转的哟。



Culling,一些漂亮的泡泡,比flash下的泡泡好看多了,至少有光照效果。



ZSorting,一些透明的泡泡,会旋转的哟,比上面的那个要好看。



Vertex Shader,波纹,很流畅的波纹动画,如果有贴图就更好了。



Phong shading,一个大圆球,这个球让我想起了学3dmax的日子。



The Journies of Prince IO,一个小游戏,风格类似于恶魔城。
(注:我没玩过恶魔城)

按向上的箭头是跳跃,空格是射出弩箭。

2009年4月17日星期五

2009年4月15日星期三

关注者