コード例 #1
0
ファイル: dbus.c プロジェクト: ChristophHaag/weston
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;
}
コード例 #2
0
ファイル: compositor-wayland.c プロジェクト: anderco/weston
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, &registry_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;
}
コード例 #3
0
ファイル: dbus.cpp プロジェクト: nyorain/iro
//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");
}
コード例 #4
0
ファイル: x11.cpp プロジェクト: nyorain/iro
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_);
}