Wayland&Weston

1.编译

  • 预设环境
    $export WLD=“~/xxxxxxxxx”  //定义一个wayland目录,编译生成到这里
    sudo apt install meson
    sudo apt install some_depenced_libs
  • Wayland
    $ git clone https://gitlab.freedesktop.org/wayland/wayland.git 
    $ cd wayland 
    $ meson build/ --prefix=$WLD 
    $ ninja -C build/ install 
    $ cd .. 
  • Wayland protocols
    $ git clone https://gitlab.freedesktop.org/wayland/wayland-protocols.git
    $ cd wayland-protocols
    $ meson build/ --prefix=$WLD
    $ ninja -C build/ install
    $ cd ..
  • Weston
    $ git clone https://gitlab.freedesktop.org/wayland/weston.git
    $ cd weston
    $ meson build/ --prefix=$WLD
    $ ninja -C build/ install
    $ cd ..
  • 第三方依赖库的编译

    需要的第三方库

    Libxml2-dev
    Libexpat-dev
    Libffi-dev
    Libinput-dev
    Libdrm-dev
    Libxkbcommon-dev
    libpixman-1-dev
    libcairo2-dev
    libudev

它们有的通过configure配置然后make, 有的通过mesa, ninja编译. 需要注意设置正确的PKG_CONFIG_PATH,使的pkg-config可以找到相关的库信息。 如果是mesa,留意目录下是否有meson_options.txt, 其中定义了各种编译选项,可对它进行修改。

  • meson

交叉编译

在meson系统中进行交叉编译,需要为meson中添加参数 –cross-file xxx_filename, 在xxx_filename中定义gcc等的路径路径

下面是一个示例

    [binaries]
    c = '/opt/cross-arm/bin/arm-linux-gnueabihf-gcc'
    cpp = '/opt/cross-arm/bin/arm-linux-gnueabihf-g++'
    ld ='/opt/cross-arm/bin/arm-linux-gnueabihf-ld'
    strip= '/opt/cross-arm/bin/arm-linux-gnueabihf-strip'
    pkgconfig ='/usr/bin/pkg-config'

    [host_machine]
    system = 'linux'
    cpu_family = 'aarch64'
    cpu = 'cortex-a73'
    endian = 'little

在configure系统中,则是export GCC CFLAG 等环境变量

指定输入输出

meson build_dir/ sourc_code_dir/

2.运行

  • configure file

    copy weston.ini to ~/.config/

  • run weston.
    1. login as root
    2. ./weston –tty=2
    3. Ctrl+Alt+Backspace –> 退出Weston界面

    如一般用户启动weston,这时要借助weston-launch 来完成。 相关code:libweston/weston-launch.c

  • run weston-client test
    1. login as root
    2. export WAYLAND_DISPLAY=wayland-1

示例1, 指定backend 和shell

    Server: ./weston --tty=2 --shell=fullscreen-shell.so --backend= drm-backend.so
    Client: weston-simple-dmabuf-egl

示例2

    Server:./weston --tty=2 --shell=fullscreen-shell.so --backend=fbdev-backend.so
    Client./weston-simple-damage

3.Wayland

3.1 code的组成

wayland主要由三部分组成。

  • Wayland提供了protocol的定义方式

在路径protocol文件夹下,以xml的形式定义了Wayland的核心协议。

如下面的xml,就定义了wl_display

    <interface name="wl_display" version="1">  
           <description summary="core global object">
                  The core global object.  This is a special singleton object.  
                  It is used for internal Wayland protocol features.   
           </description>
        .....
    </interface>

  • xml到code的转换工具

xml到code的转换工具是wayland-scanner,它的source code在wayland目录下,可通过编译生成它。

wayland_scan

  • wayland还实现了一个高效率的 Server+Client通信模式

    • Server端,主要是使用epoll+socket监听Client端事件,并对收到的消息反序列化。

      server_epoll

    • Client端:wayland-client提供了已实现的序列化接口

      client_epoll

总之,官方提供的Wayland源码,主要包括协议的定义、协议到代码的生成工具,以及一套实现好的通信模型

3.2 基础概念

几乎所有的Wayland API都需要Wayland全局对象作为参数。

名称 作用
wl_display 表示与服务器的连接。
wl_registry 全局对象注册表,全局对象需要通过它获取。
wl_compositor 窗口合成器,也是服务器。
wl_shm 内存管理器,与窗口合成器共享内存用。
wl_shell 支持窗口操作功能。
wl_seat 输入设备管理器。 。 通过capabilities( )回调函数得到pointer、keyboard等
wl_pointer 代表鼠标设备。
wl_keyboard 代表键盘设备。

Wayland没有提供Get函数来获取以上全局对象,只能通过wl_registry获取全局对象

3.2.1 Client端object的使用

Wayland中server提供给client使用的对象可以归为 global object和 resource object。 Global 也是一中resource。

Global object如 wl_display, wl_compositor, wl_seat 等。 它们在client端是通过bind来获取到一个client 对应对象,然后就可以对它进行操作

Resource object 在client端是通过Global object 来创建的, 如 wl_surface, wl_shell_surface 等。

client_object

object_generation

3.2.2 Server端object的实现

Global 资源的创建: wayland/src/wayland-server.c

  1. wl_global_create( …., bind_xxx_function )
  2. bind_xxx_function // 在client中调用wl_registry_bind函数时被call

    • wl_resource_create( )
      wayland protocol 提供的接口,创建一个resource object,并把它插入到client的map表中,以后就可以通过ID 找到对应的resource obj,有利于server<–>client 通讯调用对应函数

    • wl_resource_set_implementation( ) // 设定资源接口的实现, 可供client通过IPC调用
    • wl_priv_signal_emit( ) // wl_client_add_resource_created_listener will be notified

普通 Resource 的创建
应该是由某些 对global 资源的操作触发

  1. wl_resource_create()
  2. wl_resource_set_implementation( )

3.2.3 Client Server通讯

Listener 是server –> client 的通知方式. Client 注册listener 给server,有监听事件发生,server发信息给client.

Server侧发生通知的函数命名特征: xxxx_send_xxxx( )

3.2.4 Wayland Server实现

Wayland_Server_APIs

3.2.4 Wayland Client实现

Wayland_Client_APIs

3.3 简单的wayland app 流程

simple_wayland_app

3.4 Wayland log

需设置环境变量: export WAYLAND_DEBUG=1

wayland_log

3.5 xml

wayland_xml

其中最重要的wayland.xml中定义了如下接口:

    ./wayland/protocol/wayland.xml
        wl_display
        wl_registry
        wl_callback
        wl_compositor
        wl_shm_pool
        wl_shm
        wl_buffer
        wl_data_offer
        wl_data_source
        wl_data_device
        wl_data_device_manager
        wl_shell
        wl_shell_surface
        wl_surface
        wl_seat
        wl_pointer
        wl_keyboard
        wl_touch
        wl_output
        wl_region
        wl_subcompositor
        wl_subsurface

3.6 在线查看 wayland协议

4.Weston 简介

Weston是基于wayland协议,实现的Compositor。

Weston的入口在(这里以10.0.0为例):

weston-10.0.0./compositor/main.c
weston-10.0.0./compositor/executable.c

4.1 框架与对象

  • 框架

weston_architecture

Weston中有以下几个主要部分:Shell、Compositor、Render、backend、Input

  1. Shell:窗口管理器,画面层级、窗口信息、窗口生命周期、Focus窗口等等一些偏向于业务层的处理。默认的shell为desktop-shell,同时提供了其他shell实现(如ivi-shell)
  2. Compositor:负责画面的合成,使用DRM连接output,将画面输出到实际显示设备。
  3. Render:负责渲染,比如gl-render,做一些纹理贴图操作。
  4. Input:libinput模块,与evdev、uvdev模块交互,从底层设备节点接收touch、key等输入
  5. backend: Weston 使用后端的概念来抽象其运行环境的底层接口。后端负责处理输入和生成输出
  • 对象

weston_object

image

4.2 main函数的基本框架

实现内容:

  1. 解析cmdline
  2. 初始化log系统
  3. 创建wl_display对象,并侦听client接入
  4. 创建weston_compositor对象,从而创建global resource compositor 和 shm, 以前其他资源
  5. load backend, 默认为drm_backend, 在drm_backend初始化的过程中会load gl_renderer
  6. load shell, 默认为desktop-shell.so
  7. 调用wl_display_run( ) 循环等待event的发生
int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_data){
    // 初始化 layoutput_list
    wl_list_init(&wet.layoutput_list);
    ...
    //  parse command line
    ...
    //  init log system
    ...    
    // 调用wayland提供的函数wl_display_create()
    // 创建 wl_display 对象
    display = wl_display_create();
    ...    
    // 创建 weston_compositor 对象  
    // --> 创建 global resource compositor and shm 以及其他resource
    weston_compositor_create( );    
    // 读取config for compositor
    ...    
    // load backend,通用的为load_drm_backend( )
    // 最终调用 对应backend实现的weston_backend_init( )
    // 在backend 初始化的过程中会装载 gl_renderer
    load_backend(compositor, backend)
    ...    
    // 创建socket, 侦听client的连接请求
    weston_create_listening_socket(display, socket_name)
    ...
    // load shell, 默认为 desktop-shell.so
    wet_load_shell(compositor, shell, ...)
    ...
    // loop, 循环等待event的发生
    wl_display_run(display)
    ...
    // 退出流程,资源的释放
}

4.3 backend创建

  • Weston 使用后端的概念来抽象其运行环境的底层接口。后端负责处理输入生成输出
  • 作为 libweston 的用户,Weston 可以在不同的后端上运行,包括嵌套在其他 Wayland 合成器中的方式(使用 wayland 后端),也可以在 X11 上运行,或者在独立的后端上运行,例如 DRM/KMS。
  • 大多数情况下,人们应该允许 Weston 自动选择后端,因为它会产生最佳结果。例如,在已经运行另一个图形环境的机器上运行 Weston 时,它会自动选择合适的后端,无论是另一个 Wayland 合成器还是 X11 服务器。
  • 只有在你知道 Weston 自动选择的后端不是最佳选择,或者你想使用不同于默认加载的后端时,才需要手动指定后端。在这种情况下,可以使用 -B [backend] 命令行选项来选择后端。
  • 可用的后端包括:
    • drm:独立运行在 DRM/KMS 和 evdev 上(推荐)。
    • wayland:作为 Wayland 应用程序嵌套在另一个 Wayland 合成器实例中。
    • x11:作为 X11 应用程序嵌套在 X11 显示服务器实例中。
    • rdp:作为一个没有本地输入或输出的 RDP 服务器运行。
    • headless:无输入或输出运行,适用于测试套件。
    • pipewire:无输入,输出到 PipeWire 节点。

      backend_tree

weston_backend

weston_backend_init

weston_backend_init

{
 destroy()
 repaint_begin()   //composite之前调用
 repaint_cancel()  // 中途取消
 repaint_flush()   // composite 完成后调用, 可用于实现提交到display
 create_output()   // 创建weston_output
 device_changed()
 can_scanout_dmabuf()
}Weston_backend, Compositor->backend

4.4 shell创建

weston提供了多种shell,比如:desktop shell,ivi-shell, kiosk shell, fullscreen shell等

weston_shell

4.5 head和output

weston_head 和 weston_output 是libweston中的两个关键概念,用于管理显示输出和图像呈现。

weston_head(头部)

  • weston_head 表示一个连接器或监视器。
  • 在硬件驱动中,头部通常指的是一个显示器,但它也可以是另一个窗口系统中的窗口,或者是一个虚拟概念。
  • 头部是一个可以呈现图像的位置。
  • weston_head 负责以下任务:
    • 管理帧缓冲区。
    • 跟踪损坏区域。
    • 处理显示时序。
    • 管理重绘状态机。
  • 在显示硬件中,weston_head 表示一个CRTC(显示控制器),但仅在成功启用后才会如此。在头部的生命周期内,CRTC 可能会切换到另一个。
  • weston_head 的生命周期由libweston用户控制。
  • 您可以通过将至少一个weston_head 附加到weston_output 来构建一个可供合成器使用的weston_output 对象,然后使用 weston_output_enable() 启用该输出。已启用的输出无法重新配置,但这在未来可能会发生变化。您可以使用 weston_output_disable() 来禁用一个输出,然后重新配置它,但这会导致可见的故障。

weston_output(输出)

  • weston_output 决定了全局合成器坐标空间的哪一部分将被合成成图像以及何时进行合成。
  • 该图像在附加的头部上呈现。
  • weston_output 负责以下任务:
    • 帧缓冲区管理。
    • 损坏区域跟踪。
    • 显示时序。
    • 重绘状态机。
    • 视频模式、输出比例和输出变换是输出的属性。
    • 在显示硬件中,weston_output 表示一个CRTC,但仅在成功启用后才会如此。CRTC 可能会在输出的生命周期内切换到另一个。
    • weston_output 的生命周期由libweston用户控制。

head_output

下面是各种case的流程图

  • Heads are being created on compositor start-up with a backend that manages head lifetimes completely on its own

create_head

  • A compositor handles libweston notification of something with heads having changed. This happens on both compositor start-up and later due to hotplug change_on_head

  • A compositor creates and configures an output for a head or heads it wants to light up.

create_output

  • A compositor finds out a head has been disconnected and proceeds to destroy the corresponding output.

disconnect_head

  • The backend realises that a piece of hardware has disappeared and needs to destroy the corresponding head. The head is released, and even when the compositor is not listening for head destroy signal, the output gets automatically disabled, though not destroyed.

disable_output

4.6 layer, view, surface

layer_view_surface

view_list

4.7 create_surface

client_server_create_object

4.8 get_shell_surface

client_server_create_shell

4.9 create_pool

client_server_create_buffer

4.10 surface_attach surface_damage

client_server_surface_attach

create_shm_buffer

4.11 surface_commit

client_server_surface_commit

4.12 share buffer

4.12.1 create_shm_buffer

compositor_create_surface

4.12.2 import dmabuf

Client 基本流程如下:

  1. 绑定 linux_dmabuf wl_registry_bind(zwp_linux_dmabuf_v1_interface )

  2. 创建一个param对象 zwp_linux_dmabuf_v1_create_params( zwp_linux_dmabuf_v1)

  3. 在param中设置dmbuf的各种信息(fd,width, height), YUV时,通过数组导入多个plane信息 zwp_linux_buffer_params_v1_add(dmabuf_fd)

  4. 对param对象添加listener zwp_linux_buffer_params_v1_add_listener()

  5. 依据param在Server侧导入dmabuf对象 zwp_linux_buffer_params_v1_create( )

  6. 通过callback接收导入结果 params_listener callback create_succeeded()

Import_Linux_dmabuf_to_compositor

4.13 weston event loop

weston_event_loop

4.14 weston idle 处理

weston_idle_handler

4.15 gl-renderer

weston中的几个renderer

render

drm_backend

4.16 libinput

libinput

source code:https://gitlab.freedesktop.org/libinput/libinput

为了提高输入管理部分的模块性,Weston将对输入设备(键盘,鼠标,触摸屏等)的处理分离到一个单独的库,也就是libinput 中。具体地,它提供了设备检测设备处理输入事件处理等基本功能,类似于Android 中的EventHub。此外它还有pointer acceleration, touchpad supportgesture recognition等功能。

libinput更像是一个框架,它将几个更底层的库的功能整合起来。它主要依赖于以下几个库:

  1. mtdev: Multi-touch 设备处理,比如它会将不带tracking ID的protocol A转化为 protocol B。
  2. libevdev: 与kernel中evdev 模块对接。
  3. libudev:主要用于和 udevd(userspace device)的通信,从而获取设备的增加删除事件。也可从kernel获取。

Weston 中的输入管理模块与libinput对接,它实现了两大部分的功能:

  • 对输入设备的维护,
  • 对输入事件的处理。

对于输入事件既会在Weston中做处理,也会传给相应的 client。

从事件处理模型上来看,libinput主循环监听udev monitor fd,它主要用于监听设备的添加删除事件。如果有设备添加,会打开该设备并把fd加入到libinput的主循环上。另一方面,Weston中会将 libinput 的 epoll fd加入主循环。这样形成级联的epoll,无论是 udev monitor 还是input device的fd有事件来,都会通知到Weston和libinput的主循环。

Weston中支持三种输入设备,分别是键盘,触摸和鼠标。一套输入设备属于一个seat(严格来说,seat中包括一套输入输出设备)。因此,weston_seat 中包含weston_keyboard,weston_pointer 和weston_touch三个结构。系统中可以有多个seat,它们的结构被串在weston_compositor 的 seat_list链表中。

