Source code about AGL:https://wiki.automotivelinux.org/agl-distro/source-code
思考:为什么叫agl-compositor而不是agl-shell
本质上差别不大,compositor加载shell。agl独立了自己的一套加载shell等等的compositor.c
https://docs.automotivelinux.org/en/master/#5_Component_Documentation/1_agl-compositor/
https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/agl-compositor.git;a=blob;f=doc/arch_diagram.png;h=88a4381c4ad4d694a193b3105483a0c9ae50ff5a;hb=HEAD
这个agl-compositor有点ivi-shell的味道。就是ivi-shell的升级版,或者说,重构版本
重点,surfacecommit->weston_surface_commit_state->if (surface->committed) surface->committed(surface, state->sx, state->sy); ->dekstop.c的desktop_committed->weston_compositor_schedule_repaint
weston_compositor_schedule_repaint(surface->ivi->compositor);
wl_list_for_each(output, &compositor->output_list, link)
weston_output_schedule_repaint(output);
这里可以看到,在刚刚进入commit逻辑的时候,desktop会主导一次完整的commit逻辑。
switch (surface->role) {
case IVI_SURFACE_ROLE_DESKTOP:
case IVI_SURFACE_ROLE_REMOTE:
ivi_layout_desktop_committed(surface);
break;
case IVI_SURFACE_ROLE_POPUP:
ivi_layout_popup_committed(surface);
break;
case IVI_SURFACE_ROLE_FULLSCREEN:
ivi_layout_fullscreen_committed(surface);
break;
case IVI_SURFACE_ROLE_SPLIT_H:
case IVI_SURFACE_ROLE_SPLIT_V:
ivi_layout_split_committed(surface);
break;
case IVI_SURFACE_ROLE_NONE:
case IVI_SURFACE_ROLE_BACKGROUND:
case IVI_SURFACE_ROLE_PANEL:
default: /* fall through */
break;
在client做commit的时候,作为desktop,会将
How to clone::
git clone https://gerrit.automotivelinux.org/gerrit/src/agl-compositor.git
How to build[need have weston build environment libweston-8]::
meson builddir/ --prefix=/home/maze/Wayland/install
ninja -C builddir/ install
How to run::
./agl-compositor //Black-screen
agl-shell设置background/panel。设置ready保证所有的surface同时显示。
agl-shell-desktop用app_id激活其他的client。
│ ├── agl-shell-client-protocol.h
agl_shell_ready
*告诉服务器这个客户端已经可以显示了。服务器将在启动期间延迟显示,并将显示黑屏,直到所有shell客户端都准备好显示。这使客户端有机会将多个surface设置和配置为一个一致的接口。
*绑定到这个接口的客户端必须发送这个请求,否则他们可能会阻塞在compositor。
*如果这个请求在compositor已经完成启动后被调用,没有操作被执行。
agl_shell_set_background
agl_shell_set_panel
agl_shell_activate_app
*为了窗口管理的目的,要求compositor制作一个toplevel成为当前/聚焦的窗口。
│ ├── agl-shell-desktop-client-protocol.h
agl_shell_desktop_activate_app
agl_shell_desktop_set_app_property
agl_shell_desktop_deactivate_app
│ ├── agl-shell-desktop-protocol.c
│ ├── agl-shell-desktop-server-protocol.h
│ ├── agl-shell-protocol.c
│ ├── agl-shell-server-protocol.h
https://gitlab.apertis.org/pkg/maynard
From 7575569382f2cd90643393b091e2b3d770833dc1 Mon Sep 17 00:00:00 2001
From: maze-BUG <[email protected]>
Date: Tue, 27 Apr 2021 19:47:11 +0800
Subject: [PATCH] Add agl-shm.c
Signed-off-by: maze-BUG <[email protected]>
---
clients/agl-shm.c | 331 ++++++++++++++++++++++++++++++++++++++++++++
clients/meson.build | 15 ++
2 files changed, 346 insertions(+)
create mode 100644 clients/agl-shm.c
diff --git a/clients/agl-shm.c b/clients/agl-shm.c
new file mode 100644
index 0000000..2d19959
--- /dev/null
+++ b/clients/agl-shm.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright © 2011 Benjamin Franzke
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <stdint.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <sys/mman.h>
+#include <signal.h>
+
+#include <wayland-client.h>
+#include "shared/helpers.h"
+#include "shared/xalloc.h"
+#include "shared/file-util.h"
+#include "shared/os-compatibility.h"
+#include <libweston/zalloc.h>
+#include "agl-shell-client-protocol.h"
+#include "agl-shell-desktop-client-protocol.h"
+
+#define DEBUG_TRACE_ENABLED 1
+
+#if DEBUG_TRACE_ENABLED
+#define DEBUG_TRACE(fmt, args...) \
+ { \
+ fprintf(stderr, "TRACE [%s][%s][%4d]:"fmt"\n", __FILE__, __func__, __LINE__, ##args); \
+ }
+#else
+#define DEBUG_TRACE(fmt, args...)
+#endif
+
+
+struct framebuffer {
+ struct wl_surface *surface;
+ struct wl_buffer *buffer;
+
+ int height;
+ int width;
+
+ int ready;
+ void *shm_data;
+};
+
+struct desktop {
+ struct wl_display *display;
+ struct wl_registry *registry;
+
+ struct wl_shm *shm;
+ struct wl_compositor *compositor;
+ struct wl_output *output;
+ struct agl_shell *ashell;
+ struct agl_shell_desktop *ashell_desktop;
+
+ struct framebuffer *background;
+ struct framebuffer *panel;
+ int ready;
+};
+
+static int running = 1;
+
+static void shell_desktop_application(void *data, struct agl_shell_desktop *agl_shell_desktop,
+ const char *app_id)
+{
+ DEBUG_TRACE("APPLICATION app_id %s", app_id);
+ /* XXX: unimplemented */
+}
+
+static void shell_desktop_state_app(void *data, struct agl_shell_desktop *agl_shell_desktop,
+ const char *app_id,
+ const char *app_data,
+ uint32_t state,
+ uint32_t role)
+{
+ DEBUG_TRACE("APPLICATION STATE app_id %s state %d role %d", app_id, state, role);
+ /* XXX: unimplemented */
+}
+
+static const struct agl_shell_desktop_listener shell_desktop_listener = {
+ .application=shell_desktop_application,
+ .state_app=shell_desktop_state_app,
+};
+
+static void wl_display_error(void *data, struct wl_display *wl_display,
+ void *object_id,
+ uint32_t code,
+ const char *message)
+{
+ DEBUG_TRACE();
+}
+
+static void wl_display_delete_id(void *data, struct wl_display *wl_display, uint32_t id)
+{
+ DEBUG_TRACE();
+}
+
+struct wl_display_listener display_listener = {
+ wl_display_error,
+ wl_display_delete_id
+};
+
+static void
+shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
+{
+}
+
+struct wl_shm_listener shm_listener = {
+ shm_format
+};
+
+static void
+handle_global(void *data, struct wl_registry *registry,
+ uint32_t name, const char *interface, uint32_t version)
+{
+ struct desktop *sh_data = data;
+ printf("%s :%s\n",__func__, interface);
+ if (strcmp(interface, "wl_compositor") == 0) {
+ printf("bind%s :%s\n",__func__, interface);
+ sh_data->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);
+ } else if (strcmp(interface, "wl_output") == 0) {
+ printf("bind%s :%s\n",__func__, interface);
+ sh_data->output = wl_registry_bind(registry, name, &wl_output_interface, 1);
+ } else if (strcmp(interface, "agl_shell") == 0) {
+ printf("bind%s :%s\n",__func__, interface);
+ sh_data->ashell = wl_registry_bind(registry, name, &agl_shell_interface, 1);
+ } else if (strcmp(interface, "agl_shell_desktop") == 0) {
+ printf("bind%s :%s\n",__func__, interface);
+ sh_data->ashell_desktop =
+ wl_registry_bind(registry, name, &agl_shell_desktop_interface, 1);
+ agl_shell_desktop_add_listener(sh_data->ashell_desktop,
+ &shell_desktop_listener, sh_data);
+ agl_shell_desktop_set_user_data(sh_data->ashell_desktop, sh_data);
+ } else if (strcmp(interface, "wl_shm") == 0) {
+ printf("bind%s :%s\n",__func__, interface);
+ sh_data->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
+ wl_shm_add_listener(sh_data->shm, &shm_listener, sh_data);
+ }
+
+}
+
+static void
+handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+ /* XXX: unimplemented */
+}
+
+static const struct wl_registry_listener registry_listener = {
+ handle_global,
+ handle_global_remove
+};
+
+static void
+signal_int(int signum)
+{
+ running = 0;
+}
+
+static int create_background(struct desktop *desktop) {
+ printf("%s++\n",__func__);
+ struct wl_shm_pool *pool;
+ int size;
+ int stride;
+ int fd;
+ void *data;
+ int width = 250;
+ int height = 250;
+ desktop->background = malloc(sizeof(struct framebuffer));
+ desktop->background->width = width;
+ desktop->background->height = height;
+
+ stride = desktop->background->width * 4;
+ size = desktop->background->width * desktop->background->height * 4;
+ fd = os_create_anonymous_file(size);
+ data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (data == MAP_FAILED) {
+ fprintf(stderr, "mmap failed: %s\n", strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ if (desktop->shm == NULL) {
+ fprintf(stderr, "No wl_shm global\n");
+ exit(1);
+ }
+ pool = wl_shm_create_pool(desktop->shm, fd, size);
+ desktop->background->buffer = wl_shm_pool_create_buffer(pool, 0, width, height,
+ stride, WL_SHM_FORMAT_XRGB8888);
+ wl_shm_pool_destroy(pool);
+ close(fd);
+ desktop->background->surface = wl_compositor_create_surface(desktop->compositor);
+ desktop->background->shm_data = data;
+
+ memset(desktop->background->shm_data, 0xff, width*height*4);
+ wl_surface_attach(desktop->background->surface, desktop->background->buffer, 0, 0);
+ wl_surface_damage(desktop->background->surface, 0, 0, width, height);
+ wl_surface_commit(desktop->background->surface);
+
+ printf("%s--\n",__func__);
+ return 0;
+}
+
+static int create_panel(struct desktop *desktop) {
+ printf("%s++\n",__func__);
+ struct wl_shm_pool *pool;
+ int size;
+ int stride;
+ int fd;
+ void *data;
+ desktop->panel = malloc(sizeof(struct framebuffer));
+ desktop->panel->width = 200;
+ desktop->panel->height = 200;
+ int width = desktop->panel->width;
+ int height = desktop->panel->height;
+
+ desktop->panel->surface = wl_compositor_create_surface(desktop->compositor);
+ stride = desktop->panel->width * 4;
+ size = desktop->panel->width * desktop->panel->height * 4;
+ fd = os_create_anonymous_file(size);
+ data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ pool = wl_shm_create_pool(desktop->shm, fd, size);
+ desktop->panel->buffer = wl_shm_pool_create_buffer(pool, 0, width, height,
+ stride, WL_SHM_FORMAT_XRGB8888);
+ wl_shm_pool_destroy(pool);
+ close(fd);
+ desktop->panel->surface = wl_compositor_create_surface(desktop->compositor);
+ desktop->panel->shm_data = data;
+
+ memset(desktop->panel->shm_data, 0xff, width*height*4);
+ wl_surface_attach(desktop->panel->surface, desktop->panel->buffer, 0, 0);
+ wl_surface_damage(desktop->panel->surface, 0, 0, width, height);
+ wl_surface_commit(desktop->panel->surface);
+
+ printf("%s--\n",__func__);
+ return 0;
+}
+
+static int time_handler(struct desktop *desktop) {
+ printf("%s--\n",__func__);
+// if (!desktop->background->ready) {
+// desktop->background->ready = 1;
+ agl_shell_set_background(desktop->ashell, desktop->background->surface,
+ desktop->output);
+// }
+// if (!desktop->panel->ready) {
+// desktop->panel->ready = 1;
+ agl_shell_set_panel(desktop->ashell, desktop->panel->surface, desktop->output,
+ AGL_SHELL_EDGE_LEFT);
+// connect_enter_leave_signals(desktop);
+// }
+ agl_shell_activate_app(desktop->ashell, "simple-shm-id", desktop->output);
+// if (!desktop->ready) {
+// desktop->ready = 1;
+ agl_shell_ready(desktop->ashell);
+// }
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sigaction sigint;
+ struct wl_display *display;
+ struct wl_registry *registry;
+ int ret = 0;
+
+ struct desktop *agldesktop=malloc(sizeof(struct desktop));
+ memset(agldesktop, 0, sizeof(struct desktop));
+
+ display = wl_display_connect(NULL);
+ if (display == NULL) {
+ fprintf(stderr, "failed to create display: %s\n",
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ agldesktop->display=display;
+ wl_display_add_listener(agldesktop->display, &display_listener, agldesktop);
+
+ registry = wl_display_get_registry(display);
+ agldesktop->registry=registry;
+ wl_registry_add_listener(registry, ®istry_listener, agldesktop);
+
+ sigint.sa_handler = signal_int;
+ sigemptyset(&sigint.sa_mask);
+ sigint.sa_flags = SA_RESETHAND;
+ sigaction(SIGINT, &sigint, NULL);
+
+ wl_display_roundtrip(display);
+ wl_display_roundtrip(display);
+
+ ret = create_background(agldesktop);
+ ret = create_panel(agldesktop);
+
+ //wl_display_dispatch(display);
+
+ while (running && ret != -1) {
+ // wl_display_dispatch(display);
+ ret = time_handler(agldesktop);
+ sleep(2);
+ // ret = wl_display_dispatch(desktop->display);
+ }
+
+ fprintf(stderr, "agl-shm exiting\n");
+ return 0;
+}
diff --git a/clients/meson.build b/clients/meson.build
index 08b2c08..3df0cc8 100644
--- a/clients/meson.build
+++ b/clients/meson.build
@@ -16,6 +16,21 @@ clients = [
'deps_objs' : [ dep_wayland_client ],
'deps': [ 'cairo' ],
},
+{
+ 'basename': 'agl-shm',
+ 'sources': [
+ 'agl-shm.c',
+ '../shared/file-util.c',
+ '../shared/os-compatibility.c',
+ '../shared/xalloc.c',
+ agl_shell_client_protocol_h,
+ agl_shell_protocol_c,
+ agl_shell_desktop_client_protocol_h,
+ agl_shell_desktop_protocol_c,
+ ],
+ 'deps_objs' : [ dep_wayland_client ],
+ 'deps': [ 'cairo' ],
+},
]
foreach t: clients
--
2.25.1
panel指的是UI,最上面那一行。