Пример #1
0
static void
weston_xserver_cleanup(struct weston_process *process, int status)
{
	struct weston_xserver *mxs =
		container_of(process, struct weston_xserver, process);

	mxs->process.pid = 0;
	mxs->client = NULL;
	mxs->resource = NULL;

	mxs->abstract_source =
		wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd,
				     WL_EVENT_READABLE,
				     weston_xserver_handle_event, mxs);

	mxs->unix_source =
		wl_event_loop_add_fd(mxs->loop, mxs->unix_fd,
				     WL_EVENT_READABLE,
				     weston_xserver_handle_event, mxs);

	if (mxs->wm) {
		weston_log("xserver exited, code %d\n", status);
		weston_wm_destroy(mxs->wm);
		mxs->wm = NULL;
	} else {
		/* If the X server crashes before it binds to the
		 * xserver interface, shut down and don't try
		 * again. */
		weston_log("xserver crashing too fast: %d\n", status);
		weston_xserver_shutdown(mxs);
	}
}
Пример #2
0
static void
weston_wm_send_incr_chunk(struct weston_wm *wm)
{
	int length;

	weston_log("property deleted\n");

	wm->selection_property_set = 0;
	if (wm->flush_property_on_delete) {
		weston_log("setting new property, %zu bytes\n",
			wm->source_data.size);
		wm->flush_property_on_delete = 0;
		length = weston_wm_flush_source_data(wm);

		if (wm->data_source_fd >= 0) {
			wm->property_source =
				wl_event_loop_add_fd(wm->server->loop,
						     wm->data_source_fd,
						     WL_EVENT_READABLE,
						     weston_wm_read_data_source,
						     wm);
		} else if (length > 0) {
			/* Transfer is all done, but queue a flush for
			 * the delete of the last chunk so we can set
			 * the 0 sized propert to signal the end of
			 * the transfer. */
			wm->flush_property_on_delete = 1;
			wl_array_release(&wm->source_data);
		} else {
			wm->selection_request.requestor = XCB_NONE;
		}
	}
}
Пример #3
0
static void
weston_wm_send_data(struct weston_wm *wm, xcb_atom_t target, const char *mime_type)
{
	struct weston_data_source *source;
	struct weston_seat *seat = weston_wm_pick_seat(wm);
	int p[2];

	if (pipe2(p, O_CLOEXEC | O_NONBLOCK) == -1) {
		weston_log("pipe2 failed: %m\n");
		weston_wm_send_selection_notify(wm, XCB_ATOM_NONE);
		return;
	}

	wl_array_init(&wm->source_data);
	wm->selection_target = target;
	wm->data_source_fd = p[0];
	wm->property_source = wl_event_loop_add_fd(wm->server->loop,
						   wm->data_source_fd,
						   WL_EVENT_READABLE,
						   weston_wm_read_data_source,
						   wm);

	source = seat->selection_data_source;
	source->send(source, mime_type, p[1]);
	close(p[1]);
}
Пример #4
0
static void
weston_wm_get_incr_chunk(struct weston_wm *wm)
{
	xcb_get_property_cookie_t cookie;
	xcb_get_property_reply_t *reply;

	cookie = xcb_get_property(wm->conn,
				  0, /* delete */
				  wm->selection_window,
				  wm->atom.wl_selection,
				  XCB_GET_PROPERTY_TYPE_ANY,
				  0, /* offset */
				  0x1fffffff /* length */);

	reply = xcb_get_property_reply(wm->conn, cookie, NULL);

	dump_property(wm, wm->atom.wl_selection, reply);

	if (xcb_get_property_value_length(reply) > 0) {
		wm->property_start = 0;
		wm->property_source =
			wl_event_loop_add_fd(wm->server->loop,
					     wm->data_source_fd,
					     WL_EVENT_WRITABLE,
					     weston_wm_write_property,
					     wm);
		wm->property_reply = reply;
	} else {
		weston_log("transfer complete\n");
		close(wm->data_source_fd);
		free(reply);
	}
}
Пример #5
0
static void
weston_wm_get_selection_data(struct weston_wm *wm)
{
	xcb_get_property_cookie_t cookie;
	xcb_get_property_reply_t *reply;

	cookie = xcb_get_property(wm->conn,
				  1, /* delete */
				  wm->selection_window,
				  wm->atom.wl_selection,
				  XCB_GET_PROPERTY_TYPE_ANY,
				  0, /* offset */
				  0x1fffffff /* length */);

	reply = xcb_get_property_reply(wm->conn, cookie, NULL);

	if (reply->type == wm->atom.incr) {
		dump_property(wm, wm->atom.wl_selection, reply);
		wm->incr = 1;
		free(reply);
	} else {
		dump_property(wm, wm->atom.wl_selection, reply);
		wm->incr = 0;
		wm->property_start = 0;
		wm->property_source =
			wl_event_loop_add_fd(wm->server->loop,
					     wm->data_source_fd,
					     WL_EVENT_WRITABLE,
					     weston_wm_write_property,
					     wm);
		wm->property_reply = reply;
	}
}
Пример #6
0
static struct clipboard_source *
clipboard_source_create(struct clipboard *clipboard,
			const char *mime_type, uint32_t serial, int fd)
{
	struct wl_display *display = clipboard->seat->compositor->wl_display;
	struct wl_event_loop *loop = wl_display_get_event_loop(display);
	struct clipboard_source *source;
	char **s;

	source = malloc(sizeof *source);
	wl_array_init(&source->contents);
	wl_array_init(&source->base.mime_types);
	source->base.accept = clipboard_source_accept;
	source->base.send = clipboard_source_send;
	source->base.cancel = clipboard_source_cancel;
	source->base.resource.data = &source->base;
	wl_signal_init(&source->base.resource.destroy_signal);
	source->refcount = 1;
	source->clipboard = clipboard;
	source->serial = serial;

	s = wl_array_add(&source->base.mime_types, sizeof *s);
	*s = strdup(mime_type);

	source->event_source =
		wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
				     clipboard_source_data, source);

	return source;
}
Пример #7
0
//Callbacks implementation
unsigned int DBusHandler::Callbacks::addWatch(DBusWatch* watch, void* data)
{
	if(!data) return 0;
	auto& loop = static_cast<DBusHandler*>(data)->compositor().wlEventLoop();

    unsigned int mask = 0;
    if (dbus_watch_get_enabled(watch))
    {
        unsigned int flags = dbus_watch_get_flags(watch);

        if (flags & DBUS_WATCH_READABLE) mask |= WL_EVENT_READABLE;
        if (flags & DBUS_WATCH_WRITABLE) mask |= WL_EVENT_WRITABLE;
    }

    int fd = dbus_watch_get_unix_fd(watch);
    wl_event_source* source = wl_event_loop_add_fd(&loop, fd, mask, dispatchWatch, watch);

    if (!source)
	{
		ny::sendWarning("failed to add dbus watch wl_event_loop_fd");
		return 0;
	}

    dbus_watch_set_data(watch, source, nullptr);
    return 1;
}
Пример #8
0
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;
}
Пример #9
0
struct evdev_device *
evdev_device_create(struct weston_seat *seat, const char *path, int device_fd)
{
	struct evdev_device *device;
	struct weston_compositor *ec;
	char devname[256] = "unknown";

	device = zalloc(sizeof *device);
	if (device == NULL)
		return NULL;

	ec = seat->compositor;
	device->output =
		container_of(ec->output_list.next, struct weston_output, link);

	device->seat = seat;
	device->is_mt = 0;
	device->mtdev = NULL;
	device->devnode = strdup(path);
	device->mt.slot = -1;
	device->rel.dx = 0;
	device->rel.dy = 0;
	device->dispatch = NULL;
	device->fd = device_fd;

	ioctl(device->fd, EVIOCGNAME(sizeof(devname)), devname);
	devname[sizeof(devname) - 1] = '\0';
	device->devname = strdup(devname);

	if (!evdev_handle_device(device)) {
		evdev_device_destroy(device);
		return EVDEV_UNHANDLED_DEVICE;
	}

	if (evdev_configure_device(device) == -1)
		goto err;

	/* If the dispatch was not set up use the fallback. */
	if (device->dispatch == NULL)
		device->dispatch = fallback_dispatch_create();
	if (device->dispatch == NULL)
		goto err;

	device->source = wl_event_loop_add_fd(ec->input_loop, device->fd,
					      WL_EVENT_READABLE,
					      evdev_device_data, device);
	if (device->source == NULL)
		goto err;

	return device;

err:
	evdev_device_destroy(device);
	return NULL;
}
Пример #10
0
Файл: udev.c Проект: Azarn/wlc
static bool
input_set_event_loop(struct wl_event_loop *loop)
{
   if (input.event_source) {
      wl_event_source_remove(input.event_source);
      input.event_source = NULL;
   }

   if (input.handle && loop && !(input.event_source = wl_event_loop_add_fd(loop, libinput_get_fd(input.handle), WL_EVENT_READABLE, input_event, &input)))
      return false;
   return true;
}
Пример #11
0
struct weston_launcher *
weston_launcher_connect(struct weston_compositor *compositor, int tty,
			const char *seat_id)
{
	struct weston_launcher *launcher;
	struct wl_event_loop *loop;
	int r;

	launcher = malloc(sizeof *launcher);
	if (launcher == NULL)
		return NULL;

	launcher->logind = NULL;
	launcher->compositor = compositor;
	launcher->drm_fd = -1;
	launcher->fd = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
	if (launcher->fd != -1) {
		launcher->tty = weston_environment_get_fd("WESTON_TTY_FD");
		/* We don't get a chance to read out the original kb
		 * mode for the tty, so just hard code K_UNICODE here
		 * in case we have to clean if weston-launch dies. */
		launcher->kb_mode = K_UNICODE;

		loop = wl_display_get_event_loop(compositor->wl_display);
		launcher->source = wl_event_loop_add_fd(loop, launcher->fd,
							WL_EVENT_READABLE,
							weston_launcher_data,
							launcher);
		if (launcher->source == NULL) {
			free(launcher);
			return NULL;
		}
	} else {
		r = weston_logind_connect(&launcher->logind, compositor,
					  seat_id, tty);
		if (r < 0) {
			launcher->logind = NULL;
			if (geteuid() == 0) {
				if (setup_tty(launcher, tty) == -1) {
					free(launcher);
					return NULL;
				}
			} else {
				free(launcher);
				return NULL;
			}
		}
	}

	return launcher;
}
Пример #12
0
static void
weston_wm_write_property(struct weston_wm *wm, xcb_get_property_reply_t *reply)
{
	wm->property_start = 0;
	wm->property_reply = reply;
	writable_callback(wm->data_source_fd, WL_EVENT_WRITABLE, wm);

	if (wm->property_reply)
		wm->property_source =
			wl_event_loop_add_fd(wm->server->loop,
					     wm->data_source_fd,
					     WL_EVENT_WRITABLE,
					     writable_callback, wm);
}
Пример #13
0
static void
clipboard_client_create(struct clipboard_source *source, int fd)
{
	struct weston_seat *seat = source->clipboard->seat;
	struct clipboard_client *client;
	struct wl_event_loop *loop =
		wl_display_get_event_loop(seat->compositor->wl_display);

	client = malloc(sizeof *client);

	client->offset = 0;
	client->source = source;
	source->refcount++;
	client->event_source =
		wl_event_loop_add_fd(loop, fd, WL_EVENT_WRITABLE,
				     clipboard_client_data, client);
}
Пример #14
0
static dbus_bool_t weston_dbus_add_watch(DBusWatch *watch, void *data)
{
	struct wl_event_loop *loop = data;
	struct wl_event_source *s;
	int fd;
	uint32_t mask = 0, flags;

	if (dbus_watch_get_enabled(watch)) {
		flags = dbus_watch_get_flags(watch);
		if (flags & DBUS_WATCH_READABLE)
			mask |= WL_EVENT_READABLE;
		if (flags & DBUS_WATCH_WRITABLE)
			mask |= WL_EVENT_WRITABLE;
	}

	fd = dbus_watch_get_unix_fd(watch);
	s = wl_event_loop_add_fd(loop, fd, mask, weston_dbus_dispatch_watch,
				 watch);
	if (!s)
		return FALSE;

	dbus_watch_set_data(watch, s, NULL);
	return TRUE;
}
Пример #15
0
//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");
}
Пример #16
0
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_);
}
Пример #17
0
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;
}
Пример #18
0
struct evdev_device *
evdev_device_create(struct weston_seat *seat, const char *path, int device_fd)
{
	struct evdev_device *device;
	struct weston_compositor *ec;
	char devname[256] = "unknown";

	device = malloc(sizeof *device);
	if (device == NULL)
		return NULL;
	memset(device, 0, sizeof *device);

	ec = seat->compositor;
	device->output =
		container_of(ec->output_list.next, struct weston_output, link);

	device->seat = seat;
	device->is_mt = 0;
	device->mtdev = NULL;
	device->devnode = strdup(path);
	device->mt.slot = -1;
	device->rel.dx = 0;
	device->rel.dy = 0;
	device->dispatch = NULL;
	device->fd = device_fd;

	ioctl(device->fd, EVIOCGNAME(sizeof(devname)), devname);
	device->devname = strdup(devname);

	if (!evdev_handle_device(device)) {
		free(device->devnode);
		free(device->devname);
		free(device);
		return EVDEV_UNHANDLED_DEVICE;
	}

	if (evdev_configure_device(device) == -1)
		goto err1;

	/* If the dispatch was not set up use the fallback. */
	if (device->dispatch == NULL)
		device->dispatch = fallback_dispatch_create();
	if (device->dispatch == NULL)
		goto err1;


	if (device->is_mt) {
		device->mtdev = mtdev_new_open(device->fd);
		if (!device->mtdev)
			weston_log("mtdev failed to open for %s\n", path);
	}

	device->source = wl_event_loop_add_fd(ec->input_loop, device->fd,
					      WL_EVENT_READABLE,
					      evdev_device_data, device);
	if (device->source == NULL)
		goto err2;

	return device;

err2:
	device->dispatch->interface->destroy(device->dispatch);
err1:
	free(device->devname);
	free(device->devnode);
	free(device);
	return NULL;
}
Пример #19
0
struct tty *
tty_create(struct weston_compositor *compositor, tty_vt_func_t vt_func,
           int tty_nr)
{
	struct termios raw_attributes;
	struct vt_mode mode = { 0 };
	int ret;
	struct tty *tty;
	struct wl_event_loop *loop;
	struct stat buf;
	char filename[16];
	struct vt_stat vts;

	tty = malloc(sizeof *tty);
	if (tty == NULL)
		return NULL;

	memset(tty, 0, sizeof *tty);
	tty->compositor = compositor;
	tty->vt_func = vt_func;

	tty->fd = weston_environment_get_fd("WESTON_TTY_FD");
	if (tty->fd < 0)
		tty->fd = STDIN_FILENO;

	if (tty_nr > 0) {
		snprintf(filename, sizeof filename, "/dev/tty%d", tty_nr);
		weston_log("compositor: using %s\n", filename);
		tty->fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC);
		tty->vt = tty_nr;
	} else if (fstat(tty->fd, &buf) == 0 &&
		   major(buf.st_rdev) == TTY_MAJOR &&
		   minor(buf.st_rdev) > 0) {
		if (tty->fd == STDIN_FILENO)
			tty->fd = fcntl(STDIN_FILENO, F_DUPFD_CLOEXEC, 0);
		tty->vt = minor(buf.st_rdev);
	} else {
		/* Fall back to try opening a new VT.  This typically
		 * requires root. */
		tty->fd = try_open_vt(tty);
	}

	if (tty->fd <= 0) {
		weston_log("failed to open tty: %m\n");
		free(tty);
		return NULL;
	}

	if (ioctl(tty->fd, VT_GETSTATE, &vts) == 0)
		tty->starting_vt = vts.v_active;
	else
		tty->starting_vt = tty->vt;

	if (tty->starting_vt != tty->vt) {
		if (ioctl(tty->fd, VT_ACTIVATE, tty->vt) < 0 ||
		    ioctl(tty->fd, VT_WAITACTIVE, tty->vt) < 0) {
			weston_log("failed to swtich to new vt\n");
			goto err;
		}
	}

	if (tcgetattr(tty->fd, &tty->terminal_attributes) < 0) {
		weston_log("could not get terminal attributes: %m\n");
		goto err;
	}

	/* Ignore control characters and disable echo */
	raw_attributes = tty->terminal_attributes;
	cfmakeraw(&raw_attributes);

	/* Fix up line endings to be normal (cfmakeraw hoses them) */
	raw_attributes.c_oflag |= OPOST | OCRNL;

	if (tcsetattr(tty->fd, TCSANOW, &raw_attributes) < 0)
		weston_log("could not put terminal into raw mode: %m\n");

	loop = wl_display_get_event_loop(compositor->wl_display);

	ioctl(tty->fd, KDGKBMODE, &tty->kb_mode);
	ret = ioctl(tty->fd, KDSKBMODE, K_OFF);
	if (ret) {
		ret = ioctl(tty->fd, KDSKBMODE, K_RAW);
		if (ret) {
			weston_log("failed to set keyboard mode on tty: %m\n");
			goto err_attr;
		}

		tty->input_source = wl_event_loop_add_fd(loop, tty->fd,
							 WL_EVENT_READABLE,
							 on_tty_input, tty);
		if (!tty->input_source)
			goto err_kdkbmode;
	}

	ret = ioctl(tty->fd, KDSETMODE, KD_GRAPHICS);
	if (ret) {
		weston_log("failed to set KD_GRAPHICS mode on tty: %m\n");
		goto err_kdkbmode;
	}

	tty->has_vt = 1;
	mode.mode = VT_PROCESS;
	mode.relsig = SIGUSR1;
	mode.acqsig = SIGUSR1;
	if (ioctl(tty->fd, VT_SETMODE, &mode) < 0) {
		weston_log("failed to take control of vt handling\n");
		goto err_kdmode;
	}

	tty->vt_source =
		wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, tty);
	if (!tty->vt_source)
		goto err_vtmode;

	return tty;

