免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 503 | 回复: 0
打印 上一主题 下一主题

X Window研究笔记(10) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-09-23 11:02 |只看该作者 |倒序浏览
X Window研究笔记(10)
转载时请注明出处和作者联系方式
作者联系方式:李先静
10.X Window扩展机制--扩展(Extension)
XWindow
中有大量扩展模块,每个扩展模块完成一组相关的功能,把扩展功能从核心功能中剥离出来,可以大大提高X
Server的可配置性和扩展性。扩展模块的实现机制很简单:每一个扩展模块都有一个初始化函数,这个函数在X
Window起动时被调用,在这里面会初始化一些该模块的数据结构,然后会调用AddExtension把相关回调函数注册进去。
AddExtension的函数原型如下:


ExtensionEntry *

AddExtension(char *name, int NumEvents, int NumErrors,

             int (*MainProc)(ClientPtr c1),

             int (*SwappedMainProc)(ClientPtr c2),

             void (*CloseDownProc)(ExtensionEntry *e),

             unsigned short (*MinorOpcodeProc)(ClientPtr c3))
  • Name: 插件的名称。
  • NumEvents: 为扩展保留的事件数。
  • NumErrors:为扩展保留的错误码数。
  • MainProc: 扩展的处理函数。
  • SwappedMainProc: 扩展的处理函数,在处理前先交换字节顺序。
  • CloseDownProc: 扩展的析构函数。
  • MinorOpcodeProc: 用来得到子处理号,一般没有什么用处,在出错时,设置到错误信息里。
    从AddExtension的实现中,我们很容易看出,扩展其实也是通过前一章所说的ProcVector来实现的。

       i = NumExtensions;

        newexts = (ExtensionEntry **) xrealloc(extensions,

                           (i + 1) * sizeof(ExtensionEntry *));

        if (!newexts)


        ...{

        xfree(ext->name);

        xfree(ext);

        return((ExtensionEntry *) NULL);

        }

        NumExtensions++;

        extensions = newexts;

        extensions = ext;

        ext->index = i;

        ext->base = i + EXTENSION_BASE;

        ext->CloseDown = CloseDownProc;

        ext->MinorOpcode = MinorOpcodeProc;

        ProcVector[i + EXTENSION_BASE] = MainProc;

       SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
    从理论上说,框架完全是独立于扩展的,增加增/删扩展不需要修改框架的代码。但实际情况往往不是这样的,有的扩展依赖框架提供一些特殊功能,有的扩展依赖另外一些扩展,所以在X Server的代码中,常常出现很多ifdef之类的宏,这些宏用来控制是否启用某些扩展。
    下面我们来看一个实际的例子(render):
    在mi/miinitext.c: InitExtensions函数中,RenderExtensionInit函数被调用,RenderExtensionInit的实现如下:

    void

    RenderExtensionInit (INITARGS)


    ...{

        ExtensionEntry *extEntry;


        if (!PictureType)

        return;

        if (!PictureFinishInit ())

        return;

        RenderClientPrivateIndex = AllocateClientPrivateIndex ();

        if (!AllocateClientPrivate (RenderClientPrivateIndex,

                    sizeof (RenderClientRec)))

        return;

        if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))

        return;

       

        extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,

                     ProcRenderDispatch, SProcRenderDispatch,

                     RenderResetProc, StandardMinorOpcode);

        if (!extEntry)

        return;

    #if 0

        RenderReqCode = (CARD8) extEntry->base;

    #endif

        RenderErrBase = extEntry->errorBase;

    }
    ProcRenderDispatch是扩展的主分发函数,它调用子处理函数去完成实际的请求。其中stuff->data是子处理号,以子处理号从ProcRenderVector中找到对应的函数,并调用它。

    static int

    ProcRenderDispatch (ClientPtr client)


    ...{

        REQUEST(xReq);


        if (stuff->data  RenderNumberRequests)

        return (*ProcRenderVector[stuff->data]) (client);

        else

        return BadRequest;

    }
    (待续)
                   
                   
                   

    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/43721/showart_388007.html
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP