void _cogl_poll_renderer_add_fd (CoglRenderer *renderer, int fd, CoglPollFDEvent events, CoglPollPrepareCallback prepare, CoglPollDispatchCallback dispatch, void *user_data) { CoglPollFD pollfd = { fd, events }; CoglPollSource *source; _cogl_poll_renderer_remove_fd (renderer, fd); source = g_slice_new0 (CoglPollSource); source->fd = fd; source->prepare = prepare; source->dispatch = dispatch; source->user_data = user_data; renderer->poll_sources = g_list_prepend (renderer->poll_sources, source); g_array_append_val (renderer->poll_fds, pollfd); renderer->poll_fds_age++; }
static void dispatch_wayland_display_events (void *user_data, int revents) { CoglRenderer *renderer = user_data; CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererWayland *wayland_renderer = egl_renderer->platform; if ((revents & COGL_POLL_FD_EVENT_IN)) { if (wl_display_dispatch (wayland_renderer->wayland_display) == -1 && errno != EAGAIN && errno != EINTR) goto socket_error; } if ((revents & COGL_POLL_FD_EVENT_OUT)) { int ret = wl_display_flush (wayland_renderer->wayland_display); if (ret == -1) { if (errno != EAGAIN && errno != EINTR) goto socket_error; } else { /* There is no more data to write so we don't need to wake * up when the write buffer is emptied anymore */ _cogl_poll_renderer_modify_fd (renderer, wayland_renderer->fd, COGL_POLL_FD_EVENT_IN); } } return; socket_error: /* If there was an error on the wayland socket then it's likely that * it's going to consistently fail so we'll stop waiting on the file * descriptor instead of making the application take up 100% CPU. * FIXME: it would be nice if there was some way to report this to * the application so that it can quit or recover */ _cogl_poll_renderer_remove_fd (renderer, wayland_renderer->fd); }
static int64_t prepare_wayland_display_events (void *user_data) { CoglRenderer *renderer = user_data; CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererWayland *wayland_renderer = egl_renderer->platform; int flush_ret; flush_ret = wl_display_flush (wayland_renderer->wayland_display); if (flush_ret == -1) { /* If the socket buffer became full then we need to wake up the * main loop once it is writable again */ if (errno == EAGAIN) { _cogl_poll_renderer_modify_fd (renderer, wayland_renderer->fd, COGL_POLL_FD_EVENT_IN | COGL_POLL_FD_EVENT_OUT); } else if (errno != EINTR) { /* If the flush failed for some other reason then it's * likely that it's going to consistently fail so we'll stop * waiting on the file descriptor instead of making the * application take up 100% CPU. FIXME: it would be nice if * there was some way to report this to the application so * that it can quit or recover */ _cogl_poll_renderer_remove_fd (renderer, wayland_renderer->fd); } } /* Calling this here is a bit dodgy because Cogl usually tries to * say that it won't do any event processing until * cogl_poll_renderer_dispatch is called. However Wayland doesn't * seem to provide any way to query whether the event queue is empty * and we would need to do that in order to force the main loop to * wake up to call it from dispatch. */ wl_display_dispatch_pending (wayland_renderer->wayland_display); return -1; }
static void _cogl_winsys_renderer_disconnect (CoglRenderer *renderer) { CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererWayland *wayland_renderer = egl_renderer->platform; if (egl_renderer->edpy) eglTerminate (egl_renderer->edpy); if (wayland_renderer->wayland_display) { _cogl_poll_renderer_remove_fd (renderer, wayland_renderer->fd); if (renderer->foreign_wayland_display == NULL) wl_display_disconnect (wayland_renderer->wayland_display); } g_slice_free (CoglRendererWayland, egl_renderer->platform); g_slice_free (CoglRendererEGL, egl_renderer); }