lvgl / lv_drivers

TFT and touch pad drivers for LVGL embedded GUI library
https://docs.lvgl.io/master/porting/index.html
MIT License
290 stars 309 forks source link

listener function for opcode 3 of xdg_toplevel is NULL #294

Closed LaterBird closed 9 months ago

LaterBird commented 9 months ago

lvgl version: 8.3.10 lv_drivers: release-v8.3 wayland: 1.21.0 weston: 11.0.1

same issue #222

std::mutex my_lvgl_mutex;
std::shared_ptr<std::thread> mpThread;

void my_lvgl_lock()
{
    my_lvgl_mutex.lock();
}

void my_lvgl_unlock()
{
    my_lvgl_mutex.unlock();
}

#define TICK_INC_TIME 7
#define HANDLE_THREAD_SLEEP_TIME 1000
#define TICK_THREAD_SLEEP_TIME 1000

void my_tick()
{
    while (1)
    {
        my_lvgl_lock();
        lv_tick_inc(TICK_INC_TIME); // TICK_INC_TIME = 7
        my_lvgl_unlock();
        std::this_thread::sleep_for(std::chrono::microseconds(TICK_THREAD_SLEEP_TIME));
    }
}

void tick_thread()
{
    mpThread.reset(new std::thread([](){
        my_tick();
    }));
}

int main(int argc, char *argv[])
{
    lv_init();
    lv_wayland_init();
    lv_disp_t *disp = lv_wayland_create_window(800, 800, "test", NULL);
    if (!disp) {
        lv_wayland_deinit();
        return 0;
    }
    tick_thread();
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "wayland test");
    while (1)
    {
        my_lvgl_lock();
        lv_task_handler();
        // lv_wayland_timer_handler();
        my_lvgl_unlock();
        std::this_thread::sleep_for(std::chrono::microseconds(HANDLE_THREAD_SLEEP_TIME));
    }

    return 0;
}
LaterBird commented 9 months ago

wayland 1.21.0 source code:

        implementation = target->implementation;
    if (!implementation[opcode]) {
        wl_abort("listener function for opcode %u of %s is NULL\n",
             opcode, target->interface->name);
    } else {
            ffi_call(&cif, implementation[opcode], NULL, ffi_args);
    }

target->implementation is 'xdg_toplevel_listener' xdg_toplevel_add_listener(window->xdg_toplevel, &xdg_toplevel_listener, window);

static inline int
xdg_toplevel_add_listener(struct xdg_toplevel *xdg_toplevel,
              const struct xdg_toplevel_listener *listener, void *data)
{
    return wl_proxy_add_listener((struct wl_proxy *) xdg_toplevel,
                     (void (**)(void)) listener, data);
}

in wayland source code wl_proxy_add_listener is:

WL_EXPORT int
wl_proxy_add_listener(struct wl_proxy *proxy,
              void (**implementation)(void), void *data)
{
    if (proxy->flags & WL_PROXY_FLAG_WRAPPER)
        wl_abort("Proxy %p is a wrapper\n", proxy);

    if (proxy->object.implementation || proxy->dispatcher) {
        wl_log("proxy %p already has listener\n", proxy);
        return -1;
    }

    proxy->object.implementation = implementation; // Note here, so xdg_toplevel_listener.wm_capabilities Should be assigned a function
    proxy->user_data = data;

    return 0;
}