X系统和X启动流程和自启动

linux图像显示采用的是X Window system(也可以叫做X11或者直接叫X)这套协议,我们平时经常见到的X就是指的这套协议。这套协议里面规定的架构是C/S架构,即客服端/服务器架构。客服端是x client,服务端是x server。

20221122142435

服务端(x server)负责管理键盘、鼠标、显卡、显示器等输入输出设备。客户端收到来自键盘、鼠标等输入设备的数据,通知服务端进行显示,服务端通过控制输出设备进行输出。这样的好处是,客户端和服务端不用在一台电脑上,客户端也可以在网络上。

客户端(x client)客服端就是计算机上运行的程序(比如Firefox等)。客户端想要显示图形,必须通过服务端,然后让服务端来负责显示。

X系统详解

X窗口系统(X Window System)是Linux图形用户环境的基础,基于一种够独特的服务器/客户机架构。主要包含如下几个部分:

a)显示服务器 (X server)

b)显示管理器 (Display Manager) 例如(gdm kdm xdm等)

c)窗口管理器 (Window Manager) 例如(mutter,metacity ,fluxbox等)

d)widget库定义了一套图形用户界面的编程接口。应用程序的开发人员调用widget库来实现具体的用户界面,如按钮、菜单、滚动条、文本框等。为了便于编写GUI程序,诞生了QT,GTK等一系列图形库,从而方便程序员给程序添加GUI。

在使用中一般都是b,c,d三者集合起来构成一个完整的集成工作环境,例如KDE ,GNOME等,这就是我们平时所说的广义上的XClient。需要向X服务器请求服务的程序就是X客户端程序。

桌面环境是把各种X有关的东西(除了X服务器)整合在一起的“大杂烩”。这些程序包括像gedit这样的普通应用软件、窗口管理器、显示管理器和widget库。无论桌面环境如何复杂,最后处理图形输出的仍然是X服务器。

X系统的启动过程

X系统的启动过程基本是由显示管理器完成的。显示管理器需要做下面的工作:

  1. 启动X服务器
  2. 提供一个界面友好的屏幕,等待验证用户的身份。
  3. 执行用户的引导脚本,这个脚本用于建立用户的桌面环境。

桌面环境的引导脚本是一段用Linux命令组成的脚本程序,叫做Xsession

Xsession通过启动窗口管理器、任务栏,设定应用默认值、安装标准键绑定等来启动整个桌面环境。

Xsession会一直运行,直到用户退出,或者说,当Xsession结束后,用户就退出了。

窗口管理器(Window Manager)是Xsession启动的唯一的前提程序(其他程序都在后台执行),如果没有这个前台程序,那么用户会在登录又立即退出系统。

显示服务器 (X server)

