zoukankan      html  css  js  c++  java
  • walyand学习笔记(三) 建立各个数据结构之间的联系

     客户端真正的对象结构体

    struct wl_proxy {
    struct wl_object object;
    struct wl_display *display;
    struct wl_event_queue *queue;
    uint32_t flags;
    int refcount;
    void *user_data;
    wl_dispatcher_func_t dispatcher;
    uint32_t version;
    };
    

    Wayland协议里面的那些interface的对象在客户端其实真正的结构体是wl_proxy,而那些结构体都是不存在的,只是一个声明而已,根本不存在。如果读者有看过wayland的源码,会发现一个问题,就是wayland协议里面的那些interface对象,从来都不是程序员自己创建出来的,而是通过wayland的一些接口返回回来的。全部都是,无一例外。读者如果不相信可以自己去找找,并且可以自己尝试创建那些对象,肯定是会报错的,因为那些结构体都是不存在的,创建会编译出错

    这 所谓的interface对象是啥呢,看看wayland.xml的描述

    <interface name="wl_buffer" version="1">
    
        <description summary="content for a wl_surface">
    
          A buffer provides the content for a wl_surface. Buffers are
    
          created through factory interfaces such as wl_drm, wl_shm or
    
          similar. It has a width and a height and can be attached to a
    
          wl_surface, but the mechanism by which a client provides and
    
          updates the contents is defined by the buffer factory interface.
    
        </description>
    
     
    
        <request name="destroy" type="destructor">
    
          <description summary="destroy a buffer">
    
             Destroy a buffer. If and how you need to release the backing
    
             storage is defined by the buffer factory interface.
    
     
    
             For possible side-effects to a surface, see wl_surface.attach.
    
          </description>
    
        </request>
    
     
    
        <event name="release">
    
          <description summary="compositor releases buffer">
    
             Sent when this wl_buffer is no longer used by the compositor.
    
             The client is now free to reuse or destroy this buffer and its
    
             backing storage.
    
     
    
             If a client receives a release event before the frame callback
    
             requested in the same wl_surface.commit that attaches this
    
             wl_buffer to a surface, then the client is immediately free to
    
             reuse the buffer and its backing storage, and does not need a
    
             second buffer for the next surface content update. Typically
    
             this is possible, when the compositor maintains a copy of the
    
             wl_surface contents, e.g. as a GL texture. This is an important
    
             optimization for GL(ES) compositors with wl_shm clients.
    
          </description>
    
        </event>
    
    </interface>
    

     一个wl_buffer就是一个Interface对象.

    【服务器端的interface对象是在server端创建并返回的】

    服务器端真正的对象结构体

    struct wl_resource {
    struct wl_object object;
    wl_resource_destroy_func_t destroy;
    struct wl_list link;
    struct wl_signal destroy_signal;
    struct wl_client *client;
    void *data;
    };

    服务器端所有的interface对象全部都是wl_resource结构体对象.

    现在,我们开始通过对结构体之间关系的剖析,逐步把各个零散的概念串联起来

     

     可以看到wl_interface就是贯穿这些结构的核心,也正是wayland.xml中大费周章描述的interface对象。

    一个wayland协议xml包含一个或者多个interface, 一个interface里面包含一个或者多个request和event

    举个栗子:

    <interface name="wl_surface" version="4">
    <request name="attach">
    <arg name="buffer" type="object" interface="wl_buffer" allow-null="true" summary="buffer of surface contents"/>
    <arg name="x" type="int" summary="surface-local x coordinate"/>
    <arg name="y" type="int" summary="surface-local y coordinate"/>
    </request>
    </interface>
    

     这里wl_surface这个interface对象,有一个名叫attach的方法,这个方法的参数如下:

    第一个参数名是buffer, 类型是一个wl_buffer的指针,并且可以为空,其注释为 buffer of surface contents

    第二个参数是 int x, 描述是surface-local x coordinate

    第三个参数是 int y, 描述是surface-local y coordinate

    翻译下来,这个函数大概就是:

    void wl_surface_attach(struct wl_surface *wl_surface, struct wl_buffer *buffer, int32_t x, int32_t y);

    第一个参数可以理解为wl_surface的this指针,指出是哪个对象要调用和这个接口。

    好了,这里都是xml层面的描述,到了C的层面,这些内容都由wl_message结构体来描述。

    其中以signature为相对比较重要,这里还是举个栗子:

    以wl_display 的 delete_id为例,它只有一个uint的参数,那么这个结构体就是

    {“delete_id”, "u", [NULL]}

    NULL意味着uint的参数是一个元对象(primitive), 没有对应的wl_interface

    再看一个栗子,比如上面讲到的那个wl_surface的attach方法:

    其对应的wl_message结构体就应该是{ “attach”, "4?oii", [&wl_buffer, NULL, NULL] }

    后两个NULL的意思是对于后面两个int参数,没有对应的interface对象

    好的,到这一步就可以比较深入的了解wayland解析协议文件的输出文件了:

    一个协议源文件:里面保存了xml协议文件里面所有的interface转换而成的wl_interface结构体变量,包括wl_message结构体记录的request和event函数。

    一个客户端使用的头文件:里面封装了wl_proxy转换成指定interface假声明的结构体操作的接口函数,以及request函数的实现,但是这个request只是把请求发送到服务器端,实际调用是在服务器端进行。最后,文件里面还封装了一个回调函数的结构体,成员就是所有的event函数指针,需要客户端去实现,并设置到interface的对象里面,该文件生成了这个设置的接口,实际就是填充到wl_object结构体的implementation变量中。


    一个服务器端头文件,里面基本和客户端一样的组成。只是结构体是wl_resource,函数结构体的成员是所有request的函数指针。以及所有的event的实现。
    也就是说,客户端需要程序员自己实现事件(event),服务器端需要程序员实现请求(request)。

  • 相关阅读:
    [常用的SQL语句总结]
    [HTML辅助方法Html.Raw()的简单应用]
    [抹零操作的三种方法]
    如何禁用ViewState,EnableViewState属性设置
    vs2008自定义代码段
    C#.net模拟提交表单GET、POST
    .net 判断对象属性,model对象属性是否赋值,PropertyInfo
    PHP的microtime()? 不!这是 asp.net版的microtime()
    很不错的验证码显示页
    GridView加入自动求和求平均值小计
  • 原文地址:https://www.cnblogs.com/Arnold-Zhang/p/15306697.html
Copyright © 2011-2022 走看看