static int headless_compositor_create_output(struct headless_compositor *c, struct headless_parameters *param) { struct headless_output *output; struct wl_event_loop *loop; output = zalloc(sizeof *output); if (output == NULL) return -1; output->mode.flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED; output->mode.width = param->width; output->mode.height = param->height; output->mode.refresh = 60000; wl_list_init(&output->base.mode_list); wl_list_insert(&output->base.mode_list, &output->mode.link); output->base.current_mode = &output->mode; weston_output_init(&output->base, &c->base, 0, 0, param->width, param->height, param->transform, 1); output->base.make = "weston"; output->base.model = "headless"; loop = wl_display_get_event_loop(c->base.wl_display); output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output); output->base.start_repaint_loop = headless_output_start_repaint_loop; output->base.repaint = headless_output_repaint; output->base.destroy = headless_output_destroy; output->base.assign_planes = NULL; output->base.set_backlight = NULL; output->base.set_dpms = NULL; output->base.switch_mode = NULL; if (c->use_pixman) { output->image_buf = malloc(param->width * param->height * 4); if (!output->image_buf) return -1; output->image = pixman_image_create_bits(PIXMAN_x8r8g8b8, param->width, param->height, output->image_buf, param->width * 4); if (pixman_renderer_output_create(&output->base) < 0) return -1; pixman_renderer_output_set_buffer(&output->base, output->image); } wl_list_insert(c->base.output_list.prev, &output->base.link); return 0; }
Compositor::Compositor() : m_display(wl_display_create()) , m_time(0) { wl_list_init(&m_outputResources); if (wl_display_add_socket(m_display, 0)) { fprintf(stderr, "Fatal: Failed to open server socket\n"); exit(EXIT_FAILURE); } wl_display_add_global(m_display, &wl_compositor_interface, this, bindCompositor); m_data_device_manager.reset(new DataDeviceManager(this, m_display)); wl_display_init_shm(m_display); m_seat.reset(new Seat(this, m_display)); m_pointer = m_seat->pointer(); m_keyboard = m_seat->keyboard(); wl_display_add_global(m_display, &wl_output_interface, this, bindOutput); wl_display_add_global(m_display, &wl_shell_interface, this, bindShell); m_loop = wl_display_get_event_loop(m_display); m_fd = wl_event_loop_get_fd(m_loop); }
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; }
int main(int argc, char *argv[]) { display = wl_display_create(); if (!display) return EXIT_FAILURE; if (wl_display_add_socket(display, NULL) != 0) return EXIT_FAILURE; if (!swc_initialize(display, NULL, &manager)) return EXIT_FAILURE; swc_add_binding(SWC_BINDING_KEY, SWC_MOD_LOGO, XKB_KEY_Return, &spawn, terminal_command); swc_add_binding(SWC_BINDING_KEY, SWC_MOD_LOGO, XKB_KEY_r, &spawn, dmenu_command); swc_add_binding(SWC_BINDING_KEY, SWC_MOD_LOGO, XKB_KEY_q, &quit, NULL); event_loop = wl_display_get_event_loop(display); wl_display_run(display); wl_display_destroy(display); return EXIT_SUCCESS; }
JNIEXPORT void JNICALL Java_net_jlekstrand_wheatley_wayland_Compositor_addToLooperNative(JNIEnv *env, jclass cls, jlong nativeHandle) { struct wheatley_compositor *wc = (struct wheatley_compositor *)(intptr_t)nativeHandle; ALooper *looper; if (wc->looper) { jni_util_throw_by_name(env, "java/lang/IllegalStateException", "Compositor already assigned to a looper"); return; } looper = ALooper_forThread(); if (looper == NULL) { jni_util_throw_by_name(env, "java/lang/RuntimeException", "Current thread does not have a Looper"); return; } ALooper_addFd(looper, wl_event_loop_get_fd(wl_display_get_event_loop(wc->display)), ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT, wheatley_compositor_ALooper_func, wc); wc->looper = looper; }
JNIEXPORT void JNICALL Java_net_jlekstrand_wheatley_wayland_Compositor_removeFromLooperNative( JNIEnv *env, jclass cls, jlong nativeHandle) { struct wheatley_compositor *wc = (struct wheatley_compositor *)(intptr_t)nativeHandle; ALooper *looper; if (!wc->looper) return; looper = ALooper_forThread(); if (looper == NULL) { jni_util_throw_by_name(env, "java/lang/RuntimeException", "Current thread does not have a Looper"); return; } if (wc->looper != looper) { jni_util_throw_by_name(env, "java/lang/IllegalStateException", "Compositor is not assigned to this looper"); return; } wc->looper = NULL; ALooper_removeFd(looper, wl_event_loop_get_fd(wl_display_get_event_loop(wc->display))); }
WL_EXPORT int module_init(struct weston_compositor *compositor, int *argc, char *argv[]) { struct wl_event_loop *loop; loop = wl_display_get_event_loop(compositor->wl_display); wl_event_loop_add_idle(loop, surface_to_from_global, compositor); return 0; }
WL_EXPORT int module_init(struct weston_compositor *compositor) { struct wl_event_loop *loop; loop = wl_display_get_event_loop(compositor->wl_display); wl_event_loop_add_idle(loop, surface_transform, compositor); return 0; }
static CoglBool wayland_event_source_dispatch (GSource *base, GSourceFunc callback, void *data) { WaylandEventSource *source = (WaylandEventSource *)base; struct wl_event_loop *loop = wl_display_get_event_loop (source->display); wl_event_loop_dispatch (loop, 0); return TRUE; }
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; }
WL_EXPORT int module_init(struct weston_compositor *compositor, int *argc, char *argv[]) { char *watchdog_time_env; struct wl_event_loop *loop; long watchdog_time_conv; struct systemd_notifier *notifier; notifier = zalloc(sizeof *notifier); if (notifier == NULL) return -1; notifier->compositor_destroy_listener.notify = weston_compositor_destroy_listener; wl_signal_add(&compositor->destroy_signal, ¬ifier->compositor_destroy_listener); if (add_systemd_sockets(compositor) < 0) return -1; sd_notify(0, "READY=1"); /* 'WATCHDOG_USEC' is environment variable that is set * by systemd to transfer 'WatchdogSec' watchdog timeout * setting from service file.*/ watchdog_time_env = getenv("WATCHDOG_USEC"); if (!watchdog_time_env) return 0; if (!safe_strtoint(watchdog_time_env, &watchdog_time_conv)) return 0; /* Convert 'WATCHDOG_USEC' to milliseconds and notify * systemd every half of that time.*/ watchdog_time_conv /= 1000 * 2; if (watchdog_time_conv <= 0) return 0; notifier->watchdog_time = watchdog_time_conv; loop = wl_display_get_event_loop(compositor->wl_display); notifier->watchdog_source = wl_event_loop_add_timer(loop, watchdog_handler, notifier); wl_event_source_timer_update(notifier->watchdog_source, notifier->watchdog_time); return 0; }
void wlc_set_active(bool active) { if (active == wlc.active) return; wlc.active = active; struct wlc_activate_event ev = { .active = active, .vt = 0 }; wl_signal_emit(&wlc.signals.activate, &ev); wlc_log(WLC_LOG_INFO, (wlc.active ? "become active" : "deactive")); } bool wlc_get_active(void) { return wlc.active; } const struct wlc_interface* wlc_interface(void) { return &wlc.interface; } struct wlc_system_signals* wlc_system_signals(void) { return &wlc.signals; } struct wl_event_loop* wlc_event_loop(void) { return wl_display_get_event_loop(wlc.display); } struct wl_display* wlc_display(void) { return wlc.display; } static void compositor_event(struct wl_listener *listener, void *data) { (void)listener, (void)data; // this event is currently only used for knowing when compositor died wl_display_terminate(wlc.display); }
static GSource * wayland_event_source_new (struct wl_display *display) { WaylandEventSource *source; struct wl_event_loop *loop = wl_display_get_event_loop (display); source = (WaylandEventSource *) g_source_new (&wayland_event_source_funcs, sizeof (WaylandEventSource)); source->display = display; source->pfd.fd = wl_event_loop_get_fd (loop); source->pfd.events = G_IO_IN | G_IO_ERR; g_source_add_poll (&source->source, &source->pfd); return &source->source; }
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); }
static int headless_compositor_create_output(struct headless_compositor *c, int width, int height) { struct headless_output *output; struct wl_event_loop *loop; output = malloc(sizeof *output); if (output == NULL) return -1; memset(output, 0, sizeof *output); output->mode.flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED; output->mode.width = width; output->mode.height = height; output->mode.refresh = 60; wl_list_init(&output->base.mode_list); wl_list_insert(&output->base.mode_list, &output->mode.link); output->base.current = &output->mode; weston_output_init(&output->base, &c->base, 0, 0, width, height, WL_OUTPUT_TRANSFORM_NORMAL); output->base.make = "weston"; output->base.model = "headless"; weston_output_move(&output->base, 0, 0); loop = wl_display_get_event_loop(c->base.wl_display); output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output); output->base.origin = output->base.current; output->base.repaint = headless_output_repaint; output->base.destroy = headless_output_destroy; output->base.assign_planes = NULL; output->base.set_backlight = NULL; output->base.set_dpms = NULL; output->base.switch_mode = NULL; wl_list_insert(c->base.output_list.prev, &output->base.link); return 0; }
static int wheatley_compositor_ALooper_func(int fd, int events, void *data) { struct wheatley_compositor *wc = data; ALooper *looper = ALooper_forThread(); if (!looper || looper != wc->looper) { ALOGD("Wrong Looper. Removing dispatch hook."); return 0; /* Not the right looper */ } if (events & ALOOPER_EVENT_INPUT) wl_event_loop_dispatch(wl_display_get_event_loop(wc->display), 0); wl_display_flush_clients(wc->display); return 1; }
WL_EXPORT int controller_module_init(struct weston_compositor *compositor, int *argc, char *argv[], const struct ivi_layout_interface *iface, size_t iface_version) { struct wl_event_loop *loop; struct test_launcher *launcher; const char *path; /* strict check, since this is an internal test module */ if (iface_version != sizeof(*iface)) { weston_log("fatal: controller interface mismatch\n"); return -1; } path = getenv("WESTON_BUILD_DIR"); if (!path) { weston_log("test setup failure: WESTON_BUILD_DIR not set\n"); return -1; } launcher = zalloc(sizeof *launcher); if (!launcher) return -1; launcher->compositor = compositor; launcher->layout_interface = iface; snprintf(launcher->exe, sizeof launcher->exe, "%s/ivi-layout.ivi", path); if (wl_global_create(compositor->wl_display, &weston_test_runner_interface, 1, launcher, bind_runner) == NULL) return -1; loop = wl_display_get_event_loop(compositor->wl_display); wl_event_loop_add_idle(loop, idle_launch_client, launcher); return 0; }
static int setup_tty(struct weston_launcher *launcher, int tty) { struct wl_event_loop *loop; struct vt_mode mode = { 0 }; struct stat buf; char tty_device[32] ="<stdin>"; int ret, kd_mode; if (tty == 0) { launcher->tty = dup(tty); if (launcher->tty == -1) { weston_log("couldn't dup stdin: %m\n"); return -1; } } else { snprintf(tty_device, sizeof tty_device, "/dev/tty%d", tty); launcher->tty = open(tty_device, O_RDWR | O_CLOEXEC); if (launcher->tty == -1) { weston_log("couldn't open tty %s: %m\n", tty_device); return -1; } } if (fstat(launcher->tty, &buf) == -1 || major(buf.st_rdev) != TTY_MAJOR || minor(buf.st_rdev) == 0) { weston_log("%s not a vt\n", tty_device); weston_log("if running weston from ssh, " "use --tty to specify a tty\n"); goto err_close; } ret = ioctl(launcher->tty, KDGETMODE, &kd_mode); if (ret) { weston_log("failed to get VT mode: %m\n"); return -1; } if (kd_mode != KD_TEXT) { weston_log("%s is already in graphics mode, " "is another display server running?\n", tty_device); goto err_close; } ioctl(launcher->tty, VT_ACTIVATE, minor(buf.st_rdev)); ioctl(launcher->tty, VT_WAITACTIVE, minor(buf.st_rdev)); if (ioctl(launcher->tty, KDGKBMODE, &launcher->kb_mode)) { weston_log("failed to read keyboard mode: %m\n"); goto err_close; } if (ioctl(launcher->tty, KDSKBMUTE, 1) && ioctl(launcher->tty, KDSKBMODE, K_OFF)) { weston_log("failed to set K_OFF keyboard mode: %m\n"); goto err_close; } ret = ioctl(launcher->tty, KDSETMODE, KD_GRAPHICS); if (ret) { weston_log("failed to set KD_GRAPHICS mode on tty: %m\n"); goto err_close; } mode.mode = VT_PROCESS; mode.relsig = SIGUSR1; mode.acqsig = SIGUSR1; if (ioctl(launcher->tty, VT_SETMODE, &mode) < 0) { weston_log("failed to take control of vt handling\n"); goto err_close; } loop = wl_display_get_event_loop(launcher->compositor->wl_display); launcher->vt_source = wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, launcher); if (!launcher->vt_source) goto err_close; return 0; err_close: close(launcher->tty); return -1; }
static int setup_tty(struct launcher_direct *launcher, int tty) { struct wl_event_loop *loop; struct vt_mode mode = { 0 }; struct stat buf; char tty_device[32] ="<stdin>"; int ret, kd_mode; if (tty == 0) { launcher->tty = dup(tty); if (launcher->tty == -1) { weston_log("couldn't dup stdin: %m\n"); return -1; } } else { snprintf(tty_device, sizeof tty_device, "/dev/tty%d", tty); launcher->tty = open(tty_device, O_RDWR | O_CLOEXEC); if (launcher->tty == -1) { weston_log("couldn't open tty %s: %m\n", tty_device); return -1; } } if (fstat(launcher->tty, &buf) == -1 || major(buf.st_rdev) != TTY_MAJOR || minor(buf.st_rdev) == 0) { weston_log("%s not a vt\n", tty_device); weston_log("if running weston from ssh, " "use --tty to specify a tty\n"); goto err_close; } ret = ioctl(launcher->tty, KDGETMODE, &kd_mode); if (ret) { weston_log("failed to get VT mode: %m\n"); return -1; } if (kd_mode != KD_TEXT) { weston_log("%s is already in graphics mode, " "is another display server running?\n", tty_device); goto err_close; } ioctl(launcher->tty, VT_ACTIVATE, minor(buf.st_rdev)); ioctl(launcher->tty, VT_WAITACTIVE, minor(buf.st_rdev)); if (ioctl(launcher->tty, KDGKBMODE, &launcher->kb_mode)) { weston_log("failed to read keyboard mode: %m\n"); goto err_close; } if (ioctl(launcher->tty, KDSKBMUTE, 1) && ioctl(launcher->tty, KDSKBMODE, K_OFF)) { weston_log("failed to set K_OFF keyboard mode: %m\n"); goto err_close; } ret = ioctl(launcher->tty, KDSETMODE, KD_GRAPHICS); if (ret) { weston_log("failed to set KD_GRAPHICS mode on tty: %m\n"); goto err_close; } /* * SIGRTMIN is used as global VT-acquire+release signal. Note that * SIGRT* must be tested on runtime, as their exact values are not * known at compile-time. POSIX requires 32 of them to be available. */ if (SIGRTMIN > SIGRTMAX) { weston_log("not enough RT signals available: %u-%u\n", SIGRTMIN, SIGRTMAX); ret = -EINVAL; goto err_close; } mode.mode = VT_PROCESS; mode.relsig = SIGRTMIN; mode.acqsig = SIGRTMIN; if (ioctl(launcher->tty, VT_SETMODE, &mode) < 0) { weston_log("failed to take control of vt handling\n"); goto err_close; } loop = wl_display_get_event_loop(launcher->compositor->wl_display); launcher->vt_source = wl_event_loop_add_signal(loop, SIGRTMIN, vt_handler, launcher); if (!launcher->vt_source) goto err_close; return 0; err_close: close(launcher->tty); return -1; }
int main (int argc, char **argv) { CoglandCompositor compositor; GMainLoop *loop; CoglError *error = NULL; GError *gerror = NULL; CoglVertexP2C4 triangle_vertices[] = { {0, 0.7, 0xff, 0x00, 0x00, 0xff}, {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} }; GSource *cogl_source; if (!process_arguments (&argc, &argv, &gerror)) { fprintf (stderr, "%s\n", gerror->message); return EXIT_FAILURE; } memset (&compositor, 0, sizeof (compositor)); compositor.wayland_display = wl_display_create (); if (compositor.wayland_display == NULL) g_error ("failed to create wayland display"); wl_list_init (&compositor.frame_callbacks); if (!wl_display_add_global (compositor.wayland_display, &wl_compositor_interface, &compositor, compositor_bind)) g_error ("Failed to register wayland compositor object"); wl_display_init_shm (compositor.wayland_display); loop = g_main_loop_new (NULL, FALSE); compositor.wayland_loop = wl_display_get_event_loop (compositor.wayland_display); compositor.wayland_event_source = wayland_event_source_new (compositor.wayland_display); g_source_attach (compositor.wayland_event_source, NULL); /* We want Cogl to use an EGL renderer because otherwise it won't * set up the wl_drm object and only SHM buffers will work. */ compositor.cogl_context = create_cogl_context (&compositor, TRUE /* use EGL constraint */, &error); if (compositor.cogl_context == NULL) { /* If we couldn't get an EGL context then try any type of * context */ cogl_error_free (error); error = NULL; compositor.cogl_context = create_cogl_context (&compositor, FALSE, /* don't set EGL constraint */ &error); if (compositor.cogl_context) g_warning ("Failed to create context with EGL constraint, " "falling back"); else g_error ("Failed to create a Cogl context: %s\n", error->message); } compositor.virtual_width = 800; compositor.virtual_height = 600; if (option_multiple_outputs) { int hw = compositor.virtual_width / 2; int hh = compositor.virtual_height / 2; /* Emulate compositing with multiple monitors... */ cogland_compositor_create_output (&compositor, 0, 0, hw, hh); cogland_compositor_create_output (&compositor, hw, 0, hw, hh); cogland_compositor_create_output (&compositor, 0, hh, hw, hh); cogland_compositor_create_output (&compositor, hw, hh, hw, hh); } else { cogland_compositor_create_output (&compositor, 0, 0, compositor.virtual_width, compositor.virtual_height); } if (wl_display_add_global (compositor.wayland_display, &wl_shell_interface, &compositor, bind_shell) == NULL) g_error ("Failed to register a global shell object"); if (wl_display_add_socket (compositor.wayland_display, "wayland-0")) g_error ("Failed to create socket"); compositor.triangle = cogl_primitive_new_p2c4 (compositor.cogl_context, COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); compositor.triangle_pipeline = cogl_pipeline_new (compositor.cogl_context); cogl_source = cogl_glib_source_new (compositor.cogl_context, G_PRIORITY_DEFAULT); g_source_attach (cogl_source, NULL); g_main_loop_run (loop); return 0; }
static int launcher_logind_connect(struct weston_launcher **out, struct weston_compositor *compositor, int tty, const char *seat_id, bool sync_drm) { struct launcher_logind *wl; struct wl_event_loop *loop; char *t; int r; wl = zalloc(sizeof(*wl)); if (wl == NULL) { r = -ENOMEM; goto err_out; } wl->base.iface = &launcher_logind_iface; wl->compositor = compositor; wl->sync_drm = sync_drm; wl->seat = strdup(seat_id); if (!wl->seat) { r = -ENOMEM; goto err_wl; } r = sd_pid_get_session(getpid(), &wl->sid); if (r < 0) { weston_log("logind: not running in a systemd session\n"); goto err_seat; } t = NULL; r = sd_session_get_seat(wl->sid, &t); if (r < 0) { weston_log("logind: failed to get session seat\n"); free(t); goto err_session; } else if (strcmp(seat_id, t)) { weston_log("logind: weston's seat '%s' differs from session-seat '%s'\n", seat_id, t); r = -EINVAL; free(t); goto err_session; } free(t); r = weston_sd_session_get_vt(wl->sid, &wl->vtnr); if (r < 0) { weston_log("logind: session not running on a VT\n"); goto err_session; } else if (tty > 0 && wl->vtnr != (unsigned int )tty) { weston_log("logind: requested VT --tty=%d differs from real session VT %u\n", tty, wl->vtnr); r = -EINVAL; goto err_session; } loop = wl_display_get_event_loop(compositor->wl_display); r = weston_dbus_open(loop, DBUS_BUS_SYSTEM, &wl->dbus, &wl->dbus_ctx); if (r < 0) { weston_log("logind: cannot connect to system dbus\n"); goto err_session; } r = launcher_logind_setup_dbus(wl); if (r < 0) goto err_dbus; r = launcher_logind_take_control(wl); if (r < 0) goto err_dbus_cleanup; r = launcher_logind_activate(wl); if (r < 0) goto err_dbus_cleanup; weston_log("logind: session control granted\n"); * (struct launcher_logind **) out = wl; return 0; err_dbus_cleanup: launcher_logind_destroy_dbus(wl); err_dbus: weston_dbus_close(wl->dbus, wl->dbus_ctx); err_session: free(wl->sid); err_seat: free(wl->seat); err_wl: free(wl); err_out: weston_log("logind: cannot setup systemd-logind helper (%d), using legacy fallback\n", r); errno = -r; return -1; }
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; }
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; }
int main (int argc, char **argv) { CoglandCompositor compositor; GMainLoop *loop; CoglError *error = NULL; CoglVertexP2C4 triangle_vertices[] = { {0, 0.7, 0xff, 0x00, 0x00, 0x80}, {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} }; GSource *cogl_source; memset (&compositor, 0, sizeof (compositor)); compositor.wayland_display = wl_display_create (); if (compositor.wayland_display == NULL) g_error ("failed to create wayland display"); g_queue_init (&compositor.frame_callbacks); if (!wl_display_add_global (compositor.wayland_display, &wl_compositor_interface, &compositor, compositor_bind)) g_error ("Failed to register wayland compositor object"); compositor.wayland_shm = wl_shm_init (compositor.wayland_display, &shm_callbacks); if (!compositor.wayland_shm) g_error ("Failed to allocate setup wayland shm callbacks"); loop = g_main_loop_new (NULL, FALSE); compositor.wayland_loop = wl_display_get_event_loop (compositor.wayland_display); compositor.wayland_event_source = wayland_event_source_new (compositor.wayland_loop); g_source_attach (compositor.wayland_event_source, NULL); compositor.cogl_display = cogl_display_new (NULL, NULL); cogl_wayland_display_set_compositor_display (compositor.cogl_display, compositor.wayland_display); compositor.cogl_context = cogl_context_new (compositor.cogl_display, &error); if (!compositor.cogl_context) g_error ("Failed to create a Cogl context: %s\n", error->message); compositor.virtual_width = 640; compositor.virtual_height = 480; /* Emulate compositing with multiple monitors... */ cogland_compositor_create_output (&compositor, 0, 0, 320, 240); cogland_compositor_create_output (&compositor, 320, 0, 320, 240); cogland_compositor_create_output (&compositor, 0, 240, 320, 240); cogland_compositor_create_output (&compositor, 320, 240, 320, 240); if (wl_display_add_global (compositor.wayland_display, &wl_shell_interface, &compositor, bind_shell) == NULL) g_error ("Failed to register a global shell object"); if (wl_display_add_socket (compositor.wayland_display, "wayland-0")) g_error ("Failed to create socket"); compositor.triangle = cogl_primitive_new_p2c4 (compositor.cogl_context, COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); compositor.triangle_pipeline = cogl_pipeline_new (compositor.cogl_context); g_timeout_add (16, paint_cb, &compositor); cogl_source = cogl_glib_source_new (compositor.cogl_context, G_PRIORITY_DEFAULT); g_source_attach (cogl_source, NULL); g_main_loop_run (loop); return 0; }
/*static*/ struct wl_event_loop* Globals::eventLoop() { return wl_display_get_event_loop(display()); }
Compositor::Compositor(QWaylandCompositor *qt_compositor) : m_display(new Display) , m_default_input_device(0) , m_pageFlipper(0) , m_current_frame(0) , m_last_queued_buf(-1) , m_qt_compositor(qt_compositor) , m_orientation(Qt::PrimaryOrientation) , m_directRenderSurface(0) , m_directRenderContext(0) , m_directRenderActive(false) #if defined (QT_COMPOSITOR_WAYLAND_GL) , m_graphics_hw_integration(0) #endif , m_outputExtension(0) , m_surfaceExtension(0) , m_subSurfaceExtension(0) , m_touchExtension(0) , m_retainNotify(0) { compositor = this; #if defined (QT_COMPOSITOR_WAYLAND_GL) QWindow *window = qt_compositor->window(); if (window && window->surfaceType() != QWindow::RasterSurface) { QStringList keys = QWaylandGraphicsHardwareIntegrationFactory::keys(); QString targetKey; QByteArray hardwareIntegration = qgetenv("QT_WAYLAND_HARDWARE_INTEGRATION"); if (keys.contains(QString::fromLocal8Bit(hardwareIntegration.constData()))) { targetKey = QString::fromLocal8Bit(hardwareIntegration.constData()); } else if (keys.contains(QString::fromLatin1("wayland-egl"))) { targetKey = QString::fromLatin1("wayland-egl"); } else if (!keys.isEmpty()) { targetKey = keys.first(); } if (!targetKey.isEmpty()) { m_graphics_hw_integration = QWaylandGraphicsHardwareIntegrationFactory::create(targetKey, QStringList()); if (m_graphics_hw_integration) { m_graphics_hw_integration->setCompositor(qt_compositor); } } //BUG: if there is no hw_integration, bad things will probably happen } #endif m_windowManagerIntegration = new WindowManagerServerIntegration(qt_compositor, this); wl_display_add_global(m_display->handle(),&wl_compositor_interface,this,Compositor::bind_func); m_data_device_manager = new DataDeviceManager(this); wl_display_init_shm(m_display->handle()); m_output_global = new OutputGlobal(m_display->handle()); m_shell = new Shell(); wl_display_add_global(m_display->handle(), &wl_shell_interface, m_shell, Shell::bind_func); m_outputExtension = new OutputExtensionGlobal(this); m_surfaceExtension = new SurfaceExtensionGlobal(this); m_qtkeyExtension = new QtKeyExtensionGlobal(this); m_touchExtension = new TouchExtensionGlobal(this); if (wl_display_add_socket(m_display->handle(), qt_compositor->socketName())) { fprintf(stderr, "Fatal: Failed to open server socket\n"); exit(EXIT_FAILURE); } m_loop = wl_display_get_event_loop(m_display->handle()); int fd = wl_event_loop_get_fd(m_loop); QSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, this); connect(sockNot, SIGNAL(activated(int)), this, SLOT(processWaylandEvents())); QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processWaylandEvents())); qRegisterMetaType<SurfaceBuffer*>("SurfaceBuffer*"); //initialize distancefieldglyphcache here }
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); fprintf(stderr, "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) { fprintf(stderr, "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) { fprintf(stderr, "failed to swtich to new vt\n"); return NULL; } } if (tcgetattr(tty->fd, &tty->terminal_attributes) < 0) { fprintf(stderr, "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) fprintf(stderr, "could not put terminal into raw mode: %m\n"); ioctl(tty->fd, KDGKBMODE, &tty->kb_mode); ret = ioctl(tty->fd, KDSKBMODE, K_OFF); if (ret) { fprintf(stderr, "failed to set K_OFF keyboard mode on tty: %m\n"); goto err_attr; } ret = ioctl(tty->fd, KDSETMODE, KD_GRAPHICS); if (ret) { fprintf(stderr, "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) { fprintf(stderr, "failed to take control of vt handling\n"); goto err_kdmode; } loop = wl_display_get_event_loop(compositor->wl_display); 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: ioctl(tty->fd, KDSKBMODE, tty->kb_mode); err_attr: tcsetattr(tty->fd, TCSANOW, &tty->terminal_attributes); err: close(tty->fd); free(tty); return NULL; }
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; }
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; }