Xrandr 与Xserver 的交互

本文深入探讨了Xrandr作为Xclient与Xorg作为server端的交互过程,详细解析了RandRExternsion的注册、RandR向Xserver发出请求的流程以及Xserver如何处理Xrandr的请求。同时,解释了如何获取RandRExtension的ext->base,并通过debug实现代理理解整个交互过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

                                Xrandr 与Xserver 的交互

      

在X Windows system 中,Xrandr 做 X client ,Xorg 作为server端。

1.      RandR Externsion 的注册

对于Xorg 1.6.0,如果在xorg.conf文件中,没有显式的disable RandR。Xorg 会将Xrandr extension 加载。

InitExtensions

 

 

RRExtensionInit

 

 

AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,

                       ProcRRDispatch, SProcRRDispatch,

                       NULL, StandardMinorOpcode);

 

          X11/extensions/randr.h:40 :define RANDR_NAME  "RANDR"

此函数的作用是:为全局变量extensions 增加一个新的成员,

                                i = NumExtensions;

                                NumExtensions++;

extensions[i] = ext;

                            ext->index = i;

                            ext->base = i + EXTENSION_BASE(128);

                               strcpy(ext->name,  name); 其中的name 即为RANDR.

             ProcVector[i + EXTENSION_BASE] = MainProc即 ProcRRDispatch;

SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc 即 SProcRRDispatch;

       其中ProcVector是函数指针数组。

    1.1 ProcRRDispatch

       static int

ProcRRDispatch (ClientPtr client)

{

    REQUEST(xReq);

    if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])

       return BadRequest;

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

}

    其中ProcRandrVector也是函数指针数组。

     int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {

                 ProcRRQueryVersion,      /* 0 */

/* we skip 1 to make old clients fail pretty immediately */

                   NULL,                     /* 1 ProcRandrOldGetScreenInfo */

/* V1.0 apps share the same set screen config request id */

                 ProcRRSetScreenConfig, /* 2 */

                 NULL,                /* 3 ProcRandrOldScreenChangeSelectInput */

/* 3 used to be ScreenChangeSelectInput; deprecated */

                   ……

                     }    

    可以看出该函数的作用是利用stuff->data 作为index 做为index 来选择不同的函数。

            SProcRRDispatch

SProcRRDispatch 与 ProcRRDispatch的作用完全相同,在这里就不赘述了。但是不太明白两者的区别。

2.      RandR 向X server 发出请求。

     以 RandR函数 XRRGetScreenSizeRange 为例。

    RandR填充数据结构

      typedef struct {

    CARD8   reqType;

    CARD8   randrReqType;

    CARD16  length B16;

    Window  window B32;

} xRRGetScreenSizeRangeReq;

       

req->reqType = info->codes->major_opcode;

    req->randrReqType = X_RRGetScreenSizeRange(值是6);

    req->window = window;

      然后利用if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))将请求发出。

 

Xserver 利用函数ReadRequestFromClient将client送来的request解析出来,并赋值给数据结构:

      typedef struct _xReq {

        CARD8 reqType;

        CARD8 data;            /* meaning depends on request type */

        CARD16 length B16;         /* length in 4 bytes quantities                                  of whole request, including this header */

} xReq;

 

xReq *req = client->requestBuffer; 因此:

xReq-> reqType = req->reqType;

 xReq-> data  =  req->randrReqType (6);

 

2.1        info->codes->major_opcode

info->codes->major_opcode值 其实为第一部分中,RandR Extension 的ext->base = i + EXTENSION_BASE(128)。 但是如何得到ext->base,确实费了一番功夫。

RandR 在赋值 req->reqType = info->codes->major_opcode前,调用函数XRRFindDisplay-> XextAddDisplay,在XextAddDisplay中,会向Xserver也发送一个请求,从而得到ext->base.(具体过程后面介绍)

 

 

3.      Xserver 如何处理Xrandr的请求

 

