/** Background thread for Wayland shell events handling */ static void *Thread(void *data) { vout_window_t *wnd = data; struct wl_display *display = wnd->display.wl; struct pollfd ufd[1]; int canc = vlc_savecancel(); vlc_cleanup_push(cleanup_wl_display_read, display); ufd[0].fd = wl_display_get_fd(display); ufd[0].events = POLLIN; for (;;) { while (wl_display_prepare_read(display) != 0) wl_display_dispatch_pending(display); wl_display_flush(display); vlc_restorecancel(canc); while (poll(ufd, 1, -1) < 0); canc = vlc_savecancel(); wl_display_read_events(display); wl_display_dispatch_pending(display); } vlc_assert_unreachable(); vlc_cleanup_pop(); //vlc_restorecancel(canc); //return NULL; }
std::unique_ptr<PlatformDisplayWayland> PlatformDisplayWayland::create() { struct wl_display* wlDisplay = wl_display_connect(nullptr); if (!wlDisplay) { WTFLogAlways("PlatformDisplayWayland initialization: failed to connect to the Wayland server socket. Check your WAYLAND_DISPLAY or WAYLAND_SOCKET environment variables."); return nullptr; } std::unique_ptr<PlatformDisplayWayland> display(new PlatformDisplayWayland(wlDisplay)); if (!display->isInitialized()) { WTFLogAlways("PlatformDisplayWayland initialization: failed to complete the initialization of the display."); return nullptr; } GSource* baseSource = g_source_new(&EventSource::sourceFuncs, sizeof(EventSource)); auto* source = reinterpret_cast<EventSource*>(baseSource); source->display = display->m_display; source->pfd.fd = wl_display_get_fd(display->m_display); source->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP; source->pfd.revents = 0; g_source_add_poll(baseSource, &source->pfd); g_source_set_name(baseSource, "[WebKit] WaylandDisplay"); g_source_set_priority(baseSource, G_PRIORITY_HIGH + 30); g_source_set_can_recurse(baseSource, TRUE); g_source_attach(baseSource, g_main_context_get_thread_default()); return display; }
static void leak_closure(void) { struct wl_callback *cb; struct pollfd pfd; struct client *c = client_connect(); cb = wl_display_sync(c->wl_display); assert(cb); assert(wl_display_flush(c->wl_display) > 0); /* we don't need it, it is referenced */ wl_callback_destroy(cb); pfd.fd = wl_display_get_fd(c->wl_display); pfd.events = POLLIN; test_set_timeout(2); assert(poll(&pfd, 1, -1) == 1); /* read events, but do not dispatch them */ assert(wl_display_prepare_read(c->wl_display) == 0); assert(wl_display_read_events(c->wl_display) == 0); /* * now we have wl_callback.done and wl_display.delete_id queued; * if we now release the queue (in wl_display_disconnect()) * we should not leak memory */ client_disconnect(c); }
static gpointer gst_wl_display_thread_run (gpointer data) { GstWlDisplay *self = data; GstPollFD pollfd = GST_POLL_FD_INIT; pollfd.fd = wl_display_get_fd (self->display); gst_poll_add_fd (self->wl_fd_poll, &pollfd); gst_poll_fd_ctl_read (self->wl_fd_poll, &pollfd, TRUE); /* main loop */ while (1) { while (wl_display_prepare_read_queue (self->display, self->queue) != 0) wl_display_dispatch_queue_pending (self->display, self->queue); wl_display_flush (self->display); if (gst_poll_wait (self->wl_fd_poll, GST_CLOCK_TIME_NONE) < 0) { gboolean normal = (errno == EBUSY); wl_display_cancel_read (self->display); if (normal) break; else goto error; } else { wl_display_read_events (self->display); wl_display_dispatch_queue_pending (self->display, self->queue); } } return NULL; error: GST_ERROR ("Error communicating with the wayland server"); return NULL; }
static struct display * create_display(void) { struct display *display; display = malloc(sizeof *display); if (display == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } display->display = wl_display_connect(NULL); assert(display->display); display->formats = 0; display->registry = wl_display_get_registry(display->display); wl_registry_add_listener(display->registry, ®istry_listener, display); wl_display_roundtrip(display->display); if (display->shm == NULL) { fprintf(stderr, "No wl_shm global\n"); exit(1); } wl_display_roundtrip(display->display); if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) { fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n"); exit(1); } wl_display_get_fd(display->display); return display; }
WaylandEventQueue::WaylandEventQueue(IOLoop &_io_loop, EventQueue &_queue) :io_loop(_io_loop), queue(_queue), display(wl_display_connect(nullptr)) { if (display == nullptr) { fprintf(stderr, "wl_display_connect() failed\n"); exit(EXIT_FAILURE); } auto registry = wl_display_get_registry(display); wl_registry_add_listener(registry, ®istry_listener, this); wl_display_dispatch(display); wl_display_roundtrip(display); if (compositor == nullptr) { fprintf(stderr, "No Wayland compositor found\n"); exit(EXIT_FAILURE); } if (seat == nullptr) { fprintf(stderr, "No Wayland seat found\n"); exit(EXIT_FAILURE); } if (shell == nullptr) { fprintf(stderr, "No Wayland shell found\n"); exit(EXIT_FAILURE); } io_loop.Add(FileDescriptor(wl_display_get_fd(display)), io_loop.READ, *this); }
static struct display * create_display (void) { struct display *display; display = malloc (sizeof *display); display->display = wl_display_connect (NULL); if (display->display == NULL) { free (display); return NULL; } display->registry = wl_display_get_registry (display->display); wl_registry_add_listener (display->registry, ®istry_listener, display); wl_display_roundtrip (display->display); if (display->shm == NULL) { GST_ERROR ("No wl_shm global.."); return NULL; } wl_display_roundtrip (display->display); if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) { GST_ERROR ("WL_SHM_FORMAT_XRGB32 not available"); return NULL; } wl_display_get_fd (display->display); return display; }
WaylandDisplay::WaylandDisplay() { m_display = wl_display_connect(nullptr); m_registry = wl_display_get_registry(m_display); wl_registry_add_listener(m_registry, &g_registryListener, &m_interfaces); wl_display_roundtrip(m_display); m_eventSource = g_source_new(&EventSource::sourceFuncs, sizeof(EventSource)); auto* source = reinterpret_cast<EventSource*>(m_eventSource); source->display = m_display; source->pfd.fd = wl_display_get_fd(m_display); source->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP; source->pfd.revents = 0; g_source_add_poll(m_eventSource, &source->pfd); g_source_set_name(m_eventSource, "[WPE] WaylandDisplay"); g_source_set_priority(m_eventSource, G_PRIORITY_HIGH + 30); g_source_set_can_recurse(m_eventSource, TRUE); g_source_attach(m_eventSource, g_main_context_get_thread_default()); if (m_interfaces.xdg) { xdg_shell_add_listener(m_interfaces.xdg, &g_xdgShellListener, nullptr); xdg_shell_use_unstable_version(m_interfaces.xdg, 5); } wl_seat_add_listener(m_interfaces.seat, &g_seatListener, &m_seatData); m_seatData.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); m_seatData.xkb.composeTable = xkb_compose_table_new_from_locale(m_seatData.xkb.context, setlocale(LC_CTYPE, nullptr), XKB_COMPOSE_COMPILE_NO_FLAGS); if (m_seatData.xkb.composeTable) m_seatData.xkb.composeState = xkb_compose_state_new(m_seatData.xkb.composeTable, XKB_COMPOSE_STATE_NO_FLAGS); }
WaylandDisplay::WaylandDisplay() { m_display = wl_display_connect(nullptr); m_registry = wl_display_get_registry(m_display); wl_registry_add_listener(m_registry, &g_registryListener, &m_interfaces); wl_display_roundtrip(m_display); m_eventSource = g_source_new(&EventSource::sourceFuncs, sizeof(EventSource)); auto* source = reinterpret_cast<EventSource*>(m_eventSource); source->display = m_display; source->pfd.fd = wl_display_get_fd(m_display); source->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP; source->pfd.revents = 0; g_source_add_poll(m_eventSource, &source->pfd); g_source_set_name(m_eventSource, "[WPE] WaylandDisplay"); g_source_set_priority(m_eventSource, G_PRIORITY_HIGH + 30); g_source_set_can_recurse(m_eventSource, TRUE); g_source_attach(m_eventSource, g_main_context_get_thread_default()); if (m_interfaces.xdg) { xdg_shell_add_listener(m_interfaces.xdg, &g_xdgShellListener, nullptr); xdg_shell_use_unstable_version(m_interfaces.xdg, 5); } }
MockClient::MockClient() : display(wl_display_connect(0)) , compositor(0) , output(0) , registry(0) { if (!display) qFatal("MockClient(): wl_display_connect() failed"); registry = wl_display_get_registry(display); wl_registry_add_listener(registry, ®istryListener, this); fd = wl_display_get_fd(display); QSocketNotifier *readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); connect(readNotifier, SIGNAL(activated(int)), this, SLOT(readEvents())); QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; connect(dispatcher, SIGNAL(awake()), this, SLOT(flushDisplay())); QElapsedTimer timeout; timeout.start(); do { QCoreApplication::processEvents(); } while (!(compositor && output) && timeout.elapsed() < 1000); if (!compositor || !output) qFatal("MockClient(): failed to receive globals from display"); }
GSource * _gdk_wayland_display_event_source_new (GdkDisplay *display) { GSource *source; GdkWaylandEventSource *wl_source; GdkWaylandDisplay *display_wayland; char *name; source = g_source_new (&wl_glib_source_funcs, sizeof (GdkWaylandEventSource)); name = g_strdup_printf ("GDK Wayland Event source (%s)", "display name"); g_source_set_name (source, name); g_free (name); wl_source = (GdkWaylandEventSource *) source; display_wayland = GDK_WAYLAND_DISPLAY (display); wl_source->display = display; wl_source->pfd.fd = wl_display_get_fd(display_wayland->wl_display); wl_source->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP; g_source_add_poll(source, &wl_source->pfd); g_source_set_priority (source, GDK_PRIORITY_EVENTS); g_source_set_can_recurse (source, TRUE); g_source_attach (source, NULL); event_sources = g_list_prepend (event_sources, source); return source; }
void bar_run(struct bar *bar) { int pfds = bar->outputs->length + 2; struct pollfd *pfd = malloc(pfds * sizeof(struct pollfd)); bool dirty = true; pfd[0].fd = bar->ipc_event_socketfd; pfd[0].events = POLLIN; pfd[1].fd = bar->status_read_fd; pfd[1].events = POLLIN; int i; for (i = 0; i < bar->outputs->length; ++i) { struct output *output = bar->outputs->items[i]; pfd[i+2].fd = wl_display_get_fd(output->registry->display); pfd[i+2].events = POLLIN; } while (1) { if (dirty) { int i; for (i = 0; i < bar->outputs->length; ++i) { struct output *output = bar->outputs->items[i]; if (window_prerender(output->window) && output->window->cairo) { render(output, bar->config, bar->status); window_render(output->window); wl_display_flush(output->registry->display); } } } dirty = false; poll(pfd, pfds, -1); if (pfd[0].revents & POLLIN) { sway_log(L_DEBUG, "Got IPC event."); dirty = handle_ipc_event(bar); } if (bar->config->status_command && pfd[1].revents & POLLIN) { sway_log(L_DEBUG, "Got update from status command."); dirty = handle_status_line(bar); } // dispatch wl_display events for (i = 0; i < bar->outputs->length; ++i) { struct output *output = bar->outputs->items[i]; if (pfd[i+2].revents & POLLIN) { if (wl_display_dispatch(output->registry->display) == -1) { sway_log(L_ERROR, "failed to dispatch wl: %d", errno); } } else { wl_display_dispatch_pending(output->registry->display); } } } }
static gboolean gst_vaapi_window_wayland_sync (GstVaapiWindow * window) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); if (priv->sync_failed) return FALSE; if (priv->pollfd.fd < 0) { priv->pollfd.fd = wl_display_get_fd (wl_display); gst_poll_add_fd (priv->poll, &priv->pollfd); gst_poll_fd_ctl_read (priv->poll, &priv->pollfd, TRUE); } while (g_atomic_int_get (&priv->num_frames_pending) > 0) { while (wl_display_prepare_read_queue (wl_display, priv->event_queue) < 0) { if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) goto error; } if (wl_display_flush (wl_display) < 0) goto error; again: if (gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE) < 0) { int saved_errno = errno; if (saved_errno == EAGAIN || saved_errno == EINTR) goto again; if (saved_errno == EBUSY) { /* closing */ wl_display_cancel_read (wl_display); return FALSE; } goto error; } if (wl_display_read_events (wl_display) < 0) goto error; if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) goto error; } return TRUE; /* ERRORS */ error: { priv->sync_failed = TRUE; GST_ERROR ("Error on dispatching events: %s", g_strerror (errno)); return FALSE; } }
int main(int argc, char **argv) { struct sigaction sigint; struct display display = { 0 }; struct window window = { 0 }; window.display = &display; window.geometry.width = 250; window.geometry.height = 250; display.display = wl_display_connect(NULL); assert(display.display); wl_display_add_global_listener(display.display, display_handle_global, &display); wl_display_get_fd(display.display, event_mask_update, &display); wl_display_iterate(display.display, WL_DISPLAY_READABLE); init_egl(&display); create_surface(&window); init_gl(&window); sigint.sa_handler = signal_int; sigemptyset(&sigint.sa_mask); sigint.sa_flags = SA_RESETHAND; sigaction(SIGINT, &sigint, NULL); redraw(&window, NULL, 0); while (running) wl_display_iterate(display.display, display.mask); fprintf(stderr, "simple-egl exiting\n"); destroy_surface(&window); fini_egl(&display); if (display.shell) wl_shell_destroy(display.shell); if (display.compositor) wl_compositor_destroy(display.compositor); wl_display_flush(display.display); wl_display_disconnect(display.display); return 0; }
GSource * wayland_event_source_new (struct wl_display *display) { WaylandEventSource *source; source = (WaylandEventSource *) g_source_new (&wayland_event_source_funcs, sizeof (WaylandEventSource)); source->display = display; source->pfd.fd = wl_display_get_fd (display); source->pfd.events = G_IO_IN | G_IO_ERR; g_source_add_poll (&source->source, &source->pfd); return &source->source; }
void QWaylandEventThread::waylandDisplayConnect() { m_display = wl_display_connect(NULL); if (m_display == NULL) { qErrnoWarning(errno, "Failed to create display"); ::exit(1); } m_displayLock->unlock(); m_fileDescriptor = wl_display_get_fd(m_display); m_readNotifier = new QSocketNotifier(m_fileDescriptor, QSocketNotifier::Read, this); connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(readWaylandEvents())); }
static gpointer gst_mfx_window_wayland_thread_run (gpointer window) { GstMfxWindowWaylandPrivate *const priv = GST_MFX_WINDOW_WAYLAND_GET_PRIVATE (window); struct wl_display *const wl_display = GST_MFX_DISPLAY_HANDLE (GST_MFX_WINDOW_DISPLAY (window)); if (priv->sync_failed) return NULL; if (priv->pollfd.fd < 0) { priv->pollfd.fd = wl_display_get_fd (wl_display); gst_poll_add_fd (priv->poll, &priv->pollfd); gst_poll_fd_ctl_read (priv->poll, &priv->pollfd, TRUE); } while (1) { while (wl_display_prepare_read_queue (wl_display, priv->event_queue) < 0) { if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) goto error; } if (wl_display_flush (wl_display) < 0) goto error; again: if (gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE) < 0) { int saved_errno = errno; if (saved_errno == EAGAIN || saved_errno == EINTR) goto again; wl_display_cancel_read (wl_display); if (saved_errno == EBUSY) /* flushing */ return NULL; else goto error; } if (wl_display_read_events (wl_display) < 0) goto error; if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0) goto error; } return NULL; error: priv->sync_failed = TRUE; GST_ERROR ("Error on dispatching events: %s", g_strerror (errno)); return NULL; }
void fgPlatformSleepForEvents( fg_time_t msec ) { struct pollfd pfd; int err; pfd.fd = wl_display_get_fd( fgDisplay.pDisplay.display ); pfd.events = POLLIN | POLLERR | POLLHUP; wl_display_dispatch_pending( fgDisplay.pDisplay.display ); if ( ! wl_display_flush( fgDisplay.pDisplay.display ) ) { err = poll( &pfd, 1, msec ); if( ( -1 == err ) && ( errno != EINTR ) ) fgWarning ( "freeglut poll() error: %d", errno ); } }
GSource * _clutter_event_source_wayland_new (struct wl_display *display) { ClutterEventSourceWayland *source; source = (ClutterEventSourceWayland *) g_source_new (&clutter_event_source_wayland_funcs, sizeof (ClutterEventSourceWayland)); source->display = display; source->pfd.fd = wl_display_get_fd (display, clutter_event_source_wayland_update, source); source->pfd.events = G_IO_IN | G_IO_ERR; g_source_add_poll (&source->source, &source->pfd); return &source->source; }
static struct touch * touch_create(int width, int height) { struct touch *touch; touch = malloc(sizeof *touch); touch->display = wl_display_connect(NULL); assert(touch->display); touch->has_argb = 0; touch->registry = wl_display_get_registry(touch->display); wl_registry_add_listener(touch->registry, ®istry_listener, touch); wl_display_dispatch(touch->display); wl_display_roundtrip(touch->display); if (!touch->has_argb) { fprintf(stderr, "WL_SHM_FORMAT_ARGB32 not available\n"); exit(1); } wl_display_get_fd(touch->display); touch->width = width; touch->height = height; touch->surface = wl_compositor_create_surface(touch->compositor); touch->shell_surface = wl_shell_get_shell_surface(touch->shell, touch->surface); create_shm_buffer(touch); if (touch->shell_surface) { wl_shell_surface_add_listener(touch->shell_surface, &shell_surface_listener, touch); wl_shell_surface_set_toplevel(touch->shell_surface); } wl_surface_set_user_data(touch->surface, touch); wl_shell_surface_set_title(touch->shell_surface, "simple-touch"); memset(touch->data, 64, width * height * 4); wl_surface_attach(touch->surface, touch->buffer, 0, 0); wl_surface_damage(touch->surface, 0, 0, width, height); wl_surface_commit(touch->surface); return touch; }
static void *Thread(void *data) { demux_t *demux = data; demux_sys_t *sys = demux->p_sys; struct wl_display *display = sys->display; struct pollfd ufd[1]; unsigned interval = lroundf(CLOCK_FREQ / (sys->rate * 1000.f)); int canc = vlc_savecancel(); vlc_cleanup_push(cleanup_wl_display_read, display); ufd[0].fd = wl_display_get_fd(display); ufd[0].events = POLLIN; for (;;) { if (DisplayError(demux, display)) break; if (sys->es != NULL) { block_t *block = Shoot(demux); block->i_pts = block->i_dts = vlc_tick_now(); es_out_SetPCR(demux->out, block->i_pts); es_out_Send(demux->out, sys->es, block); } while (wl_display_prepare_read(display) != 0) wl_display_dispatch_pending(display); wl_display_flush(display); vlc_restorecancel(canc); while (poll(ufd, 1, interval) < 0); canc = vlc_savecancel(); wl_display_read_events(display); wl_display_dispatch_pending(display); } vlc_cleanup_pop(); vlc_restorecancel(canc); return NULL; }
void _glfwPlatformWaitEvents(void) { struct wl_display* display = _glfw.wl.display; struct pollfd fds[] = { { wl_display_get_fd(display), POLLIN }, }; while (wl_display_prepare_read(display) != 0) wl_display_dispatch_pending(display); wl_display_flush(display); if (poll(fds, 1, -1) > 0) { wl_display_read_events(display); wl_display_dispatch_pending(display); } else { wl_display_cancel_read(display); } }
void WaylandCore::pollEvents() { if( mDisplay == NULL || mRegistry == NULL ) { mShouldClose = true; return; } pollfd fds[] = { { wl_display_get_fd(mDisplay), POLLIN }, }; while( wl_display_prepare_read(mDisplay) != 0 ) { wl_display_dispatch_pending(mDisplay); } wl_display_flush(mDisplay); if( poll(fds,1,0) > 0 ) { wl_display_read_events(mDisplay); wl_display_dispatch_pending(mDisplay); } else { wl_display_cancel_read(mDisplay); } }
QWaylandDisplay::QWaylandDisplay(void) : argb_visual(0), premultiplied_argb_visual(0), rgb_visual(0) { display = this; qRegisterMetaType<uint32_t>("uint32_t"); mDisplay = wl_display_connect(NULL); if (mDisplay == NULL) { qErrnoWarning(errno, "Failed to create display"); qFatal("No wayland connection available."); } wl_display_add_global_listener(mDisplay, QWaylandDisplay::displayHandleGlobal, this); #ifdef QT_WAYLAND_GL_SUPPORT mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); #endif #ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT mWindowManagerIntegration = QWaylandWindowManagerIntegration::createIntegration(this); #endif blockingReadEvents(); #ifdef QT_WAYLAND_GL_SUPPORT mEglIntegration->initialize(); #endif connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(flushRequests())); mFd = wl_display_get_fd(mDisplay, sourceUpdate, this); mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read, this); connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents())); waitForScreens(); }
static void handleEvents(int timeout) { struct wl_display* display = _glfw.wl.display; struct pollfd fds[] = { { wl_display_get_fd(display), POLLIN }, }; while (wl_display_prepare_read(display) != 0) wl_display_dispatch_pending(display); // If an error different from EAGAIN happens, we have likely been // disconnected from the Wayland session, try to handle that the best we // can. if (wl_display_flush(display) < 0 && errno != EAGAIN) { _GLFWwindow* window = _glfw.windowListHead; while (window) { _glfwInputWindowCloseRequest(window); window = window->next; } wl_display_cancel_read(display); return; } if (poll(fds, 1, timeout) > 0) { wl_display_read_events(display); wl_display_dispatch_pending(display); } else { wl_display_cancel_read(display); } }
static struct display * create_display(void) { struct display *display; display = malloc(sizeof *display); display->display = wl_display_connect(NULL); assert(display->display); display->formats = 0; wl_display_add_global_listener(display->display, display_handle_global, display); wl_display_iterate(display->display, WL_DISPLAY_READABLE); wl_display_roundtrip(display->display); if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) { fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n"); exit(1); } wl_display_get_fd(display->display, event_mask_update, display); return display; }
static struct weston_compositor * wayland_compositor_create(struct wl_display *display, int width, int height, const char *display_name, int *argc, char *argv[], struct weston_config *config) { struct wayland_compositor *c; struct wl_event_loop *loop; int fd; c = malloc(sizeof *c); if (c == NULL) return NULL; memset(c, 0, sizeof *c); if (weston_compositor_init(&c->base, display, argc, argv, config) < 0) goto err_free; c->parent.wl_display = wl_display_connect(display_name); if (c->parent.wl_display == NULL) { weston_log("failed to create display: %m\n"); goto err_compositor; } wl_list_init(&c->input_list); c->parent.registry = wl_display_get_registry(c->parent.wl_display); wl_registry_add_listener(c->parent.registry, ®istry_listener, c); wl_display_dispatch(c->parent.wl_display); c->base.wl_display = display; if (gl_renderer_create(&c->base, c->parent.wl_display, gl_renderer_alpha_attribs, NULL) < 0) goto err_display; c->base.destroy = wayland_destroy; c->base.restore = wayland_restore; c->border.top = 30; c->border.bottom = 24; c->border.left = 25; c->border.right = 26; /* requires border fields */ if (wayland_compositor_create_output(c, width, height) < 0) goto err_gl; /* requires gl_renderer_output_state_create called * by wayland_compositor_create_output */ create_border(c); loop = wl_display_get_event_loop(c->base.wl_display); fd = wl_display_get_fd(c->parent.wl_display); c->parent.wl_source = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, wayland_compositor_handle_event, c); if (c->parent.wl_source == NULL) goto err_gl; wl_event_source_check(c->parent.wl_source); return &c->base; err_gl: c->base.renderer->destroy(&c->base); err_display: wl_display_disconnect(c->parent.wl_display); err_compositor: weston_compositor_shutdown(&c->base); err_free: free(c); return NULL; }
int GetFd(){ return wl_display_get_fd(cobj); }
static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver) { #ifdef HAVE_OPENGL static const EGLint egl_attribs_gl[] = { WL_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE, }; #endif #ifdef HAVE_OPENGLES #ifdef HAVE_OPENGLES2 static const EGLint egl_attribs_gles[] = { WL_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE, }; #endif #ifdef HAVE_OPENGLES3 #ifdef EGL_KHR_create_context static const EGLint egl_attribs_gles3[] = { WL_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, EGL_NONE, }; #endif #endif #endif #ifdef HAVE_EGL static const EGLint egl_attribs_vg[] = { WL_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, EGL_NONE, }; EGLint major = 0, minor = 0; EGLint n; const EGLint *attrib_ptr = NULL; #endif gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*) calloc(1, sizeof(gfx_ctx_wayland_data_t)); if (!wl) return NULL; (void)video_driver; #ifdef HAVE_EGL switch (wl_api) { case GFX_CTX_OPENGL_API: #ifdef HAVE_OPENGL attrib_ptr = egl_attribs_gl; #endif break; case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_OPENGLES #ifdef HAVE_OPENGLES3 #ifdef EGL_KHR_create_context if (g_egl_major >= 3) attrib_ptr = egl_attribs_gles3; else #endif #endif #ifdef HAVE_OPENGLES2 attrib_ptr = egl_attribs_gles; #endif #endif break; case GFX_CTX_OPENVG_API: #ifdef HAVE_VG attrib_ptr = egl_attribs_vg; #endif break; case GFX_CTX_NONE: default: break; } #endif frontend_driver_destroy_signal_handler_state(); wl->input.dpy = wl_display_connect(NULL); wl->buffer_scale = 1; if (!wl->input.dpy) { RARCH_ERR("[Wayland]: Failed to connect to Wayland server.\n"); goto error; } frontend_driver_install_signal_handler(); wl->registry = wl_display_get_registry(wl->input.dpy); wl_registry_add_listener(wl->registry, ®istry_listener, wl); wl_display_roundtrip(wl->input.dpy); if (!wl->compositor) { RARCH_ERR("[Wayland]: Failed to create compositor.\n"); goto error; } if (!wl->shm) { RARCH_ERR("[Wayland]: Failed to create shm.\n"); goto error; } if (!wl->shell) { RARCH_ERR("[Wayland]: Failed to create shell.\n"); goto error; } wl->input.fd = wl_display_get_fd(wl->input.dpy); switch (wl_api) { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENVG_API: #ifdef HAVE_EGL if (!egl_init_context(&wl->egl, EGL_PLATFORM_WAYLAND_KHR, (EGLNativeDisplayType)wl->input.dpy, &major, &minor, &n, attrib_ptr)) { egl_report_error(); goto error; } if (n == 0 || !egl_has_config(&wl->egl)) goto error; #endif break; case GFX_CTX_VULKAN_API: #ifdef HAVE_VULKAN if (!vulkan_context_init(&wl->vk, VULKAN_WSI_WAYLAND)) goto error; #endif break; case GFX_CTX_NONE: default: break; } wl->input.keyboard_focus = true; wl->input.mouse.focus = true; wl->cursor.surface = wl_compositor_create_surface(wl->compositor); wl->cursor.theme = wl_cursor_theme_load(NULL, 16, wl->shm); wl->cursor.default_cursor = wl_cursor_theme_get_cursor(wl->cursor.theme, "left_ptr"); flush_wayland_fd(&wl->input); return wl; error: gfx_ctx_wl_destroy_resources(wl); if (wl) free(wl); return NULL; }
static CoglBool _cogl_winsys_renderer_connect (CoglRenderer *renderer, CoglError **error) { CoglRendererEGL *egl_renderer; CoglRendererWayland *wayland_renderer; renderer->winsys = g_slice_new0 (CoglRendererEGL); egl_renderer = renderer->winsys; wayland_renderer = g_slice_new0 (CoglRendererWayland); egl_renderer->platform = wayland_renderer; egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable; if (renderer->foreign_wayland_display) { wayland_renderer->wayland_display = renderer->foreign_wayland_display; } else { wayland_renderer->wayland_display = wl_display_connect (NULL); if (!wayland_renderer->wayland_display) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "Failed to connect wayland display"); goto error; } } wayland_renderer->wayland_registry = wl_display_get_registry (wayland_renderer->wayland_display); wl_registry_add_listener (wayland_renderer->wayland_registry, ®istry_listener, egl_renderer); /* * Ensure that that we've received the messages setting up the * compostor and shell object. */ wl_display_roundtrip (wayland_renderer->wayland_display); if (!wayland_renderer->wayland_compositor || !wayland_renderer->wayland_shell) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "Unable to find wl_compositor or wl_shell"); goto error; } egl_renderer->edpy = eglGetDisplay ((EGLNativeDisplayType) wayland_renderer->wayland_display); if (!_cogl_winsys_egl_renderer_connect_common (renderer, error)) goto error; wayland_renderer->fd = wl_display_get_fd (wayland_renderer->wayland_display); if (renderer->wayland_enable_event_dispatch) _cogl_poll_renderer_add_fd (renderer, wayland_renderer->fd, COGL_POLL_FD_EVENT_IN, prepare_wayland_display_events, dispatch_wayland_display_events, renderer); return TRUE; error: _cogl_winsys_renderer_disconnect (renderer); return FALSE; }