X服务器用于实际控制输入设备(如键盘、鼠标等)和位图式输出设备((如显示器)。准确地说,X服务器定义了给X客户机使用这些设备的抽象接口,但没有定义高级实体的编程接口,这意味着它不能理解“画一个按钮”这类语句。而必须告诉它:“画一个方块,周围有阴影,用户点鼠标左键的时候阴影要消失、、、方块上还要有字、、”。

xorg则是这套X11协议的程序实现,可以运行到电脑上。xorg主要是扮演服务端(x server)的角色。

显示管理器(DM)

显示管理器提供了一个登录界面,它的任务就是验证用户的身份,让用户登录到系统。可以说,图形界面的一切(除了它自己)都是由显示管理器启动,包括X服务器。

用户可以选择关闭显示管理器,这样就必须通过命令运行startx命令(或使用.login脚本)来启动X服务器。

startx的作用可以看作是Display Manager的一种隐性实现。它使用xinit命令,分别根据/etc/X11/xinit/xinitrc/etc/X11/xinit/xserverrc中所指定的设置唤起X。其中,xserverrc执行X server的运行任务;xinitrc则运行Xsession命令。

/etc/X11/Xsession脚本的内容可以看出,它也就是进入/etc/X11/Xsession.d/目录轮询地执行所有脚本。很明显,这些就是session初始化工作。

因此,Display Manager完成三个任务:1, X Server的启动; 2, X session的初始化; 3, X session的管理。

(1)XDM(默认的X Window System Display Manager) (2)GDM(gnome提供的Display Manager) (3)KDM(KDE提供的Display Manager) (4)SDDM 基于QML的显示管理器和KDM的后继者; 推荐用于 Plasma和 LXQt; ​(5)LightDM 跨桌面显示管理器,可以使用任何工具包中编写的各种前端,Ubuntu默认使用该管理器。

窗口管理器(WM)

X Server提供了基本的图形显示能力。然而具体怎么绘制应用程序的界面,却是要有应用程序自己解决的。

窗口管理器实现一个屏幕上显示多个X程序,实现调整程序大小,标题栏,最大化,最小化,关闭按钮,虚拟桌面这些功能。

如果没有窗口管理器,那么一次只能运行一个GUI程序,而且分辨率锁死,显然很不符合使用习惯。

窗口管理器往往集成在常见的桌面环境中,比如Xfce使用的窗口管理器为Xfwm,此外还有Gnome的mutter,KDE的Kwin等。

从本质上来说,窗口管理器是一种特殊的X客户端程序,因为这些功能也是需要向X服务器发送指令实现的。提供统一的GUI组件的(窗口、外框、菜单、按钮等)。否则,应用程序们各自为政,既增加了程序开发的负担,不统一的桌面风格对视觉也是不小的挑战。

WM的启动由DM控制,在gdm的登录窗口,我们可以进行选择。常见的WM有:Mutter, Metacity, fluxbox, fvwm, E17等

Openbox 是一个轻量级、可高度定制以及支持大量标准的窗口管理器,几乎无冗余软件,仅是一个窗口管理器,比较适合嵌入式应用环境。

Metacity曾经是GNOME桌面环境下默认的复合窗口管理器。在GNOME 2.2正式引进Metacity之前,GNOME陆续使用了Enlightenment和Sawfish作为它的窗口管理器。虽然Metacity是GNOME工程的一部分来并且被设计为集成进GNOME桌面,但它并不需要GNOME才能运行。同样GNOME也可以使用各种不同的窗口管理器,只要它们支持ICCCM规范。Metacity由GTK+实现,这使得它可以主题化并与其他GTK+应用程序相融合。

2011年,Gnome 3 发布,Metacity被mutter代替。Mutter 是Gnome 3的窗口管理器,用来取代原本的Metacity,Gnome Shell实际上是Mutter的一个插件,Mutter是Metacity Clutter的缩写。它使用了Clutter这个图形库,支持OpenGL。

Xsession

查看系统内置的xsession

~$ ll /usr/share/xsessions/
total 28K
drwxr-xr-x 2 root root 4.0K Nov 2 11:54 .
drwxr-xr-x 162 root root 4.0K Nov 2 11:54 ..
-rw-r--r-- 1 root root 1.5K Jan 21 2017 LXDE.desktop
-rw-r--r-- 1 root root 86 Aug 6 2011 lightdm-xsession.desktop
-rw-r--r-- 1 root root 198 Nov 24 2016 openbox.desktop
-rw-r--r-- 1 root root 5.4K Nov 12 2016 xfce.desktop

修改lightdm默认登陆的Xsession

vim /etc/lightdm/lightdm.conf

autologin-user=root
autologin-user-timeout=0
autologin-session=Openbox

X Clients

X客户端程序,顾名思义,就是使用X服务的程序。firefox,gedit等等都属于X Client程序。

X Client部分值得考虑一下的就是DISPLAY环境变量。它主要用于远程X Client的使用。该变量表示输出目的地的位置,由三个要素组成:

[host]:display[.screen]

host指网络上远程主机的名称,可以是主机名、IP地址等。默认的host是本地系统,你可以在自己系统上echo $DISPLAY看一下。

display和screen分别代表输出画面的编号和屏幕的编号。具体细节由于硬件的缺乏,还有待进一步研究。

startx

startx其实是个脚本,最终调用的是xinit命令,其用法如下:

xinit用法

xinit 的用法为: xinit [[client] options ] [-- [server] [display] options]

  • client 用于指定一个基于 X 的应用程序, client 后面的 options 是传给这个应用程序的参数
  • server 是用于指定启动哪个 X 服务器,一般为 /usr/bin/X 或 /usr/bin/Xorg
  • display 用于指定 display number ,一般 为 0 ,表示第一个 display , option 为传给 server 的参数。

如果不指定 client , xinit 会查找 HOME ( 环境变量 ) 目录下的 .xinitrc 文件

  • 如果存在这个 文件, xinit 直接调用 execvp 函数执行该文件。
  • 如果这个文件不存在,那么 client 及其 options 为: xterm -geometry +1+1 -n login -display :0 。

如果不指定 server , xinit 会查找 HOME( 环境变量 ) 目录下的 .xserverrc 文件.

  • 如果存在这个文件, xinit 直接调用 execvp 函数执行该文件.
  • 如果这个文件 不存在,那么 server 及其 display 为: X :0 。
  • 如果系统目录中不存在 X 命令,那么我们需要在系统目录下建立一个名为 X 的链接,使其指向真正的 X server 命令( Ubuntu 下为 Xorg )。

startx方式

由对 startx 脚本的分析,我们可以知道 startx 主要有三种启动方式:

  1. 、一种是自己指定要启动的 client 和 server , 例如: startx /usr/bin/xclock -- /usr/bin/X :0 ;

b)、一种是通过在 $HOME 下新建 .xinitrc 文件来指定要启动的多个 client 和 .xserverrc 来指定要启动的 server;

