microwindows代码分析 (三)screen driver显示驱动之X11

转载时请注明出处和作者联系方式:http://blog.csdn.net/mimepp

作者联系方式:YU TAO <yut616 at sohu dot com>

microwindows代码分析 (三)screen driver显示驱动之X11

在microwindows的嵌入式开发中,为了简化调试和check memory leak,那么最好是先将应用程序在X11下做好验证,保证function已经完成并且不会出现内存泄露的问题。这样就会用到microwindows的X11 screen driver显示驱动,我们在这里详细分析一下。

在我们讨论的microwindows的应用中,目前只涉及到microwindows的screen driver,并不涉及到鼠标和键盘的driver。也就是说,使用的microwindows只用到它的画图功能。

在编译X11 screen driver方式的microwindows时,会进入到drivers/Makefile,其中X11为Y,那么就会编译到

OBJS += genmem.o fb.o scr_x11.o /
        fblin1.o fblin2.o fblin4.o fblin8.o fblin16.o fblin24.o fblin32.o /
        fblin32alpha.o mou_x11.o

其中scr_x11.o就是x11接口的screen driver的实现,它里面会调用到X11 lib的一系列函数,实现draw pixel。

另外,可以看到有一系列的fblinXXX开头的代码也被编译了进来,这个内容主要是对应不同的pixel type,来做一些pixel的叠加运算等。它是作为sub driver来被scr_x11所使用的,因为scr_x11中主要是将X11 lib做一个包装,从而将运算好了的pixel输出到X11 output,而fblinXXX是一个sub driver,来根据不同的pixel type处理需要输出的pixel,如alpha blending混合。 而且fblinXXX在其他screen driver的情况下也是一样公用的,如framebuffer,也即fblinXXX也会被指定为sub driver。所以看到X11方式的screen driver会用到fb开头的内容,也不用奇怪。

下面来看drivers/scr_x11.c的具体内容。

scr文件名前缀就是screen driver的含义。

在这个screen driver中,定义了一个x11方式的SCREENDEVICE scrdev,这个变量的名字,在各个screen driver的实现中都是同一个名字,只是一个编译只使用一个具体的scrdev,在我们这里,就是X11方式的scrdev。

这个scrdev定义了X11方式的各个函数,如X11_open,X11_drawpixel,X11_fillrect,X11_blit等。

一、变量

在代码中,定义一些全局的涉及到X11显示操作的变量,如:

/* called from keyboard/mouse/screen */
Display *x11_dpy;
int x11_scr;
Visual *x11_vis;
Colormap x11_colormap;
Window x11_win;
GC x11_gc;
unsigned int x11_event_mask;
static int x11_width, x11_height;
static int x11_depth;           /* Screen depth in bpp */

在这里,x11_dpy是一个与x11 server所建立的connection;

x11_vis是记录视觉类型的变量;

x11_colormap是色彩映射;

在我们的应用中,如果是使用32位的无符号整数来表示颜色,也就是一般说的像素值,即pixel value,但这个像素值,在显示到输出时,会受到很多因素的影响,如

1、色彩深度

2、色彩映射,colormap,也就是含有R/G/B的强度值的表

3、视觉类型,visual type,指明如何来表示颜色

视觉分类里有如下几种类型:

char *classnm[] = { "StaticGray", "GrayScale", "StaticColor",
	"PseudoColor", "TrueColor", "DirectColor"
};

其中X11 server支持的主要是true color和direct color。

true color是直接根据rgb值,来得到像素值,而direct color是将rgb拿来到表里做一个查询后再转到像素值的。

二、X11_open

下面来看一下screen driver的open实现:X11_open

在这个函数里,会先调用X11的初始化函数来建立与X11 server的连接,x11_setup_display(附kscope图):

 

XOpenDisplay即根据display name与X11 server建立了一个connenction; 然后获得一个default screen; 再调用select_visual时,它会列出screen的不同depth的所对应的visual 类型。

