目录

  • 简介
  • 注册BlockHandler和WakeupHandler
    • RegisterBlockAndWakeupHandlers
    • 注册到Screen
  • 注册InputHandler
  • 注册GeneralHandler
  • Handler的执行
    • BlockHandler函数
    • WakeupHandler函数
  • xf86Wakeup函数

简介

Xorg Handler用于处理各种类型的回调函数,Xorg一共支持四种类型的Handler:

  • BlockHandler: 在阻塞之前调用;
  • WakeupHandler: 在唤醒之后调用;
  • InputHandler: 用于键盘鼠标等输入设备;
  • GeneralHandler: 用于其它类型的设备;

其中BlockHandler和WakeupHandler属于同一种类型,它们的回调函数不需要关联设备文件句柄,并且一旦注册上就会无条件执行。

InputHandler和GeneralHandler属于另一种类型,它们的回调函数需要关联到某一个设备句柄(例如键盘设备文件),当设备句柄有数据到达时,可以马上唤醒阻塞中的Xorg,并且只有在设备句柄可读/可写时,对应的回调函数才会执行。

注册BlockHandler和WakeupHandler

RegisterBlockAndWakeupHandlers

BlockHandler和WakeupHandler通过调用RegisterBlockAndWakeupHandlers函数注册,该函数同时注册两个回调函数,通过往static数组handlers增加一个成员实现:

Bool
RegisterBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler,WakeupHandlerProcPtr wakeupHandler,void *blockData)
{BlockHandlerPtr new;if (numHandlers >= sizeHandlers) {new = (BlockHandlerPtr) realloc(handlers, (numHandlers + 1) *sizeof(BlockHandlerRec));if (!new)return FALSE;handlers = new;sizeHandlers = numHandlers + 1;}handlers[numHandlers].BlockHandler = blockHandler;handlers[numHandlers].WakeupHandler = wakeupHandler;handlers[numHandlers].blockData = blockData;handlers[numHandlers].deleted = FALSE;numHandlers = numHandlers + 1;return TRUE;
}

注册到Screen

除了调用上面的函数注册到handlers,也可以通过直接修改指针注册到Screen,典型代码如下:

/** Setup points to the block and wakeup handlers.  Pass a pointer* to the current screen as pWakeupdata.*/
pScreen->BlockHandler = winBlockHandler;
pScreen->WakeupHandler = winWakeupHandler;

如果使用直接修改指针的方式注册,需要在修改之前保存原始指针,退出时进行还原。这两种注册方式使用场景也有差别,第二种注册的回调函数与对应的Screen绑定,第一种注册方式没有绑定。

注册InputHandler

InputHandler通过调用xf86AddInputHandler函数注册,该函数在InputHandlers链表中增加一个成员。

static void *
addInputHandler(int fd, InputHandlerProc proc, void *data)
{IHPtr ih;if (fd < 0 || !proc)return NULL;ih = calloc(sizeof(*ih), 1);if (!ih)return NULL;ih->fd = fd;ih->ihproc = proc;ih->data = data;ih->enabled = TRUE;ih->next = InputHandlers;InputHandlers = ih;return ih;
}void *
xf86AddInputHandler(int fd, InputHandlerProc proc, void *data)
{IHPtr ih = addInputHandler(fd, proc, data);if (ih) {AddEnabledDevice(fd);ih->is_input = TRUE;}return ih;
}

注册GeneralHandler

GeneralHandler通过调用xf86AddGeneralHandler函数注册。该函数与xf86AddInputHandler一样,内部也是通过调用addInputHandler实现,不同的是InputHandler被标记为输入设备,除此之外没有其它差别。

void *
xf86AddGeneralHandler(int fd, InputHandlerProc proc, void *data)
{IHPtr ih = addInputHandler(fd, proc, data);if (ih)AddGeneralSocket(fd);return ih;
}

Handler的执行

