天天看点

display:weston:desktop & xdg-shell

desktop shell强相关的一共分如下几部分:

1.client/desktop-shell.c + window.c

2.desktop-shell目录

3.libweston-desktop部分\

1是desktop客户端的实现,因为桌面本身也是一个负责和weston交互的客户端。

2是负责大多数desktop-shell.c里面的实现,如创建鼠标,键盘,窗口布局,窗口效果。

3则是xdg一些独立于desktop的实现,在任何窗口都有可能需要用到。

一句话来说,desktop-shell目录是一些具体的特殊的情况,而libweston-desktop则是一些普遍的实现

desktop-shell.c

main
    ...
    config相关,如panel位置(就是显示时间那一行),显示的时间格式等等
    ...
    ###########display_create
    desktop.display = display_create(&argc, argv);

        d->display = wl_display_connect(NULL);//Connect to the Wayland display named \c name. 
If \c name is \c NULL,its value will be replaced with the WAYLAND_DISPLAY 
environment variable if it is set, otherwise display "wayland-0" will be used.
如果有多个监听的节点(可能是多个server,或者单一server但是监听多个节点),这个时候就可以决定对应的客户端与那个socket节点通信。

        d->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);//键盘输入相关
https://wayland-book.com/seat/xkb.html
    
        //epoll, handle_display_data是对应的处理事件,
主要是wl_display_dispatch和wl_display_flush
        d->epoll_fd = os_epoll_create_cloexec();
	    d->display_fd = wl_display_get_fd(d->display);
	    d->display_task.run = handle_display_data;
	    display_watch_fd(d, d->display_fd, EPOLLIN | EPOLLERR | EPOLLHUP,
		    	 &d->display_task);

        wl_list_init(&d->deferred_list);
	    wl_list_init(&d->input_list);
	    wl_list_init(&d->output_list);//这个对应实际的屏幕,output
	    wl_list_init(&d->global_list);//这个是gloabel object的列表,如下会全部保存一份         

        //注册绑定对应的global服务
	    d->registry = wl_display_get_registry(d->display);
	    wl_registry_add_listener(d->registry, &registry_listener, d);
        //registry_handle_global里面把所有的global interface全部装在之前创建的 global_list里面:
            global = xmalloc(sizeof *global);
	        global->name = id;
	        global->interface = strdup(interface);
	        global->version = version;
	        wl_list_insert(d->global_list.prev, &global->link);

        #ifdef HAVE_CAIRO_EGL              //init_egl
	    if (init_egl(d) < 0)

        create_cursors(d);                 //鼠标 https://invisible-island.net/xterm/xcursor/xcursor.html
        
        d->theme = theme_create();         //主要是和窗口主题相关内容,比方说,窗口背后阴影
窗口的帮助栏大小等等。比较复杂,目前不理解
    
        wl_list_init(&d->window_list);

        init_dummy_surface(d);            //貌似和weston桌面鼠标停留左上角terminal的info有关
    ##########

    //初始化desktop.display对象的data,global_handler和globale_handler_remove
	display_set_user_data(desktop.display, &desktop);
	display_set_global_handler(desktop.display, global_handler);//此处会注册绑定
weston_desktop_shell和wl_output接口,这里面很有意思,先来的信号是wl_output
    //因为先来的是wl_output,那么create_output里面的if(desktop->shell)就不会成功,
