예제 #1
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");
}
예제 #2
0
파일: tty.cpp 프로젝트: nyorain/iro
//TerminalHandler
TerminalHandler::TerminalHandler(Compositor& comp)
{
    const char* number = getenv("XDG_VTNR");
    if(!number)
    {
        throw std::runtime_error("tty::tty: XDG_VTNR not set");
        return;
    }
	
	number_ = std::stoi(number);

	//open tty
    std::string ttyString = "/dev/tty" + std::to_string(number_);
	tty_ = open(ttyString.c_str(), O_RDWR | O_NOCTTY | O_CLOEXEC);
	if(tty_ < 0)
	{
        throw std::runtime_error("TerminalHandler::TerminalHandler: couldnt open " + ttyString);
        return;
	}

	int fd = tty_;

    //save current
    vt_stat state;
    if(ioctl(fd, VT_GETSTATE, &state) == -1)
    {
        throw std::runtime_error("could not get current tty");
        return;
    }

    //set it up
    if(ioctl(tty_, VT_ACTIVATE, number_) == -1 || ioctl(tty_, VT_WAITACTIVE, number_) == -1)
    {
        throw std::runtime_error("Could not activate tty");
        return;
    }
    focus_ = 1;
/*
	if (ioctl(fd, KDSKBMUTE, 1) == -1 && ioctl(fd, KDSKBMODE, K_OFF) == -1) 
	{
	    throw std::runtime_error("failed to set tty keyboard mode");
	    return;
	}

    if(ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1)
    {
        throw std::runtime_error("Could not set tty to graphics mode");
        return;
    }
*/

    vt_mode mode;
    mode.mode = VT_PROCESS;
    mode.acqsig = SIGUSR1;
    mode.relsig = SIGUSR2;

    if(ioctl(fd, VT_SETMODE, &mode) == -1)
    {
        throw std::runtime_error("Could not set vt_mode");
        return;
    }

	wl_event_loop_add_signal(&comp.wlEventLoop(), SIGUSR1, ttySignalhandler, this);
	wl_event_loop_add_signal(&comp.wlEventLoop(), SIGUSR2, ttySignalhandler, this);
}
예제 #3
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_);
}