void flush_wayland_fd(void *data) { struct pollfd fd = {0}; input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data; wl_display_dispatch_pending(wl->dpy); wl_display_flush(wl->dpy); fd.fd = wl->fd; fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP; if (poll(&fd, 1, 0) > 0) { if (fd.revents & (POLLERR | POLLHUP)) { close(wl->fd); frontend_driver_set_signal_handler_state(1); } if (fd.revents & POLLIN) wl_display_dispatch(wl->dpy); if (fd.revents & POLLOUT) wl_display_flush(wl->dpy); } }
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 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); }
void gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, const GstVideoInfo * info) { if (G_UNLIKELY (info)) { window->video_width = gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); window->video_height = info->height; wl_subsurface_set_sync (window->video_subsurface); gst_wl_window_resize_video_surface (window, FALSE); gst_wl_window_set_opaque (window, info); } if (G_LIKELY (buffer)) gst_wl_buffer_attach (buffer, window->video_surface_wrapper); else wl_surface_attach (window->video_surface_wrapper, NULL, 0, 0); wl_surface_damage (window->video_surface_wrapper, 0, 0, window->video_rectangle.w, window->video_rectangle.h); wl_surface_commit (window->video_surface_wrapper); if (G_UNLIKELY (info)) { /* commit also the parent (area_surface) in order to change * the position of the video_subsurface */ wl_surface_damage (window->area_surface_wrapper, 0, 0, window->render_rectangle.w, window->render_rectangle.h); wl_surface_commit (window->area_surface_wrapper); wl_subsurface_set_desync (window->video_subsurface); } wl_display_flush (window->display->display); }
/** 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; }
static gboolean gdk_event_source_prepare(GSource *base, gint *timeout) { GdkWaylandEventSource *source = (GdkWaylandEventSource *) base; GdkWaylandDisplay *display = (GdkWaylandDisplay *) source->display; *timeout = -1; if (source->display->event_pause_count > 0) return _gdk_event_queue_find_first (source->display) != NULL; /* We have to add/remove the GPollFD if we want to update our * poll event mask dynamically. Instead, let's just flush all * write on idle instead, which is what this amounts to. */ if (_gdk_event_queue_find_first (source->display) != NULL) return TRUE; if (wl_display_flush (display->wl_display) < 0) g_error ("Error flushing display: %s", g_strerror (errno)); if (wl_display_dispatch_pending (display->wl_display) < 0) g_error ("Error dispatching display: %s", g_strerror (errno)); return FALSE; }
static void send_state(int fd, struct display* display) { char buf[64]; int len; int visible = display->surface->output != NULL; wl_fixed_t x = wl_fixed_from_int(-1); wl_fixed_t y = wl_fixed_from_int(-1); if (display->input->pointer_focus != NULL) { assert(display->input->pointer_focus == display->surface); x = wl_fixed_from_double(display->input->x); y = wl_fixed_from_double(display->input->y); } if (visible) { /* FIXME: this fails on multi-display setup */ /* assert(display->surface->output == display->output); */ } wl_display_flush(display->display); len = snprintf(buf, sizeof buf, "%d %d %d\n", x, y, visible); assert(write(fd, buf, len) == len); wl_display_roundtrip(display->display); }
static void gst_gl_window_wayland_egl_close (GstGLWindow * window) { GstGLWindowWaylandEGL *window_egl; window_egl = GST_GL_WINDOW_WAYLAND_EGL (window); destroy_surface (window_egl); if (window_egl->display.cursor_surface) wl_surface_destroy (window_egl->display.cursor_surface); if (window_egl->display.cursor_theme) wl_cursor_theme_destroy (window_egl->display.cursor_theme); if (window_egl->display.shell) wl_shell_destroy (window_egl->display.shell); if (window_egl->display.compositor) wl_compositor_destroy (window_egl->display.compositor); if (window_egl->display.display) { wl_display_flush (window_egl->display.display); wl_display_disconnect (window_egl->display.display); } }
NativeStateWayland::~NativeStateWayland() { if (window_) { if (window_->shell_surface) wl_shell_surface_destroy(window_->shell_surface); if (window_->opaque_reqion) wl_region_destroy(window_->opaque_reqion); if (window_->surface) wl_surface_destroy(window_->surface); if (window_->native) wl_egl_window_destroy(window_->native); delete window_; } if (display_) { if (display_->shell) wl_shell_destroy(display_->shell); for (OutputsVector::iterator it = display_->outputs.begin(); it != display_->outputs.end(); ++it) { wl_output_destroy((*it)->output); delete *it; } if (display_->compositor) wl_compositor_destroy(display_->compositor); if (display_->registry) wl_registry_destroy(display_->registry); if (display_->display) { wl_display_flush(display_->display); wl_display_disconnect(display_->display); } delete display_; } }
/* must be called with the render lock */ static void render_last_buffer (GstWaylandSink * sink) { GstWlMeta *meta; struct wl_surface *surface; struct wl_callback *callback; meta = gst_buffer_get_wl_meta (sink->last_buffer); surface = gst_wl_window_get_wl_surface (sink->window); g_atomic_int_set (&sink->redraw_pending, TRUE); callback = wl_surface_frame (surface); wl_callback_add_listener (callback, &frame_callback_listener, sink); /* Here we essentially add a reference to the buffer. This represents * the fact that the compositor is using the buffer and it should * not return back to the pool and be reused until the compositor * releases it. The release is handled internally in the pool */ gst_wayland_compositor_acquire_buffer (meta->pool, sink->last_buffer); wl_surface_attach (surface, meta->wbuffer, 0, 0); wl_surface_damage (surface, 0, 0, sink->window->surface_width, sink->window->surface_height); wl_surface_commit (surface); wl_display_flush (sink->display->display); }
void wl_dispatch_events() { wl_display_flush(registry->display); if (wl_display_dispatch(registry->display) == -1) { sway_log(L_ERROR, "failed to run wl_display_dispatch"); exit(1); } }
static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl) { if (!wl) return; switch (wl_api) { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENVG_API: #ifdef HAVE_EGL egl_destroy(&wl->egl); if (wl->win) wl_egl_window_destroy(wl->win); #endif break; case GFX_CTX_VULKAN_API: #ifdef HAVE_VULKAN vulkan_context_destroy(&wl->vk, wl->surface); if (wl->fd >= 0) close(wl->fd); #endif break; case GFX_CTX_NONE: default: break; } if (wl->shell) wl_shell_destroy(wl->shell); if (wl->compositor) wl_compositor_destroy(wl->compositor); if (wl->registry) wl_registry_destroy(wl->registry); if (wl->shell_surf) wl_shell_surface_destroy(wl->shell_surf); if (wl->surface) wl_surface_destroy(wl->surface); if (wl->dpy) { wl_display_flush(wl->dpy); wl_display_disconnect(wl->dpy); } #ifdef HAVE_EGL wl->win = NULL; #endif wl->shell = NULL; wl->compositor = NULL; wl->registry = NULL; wl->dpy = NULL; wl->shell_surf = NULL; wl->surface = NULL; wl->width = 0; wl->height = 0; }
void XdevLWindowWayland::show() { if(m_fullScreen) { wl_shell_surface_set_fullscreen(m_shellSurface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, nullptr); } else { wl_shell_surface_set_toplevel(m_shellSurface); } wl_display_flush(display); }
bool WL_destroy() { wl_registry_destroy(_WL_display.registry); NWMan_events_destroy(); wl_display_flush(_WL_display.display); wl_display_disconnect(_WL_display.display); return true; }
void sigalarm_handler(int sig) { signal(SIGALRM, SIG_IGN); // Hide typing indicator render_data.auth_state = AUTH_STATE_IDLE; render(&render_data); wl_display_flush(registry->display); signal(SIGALRM, sigalarm_handler); }
static void gdk_wayland_display_flush (GdkDisplay *display) { g_return_if_fail (GDK_IS_DISPLAY (display)); if (!display->closed) wl_display_flush (GDK_WAYLAND_DISPLAY (display)->wl_display); }
void WaylandNativeWindow::finishSwap() { int ret = 0; lock(); WaylandNativeWindowBuffer *wnb = queue.front(); if (!wnb) { wnb = m_lastBuffer; } else { queue.pop_front(); } assert(wnb); m_lastBuffer = wnb; wnb->busy = 1; ret = readQueue(false); if (this->frame_callback) { do { ret = readQueue(true); } while (this->frame_callback && ret != -1); } if (ret < 0) { HYBRIS_TRACE_END("wayland-platform", "queueBuffer_wait_for_frame_callback", "-%p", wnb); return; } if (wnb->wlbuffer == NULL) { wnb->wlbuffer_from_native_handle(m_android_wlegl, m_display, wl_queue); TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer); wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this); wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue); } if (m_swap_interval > 0) { this->frame_callback = wl_surface_frame(m_window->surface); wl_callback_add_listener(this->frame_callback, &frame_listener, this); wl_proxy_set_queue((struct wl_proxy *) this->frame_callback, this->wl_queue); } wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0); wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height); wl_surface_commit(m_window->surface); // Some compositors, namely Weston, queue buffer release events instead // of sending them immediately. If a frame event is used, this should // not be a problem. Without a frame event, we need to send a sync // request to ensure that they get flushed. wl_callback_destroy(wl_display_sync(m_display)); wl_display_flush(m_display); fronted.push_back(wnb); m_window->attached_width = wnb->width; m_window->attached_height = wnb->height; m_damage_rects = NULL; m_damage_n_rects = 0; unlock(); }
static void gst_wl_display_finalize (GObject * gobject) { GstWlDisplay *self = GST_WL_DISPLAY (gobject); gst_poll_set_flushing (self->wl_fd_poll, TRUE); if (self->thread) g_thread_join (self->thread); /* to avoid buffers being unregistered from another thread * at the same time, take their ownership */ g_mutex_lock (&self->buffers_mutex); self->shutting_down = TRUE; g_hash_table_foreach (self->buffers, (GHFunc) g_object_ref, NULL); g_mutex_unlock (&self->buffers_mutex); g_hash_table_foreach (self->buffers, (GHFunc) gst_wl_buffer_force_release_and_unref, NULL); g_hash_table_remove_all (self->buffers); g_array_unref (self->shm_formats); g_array_unref (self->dmabuf_formats); gst_poll_free (self->wl_fd_poll); g_hash_table_unref (self->buffers); g_mutex_clear (&self->buffers_mutex); if (self->viewporter) wp_viewporter_destroy (self->viewporter); if (self->shm) wl_shm_destroy (self->shm); if (self->dmabuf) zwp_linux_dmabuf_v1_destroy (self->dmabuf); if (self->shell) wl_shell_destroy (self->shell); if (self->compositor) wl_compositor_destroy (self->compositor); if (self->subcompositor) wl_subcompositor_destroy (self->subcompositor); if (self->registry) wl_registry_destroy (self->registry); if (self->queue) wl_event_queue_destroy (self->queue); if (self->own_display) { wl_display_flush (self->display); wl_display_disconnect (self->display); } G_OBJECT_CLASS (gst_wl_display_parent_class)->finalize (gobject); }
static int wayland_compositor_handle_event(int fd, uint32_t mask, void *data) { struct wayland_compositor *c = data; int count = 0; if (mask & WL_EVENT_READABLE) count = wl_display_dispatch(c->parent.wl_display); if (mask & WL_EVENT_WRITABLE) wl_display_flush(c->parent.wl_display); if (mask == 0) { count = wl_display_dispatch_pending(c->parent.wl_display); wl_display_flush(c->parent.wl_display); } return count; }
void QWaylandDisplay::flushRequests() { int ret = wl_display_dispatch_queue_pending(mDisplay, mEventQueue); if (ret < 0) { qWarning("The wayland connection broke (error %d). Did the wayland compositor die?", errno); exit(1); } wl_display_flush(mDisplay); }
xdl_int XdevLWindowEventServerWayland::update() { while(wl_display_prepare_read(display) < 0) { wl_display_dispatch_pending(display); } wl_display_flush(display); wl_display_read_events(display); return ERR_OK; }
void XdevLWindowWayland::setFullscreen(xdl_bool state) { m_fullScreen = state; if(state) { wl_shell_surface_set_fullscreen(m_shellSurface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, nullptr); } else { wl_shell_surface_set_toplevel(m_shellSurface); } wl_display_flush(display); }
static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic, vlc_tick_t date) { VLC_UNUSED(date); vout_display_sys_t *sys = vd->sys; struct wl_display *display = sys->embed->display.wl; struct wl_surface *surface = sys->embed->handle.wl; struct picture_buffer_t *picbuf = pic->p_sys; if (picbuf->fd == -1) return; struct buffer_data *d = malloc(sizeof (*d)); if (unlikely(d == NULL)) return; d->picture = pic; d->counter = &sys->active_buffers; off_t offset = picbuf->offset; const size_t stride = pic->p->i_pitch; const size_t size = pic->p->i_lines * stride; struct wl_shm_pool *pool; struct wl_buffer *buf; pool = wl_shm_create_pool(sys->shm, picbuf->fd, offset + size); if (pool == NULL) { free(d); return; } if (sys->viewport == NULL) /* Poor man's crop */ offset += 4 * vd->fmt.i_x_offset + pic->p->i_pitch * vd->fmt.i_y_offset; buf = wl_shm_pool_create_buffer(pool, offset, vd->fmt.i_visible_width, vd->fmt.i_visible_height, stride, WL_SHM_FORMAT_XRGB8888); wl_shm_pool_destroy(pool); if (buf == NULL) { free(d); return; } picture_Hold(pic); wl_buffer_add_listener(buf, &buffer_cbs, d); wl_surface_attach(surface, buf, 0, 0); wl_surface_damage(surface, 0, 0, sys->display_width, sys->display_height); wl_display_flush(display); sys->active_buffers++; (void) subpic; }
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); } } } }
int WaylandNativeWindow::postBuffer(ANativeWindowBuffer* buffer) { TRACE(""); WaylandNativeWindowBuffer *wnb = NULL; lock(); std::list<WaylandNativeWindowBuffer *>::iterator it = post_registered.begin(); for (; it != post_registered.end(); it++) { if ((*it)->other == buffer) { wnb = (*it); break; } } unlock(); if (!wnb) { wnb = new WaylandNativeWindowBuffer(buffer); wnb->common.incRef(&wnb->common); buffer->common.incRef(&buffer->common); } int ret = 0; lock(); wnb->busy = 1; ret = readQueue(false); unlock(); if (ret < 0) { return ret; } lock(); if (wnb->wlbuffer == NULL) { wnb->wlbuffer_from_native_handle(m_android_wlegl, m_display, wl_queue); TRACE("%p add listener with %p inside", wnb, wnb->wlbuffer); wl_buffer_add_listener(wnb->wlbuffer, &wl_buffer_listener, this); wl_proxy_set_queue((struct wl_proxy *) wnb->wlbuffer, this->wl_queue); post_registered.push_back(wnb); } TRACE("%p DAMAGE AREA: %dx%d", wnb, wnb->width, wnb->height); wl_surface_attach(m_window->surface, wnb->wlbuffer, 0, 0); wl_surface_damage(m_window->surface, 0, 0, wnb->width, wnb->height); wl_surface_commit(m_window->surface); wl_display_flush(m_display); posted.push_back(wnb); unlock(); return NO_ERROR; }
static int Control(vout_window_t *wnd, int cmd, va_list ap) { vout_window_sys_t *sys = wnd->sys; struct wl_display *display = wnd->display.wl; switch (cmd) { case VOUT_WINDOW_SET_STATE: return VLC_EGENERIC; case VOUT_WINDOW_SET_SIZE: { unsigned width = va_arg (ap, unsigned); unsigned height = va_arg (ap, unsigned); vlc_mutex_lock(&sys->lock); sys->top_width = width; sys->top_height = height; if (!sys->fullscreen) vout_window_ReportSize(wnd, width, height); vlc_mutex_unlock(&sys->lock); break; } case VOUT_WINDOW_SET_FULLSCREEN: { bool fs = va_arg(ap, int); if (fs && sys->output != NULL) { wl_shell_surface_set_fullscreen(sys->shell_surface, 1, 0, sys->output); vlc_mutex_lock(&sys->lock); sys->fullscreen = true; vout_window_ReportSize(wnd, sys->fs_width, sys->fs_height); vlc_mutex_unlock(&sys->lock); } else { wl_shell_surface_set_toplevel(sys->shell_surface); vlc_mutex_lock(&sys->lock); sys->fullscreen = false; vout_window_ReportSize(wnd, sys->top_width, sys->top_height); vlc_mutex_unlock(&sys->lock); } break; } default: msg_Err(wnd, "request %d not implemented", cmd); return VLC_EGENERIC; } wl_display_flush(display); return VLC_SUCCESS; }
const char* nsRetrievalContextWayland::GetClipboardData(const char* aMimeType, int32_t aWhichClipboard, uint32_t* aContentLength) { NS_ASSERTION(mDataOffer, "Requested data without valid data offer!"); if (!mDataOffer) { // TODO // Something went wrong. We're requested to provide clipboard data // but we haven't got any from wayland. Looks like rhbz#1455915. return nullptr; } int pipe_fd[2]; if (pipe(pipe_fd) == -1) return nullptr; wl_data_offer_receive(mDataOffer, aMimeType, pipe_fd[1]); close(pipe_fd[1]); wl_display_flush(mDisplay); struct pollfd fds; fds.fd = pipe_fd[0]; fds.events = POLLIN; // Choose some reasonable timeout here int ret = poll(&fds, 1, kClipboardTimeout / 1000); if (!ret || ret == -1) { close(pipe_fd[0]); return nullptr; } GIOChannel *channel = g_io_channel_unix_new(pipe_fd[0]); GError* error = nullptr; gchar *clipboardData = nullptr; gsize dataLength = 0; g_io_channel_set_encoding(channel, nullptr, &error); if (!error) { g_io_channel_read_to_end(channel, &clipboardData, &dataLength, &error); } if (error) { NS_WARNING( nsPrintfCString("Unexpected error when reading clipboard data: %s", error->message).get()); g_error_free(error); } g_io_channel_unref(channel); close(pipe_fd[0]); *aContentLength = dataLength; return reinterpret_cast<const char*>(clipboardData); }
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; } }
static void kick_display(struct wit_client *c) { assert(c); wl_display_flush(c->display); wl_display_dispatch_pending(c->display); int stat = kill(getppid(), SIGUSR1); assertf(stat == 0, "Failed sending SIGUSR1 signal to display"); }
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; }