X11 x11

概念

Display

a workstation consisting of a keyboard, a pointing device such as a
mouse, and one or more screens.
Display是工作站,而不是通常意义上的显示设备。显示设备在X11中的术语是Screen,多台显示设备、键盘、鼠标等一起可以构成一个Display。一个Display不管有多少个Screen,都只能有一个X
Server Process与之对应。

  1. 在网络中的标识

host:display\[.screen\]
其中host是网络地址。display是\>=0的整数,表示Display。screen是从0开始编号的数字。

  1. Xinerama

可以把某个Display上所有的显卡和显示器组合成一个巨型显示器,这种技术即称为Xinerama,与Cinerama(全景电影)仅一个字符的差别。有了Xinerama,一个Window可以用多个显示器来显示。

  1. Seperate Screens

某个Display的多个显示设备也可配置成seperate
screens,每个Screen都会有自己独立的地址,此时,Window不能跨显示设备来显示,也不能在两个显示设备之间移动,只有鼠标可以在两个显示设备间移动。Seperate
Screens技术早于Xinerama,在演示教学中还很有用。

X Window Server

  1. 网络连接
  1. 端口

X
Server的端口一般从6000开始,:0用的是6000,:15用的即会是6015。不管该X
Server对应的Display有几个screen,都是通过这同一个端口来访问,确定screen是X
protocol的事情。

  1. 本地连接

如果Display的标识为:0,Linux中一般会用Unix domain
sockets来进行连接。在Display的标识的host中取为“unix”,即可使用Unix
domain
sockets进行连接。需要注意的是,host用了localhost会启用TCP/IP的本地lo接口,性能很受影响。在用Unix
domain
sockets连接完成后,一般客户端和服务器还会用共享内存来交换数据,这要求有MIT
SHM extension。

  1. xorg.conf

要在screen section中设定screen的大小,添加如下subsection:

`` example
SubSection "Display"
Depth 24
Modes "1280x1024" "800x600"
EndSubSection


如果用户更改了分辨率并不会更改screen的大小。

  1. 快捷键
  1. Ctrl-Alt-Backspace Zap X Server
  2. Ctrl-Alt-Fn Switch Virtual Terminal(chvt)

<h2 id="X认证">X认证</h2>

<h3 id="认证方法">认证方法</h3>

  1. Host-based X authentication

使用xhost程序来控制连接到X
display的主机列表。在host列表上的主机上,任何用户都可以使用X
display。

  1. Key-based X authentication

使用xauth程序来控制连接到X display的X authentication keys(display
keys)列表。这些keys一般存放在客户端的文件中(如~/.Xauthority),连同客户端需要连接的display的数据。客户端通过发送xauth文件中信息给服务器来获取服务器的认证。
display key都是从X
server获取的。如果启动xinit或startx,这两个程序在启动X
server的同时,还会把X server的display key写入启动帐户的auth
data(文件)中。如果你去连接运行了XDM(X Display
Manager)的远程主机,在建立XDM session时,你的X server的display
key会同时被传送到远程的帐号中去。 参考:X" target="_blank">http://docstore.mik.ua/orelly/networking_2ndEd/ssh/ch09_03.htm">X
Forwarding

<h2 id="配置">配置</h2>

<h3 id="Xinerama与Multi-Screen的区别">Xinerama与Multi-Screen的区别</h3>

Xinerama是把多个显示设备组合成了单个屏幕,这个硬件层面的屏幕足够容纳所有的显示设备,然而,不同显示设备的大小是不统一的,这就导致硬件屏幕的一部分可能无法显示出来。因此,在使用xinerama时,会出现光标找不到的情况,其实是光标被移动到了显示设备之外的区域。使用Multi-Screen就不会有这种情形,因为每块屏幕是独立的,并没有无法显示的区域。

<h2 id="虚拟机上成功远程使用xclock的步骤">虚拟机上成功远程使用xclock的步骤</h2>

  1. client和server端都安装xauth
  1. server端启动vncserver,注意其端口号
  1. 在client设置DISPLAY变量,如果server的vncserver端口号为6001,则DISPLAY值为"serverip:1.0"
  1. server端执行下面命令:
example

xauth extract - :1.0 | ssh clientip xauth merge -


  1. 在client端执行xclock

<h2 id="Utility">Utility</h2>

  1. xdpyinfo 显示 X server 相关信息。
  2. xev 打印X event的内容。
  3. xset 设置用户与display相关的参数。
  4. showrgb 显示 X server

设置好的颜色名字,与/etc/X11/rgb.txt的内容相同。

  1. xrandr RandR extension的命令工具,可设定screen的大小,orientation,

reflection。

<h2 id="MultiseatX">MultiseatX</h2>

<https://help.ubuntu.com/community/MultiseatX>
multiseat是指单个机器让多个自带显示器、键盘、鼠标的设备来使用,它不同于multi-head,multi-head是让一个用户同时使用多个显示器。

<h2 id="Linux文件关联原理解析">Linux文件关联原理解析</h2>

<h3 id="Reference:">Reference:</h3>

archwiki: Default Application freedesktop:
Specifications/mime-actions-spec

<h3 id="xdg-open">xdg-open</h3>

包括chrome在内的很多程序都是通过调用xdg-open来打开文件和文件夹,所以我们先来看看这个命令。

example

xdg-open file:///home/
xdg-open /tmp/foobar.png


通过which命令便可知xdg-open是位于/usr/bin/xdg-open的shell脚本,这个脚本的基本工作流程是:

  1. 判断桌面环境,将其写入DE变量,如gnome、kde、xfce、lxde。所以单用openbox或awesome之类的窗口管理器的,可以在.xinitrc中强制指定DE。
  2. 根据DE变量,调用诸如gnome-open、kde-open、exo-open等命令。
  3. 如果不是桌面环境,就调用通过xdg-mime命令查询到的对应程序打开。

xdg-mime也是shell脚本,它主要的工作就是维护 mime-type和default
program之间的对应关系。 xdg-mime用法很多,其中我们关心的query
default,也就是查询对应的默认程序的工作原理如下:

  1. 首先探测桌面环境,存入DE变量。
  2. 如果是KDE下,用ktraderclient命令查询
  3. 其他情况,依次查询\$HOME/.local/share/applications/default.list和/usr/share/applications/default.list

根据Ref2的构思:新装的软件则将配置放入全局mimeapps.list中,用户则可以修改用户级的mimeapps.list,不过看xdg-open和xdg-mime的源码,这个构想应该还没完全实现。

<h3 id="default.list">default.list</h3>

default.list文件格式相对简单,如:

example

application/x-php=gedit.desktop
application/x-python=gedit.desktop


后面的.desktop文件,必须得存在于\$HOME/.local/share/applications或/usr/share/applicaitons目录下,且满足特定的格式,见Desktop
Entry Specification。

<h3 id="mimeapps.list">mimeapps.list</h3>

mimeapps.list类似于default.list,但其有两端,一段和后者相同:\[Default
Applications\],另一段是\[Added Associations\]。
格式可以参考Ref2,简单用法和default.list一样。 相关测试结果(GNOME 3.2,
KDE 4.7.3): gnome-open: \[Added Addociations\]段貌似无效。 gnome-open:
mimeapps.list 优先级高于 default.list
KDE下mimeapps.list,default.list均无效。

<h3 id="Result">Result</h3>

从以上的分析可知,目前想要修改默认程序,根据桌面的不同,有以下步骤:
如果是KDE,只能使用桌面环境自带的文件关联程序
其余情况,应该优先使用桌面环境自带的文件关联程序 。
\[不推荐,不清晰,未测试\]可通过xdg-mime对文件关联进行设置,可自动对应多个桌面环境。
GNOME中,通过对gnome-open的试验,发现其支持mimeapps.list
,且优先级大于default.list,优先设定mimeapp.list。
\[不推荐\]最后可修改default.list。
顺便一提,文件夹对应的mime是inode/directory,这个确实不太好找。

