static gboolean gst_gl_window_wayland_egl_open (GstGLWindow * window, GError ** error) { GstGLDisplayWayland *display; GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (window); if (!GST_IS_GL_DISPLAY_WAYLAND (window->display)) { g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE, "Failed to retrieve Wayland display (wrong type?)"); return FALSE; } display = GST_GL_DISPLAY_WAYLAND (window->display); if (!display->display) { g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE, "Failed to retrieve Wayland display"); return FALSE; } window_egl->window.queue = wl_display_create_queue (display->display); window_egl->wl_source = wayland_event_source_new (display->display, window_egl->window.queue); if (!GST_GL_WINDOW_CLASS (parent_class)->open (window, error)) return FALSE; g_source_attach (window_egl->wl_source, g_main_context_get_thread_default ()); return TRUE; }
WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, const gralloc_module_t* gralloc, alloc_device_t* alloc_device) { int i; this->m_window = window; this->m_display = display; this->m_width = window->width; this->m_height = window->height; this->m_defaultWidth = window->width; this->m_defaultHeight = window->height; this->m_format = 1; this->wl_queue = wl_display_create_queue(display); this->frame_callback = NULL; this->registry = wl_display_get_registry(display); wl_proxy_set_queue((struct wl_proxy *) this->registry, this->wl_queue); wl_registry_add_listener(this->registry, ®istry_listener, this); assert(wayland_roundtrip(this) >= 0); assert(this->m_android_wlegl != NULL); this->m_gralloc = gralloc; this->m_alloc = alloc_device; m_usage=GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; pthread_mutex_init(&mutex, NULL); TRACE("WaylandNativeWindow created in %p", pthread_self()); }
WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, const gralloc_module_t* gralloc, alloc_device_t* alloc_device) { int wayland_ok; HYBRIS_TRACE_BEGIN("wayland-platform", "create_window", ""); this->m_window = window; this->m_window->nativewindow = (void *) this; this->m_display = display; this->m_width = window->width; this->m_height = window->height; this->m_defaultWidth = window->width; this->m_defaultHeight = window->height; this->m_window->resize_callback = resize_callback; this->m_format = 1; this->wl_queue = wl_display_create_queue(display); this->frame_callback = NULL; this->registry = wl_display_get_registry(display); wl_proxy_set_queue((struct wl_proxy *) this->registry, this->wl_queue); wl_registry_add_listener(this->registry, ®istry_listener, this); wayland_ok = wayland_roundtrip(this); assert(wayland_ok >= 0); assert(this->m_android_wlegl != NULL); this->m_gralloc = gralloc; this->m_alloc = alloc_device; m_usage=GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); m_freeBufs = 0; setBufferCount(3); HYBRIS_TRACE_END("wayland-platform", "create_window", ""); }
GstWlDisplay * gst_wl_display_new_existing (struct wl_display * display, gboolean take_ownership, GError ** error) { GstWlDisplay *self; GError *err = NULL; gint i; g_return_val_if_fail (display != NULL, NULL); self = g_object_new (GST_TYPE_WL_DISPLAY, NULL); self->display = display; self->own_display = take_ownership; self->queue = wl_display_create_queue (self->display); self->registry = wl_display_get_registry (self->display); wl_proxy_set_queue ((struct wl_proxy *) self->registry, self->queue); wl_registry_add_listener (self->registry, ®istry_listener, self); /* we need exactly 2 roundtrips to discover global objects and their state */ for (i = 0; i < 2; i++) { if (gst_wl_display_roundtrip (self) < 0) { *error = g_error_new (g_quark_from_static_string ("GstWlDisplay"), 0, "Error communicating with the wayland display"); g_object_unref (self); return NULL; } } /* verify we got all the required interfaces */ #define VERIFY_INTERFACE_EXISTS(var, interface) \ if (!self->var) { \ g_set_error (error, g_quark_from_static_string ("GstWlDisplay"), 0, \ "Could not bind to " interface ". Either it is not implemented in " \ "the compositor, or the implemented version doesn't match"); \ g_object_unref (self); \ return NULL; \ } VERIFY_INTERFACE_EXISTS (compositor, "wl_compositor"); VERIFY_INTERFACE_EXISTS (subcompositor, "wl_subcompositor"); VERIFY_INTERFACE_EXISTS (shell, "wl_shell"); VERIFY_INTERFACE_EXISTS (shm, "wl_shm"); VERIFY_INTERFACE_EXISTS (scaler, "wl_scaler"); #undef VERIFY_INTERFACE_EXISTS self->thread = g_thread_try_new ("GstWlDisplay", gst_wl_display_thread_run, self, &err); if (err) { g_propagate_prefixed_error (error, err, "Failed to start thread for the display's events"); g_object_unref (self); return NULL; } return self; }
static gboolean gst_vaapi_window_wayland_create (GstVaapiWindow * window, guint * width, guint * height) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GstVaapiDisplayWaylandPrivate *const priv_display = GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_OBJECT_DISPLAY (window)); GST_DEBUG ("create window, size %ux%u", *width, *height); g_return_val_if_fail (priv_display->compositor != NULL, FALSE); g_return_val_if_fail (priv_display->shell != NULL, FALSE); GST_VAAPI_OBJECT_LOCK_DISPLAY (window); priv->event_queue = wl_display_create_queue (priv_display->wl_display); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); if (!priv->event_queue) return FALSE; GST_VAAPI_OBJECT_LOCK_DISPLAY (window); priv->surface = wl_compositor_create_surface (priv_display->compositor); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); if (!priv->surface) return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue); GST_VAAPI_OBJECT_LOCK_DISPLAY (window); priv->shell_surface = wl_shell_get_shell_surface (priv_display->shell, priv->surface); GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); if (!priv->shell_surface) return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->shell_surface, priv->event_queue); wl_shell_surface_add_listener (priv->shell_surface, &shell_surface_listener, priv); wl_shell_surface_set_toplevel (priv->shell_surface); priv->poll = gst_poll_new (TRUE); gst_poll_fd_init (&priv->pollfd); if (priv->fullscreen_on_show) gst_vaapi_window_wayland_set_fullscreen (window, TRUE); priv->surface_format = GST_VIDEO_FORMAT_ENCODED; priv->use_vpp = GST_VAAPI_DISPLAY_HAS_VPP (GST_VAAPI_OBJECT_DISPLAY (window)); priv->is_shown = TRUE; return TRUE; }
QWaylandDisplay::QWaylandDisplay() : mLastKeyboardFocusInputDevice(0) , mDndSelectionHandler(0) , mWindowExtension(0) , mSubSurfaceExtension(0) , mOutputExtension(0) , mTouchExtension(0) , mQtKeyExtension(0) { display = this; qRegisterMetaType<uint32_t>("uint32_t"); mEventThreadObject = new QWaylandEventThread(0); mEventThread = new QThread(this); mEventThreadObject->moveToThread(mEventThread); mEventThread->start(); mEventThreadObject->displayConnect(); mDisplay = mEventThreadObject->display(); //blocks until display is available //Create a new even queue for the QtGui thread mEventQueue = wl_display_create_queue(mDisplay); struct ::wl_registry *registry = wl_display_get_registry(mDisplay); wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue); init(registry); QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(flushRequests())); connect(mEventThreadObject, SIGNAL(newEventsRead()), this, SLOT(flushRequests())); #ifdef QT_WAYLAND_GL_SUPPORT mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); #endif mWindowManagerIntegration = new QWaylandWindowManagerIntegration(this); blockingReadEvents(); #ifdef QT_WAYLAND_GL_SUPPORT mEglIntegration->initialize(); flushRequests(); while (mEglIntegration->waitingForEvents()) blockingReadEvents(); #endif waitForScreens(); }
extern "C" _EGLDisplay *waylandws_GetDisplay(EGLNativeDisplayType display) { WaylandDisplay *wdpy = new WaylandDisplay; wdpy->wl_dpy = (wl_display *)display; wdpy->wlegl = NULL; wdpy->queue = wl_display_create_queue(wdpy->wl_dpy); wdpy->registry = wl_display_get_registry(wdpy->wl_dpy); wl_proxy_set_queue((wl_proxy *) wdpy->registry, wdpy->queue); wl_registry_add_listener(wdpy->registry, ®istry_listener, wdpy); wl_callback *cb = wl_display_sync(wdpy->wl_dpy); wl_proxy_set_queue((wl_proxy *) cb, wdpy->queue); wl_callback_add_listener(cb, &callback_listener, wdpy); return &wdpy->base; }
WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, alloc_device_t* alloc_device) : m_android_wlegl(NULL) { int wayland_ok; HYBRIS_TRACE_BEGIN("wayland-platform", "create_window", ""); this->m_window = window; this->m_window->nativewindow = (void *) this; this->m_display = display; this->m_width = window->width; this->m_height = window->height; this->m_defaultWidth = window->width; this->m_defaultHeight = window->height; this->m_window->resize_callback = resize_callback; this->m_window->free_callback = free_callback; this->m_format = 1; this->frame_callback = NULL; this->wl_queue = wl_display_create_queue(display); this->registry = wl_display_get_registry(display); this->m_android_wlegl = NULL; wl_proxy_set_queue((struct wl_proxy *) this->registry, this->wl_queue); wl_registry_add_listener(this->registry, ®istry_listener, this); const_cast<int&>(ANativeWindow::minSwapInterval) = 0; const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; // This is the default as per the EGL documentation this->m_swap_interval = 1; wayland_ok = wayland_roundtrip(this); assert(wayland_ok >= 0); assert(this->m_android_wlegl != NULL); this->m_alloc = alloc_device; m_usage=GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); m_queueReads = 0; m_freeBufs = 0; m_damage_rects = NULL; m_damage_n_rects = 0; m_lastBuffer = 0; setBufferCount(3); HYBRIS_TRACE_END("wayland-platform", "create_window", ""); }
WaylandNativeWindow::WaylandNativeWindow(struct wl_egl_window *window, struct wl_display *display, android_wlegl *wlegl, alloc_device_t* alloc_device, gralloc_module_t *gralloc) : m_android_wlegl(wlegl) { int wayland_ok; HYBRIS_TRACE_BEGIN("wayland-platform", "create_window", ""); this->m_window = window; this->m_window->nativewindow = (void *) this; this->m_display = display; this->m_width = window->width; this->m_height = window->height; this->m_defaultWidth = window->width; this->m_defaultHeight = window->height; this->m_window->resize_callback = resize_callback; this->m_window->free_callback = free_callback; this->frame_callback = NULL; this->wl_queue = wl_display_create_queue(display); this->m_format = 1; const_cast<int&>(ANativeWindow::minSwapInterval) = 0; const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; // This is the default as per the EGL documentation this->m_swap_interval = 1; this->m_alloc = alloc_device; m_gralloc = gralloc; m_usage=GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); m_queueReads = 0; m_freeBufs = 0; m_damage_rects = NULL; m_damage_n_rects = 0; m_lastBuffer = 0; setBufferCount(3); HYBRIS_TRACE_END("wayland-platform", "create_window", ""); }
/* Test that when receiving the first of two synchronization * callback events, destroying the second one doesn't cause any * errors even if the delete_id event is handled out of order. */ static int client_test_multiple_queues(void) { struct wl_event_queue *queue; struct wl_callback *callback1; struct multiple_queues_state state; int ret = 0; state.display = wl_display_connect(SOCKET_NAME); client_assert(state.display); /* Make the current thread the display thread. This is because * wl_display_dispatch_queue() will only read the display fd if * the main display thread has been set. */ wl_display_dispatch_pending(state.display); queue = wl_display_create_queue(state.display); client_assert(queue); state.done = false; callback1 = wl_display_sync(state.display); wl_callback_add_listener(callback1, &sync_listener, &state); wl_proxy_set_queue((struct wl_proxy *) callback1, queue); state.callback2 = wl_display_sync(state.display); wl_callback_add_listener(state.callback2, &sync_listener, NULL); wl_proxy_set_queue((struct wl_proxy *) state.callback2, queue); wl_display_flush(state.display); while (!state.done && !ret) ret = wl_display_dispatch_queue(state.display, queue); wl_display_disconnect(state.display); return ret == -1 ? -1 : 0; }
static gboolean gst_mfx_window_wayland_create (GstMfxWindow * window, guint * width, guint * height) { GstMfxWindowWaylandPrivate *const priv = GST_MFX_WINDOW_WAYLAND_GET_PRIVATE (window); GstMfxDisplayWaylandPrivate *const priv_display = GST_MFX_DISPLAY_WAYLAND_GET_PRIVATE (GST_MFX_WINDOW_DISPLAY (window)); struct wl_display *const wl_display = GST_MFX_DISPLAY_HANDLE (GST_MFX_WINDOW_DISPLAY (window)); GError *err = NULL; GST_DEBUG ("create window, size %ux%u", *width, *height); g_return_val_if_fail (priv_display->compositor != NULL, FALSE); g_return_val_if_fail (priv_display->shell != NULL, FALSE); GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->event_queue = wl_display_create_queue (wl_display); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); if (!priv->event_queue) return FALSE; GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->surface = wl_compositor_create_surface (priv_display->compositor); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); if (!priv->surface) return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue); GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->shell_surface = wl_shell_get_shell_surface (priv_display->shell, priv->surface); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); if (!priv->shell_surface) return FALSE; wl_proxy_set_queue ((struct wl_proxy *) priv->shell_surface, priv->event_queue); wl_shell_surface_add_listener (priv->shell_surface, &shell_surface_listener, window); wl_shell_surface_set_toplevel (priv->shell_surface); #ifdef USE_WESTON_4_0 if (priv_display->viewporter) { GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->wp_viewport = wp_viewporter_get_viewport (priv_display->viewporter, priv->surface); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); } #else if (priv_display->scaler) { GST_MFX_DISPLAY_LOCK (GST_MFX_WINDOW_DISPLAY (window)); priv->viewport = wl_scaler_get_viewport (priv_display->scaler, priv->surface); GST_MFX_DISPLAY_UNLOCK (GST_MFX_WINDOW_DISPLAY (window)); } #endif priv->poll = gst_poll_new (TRUE); gst_poll_fd_init (&priv->pollfd); if (priv->fullscreen_on_show) gst_mfx_window_wayland_set_fullscreen (window, TRUE); #ifdef USE_EGL if (gst_mfx_display_has_opengl (GST_MFX_WINDOW_DISPLAY (window))) { priv->egl_window = wl_egl_window_create (priv->surface, *width, *height); if (!priv->egl_window) return FALSE; GST_MFX_WINDOW_ID (window) = GPOINTER_TO_INT(priv->egl_window); } #endif priv->thread = g_thread_try_new ("wayland-thread", gst_mfx_window_wayland_thread_run, window, &err); if (err) return FALSE; priv->is_shown = TRUE; return TRUE; }
static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg, video_format_t *fmtp, vlc_video_context *context) { if (cfg->window->type != VOUT_WINDOW_TYPE_WAYLAND) return VLC_EGENERIC; vout_display_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; vd->sys = sys; sys->embed = NULL; sys->eventq = NULL; sys->shm = NULL; sys->viewporter = NULL; sys->active_buffers = 0; sys->display_width = cfg->display.width; sys->display_height = cfg->display.height; sys->use_buffer_transform = false; /* Get window */ sys->embed = cfg->window; assert(sys->embed != NULL); struct wl_display *display = sys->embed->display.wl; sys->eventq = wl_display_create_queue(display); if (sys->eventq == NULL) goto error; struct wl_registry *registry = wl_display_get_registry(display); if (registry == NULL) goto error; wl_proxy_set_queue((struct wl_proxy *)registry, sys->eventq); wl_registry_add_listener(registry, ®istry_cbs, vd); wl_display_roundtrip_queue(display, sys->eventq); wl_registry_destroy(registry); if (sys->shm == NULL) goto error; wl_shm_add_listener(sys->shm, &shm_cbs, vd); wl_display_roundtrip_queue(display, sys->eventq); struct wl_surface *surface = sys->embed->handle.wl; if (sys->viewporter != NULL) sys->viewport = wp_viewporter_get_viewport(sys->viewporter, surface); else sys->viewport = NULL; /* Determine our pixel format */ static const enum wl_output_transform transforms[8] = { [ORIENT_TOP_LEFT] = WL_OUTPUT_TRANSFORM_NORMAL, [ORIENT_TOP_RIGHT] = WL_OUTPUT_TRANSFORM_FLIPPED, [ORIENT_BOTTOM_LEFT] = WL_OUTPUT_TRANSFORM_FLIPPED_180, [ORIENT_BOTTOM_RIGHT] = WL_OUTPUT_TRANSFORM_180, [ORIENT_LEFT_TOP] = WL_OUTPUT_TRANSFORM_FLIPPED_270, [ORIENT_LEFT_BOTTOM] = WL_OUTPUT_TRANSFORM_90, [ORIENT_RIGHT_TOP] = WL_OUTPUT_TRANSFORM_270, [ORIENT_RIGHT_BOTTOM] = WL_OUTPUT_TRANSFORM_FLIPPED_90, };
GstWlDisplay * gst_wl_display_new_existing (struct wl_display * display, gboolean take_ownership, GError ** error) { GstWlDisplay *self; GError *err = NULL; gint i; g_return_val_if_fail (display != NULL, NULL); self = g_object_new (GST_TYPE_WL_DISPLAY, NULL); self->display = display; self->own_display = take_ownership; self->queue = wl_display_create_queue (self->display); self->registry = wl_display_get_registry (self->display); wl_proxy_set_queue ((struct wl_proxy *) self->registry, self->queue); wl_registry_add_listener (self->registry, ®istry_listener, self); /* we need exactly 2 roundtrips to discover global objects and their state */ for (i = 0; i < 2; i++) { if (gst_wl_display_roundtrip (self) < 0) { *error = g_error_new (g_quark_from_static_string ("GstWlDisplay"), 0, "Error communicating with the wayland display"); g_object_unref (self); return NULL; } } /* verify we got all the required interfaces */ #define VERIFY_INTERFACE_EXISTS(var, interface) \ if (!self->var) { \ g_set_error (error, g_quark_from_static_string ("GstWlDisplay"), 0, \ "Could not bind to " interface ". Either it is not implemented in " \ "the compositor, or the implemented version doesn't match"); \ g_object_unref (self); \ return NULL; \ } VERIFY_INTERFACE_EXISTS (compositor, "wl_compositor"); VERIFY_INTERFACE_EXISTS (subcompositor, "wl_subcompositor"); VERIFY_INTERFACE_EXISTS (shell, "wl_shell"); VERIFY_INTERFACE_EXISTS (shm, "wl_shm"); #undef VERIFY_INTERFACE_EXISTS /* We make the viewporter optional even though it may cause bad display. * This is so one can test wayland display on older compositor or on * compositor that don't implement this extension. */ if (!self->viewporter) { g_warning ("Wayland compositor is missing the ability to scale, video " "display may not work properly."); } if (!self->dmabuf) { g_warning ("Could not bind to zwp_linux_dmabuf_v1"); } self->thread = g_thread_try_new ("GstWlDisplay", gst_wl_display_thread_run, self, &err); if (err) { g_propagate_prefixed_error (error, err, "Failed to start thread for the display's events"); g_object_unref (self); return NULL; } return self; }
/* Initialize a native display for use with WSEGL */ static WSEGLError wseglInitializeDisplay (NativeDisplayType nativeDisplay, WSEGLDisplayHandle *display, const WSEGLCaps **caps, WSEGLConfig **configs) { struct wl_egl_display *egldisplay = wl_egl_display_create((struct wl_display *) nativeDisplay); if (wseglFetchContext(egldisplay) != 1) { wl_egl_display_destroy(egldisplay); return WSEGL_OUT_OF_MEMORY; } /* If it is a framebuffer */ if (egldisplay->display == NULL) { wsegl_info("wayland-wsegl: Initializing framebuffer"); int fd; WSEGLPixelFormat format; /* Open the framebuffer and fetch its properties */ fd = open("/dev/fb0", O_RDWR, 0); if (fd < 0) { perror("/dev/fb0"); wseglReleaseContext(egldisplay); wl_egl_display_destroy(egldisplay); return WSEGL_CANNOT_INITIALISE; } if (ioctl(fd, FBIOGET_VSCREENINFO, &egldisplay->var) < 0) { perror("FBIOGET_VSCREENINFO"); wseglReleaseContext(egldisplay); wl_egl_display_destroy(egldisplay); close(fd); return WSEGL_CANNOT_INITIALISE; } if (ioctl(fd, FBIOGET_FSCREENINFO, &egldisplay->fix) < 0) { perror("FBIOGET_FSCREENINFO"); wseglReleaseContext(egldisplay); wl_egl_display_destroy(egldisplay); close(fd); return WSEGL_CANNOT_INITIALISE; } egldisplay->fd = fd; format = getwseglPixelFormat(egldisplay); egldisplay->wseglDisplayConfigs[0].ePixelFormat = format; egldisplay->wseglDisplayConfigs[1].ePixelFormat = format; } else { egldisplay->queue = wl_display_create_queue(nativeDisplay); egldisplay->frame_callback = NULL; egldisplay->registry = wl_display_get_registry(nativeDisplay); wl_proxy_set_queue(egldisplay->registry, egldisplay->queue); wl_registry_add_listener(egldisplay->registry, ®istry_listener, egldisplay); assert(wayland_roundtrip(egldisplay) >= 0); assert(egldisplay->sgx_wlegl); } *display = (WSEGLDisplayHandle)egldisplay; *caps = wseglDisplayCaps; *configs = egldisplay->wseglDisplayConfigs; return WSEGL_SUCCESS; }
struct wl_event_queue *CreateQueue(){ return wl_display_create_queue(cobj); }