Handler执行流程如下图所示,在WaitForSomething函数中先调用BlockHandler执行所有block类型的handler,然后执行select等待输入事件,select阻塞结束后执行WakeupHandler执行所有wakeup类型的handler。InputHandler和GeneralHandler由xf86Wakeup函数执行,该函数在Xorg初始化时会被注册为一个WakeupHandler。

BlockHandler函数

void
BlockHandler(void *pTimeout, void *pReadmask)
{int i, j;++inHandler;for (i = 0; i < screenInfo.numScreens; i++)(*screenInfo.screens[i]->BlockHandler) (screenInfo.screens[i],pTimeout, pReadmask);for (i = 0; i < screenInfo.numGPUScreens; i++)(*screenInfo.gpuscreens[i]->BlockHandler) (screenInfo.gpuscreens[i],pTimeout, pReadmask);for (i = 0; i < numHandlers; i++)if (!handlers[i].deleted)(*handlers[i].BlockHandler) (handlers[i].blockData,pTimeout, pReadmask);if (handlerDeleted) {for (i = 0; i < numHandlers;)if (handlers[i].deleted) {for (j = i; j < numHandlers - 1; j++)handlers[j] = handlers[j + 1];numHandlers--;}elsei++;handlerDeleted = FALSE;}--inHandler;
}

WakeupHandler函数

void
WakeupHandler(int result, void *pReadmask)
{int i, j;++inHandler;for (i = numHandlers - 1; i >= 0; i--)if (!handlers[i].deleted)(*handlers[i].WakeupHandler) (handlers[i].blockData,result, pReadmask);for (i = 0; i < screenInfo.numScreens; i++)(*screenInfo.screens[i]->WakeupHandler) (screenInfo.screens[i],result, pReadmask);for (i = 0; i < screenInfo.numGPUScreens; i++)(*screenInfo.gpuscreens[i]->WakeupHandler) (screenInfo.gpuscreens[i],result, pReadmask);if (handlerDeleted) {for (i = 0; i < numHandlers;)if (handlers[i].deleted) {for (j = i; j < numHandlers - 1; j++)handlers[j] = handlers[j + 1];numHandlers--;}elsei++;handlerDeleted = FALSE;}--inHandler;
}

xf86Wakeup函数

Xorg在初始化时调用RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr) NoopDDA, xf86Wakeup, NULL);注册xf86Wakeup。

void
xf86Wakeup(void *blockData, int err, void *pReadmask)
{fd_set *LastSelectMask = (fd_set *) pReadmask;fd_set devicesWithInput;InputInfoPtr pInfo;if (err >= 0) {XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices);if (XFD_ANYSET(&devicesWithInput)) {pInfo = xf86InputDevs;while (pInfo) {if (pInfo->read_input && pInfo->fd >= 0 &&(FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) {OsBlockSIGIO();/** Remove the descriptior from the set because more than one* device may share the same file descriptor.*/FD_CLR(pInfo->fd, &devicesWithInput);pInfo->read_input(pInfo);OsReleaseSIGIO();}pInfo = pInfo->next;}}}if (err >= 0) {             /* we don't want the handlers called if select() */IHPtr ih, ih_tmp;       /* returned with an error condition, do we?      */nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) {if (ih->enabled && ih->fd >= 0 && ih->ihproc &&(FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) {ih->ihproc(ih->fd, ih->data);}}}if (xf86VTSwitchPending())xf86VTSwitch();
}