err_vtmode:
	ioctl(tty->fd, VT_SETMODE, &mode);

err_kdmode:
	ioctl(tty->fd, KDSETMODE, KD_TEXT);

err_kdkbmode:
	if (tty->input_source)
		wl_event_source_remove(tty->input_source);
	ioctl(tty->fd, KDSKBMODE, tty->kb_mode);

err_attr:
	tcsetattr(tty->fd, TCSANOW, &tty->terminal_attributes);

err:
	close(tty->fd);
	free(tty);
	return NULL;
}
Пример #20
0
WL_EXPORT int
weston_xserver_init(struct weston_compositor *compositor)
{
	struct wl_display *display = compositor->wl_display;
	struct weston_xserver *mxs;
	char lockfile[256], display_name[8];

	mxs = malloc(sizeof *mxs);
	memset(mxs, 0, sizeof *mxs);

	mxs->process.cleanup = weston_xserver_cleanup;
	mxs->wl_display = display;
	mxs->compositor = compositor;

	mxs->display = 0;

 retry:
	if (create_lockfile(mxs->display, lockfile, sizeof lockfile) < 0) {
		if (errno == EAGAIN) {
			goto retry;
		} else if (errno == EEXIST) {
			mxs->display++;
			goto retry;
		} else {
			free(mxs);
			return -1;
		}
	}

	mxs->abstract_fd = bind_to_abstract_socket(mxs->display);
	if (mxs->abstract_fd < 0 && errno == EADDRINUSE) {
		mxs->display++;
		unlink(lockfile);
		goto retry;
	}

	mxs->unix_fd = bind_to_unix_socket(mxs->display);
	if (mxs->unix_fd < 0) {
		unlink(lockfile);
		close(mxs->abstract_fd);
		free(mxs);
		return -1;
	}

	snprintf(display_name, sizeof display_name, ":%d", mxs->display);
	weston_log("xserver listening on display %s\n", display_name);
	setenv("DISPLAY", display_name, 1);

	mxs->loop = wl_display_get_event_loop(display);
	mxs->abstract_source =
		wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd,
				     WL_EVENT_READABLE,
				     weston_xserver_handle_event, mxs);
	mxs->unix_source =
		wl_event_loop_add_fd(mxs->loop, mxs->unix_fd,
				     WL_EVENT_READABLE,
				     weston_xserver_handle_event, mxs);

	wl_display_add_global(display, &xserver_interface, mxs, bind_xserver);

	mxs->destroy_listener.notify = weston_xserver_destroy;
	wl_signal_add(&compositor->destroy_signal, &mxs->destroy_listener);

	return 0;
}
Пример #21
0
Файл: drm.c Проект: ibab/swc
bool swc_drm_initialize()
{
    struct stat master, render;

    if (!find_primary_drm_device(drm.path, sizeof drm.path))
    {
        ERROR("Could not find DRM device\n");
        goto error0;
    }

    drm.taken_ids = 0;
    swc.drm->fd = launch_open_device(drm.path, O_RDWR | O_CLOEXEC);

    if (swc.drm->fd == -1)
    {
        ERROR("Could not open DRM device at %s\n", drm.path);
        goto error0;
    }

    if (fstat(swc.drm->fd, &master) != 0)
    {
        ERROR("Could not fstat DRM FD: %s\n", strerror(errno));
        goto error1;
    }

    if (snprintf(drm.path, sizeof drm.path, "/dev/dri/renderD%d",
                 minor(master.st_rdev) + 0x80) >= sizeof drm.path)
    {
        ERROR("Render node path is too long");
        goto error1;
    }

    if (stat(drm.path, &render) != 0)
    {
        ERROR("Could not stat render node for primary DRM device: %s\n",
              strerror(errno));
        goto error1;
    }

    if (master.st_mode != render.st_mode
        || minor(master.st_rdev) + 0x80 != minor(render.st_rdev))
    {
        ERROR("Render node does not have expected mode or minor number\n");
        goto error1;
    }

    if (!(swc.drm->context = wld_drm_create_context(swc.drm->fd)))
    {
        ERROR("Could not create WLD DRM context\n");
        goto error1;
    }

    if (!(swc.drm->renderer = wld_create_renderer(swc.drm->context)))
    {
        ERROR("Could not create WLD DRM renderer\n");
        goto error2;
    }

    drm.event_source = wl_event_loop_add_fd
        (swc.event_loop, swc.drm->fd, WL_EVENT_READABLE, &handle_data, NULL);

    if (!drm.event_source)
    {
        ERROR("Could not create DRM event source\n");
        goto error3;
    }

    if (!wld_drm_is_dumb(swc.drm->context))
    {
        drm.global = wl_global_create(swc.display, &wl_drm_interface, 2,
                                      NULL, &bind_drm);

        if (!drm.global)
        {
            ERROR("Could not create wl_drm global\n");
            goto error4;
        }
    }

    return true;

  error4:
    wl_event_source_remove(drm.event_source);
  error3:
    wld_destroy_renderer(swc.drm->renderer);
  error2:
    wld_destroy_context(swc.drm->context);
  error1:
    close(swc.drm->fd);
  error0:
    return false;
}
Пример #22
0
WL_EXPORT int
module_init(struct weston_compositor *compositor,
	    int *argc, char *argv[])