c)、还有一种是直接输入 startx 而不指定参数,这也就是我们启动 gnome 桌面的方法。

在这种启动方法中, startx 脚本会先去看系统目录( /etc/X11/xinit/ )下的 rc 文件是否存在,如果不存在就会用默认的 xterm 和 /usr/bin/X 来启动 xinit 。

startx 的默认启动过程为:

  • startx 调用并将系统文件 /etc/X11/xinit/xinitrc 和 /etc/X11/xinit/xserverrc 作为参数传给 xinit
  • xinit 就会先执行系统文件 /etc/X11/xinit/xserverrc 以启动 X Server
  • 然后执行 /etc/X11/xinit/xinitrc
  • xinitrc 则会执行脚本 /etc/X11/Xsession
  • Xsession 则会按顺序调用执行 /etc/X11/Xsession.d 目录下的文件
  • 最终调用了 gnome-session 这个用于 启动 GNOME 桌面环境的程序

开机自启图形界面

自动登录用户

第1步:修改/usr/share/lightdm/lightdm.conf.d/01_debian.conf

autologin-user=root
autologin-user-timeout=0

第2步:修改lightdm-autologin

vim /etc/pam.d/lightdm-autologin

# change:
auth required pam_succeed_if.so user != root quiet_success
# to:
auth required pam_succeed_if.so user != anything quiet_success

自动启动程序

/etc/xdg/autostart 目录下存放着图形登录后自启动的启动器(.desktop)文件,我们可以为自己程序写一个.desktop文件,然后放到这里来,实现开机自启动。

也可以在当前用户目录下,即$HOME下,路径为$HOME/.config/autostart下放置.desktop文件可以起到为当前用户创建一个图形登录启动文件

[Desktop Entry] //必须
Version=1.0.0 //版本,可选
Name=FanTest //程序名,必须
Name[zh_CN]=帆 //中文程序名,可选
Exec=env 环境变量=/path/to/your/var /path/to/your/app
Icon=/home/fan/FanTest/FanTest.png //程序图标,可选。路径必须是绝对路径,末尾不能有空格,否则将会导致无法加载图标
Type=Application //类型为应用程序,必选

编辑后保存,在终端中输入以下命令为其添加可执行权限,这样就可以双击打开了,也可以复制到桌面作为快捷方式

无桌面自启

  1. 切换到/usr/share/xsessions目录
  2. 创建desktop文件
touch custom.desktop

# 文件内容参考以下内容,按需修改即可
[Desktop Entry]
Encoding=UTF-8
Type=XSession
Exec=/usr/bin/qtcreator
Name=qtcreator
Comment=desktop entry for qtcreator

直接启动

  1. 修改默认运行级别sudo systemctl set-default multi-user.target
  2. 设置用户自动登录
  3. 禁用lightdmecho "false" > /etc/X11/default-display-manager
  4. 启动自定义的界面程序

编写文件/usr/bin/autologin,添加执行权限

#!/bin/bash
/bin/login -f #你的用户名

编写文件/etc/init/tty1.conf

# tty1 - getty
#
# This service maintains a getty on tty1 from the point the system is
# started until it is shut down again.

start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty -n -l /usr/bin/autologin -8 38400 tty1

自定义的界面程序

export client=qtcreator
startx

作死修复

lxde lightdm openbox