这段代码没有看懂,以下是debug情况下的总结,我在终端是终端上输入命令xrandr –q。

 

WaitforSometing一直在循环等待,当有请求时。

首先调用EstablishNewConnections -àNextAvailableClient-à InitClient,在InitClient中将client->requestVector = InitialVector。

InitialVector的定义如下:

   int (* InitialVector[3]) (

       ClientPtr /* client */

    ) =

{

    0,

    ProcInitialConnection,

    ProcEstablishConnection

};

 

Dispatch继续向下调用,455行,result = (* client->requestVector[MAJOROP])(client),即调用ProcEstablishConnection。(不明白MAJOROP为什么此时是2.)

 

ProcEstablishConnection调用函数SendConnSetup,SendConnSetup中

client->requestVector = client->swapped ? SwappedProcVector : ProcVector;。进行Vector的选择,本例中选择的是ProcVector。

 

在下一次Dispatch的循环中,455 行调用。

result = (* client->requestVector[MAJOROP])(client); ,其中#define MAJOROP ((xReq *)client->requestBuffer)->reqType ,从2.1可知,reqType为ext->base. 即刚才的语句调用了函数ProcRRDispatch。而在函数ProcRRDispatch又根据xReq-> data最终调用到函数ProcRRGetScreenSizeRange。

 

 

4. 如何得到      RandR Extension 的ext->base = i + EXTENSION_BASE(128)

以Randr中的函数XRRGetScreenInfo为例。

 XRRGetScreenInfo-> XRRFindDisplay->XextAddDisplay (&XRRExtensionInfo, dpy,

         XRRExtensionName,  &rr_extension_hooks,  RRNumberEvents,  0);

è XInitExtension -> XQueryExtension

  XQueryExtension 首先利用GetReq(QueryExtension, req),将

req->reqType = X_##name;\,即req->reqType =X_QueryExternsion,(98)然后调用_XReply (dpy, (xReply *)&rep, 0, xTrue),向Xserver发出请求。

Xserver收到请求后,从ProcVector中找到index 为98的函数ProcQueryExtension,在这个函数中,会根据req中Externsion的名字(RandR),遍历全局变量extensions,找到RandR extension,并返回ext->base。

 

 

 

 

