aboutsummaryrefslogtreecommitdiffstats
path: root/compositor
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2011-02-14 22:17:41 -0500
committerKristian Høgsberg <krh@bitplanet.net>2011-02-14 22:21:13 -0500
commitfcfb4e30a47a4cd2416dac210521594b489c8bfd (patch)
treee940236740627c99898ad726246226977c9d7af8 /compositor
parentcompositor: Clip repaint to the damage region (diff)
downloadwayland-fcfb4e30a47a4cd2416dac210521594b489c8bfd.tar
wayland-fcfb4e30a47a4cd2416dac210521594b489c8bfd.tar.gz
wayland-fcfb4e30a47a4cd2416dac210521594b489c8bfd.tar.bz2
wayland-fcfb4e30a47a4cd2416dac210521594b489c8bfd.tar.lz
wayland-fcfb4e30a47a4cd2416dac210521594b489c8bfd.tar.xz
wayland-fcfb4e30a47a4cd2416dac210521594b489c8bfd.tar.zst
wayland-fcfb4e30a47a4cd2416dac210521594b489c8bfd.zip
Split into a core repository that only holds the core Wayland libraries
Diffstat (limited to 'compositor')
-rw-r--r--compositor/.gitignore3
-rw-r--r--compositor/70-wayland.rules7
-rw-r--r--compositor/Makefile.am55
-rw-r--r--compositor/compositor-drm.c383
-rw-r--r--compositor/compositor-wayland.c542
-rw-r--r--compositor/compositor-x11.c795
-rw-r--r--compositor/compositor.c1411
-rw-r--r--compositor/compositor.h269
-rw-r--r--compositor/drm.c246
-rw-r--r--compositor/evdev.c239
-rw-r--r--compositor/screenshooter.c88
-rw-r--r--compositor/shell.c676
-rw-r--r--compositor/shm.c174
-rw-r--r--compositor/tty.c160
14 files changed, 0 insertions, 5048 deletions
diff --git a/compositor/.gitignore b/compositor/.gitignore
deleted file mode 100644
index dc926c1..0000000
--- a/compositor/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-compositor
-screenshooter-protocol.c
-screenshooter-server-protocol.h
diff --git a/compositor/70-wayland.rules b/compositor/70-wayland.rules
deleted file mode 100644
index 1b7ca66..0000000
--- a/compositor/70-wayland.rules
+++ /dev/null
@@ -1,7 +0,0 @@
-KERNEL=="event*", ENV{ID_INPUT_KEYBOARD}=="1", ENV{WAYLAND_SEAT}="1"
-KERNEL=="event*", ENV{ID_INPUT_MOUSE}=="1", ENV{WAYLAND_SEAT}="1"
-KERNEL=="event*", ENV{ID_INPUT_TOUCHPAD}=="1", ENV{WAYLAND_SEAT}="1"
-KERNEL=="event*", ENV{ID_INPUT_TOUCHSCREEN}=="1", ENV{WAYLAND_SEAT}="1"
-KERNEL=="event*", ENV{ID_INPUT_TABLET}=="1", ENV{WAYLAND_SEAT}="1"
-KERNEL=="card0", ENV{WAYLAND_SEAT}="1"
-
diff --git a/compositor/Makefile.am b/compositor/Makefile.am
deleted file mode 100644
index d2baa43..0000000
--- a/compositor/Makefile.am
+++ /dev/null
@@ -1,55 +0,0 @@
-noinst_PROGRAMS = compositor
-
-AM_CPPFLAGS = \
- -DDATADIR='"$(datadir)"' \
- -I$(top_builddir)/wayland \
- -I$(top_srcdir)/wayland \
- $(COMPOSITOR_CFLAGS)
-
-AM_CFLAGS = $(GCC_CFLAGS)
-
-compositor_LDADD = \
- $(top_builddir)/wayland/libwayland-server.la \
- $(top_builddir)/wayland/libwayland-client.la \
- $(COMPOSITOR_LIBS)
-
-if ENABLE_DRM_COMPOSITOR
-drm_compositor_sources = compositor-drm.c tty.c evdev.c
-drm_sources = drm.c
-endif
-
-if ENABLE_X11_COMPOSITOR
-x11_compositor_sources = compositor-x11.c
-drm_sources = drm.c
-endif
-
-if ENABLE_WAYLAND_COMPOSITOR
-wayland_compositor_sources = compositor-wayland.c
-drm_sources = drm.c
-endif
-
-compositor_SOURCES = \
- compositor.c \
- compositor.h \
- shell.c \
- screenshooter.c \
- screenshooter-protocol.c \
- screenshooter-server-protocol.h \
- shm.c \
- $(drm_compositor_sources) \
- $(x11_compositor_sources) \
- $(wayland_compositor_sources) \
- $(drm_sources)
-
-udevrulesddir = $(sysconfdir)/udev/rules.d
-
-dist_udevrulesd_DATA = \
- 70-wayland.rules
-
-BUILT_SOURCES = \
- screenshooter-server-protocol.h \
- screenshooter-protocol.c
-
-CLEANFILES = $(BUILT_SOURCES)
-
-include $(top_srcdir)/wayland/scanner.mk
diff --git a/compositor/compositor-drm.c b/compositor/compositor-drm.c
deleted file mode 100644
index 50f353b..0000000
--- a/compositor/compositor-drm.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright © 2008-2010 Kristian Høgsberg
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include "compositor.h"
-
-struct drm_compositor {
- struct wlsc_compositor base;
-
- struct udev *udev;
- struct wl_event_source *drm_source;
-
- struct tty *tty;
-};
-
-struct drm_output {
- struct wlsc_output base;
-
- drmModeModeInfo mode;
- uint32_t crtc_id;
- uint32_t connector_id;
- GLuint rbo[2];
- uint32_t fb_id[2];
- EGLImageKHR image[2];
- uint32_t current;
-};
-
-static void
-drm_compositor_present(struct wlsc_compositor *ec)
-{
- struct drm_compositor *c = (struct drm_compositor *) ec;
- struct drm_output *output;
-
- wl_list_for_each(output, &ec->output_list, base.link) {
- output->current ^= 1;
-
- glFramebufferRenderbuffer(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER,
- output->rbo[output->current]);
- glFlush();
-
- drmModePageFlip(c->base.drm.fd, output->crtc_id,
- output->fb_id[output->current ^ 1],
- DRM_MODE_PAGE_FLIP_EVENT, output);
- }
-}
-
-static void
-page_flip_handler(int fd, unsigned int frame,
- unsigned int sec, unsigned int usec, void *data)
-{
- struct wlsc_output *output = data;
- struct wlsc_compositor *compositor = output->compositor;
- uint32_t msecs;
-
- msecs = sec * 1000 + usec / 1000;
- wlsc_compositor_finish_frame(compositor, msecs);
-}
-
-static void
-on_drm_input(int fd, uint32_t mask, void *data)
-{
- drmEventContext evctx;
-
- memset(&evctx, 0, sizeof evctx);
- evctx.version = DRM_EVENT_CONTEXT_VERSION;
- evctx.page_flip_handler = page_flip_handler;
- drmHandleEvent(fd, &evctx);
-}
-
-static int
-init_egl(struct drm_compositor *ec, struct udev_device *device)
-{
- EGLint major, minor;
- const char *extensions, *filename;
- int fd;
- static const EGLint context_attribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
-
- filename = udev_device_get_devnode(device);
- fd = open(filename, O_RDWR);
- if (fd < 0) {
- /* Probably permissions error */
- fprintf(stderr, "couldn't open %s, skipping\n",
- udev_device_get_devnode(device));
- return -1;
- }
-
- wlsc_drm_init(&ec->base, fd, filename);
-
- ec->base.display = eglGetDRMDisplayMESA(ec->base.drm.fd);
- if (ec->base.display == NULL) {
- fprintf(stderr, "failed to create display\n");
- return -1;
- }
-
- if (!eglInitialize(ec->base.display, &major, &minor)) {
- fprintf(stderr, "failed to initialize display\n");
- return -1;
- }
-
- extensions = eglQueryString(ec->base.display, EGL_EXTENSIONS);
- if (!strstr(extensions, "EGL_KHR_surfaceless_opengl")) {
- fprintf(stderr, "EGL_KHR_surfaceless_opengl not available\n");
- return -1;
- }
-
- if (!eglBindAPI(EGL_OPENGL_ES_API)) {
- fprintf(stderr, "failed to bind api EGL_OPENGL_ES_API\n");
- return -1;
- }
-
- ec->base.context = eglCreateContext(ec->base.display, NULL,
- EGL_NO_CONTEXT, context_attribs);
- if (ec->base.context == NULL) {
- fprintf(stderr, "failed to create context\n");
- return -1;
- }
-
- if (!eglMakeCurrent(ec->base.display, EGL_NO_SURFACE,
- EGL_NO_SURFACE, ec->base.context)) {
- fprintf(stderr, "failed to make context current\n");
- return -1;
- }
-
- return 0;
-}
-
-static drmModeModeInfo builtin_1024x768 = {
- 63500, /* clock */
- 1024, 1072, 1176, 1328, 0,
- 768, 771, 775, 798, 0,
- 59920,
- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- 0,
- "1024x768"
-};
-
-static int
-create_output_for_connector(struct drm_compositor *ec,
- drmModeRes *resources,
- drmModeConnector *connector)
-{
- struct drm_output *output;
- drmModeEncoder *encoder;
- drmModeModeInfo *mode;
- int i, ret;
- EGLint handle, stride, attribs[] = {
- EGL_WIDTH, 0,
- EGL_HEIGHT, 0,
- EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
- EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA,
- EGL_NONE
- };
-
- output = malloc(sizeof *output);
- if (output == NULL)
- return -1;
-
- if (connector->count_modes > 0)
- mode = &connector->modes[0];
- else
- mode = &builtin_1024x768;
-
- encoder = drmModeGetEncoder(ec->base.drm.fd, connector->encoders[0]);
- if (encoder == NULL) {
- fprintf(stderr, "No encoder for connector.\n");
- return -1;
- }
-
- for (i = 0; i < resources->count_crtcs; i++) {
- if (encoder->possible_crtcs & (1 << i))
- break;
- }
- if (i == resources->count_crtcs) {
- fprintf(stderr, "No usable crtc for encoder.\n");
- return -1;
- }
-
- memset(output, 0, sizeof *output);
- wlsc_output_init(&output->base, &ec->base, 0, 0,
- mode->hdisplay, mode->vdisplay);
-
- output->crtc_id = resources->crtcs[i];
- output->connector_id = connector->connector_id;
- output->mode = *mode;
-
- drmModeFreeEncoder(encoder);
-
- glGenRenderbuffers(2, output->rbo);
- for (i = 0; i < 2; i++) {
- glBindRenderbuffer(GL_RENDERBUFFER, output->rbo[i]);
-
- attribs[1] = output->base.width;
- attribs[3] = output->base.height;
- output->image[i] =
- eglCreateDRMImageMESA(ec->base.display, attribs);
- glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
- output->image[i]);
- eglExportDRMImageMESA(ec->base.display, output->image[i],
- NULL, &handle, &stride);
-
- ret = drmModeAddFB(ec->base.drm.fd,
- output->base.width, output->base.height,
- 32, 32, stride, handle, &output->fb_id[i]);
- if (ret) {
- fprintf(stderr, "failed to add fb %d: %m\n", i);
- return -1;
- }
- }
-
- output->current = 0;
- glFramebufferRenderbuffer(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER,
- output->rbo[output->current]);
- ret = drmModeSetCrtc(ec->base.drm.fd, output->crtc_id,
- output->fb_id[output->current ^ 1], 0, 0,
- &output->connector_id, 1, &output->mode);
- if (ret) {
- fprintf(stderr, "failed to set mode: %m\n");
- return -1;
- }
-
- wl_list_insert(ec->base.output_list.prev, &output->base.link);
-
- return 0;
-}
-
-static int
-create_outputs(struct drm_compositor *ec, int option_connector)
-{
- drmModeConnector *connector;
- drmModeRes *resources;
- int i;
-
- resources = drmModeGetResources(ec->base.drm.fd);
- if (!resources) {
- fprintf(stderr, "drmModeGetResources failed\n");
- return -1;
- }
-
- for (i = 0; i < resources->count_connectors; i++) {
- connector = drmModeGetConnector(ec->base.drm.fd, resources->connectors[i]);
- if (connector == NULL)
- continue;
-
- if (connector->connection == DRM_MODE_CONNECTED &&
- (option_connector == 0 ||
- connector->connector_id == option_connector))
- if (create_output_for_connector(ec, resources, connector) < 0)
- return -1;
-
- drmModeFreeConnector(connector);
- }
-
- if (wl_list_empty(&ec->base.output_list)) {
- fprintf(stderr, "No currently active connector found.\n");
- return -1;
- }
-
- drmModeFreeResources(resources);
-
- return 0;
-}
-
-static int
-drm_authenticate(struct wlsc_compositor *c, uint32_t id)
-{
- struct drm_compositor *ec = (struct drm_compositor *) c;
-
- return drmAuthMagic(ec->base.drm.fd, id);
-}
-
-static void
-drm_destroy(struct wlsc_compositor *ec)
-{
- struct drm_compositor *d = (struct drm_compositor *) ec;
-
- tty_destroy(d->tty);
-
- free(d);
-}
-
-struct wlsc_compositor *
-drm_compositor_create(struct wl_display *display, int connector)
-{
- struct drm_compositor *ec;
- struct udev_enumerate *e;
- struct udev_list_entry *entry;
- struct udev_device *device;
- const char *path;
- struct wl_event_loop *loop;
-
- ec = malloc(sizeof *ec);
- if (ec == NULL)
- return NULL;
-
- memset(ec, 0, sizeof *ec);
- ec->udev = udev_new();
- if (ec->udev == NULL) {
- fprintf(stderr, "failed to initialize udev context\n");
- return NULL;
- }
-
- e = udev_enumerate_new(ec->udev);
- udev_enumerate_add_match_subsystem(e, "drm");
- udev_enumerate_add_match_property(e, "WAYLAND_SEAT", "1");
- udev_enumerate_scan_devices(e);
- device = NULL;
- udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
- path = udev_list_entry_get_name(entry);
- device = udev_device_new_from_syspath(ec->udev, path);
- break;
- }
- udev_enumerate_unref(e);
-
- if (device == NULL) {
- fprintf(stderr, "no drm device found\n");
- return NULL;
- }
-
- ec->base.wl_display = display;
- if (init_egl(ec, device) < 0) {
- fprintf(stderr, "failed to initialize egl\n");
- return NULL;
- }
-
- ec->base.destroy = drm_destroy;
- ec->base.authenticate = drm_authenticate;
- ec->base.present = drm_compositor_present;
- ec->base.create_buffer = wlsc_drm_buffer_create;
- ec->base.focus = 1;
-
- /* Can't init base class until we have a current egl context */
- if (wlsc_compositor_init(&ec->base, display) < 0)
- return NULL;
-
- if (create_outputs(ec, connector) < 0) {
- fprintf(stderr, "failed to create output for %s\n", path);
- return NULL;
- }
-
- evdev_input_add_devices(&ec->base, ec->udev);
-
- loop = wl_display_get_event_loop(ec->base.wl_display);
- ec->drm_source =
- wl_event_loop_add_fd(loop, ec->base.drm.fd,
- WL_EVENT_READABLE, on_drm_input, ec);
- ec->tty = tty_create(&ec->base);
-
- return &ec->base;
-}
diff --git a/compositor/compositor-wayland.c b/compositor/compositor-wayland.c
deleted file mode 100644
index 11320d8..0000000
--- a/compositor/compositor-wayland.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright © 2010 Benjamin Franzke
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stddef.h>
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "wayland-client.h"
-
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include "compositor.h"
-
-struct wayland_compositor {
- struct wlsc_compositor base;
-
- struct {
- struct wl_display *display;
- struct wl_compositor *compositor;
- struct wl_shell *shell;
- struct wl_drm *drm;
- struct wl_output *output;
-
- struct {
- int32_t x, y, width, height;
- } screen_allocation;
-
- char *device_name;
- int authenticated;
-
- struct wl_event_source *wl_source;
- uint32_t event_mask;
- } parent;
-
- struct wl_list input_list;
-};
-
-struct wayland_output {
- struct wlsc_output base;
-
- struct {
- struct wl_surface *surface;
- struct wl_buffer *buffer[2];
- } parent;
- EGLImageKHR image[2];
- GLuint rbo[2];
- uint32_t fb_id[2];
- uint32_t current;
-};
-
-struct wayland_input {
- struct wayland_compositor *compositor;
- struct wl_input_device *input_device;
- struct wl_list link;
-};
-
-static int
-wayland_input_create(struct wayland_compositor *c)
-{
- struct wlsc_input_device *input;
-
- input = malloc(sizeof *input);
- if (input == NULL)
- return -1;
-
- memset(input, 0, sizeof *input);
- wlsc_input_device_init(input, &c->base);
-
- c->base.input_device = &input->input_device;
-
- return 0;
-}
-
-static int
-wayland_compositor_init_egl(struct wayland_compositor *c)
-{
- EGLint major, minor;
- const char *extensions;
- drm_magic_t magic;
- int fd;
- static const EGLint context_attribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
-
- fd = open(c->parent.device_name, O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "drm open failed: %m\n");
- return -1;
- }
-
- wlsc_drm_init(&c->base, fd, c->parent.device_name);
-
- if (drmGetMagic(fd, &magic)) {
- fprintf(stderr, "DRI2: failed to get drm magic");
- return -1;
- }
-
- wl_drm_authenticate(c->parent.drm, magic);
- wl_display_iterate(c->parent.display, WL_DISPLAY_WRITABLE);
- while (!c->parent.authenticated)
- wl_display_iterate(c->parent.display, WL_DISPLAY_READABLE);
-
- c->base.display = eglGetDRMDisplayMESA(fd);
- if (c->base.display == NULL) {
- fprintf(stderr, "failed to create display\n");
- return -1;
- }
-
- if (!eglInitialize(c->base.display, &major, &minor)) {
- fprintf(stderr, "failed to initialize display\n");
- return -1;
- }
-
- extensions = eglQueryString(c->base.display, EGL_EXTENSIONS);
- if (!strstr(extensions, "EGL_KHR_surfaceless_opengl")) {
- fprintf(stderr, "EGL_KHR_surfaceless_opengl not available\n");
- return -1;
- }
-
- if (!eglBindAPI(EGL_OPENGL_ES_API)) {
- fprintf(stderr, "failed to bind EGL_OPENGL_ES_API\n");
- return -1;
- }
-
- c->base.context = eglCreateContext(c->base.display, NULL,
- EGL_NO_CONTEXT, context_attribs);
- if (c->base.context == NULL) {
- fprintf(stderr, "failed to create context\n");
- return -1;
- }
-
- if (!eglMakeCurrent(c->base.display, EGL_NO_SURFACE,
- EGL_NO_SURFACE, c->base.context)) {
- fprintf(stderr, "failed to make context current\n");
- return -1;
- }
-
- return 0;
-}
-
-static void
-frame_callback(void *data, uint32_t time)
-{
- struct wayland_compositor *c = (struct wayland_compositor *) data;
-
- wlsc_compositor_finish_frame(&c->base, time);
-}
-
-static void
-wayland_compositor_present(struct wlsc_compositor *base)
-{
- struct wayland_compositor *c = (struct wayland_compositor *) base;
- struct wayland_output *output;
-
- glFlush();
-
- wl_list_for_each(output, &base->output_list, base.link) {
- output->current ^= 1;
-
- glFramebufferRenderbuffer(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER,
- output->rbo[output->current]);
-
- wl_surface_attach(output->parent.surface,
- output->parent.buffer[output->current ^ 1],
- 0, 0);
- wl_surface_damage(output->parent.surface, 0, 0,
- output->base.width, output->base.height);
- }
-
- wl_display_frame_callback(c->parent.display, frame_callback, c);
-}
-
-static int
-wayland_authenticate(struct wlsc_compositor *ec, uint32_t id)
-{
- struct wayland_compositor *c = (struct wayland_compositor *) ec;
-
- wl_drm_authenticate(c->parent.drm, id);
- /* FIXME: recv drm_authenticated event from parent? */
- wl_display_iterate(c->parent.display, WL_DISPLAY_WRITABLE);
-
- return 0;
-}
-
-static int
-wayland_compositor_create_output(struct wayland_compositor *c,
- int width, int height)
-{
- struct wayland_output *output;
- struct wl_visual *visual;
- int i;
- EGLint name, stride, attribs[] = {
- EGL_WIDTH, 0,
- EGL_HEIGHT, 0,
- EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
- EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA,
- EGL_NONE
- };
-
- output = malloc(sizeof *output);
- if (output == NULL)
- return -1;
- memset(output, 0, sizeof *output);
-
- wlsc_output_init(&output->base, &c->base, 0, 0, width, height);
- output->parent.surface =
- wl_compositor_create_surface(c->parent.compositor);
- wl_surface_set_user_data(output->parent.surface, output);
-
- glGenRenderbuffers(2, output->rbo);
- visual = wl_display_get_premultiplied_argb_visual(c->parent.display);
- for (i = 0; i < 2; i++) {
- glBindRenderbuffer(GL_RENDERBUFFER, output->rbo[i]);
-
- attribs[1] = width;
- attribs[3] = height;
- output->image[i] =
- eglCreateDRMImageMESA(c->base.display, attribs);
- glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
- output->image[i]);
- eglExportDRMImageMESA(c->base.display, output->image[i],
- &name, NULL, &stride);
- output->parent.buffer[i] =
- wl_drm_create_buffer(c->parent.drm, name,
- width, height,
- stride, visual);
- }
-
- output->current = 0;
- glFramebufferRenderbuffer(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER,
- output->rbo[output->current]);
-
- wl_surface_attach(output->parent.surface,
- output->parent.buffer[output->current], 0, 0);
- wl_surface_map_toplevel(output->parent.surface);
-
- glClearColor(0, 0, 0, 0.5);
-
- wl_list_insert(c->base.output_list.prev, &output->base.link);
-
- return 0;
-}
-
-/* Events received from the wayland-server this compositor is client of: */
-
-/* parent output interface */
-static void
-display_handle_geometry(void *data,
- struct wl_output *output,
- int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- struct wayland_compositor *c = data;
-
- c->parent.screen_allocation.x = x;
- c->parent.screen_allocation.y = y;
- c->parent.screen_allocation.width = width;
- c->parent.screen_allocation.height = height;
-}
-
-static const struct wl_output_listener output_listener = {
- display_handle_geometry,
-};
-
-/* parent shell interface */
-static void
-handle_configure(void *data, struct wl_shell *shell,
- uint32_t time, uint32_t edges,
- struct wl_surface *surface, int32_t width, int32_t height)
-{
-#if 0
- struct output *output = wl_surface_get_user_data(surface);
-
- /* FIXME: add resize? */
-#endif
-}
-
-static const struct wl_shell_listener shell_listener = {
- handle_configure,
-};
-
-/* parent drm interface */
-static void
-drm_handle_device(void *data, struct wl_drm *drm, const char *device)
-{
- struct wayland_compositor *c = data;
-
- c->parent.device_name = strdup(device);
-}
-
-static void drm_handle_authenticated(void *data, struct wl_drm *drm)
-{
- struct wayland_compositor *c = data;
-
- c->parent.authenticated = 1;
-}
-
-static const struct wl_drm_listener drm_listener = {
- drm_handle_device,
- drm_handle_authenticated
-};
-
-/* parent input interface */
-static void
-input_handle_motion(void *data, struct wl_input_device *input_device,
- uint32_t time,
- int32_t x, int32_t y, int32_t sx, int32_t sy)
-{
- struct wayland_input *input = data;
- struct wayland_compositor *c = input->compositor;
-
- notify_motion(c->base.input_device, time, sx, sy);
-}
-
-static void
-input_handle_button(void *data,
- struct wl_input_device *input_device,
- uint32_t time, uint32_t button, uint32_t state)
-{
- struct wayland_input *input = data;
- struct wayland_compositor *c = input->compositor;
-
- notify_button(c->base.input_device, time, button, state);
-}
-
-static void
-input_handle_key(void *data, struct wl_input_device *input_device,
- uint32_t time, uint32_t key, uint32_t state)
-{
- struct wayland_input *input = data;
- struct wayland_compositor *c = input->compositor;
-
- notify_key(c->base.input_device, time, key, state);
-}
-
-static void
-input_handle_pointer_focus(void *data,
- struct wl_input_device *input_device,
- uint32_t time, struct wl_surface *surface,
- int32_t x, int32_t y, int32_t sx, int32_t sy)
-{
- struct wayland_input *input = data;
- struct wayland_output *output;
- struct wayland_compositor *c = input->compositor;
-
- if (surface) {
- output = wl_surface_get_user_data(surface);
- notify_pointer_focus(c->base.input_device,
- time, &output->base, sx, sy);
- } else {
- notify_pointer_focus(c->base.input_device, time, NULL, 0, 0);
- }
-}
-
-static void
-input_handle_keyboard_focus(void *data,
- struct wl_input_device *input_device,
- uint32_t time,
- struct wl_surface *surface,
- struct wl_array *keys)
-{
- struct wayland_input *input = data;
- struct wayland_compositor *c = input->compositor;
- struct wayland_output *output;
-
- if (surface) {
- output = wl_surface_get_user_data(surface);
- notify_keyboard_focus(c->base.input_device,
- time, &output->base, keys);
- } else {
- notify_keyboard_focus(c->base.input_device, time, NULL, NULL);
- }
-}
-
-static const struct wl_input_device_listener input_device_listener = {
- input_handle_motion,
- input_handle_button,
- input_handle_key,
- input_handle_pointer_focus,
- input_handle_keyboard_focus,
-};
-
-static void
-display_add_input(struct wayland_compositor *c, uint32_t id)
-{
- struct wayland_input *input;
-
- input = malloc(sizeof *input);
- if (input == NULL)
- return;
-
- memset(input, 0, sizeof *input);
-
- input->compositor = c;
- input->input_device = wl_input_device_create(c->parent.display, id);
- wl_list_insert(c->input_list.prev, &input->link);
-
- wl_input_device_add_listener(input->input_device,
- &input_device_listener, input);
- wl_input_device_set_user_data(input->input_device, input);
-}
-
-static void
-display_handle_global(struct wl_display *display, uint32_t id,
- const char *interface, uint32_t version, void *data)
-{
- struct wayland_compositor *c = data;
-
- if (strcmp(interface, "compositor") == 0) {
- c->parent.compositor = wl_compositor_create(display, id);
- } else if (strcmp(interface, "output") == 0) {
- c->parent.output = wl_output_create(display, id);
- wl_output_add_listener(c->parent.output, &output_listener, c);
- } else if (strcmp(interface, "input_device") == 0) {
- display_add_input(c, id);
- } else if (strcmp(interface, "shell") == 0) {
- c->parent.shell = wl_shell_create(display, id);
- wl_shell_add_listener(c->parent.shell, &shell_listener, c);
- } else if (strcmp(interface, "drm") == 0) {
- c->parent.drm = wl_drm_create(display, id);
- wl_drm_add_listener(c->parent.drm, &drm_listener, c);
- }
-}
-
-static int
-update_event_mask(uint32_t mask, void *data)
-{
- struct wayland_compositor *c = data;
-
- c->parent.event_mask = mask;
- if (c->parent.wl_source)
- wl_event_source_fd_update(c->parent.wl_source, mask);
-
- return 0;
-}
-
-static void
-wayland_compositor_handle_event(int fd, uint32_t mask, void *data)
-{
- struct wayland_compositor *c = data;
-
- if (mask & WL_EVENT_READABLE)
- wl_display_iterate(c->parent.display, WL_DISPLAY_READABLE);
- if (mask & WL_EVENT_WRITEABLE)
- wl_display_iterate(c->parent.display, WL_DISPLAY_WRITABLE);
-}
-
-static void
-wayland_destroy(struct wlsc_compositor *ec)
-{
- free(ec);
-}
-
-struct wlsc_compositor *
-wayland_compositor_create(struct wl_display *display, int width, int height)
-{
- 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);
-
- c->parent.display = wl_display_connect(NULL);
-
- if (c->parent.display == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return NULL;
- }
-
- wl_list_init(&c->input_list);
- wl_display_add_global_listener(c->parent.display,
- display_handle_global, c);
-
- wl_display_iterate(c->parent.display, WL_DISPLAY_READABLE);
-
- c->base.wl_display = display;
- if (wayland_compositor_init_egl(c) < 0)
- return NULL;
-
- c->base.destroy = wayland_destroy;
- c->base.authenticate = wayland_authenticate;
- c->base.present = wayland_compositor_present;
- c->base.create_buffer = wlsc_drm_buffer_create;
-
- /* Can't init base class until we have a current egl context */
- if (wlsc_compositor_init(&c->base, display) < 0)
- return NULL;
-
- if (wayland_compositor_create_output(c, width, height) < 0)
- return NULL;
-
- if (wayland_input_create(c) < 0)
- return NULL;
-
- loop = wl_display_get_event_loop(c->base.wl_display);
-
- fd = wl_display_get_fd(c->parent.display, update_event_mask, c);
- c->parent.wl_source =
- wl_event_loop_add_fd(loop, fd, c->parent.event_mask,
- wayland_compositor_handle_event, c);
- if (c->parent.wl_source == NULL)
- return NULL;
-
- return &c->base;
-}
diff --git a/compositor/compositor-x11.c b/compositor/compositor-x11.c
deleted file mode 100644
index 4365c0a..0000000
--- a/compositor/compositor-x11.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * Copyright © 2008-2010 Kristian Høgsberg
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <linux/input.h>
-
-#include <xcb/xcb.h>
-#include <xcb/dri2.h>
-#include <xcb/xfixes.h>
-
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include "compositor.h"
-
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-
-struct x11_compositor {
- struct wlsc_compositor base;
-
- xcb_connection_t *conn;
- xcb_screen_t *screen;
- xcb_cursor_t null_cursor;
- int dri2_major;
- int dri2_minor;
- struct wl_array keys;
- struct wl_event_source *xcb_source;
- struct {
- xcb_atom_t wm_protocols;
- xcb_atom_t wm_normal_hints;
- xcb_atom_t wm_size_hints;
- xcb_atom_t wm_delete_window;
- xcb_atom_t wm_class;
- xcb_atom_t net_wm_name;
- xcb_atom_t net_wm_icon;
- xcb_atom_t string;
- xcb_atom_t utf8_string;
- xcb_atom_t cardinal;
- } atom;
-};
-
-struct x11_output {
- struct wlsc_output base;
-
- xcb_xfixes_region_t region;
- xcb_window_t window;
- GLuint rbo;
- EGLImageKHR image;
- xcb_rectangle_t damage[16];
- int damage_count;
-};
-
-struct x11_input {
- struct wlsc_input_device base;
-};
-
-
-static int
-x11_input_create(struct x11_compositor *c)
-{
- struct x11_input *input;
-
- input = malloc(sizeof *input);
- if (input == NULL)
- return -1;
-
- memset(input, 0, sizeof *input);
- wlsc_input_device_init(&input->base, &c->base);
-
- c->base.input_device = &input->base.input_device;
-
- return 0;
-}
-
-
-static int
-dri2_connect(struct x11_compositor *c)
-{
- xcb_xfixes_query_version_reply_t *xfixes_query;
- xcb_xfixes_query_version_cookie_t xfixes_query_cookie;
- xcb_dri2_query_version_reply_t *dri2_query;
- xcb_dri2_query_version_cookie_t dri2_query_cookie;
- xcb_dri2_connect_reply_t *connect;
- xcb_dri2_connect_cookie_t connect_cookie;
- xcb_generic_error_t *error;
- char path[256];
- int fd;
-
- xcb_prefetch_extension_data (c->conn, &xcb_xfixes_id);
- xcb_prefetch_extension_data (c->conn, &xcb_dri2_id);
-
- xfixes_query_cookie =
- xcb_xfixes_query_version(c->conn,
- XCB_XFIXES_MAJOR_VERSION,
- XCB_XFIXES_MINOR_VERSION);
-
- dri2_query_cookie =
- xcb_dri2_query_version (c->conn,
- XCB_DRI2_MAJOR_VERSION,
- XCB_DRI2_MINOR_VERSION);
-
- connect_cookie = xcb_dri2_connect_unchecked (c->conn,
- c->screen->root,
- XCB_DRI2_DRIVER_TYPE_DRI);
-
- xfixes_query =
- xcb_xfixes_query_version_reply (c->conn,
- xfixes_query_cookie, &error);
- if (xfixes_query == NULL ||
- error != NULL || xfixes_query->major_version < 2) {
- free(error);
- return -1;
- }
- free(xfixes_query);
-
- dri2_query =
- xcb_dri2_query_version_reply (c->conn,
- dri2_query_cookie, &error);
- if (dri2_query == NULL || error != NULL) {
- fprintf(stderr, "DRI2: failed to query version\n");
- free(error);
- return EGL_FALSE;
- }
- c->dri2_major = dri2_query->major_version;
- c->dri2_minor = dri2_query->minor_version;
- free(dri2_query);
-
- connect = xcb_dri2_connect_reply (c->conn,
- connect_cookie, NULL);
- if (connect == NULL ||
- connect->driver_name_length + connect->device_name_length == 0) {
- fprintf(stderr, "DRI2: failed to connect, DRI2 version: %u.%u\n",
- c->dri2_major, c->dri2_minor);
- return -1;
- }
-
-#ifdef XCB_DRI2_CONNECT_DEVICE_NAME_BROKEN
- {
- char *driver_name, *device_name;
-
- driver_name = xcb_dri2_connect_driver_name (connect);
- device_name = driver_name +
- ((connect->driver_name_length + 3) & ~3);
- snprintf(path, sizeof path, "%.*s",
- xcb_dri2_connect_device_name_length (connect),
- device_name);
- }
-#else
- snprintf(path, sizeof path, "%.*s",
- xcb_dri2_connect_device_name_length (connect),
- xcb_dri2_connect_device_name (connect));
-#endif
- free(connect);
-
- fd = open(path, O_RDWR);
- if (fd < 0) {
- fprintf(stderr,
- "DRI2: could not open %s (%s)\n", path, strerror(errno));
- return -1;
- }
-
- return wlsc_drm_init(&c->base, fd, path);
-}
-
-static int
-dri2_authenticate(struct x11_compositor *c, uint32_t magic)
-{
- xcb_dri2_authenticate_reply_t *authenticate;
- xcb_dri2_authenticate_cookie_t authenticate_cookie;
-
- authenticate_cookie =
- xcb_dri2_authenticate_unchecked(c->conn,
- c->screen->root, magic);
- authenticate =
- xcb_dri2_authenticate_reply(c->conn,
- authenticate_cookie, NULL);
- if (authenticate == NULL || !authenticate->authenticated) {
- fprintf(stderr, "DRI2: failed to authenticate\n");
- free(authenticate);
- return -1;
- }
-
- free(authenticate);
-
- return 0;
-}
-
-static int
-x11_compositor_init_egl(struct x11_compositor *c)
-{
- EGLint major, minor;
- const char *extensions;
- drm_magic_t magic;
- static const EGLint context_attribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
-
- if (dri2_connect(c) < 0)
- return -1;
-
- if (drmGetMagic(c->base.drm.fd, &magic)) {
- fprintf(stderr, "DRI2: failed to get drm magic\n");
- return -1;
- }
-
- if (dri2_authenticate(c, magic) < 0)
- return -1;
-
- c->base.display = eglGetDRMDisplayMESA(c->base.drm.fd);
- if (c->base.display == NULL) {
- fprintf(stderr, "failed to create display\n");
- return -1;
- }
-
- if (!eglInitialize(c->base.display, &major, &minor)) {
- fprintf(stderr, "failed to initialize display\n");
- return -1;
- }
-
- extensions = eglQueryString(c->base.display, EGL_EXTENSIONS);
- if (!strstr(extensions, "EGL_KHR_surfaceless_opengl")) {
- fprintf(stderr, "EGL_KHR_surfaceless_opengl not available\n");
- return -1;
- }
-
- if (!eglBindAPI(EGL_OPENGL_ES_API)) {
- fprintf(stderr, "failed to bind EGL_OPENGL_ES_API\n");
- return -1;
- }
-
- c->base.context = eglCreateContext(c->base.display, NULL,
- EGL_NO_CONTEXT, context_attribs);
- if (c->base.context == NULL) {
- fprintf(stderr, "failed to create context\n");
- return -1;
- }
-
- if (!eglMakeCurrent(c->base.display, EGL_NO_SURFACE,
- EGL_NO_SURFACE, c->base.context)) {
- fprintf(stderr, "failed to make context current\n");
- return -1;
- }
-
- return 0;
-}
-
-static void
-x11_compositor_present(struct wlsc_compositor *base)
-{
- struct x11_compositor *c = (struct x11_compositor *) base;
- struct x11_output *output;
- xcb_dri2_copy_region_cookie_t cookie;
- struct timeval tv;
- uint32_t msec;
-
- glFlush();
-
- wl_list_for_each(output, &c->base.output_list, base.link) {
- cookie = xcb_dri2_copy_region_unchecked(c->conn,
- output->window,
- output->region,
- XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
- XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT);
- free(xcb_dri2_copy_region_reply(c->conn, cookie, NULL));
- }
-
- gettimeofday(&tv, NULL);
- msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
- wlsc_compositor_finish_frame(&c->base, msec);
-}
-
-static void
-x11_output_set_wm_protocols(struct x11_output *output)
-{
- xcb_atom_t list[1];
- struct x11_compositor *c =
- (struct x11_compositor *) output->base.compositor;
-
- list[0] = c->atom.wm_delete_window;
- xcb_change_property (c->conn,
- XCB_PROP_MODE_REPLACE,
- output->window,
- c->atom.wm_protocols,
- XCB_ATOM_ATOM,
- 32,
- ARRAY_SIZE(list),
- list);
-}
-
-struct wm_normal_hints {
- uint32_t flags;
- uint32_t pad[4];
- int32_t min_width, min_height;
- int32_t max_width, max_height;
- int32_t width_inc, height_inc;
- int32_t min_aspect_x, min_aspect_y;
- int32_t max_aspect_x, max_aspect_y;
- int32_t base_width, base_height;
- int32_t win_gravity;
-};
-
-#define WM_NORMAL_HINTS_MIN_SIZE 16
-#define WM_NORMAL_HINTS_MAX_SIZE 32
-
-static void
-x11_output_set_icon(struct x11_compositor *c, struct x11_output *output,
- const char *filename, int width, int height)
-{
- uint32_t *icon, *pixels;
-
- pixels = wlsc_load_image(filename, width, height);
- if (!pixels)
- return;
- icon = malloc(width * height * 4 + 8);
- if (!icon) {
- free(pixels);
- return;
- }
-
- icon[0] = width;
- icon[1] = height;
- memcpy(icon + 2, pixels, width * height * 4);
- xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
- c->atom.net_wm_icon, c->atom.cardinal, 32,
- width * height + 2, icon);
- free(icon);
- free(pixels);
-}
-
-static int
-x11_compositor_create_output(struct x11_compositor *c, int width, int height)
-{
- static const char name[] = "Wayland Compositor";
- static const char class[] = "wayland-1\0Wayland Compositor";
- struct x11_output *output;
- xcb_dri2_dri2_buffer_t *buffers;
- xcb_dri2_get_buffers_reply_t *reply;
- xcb_dri2_get_buffers_cookie_t cookie;
- xcb_screen_iterator_t iter;
- xcb_rectangle_t rectangle;
- struct wm_normal_hints normal_hints;
- unsigned int attachments[] =
- { XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT};
- uint32_t mask = XCB_CW_EVENT_MASK | XCB_CW_CURSOR;
- uint32_t values[2] = {
- XCB_EVENT_MASK_KEY_PRESS |
- XCB_EVENT_MASK_KEY_RELEASE |
- XCB_EVENT_MASK_BUTTON_PRESS |
- XCB_EVENT_MASK_BUTTON_RELEASE |
- XCB_EVENT_MASK_POINTER_MOTION |
- XCB_EVENT_MASK_EXPOSURE |
- XCB_EVENT_MASK_STRUCTURE_NOTIFY |
- XCB_EVENT_MASK_ENTER_WINDOW |
- XCB_EVENT_MASK_LEAVE_WINDOW |
- XCB_EVENT_MASK_KEYMAP_STATE |
- XCB_EVENT_MASK_FOCUS_CHANGE,
- 0
- };
-
- EGLint attribs[] = {
- EGL_WIDTH, 0,
- EGL_HEIGHT, 0,
- EGL_DRM_BUFFER_STRIDE_MESA, 0,
- EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
- EGL_NONE
- };
-
- output = malloc(sizeof *output);
- if (output == NULL)
- return -1;
-
- memset(output, 0, sizeof *output);
- wlsc_output_init(&output->base, &c->base, 0, 0, width, height);
-
- values[1] = c->null_cursor;
- output->window = xcb_generate_id(c->conn);
- iter = xcb_setup_roots_iterator(xcb_get_setup(c->conn));
- xcb_create_window(c->conn,
- XCB_COPY_FROM_PARENT,
- output->window,
- iter.data->root,
- 0, 0,
- width, height,
- 0,
- XCB_WINDOW_CLASS_INPUT_OUTPUT,
- iter.data->root_visual,
- mask, values);
-
- /* Don't resize me. */
- memset(&normal_hints, 0, sizeof normal_hints);
- normal_hints.flags =
- WM_NORMAL_HINTS_MAX_SIZE | WM_NORMAL_HINTS_MIN_SIZE;
- normal_hints.min_width = width;
- normal_hints.min_height = height;
- normal_hints.max_width = width;
- normal_hints.max_height = height;
- xcb_change_property (c->conn, XCB_PROP_MODE_REPLACE, output->window,
- c->atom.wm_normal_hints,
- c->atom.wm_size_hints, 32,
- sizeof normal_hints / 4,
- (uint8_t *) &normal_hints);
-
- /* Set window name. Don't bother with non-EWMH WMs. */
- xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
- c->atom.net_wm_name, c->atom.utf8_string, 8,
- strlen(name), name);
- xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
- c->atom.wm_class, c->atom.string, 8,
- sizeof class, class);
-
- x11_output_set_icon(c, output,
- DATADIR "/wayland/wayland.png", 128, 128);
-
- xcb_map_window(c->conn, output->window);
-
- rectangle.x = 0;
- rectangle.y = 0;
- rectangle.width = width;
- rectangle.height = height;
- output->region = xcb_generate_id(c->conn);
- xcb_xfixes_create_region(c->conn, output->region, 1, &rectangle);
-
- xcb_dri2_create_drawable (c->conn, output->window);
-
- x11_output_set_wm_protocols(output);
-
- cookie = xcb_dri2_get_buffers_unchecked (c->conn,
- output->window,
- 1, 1, attachments);
- reply = xcb_dri2_get_buffers_reply (c->conn, cookie, NULL);
- if (reply == NULL)
- return -1;
- buffers = xcb_dri2_get_buffers_buffers (reply);
- if (buffers == NULL)
- return -1;
-
- if (reply->count != 1) {
- fprintf(stderr,
- "got wrong number of buffers (%d)\n", reply->count);
- return -1;
- }
-
- attribs[1] = reply->width;
- attribs[3] = reply->height;
- attribs[5] = buffers[0].pitch / 4;
- output->image =
- eglCreateImageKHR(c->base.display,
- EGL_NO_CONTEXT,
- EGL_DRM_BUFFER_MESA,
- (EGLClientBuffer) buffers[0].name,
- attribs);
- free(reply);
-
- glGenRenderbuffers(1, &output->rbo);
- glBindRenderbuffer(GL_RENDERBUFFER, output->rbo);
-
- glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
- output->image);
-
- glFramebufferRenderbuffer(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER,
- output->rbo);
-
- wl_list_insert(c->base.output_list.prev, &output->base.link);
-
- return 0;
-}
-
-static void
-idle_repaint(void *data)
-{
- struct x11_output *output = data;
- struct x11_compositor *c =
- (struct x11_compositor *) output->base.compositor;
- xcb_xfixes_region_t region;
- xcb_dri2_copy_region_cookie_t cookie;
-
- if (output->damage_count <= ARRAY_SIZE(output->damage)) {
- region = xcb_generate_id(c->conn);
- xcb_xfixes_create_region(c->conn, region,
- output->damage_count, output->damage);
- } else {
- region = output->region;
- }
-
- cookie = xcb_dri2_copy_region_unchecked(c->conn,
- output->window,
- region,
- XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
- XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT);
-
- if (region != output->region)
- xcb_xfixes_destroy_region(c->conn, region);
-
- free(xcb_dri2_copy_region_reply(c->conn, cookie, NULL));
- output->damage_count = 0;
-}
-
-static struct x11_output *
-x11_compositor_find_output(struct x11_compositor *c, xcb_window_t window)
-{
- struct x11_output *output;
-
- wl_list_for_each(output, &c->base.output_list, base.link) {
- if (output->window == window)
- return output;
- }
-
- return NULL;
-}
-
-static void
-x11_compositor_handle_event(int fd, uint32_t mask, void *data)
-{
- struct x11_compositor *c = data;
- struct x11_output *output;
- xcb_generic_event_t *event;
- struct wl_event_loop *loop;
- xcb_client_message_event_t *client_message;
- xcb_motion_notify_event_t *motion_notify;
- xcb_enter_notify_event_t *enter_notify;
- xcb_key_press_event_t *key_press;
- xcb_button_press_event_t *button_press;
- xcb_keymap_notify_event_t *keymap_notify;
- xcb_focus_in_event_t *focus_in;
- xcb_expose_event_t *expose;
- xcb_rectangle_t *r;
- xcb_atom_t atom;
- uint32_t *k;
- int i, set;
-
- loop = wl_display_get_event_loop(c->base.wl_display);
- while (event = xcb_poll_for_event (c->conn), event != NULL) {
- switch (event->response_type & ~0x80) {
-
- case XCB_KEY_PRESS:
- key_press = (xcb_key_press_event_t *) event;
- notify_key(c->base.input_device,
- key_press->time, key_press->detail - 8, 1);
- break;
- case XCB_KEY_RELEASE:
- key_press = (xcb_key_press_event_t *) event;
- notify_key(c->base.input_device,
- key_press->time, key_press->detail - 8, 0);
- break;
- case XCB_BUTTON_PRESS:
- button_press = (xcb_button_press_event_t *) event;
- notify_button(c->base.input_device,
- button_press->time,
- button_press->detail + BTN_LEFT - 1, 1);
- break;
- case XCB_BUTTON_RELEASE:
- button_press = (xcb_button_press_event_t *) event;
- notify_button(c->base.input_device,
- button_press->time,
- button_press->detail + BTN_LEFT - 1, 0);
- break;
-
- case XCB_MOTION_NOTIFY:
- motion_notify = (xcb_motion_notify_event_t *) event;
- notify_motion(c->base.input_device,
- motion_notify->time,
- motion_notify->event_x,
- motion_notify->event_y);
- break;
-
- case XCB_EXPOSE:
- expose = (xcb_expose_event_t *) event;
- output = x11_compositor_find_output(c, expose->window);
- if (output->damage_count == 0)
- wl_event_loop_add_idle(loop,
- idle_repaint, output);
-
- r = &output->damage[output->damage_count++];
- if (output->damage_count > 16)
- break;
- r->x = expose->x;
- r->y = expose->y;
- r->width = expose->width;
- r->height = expose->height;
- break;
-
- case XCB_ENTER_NOTIFY:
- enter_notify = (xcb_enter_notify_event_t *) event;
- if (enter_notify->state >= Button1Mask)
- break;
- output = x11_compositor_find_output(c, enter_notify->event);
- notify_pointer_focus(c->base.input_device,
- enter_notify->time,
- &output->base,
- enter_notify->event_x,
- enter_notify->event_y);
- break;
-
- case XCB_LEAVE_NOTIFY:
- enter_notify = (xcb_enter_notify_event_t *) event;
- if (enter_notify->state >= Button1Mask)
- break;
- notify_pointer_focus(c->base.input_device,
- enter_notify->time,
- NULL,
- enter_notify->event_x,
- enter_notify->event_y);
- break;
-
- case XCB_CLIENT_MESSAGE:
- client_message = (xcb_client_message_event_t *) event;
- atom = client_message->data.data32[0];
- if (atom == c->atom.wm_delete_window)
- wl_display_terminate(c->base.wl_display);
- break;
-
- case XCB_FOCUS_IN:
- focus_in = (xcb_focus_in_event_t *) event;
- if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED)
- break;
-
- output = x11_compositor_find_output(c, focus_in->event);
- notify_keyboard_focus(c->base.input_device,
- get_time(),
- &output->base, &c->keys);
- break;
-
- case XCB_FOCUS_OUT:
- focus_in = (xcb_focus_in_event_t *) event;
- if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED)
- break;
- notify_keyboard_focus(c->base.input_device,
- get_time(), NULL, NULL);
- break;
-
- case XCB_KEYMAP_NOTIFY:
- keymap_notify = (xcb_keymap_notify_event_t *) event;
- c->keys.size = 0;
- for (i = 0; i < ARRAY_LENGTH(keymap_notify->keys) * 8; i++) {
- set = keymap_notify->keys[i >> 3] &
- (1 << (i & 7));
- if (set) {
- k = wl_array_add(&c->keys, sizeof *k);
- *k = i;
- }
- }
- break;
- default:
- break;
- }
-
- free (event);
- }
-}
-
-#define F(field) offsetof(struct x11_compositor, field)
-
-static void
-x11_compositor_get_resources(struct x11_compositor *c)
-{
- static const struct { const char *name; int offset; } atoms[] = {
- { "WM_PROTOCOLS", F(atom.wm_protocols) },
- { "WM_NORMAL_HINTS", F(atom.wm_normal_hints) },
- { "WM_SIZE_HINTS", F(atom.wm_size_hints) },
- { "WM_DELETE_WINDOW", F(atom.wm_delete_window) },
- { "WM_CLASS", F(atom.wm_class) },
- { "_NET_WM_NAME", F(atom.net_wm_name) },
- { "_NET_WM_ICON", F(atom.net_wm_icon) },
- { "STRING", F(atom.string) },
- { "UTF8_STRING", F(atom.utf8_string) },
- { "CARDINAL", F(atom.cardinal) },
- };
-
- xcb_intern_atom_cookie_t cookies[ARRAY_SIZE(atoms)];
- xcb_intern_atom_reply_t *reply;
- xcb_pixmap_t pixmap;
- xcb_gc_t gc;
- int i;
- uint8_t data[] = { 0, 0, 0, 0 };
-
- for (i = 0; i < ARRAY_SIZE(atoms); i++)
- cookies[i] = xcb_intern_atom (c->conn, 0,
- strlen(atoms[i].name),
- atoms[i].name);
-
- for (i = 0; i < ARRAY_SIZE(atoms); i++) {
- reply = xcb_intern_atom_reply (c->conn, cookies[i], NULL);
- *(xcb_atom_t *) ((char *) c + atoms[i].offset) = reply->atom;
- free(reply);
- }
-
- pixmap = xcb_generate_id(c->conn);
- gc = xcb_generate_id(c->conn);
- xcb_create_pixmap(c->conn, 1, pixmap, c->screen->root, 1, 1);
- xcb_create_gc(c->conn, gc, pixmap, 0, NULL);
- xcb_put_image(c->conn, XCB_IMAGE_FORMAT_XY_PIXMAP,
- pixmap, gc, 1, 1, 0, 0, 0, 32, sizeof data, data);
- c->null_cursor = xcb_generate_id(c->conn);
- xcb_create_cursor (c->conn, c->null_cursor,
- pixmap, pixmap, 0, 0, 0, 0, 0, 0, 1, 1);
- xcb_free_gc(c->conn, gc);
- xcb_free_pixmap(c->conn, pixmap);
-}
-
-static int
-x11_authenticate(struct wlsc_compositor *c, uint32_t id)
-{
- return dri2_authenticate((struct x11_compositor *) c, id);
-}
-
-static void
-x11_destroy(struct wlsc_compositor *ec)
-{
- free(ec);
-}
-
-struct wlsc_compositor *
-x11_compositor_create(struct wl_display *display, int width, int height)
-{
- struct x11_compositor *c;
- struct wl_event_loop *loop;
- xcb_screen_iterator_t s;
-
- c = malloc(sizeof *c);
- if (c == NULL)
- return NULL;
-
- memset(c, 0, sizeof *c);
- c->conn = xcb_connect(0, 0);
-
- if (xcb_connection_has_error(c->conn))
- return NULL;
-
- s = xcb_setup_roots_iterator(xcb_get_setup(c->conn));
- c->screen = s.data;
- wl_array_init(&c->keys);
-
- x11_compositor_get_resources(c);
-
- c->base.wl_display = display;
- if (x11_compositor_init_egl(c) < 0)
- return NULL;
-
- c->base.destroy = x11_destroy;
- c->base.authenticate = x11_authenticate;
- c->base.present = x11_compositor_present;
- c->base.create_buffer = wlsc_drm_buffer_create;
-
- /* Can't init base class until we have a current egl context */
- if (wlsc_compositor_init(&c->base, display) < 0)
- return NULL;
-
- if (x11_compositor_create_output(c, width, height) < 0)
- return NULL;
-
- if (x11_input_create(c) < 0)
- return NULL;
-
- loop = wl_display_get_event_loop(c->base.wl_display);
-
- c->xcb_source =
- wl_event_loop_add_fd(loop, xcb_get_file_descriptor(c->conn),
- WL_EVENT_READABLE,
- x11_compositor_handle_event, c);
-
- return &c->base;
-}
diff --git a/compositor/compositor.c b/compositor/compositor.c
deleted file mode 100644
index afff961..0000000
--- a/compositor/compositor.c
+++ /dev/null
@@ -1,1411 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-
-#include "config.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <math.h>
-#include <linux/input.h>
-
-#include "wayland-server.h"
-#include "compositor.h"
-
-struct wlsc_switcher {
- struct wlsc_compositor *compositor;
- struct wlsc_surface *current;
- struct wl_listener listener;
-};
-
-/* The plan here is to generate a random anonymous socket name and
- * advertise that through a service on the session dbus.
- */
-static const char *option_socket_name = NULL;
-static const char *option_background = "background.jpg";
-static const char *option_geometry = "1024x640";
-static int option_connector = 0;
-
-static const GOptionEntry option_entries[] = {
- { "background", 'b', 0, G_OPTION_ARG_STRING,
- &option_background, "Background image" },
- { "connector", 'c', 0, G_OPTION_ARG_INT,
- &option_connector, "KMS connector" },
- { "geometry", 'g', 0, G_OPTION_ARG_STRING,
- &option_geometry, "Geometry" },
- { "socket", 's', 0, G_OPTION_ARG_STRING,
- &option_socket_name, "Socket Name" },
- { NULL }
-};
-
-static void
-wlsc_matrix_init(struct wlsc_matrix *matrix)
-{
- static const struct wlsc_matrix identity = {
- { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }
- };
-
- memcpy(matrix, &identity, sizeof identity);
-}
-
-static void
-wlsc_matrix_multiply(struct wlsc_matrix *m, const struct wlsc_matrix *n)
-{
- struct wlsc_matrix tmp;
- const GLfloat *row, *column;
- div_t d;
- int i, j;
-
- for (i = 0; i < 16; i++) {
- tmp.d[i] = 0;
- d = div(i, 4);
- row = m->d + d.quot * 4;
- column = n->d + d.rem;
- for (j = 0; j < 4; j++)
- tmp.d[i] += row[j] * column[j * 4];
- }
- memcpy(m, &tmp, sizeof tmp);
-}
-
-static void
-wlsc_matrix_translate(struct wlsc_matrix *matrix, GLfloat x, GLfloat y, GLfloat z)
-{
- struct wlsc_matrix translate = {
- { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 }
- };
-
- wlsc_matrix_multiply(matrix, &translate);
-}
-
-static void
-wlsc_matrix_scale(struct wlsc_matrix *matrix, GLfloat x, GLfloat y, GLfloat z)
-{
- struct wlsc_matrix scale = {
- { x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 }
- };
-
- wlsc_matrix_multiply(matrix, &scale);
-}
-
-static void
-wlsc_matrix_transform(struct wlsc_matrix *matrix, struct wlsc_vector *v)
-{
- int i, j;
- struct wlsc_vector t;
-
- for (i = 0; i < 4; i++) {
- t.f[i] = 0;
- for (j = 0; j < 4; j++)
- t.f[i] += v->f[j] * matrix->d[i + j * 4];
- }
-
- *v = t;
-}
-
-static struct wlsc_surface *
-wlsc_surface_create(struct wlsc_compositor *compositor,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- struct wlsc_surface *surface;
-
- surface = malloc(sizeof *surface);
- if (surface == NULL)
- return NULL;
-
- wl_list_init(&surface->surface.destroy_listener_list);
- wl_list_init(&surface->link);
- surface->map_type = WLSC_SURFACE_MAP_UNMAPPED;
-
- glGenTextures(1, &surface->texture);
- glBindTexture(GL_TEXTURE_2D, surface->texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- surface->compositor = compositor;
- surface->visual = NULL;
- surface->x = x;
- surface->y = y;
- surface->width = width;
- surface->height = height;
- wlsc_matrix_init(&surface->matrix);
- wlsc_matrix_scale(&surface->matrix, width, height, 1);
- wlsc_matrix_translate(&surface->matrix, x, y, 0);
-
- wlsc_matrix_init(&surface->matrix_inv);
- wlsc_matrix_translate(&surface->matrix_inv, -x, -y, 0);
- wlsc_matrix_scale(&surface->matrix_inv, 1.0 / width, 1.0 / height, 1);
-
- return surface;
-}
-
-void
-wlsc_surface_damage_rectangle(struct wlsc_surface *surface,
- int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- struct wlsc_compositor *compositor = surface->compositor;
-
- pixman_region32_union_rect(&compositor->damage_region,
- &compositor->damage_region,
- surface->x + x, surface->y + y,
- width, height);
- wlsc_compositor_schedule_repaint(compositor);
-}
-
-void
-wlsc_surface_damage(struct wlsc_surface *surface)
-{
- wlsc_surface_damage_rectangle(surface, 0, 0,
- surface->width, surface->height);
-}
-
-uint32_t
-get_time(void)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
-
- return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-}
-
-static void
-destroy_surface(struct wl_resource *resource, struct wl_client *client)
-{
- struct wlsc_surface *surface =
- container_of(resource, struct wlsc_surface, surface.resource);
- struct wl_listener *l, *next;
- uint32_t time;
-
- wlsc_surface_damage(surface);
-
- wl_list_remove(&surface->link);
- glDeleteTextures(1, &surface->texture);
-
- time = get_time();
- wl_list_for_each_safe(l, next,
- &surface->surface.destroy_listener_list, link)
- l->func(l, &surface->surface, time);
-
- free(surface);
-}
-
-uint32_t *
-wlsc_load_image(const char *filename, int width, int height)
-{
- GdkPixbuf *pixbuf;
- GError *error = NULL;
- int stride, i, n_channels;
- unsigned char *pixels, *end, *argb_pixels, *s, *d;
-
- pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
- width, height,
- FALSE, &error);
- if (error != NULL) {
- fprintf(stderr, "failed to load image: %s\n", error->message);
- g_error_free(error);
- return NULL;
- }
-
- stride = gdk_pixbuf_get_rowstride(pixbuf);
- pixels = gdk_pixbuf_get_pixels(pixbuf);
- n_channels = gdk_pixbuf_get_n_channels(pixbuf);
-
- argb_pixels = malloc (height * width * 4);
- if (argb_pixels == NULL) {
- g_object_unref(pixbuf);
- return NULL;
- }
-
- if (n_channels == 4) {
- for (i = 0; i < height; i++) {
- s = pixels + i * stride;
- end = s + width * 4;
- d = argb_pixels + i * width * 4;
- while (s < end) {
- unsigned int t;
-
-#define MULT(_d,c,a,t) \
- do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0)
-
- MULT(d[0], s[2], s[3], t);
- MULT(d[1], s[1], s[3], t);
- MULT(d[2], s[0], s[3], t);
- d[3] = s[3];
- s += 4;
- d += 4;
- }
- }
- } else if (n_channels == 3) {
- for (i = 0; i < height; i++) {
- s = pixels + i * stride;
- end = s + width * 3;
- d = argb_pixels + i * width * 4;
- while (s < end) {
- d[0] = s[2];
- d[1] = s[1];
- d[2] = s[0];
- d[3] = 0xff;
- s += 3;
- d += 4;
- }
- }
- }
-
- g_object_unref(pixbuf);
-
- return (uint32_t *) argb_pixels;
-}
-
-static struct wl_buffer *
-create_buffer_from_png(struct wlsc_compositor *ec,
- const char *filename, int width, int height)
-{
- uint32_t *pixels;
- struct wl_buffer *buffer;
-
- pixels = wlsc_load_image(filename, width, height);
- if(pixels == NULL)
- return NULL;
-
- buffer = ec->create_buffer(ec, width, height,
- &ec->compositor.premultiplied_argb_visual,
- pixels);
-
- free(pixels);
-
- return buffer;
-}
-
-static const struct {
- const char *filename;
- int hotspot_x, hotspot_y;
-} pointer_images[] = {
- { DATADIR "/wayland/bottom_left_corner.png", 6, 30 },
- { DATADIR "/wayland/bottom_right_corner.png", 28, 28 },
- { DATADIR "/wayland/bottom_side.png", 16, 20 },
- { DATADIR "/wayland/grabbing.png", 20, 17 },
- { DATADIR "/wayland/left_ptr.png", 10, 5 },
- { DATADIR "/wayland/left_side.png", 10, 20 },
- { DATADIR "/wayland/right_side.png", 30, 19 },
- { DATADIR "/wayland/top_left_corner.png", 8, 8 },
- { DATADIR "/wayland/top_right_corner.png", 26, 8 },
- { DATADIR "/wayland/top_side.png", 18, 8 },
- { DATADIR "/wayland/xterm.png", 15, 15 }
-};
-
-static void
-create_pointer_images(struct wlsc_compositor *ec)
-{
- int i, count;
- const int width = 32, height = 32;
-
- count = ARRAY_LENGTH(pointer_images);
- ec->pointer_buffers = malloc(count * sizeof *ec->pointer_buffers);
- for (i = 0; i < count; i++) {
- ec->pointer_buffers[i] =
- create_buffer_from_png(ec,
- pointer_images[i].filename,
- width, height);
- }
-}
-
-static struct wlsc_surface *
-background_create(struct wlsc_output *output, const char *filename)
-{
- struct wlsc_surface *background;
- struct wl_buffer *buffer;
-
- background = wlsc_surface_create(output->compositor,
- output->x, output->y,
- output->width, output->height);
- if (background == NULL)
- return NULL;
-
- buffer = create_buffer_from_png(output->compositor,
- filename,
- output->width, output->height);
- if (buffer == NULL) {
- free(background);
- return NULL;
- }
- buffer->attach(buffer, &background->surface);
-
- return background;
-}
-
-static void
-wlsc_surface_draw(struct wlsc_surface *es,
- struct wlsc_output *output, pixman_region32_t *clip)
-{
- struct wlsc_compositor *ec = es->compositor;
- GLfloat *v, inv_width, inv_height;
- unsigned int *p;
- pixman_region32_t repaint;
- pixman_box32_t *rectangles;
- int i, n;
-
- pixman_region32_init_rect(&repaint,
- es->x, es->y, es->width, es->height);
- pixman_region32_intersect(&repaint, &repaint, clip);
- if (!pixman_region32_not_empty(&repaint))
- return;
-
- if (es->visual == &ec->compositor.argb_visual) {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- } else if (es->visual == &ec->compositor.premultiplied_argb_visual) {
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- } else {
- glDisable(GL_BLEND);
- }
-
- rectangles = pixman_region32_rectangles(&repaint, &n);
- v = wl_array_add(&ec->vertices, n * 16 * sizeof *v);
- p = wl_array_add(&ec->indices, n * 6 * sizeof *p);
- inv_width = 1.0 / es->width;
- inv_height = 1.0 / es->height;
- for (i = 0; i < n; i++, v += 16, p += 6) {
- v[ 0] = rectangles[i].x1;
- v[ 1] = rectangles[i].y1;
- v[ 2] = (GLfloat) (rectangles[i].x1 - es->x) * inv_width;
- v[ 3] = (GLfloat) (rectangles[i].y1 - es->y) * inv_height;
-
- v[ 4] = rectangles[i].x1;
- v[ 5] = rectangles[i].y2;
- v[ 6] = v[ 2];
- v[ 7] = (GLfloat) (rectangles[i].y2 - es->y) * inv_height;
-
- v[ 8] = rectangles[i].x2;
- v[ 9] = rectangles[i].y1;
- v[10] = (GLfloat) (rectangles[i].x2 - es->x) * inv_width;
- v[11] = v[ 3];
-
- v[12] = rectangles[i].x2;
- v[13] = rectangles[i].y2;
- v[14] = v[10];
- v[15] = v[ 7];
-
- p[0] = i * 4 + 0;
- p[1] = i * 4 + 1;
- p[2] = i * 4 + 2;
- p[3] = i * 4 + 2;
- p[4] = i * 4 + 1;
- p[5] = i * 4 + 3;
- }
-
- glBindTexture(GL_TEXTURE_2D, es->texture);
- v = ec->vertices.data;
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[0]);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[2]);
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glDrawElements(GL_TRIANGLES, n * 6, GL_UNSIGNED_INT, ec->indices.data);
-
- ec->vertices.size = 0;
- ec->indices.size = 0;
- pixman_region32_fini(&repaint);
-}
-
-static void
-wlsc_surface_raise(struct wlsc_surface *surface)
-{
- struct wlsc_compositor *compositor = surface->compositor;
-
- wl_list_remove(&surface->link);
- wl_list_insert(&compositor->surface_list, &surface->link);
-}
-
-void
-wlsc_surface_update_matrix(struct wlsc_surface *es)
-{
- wlsc_matrix_init(&es->matrix);
- wlsc_matrix_scale(&es->matrix, es->width, es->height, 1);
- wlsc_matrix_translate(&es->matrix, es->x, es->y, 0);
-
- wlsc_matrix_init(&es->matrix_inv);
- wlsc_matrix_translate(&es->matrix_inv, -es->x, -es->y, 0);
- wlsc_matrix_scale(&es->matrix_inv,
- 1.0 / es->width, 1.0 / es->height, 1);
-}
-
-void
-wlsc_compositor_finish_frame(struct wlsc_compositor *compositor, int msecs)
-{
- wl_display_post_frame(compositor->wl_display, msecs);
- wl_event_source_timer_update(compositor->timer_source, 5);
- compositor->repaint_on_timeout = 1;
-}
-
-static void
-wlsc_output_repaint(struct wlsc_output *output)
-{
- struct wlsc_compositor *ec = output->compositor;
- struct wlsc_surface *es;
- struct wlsc_input_device *eid;
- pixman_region32_t new_damage, total_damage;
-
- glViewport(0, 0, output->width, output->height);
-
- glUniformMatrix4fv(ec->proj_uniform, 1, GL_FALSE, output->matrix.d);
- glUniform1i(ec->tex_uniform, 0);
-
- pixman_region32_init(&new_damage);
- pixman_region32_init(&total_damage);
- pixman_region32_intersect_rect(&new_damage,
- &ec->damage_region,
- output->x, output->y,
- output->width, output->height);
- pixman_region32_subtract(&ec->damage_region,
- &ec->damage_region, &new_damage);
- pixman_region32_union(&total_damage, &new_damage,
- &output->previous_damage_region);
- pixman_region32_copy(&output->previous_damage_region, &new_damage);
-
- es = container_of(ec->surface_list.next, struct wlsc_surface, link);
- if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN &&
- es->fullscreen_output == output) {
- if (es->width < output->width || es->height < output->height)
- glClear(GL_COLOR_BUFFER_BIT);
- wlsc_surface_draw(es, output, &total_damage);
- } else {
- if (output->background)
- wlsc_surface_draw(output->background,
- output, &total_damage);
- else
- glClear(GL_COLOR_BUFFER_BIT);
-
- wl_list_for_each_reverse(es, &ec->surface_list, link) {
- if (ec->switcher &&
- ec->switcher->current == es)
- continue;
-
- wlsc_surface_draw(es, output, &total_damage);
- }
- }
-
- if (ec->switcher)
- wlsc_surface_draw(ec->switcher->current,
- output, &total_damage);
-
- if (ec->focus)
- wl_list_for_each(eid, &ec->input_device_list, link)
- wlsc_surface_draw(eid->sprite, output, &total_damage);
-}
-
-static void
-repaint(void *data)
-{
- struct wlsc_compositor *ec = data;
- struct wlsc_output *output;
-
- if (!ec->repaint_needed) {
- ec->repaint_on_timeout = 0;
- return;
- }
-
- wl_list_for_each(output, &ec->output_list, link)
- wlsc_output_repaint(output);
-
- ec->present(ec);
-
- ec->repaint_needed = 0;
-}
-
-void
-wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor)
-{
- compositor->repaint_needed = 1;
- if (compositor->repaint_on_timeout)
- return;
-
- wl_event_source_timer_update(compositor->timer_source, 1);
- compositor->repaint_on_timeout = 1;
-}
-
-static void
-surface_destroy(struct wl_client *client,
- struct wl_surface *surface)
-{
- wl_resource_destroy(&surface->resource, client);
-}
-
-static void
-surface_attach(struct wl_client *client,
- struct wl_surface *surface, struct wl_buffer *buffer,
- int32_t x, int32_t y)
-{
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
-
- /* FIXME: This damages the entire old surface, but we should
- * really just damage the part that's no longer covered by the
- * surface. Anything covered by the new surface will be
- * damaged by the client. */
- wlsc_surface_damage(es);
-
- buffer->attach(buffer, surface);
- es->buffer = buffer;
- es->x += x;
- es->y += y;
- es->width = buffer->width;
- es->height = buffer->height;
- wlsc_surface_update_matrix(es);
-}
-
-static void
-surface_map_toplevel(struct wl_client *client,
- struct wl_surface *surface)
-{
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
-
- switch (es->map_type) {
- case WLSC_SURFACE_MAP_UNMAPPED:
- es->x = 10 + random() % 400;
- es->y = 10 + random() % 400;
- wlsc_surface_update_matrix(es);
- wl_list_insert(&es->compositor->surface_list, &es->link);
- break;
- case WLSC_SURFACE_MAP_TOPLEVEL:
- return;
- case WLSC_SURFACE_MAP_FULLSCREEN:
- es->fullscreen_output = NULL;
- es->x = es->saved_x;
- es->y = es->saved_y;
- wlsc_surface_update_matrix(es);
- break;
- default:
- break;
- }
-
- wlsc_surface_damage(es);
- es->map_type = WLSC_SURFACE_MAP_TOPLEVEL;
-}
-
-static void
-surface_map_transient(struct wl_client *client,
- struct wl_surface *surface, struct wl_surface *parent,
- int x, int y, uint32_t flags)
-{
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
- struct wlsc_surface *pes = (struct wlsc_surface *) parent;
-
- switch (es->map_type) {
- case WLSC_SURFACE_MAP_UNMAPPED:
- wl_list_insert(&es->compositor->surface_list, &es->link);
- break;
- case WLSC_SURFACE_MAP_FULLSCREEN:
- es->fullscreen_output = NULL;
- break;
- default:
- break;
- }
-
- es->x = pes->x + x;
- es->y = pes->y + y;
-
- wlsc_surface_update_matrix(es);
- wlsc_surface_damage(es);
- es->map_type = WLSC_SURFACE_MAP_TRANSIENT;
-}
-
-static void
-surface_map_fullscreen(struct wl_client *client, struct wl_surface *surface)
-{
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
- struct wlsc_output *output;
-
- switch (es->map_type) {
- case WLSC_SURFACE_MAP_UNMAPPED:
- es->x = 10 + random() % 400;
- es->y = 10 + random() % 400;
- wl_list_insert(&es->compositor->surface_list, &es->link);
- break;
- case WLSC_SURFACE_MAP_FULLSCREEN:
- return;
- default:
- break;
- }
-
- /* FIXME: Fullscreen on first output */
- /* FIXME: Handle output going away */
- output = container_of(es->compositor->output_list.next,
- struct wlsc_output, link);
-
- es->saved_x = es->x;
- es->saved_y = es->y;
- es->x = (output->width - es->width) / 2;
- es->y = (output->height - es->height) / 2;
- es->fullscreen_output = output;
- wlsc_surface_update_matrix(es);
- wlsc_surface_damage(es);
- es->map_type = WLSC_SURFACE_MAP_FULLSCREEN;
-}
-
-static void
-surface_damage(struct wl_client *client,
- struct wl_surface *surface,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
-
- es->buffer->damage(es->buffer, surface, x, y, width, height);
-
- wlsc_surface_damage_rectangle(es, x, y, width, height);
-}
-
-const static struct wl_surface_interface surface_interface = {
- surface_destroy,
- surface_attach,
- surface_map_toplevel,
- surface_map_transient,
- surface_map_fullscreen,
- surface_damage
-};
-
-static void
-wlsc_input_device_attach(struct wlsc_input_device *device,
- struct wl_buffer *buffer, int x, int y)
-{
- wlsc_surface_damage(device->sprite);
-
- buffer->attach(buffer, &device->sprite->surface);
- device->hotspot_x = x;
- device->hotspot_y = y;
-
- device->sprite->x = device->input_device.x - device->hotspot_x;
- device->sprite->y = device->input_device.y - device->hotspot_y;
- device->sprite->width = buffer->width;
- device->sprite->height = buffer->height;
- wlsc_surface_update_matrix(device->sprite);
-
- wlsc_surface_damage(device->sprite);
-}
-
-
-void
-wlsc_input_device_set_pointer_image(struct wlsc_input_device *device,
- enum wlsc_pointer_type type)
-{
- struct wlsc_compositor *compositor =
- (struct wlsc_compositor *) device->input_device.compositor;
-
- wlsc_input_device_attach(device,
- compositor->pointer_buffers[type],
- pointer_images[type].hotspot_x,
- pointer_images[type].hotspot_y);
-}
-
-static void
-compositor_create_surface(struct wl_client *client,
- struct wl_compositor *compositor, uint32_t id)
-{
- struct wlsc_compositor *ec = (struct wlsc_compositor *) compositor;
- struct wlsc_surface *surface;
-
- surface = wlsc_surface_create(ec, 0, 0, 0, 0);
- if (surface == NULL) {
- wl_client_post_no_memory(client);
- return;
- }
-
- surface->surface.resource.destroy = destroy_surface;
-
- surface->surface.resource.object.id = id;
- surface->surface.resource.object.interface = &wl_surface_interface;
- surface->surface.resource.object.implementation =
- (void (**)(void)) &surface_interface;
- surface->surface.client = client;
-
- wl_client_add_resource(client, &surface->surface.resource);
-}
-
-const static struct wl_compositor_interface compositor_interface = {
- compositor_create_surface,
-};
-
-static void
-wlsc_surface_transform(struct wlsc_surface *surface,
- int32_t x, int32_t y, int32_t *sx, int32_t *sy)
-{
- struct wlsc_vector v = { { x, y, 0, 1 } };
-
- wlsc_matrix_transform(&surface->matrix_inv, &v);
- *sx = v.f[0] * surface->width;
- *sy = v.f[1] * surface->height;
-}
-
-struct wlsc_surface *
-pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy)
-{
- struct wlsc_compositor *ec =
- (struct wlsc_compositor *) device->compositor;
- struct wlsc_surface *es;
-
- wl_list_for_each(es, &ec->surface_list, link) {
- wlsc_surface_transform(es, device->x, device->y, sx, sy);
- if (0 <= *sx && *sx < es->width &&
- 0 <= *sy && *sy < es->height)
- return es;
- }
-
- return NULL;
-}
-
-
-static void
-motion_grab_motion(struct wl_grab *grab,
- uint32_t time, int32_t x, int32_t y)
-{
- struct wlsc_input_device *device =
- (struct wlsc_input_device *) grab->input_device;
- struct wlsc_surface *es =
- (struct wlsc_surface *) device->input_device.pointer_focus;
- int32_t sx, sy;
-
- wlsc_surface_transform(es, x, y, &sx, &sy);
- wl_client_post_event(es->surface.client,
- &device->input_device.object,
- WL_INPUT_DEVICE_MOTION,
- time, x, y, sx, sy);
-}
-
-static void
-motion_grab_button(struct wl_grab *grab,
- uint32_t time, int32_t button, int32_t state)
-{
- wl_client_post_event(grab->input_device->pointer_focus->client,
- &grab->input_device->object,
- WL_INPUT_DEVICE_BUTTON,
- time, button, state);
-}
-
-static void
-motion_grab_end(struct wl_grab *grab, uint32_t time)
-{
-}
-
-static const struct wl_grab_interface motion_grab_interface = {
- motion_grab_motion,
- motion_grab_button,
- motion_grab_end
-};
-
-void
-notify_motion(struct wl_input_device *device, uint32_t time, int x, int y)
-{
- struct wlsc_surface *es;
- struct wlsc_compositor *ec =
- (struct wlsc_compositor *) device->compositor;
- struct wlsc_output *output;
- const struct wl_grab_interface *interface;
- struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
- int32_t sx, sy;
-
- /* FIXME: We need some multi head love here. */
- output = container_of(ec->output_list.next, struct wlsc_output, link);
- if (x < output->x)
- x = 0;
- if (y < output->y)
- y = 0;
- if (x >= output->x + output->width)
- x = output->x + output->width - 1;
- if (y >= output->y + output->height)
- y = output->y + output->height - 1;
-
- device->x = x;
- device->y = y;
-
- if (device->grab) {
- interface = device->grab->interface;
- interface->motion(device->grab, time, x, y);
- } else {
- es = pick_surface(device, &sx, &sy);
- wl_input_device_set_pointer_focus(device,
- &es->surface,
- time, x, y, sx, sy);
- if (es)
- wl_client_post_event(es->surface.client,
- &device->object,
- WL_INPUT_DEVICE_MOTION,
- time, x, y, sx, sy);
- }
-
- wlsc_surface_damage(wd->sprite);
-
- wd->sprite->x = device->x - wd->hotspot_x;
- wd->sprite->y = device->y - wd->hotspot_y;
- wlsc_surface_update_matrix(wd->sprite);
-
- wlsc_surface_damage(wd->sprite);
-}
-
-static void
-wlsc_surface_activate(struct wlsc_surface *surface,
- struct wlsc_input_device *device, uint32_t time)
-{
- wlsc_surface_raise(surface);
- if (device->selection)
- wlsc_selection_set_focus(device->selection,
- &surface->surface, time);
-
- wl_input_device_set_keyboard_focus(&device->input_device,
- &surface->surface,
- time);
-}
-
-void
-notify_button(struct wl_input_device *device,
- uint32_t time, int32_t button, int32_t state)
-{
- struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
- struct wlsc_surface *surface;
- struct wlsc_compositor *compositor =
- (struct wlsc_compositor *) device->compositor;
-
- surface = (struct wlsc_surface *) device->pointer_focus;
- uint32_t edges = 0;
- int32_t x, y;
-
- if (state && surface && device->grab == NULL) {
- wlsc_surface_activate(surface, wd, time);
- wl_input_device_start_grab(device,
- &device->motion_grab,
- button, time);
- }
-
- if (state && surface && button == BTN_LEFT &&
- (wd->modifier_state & MODIFIER_SUPER))
- shell_move(NULL,
- (struct wl_shell *) &compositor->shell,
- &surface->surface, device, time);
- else if (state && surface && button == BTN_MIDDLE &&
- (wd->modifier_state & MODIFIER_SUPER)) {
-
- x = device->grab_x - surface->x;
- y = device->grab_y - surface->y;
-
- if (x < surface->width / 3)
- edges |= WL_SHELL_RESIZE_LEFT;
- else if (x < 2 * surface->width / 3)
- edges |= 0;
- else
- edges |= WL_SHELL_RESIZE_RIGHT;
-
- if (y < surface->height / 3)
- edges |= WL_SHELL_RESIZE_TOP;
- else if (y < 2 * surface->height / 3)
- edges |= 0;
- else
- edges |= WL_SHELL_RESIZE_BOTTOM;
-
- shell_resize(NULL,
- (struct wl_shell *) &compositor->shell,
- &surface->surface, device, time, edges);
- }
-
- if (device->grab)
- device->grab->interface->button(device->grab, time,
- button, state);
-
- if (!state && device->grab && device->grab_button == button)
- wl_input_device_end_grab(device, time);
-}
-
-static void
-wlsc_switcher_next(struct wlsc_switcher *switcher)
-{
- struct wl_list *l;
-
- wlsc_surface_damage(switcher->current);
- l = switcher->current->link.next;
- if (l == &switcher->compositor->surface_list)
- l = switcher->compositor->surface_list.next;
- switcher->current = container_of(l, struct wlsc_surface, link);
- wl_list_remove(&switcher->listener.link);
- wl_list_insert(switcher->current->surface.destroy_listener_list.prev,
- &switcher->listener.link);
- wlsc_surface_damage(switcher->current);
-}
-
-static void
-switcher_handle_surface_destroy(struct wl_listener *listener,
- struct wl_surface *surface, uint32_t time)
-{
- struct wlsc_switcher *switcher =
- container_of(listener, struct wlsc_switcher, listener);
-
- wlsc_switcher_next(switcher);
-}
-
-static struct wlsc_switcher *
-wlsc_switcher_create(struct wlsc_compositor *compositor)
-{
- struct wlsc_switcher *switcher;
-
- switcher = malloc(sizeof *switcher);
- switcher->compositor = compositor;
- switcher->current = container_of(compositor->surface_list.next,
- struct wlsc_surface, link);
- switcher->listener.func = switcher_handle_surface_destroy;
- wl_list_init(&switcher->listener.link);
-
- return switcher;
-}
-
-static void
-wlsc_switcher_destroy(struct wlsc_switcher *switcher)
-{
- wl_list_remove(&switcher->listener.link);
- free(switcher);
-}
-
-void
-notify_key(struct wl_input_device *device,
- uint32_t time, uint32_t key, uint32_t state)
-{
- struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
- struct wlsc_compositor *compositor =
- (struct wlsc_compositor *) device->compositor;
- uint32_t *k, *end;
- uint32_t modifier;
-
- switch (key | wd->modifier_state) {
- case KEY_BACKSPACE | MODIFIER_CTRL | MODIFIER_ALT:
- wl_display_terminate(compositor->wl_display);
- return;
-
- case KEY_TAB | MODIFIER_SUPER:
- if (!state)
- return;
- if (wl_list_empty(&compositor->surface_list))
- return;
- if (compositor->switcher == NULL)
- compositor->switcher = wlsc_switcher_create(compositor);
-
- wlsc_switcher_next(compositor->switcher);
- return;
-
- case KEY_LEFTMETA | MODIFIER_SUPER:
- case KEY_RIGHTMETA | MODIFIER_SUPER:
- if (compositor->switcher && !state) {
- wlsc_surface_activate(compositor->switcher->current,
- wd, time);
- wlsc_switcher_destroy(compositor->switcher);
- compositor->switcher = NULL;
- }
- break;
- }
-
- switch (key) {
- case KEY_LEFTCTRL:
- case KEY_RIGHTCTRL:
- modifier = MODIFIER_CTRL;
- break;
-
- case KEY_LEFTALT:
- case KEY_RIGHTALT:
- modifier = MODIFIER_ALT;
- break;
-
- case KEY_LEFTMETA:
- case KEY_RIGHTMETA:
- modifier = MODIFIER_SUPER;
- break;
-
- default:
- modifier = 0;
- break;
- }
-
- if (state)
- wd->modifier_state |= modifier;
- else
- wd->modifier_state &= ~modifier;
-
- end = device->keys.data + device->keys.size;
- for (k = device->keys.data; k < end; k++) {
- if (*k == key)
- *k = *--end;
- }
- device->keys.size = (void *) end - device->keys.data;
- if (state) {
- k = wl_array_add(&device->keys, sizeof *k);
- *k = key;
- }
-
- if (device->keyboard_focus != NULL)
- wl_client_post_event(device->keyboard_focus->client,
- &device->object,
- WL_INPUT_DEVICE_KEY, time, key, state);
-}
-
-void
-notify_pointer_focus(struct wl_input_device *device,
- uint32_t time, struct wlsc_output *output,
- int32_t x, int32_t y)
-{
- struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
- struct wlsc_compositor *compositor =
- (struct wlsc_compositor *) device->compositor;
- struct wlsc_surface *es;
- int32_t sx, sy;
-
- if (output) {
- device->x = x;
- device->y = y;
- es = pick_surface(device, &sx, &sy);
- wl_input_device_set_pointer_focus(device,
- &es->surface,
- time, x, y, sx, sy);
-
- compositor->focus = 1;
-
- wd->sprite->x = device->x - wd->hotspot_x;
- wd->sprite->y = device->y - wd->hotspot_y;
- wlsc_surface_update_matrix(wd->sprite);
- } else {
- wl_input_device_set_pointer_focus(device, NULL,
- time, 0, 0, 0, 0);
- compositor->focus = 0;
- }
-
- wlsc_surface_damage(wd->sprite);
-}
-
-void
-notify_keyboard_focus(struct wl_input_device *device,
- uint32_t time, struct wlsc_output *output,
- struct wl_array *keys)
-{
- struct wlsc_input_device *wd =
- (struct wlsc_input_device *) device;
- struct wlsc_compositor *compositor =
- (struct wlsc_compositor *) device->compositor;
- struct wlsc_surface *es;
-
- if (!wl_list_empty(&compositor->surface_list))
- es = container_of(compositor->surface_list.next,
- struct wlsc_surface, link);
- else
- es = NULL;
-
- if (output) {
- wl_array_copy(&wd->input_device.keys, keys);
- wl_input_device_set_keyboard_focus(&wd->input_device,
- &es->surface, time);
- } else {
- wl_input_device_set_keyboard_focus(&wd->input_device,
- NULL, time);
- }
-}
-
-
-static void
-input_device_attach(struct wl_client *client,
- struct wl_input_device *device_base,
- uint32_t time,
- struct wl_buffer *buffer, int32_t x, int32_t y)
-{
- struct wlsc_input_device *device =
- (struct wlsc_input_device *) device_base;
-
- if (time < device->input_device.pointer_focus_time)
- return;
- if (device->input_device.pointer_focus == NULL)
- return;
- if (device->input_device.pointer_focus->client != client)
- return;
-
- if (buffer == NULL) {
- wlsc_input_device_set_pointer_image(device,
- WLSC_POINTER_LEFT_PTR);
- return;
- }
-
- wlsc_input_device_attach(device, buffer, x, y);
-}
-
-const static struct wl_input_device_interface input_device_interface = {
- input_device_attach,
-};
-
-void
-wlsc_input_device_init(struct wlsc_input_device *device,
- struct wlsc_compositor *ec)
-{
- wl_input_device_init(&device->input_device, &ec->compositor);
-
- device->input_device.object.interface = &wl_input_device_interface;
- device->input_device.object.implementation =
- (void (**)(void)) &input_device_interface;
- wl_display_add_object(ec->wl_display, &device->input_device.object);
- wl_display_add_global(ec->wl_display, &device->input_device.object, NULL);
-
- device->sprite = wlsc_surface_create(ec,
- device->input_device.x,
- device->input_device.y, 32, 32);
- device->hotspot_x = 16;
- device->hotspot_y = 16;
-
- device->input_device.motion_grab.interface = &motion_grab_interface;
-
- wl_list_insert(ec->input_device_list.prev, &device->link);
-
- wlsc_input_device_set_pointer_image(device, WLSC_POINTER_LEFT_PTR);
-}
-
-static void
-wlsc_output_post_geometry(struct wl_client *client, struct wl_object *global)
-{
- struct wlsc_output *output =
- container_of(global, struct wlsc_output, object);
-
- wl_client_post_event(client, global,
- WL_OUTPUT_GEOMETRY,
- output->x, output->y,
- output->width, output->height);
-}
-
-static const char vertex_shader[] =
- "uniform mat4 proj;\n"
- "attribute vec2 position;\n"
- "attribute vec2 texcoord;\n"
- "varying vec2 v_texcoord;\n"
- "void main()\n"
- "{\n"
- " gl_Position = proj * vec4(position, 0.0, 1.0);\n"
- " v_texcoord = texcoord;\n"
- "}\n";
-
-static const char fragment_shader[] =
- "precision mediump float;\n"
- "varying vec2 v_texcoord;\n"
- "uniform sampler2D tex;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = texture2D(tex, v_texcoord)\n;"
- "}\n";
-
-static int
-init_shaders(struct wlsc_compositor *ec)
-{
- GLuint v, f, program;
- const char *p;
- char msg[512];
- GLint status;
-
- p = vertex_shader;
- v = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(v, 1, &p, NULL);
- glCompileShader(v);
- glGetShaderiv(v, GL_COMPILE_STATUS, &status);
- if (!status) {
- glGetShaderInfoLog(v, sizeof msg, NULL, msg);
- fprintf(stderr, "vertex shader info: %s\n", msg);
- return -1;
- }
-
- p = fragment_shader;
- f = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(f, 1, &p, NULL);
- glCompileShader(f);
- glGetShaderiv(f, GL_COMPILE_STATUS, &status);
- if (!status) {
- glGetShaderInfoLog(f, sizeof msg, NULL, msg);
- fprintf(stderr, "fragment shader info: %s\n", msg);
- return -1;
- }
-
- program = glCreateProgram();
- glAttachShader(program, v);
- glAttachShader(program, f);
- glBindAttribLocation(program, 0, "position");
- glBindAttribLocation(program, 1, "texcoord");
-
- glLinkProgram(program);
- glGetProgramiv(program, GL_LINK_STATUS, &status);
- if (!status) {
- glGetProgramInfoLog(program, sizeof msg, NULL, msg);
- fprintf(stderr, "link info: %s\n", msg);
- return -1;
- }
-
- glUseProgram(program);
- ec->proj_uniform = glGetUniformLocation(program, "proj");
- ec->tex_uniform = glGetUniformLocation(program, "tex");
-
- return 0;
-}
-
-void
-wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
- int x, int y, int width, int height)
-{
- output->compositor = c;
- output->x = x;
- output->y = y;
- output->width = width;
- output->height = height;
-
- pixman_region32_init(&output->previous_damage_region);
-
- output->background =
- background_create(output, option_background);
-
- wlsc_matrix_init(&output->matrix);
- wlsc_matrix_translate(&output->matrix,
- -output->x - output->width / 2.0,
- -output->y - output->height / 2.0, 0);
- wlsc_matrix_scale(&output->matrix,
- 2.0 / output->width, 2.0 / output->height, 1);
-
- output->object.interface = &wl_output_interface;
- wl_display_add_object(c->wl_display, &output->object);
- wl_display_add_global(c->wl_display, &output->object,
- wlsc_output_post_geometry);
-
- pixman_region32_union_rect(&c->damage_region,
- &c->damage_region,
- x, y, width, height);
-}
-
-int
-wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display)
-{
- struct wl_event_loop *loop;
- const char *extensions;
-
- ec->wl_display = display;
-
- wl_compositor_init(&ec->compositor, &compositor_interface, display);
-
- wlsc_shm_init(ec);
-
- wlsc_shell_init(ec);
-
- wl_list_init(&ec->surface_list);
- wl_list_init(&ec->input_device_list);
- wl_list_init(&ec->output_list);
-
- create_pointer_images(ec);
-
- screenshooter_create(ec);
-
- extensions = (const char *) glGetString(GL_EXTENSIONS);
- if (!strstr(extensions, "GL_EXT_texture_format_BGRA8888")) {
- fprintf(stderr,
- "GL_EXT_texture_format_BGRA8888 not available\n");
- return -1;
- }
-
- glGenFramebuffers(1, &ec->fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, ec->fbo);
- glActiveTexture(GL_TEXTURE0);
- if (init_shaders(ec) < 0)
- return -1;
-
- loop = wl_display_get_event_loop(ec->wl_display);
- ec->timer_source = wl_event_loop_add_timer(loop, repaint, ec);
- pixman_region32_init(&ec->damage_region);
- wlsc_compositor_schedule_repaint(ec);
-
- return 0;
-}
-
-static void on_term_signal(int signal_number, void *data)
-{
- struct wlsc_compositor *ec = data;
-
- wl_display_terminate(ec->wl_display);
-}
-
-int main(int argc, char *argv[])
-{
- struct wl_display *display;
- struct wlsc_compositor *ec;
- struct wl_event_loop *loop;
- GError *error = NULL;
- GOptionContext *context;
- int width, height;
-
- g_type_init(); /* GdkPixbuf needs this, it seems. */
-
- context = g_option_context_new(NULL);
- g_option_context_add_main_entries(context, option_entries, "Wayland");
- if (!g_option_context_parse(context, &argc, &argv, &error)) {
- fprintf(stderr, "option parsing failed: %s\n", error->message);
- exit(EXIT_FAILURE);
- }
- if (sscanf(option_geometry, "%dx%d", &width, &height) != 2) {
- fprintf(stderr, "invalid geometry option: %s \n",
- option_geometry);
- exit(EXIT_FAILURE);
- }
-
- display = wl_display_create();
-
- ec = NULL;
-
-#if BUILD_WAYLAND_COMPOSITOR
- if (getenv("WAYLAND_DISPLAY"))
- ec = wayland_compositor_create(display, width, height);
-#endif
-
-#if BUILD_X11_COMPOSITOR
- if (ec == NULL && getenv("DISPLAY"))
- ec = x11_compositor_create(display, width, height);
-#endif
-
-#if BUILD_DRM_COMPOSITOR
- if (ec == NULL)
- ec = drm_compositor_create(display, option_connector);
-#endif
-
- if (ec == NULL) {
- fprintf(stderr, "failed to create compositor\n");
- exit(EXIT_FAILURE);
- }
-
- if (wl_display_add_socket(display, option_socket_name)) {
- fprintf(stderr, "failed to add socket: %m\n");
- exit(EXIT_FAILURE);
- }
-
- loop = wl_display_get_event_loop(ec->wl_display);
- wl_event_loop_add_signal(loop, SIGTERM, on_term_signal, ec);
- wl_event_loop_add_signal(loop, SIGINT, on_term_signal, ec);
-
- wl_display_run(display);
-
- wl_display_destroy(display);
-
- ec->destroy(ec);
-
- return 0;
-}
diff --git a/compositor/compositor.h b/compositor/compositor.h
deleted file mode 100644
index b0901e8..0000000
--- a/compositor/compositor.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef _WAYLAND_SYSTEM_COMPOSITOR_H_
-#define _WAYLAND_SYSTEM_COMPOSITOR_H_
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <libudev.h>
-#include <pixman.h>
-#include "wayland-server.h"
-#include "wayland-util.h"
-
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
-
-struct wlsc_matrix {
- GLfloat d[16];
-};
-
-struct wlsc_surface;
-
-struct wlsc_output {
- struct wl_object object;
- struct wl_list link;
- struct wlsc_compositor *compositor;
- struct wlsc_surface *background;
- struct wlsc_matrix matrix;
- int32_t x, y, width, height;
- pixman_region32_t previous_damage_region;
-};
-
-enum wlsc_pointer_type {
- WLSC_POINTER_BOTTOM_LEFT,
- WLSC_POINTER_BOTTOM_RIGHT,
- WLSC_POINTER_BOTTOM,
- WLSC_POINTER_DRAGGING,
- WLSC_POINTER_LEFT_PTR,
- WLSC_POINTER_LEFT,
- WLSC_POINTER_RIGHT,
- WLSC_POINTER_TOP_LEFT,
- WLSC_POINTER_TOP_RIGHT,
- WLSC_POINTER_TOP,
- WLSC_POINTER_IBEAM,
-};
-
-struct wlsc_input_device {
- struct wl_input_device input_device;
- struct wlsc_surface *sprite;
- int32_t hotspot_x, hotspot_y;
- struct wl_list link;
- uint32_t modifier_state;
- struct wl_selection *selection;
-};
-
-struct wlsc_drm {
- struct wl_object object;
- int fd;
- char *filename;
-};
-
-struct wlsc_shm {
- struct wl_object object;
-};
-
-struct wlsc_compositor {
- struct wl_compositor compositor;
-
- struct wlsc_drm drm;
- struct wlsc_shm shm;
- EGLDisplay display;
- EGLContext context;
- GLuint fbo;
- GLuint proj_uniform, tex_uniform;
- struct wl_buffer **pointer_buffers;
- struct wl_display *wl_display;
-
- /* We implement the shell interface. */
- struct wl_shell shell;
-
- /* There can be more than one, but not right now... */
- struct wl_input_device *input_device;
-
- struct wl_list output_list;
- struct wl_list input_device_list;
- struct wl_list surface_list;
-
- /* Repaint state. */
- struct wl_event_source *timer_source;
- int repaint_needed;
- int repaint_on_timeout;
- struct timespec previous_swap;
- pixman_region32_t damage_region;
- struct wl_array vertices, indices;
-
- struct wlsc_switcher *switcher;
- uint32_t focus;
-
- void (*destroy)(struct wlsc_compositor *ec);
- int (*authenticate)(struct wlsc_compositor *c, uint32_t id);
- void (*present)(struct wlsc_compositor *c);
- struct wl_buffer *(*create_buffer)(struct wlsc_compositor *c,
- int32_t width, int32_t height,
- struct wl_visual *visual,
- const void *data);
-};
-
-#define MODIFIER_CTRL (1 << 8)
-#define MODIFIER_ALT (1 << 9)
-#define MODIFIER_SUPER (1 << 10)
-
-struct wlsc_vector {
- GLfloat f[4];
-};
-
-enum wlsc_surface_map_type {
- WLSC_SURFACE_MAP_UNMAPPED,
- WLSC_SURFACE_MAP_TOPLEVEL,
- WLSC_SURFACE_MAP_TRANSIENT,
- WLSC_SURFACE_MAP_FULLSCREEN
-};
-
-struct wlsc_surface {
- struct wl_surface surface;
- struct wlsc_compositor *compositor;
- GLuint texture;
- int32_t x, y, width, height;
- int32_t saved_x, saved_y;
- struct wl_list link;
- struct wlsc_matrix matrix;
- struct wlsc_matrix matrix_inv;
- struct wl_visual *visual;
- struct wl_buffer *buffer;
- enum wlsc_surface_map_type map_type;
- struct wlsc_output *fullscreen_output;
-};
-
-void
-wlsc_surface_update_matrix(struct wlsc_surface *es);
-
-void
-notify_motion(struct wl_input_device *device,
- uint32_t time, int x, int y);
-void
-notify_button(struct wl_input_device *device,
- uint32_t time, int32_t button, int32_t state);
-void
-notify_key(struct wl_input_device *device,
- uint32_t time, uint32_t key, uint32_t state);
-
-void
-notify_pointer_focus(struct wl_input_device *device,
- uint32_t time,
- struct wlsc_output *output,
- int32_t x, int32_t y);
-
-void
-notify_keyboard_focus(struct wl_input_device *device,
- uint32_t time, struct wlsc_output *output,
- struct wl_array *keys);
-
-void
-wlsc_compositor_finish_frame(struct wlsc_compositor *compositor, int msecs);
-void
-wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor);
-
-void
-wlsc_surface_damage(struct wlsc_surface *surface);
-
-void
-wlsc_surface_damage_rectangle(struct wlsc_surface *surface,
- int32_t x, int32_t y,
- int32_t width, int32_t height);
-
-void
-wlsc_input_device_set_pointer_image(struct wlsc_input_device *device,
- enum wlsc_pointer_type type);
-struct wlsc_surface *
-pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy);
-
-void
-wlsc_selection_set_focus(struct wl_selection *selection,
- struct wl_surface *surface, uint32_t time);
-
-uint32_t
-get_time(void);
-
-struct wl_buffer *
-wlsc_drm_buffer_create(struct wlsc_compositor *ec,
- int width, int height,
- struct wl_visual *visual, const void *data);
-
-int
-wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display);
-void
-wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
- int x, int y, int width, int height);
-void
-wlsc_input_device_init(struct wlsc_input_device *device,
- struct wlsc_compositor *ec);
-int
-wlsc_drm_init(struct wlsc_compositor *ec, int fd, const char *filename);
-
-int
-wlsc_shm_init(struct wlsc_compositor *ec);
-
-int
-wlsc_shell_init(struct wlsc_compositor *ec);
-
-void
-shell_move(struct wl_client *client, struct wl_shell *shell,
- struct wl_surface *surface,
- struct wl_input_device *device, uint32_t time);
-
-void
-shell_resize(struct wl_client *client, struct wl_shell *shell,
- struct wl_surface *surface,
- struct wl_input_device *device, uint32_t time, uint32_t edges);
-
-struct wl_buffer *
-wl_buffer_create_drm(struct wlsc_compositor *compositor,
- struct wl_visual *visual);
-
-struct wlsc_compositor *
-x11_compositor_create(struct wl_display *display, int width, int height);
-
-struct wlsc_compositor *
-drm_compositor_create(struct wl_display *display, int connector);
-
-struct wlsc_compositor *
-wayland_compositor_create(struct wl_display *display, int width, int height);
-
-void
-evdev_input_add_devices(struct wlsc_compositor *c, struct udev *udev);
-
-struct tty *
-tty_create(struct wlsc_compositor *compositor);
-
-void
-tty_destroy(struct tty *tty);
-
-void
-screenshooter_create(struct wlsc_compositor *ec);
-
-uint32_t *
-wlsc_load_image(const char *filename, int width, int height);
-
-#endif
diff --git a/compositor/drm.c b/compositor/drm.c
deleted file mode 100644
index 9e25d33..0000000
--- a/compositor/drm.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright © 2010 Kristian Høgsberg
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "compositor.h"
-
-struct wlsc_drm_buffer {
- struct wl_buffer buffer;
- EGLImageKHR image;
-};
-
-static void
-drm_authenticate(struct wl_client *client,
- struct wl_drm *drm_base, uint32_t id)
-{
- struct wlsc_drm *drm = (struct wlsc_drm *) drm_base;
- struct wlsc_compositor *compositor =
- container_of(drm, struct wlsc_compositor, drm);
-
- if (compositor->authenticate(compositor, id) < 0)
- wl_client_post_event(client,
- (struct wl_object *) compositor->wl_display,
- WL_DISPLAY_INVALID_OBJECT, 0);
- else
- wl_client_post_event(client, &drm->object,
- WL_DRM_AUTHENTICATED);
-}
-
-static void
-destroy_buffer(struct wl_resource *resource, struct wl_client *client)
-{
- struct wlsc_drm_buffer *buffer =
- container_of(resource, struct wlsc_drm_buffer, buffer.resource);
- struct wlsc_compositor *compositor =
- (struct wlsc_compositor *) buffer->buffer.compositor;
-
- eglDestroyImageKHR(compositor->display, buffer->image);
- free(buffer);
-}
-
-static void
-buffer_destroy(struct wl_client *client, struct wl_buffer *buffer)
-{
- wl_resource_destroy(&buffer->resource, client);
-}
-
-const static struct wl_buffer_interface buffer_interface = {
- buffer_destroy
-};
-
-static void
-drm_buffer_attach(struct wl_buffer *buffer_base, struct wl_surface *surface)
-{
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
- struct wlsc_drm_buffer *buffer =
- (struct wlsc_drm_buffer *) buffer_base;
-
- glBindTexture(GL_TEXTURE_2D, es->texture);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, buffer->image);
- es->visual = buffer->buffer.visual;
-}
-
-static void
-drm_buffer_damage(struct wl_buffer *buffer,
- struct wl_surface *surface,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
-}
-
-static struct wlsc_drm_buffer *
-wlsc_drm_buffer_create_for_image(struct wlsc_compositor *compositor,
- EGLImageKHR *image,
- int32_t width, int32_t height,
- struct wl_visual *visual)
-{
- struct wlsc_drm_buffer *buffer;
-
- buffer = malloc(sizeof *buffer);
- if (buffer == NULL)
- return NULL;
-
- buffer->buffer.compositor = &compositor->compositor;
- buffer->buffer.width = width;
- buffer->buffer.height = height;
- buffer->buffer.visual = visual;
- buffer->buffer.attach = drm_buffer_attach;
- buffer->buffer.damage = drm_buffer_damage;
- buffer->image = image;
-
- return buffer;
-}
-
-static void
-drm_create_buffer(struct wl_client *client, struct wl_drm *drm_base,
- uint32_t id, uint32_t name, int32_t width, int32_t height,
- uint32_t stride, struct wl_visual *visual)
-{
- struct wlsc_drm *drm = (struct wlsc_drm *) drm_base;
- struct wlsc_compositor *compositor =
- container_of(drm, struct wlsc_compositor, drm);
- struct wlsc_drm_buffer *buffer;
- EGLImageKHR image;
- EGLint attribs[] = {
- EGL_WIDTH, 0,
- EGL_HEIGHT, 0,
- EGL_DRM_BUFFER_STRIDE_MESA, 0,
- EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
- EGL_NONE
- };
-
- if (visual->object.interface != &wl_visual_interface) {
- /* FIXME: Define a real exception event instead of
- * abusing this one */
- wl_client_post_event(client,
- (struct wl_object *) compositor->wl_display,
- WL_DISPLAY_INVALID_OBJECT, 0);
- fprintf(stderr, "invalid visual in create_buffer\n");
- return;
- }
-
- attribs[1] = width;
- attribs[3] = height;
- attribs[5] = stride / 4;
- image = eglCreateImageKHR(compositor->display,
- EGL_NO_CONTEXT,
- EGL_DRM_BUFFER_MESA,
- (EGLClientBuffer) name, attribs);
- if (image == NULL) {
- /* FIXME: Define a real exception event instead of
- * abusing this one */
- wl_client_post_event(client,
- (struct wl_object *) compositor->wl_display,
- WL_DISPLAY_INVALID_OBJECT, 0);
- fprintf(stderr, "failed to create image for name %d\n", name);
- return;
- }
-
- buffer = wlsc_drm_buffer_create_for_image(compositor, image,
- width, height, visual);
- if (buffer == NULL) {
- eglDestroyImageKHR(compositor->display, image);
- wl_client_post_no_memory(client);
- return;
- }
-
- buffer->buffer.resource.object.id = id;
- buffer->buffer.resource.object.interface = &wl_buffer_interface;
- buffer->buffer.resource.object.implementation = (void (**)(void))
- &buffer_interface;
-
- buffer->buffer.resource.destroy = destroy_buffer;
-
- wl_client_add_resource(client, &buffer->buffer.resource);
-}
-
-const static struct wl_drm_interface drm_interface = {
- drm_authenticate,
- drm_create_buffer
-};
-
-static void
-post_drm_device(struct wl_client *client, struct wl_object *global)
-{
- struct wlsc_drm *drm = container_of(global, struct wlsc_drm, object);
-
- wl_client_post_event(client, global, WL_DRM_DEVICE, drm->filename);
-}
-
-int
-wlsc_drm_init(struct wlsc_compositor *ec, int fd, const char *filename)
-{
- struct wlsc_drm *drm = &ec->drm;
-
- drm->fd = fd;
- drm->filename = strdup(filename);
- if (drm->filename == NULL)
- return -1;
-
- drm->object.interface = &wl_drm_interface;
- drm->object.implementation = (void (**)(void)) &drm_interface;
- wl_display_add_object(ec->wl_display, &drm->object);
- wl_display_add_global(ec->wl_display, &drm->object, post_drm_device);
-
- return 0;
-}
-
-struct wl_buffer *
-wlsc_drm_buffer_create(struct wlsc_compositor *ec, int width, int height,
- struct wl_visual *visual, const void *data)
-{
- struct wlsc_drm_buffer *buffer;
- EGLImageKHR image;
- GLuint texture;
-
- EGLint image_attribs[] = {
- EGL_WIDTH, 0,
- EGL_HEIGHT, 0,
- EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
- EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA,
- EGL_NONE
- };
-
- image_attribs[1] = width;
- image_attribs[3] = height;
-
- image = eglCreateDRMImageMESA(ec->display, image_attribs);
- if (image == NULL)
- return NULL;
-
- buffer = wlsc_drm_buffer_create_for_image(ec, image,
- width, height, visual);
-
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, buffer->image);
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
- GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
-
- glDeleteTextures(1, &texture);
-
- return &buffer->buffer;
-}
diff --git a/compositor/evdev.c b/compositor/evdev.c
deleted file mode 100644
index 6ff7b69..0000000
--- a/compositor/evdev.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. The copyright holders make
- * no representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <linux/input.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "compositor.h"
-
-struct evdev_input {
- struct wlsc_input_device base;
-};
-
-struct evdev_input_device {
- struct evdev_input *master;
- struct wl_event_source *source;
- int tool, new_x, new_y;
- int base_x, base_y;
- int fd;
- int min_x, max_x, min_y, max_y;
-};
-
-static void evdev_input_device_data(int fd, uint32_t mask, void *data)
-{
- struct wlsc_compositor *ec;
- struct evdev_input_device *device = data;
- struct input_event ev[8], *e, *end;
- int len, value, dx, dy, absolute_event;
- int x, y;
- uint32_t time;
-
- /* FIXME: Obviously we need to not hardcode these here, but
- * instead get the values from the output it's associated with. */
- const int screen_width = 1024, screen_height = 600;
-
- ec = (struct wlsc_compositor *)
- device->master->base.input_device.compositor;
- if (!ec->focus)
- return;
-
- dx = 0;
- dy = 0;
- absolute_event = 0;
- x = device->master->base.input_device.x;
- y = device->master->base.input_device.y;
-
- len = read(fd, &ev, sizeof ev);
- if (len < 0 || len % sizeof e[0] != 0) {
- /* FIXME: handle error... reopen device? */;
- return;
- }
-
- e = ev;
- end = (void *) ev + len;
- for (e = ev; e < end; e++) {
- /* Get the signed value, earlier kernels had this as unsigned */
- value = e->value;
- time = e->time.tv_sec * 1000 + e->time.tv_usec / 1000;
-
- switch (e->type) {
- case EV_REL:
- switch (e->code) {
- case REL_X:
- dx += value;
- break;
-
- case REL_Y:
- dy += value;
- break;
- }
- break;
-
- case EV_ABS:
- switch (e->code) {
- case ABS_X:
- absolute_event = device->tool;
- x = (value - device->min_x) * screen_width /
- (device->max_x - device->min_x);
- break;
- case ABS_Y:
- absolute_event = device->tool;
- y = (value - device->min_y) * screen_height /
- (device->max_y - device->min_y);
- break;
- }
- break;
-
- case EV_KEY:
- if (value == 2)
- break;
-
- switch (e->code) {
- case BTN_TOUCH:
- case BTN_TOOL_PEN:
- case BTN_TOOL_RUBBER:
- case BTN_TOOL_BRUSH:
- case BTN_TOOL_PENCIL:
- case BTN_TOOL_AIRBRUSH:
- case BTN_TOOL_FINGER:
- case BTN_TOOL_MOUSE:
- case BTN_TOOL_LENS:
- device->tool = value ? e->code : 0;
- break;
-
- case BTN_LEFT:
- case BTN_RIGHT:
- case BTN_MIDDLE:
- case BTN_SIDE:
- case BTN_EXTRA:
- case BTN_FORWARD:
- case BTN_BACK:
- case BTN_TASK:
- notify_button(&device->master->base.input_device,
- time, e->code, value);
- break;
-
- default:
- notify_key(&device->master->base.input_device,
- time, e->code, value);
- break;
- }
- }
- }
-
- if (dx != 0 || dy != 0)
- notify_motion(&device->master->base.input_device,
- time, x + dx, y + dy);
- if (absolute_event)
- notify_motion(&device->master->base.input_device, time, x, y);
-}
-
-#define TEST_BIT(b, i) (b[(i) / 32] & (1 << (i & 31)))
-
-static struct evdev_input_device *
-evdev_input_device_create(struct evdev_input *master,
- struct wl_display *display, const char *path)
-{
- struct evdev_input_device *device;
- struct wl_event_loop *loop;
- struct input_absinfo absinfo;
- uint32_t ev_bits[EV_MAX];
- uint32_t key_bits[KEY_MAX];
-
- device = malloc(sizeof *device);
- if (device == NULL)
- return NULL;
-
- device->tool = 1;
- device->new_x = 1;
- device->new_y = 1;
- device->master = master;
-
- device->fd = open(path, O_RDONLY);
- if (device->fd < 0) {
- free(device);
- fprintf(stderr, "couldn't create pointer for %s: %m\n", path);
- return NULL;
- }
-
- ioctl(device->fd, EVIOCGBIT(0, EV_MAX), ev_bits);
- if (TEST_BIT(ev_bits, EV_ABS)) {
- ioctl(device->fd, EVIOCGBIT(EV_ABS, EV_MAX), key_bits);
- if (TEST_BIT(key_bits, ABS_X)) {
- ioctl(device->fd, EVIOCGABS(ABS_X), &absinfo);
- device->min_x = absinfo.minimum;
- device->max_x = absinfo.maximum;
- }
- if (TEST_BIT(key_bits, ABS_Y)) {
- ioctl(device->fd, EVIOCGABS(ABS_Y), &absinfo);
- device->min_y = absinfo.minimum;
- device->max_y = absinfo.maximum;
- }
- }
-
- loop = wl_display_get_event_loop(display);
- device->source = wl_event_loop_add_fd(loop, device->fd,
- WL_EVENT_READABLE,
- evdev_input_device_data, device);
- if (device->source == NULL) {
- close(device->fd);
- free(device);
- return NULL;
- }
-
- return device;
-}
-
-void
-evdev_input_add_devices(struct wlsc_compositor *c, struct udev *udev)
-{
- struct evdev_input *input;
- struct udev_enumerate *e;
- struct udev_list_entry *entry;
- struct udev_device *device;
- const char *path;
-
- input = malloc(sizeof *input);
- if (input == NULL)
- return;
-
- memset(input, 0, sizeof *input);
- wlsc_input_device_init(&input->base, c);
-
- e = udev_enumerate_new(udev);
- udev_enumerate_add_match_subsystem(e, "input");
- udev_enumerate_add_match_property(e, "WAYLAND_SEAT", "1");
- udev_enumerate_scan_devices(e);
- udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
- path = udev_list_entry_get_name(entry);
- device = udev_device_new_from_syspath(udev, path);
- evdev_input_device_create(input, c->wl_display,
- udev_device_get_devnode(device));
- }
- udev_enumerate_unref(e);
-
- c->input_device = &input->base.input_device;
-}
diff --git a/compositor/screenshooter.c b/compositor/screenshooter.c
deleted file mode 100644
index 53ed931..0000000
--- a/compositor/screenshooter.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <stdlib.h>
-#include <GLES2/gl2.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-#include "compositor.h"
-#include "screenshooter-server-protocol.h"
-
-struct wl_screenshooter {
- struct wl_object base;
- struct wlsc_compositor *ec;
-};
-
-static void
-screenshooter_shoot(struct wl_client *client, struct wl_screenshooter *shooter)
-{
- struct wlsc_compositor *ec = shooter->ec;
- struct wlsc_output *output;
- char buffer[256];
- GdkPixbuf *pixbuf;
- GError *error = NULL;
- unsigned char *data;
- int i, j;
-
- i = 0;
- wl_list_for_each(output, &ec->output_list, link) {
- snprintf(buffer, sizeof buffer, "wayland-screenshot-%d.png", i++);
- data = malloc(output->width * output->height * 4);
- if (data == NULL) {
- fprintf(stderr, "couldn't allocate image buffer\n");
- continue;
- }
-
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glReadPixels(0, 0, output->width, output->height,
- GL_RGBA, GL_UNSIGNED_BYTE, data);
-
- /* FIXME: We should just use a RGB visual for the frontbuffer. */
- for (j = 3; j < output->width * output->height * 4; j += 4)
- data[j] = 0xff;
-
- pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE,
- 8, output->width, output->height, output->width * 4,
- NULL, NULL);
- gdk_pixbuf_save(pixbuf, buffer, "png", &error, NULL);
- g_object_unref(pixbuf);
- free(data);
- }
-}
-
-struct wl_screenshooter_interface screenshooter_implementation = {
- screenshooter_shoot
-};
-
-void
-screenshooter_create(struct wlsc_compositor *ec)
-{
- struct wl_screenshooter *shooter;
-
- shooter = malloc(sizeof *shooter);
- if (shooter == NULL)
- return;
-
- shooter->base.interface = &wl_screenshooter_interface;
- shooter->base.implementation =
- (void(**)(void)) &screenshooter_implementation;
- shooter->ec = ec;
-
- wl_display_add_object(ec->wl_display, &shooter->base);
- wl_display_add_global(ec->wl_display, &shooter->base, NULL);
-};
diff --git a/compositor/shell.c b/compositor/shell.c
deleted file mode 100644
index a19d3db..0000000
--- a/compositor/shell.c
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. The copyright holders make
- * no representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "wayland-server.h"
-#include "compositor.h"
-
-struct wlsc_move_grab {
- struct wl_grab grab;
- struct wlsc_surface *surface;
- int32_t dx, dy;
-};
-
-static void
-move_grab_motion(struct wl_grab *grab,
- uint32_t time, int32_t x, int32_t y)
-{
- struct wlsc_move_grab *move = (struct wlsc_move_grab *) grab;
- struct wlsc_surface *es = move->surface;
-
- wlsc_surface_damage(es);
- es->x = x + move->dx;
- es->y = y + move->dy;
- wlsc_surface_update_matrix(es);
- wlsc_surface_damage(es);
-}
-
-static void
-move_grab_button(struct wl_grab *grab,
- uint32_t time, int32_t button, int32_t state)
-{
-}
-
-static void
-move_grab_end(struct wl_grab *grab, uint32_t time)
-{
- struct wlsc_surface *es;
- struct wl_input_device *device = grab->input_device;
- int32_t sx, sy;
-
- es = pick_surface(grab->input_device, &sx, &sy);
- wl_input_device_set_pointer_focus(device,
- &es->surface, time,
- device->x, device->y, sx, sy);
- free(grab);
-}
-
-static const struct wl_grab_interface move_grab_interface = {
- move_grab_motion,
- move_grab_button,
- move_grab_end
-};
-
-void
-shell_move(struct wl_client *client, struct wl_shell *shell,
- struct wl_surface *surface,
- struct wl_input_device *device, uint32_t time)
-{
- struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
- struct wlsc_move_grab *move;
-
- /* FIXME: Reject if fullscreen */
-
- move = malloc(sizeof *move);
- if (!move) {
- wl_client_post_no_memory(client);
- return;
- }
-
- move->grab.interface = &move_grab_interface;
- move->dx = es->x - wd->input_device.grab_x;
- move->dy = es->y - wd->input_device.grab_y;
- move->surface = es;
-
- if (wl_input_device_update_grab(&wd->input_device,
- &move->grab, surface, time) < 0)
- return;
-
- wlsc_input_device_set_pointer_image(wd, WLSC_POINTER_DRAGGING);
- wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
-}
-
-struct wlsc_resize_grab {
- struct wl_grab grab;
- uint32_t edges;
- int32_t dx, dy, width, height;
- struct wlsc_surface *surface;
-};
-
-static void
-resize_grab_motion(struct wl_grab *grab,
- uint32_t time, int32_t x, int32_t y)
-{
- struct wlsc_resize_grab *resize = (struct wlsc_resize_grab *) grab;
- struct wl_input_device *device = grab->input_device;
- struct wlsc_compositor *ec =
- (struct wlsc_compositor *) device->compositor;
- struct wl_surface *surface = &resize->surface->surface;
- int32_t width, height;
-
- if (resize->edges & WL_SHELL_RESIZE_LEFT) {
- width = device->grab_x - x + resize->width;
- } else if (resize->edges & WL_SHELL_RESIZE_RIGHT) {
- width = x - device->grab_x + resize->width;
- } else {
- width = resize->width;
- }
-
- if (resize->edges & WL_SHELL_RESIZE_TOP) {
- height = device->grab_y - y + resize->height;
- } else if (resize->edges & WL_SHELL_RESIZE_BOTTOM) {
- height = y - device->grab_y + resize->height;
- } else {
- height = resize->height;
- }
-
- wl_client_post_event(surface->client, &ec->shell.object,
- WL_SHELL_CONFIGURE, time, resize->edges,
- surface, width, height);
-}
-
-static void
-resize_grab_button(struct wl_grab *grab,
- uint32_t time, int32_t button, int32_t state)
-{
-}
-
-static void
-resize_grab_end(struct wl_grab *grab, uint32_t time)
-{
- struct wlsc_surface *es;
- struct wl_input_device *device = grab->input_device;
- int32_t sx, sy;
-
- es = pick_surface(grab->input_device, &sx, &sy);
- wl_input_device_set_pointer_focus(device,
- &es->surface, time,
- device->x, device->y, sx, sy);
- free(grab);
-}
-
-static const struct wl_grab_interface resize_grab_interface = {
- resize_grab_motion,
- resize_grab_button,
- resize_grab_end
-};
-
-void
-shell_resize(struct wl_client *client, struct wl_shell *shell,
- struct wl_surface *surface,
- struct wl_input_device *device, uint32_t time, uint32_t edges)
-{
- struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
- struct wlsc_resize_grab *resize;
- enum wlsc_pointer_type pointer = WLSC_POINTER_LEFT_PTR;
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
-
- /* FIXME: Reject if fullscreen */
-
- resize = malloc(sizeof *resize);
- if (!resize) {
- wl_client_post_no_memory(client);
- return;
- }
-
- resize->grab.interface = &resize_grab_interface;
- resize->edges = edges;
- resize->dx = es->x - wd->input_device.grab_x;
- resize->dy = es->y - wd->input_device.grab_y;
- resize->width = es->width;
- resize->height = es->height;
- resize->surface = es;
-
- if (edges == 0 || edges > 15 ||
- (edges & 3) == 3 || (edges & 12) == 12)
- return;
-
- switch (edges) {
- case WL_SHELL_RESIZE_TOP:
- pointer = WLSC_POINTER_TOP;
- break;
- case WL_SHELL_RESIZE_BOTTOM:
- pointer = WLSC_POINTER_BOTTOM;
- break;
- case WL_SHELL_RESIZE_LEFT:
- pointer = WLSC_POINTER_LEFT;
- break;
- case WL_SHELL_RESIZE_TOP_LEFT:
- pointer = WLSC_POINTER_TOP_LEFT;
- break;
- case WL_SHELL_RESIZE_BOTTOM_LEFT:
- pointer = WLSC_POINTER_BOTTOM_LEFT;
- break;
- case WL_SHELL_RESIZE_RIGHT:
- pointer = WLSC_POINTER_RIGHT;
- break;
- case WL_SHELL_RESIZE_TOP_RIGHT:
- pointer = WLSC_POINTER_TOP_RIGHT;
- break;
- case WL_SHELL_RESIZE_BOTTOM_RIGHT:
- pointer = WLSC_POINTER_BOTTOM_RIGHT;
- break;
- }
-
- if (wl_input_device_update_grab(&wd->input_device,
- &resize->grab, surface, time) < 0)
- return;
-
- wlsc_input_device_set_pointer_image(wd, pointer);
- wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
-}
-
-static void
-destroy_drag(struct wl_resource *resource, struct wl_client *client)
-{
- struct wl_drag *drag =
- container_of(resource, struct wl_drag, resource);
-
- wl_list_remove(&drag->drag_focus_listener.link);
- if (drag->grab.input_device)
- wl_input_device_end_grab(drag->grab.input_device, get_time());
-
- free(drag);
-}
-
-
-static void
-wl_drag_set_pointer_focus(struct wl_drag *drag,
- struct wl_surface *surface, uint32_t time,
- int32_t x, int32_t y, int32_t sx, int32_t sy)
-{
- char **p, **end;
-
- if (drag->drag_focus == surface)
- return;
-
- if (drag->drag_focus &&
- (!surface || drag->drag_focus->client != surface->client))
- wl_client_post_event(drag->drag_focus->client,
- &drag->drag_offer.object,
- WL_DRAG_OFFER_POINTER_FOCUS,
- time, NULL, 0, 0, 0, 0);
-
- if (surface &&
- (!drag->drag_focus ||
- drag->drag_focus->client != surface->client)) {
- wl_client_post_global(surface->client,
- &drag->drag_offer.object);
-
- end = drag->types.data + drag->types.size;
- for (p = drag->types.data; p < end; p++)
- wl_client_post_event(surface->client,
- &drag->drag_offer.object,
- WL_DRAG_OFFER_OFFER, *p);
- }
-
- if (surface) {
- wl_client_post_event(surface->client,
- &drag->drag_offer.object,
- WL_DRAG_OFFER_POINTER_FOCUS,
- time, surface,
- x, y, sx, sy);
-
- }
-
- drag->drag_focus = surface;
- drag->pointer_focus_time = time;
- drag->target = NULL;
-
- wl_list_remove(&drag->drag_focus_listener.link);
- if (surface)
- wl_list_insert(surface->destroy_listener_list.prev,
- &drag->drag_focus_listener.link);
-}
-
-static void
-drag_offer_accept(struct wl_client *client,
- struct wl_drag_offer *offer, uint32_t time, const char *type)
-{
- struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
- char **p, **end;
-
- /* If the client responds to drag pointer_focus or motion
- * events after the pointer has left the surface, we just
- * discard the accept requests. The drag source just won't
- * get the corresponding 'target' events and eventually the
- * next surface/root will start sending events. */
- if (time < drag->pointer_focus_time)
- return;
-
- drag->target = client;
- drag->type = NULL;
- end = drag->types.data + drag->types.size;
- for (p = drag->types.data; p < end; p++)
- if (type && strcmp(*p, type) == 0)
- drag->type = *p;
-
- wl_client_post_event(drag->source->client, &drag->resource.object,
- WL_DRAG_TARGET, drag->type);
-}
-
-static void
-drag_offer_receive(struct wl_client *client,
- struct wl_drag_offer *offer, int fd)
-{
- struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
-
- wl_client_post_event(drag->source->client, &drag->resource.object,
- WL_DRAG_FINISH, fd);
- close(fd);
-}
-
-static void
-drag_offer_reject(struct wl_client *client, struct wl_drag_offer *offer)
-{
- struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
-
- wl_client_post_event(drag->source->client, &drag->resource.object,
- WL_DRAG_REJECT);
-}
-
-static const struct wl_drag_offer_interface drag_offer_interface = {
- drag_offer_accept,
- drag_offer_receive,
- drag_offer_reject
-};
-
-static void
-drag_offer(struct wl_client *client, struct wl_drag *drag, const char *type)
-{
- char **p;
-
- p = wl_array_add(&drag->types, sizeof *p);
- if (p)
- *p = strdup(type);
- if (!p || !*p)
- wl_client_post_no_memory(client);
-}
-
-static void
-drag_grab_motion(struct wl_grab *grab,
- uint32_t time, int32_t x, int32_t y)
-{
- struct wl_drag *drag = container_of(grab, struct wl_drag, grab);
- struct wlsc_surface *es;
- int32_t sx, sy;
-
- es = pick_surface(grab->input_device, &sx, &sy);
- wl_drag_set_pointer_focus(drag, &es->surface, time, x, y, sx, sy);
- if (es)
- wl_client_post_event(es->surface.client,
- &drag->drag_offer.object,
- WL_DRAG_OFFER_MOTION,
- time, x, y, sx, sy);
-}
-
-static void
-drag_grab_button(struct wl_grab *grab,
- uint32_t time, int32_t button, int32_t state)
-{
-}
-
-static void
-drag_grab_end(struct wl_grab *grab, uint32_t time)
-{
- struct wl_drag *drag = container_of(grab, struct wl_drag, grab);
- struct wlsc_surface *es;
- struct wl_input_device *device = grab->input_device;
- int32_t sx, sy;
-
- if (drag->target)
- wl_client_post_event(drag->target,
- &drag->drag_offer.object,
- WL_DRAG_OFFER_DROP);
-
- wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
-
- es = pick_surface(grab->input_device, &sx, &sy);
- wl_input_device_set_pointer_focus(device,
- &es->surface, time,
- device->x, device->y, sx, sy);
-}
-
-static const struct wl_grab_interface drag_grab_interface = {
- drag_grab_motion,
- drag_grab_button,
- drag_grab_end
-};
-
-static void
-drag_activate(struct wl_client *client,
- struct wl_drag *drag,
- struct wl_surface *surface,
- struct wl_input_device *device, uint32_t time)
-{
- struct wl_display *display = wl_client_get_display (client);
- struct wlsc_surface *target;
- int32_t sx, sy;
-
- if (wl_input_device_update_grab(device,
- &drag->grab, surface, time) < 0)
- return;
-
- drag->grab.interface = &drag_grab_interface;
-
- drag->source = surface;
-
- drag->drag_offer.object.interface = &wl_drag_offer_interface;
- drag->drag_offer.object.implementation =
- (void (**)(void)) &drag_offer_interface;
-
- wl_display_add_object(display, &drag->drag_offer.object);
-
- target = pick_surface(device, &sx, &sy);
- wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
- wl_drag_set_pointer_focus(drag, &target->surface, time,
- device->x, device->y, sx, sy);
-}
-
-static void
-drag_destroy(struct wl_client *client, struct wl_drag *drag)
-{
- wl_resource_destroy(&drag->resource, client);
-}
-
-static const struct wl_drag_interface drag_interface = {
- drag_offer,
- drag_activate,
- drag_destroy,
-};
-
-static void
-drag_handle_surface_destroy(struct wl_listener *listener,
- struct wl_surface *surface, uint32_t time)
-{
- struct wl_drag *drag =
- container_of(listener, struct wl_drag, drag_focus_listener);
-
- if (drag->drag_focus == surface)
- wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
-}
-
-static void
-shell_create_drag(struct wl_client *client,
- struct wl_shell *shell, uint32_t id)
-{
- struct wl_drag *drag;
-
- drag = malloc(sizeof *drag);
- if (drag == NULL) {
- wl_client_post_no_memory(client);
- return;
- }
-
- memset(drag, 0, sizeof *drag);
- drag->resource.object.id = id;
- drag->resource.object.interface = &wl_drag_interface;
- drag->resource.object.implementation =
- (void (**)(void)) &drag_interface;
-
- drag->resource.destroy = destroy_drag;
-
- drag->drag_focus_listener.func = drag_handle_surface_destroy;
- wl_list_init(&drag->drag_focus_listener.link);
-
- wl_client_add_resource(client, &drag->resource);
-}
-
-void
-wlsc_selection_set_focus(struct wl_selection *selection,
- struct wl_surface *surface, uint32_t time)
-{
- char **p, **end;
-
- if (selection->selection_focus == surface)
- return;
-
- if (selection->selection_focus != NULL)
- wl_client_post_event(selection->selection_focus->client,
- &selection->selection_offer.object,
- WL_SELECTION_OFFER_KEYBOARD_FOCUS,
- NULL);
-
- if (surface) {
- wl_client_post_global(surface->client,
- &selection->selection_offer.object);
-
- end = selection->types.data + selection->types.size;
- for (p = selection->types.data; p < end; p++)
- wl_client_post_event(surface->client,
- &selection->selection_offer.object,
- WL_SELECTION_OFFER_OFFER, *p);
-
- wl_list_remove(&selection->selection_focus_listener.link);
- wl_list_insert(surface->destroy_listener_list.prev,
- &selection->selection_focus_listener.link);
-
- wl_client_post_event(surface->client,
- &selection->selection_offer.object,
- WL_SELECTION_OFFER_KEYBOARD_FOCUS,
- selection->input_device);
- }
-
- selection->selection_focus = surface;
-
- wl_list_remove(&selection->selection_focus_listener.link);
- if (surface)
- wl_list_insert(surface->destroy_listener_list.prev,
- &selection->selection_focus_listener.link);
-}
-
-static void
-selection_offer_receive(struct wl_client *client,
- struct wl_selection_offer *offer,
- const char *mime_type, int fd)
-{
- struct wl_selection *selection =
- container_of(offer, struct wl_selection, selection_offer);
-
- wl_client_post_event(selection->client,
- &selection->resource.object,
- WL_SELECTION_SEND, mime_type, fd);
- close(fd);
-}
-
-static const struct wl_selection_offer_interface selection_offer_interface = {
- selection_offer_receive
-};
-
-static void
-selection_offer(struct wl_client *client,
- struct wl_selection *selection, const char *type)
-{
- char **p;
-
- p = wl_array_add(&selection->types, sizeof *p);
- if (p)
- *p = strdup(type);
- if (!p || !*p)
- wl_client_post_no_memory(client);
-}
-
-static void
-selection_activate(struct wl_client *client,
- struct wl_selection *selection,
- struct wl_input_device *device, uint32_t time)
-{
- struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
- struct wl_display *display = wl_client_get_display (client);
-
- selection->input_device = device;
-
- selection->selection_offer.object.interface =
- &wl_selection_offer_interface;
- selection->selection_offer.object.implementation =
- (void (**)(void)) &selection_offer_interface;
-
- wl_display_add_object(display, &selection->selection_offer.object);
-
- if (wd->selection) {
- wl_client_post_event(wd->selection->client,
- &wd->selection->resource.object,
- WL_SELECTION_CANCELLED);
- }
- wd->selection = selection;
-
- wlsc_selection_set_focus(selection, device->keyboard_focus, time);
-}
-
-static void
-selection_destroy(struct wl_client *client, struct wl_selection *selection)
-{
- wl_resource_destroy(&selection->resource, client);
-}
-
-static const struct wl_selection_interface selection_interface = {
- selection_offer,
- selection_activate,
- selection_destroy
-};
-
-static void
-destroy_selection(struct wl_resource *resource, struct wl_client *client)
-{
- struct wl_selection *selection =
- container_of(resource, struct wl_selection, resource);
- struct wlsc_input_device *wd =
- (struct wlsc_input_device *) selection->input_device;
-
- if (wd && wd->selection == selection) {
- wd->selection = NULL;
- wlsc_selection_set_focus(selection, NULL, get_time());
- }
-
- wl_list_remove(&selection->selection_focus_listener.link);
- free(selection);
-}
-
-static void
-selection_handle_surface_destroy(struct wl_listener *listener,
- struct wl_surface *surface, uint32_t time)
-{
-}
-
-static void
-shell_create_selection(struct wl_client *client,
- struct wl_shell *shell, uint32_t id)
-{
- struct wl_selection *selection;
-
- selection = malloc(sizeof *selection);
- if (selection == NULL) {
- wl_client_post_no_memory(client);
- return;
- }
-
- memset(selection, 0, sizeof *selection);
- selection->resource.object.id = id;
- selection->resource.object.interface = &wl_selection_interface;
- selection->resource.object.implementation =
- (void (**)(void)) &selection_interface;
-
- selection->client = client;
- selection->resource.destroy = destroy_selection;
- selection->selection_focus = NULL;
-
- selection->selection_focus_listener.func =
- selection_handle_surface_destroy;
- wl_list_init(&selection->selection_focus_listener.link);
-
- wl_client_add_resource(client, &selection->resource);
-}
-
-const static struct wl_shell_interface shell_interface = {
- shell_move,
- shell_resize,
- shell_create_drag,
- shell_create_selection
-};
-
-int
-wlsc_shell_init(struct wlsc_compositor *ec)
-{
- struct wl_shell *shell = &ec->shell;
-
- shell->object.interface = &wl_shell_interface;
- shell->object.implementation = (void (**)(void)) &shell_interface;
- wl_display_add_object(ec->wl_display, &shell->object);
- if (wl_display_add_global(ec->wl_display, &shell->object, NULL))
- return -1;
-
- return 0;
-}
diff --git a/compositor/shm.c b/compositor/shm.c
deleted file mode 100644
index 389eeaa..0000000
--- a/compositor/shm.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright © 2010 Kristian Høgsberg
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include "compositor.h"
-
-struct wlsc_shm_buffer {
- struct wl_buffer buffer;
- int32_t stride;
- void *data;
-};
-
-static void
-destroy_buffer(struct wl_resource *resource, struct wl_client *client)
-{
- struct wlsc_shm_buffer *buffer =
- container_of(resource, struct wlsc_shm_buffer, buffer.resource);
-
- munmap(buffer->data, buffer->stride * buffer->buffer.height);
- free(buffer);
-}
-
-static void
-buffer_destroy(struct wl_client *client, struct wl_buffer *buffer)
-{
- // wl_resource_destroy(&buffer->base, client);
-}
-
-const static struct wl_buffer_interface buffer_interface = {
- buffer_destroy
-};
-
-static void
-shm_buffer_attach(struct wl_buffer *buffer_base, struct wl_surface *surface)
-{
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
- struct wlsc_shm_buffer *buffer =
- (struct wlsc_shm_buffer *) buffer_base;
-
- glBindTexture(GL_TEXTURE_2D, es->texture);
-
- /* Unbind any EGLImage texture that may be bound, so we don't
- * overwrite it.*/
- glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
- 0, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
- buffer->buffer.width, buffer->buffer.height, 0,
- GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer->data);
- es->visual = buffer->buffer.visual;
-}
-
-static void
-shm_buffer_damage(struct wl_buffer *buffer_base,
- struct wl_surface *surface,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- struct wlsc_surface *es = (struct wlsc_surface *) surface;
- struct wlsc_shm_buffer *buffer =
- (struct wlsc_shm_buffer *) buffer_base;
-
- glBindTexture(GL_TEXTURE_2D, es->texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
- buffer->buffer.width, buffer->buffer.height, 0,
- GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer->data);
-
- /* Hmm, should use glTexSubImage2D() here but GLES2 doesn't
- * support any unpack attributes except GL_UNPACK_ALIGNMENT. */
-}
-
-static void
-shm_create_buffer(struct wl_client *client, struct wl_shm *shm,
- uint32_t id, int fd, int32_t width, int32_t height,
- uint32_t stride, struct wl_visual *visual)
-{
- struct wlsc_compositor *compositor =
- container_of((struct wlsc_shm *) shm,
- struct wlsc_compositor, shm);
- struct wlsc_shm_buffer *buffer;
-
- /* FIXME: Define a real exception event instead of abusing the
- * display.invalid_object error */
- if (visual->object.interface != &wl_visual_interface) {
- wl_client_post_event(client,
- (struct wl_object *) compositor->wl_display,
- WL_DISPLAY_INVALID_OBJECT, 0);
- fprintf(stderr, "invalid visual in create_buffer\n");
- close(fd);
- return;
- }
-
- if (width < 0 || height < 0 || stride < width) {
- wl_client_post_event(client,
- (struct wl_object *) compositor->wl_display,
- WL_DISPLAY_INVALID_OBJECT, 0);
- fprintf(stderr,
- "invalid width, height or stride in create_buffer\n");
- close(fd);
- return;
- }
-
- buffer = malloc(sizeof *buffer);
- if (buffer == NULL) {
- close(fd);
- wl_client_post_no_memory(client);
- return;
- }
-
- buffer->buffer.compositor = (struct wl_compositor *) compositor;
- buffer->buffer.width = width;
- buffer->buffer.height = height;
- buffer->buffer.visual = visual;
- buffer->buffer.attach = shm_buffer_attach;
- buffer->buffer.damage = shm_buffer_damage;
- buffer->stride = stride;
- buffer->data =
- mmap(NULL, stride * height, PROT_READ, MAP_SHARED, fd, 0);
- close(fd);
- if (buffer->data == MAP_FAILED) {
- /* FIXME: Define a real exception event instead of
- * abusing this one */
- free(buffer);
- wl_client_post_event(client,
- (struct wl_object *) compositor->wl_display,
- WL_DISPLAY_INVALID_OBJECT, 0);
- fprintf(stderr, "failed to create image for fd %d\n", fd);
- return;
- }
-
- buffer->buffer.resource.object.id = id;
- buffer->buffer.resource.object.interface = &wl_buffer_interface;
- buffer->buffer.resource.object.implementation = (void (**)(void))
- &buffer_interface;
-
- buffer->buffer.resource.destroy = destroy_buffer;
-
- wl_client_add_resource(client, &buffer->buffer.resource);
-}
-
-const static struct wl_shm_interface shm_interface = {
- shm_create_buffer
-};
-
-int
-wlsc_shm_init(struct wlsc_compositor *ec)
-{
- struct wlsc_shm *shm = &ec->shm;
-
- shm->object.interface = &wl_shm_interface;
- shm->object.implementation = (void (**)(void)) &shm_interface;
- wl_display_add_object(ec->wl_display, &shm->object);
- wl_display_add_global(ec->wl_display, &shm->object, NULL);
-
- return 0;
-}
diff --git a/compositor/tty.c b/compositor/tty.c
deleted file mode 100644
index 0de7584..0000000
--- a/compositor/tty.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. The copyright holders make
- * no representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <termios.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <linux/kd.h>
-#include <linux/vt.h>
-#include <sys/ioctl.h>
-
-#include "compositor.h"
-
-struct tty {
- struct wlsc_compositor *compositor;
- int fd;
- struct termios terminal_attributes;
-
- struct wl_event_source *input_source;
- struct wl_event_source *enter_vt_source;
- struct wl_event_source *leave_vt_source;
-};
-
-static void on_enter_vt(int signal_number, void *data)
-{
- struct tty *tty = data;
- int ret;
-
- fprintf(stderr, "enter vt\n");
-
- ioctl(tty->fd, VT_RELDISP, VT_ACKACQ);
- ret = ioctl(tty->fd, KDSETMODE, KD_GRAPHICS);
- if (ret)
- fprintf(stderr, "failed to set KD_GRAPHICS mode on console: %m\n");
-}
-
-static void on_leave_vt(int signal_number, void *data)
-{
- struct tty *tty = data;
- int ret;
-
- ioctl (tty->fd, VT_RELDISP, 1);
- ret = ioctl(tty->fd, KDSETMODE, KD_TEXT);
- if (ret)
- fprintf(stderr,
- "failed to set KD_TEXT mode on console: %m\n");
-}
-
-static void
-on_tty_input(int fd, uint32_t mask, void *data)
-{
- struct tty *tty = data;
-
- /* Ignore input to tty. We get keyboard events from evdev
- */
- tcflush(tty->fd, TCIFLUSH);
-}
-
-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;
-}
-
-void
-tty_destroy(struct tty *tty)
-{
- if(!tty)
- return;
-
- if (ioctl(tty->fd, KDSETMODE, KD_TEXT))
- fprintf(stderr,
- "failed to set KD_TEXT mode on tty: %m\n");
-
- if (tcsetattr(tty->fd, TCSANOW, &tty->terminal_attributes) < 0)
- fprintf(stderr,
- "could not restore terminal to canonical mode\n");
-
- free(tty);
-}