也就不会在这里创建panel和background
            global_handler
                ...
                } else if (!strcmp(interface, "wl_output")) {
		                create_output(desktop, id);
                                    if (desktop->shell) {
                            		output_init(output, desktop);
                ...
	display_set_global_handler_remove(desktop.display, global_handler_remove);

    ##########创建background和panel的地方
    weston_desktop_shell_set_panel_position(desktop.shell, desktop.panel_position); //对应
    desktop-shell文件夹里面实现的weston_desktop_shell_interface->desktop_shell_set_panel_position
    wl_list_for_each(output, &desktop.outputs, link)
		if (!output->panel)
			output_init(output, &desktop);

                    output->panel = panel_create(desktop, output);
		            surface = window_get_wl_surface(output->panel->window);
		            weston_desktop_shell_set_panel(desktop->shell,
				        	        output->output, surface);

       	            output->background = background_create(desktop, output);
       	            surface = window_get_wl_surface(output->background->window);
	                weston_desktop_shell_set_background(desktop->shell,
				            	    output->output, surface);
    ##########

    grab_surface_create(&desktop);        //应该是用鼠标设置窗口大小时候的那个手一样的surface
由下面的desktop_shell_set_grab_surface支持

    display_run(desktop.display);
           

整个desktop client不使用xdg-shell相关。 

参考weston目录下的weston-desktop-shell.xml;

client在绑定desktop-shell的时候,实现了会从server那边收到的三个消息:configure,prepare_lock_surface,grab_cursor。

并在绑定wl_output的时候实现了create_output,这是显而易见的,因为我们可以从wl_output_protocol里面获取屏幕大小等用来创建全局窗口的有用信息。

desktop-shell里面的接口:

static const struct weston_desktop_shell_interface desktop_shell_implementation = {
	desktop_shell_set_background,
	desktop_shell_set_panel,
	desktop_shell_set_lock_surface,
	desktop_shell_unlock,
	desktop_shell_set_grab_surface,
	desktop_shell_desktop_ready,
	desktop_shell_set_panel_position
};
           

xdg-shell里面有几套接口,分别是:

static const struct xdg_wm_base_interface weston_desktop_xdg_shell_implementation = {
	.destroy = weston_desktop_destroy_request,
	.create_positioner = weston_desktop_xdg_shell_protocol_create_positioner,
	.get_xdg_surface = weston_desktop_xdg_shell_protocol_get_xdg_surface,
	.pong = weston_desktop_xdg_shell_protocol_pong,
};
           

在client 端bind wm_base以后提供的接口,可以通过wl_surface获取xdg_surface。

static const struct xdg_surface_interface weston_desktop_xdg_surface_implementation = {
	.destroy             = weston_desktop_destroy_request,
	.get_toplevel        = weston_desktop_xdg_surface_protocol_get_toplevel,
	.get_popup           = weston_desktop_xdg_surface_protocol_get_popup,
	.set_window_geometry = weston_desktop_xdg_surface_protocol_set_window_geometry,
	.ack_configure       = weston_desktop_xdg_surface_protocol_ack_configure,
};
           

在获取xdg_surface以后,可以通过上述接口获得具体的角色,toplevel或者popup。

static const struct weston_desktop_surface_implementation weston_desktop_xdg_surface_internal_implementation = {
	/* These are used for toplevel only */
	.set_maximized = weston_desktop_xdg_toplevel_set_maximized,
	.set_fullscreen = weston_desktop_xdg_toplevel_set_fullscreen,
	.set_resizing = weston_desktop_xdg_toplevel_set_resizing,
	.set_activated = weston_desktop_xdg_toplevel_set_activated,
	.set_size = weston_desktop_xdg_toplevel_set_size,

	.get_maximized = weston_desktop_xdg_toplevel_get_maximized,
	.get_fullscreen = weston_desktop_xdg_toplevel_get_fullscreen,
	.get_resizing = weston_desktop_xdg_toplevel_get_resizing,
	.get_activated = weston_desktop_xdg_toplevel_get_activated,

	/* These are used for popup only */
	.update_position = weston_desktop_xdg_popup_update_position,

	/* Common API */
	.committed = weston_desktop_xdg_surface_committed,
	.ping = weston_desktop_xdg_surface_ping,
	.close = weston_desktop_xdg_surface_close,

	.destroy = weston_desktop_xdg_surface_destroy,
};
           

这一部分是内部用的,并不是暴露给client的,而是用来和weston\desktop-shell目录所生成的desktop-shell.so对接,是desktop-shell.so里面功能的实现。

static const struct xdg_popup_interface weston_desktop_xdg_popup_implementation = {
	.destroy             = weston_desktop_destroy_request,
	.grab                = weston_desktop_xdg_popup_protocol_grab,
};
           
static const struct xdg_toplevel_interface weston_desktop_xdg_toplevel_implementation = {
	.destroy             = weston_desktop_destroy_request,
	.set_parent          = weston_desktop_xdg_toplevel_protocol_set_parent,
	.set_title           = weston_desktop_xdg_toplevel_protocol_set_title,
	.set_app_id          = weston_desktop_xdg_toplevel_protocol_set_app_id,
	.show_window_menu    = weston_desktop_xdg_toplevel_protocol_show_window_menu,
	.move                = weston_desktop_xdg_toplevel_protocol_move,
	.resize              = weston_desktop_xdg_toplevel_protocol_resize,
	.set_min_size        = weston_desktop_xdg_toplevel_protocol_set_min_size,
	.set_max_size        = weston_desktop_xdg_toplevel_protocol_set_max_size,
	.set_maximized       = weston_desktop_xdg_toplevel_protocol_set_maximized,
	.unset_maximized     = weston_desktop_xdg_toplevel_protocol_unset_maximized,
	.set_fullscreen      = weston_desktop_xdg_toplevel_protocol_set_fullscreen,
	.unset_fullscreen    = weston_desktop_xdg_toplevel_protocol_unset_fullscreen,
	.set_minimized       = weston_desktop_xdg_toplevel_protocol_set_minimized,
};
           

这两部分是给client使用的,对接client端具体角色的具体功能的接口