<think>我们正在讨论Linux中的X服务。用户的问题是关于X服务的定义和用途。根据用户提供的引用,这些引用主要涉及Linux服务器、FTP、目录结构等,X服务没有直接关系。因此,我们需要依靠自己的知识库来回答。 X服务通常指的是XWindow System,它是Linux和类Unix系统中提供图形用户界面(GUI)的底层框架。###定义XWindow System(通常称为X11或X)是一种网络透明的窗口系统,用于位图显示。它提供了在计算机屏幕上绘制和移动窗口的基本框架,以及鼠标和键盘的交互。X WindowSystem采用客户端-服务器模型,其中X服务器负责管理显示硬件,而客户端应用程序(如窗口管理器、图形应用程序)则通过网络协议服务器通信。###用途1.**提供图形用户界面(GUI)**:X服务允许用户在Linux系统上运行图形化应用程序,而不局限于命令行界面。2.**网络透明性**:X的设计允许应用程序(客户端)运行在一个机器上,而显示(服务器)在另一个机器上。例如,可以在远程服务器上运行图形程序,而在本地显示。3.**支持多种窗口管理器**:X本身只提供基本的窗口功能,窗口管理器(如GNOME、KDE等)则提供用户界面的外观和感觉。 4. **设备抽象**:X服务器管理输入设备(如鼠标、键盘)和输出设备(如显示器),为应用程序提供统一的接口。 ###工作方式- **X服务器**:直接硬件交互,控制显示和输入设备。- **X客户端**:应用程序,通过X协议X服务器通信,发送绘图请求并接收输入事件。- **X窗口管理器**:管理窗口的布局、装饰和切换。 ###历史现状- XWindowSystem最早于1984年由MIT开发,现在由X.Org基金会维护。 -现代Linux发行版通常使用X.OrgServer作为X服务的实现。-近年来,Wayland作为X的替代品逐渐流行,但X仍然被广泛支持。 ###常见命令-启动X服务:通常由显示管理器(如GDM、LightDM)自动启动,也可以手动使用`startx`命令启动。 -检查X服务是否运行:`ps aux| grepXorg`###问题排查如果X服务启动失败,用户可能会陷入命令行界面。此时可以查看日志文件(通常位于`/var/log/Xorg.0.log`)来诊断问题。###总结X服务是Linux图形界面的基石,它通过客户端-服务器模型提供了图形显示和输入处理的能力,使得用户可以在Linux上使用丰富的图形应用程序。§§相关问题§§1.X WindowSystem和Wayland有什么区别?2.如何在Linux系统中配置多显示器?3.X服务常见的故障排除方法有哪些?</think>### Linux中的X服务:定义用途 #### **1. X服务的定义** - **核心概念**:X服务(X Window System,简称X11)是Linux和类Unix系统中的**图形显示协议**,负责管理图形用户界面(GUI)的底层框架。它采用客户端-服务器模型: - **X服务器**:直接控制显示硬件(如显卡、显示器)和输入设备(鼠标、键盘)。 - **X客户端**:应用程序(如浏览器、文本编辑器),通过X协议服务器通信。 - **技术本质**:X服务是一个**网络透明的窗口系统**,允许应用程序在本地或远程机器上运行,但图形输出显示在本地屏幕[^3]。 #### **2. 主要用途** ##### **(1)提供图形用户界面(GUI)** - 将命令行终端转化为可视化桌面环境(如GNOME、KDE)。 - 支持窗口管理、图标显示、菜单交互等基础功能。 - *示例*:通过X服务,用户可同时运行多个图形化程序(如Firefox和LibreOffice)。 ##### **(2)实现网络透明性** - **关键特性**:应用程序可在远程服务器运行,但图形界面显示在本地。 ```bash ssh -X user@remote-server # 启用X11转发 gedit & # 远程运行gedit,界面显示在本地 ``` - 适用于远程图形管理(如服务器维护)[^1][^3]。 ##### **(3)硬件抽象设备管理** - 统一管理不同显卡、显示器、输入设备的驱动交互。 - 支持多显示器配置和分辨率调整(通过`xrandr`工具)。 ##### **(4)支持窗口管理器** - X服务提供**基础绘图能力**,窗口管理器(如i3、Openbox)在其上实现: - 窗口布局 - 标题栏渲染 - 虚拟桌面管理 #### **3. 核心组件** | 组件 | 作用 | 典型路径 | |---------------|-------------------------------|----------------------| | X Server | 直接控制硬件 | `/usr/bin/Xorg` | | X Client | 应用程序(需图形界面) | 如`/usr/bin/gedit` | | X Protocol | 客户端服务器通信协议 | 网络传输层协议 | | 窗口管理器 | 管理窗口外观和行为 | 如`/usr/bin/i3` | #### **4. 工作流程** 1. **启动X服务**:系统通过显示管理器(如GDM)或`startx`命令启动X服务器。 2. **加载配置**:读取`/etc/X11/xorg.conf`定义的分辨率、输入设备等[^4]。 3. **运行客户端**:应用程序通过X协议向服务器发送绘图指令。 4. **事件处理**:服务器将鼠标/键盘事件转发给对应客户端。 #### **5. 现状演进** - **主流实现**:现代Linux使用**X.Org Server**(开源实现)。 - **替代技术**:Wayland协议逐渐取代X服务(更轻量、安全),但X11仍广泛兼容。 - *日志位置*:故障排查可查看`/var/log/Xorg.0.log`[^3]。 > **总结**:X服务是Linux图形生态的基石,通过解耦应用程序硬件,实现跨网络图形显示和多任务GUI环境。其网络透明性设计在服务器管理中尤为关键[^1][^3]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值