static int weston_dbus_bind(struct wl_event_loop *loop, DBusConnection *c, struct wl_event_source **ctx_out) { bool b; int r, fd; /* Idle events cannot reschedule themselves, therefore we use a dummy * event-fd and mark it for post-dispatch. Hence, the dbus * dispatcher is called after every dispatch-round. * This is required as dbus doesn't allow dispatching events from * within its own event sources. */ fd = eventfd(0, EFD_CLOEXEC); if (fd < 0) return -errno; *ctx_out = wl_event_loop_add_fd(loop, fd, 0, weston_dbus_dispatch, c); close(fd); if (!*ctx_out) return -ENOMEM; wl_event_source_check(*ctx_out); b = dbus_connection_set_watch_functions(c, weston_dbus_add_watch, weston_dbus_remove_watch, weston_dbus_toggle_watch, loop, NULL); if (!b) { r = -ENOMEM; goto error; } b = dbus_connection_set_timeout_functions(c, weston_dbus_add_timeout, weston_dbus_remove_timeout, weston_dbus_toggle_timeout, loop, NULL); if (!b) { r = -ENOMEM; goto error; } dbus_connection_ref(c); return 0; error: dbus_connection_set_timeout_functions(c, NULL, NULL, NULL, NULL, NULL); dbus_connection_set_watch_functions(c, NULL, NULL, NULL, NULL, NULL); wl_event_source_remove(*ctx_out); *ctx_out = NULL; return r; }
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; }
//DbusHandler DBusHandler::DBusHandler(Compositor& comp) : compositor_(&comp) { DBusError err; dbus_error_init(&err); dbus_connection_set_change_sigpipe(false); //todo: error checking everywhere if(!(dbusConnection_ = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err))) { std::string errStr; checkError(err, errStr); throw std::runtime_error("DBus::DBus: cant connect to dbus. " + errStr); return; } dbus_connection_set_exit_on_disconnect(dbusConnection_, false); //use dummy event fd int fd; if((fd = eventfd(0, EFD_CLOEXEC)) < 0) { throw std::runtime_error("DBus::DBus: cant create eventfd"); return; } //event source dbusEventSource_ = wl_event_loop_add_fd(&comp.wlEventLoop(), fd, 0, Callbacks::dispatchDBus, this); close(fd); wl_event_source_check(dbusEventSource_); //watch if(!dbus_connection_set_watch_functions(dbusConnection_, Callbacks::addWatch, Callbacks::removeWatch, Callbacks::toggleWatch, this, nullptr)) { throw std::runtime_error("dbus_connection_set_watch_functions failed"); return; } //timeout if(!dbus_connection_set_timeout_functions(dbusConnection_, Callbacks::addTimeout, Callbacks::removeTimeout, Callbacks::toggleTimeout, this, nullptr)) { throw std::runtime_error("dbus_connection_set_timeout_functions failed"); return; } //filter if(!dbus_connection_add_filter(dbusConnection_, Callbacks::dbusFilter, this, nullptr)) { throw std::runtime_error("dbus add filter failed"); return; } //disconnected callback signalCallbacks_.emplace_back(MsgCallback{DBUS_INTERFACE_LOCAL, "Diconnected", nytl::memberCallback(&DBusHandler::disconnected, this)}); ny::sendLog("dbus handler succesfully set up"); }
X11Backend::X11Backend(Compositor& comp, Seat& seat) : Backend(), compositor_(&comp), seat_(&seat) { //setup x connection xDisplay_ = XOpenDisplay(nullptr); if(!xDisplay_) { throw std::runtime_error("cant connect to x11 server"); return; } xConnection_ = XGetXCBConnection(xDisplay_); if(!xConnection_) { throw std::runtime_error("cant get xcb connection"); return; } XSetEventQueueOwner(xDisplay_, XCBOwnsEventQueue); if(xcb_connection_has_error(xConnection_)) { throw std::runtime_error("xcb connection error"); return; } xScreen_ = xcb_setup_roots_iterator(xcb_get_setup(xConnection_)).data; //atoms struct atomProp { xcb_atom_t& ret; std::string str; }; atomProp vec[] = { {atoms::protocols, "WM_PROTOCOLS"}, {atoms::deleteWindow, "WM_DELETE_WINDOW"} }; xcb_intern_atom_reply_t* reply; for(auto& p : vec) { auto atom = xcb_intern_atom(xConnection_, 0, p.str.size(), p.str.c_str()); reply = xcb_intern_atom_reply(xConnection_, atom, nullptr); p.ret = (reply ? reply->atom : 0); } //xkb xkbSetup(); //event source inputEventSource_ = wl_event_loop_add_fd(&comp.wlEventLoop(), xcb_get_file_descriptor(xConnection_), WL_EVENT_READABLE, eventCallback, this); if(!inputEventSource_) throw std::runtime_error("could not create wayland event source"); //what does this? really needed? wl_event_source_check(inputEventSource_); //eglContext eglContext_ = std::make_unique<WaylandEglContext>(xDisplay_); if(!eglContext_) throw std::runtime_error("x11Backend::x11Backend: failed to create EglContext"); eglContext_->bindWlDisplay(compositor_->wlDisplay()); xcb_flush(xConnection_); }