可以看到,对于焦点处理,每个设备有自己的focus,它指向焦点窗口,用于拖拽和输入等。成员focus_resource_list 中包含了焦点窗口所在client中输入设备 proxy对应的 resource 对象。在这个 list 中意味着可以接收到相应的事件。

libinput

wayland_input

对于焦点处理,每个设备有自己的 focus,它指向焦点窗口,用于拖拽和输入等。成员focus_resource_list 中包含了焦点窗口所在 client 中输入设备 proxy 对应的 resource 对象。在这个list中的resource就可以接收到相应的事件。 相关函数weston_keyboard_send_key(), 参考 4.18.10 key的处理

libinput_seat

input

4.16.1 udevd

udev 是 Linux 系统中的一个重要组件,用于动态设备管理。详细介绍一下:

udev 的全称是 “userspace device”,它是一个用户空间的设备管理工具。

  1. 功能: 接收来自内核的设备事件(uevents),例如设备的添加、移除或状态变化。 根据配置的一组规则,对设备进行识别和处理。 管理设备节点的权限和属性。 创建符号链接以提供有意义的设备名称。

  2. 工作流程:
    • 内核发出设备事件(uevent)。
    • udev 守护进程(通常是 systemd-udevd.service)接收事件。
    • udev 根据配置的规则匹配设备属性,识别设备。
    • 匹配的规则可能会创建符号链接、修改设备节点的权限或运行指定的程序。
  3. 规则文件:
    • udev 规则存储在不同目录下的文件中,例如 /usr/lib/udev/rules.d、/run/udev/rules.d 和 /etc/udev/rules.d。
    • 规则文件以 .rules 扩展名结尾。
    • 每行包含至少一个键值对,用于匹配和赋值。
    • 规则按照词法顺序处理,可以覆盖系统提供的规则。
  4. 库支持: udev 处理的所有设备信息存储在 udev 数据库中,并通过 libudev 库提供对存储数据和事件源的访问。

总之,udev 是一个关键的 Linux 设备管理工具,负责设备事件的处理、设备识别、权限管理和符号链接的创建

4.16.2 grab key

特殊情况下,shell对key的grab

grab_key

4.17 Client创建窗口

4.17.1 创建shm窗口

simple_create_window

4.17.2 创建egl窗口

create_egl_window

4.18 调用的backtrace

4.18.1 Client eglSwapBuffers

Client App 调用eglSwapBuffers 提交buffer给compositor的堆栈

client_eglSwapBuffers

4.18.2 wl_output global的创建

wl_output_create

4.18.3 wl_surface_commit

wl_surface_commit() 触发的后继操作

wl_surface_commit

4.18.4 drm_output_repaint()

drm_output_repaint() 的调用栈

drm_output_repaint

4.18.5 repaint_views

repaint_views() 的调用栈

repaint_views

4.18.6 第一次repaint的触发

first_repaint

4.18.7 送显的backtrace

shown_on_display

4.18.8 weston-desktop-shell

weston_desktop_shell

4.18.9 Weston_keyboard 进程的创建

在weston.ini中的【input-method】设置 path= 空 来不创建它, 函数launch_input_method() 会检查path.

keyboard

4.18.10 key的处理

handle_key

4.19 weston misc

4.19.1 定时器函数

  1. 创建定时器:wl_event_loop_add_timer()
  2. Enable 定时器:wl_event_source_timer_update( source, ms_delay) // ms_delay ==0 disable

4.19.2 wayland signal

  • wl_signal_add( , ) 添加一个listener到 listerner_list 链表
  • wl_signal_emit( , ) 触发一个signal, 从listener_list中调用每个listener notify
  • listerner_list 其实就是一个callback链表
      struct wl_listener {
          struct wl_list link;
          wl_notify_func_t notify;
      };
    

4 12.3 libwayland-egl.so.xxx

  1. 由 wayland-1.20.0/egl下文件编译生成
  2. 主要功能生成/销毁wl_egl_window, 并获取它的大小属性
  3. 使用: client/backend-wayland 可以利用它来生成wl_egl_window, 然后传给eglCreateWindowSurface( )
  4. 示例:./clients/simple-egl.c
  5. 好像不需要再分配buffer attch到 wl_surface, 参考simple-egl-window.c

4.19.4 weston_client_start()

在weston里定义, Weston call 它来 发起一个client 进程, 它会调用weston_client_launch()