XDefaultVisual:
  Visual  class: TrueColor (4)
             id: 35
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Screen RootDepth: 24
Screen RootVisual
  Visual  class: TrueColor (4)
             id: 35
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
screen->ndepths: 7
Depth: 24
dp->nvisuals: 8
Visual: 0
  Visual  class: TrueColor (4)
             id: 35
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Visual: 1
  Visual  class: TrueColor (4)
             id: 36
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Visual: 2
  Visual  class: TrueColor (4)
             id: 37
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Visual: 3
  Visual  class: TrueColor (4)
             id: 38
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Visual: 4
  Visual  class: DirectColor (5)
             id: 39
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Visual: 5
  Visual  class: DirectColor (5)
             id: 40
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Visual: 6
  Visual  class: DirectColor (5)
             id: 41
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Visual: 7
  Visual  class: DirectColor (5)
             id: 42
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Depth: 1
dp->nvisuals: 0
Depth: 4
dp->nvisuals: 0
Depth: 8
dp->nvisuals: 0
Depth: 15
dp->nvisuals: 0
Depth: 16
dp->nvisuals: 0
Depth: 32
dp->nvisuals: 1
Visual: 0
  Visual  class: TrueColor (4)
             id: 100
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff
Selected Visual:
  Visual  class: TrueColor (4)
             id: 35
   bits_per_rgb: 8
    map_entries: 256
       red_mask: 0x00ff0000
     green_mask: 0x0000ff00
      blue_mask: 0x000000ff

而我们的应用中,实际使用的visual也就是XDefaultVisual的值。即Visual class: TrueColor (4),id: 35,map_entries: 256。

在完成X11的display初始化后,会XCreateColormap,还有XCreateWindow建立窗口,长宽也即你指定的x11_width, x11_height,然后会再调用XDefaultDepth获得default的depth等,如下图(附kscope图):

 

在X11_open函数的后部,可以看到 savebits = *psd; 然后会调用到select_fb_subdriver(fb.c中),来根据planes和 bpp选择sub driver,如我们的应用中使用的是MWPF_TRUECOLOR8888,那么就会选用fblinear32alpha作为sub driver。然后会调用:

static SCREENDEVICE savebits;	/* permanent offscreen drawing buffer */
set_subdriver(&savebits, subdriver, TRUE);
savebits.addr = malloc(size);
/* set X11 psd to savebits memaddr for screen->offscreen blits... */
psd->addr = savebits.addr;

这个部分是一个很重要的内容。 它会将savebits的操作函数做一个更新,即设置到sub driver上,也即drivers/fblin32alpha.c中:

SUBDRIVER fblinear32alpha = {
        linear32a_init,
        linear32a_drawpixel,
        linear32a_readpixel,
        linear32a_drawhorzline,
        linear32a_drawvertline,
        gen_fillrect,
        linear32a_blit,
        linear32a_drawarea,
        linear32a_stretchblit,
        linear32a_stretchblitex,
};

这个savebits是保存的off sreen的buffer,也即最后的输出,都是从这个savebits中来得到的。

savebits.addr即malloc出来的一个显示buffer缓冲,是最后送到X11输出前保存各个pixel的地方。

psd->addr也则是对应的这个地址,但它是给上层的microwindows所使用的一个地址。各个不同的screen driver也都需要定义这个psd->addr。

三、draw pixel

我们再来看X11_drawpixel:

static void
X11_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c)
{
	/* draw savebits for readpixel or blit */
	savebits.DrawPixel(&savebits, x, y, c);
	if (gr_mode == MWMODE_COPY) {
		set_color(c);
		set_mode(gr_mode);
		XDrawPoint(x11_dpy, x11_win, x11_gc, x, y);
	} else {
		update_from_savebits(x, y, 1, 1);
	}
}

在其中,即会先调用sub drvier的DrawPixel函数,用pixel value值c来更新savebits里的addr的数据,然后调用update_from_savebits将savebits.addr的像素内容输出到X11上。

上面的 drawpixel 是操作一个像素点,也就是说将 c 的值画到 psd 的 x/y 位置处,所以你可以看到

update_from_savebits(x, y, 1, 1); 的参数是w=1, h=1。

其他的X11_xxx也都是类似如此的像素操作,即都是先调用sub driver的操作函数,然后X11的接口负责输出到X11 display上。

四、总结

总体来说,scr_x11是负责像素pixel在X11上输出的,在它里面是不涉及到图像的叠加等操作的。

它所操作的内容主要是将运算过的像素pixel输出到X11上,从而实现了microwindows在X11上的运行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值