• X Window研究笔记(10)


    X Window研究笔记(10)

    转载时请注明出处和作者联系方式
    作者联系方式:李先静 <xianjimli at hotmail dot com>

    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))

    1. Name: 插件的名称。
    2. NumEvents: 为扩展保留的事件数。
    3. NumErrors:为扩展保留的错误码数。
    4. MainProc: 扩展的处理函数。
    5. SwappedMainProc: 扩展的处理函数,在处理前先交换字节顺序。
    6. CloseDownProc: 扩展的析构函数。
    7. 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[i] 
    = 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;
    }


    (待续)

     
  • 相关阅读:
    线程(中)
    线程
    生产者消费者模型
    进程的常用方法
    HTML中head与body标签
    HTTP协议
    mysql:视图,触发器,事务,存储过程,函数。
    关于MySQL中pymysql安装的问题。
    MySQL多表查询,pymysql模块。
    MySQL之单表查询
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167679.html
Copyright © 2020-2023  润新知