4.19.5 weston-screenshooter

截屏进程, 被desktop-shell 进程call screenshooter_create( )创建

4.19.6 显示一帧的过程

  1. epoll收到event
  2. 构建compositor View_list, 含有order信息
  3. backend call gl_renderer set current surface
  4. 依次根据各个view的信息构建纹理,进行渲染
  5. eglswapbuffer()
  6. 遍历各个output,完成1~4
  7. repaint_flash() -> drm 上屏

4.19.7 repaint_timer_triger

repaint_timer_triger

4.19.8 Compositor sleep 相关

  1. In weston.init, 相关配置 idle-time, 单位sec
  2. 在函数weston_compositor_wake()设置 多长时间无操作进入sleep状态
  3. 定时器compositor->idle_source, 在weston_compositor_create()中创建
  4. 在weston_compositor_offscreen() , weston_compositor_sleep() 中关闭定时器

4.19.9 surface与buffer

  • Surface:

    • Surface 是 DRM 中的一个概念,用于描述一个可绘制的区域。它是一个抽象的图形表面,可以用于绘制图像、文本或其他内容。
    • Surface 可以是屏幕上的一部分,也可以是一个窗口、一个图像或其他可视元素。
    • 应用程序可以将图形绘制到 Surface 上,然后由 DRM 管理其显示。
    • 例如,在 DRM 中,一个窗口可以有多个关联的 Surface,每个 Surface 对应一个缓冲区。
  • Buffer:
    • Buffer 是一块内存区域,用于存储像素数据。在 DRM 中,它通常与 Surface 关联。
    • Buffer 可以是帧缓冲区、纹理、渲染缓冲区等。
    • Buffer 存储着图像的像素值,可以直接访问和操作。
    • 例如,当应用程序绘制图像时,它将像素数据写入 Buffer,然后由 DRM 将其显示在屏幕上。
  • 总结:
  • Surface 是一个抽象的图形表面,用于绘制图像。
  • Buffer 是实际存储像素数据的内存区域,与 Surface 关联。

4.19.10 drm_virtual_output

drm_backend_init_virtual_output_api () <- #ifdef BUILD_DRM_VIRTUAL 
                 <- /libweston/backend-drm/meson.build
                     <- remoting or pipewire  in configure

drm_virtual_output 用于 remoting or pipewire 场景, 在meson_options.txt 里配置

4.19.11 explicit-synchronization

explicit_sync

linux_explicit_synchronization

  1. 绑定显示同步对象

    wl_registry_bind(zwp_linux_explicit_synchronization_v1_interface)

  2. 针对surface创建sync对象

    zwp_linux_explicit_synchronization_v1_get_synchronization(expliciti_sync, surface)

  3. Client 进行Opengl渲染,并通过sync 创建一个fence_fd
    • eglCreateSyncKHR() --> sync
    • eglDupNativeFenceFDANDROID(sync) --> fence_fd
    • eglDestroySyncKHR(sync)
  4. 为surface_sync对象设置fence_fd, compositor将会等待它的完成

    zwp_linux_surface_synchronization_v1_set_acquire_fence(fence_fd)

  5. 创建release对象,用于监听server callback

    zwp_linux_surface_synchronization_v1_get_release(surface_sync)

  6. 提交surface,compositor开始合成并通过callback 返回要client等待的fence_fd

    wl_surface_attach()
    wl_surface_commit()

  7. Client 等待上面callback 返回的fence_fd

    eglCreateSyncKHR(..fence_fd..) –> sync
    eglWaitSyncKHR(..sync..)

4.20 shell

weston提供有四种shell, desktopIVIkioskfullscreen-shell

    ./kiosk-shell/util.c
    ./kiosk-shell/kiosk-shell.c
    ./kiosk-shell/kiosk-shell-grab.c
    
    ./ivi-shell/hmi-controller.c
    ./ivi-shell/ivi-shell.c
    ./ivi-shell/ivi-layout-transition.c
    ./ivi-shell/ivi-layout.c
    
    ./fullscreen-shell/fullscreen-shell.c
    
    ./desktop-shell/input-panel.c
    ./desktop-shell/exposay.c
    ./desktop-shell/shell.c

4.20.1 kiosk-shell