<h3 id="Tips">Tips</h3>

对arch用户,当gnome的default.list混乱时,可以参见AUR上gnome-defaults-list包。
引自:http://ninehills.info/2011/12/01/linux-default-program.html

<h2 id="nvidia配置注意事项">nvidia配置注意事项</h2>

nv驱动是开源的,而nvidia而是受限驱动,nvidia-settings工作只针对受限驱动。Ubuntu中安装好nvidia-current驱动后,需要用nvidia-xconfig来自动生成xorg.conf文件,重启X,此时即会使用受限驱动。由于xorg配置了标准的glx模块,而nvidia需要使用自带的glx,如果不设置好次序,会在Xorg.0.log中发现错误信息,说是“无法初始化glx模块,重装nvidia驱动”云云。其实重装了驱动也没用,关键是加载libglx.so的次序问题。在Files
Section中设置如下次序:

example

ModulePath "/usr/lib/nvidia-current/xorg"
ModulePath "/usr/lib/xorg/modules"


让xorg在搜索模块时先从nvidia的目录开始找,再到标准目录下去找,重启X后可以日志中发现如下信息:

example

Support for GLX with the Damage and Composite X extensions is enabled.


在Device Section中设置如下两个选项:

example

Option "HWcursor" "True"
Option "Accel" "True"


可在日志中发现如下信息: (\*\*) NVIDIA(0): Option "HWcursor" "True"
(\*\*) Dec 31 14:55:39 NVIDIA(0): Enabling RENDER acceleration

<h2 id="T410安装NVIDIA显卡闭源驱动后亮度不能调节问题">T410安装NVIDIA显卡闭源驱动后亮度不能调节问题</h2>

在Device Section中加入下面这一行:

example

Option "RegistryDwords" "EnableBrightnessControl=1"


<h2 id="找出哪个窗口获取了X selection的办法">找出哪个窗口获取了X selection的办法</h2>

出现了鼠标无法选择文本的问题,stackexchange上有这样的解决办法:
<http://unix.stackexchange.com/questions/75534/selecting-highlighting-text-problem>

Possibly something is constantly stealing the X selection. To find out
who it is. You could compile this:

c

#include
#include
#include

int main() {
printf("0x%x\n", XGetSelectionOwner (XOpenDisplay(0), XA_PRIMARY));
return 0;
}


With:

gcc that-file.c -lX11

That code is to return the window ID of the owner of the PRIMARY X
selection. Then you can look up that window ID in the output of xwininfo
-root -all:

xwininfo -root -all \| less "+/\$(./a.out)"

The window that owns the selection may not have a name, but you can look
at its parent or grant parent for more clue. Once you find the ancestor
that is managed by the Window manager, you can get the process ID
(assuming the window is displayed by a local process) with:

xprop -id that-id <sub>NETWMPID</sub>

Example:

\$ xwininfo -root -wm -tree \| grep -B3 \$(./a.out) 24 children:
0x2800024 "Sun 12 May - 21:40 - zsh (2)": ("xterm" "XTerm")
1920x1059+0+19 +0+19 1 child: 0x280002f (has no name): () 1920x1059+0+0
+0+19

0x280002f owns the PRIMARY selection, whose parent is "xterm" (0x2800024
managed by the Window Manager).

\$ xprop -id 0x2800024 <sub>NETWMPID</sub> <sub>NETWMPID</sub>(CARDINAL)
= 9707

\$ ps -fp 9707 UID PID PPID C STIME TTY TIME CMD chazelas 9707 1 0 08:50
? 00:00:02 xterm

And that's its pid.

Once you know who owns that selection, it may become clearer what's
happening.

<h1 id="Xfce <span class="tag" tag-name="xfce"><span class="smallcaps">xfce</span></span>">Xfce <span class="tag" tag-name="xfce"><span class="smallcaps">xfce</span></span></h1>

<h2 id="配置应用程序菜单">配置应用程序菜单</h2>

<http://wiki.xfce.org/howto/customize-menu>

<h2 id="compiz">compiz</h2>

