X Window研究笔记(10)

本文介绍了XWindow系统的扩展机制,详细解释了如何通过扩展模块增强XServer的功能,包括扩展的初始化过程、回调函数注册及实际扩展例子(如Render扩展)。
X Window研究笔记(10)

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

10.X Window扩展机制--扩展(Extension)

XWindow中有大量扩展模块,每个扩展模块完成一组相关的功能,把扩展功能从核心功能中剥离出来,可以大大提高X Server的可配置性和扩展性。扩展模块的实现机制很简单:每一个扩展模块都有一个初始化函数,这个函数在X Window起动时被调用,在这里面会初始化一些该模块的数据结构,然后会调用AddExtension把相关回调函数注册进去。

AddExtension的函数原型如下:


ExtensionEntry
*
AddExtension(
char*name,intNumEvents,intNumErrors,
int(*MainProc)(ClientPtrc1),
int(*SwappedMainProc)(ClientPtrc2),
void(*CloseDownProc)(ExtensionEntry*e),
unsigned
short(*MinorOpcodeProc)(ClientPtrc3))

  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;
#if0
RenderReqCode
=(CARD8)extEntry->base;
#endif
RenderErrBase
=extEntry->errorBase;
}


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

staticint
ProcRenderDispatch(ClientPtrclient)
...{
REQUEST(xReq);

if(stuff->data<RenderNumberRequests)
return(*ProcRenderVector[stuff->data])(client);
else
returnBadRequest;
}


(待续)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值