天天看點

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端具體角色的具體功能的接口