<https://wiki.archlinux.org/index.php/Compiz>
<https://help.ubuntu.com/community/CompositeManager>

<h1 id="D-Bus">D-Bus</h1>

<h2 id="概念">概念</h2>

D-Bus提供两种守护进程:a system daemon and a per-user-login-session
daemon。system
daemon处理诸如“有新的硬件被添加进来”,“打印队列被更改”等事件。而per-user-login-session
daemon主要用于用户进程之间交换事件信息。 Unlike more heavyweight
conventional messaging middleware, D-Bus is non-transactional. It is
stateful and connection-based, however, making it "smarter" than
low-level message-passing protocols such as UDP. On the other hand, it
does carry messages as discrete items—not continuous streams of data as
is the case with TCP. Both one-to-one messaging and publish/subscribe
communication are supported. The daemon runs an actual bus, a kind of
"street" that messages are transported over, and to which any number of
processes may be connected at any given time.

<h3 id="Object Model">Object Model</h3>

TCP、UDP等协议是对称的,数据总是从一个端口传入另一个端口。D-Bus的模型更为复杂一些,发送方与接收方可以不是同一种类型(Type)。
D-Bus中通信的endpoint被称为Object,Object由客户端进程创建,一个客户端进程可以创建多个object。D-Bus中可以传递的消息总共只有三种情况:

  1. client process对objects的请求。
  2. 从object到process的响应。
  3. 从object发出的单向消息,可以广播到所有连接上客户端进程中。(客户端进程已经注册了监听该消息)。

总的说来,D-Bus支持“1:1 request-reply”和1:n
publish-subscribe“两种模式。每个bus至少会有一个object,这个object即是bus自身,客户端进程通过查询该object可以知道bus相关的信息。

<h3 id="组成">组成</h3>

D-Bus由两个组件构成:dbus library,dbus daemon。dbus
library用于实现点对点的通信功能。dbus
daemon则为真实的通道,相当于“街道”,任意进程均可使用这条街道。

<h3 id="地址">地址</h3>

进程需要知道bus的地址后才能连接上去。一般情况下,bus地址是Unix-domain
socket,比如:/tmp/.hiddensocket。当然地址也可以是dbus
daemon正在监听的TCP端口,甚至更底层的连接方式。如何接到bus上,完全由dbus
library包装好,使用者不必关心。

<h3 id="配置">配置</h3>

dbus
daemon由dbus-launch命令启动,它需要–config-file选项用于指定配置文件。这些配置文件一般在以下位置:

example

/etc/dbus-1/system.conf
/etc/dbus-1/session.conf


<h3 id="连接">连接</h3>

<h2 id="工具">工具</h2>

<h2 id="dbus-launch">dbus-launch</h2>

dbus-launch可用于命令行方式启动message
bus。dbus-launch会用dbus-daemon创建session bus,与dbus
daemon不同之处在于,dbus-launch会自动退出,它的输出可用作Shell执行的脚本。比如下面的命令:

example

dbus-launch --sh-syntax --exit-with-session


它的输出为:

bash

DBUS_SESSION_BUS_ADDRESS='unix:abstract=/tmp/dbus-pGQgsgwTpe,guid=e918647ba637ea6c3998ecfe55f39036';
export DBUS_SESSION_BUS_ADDRESS;
DBUS_SESSION_BUS_PID=2572;


<h1 id="fcitx">fcitx</h1>

配置文件: 全局: *usr/share/fcitx/data/conf 用户: ~*.config/fcitx/conf
关闭联想功能: CTRL+L是切换键

<h1 id="Menu">Menu</h1>

Gnome菜单编辑器Alacarte 也可手动编辑.desktop文件添加菜单项,一般位置为:

example

~/.local/share/applications/

``

VNC

VNC实现Windows远程访问Ubuntu 16.04(无需安装第三方桌面)

<https://www.cnblogs.com/xuliangxing/p/7642650.html> 安装dconf-editor

依次展开org-\>gnome-\>desktop-\>remote-access,然后取消
“requlre-encryption”的勾选即可。