在 Weston 中,kiosk-shell 是一种简单的窗口管理器(shell),专为单应用程序单应用程序模式(kiosk 模式)设计。让我详细介绍一下:

  1. kiosk-shell 的功能

    • kiosk-shell 使所有顶层应用程序窗口全屏显示。
    • 它支持定义将哪些应用程序放置在特定输出上。 这通过在 weston.ini 中相应输出部分的 app-ids= 字段中实现。
  2. 使用示例

    在 weston.ini 中,您可以指定哪些应用程序应该在特定输出上运行。 例如:

     [output]
     name=screen0
     app-ids=org.domain.app1,com.domain.app2
    

    要使用 kiosk-shell 运行 Weston,请在 weston.ini 中设置 shell=kiosk-shell.so,或使用命令行选项 –shell=kiosk-shell.so。

  3. 适用场景

    kiosk-shell 适用于嵌入式设备、数字标牌、自助服务终端、展示台等场景,其中只有一个应用程序需要全屏显示

4.20.2 ivi-shell

IVI : In-Vehicle Information

在 Weston 项目中,IVI-shell 是一个高度可定制的外壳(shell),专注于那些需要对外壳窗口布局进行自定义控制的用例,而无需用户进行交互式布局配置。IVI-shell的示例用例包括汽车信息娱乐系统(IVI)应用程序或工业人机界面。通常情况下,当用户界面需要在一个或多个屏幕上精确定位多个应用程序表面时,IVI-shell 是一个理想的选择。

以下是关于 IVI-shell的一些重要信息:

  1. IVI-shell客户端协议

    Wayland 客户端可以实现 ivi_application Wayland 协议,通过该协议,它们可以指定一个 ivi_id,以便 IVI控制器可以识别应用程序。这使得控制器可以为众所周知的应用程序实现特殊行为。此外,IVI-shell也可以处理使用xdg-shell协议的客户端,但在这些情况下,IVI-shell需要其他方式来识别客户端应用程序。

  2. IVI-shell的组成部分
    • ivi-shell.so:负责处理应用程序ID,并提供抽象来通过ivi_layout_interface配置窗口布局。这个接口在IVI-shell组合器实现中讨论。
    • 自定义 IVI 控制器:使用 ivi_layout_interface 来实现窗口管理器,负责配置窗口布局,即应用程序在屏幕上的位置。由于这种分离,必须在您的weston.ini中加载这两个模块才能使用IVI-shell。
  3. IVI-shell的控制
    • IVI-shell提供了 ivi_layout_interface API,控制器必须使用它来控制IVI-shell的窗口布局。有关此 API 的定义,请参阅 ivi-shell/ivi-layout-export.h
    • 对于初始配置,控制器必须至少创建一个 ivi_layout_layer 并将其添加到一个 weston_output。图层允许将多个应用程序表面分组并一起控制,是组织和管理表面的主要机制。
    • 控制器还必须使用触发器来获取对客户端表面的控制权。客户端表面显示为 ivi_layout_surface。这些表面具有 ID,允许控制器识别表面并相应地重新配置窗口布局。

总之,IVI-shell是一个强大的工具,用于在汽车信息娱乐系统、工业界面等场景中精确控制应用程序的窗口布局

4.20.3 fullscreen-shell

下图是fullscreen-shell的初始化,以及surface commit时的处理。 可参考 [4.11 surface_commit]

Fullscreen-shell

4.21 wcap

在 Weston项目中,wcap 目录是用于处理 Weston 的屏幕录制功能的。具体来说,wcap 是一种特定于 Weston的无损视频格式,它仅记录帧之间的差异。这意味着它只捕获屏幕上发生变化的部分,而不是完整的每一帧。这对于屏幕录制非常有用,因为它可以减少文件大小并提高效率。

如果您在 Weston 中进行屏幕录制,生成的录制文件将以 .wcap 格式保存在当前工作目录中。要播放这些录制文件,您需要将 .wcap文件转换为其他媒体播放器可以理解的格式。例如,您可以使用 wcap-decode工具将 .wcap 文件转换为单独的PNG图像文件,以便查看每一帧的屏幕内容。

请注意,这里提到的 wcap 是一种专门用于 Weston 的格式,不同于其他常见的视频格式,如 MP4 或 AVI。

./wcap/main.c
./wcap/wcap-decode.c

results matching ""

    No results matching ""