{
	struct wl_display *display = compositor->wl_display;
	struct weston_xserver *wxs;
	char lockfile[256], display_name[8];

	wxs = zalloc(sizeof *wxs);
	if (wxs == NULL)
		return -1;
	wxs->process.cleanup = weston_xserver_cleanup;
	wxs->wl_display = display;
	wxs->compositor = compositor;

	wxs->display = 0;

 retry:
	if (create_lockfile(wxs->display, lockfile, sizeof lockfile) < 0) {
		if (errno == EAGAIN) {
			goto retry;
		} else if (errno == EEXIST) {
			wxs->display++;
			goto retry;
		} else {
			free(wxs);
			return -1;
		}
	}

	wxs->abstract_fd = bind_to_abstract_socket(wxs->display);
	if (wxs->abstract_fd < 0 && errno == EADDRINUSE) {
		wxs->display++;
		unlink(lockfile);
		goto retry;
	}

	wxs->unix_fd = bind_to_unix_socket(wxs->display);
	if (wxs->unix_fd < 0) {
		unlink(lockfile);
		close(wxs->abstract_fd);
		free(wxs);
		return -1;
	}

	snprintf(display_name, sizeof display_name, ":%d", wxs->display);
	weston_log("xserver listening on display %s\n", display_name);
	setenv("DISPLAY", display_name, 1);

	wxs->loop = wl_display_get_event_loop(display);
	wxs->abstract_source =
		wl_event_loop_add_fd(wxs->loop, wxs->abstract_fd,
				     WL_EVENT_READABLE,
				     weston_xserver_handle_event, wxs);
	wxs->unix_source =
		wl_event_loop_add_fd(wxs->loop, wxs->unix_fd,
				     WL_EVENT_READABLE,
				     weston_xserver_handle_event, wxs);

	wxs->sigusr1_source = wl_event_loop_add_signal(wxs->loop, SIGUSR1,
						       handle_sigusr1, wxs);
	wxs->destroy_listener.notify = weston_xserver_destroy;
	wl_signal_add(&compositor->destroy_signal, &wxs->destroy_listener);

	return 0;
}
Пример #23
0
struct tty *
tty_create(struct wlsc_compositor *compositor)
{
	struct termios raw_attributes;
	struct vt_mode mode = { 0 };
	int ret;
	struct tty *tty;
	struct wl_event_loop *loop;

	tty = malloc(sizeof *tty);
	if (tty == NULL)
		return NULL;

	memset(tty, 0, sizeof *tty);
	tty->compositor = compositor;
	tty->fd = open("/dev/tty0", O_RDWR | O_NOCTTY);
	if (tty->fd <= 0) {
		fprintf(stderr, "failed to open active tty: %m\n");
		return NULL;
	}

	if (tcgetattr(tty->fd, &tty->terminal_attributes) < 0) {
		fprintf(stderr, "could not get terminal attributes: %m\n");
		return NULL;
	}

	/* Ignore control characters and disable echo */
	raw_attributes = tty->terminal_attributes;
	cfmakeraw(&raw_attributes);

	/* Fix up line endings to be normal (cfmakeraw hoses them) */
	raw_attributes.c_oflag |= OPOST | OCRNL;

	if (tcsetattr(tty->fd, TCSANOW, &raw_attributes) < 0)
		fprintf(stderr, "could not put terminal into raw mode: %m\n");

	loop = wl_display_get_event_loop(compositor->wl_display);
	tty->input_source =
		wl_event_loop_add_fd(loop, tty->fd,
				     WL_EVENT_READABLE, on_tty_input, tty);

	ret = ioctl(tty->fd, KDSETMODE, KD_GRAPHICS);
	if (ret) {
		fprintf(stderr, "failed to set KD_GRAPHICS mode on tty: %m\n");
		return NULL;
	}

	tty->compositor->focus = 1;
	mode.mode = VT_PROCESS;
	mode.relsig = SIGUSR1;
	mode.acqsig = SIGUSR2;
	if (!ioctl(tty->fd, VT_SETMODE, &mode) < 0) {
		fprintf(stderr, "failed to take control of vt handling\n");
		return NULL;
	}

	tty->leave_vt_source =
		wl_event_loop_add_signal(loop, SIGUSR1, on_leave_vt, tty);
	tty->enter_vt_source =
		wl_event_loop_add_signal(loop, SIGUSR2, on_enter_vt, tty);

	return tty;
}
Пример #24
0
WLC_API struct wlc_event_source*
wlc_event_loop_add_fd(int fd, uint32_t mask, int (*cb)(int fd, uint32_t mask, void *arg), void *arg)
{
   assert(wlc_event_loop());
   return (struct wlc_event_source*)wl_event_loop_add_fd(wlc_event_loop(), fd, mask, cb, arg);
}