Xorg Handler简介相关推荐

  1. Android攻城狮Handler简介

    Handler是什么? Handler是Android提供的一套用来更新UI的机制,也是一套消息处理机制,可以通过它发送消息,也可以通过它处理消息. 所有Activity生命周期回调的方法(例如onC ...

  2. Handler 简介

    文章目录 概要 源码分析 Looper.prepare() 作用及实现 loop 如何实现等待功能 概要 Handler 主要有两个作用 定时执行消息或 Runnable 任务 向其它线程发送消息或 ...

  3. Android中Handler消息机制

    作用:跨线程通信. 应用:AsyncTask.retrofit都对Handler进行了封装. 四要素:Message.MessageQueue.Looper.Handler Message简介: 线程 ...

  4. 【Android开发】消息处理类(Handler)与消息类(Message)介绍

    一.消息处理类(Handler)简介 消息处理类Handler允许发送和处理Message或Runnable对象到其所在线程的MessageQueue中.Handler主要有一下两个作用: 1.将Me ...

  5. java handler使用方法_Handler 使用详解

    阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容: Handler 消息处理机制原理 Han ...

  6. Android学习笔记:Handler

    一.Handler简介 Handler是Android消息机制的上层接口,这使得在开发过程中只需要和Handler交互即可.Handler的使用过程很简单,通过它可以轻松的将一个任务转换到Handle ...

  7. Netty源码解析4-Handler综述

    请戳GitHub原文: github.com/wangzhiwubi- 更多文章关注:多线程/集合/分布式/Netty/NIO/RPC Java高级特性增强-集合 Java高级特性增强-多线程 Jav ...

  8. 71道Android开发面试题

    注:本文来自"安卓巴士" Android面试题 1.        下列哪些语句关于内存回收的说明是正确的? (b ) A. 程序员必须创建一个线程来释放内存   B. 内存回收程 ...

  9. android最全面试题71道题 详解

    Android面试题 1. 下列哪些语句关于内存回收的说明是正确的? (b ) A. 程序员必须创建一个线程来释放内存 B. 内存回收程序负责释放无用内存 C. 内存回收程序允许程序员直接释放内存 D ...

最新文章

  1. 在移动端禁用长按选中文本功能
  2. Google的TensorFlow,微软CNTK, Amazon 的MxNet,Facebook 的Caffe2, PyTorch,国内百度的PaddlePaddle...
  3. 消息消费端的确认机制
  4. 【ArcGIS风暴】ArcGIS平台上点云(.las)数据生成等高线方法案例精解
  5. 【渝粤教育】国家开放大学2018年春季 0529-22T高级英语阅读(1) 参考试题
  6. linux中sybase删除数据库,Linux_Sybase ASE数据库的常见问题解答,1 数据库占用磁盘空间的形式 - phpStudy...
  7. 安装head插件依赖包grunt-cli
  8. 计算机审计的概念的论文,论文:浅谈计算机审计中的数据分析
  9. Silverlight/WPF/WP7一周学习导读(12月6-12月12)
  10. 端午节海报|端午节海报设计素材图片大全
  11. 有多少个斐波那契子数列(微软笔试题)
  12. Inter Edsion添加USB有线网卡解决办法
  13. 财务会计科目与预算会计科目关联对照表
  14. hexeditor作用_Hex编辑器Free Hex Editor Neo
  15. 中国染料产业竞争格局分析与消费需求调研报告2022版
  16. 自主可控国产服务器思考
  17. 测绘类专业计算机要学什么科目,测绘类专业选考科目要求是什么
  18. 操作系统学习笔记——北京大学陈向群老师课后及习题答案(1)
  19. typecho图片水印插件
  20. Microsoft Project 2010基础使用方法

热门文章

  1. Castor-解析xml的另外一种方法
  2. 网安:haveibeenpwned(社工库)查看信息是否被泄露
  3. 计算机常用的加密方法,加密方式有哪些_教你常用加密方式有哪些
  4. PHP七彩自助发卡系统源码娱乐影视卡密自助发放系统+教程
  5. iOS开发 -- iPhone手机屏幕尺寸
  6. 3DMAX高级光照相关的名词解释
  7. 智能合约(一)————智能合约入门
  8. VS2017安装警告。未能安装包“Microsoft.VisualCpp.Redist.14,version=14.16.27033.4,chip=x86”
  9. 联想一体机开机黑屏只显示LOGO联想标志两个字解决办法
  10. CCF-CSP-202112-1/2:序列查询(新解)