aboutsummaryrefslogtreecommitdiffstats
path: root/clients
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 /clients
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 'clients')
-rw-r--r--clients/.gitignore13
-rw-r--r--clients/Makefile.am82
-rw-r--r--clients/cairo-util.c264
-rw-r--r--clients/cairo-util.h37
-rw-r--r--clients/dnd.c695
-rw-r--r--clients/eventdemo.c396
-rw-r--r--clients/flower.c166
-rw-r--r--clients/gears.c433
-rw-r--r--clients/image.c259
-rw-r--r--clients/resizor.c234
-rw-r--r--clients/screenshot.c79
-rw-r--r--clients/simple-client.c325
-rw-r--r--clients/smoke.c296
-rw-r--r--clients/terminal.c2398
-rw-r--r--clients/view.c268
-rw-r--r--clients/wayland-glib.c105
-rw-r--r--clients/wayland-glib.h32
-rw-r--r--clients/window.c1741
-rw-r--r--clients/window.h245
19 files changed, 0 insertions, 8068 deletions
diff --git a/clients/.gitignore b/clients/.gitignore
deleted file mode 100644
index 8b3c40c..0000000
--- a/clients/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-dnd
-eventdemo
-flower
-gears
-image
-resizor
-screenshooter-client-protocol.h
-screenshooter-protocol.c
-screenshot
-simple-client
-smoke
-terminal
-view
diff --git a/clients/Makefile.am b/clients/Makefile.am
deleted file mode 100644
index 6c92a1c..0000000
--- a/clients/Makefile.am
+++ /dev/null
@@ -1,82 +0,0 @@
-noinst_PROGRAMS = \
- gears \
- flower \
- screenshot \
- terminal \
- image \
- $(poppler_programs) \
- dnd \
- smoke \
- resizor \
- simple-client \
- eventdemo
-
-noinst_LTLIBRARIES = libtoytoolkit.la
-
-AM_CFLAGS = $(GCC_CFLAGS)
-AM_CPPFLAGS = \
- -DDATADIR='"$(datadir)"' \
- -I$(top_builddir)/wayland \
- -I$(top_srcdir)/wayland \
- $(CLIENT_CFLAGS)
-
-libtoytoolkit_la_SOURCES = \
- window.c \
- window.h \
- wayland-glib.c \
- wayland-glib.h \
- cairo-util.c \
- cairo-util.h
-
-toolkit_libs = \
- libtoytoolkit.la \
- $(top_builddir)/wayland/libwayland-client.la \
- $(CLIENT_LIBS) -lrt -lm -lwayland-egl
-
-gears_SOURCES = gears.c
-gears_LDADD = $(toolkit_libs)
-
-flower_SOURCES = flower.c
-flower_LDADD = $(toolkit_libs)
-
-screenshot_SOURCES = screenshot.c screenshooter-protocol.c
-screenshot_LDADD = $(toolkit_libs)
-
-terminal_SOURCES = terminal.c
-terminal_LDADD = $(toolkit_libs) -lutil
-
-image_SOURCES = image.c
-image_LDADD = $(toolkit_libs)
-
-dnd_SOURCES = dnd.c
-dnd_LDADD = $(toolkit_libs)
-
-smoke_SOURCES = smoke.c
-smoke_LDADD = $(toolkit_libs)
-
-resizor_SOURCES = resizor.c
-resizor_LDADD = $(toolkit_libs)
-
-simple_client_SOURCES = simple-client.c
-simple_client_LDADD = \
- $(top_builddir)/wayland/libwayland-client.la -lm \
- $(GLES2_LIBS) \
- -lwayland-egl
-
-eventdemo_SOURCES = eventdemo.c
-eventdemo_LDADD = $(toolkit_libs)
-
-BUILT_SOURCES = \
- screenshooter-client-protocol.h \
- screenshooter-protocol.c
-
-CLEANFILES = $(BUILT_SOURCES)
-
-include $(top_srcdir)/wayland/scanner.mk
-
-if HAVE_POPPLER
-poppler_programs = view
-view_SOURCES = view.c
-view_LDADD = $(toolkit_libs) $(POPPLER_LIBS)
-view_CPPFLAGS = $(AM_CPPFLAGS) $(POPPLER_CFLAGS)
-endif
diff --git a/clients/cairo-util.c b/clients/cairo-util.c
deleted file mode 100644
index 5aa9857..0000000
--- a/clients/cairo-util.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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 <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-#include <cairo.h>
-#include "cairo-util.h"
-
-#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
-
-void
-blur_surface(cairo_surface_t *surface, int margin)
-{
- int32_t width, height, stride, x, y, z, w;
- uint8_t *src, *dst;
- uint32_t *s, *d, a, p;
- int i, j, k, size, half;
- uint32_t kernel[49];
- double f;
-
- size = ARRAY_LENGTH(kernel);
- width = cairo_image_surface_get_width(surface);
- height = cairo_image_surface_get_height(surface);
- stride = cairo_image_surface_get_stride(surface);
- src = cairo_image_surface_get_data(surface);
-
- dst = malloc(height * stride);
-
- half = size / 2;
- a = 0;
- for (i = 0; i < size; i++) {
- f = (i - half);
- kernel[i] = exp(- f * f / ARRAY_LENGTH(kernel)) * 10000;
- a += kernel[i];
- }
-
- for (i = 0; i < height; i++) {
- s = (uint32_t *) (src + i * stride);
- d = (uint32_t *) (dst + i * stride);
- for (j = 0; j < width; j++) {
- if (margin < j && j < width - margin) {
- d[j] = s[j];
- continue;
- }
-
- x = 0;
- y = 0;
- z = 0;
- w = 0;
- for (k = 0; k < size; k++) {
- if (j - half + k < 0 || j - half + k >= width)
- continue;
- p = s[j - half + k];
-
- x += (p >> 24) * kernel[k];
- y += ((p >> 16) & 0xff) * kernel[k];
- z += ((p >> 8) & 0xff) * kernel[k];
- w += (p & 0xff) * kernel[k];
- }
- d[j] = (x / a << 24) | (y / a << 16) | (z / a << 8) | w / a;
- }
- }
-
- for (i = 0; i < height; i++) {
- s = (uint32_t *) (dst + i * stride);
- d = (uint32_t *) (src + i * stride);
- for (j = 0; j < width; j++) {
- if (margin <= i && i < height - margin) {
- d[j] = s[j];
- continue;
- }
-
- x = 0;
- y = 0;
- z = 0;
- w = 0;
- for (k = 0; k < size; k++) {
- if (i - half + k < 0 || i - half + k >= height)
- continue;
- s = (uint32_t *) (dst + (i - half + k) * stride);
- p = s[j];
-
- x += (p >> 24) * kernel[k];
- y += ((p >> 16) & 0xff) * kernel[k];
- z += ((p >> 8) & 0xff) * kernel[k];
- w += (p & 0xff) * kernel[k];
- }
- d[j] = (x / a << 24) | (y / a << 16) | (z / a << 8) | w / a;
- }
- }
-
- free(dst);
- cairo_surface_mark_dirty(surface);
-}
-
-void
-tile_mask(cairo_t *cr, cairo_surface_t *surface,
- int x, int y, int width, int height, int margin, int top_margin)
-{
- cairo_pattern_t *pattern;
- cairo_matrix_t matrix;
- int i, fx, fy, vmargin;
-
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- pattern = cairo_pattern_create_for_surface (surface);
-
- for (i = 0; i < 4; i++) {
- fx = i & 1;
- fy = i >> 1;
-
- cairo_matrix_init_translate(&matrix,
- -x + fx * (128 - width),
- -y + fy * (128 - height));
- cairo_pattern_set_matrix(pattern, &matrix);
-
- if (fy)
- vmargin = margin;
- else
- vmargin = top_margin;
-
- cairo_reset_clip(cr);
- cairo_rectangle(cr,
- x + fx * (width - margin),
- y + fy * (height - vmargin),
- margin, vmargin);
- cairo_clip (cr);
- cairo_mask(cr, pattern);
- }
-
- /* Top strecth */
- cairo_matrix_init_translate(&matrix, 64, 0);
- cairo_matrix_scale(&matrix, 64.0 / (width - 2 * margin), 1);
- cairo_matrix_translate(&matrix, -x - width / 2, -y);
- cairo_pattern_set_matrix(pattern, &matrix);
- cairo_rectangle(cr, x + margin, y, width - 2 * margin, margin);
-
- cairo_reset_clip(cr);
- cairo_rectangle(cr,
- x + margin,
- y,
- width - 2 * margin, margin);
- cairo_clip (cr);
- cairo_mask(cr, pattern);
-
- /* Bottom strecth */
- cairo_matrix_translate(&matrix, 0, -height + 128);
- cairo_pattern_set_matrix(pattern, &matrix);
-
- cairo_reset_clip(cr);
- cairo_rectangle(cr, x + margin, y + height - margin,
- width - 2 * margin, margin);
- cairo_clip (cr);
- cairo_mask(cr, pattern);
-
- /* Left strecth */
- cairo_matrix_init_translate(&matrix, 0, 64);
- cairo_matrix_scale(&matrix, 1, 64.0 / (height - 2 * margin));
- cairo_matrix_translate(&matrix, -x, -y - height / 2);
- cairo_pattern_set_matrix(pattern, &matrix);
- cairo_reset_clip(cr);
- cairo_rectangle(cr, x, y + margin, margin, height - 2 * margin);
- cairo_clip (cr);
- cairo_mask(cr, pattern);
-
- /* Right strecth */
- cairo_matrix_translate(&matrix, -width + 128, 0);
- cairo_pattern_set_matrix(pattern, &matrix);
- cairo_rectangle(cr, x + width - margin, y + margin,
- margin, height - 2 * margin);
- cairo_reset_clip(cr);
- cairo_clip (cr);
- cairo_mask(cr, pattern);
-
- cairo_pattern_destroy(pattern);
- cairo_reset_clip(cr);
-}
-
-void
-tile_source(cairo_t *cr, cairo_surface_t *surface,
- int x, int y, int width, int height, int margin, int top_margin)
-{
- cairo_pattern_t *pattern;
- cairo_matrix_t matrix;
- int i, fx, fy, vmargin;
-
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- pattern = cairo_pattern_create_for_surface (surface);
- cairo_set_source(cr, pattern);
- cairo_pattern_destroy(pattern);
-
- for (i = 0; i < 4; i++) {
- fx = i & 1;
- fy = i >> 1;
-
- cairo_matrix_init_translate(&matrix,
- -x + fx * (128 - width),
- -y + fy * (128 - height));
- cairo_pattern_set_matrix(pattern, &matrix);
-
- if (fy)
- vmargin = margin;
- else
- vmargin = top_margin;
-
- cairo_rectangle(cr,
- x + fx * (width - margin),
- y + fy * (height - vmargin),
- margin, vmargin);
- cairo_fill(cr);
- }
-
- /* Top strecth */
- cairo_matrix_init_translate(&matrix, 64, 0);
- cairo_matrix_scale(&matrix, 64.0 / (width - 2 * margin), 1);
- cairo_matrix_translate(&matrix, -x - width / 2, -y);
- cairo_pattern_set_matrix(pattern, &matrix);
- cairo_rectangle(cr, x + margin, y, width - 2 * margin, top_margin);
- cairo_fill(cr);
-
- /* Bottom strecth */
- cairo_matrix_translate(&matrix, 0, -height + 128);
- cairo_pattern_set_matrix(pattern, &matrix);
- cairo_rectangle(cr, x + margin, y + height - margin,
- width - 2 * margin, margin);
- cairo_fill(cr);
-
- /* Left strecth */
- cairo_matrix_init_translate(&matrix, 0, 64);
- cairo_matrix_scale(&matrix, 1, 64.0 / (height - margin - top_margin));
- cairo_matrix_translate(&matrix, -x, -y - height / 2);
- cairo_pattern_set_matrix(pattern, &matrix);
- cairo_rectangle(cr, x, y + top_margin,
- margin, height - margin - top_margin);
- cairo_fill(cr);
-
- /* Right strecth */
- cairo_matrix_translate(&matrix, -width + 128, 0);
- cairo_pattern_set_matrix(pattern, &matrix);
- cairo_rectangle(cr, x + width - margin, y + top_margin,
- margin, height - margin - top_margin);
- cairo_fill(cr);
-}
diff --git a/clients/cairo-util.h b/clients/cairo-util.h
deleted file mode 100644
index f28ac5f..0000000
--- a/clients/cairo-util.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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.
- */
-
-#ifndef _CAIRO_UTIL_H
-#define _CAIRO_UTIL_H
-
-void
-blur_surface(cairo_surface_t *surface, int margin);
-
-void
-tile_mask(cairo_t *cr, cairo_surface_t *surface,
- int x, int y, int width, int height, int margin, int top_margin);
-
-void
-tile_source(cairo_t *cr, cairo_surface_t *surface,
- int x, int y, int width, int height, int margin, int top_margin);
-
-#endif
diff --git a/clients/dnd.c b/clients/dnd.c
deleted file mode 100644
index 1625ffd..0000000
--- a/clients/dnd.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
- * Copyright © 2010 Kristian Høgsberg
- *
- * 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-#include <sys/time.h>
-#include <cairo.h>
-#include <glib.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-#include "wayland-client.h"
-#include "wayland-glib.h"
-
-#include "window.h"
-
-struct dnd {
- struct window *window;
- struct display *display;
- uint32_t key;
- struct item *items[16];
-};
-
-struct dnd_drag {
- cairo_surface_t *translucent;
- cairo_surface_t *opaque;
- int hotspot_x, hotspot_y;
- struct dnd *dnd;
- struct input *input;
- uint32_t time;
- struct item *item;
- int x_offset, y_offset;
- const char *mime_type;
-};
-
-struct dnd_offer {
- int refcount;
- struct dnd *dnd;
- struct wl_array types;
- const char *drag_type;
- uint32_t tag;
- int x, y;
-};
-
-struct item {
- cairo_surface_t *surface;
- int seed;
- int x, y;
-};
-
-struct dnd_flower_message {
- int seed, x_offset, y_offset;
-};
-
-
-static const int item_width = 64;
-static const int item_height = 64;
-static const int item_padding = 16;
-
-static struct item *
-item_create(struct display *display, int x, int y, int seed)
-{
- struct item *item;
- struct timeval tv;
-
- item = malloc(sizeof *item);
- if (item == NULL)
- return NULL;
-
-
- gettimeofday(&tv, NULL);
- item->seed = seed ? seed : tv.tv_usec;
- srandom(item->seed);
-
- const int petal_count = 3 + random() % 5;
- const double r1 = 20 + random() % 10;
- const double r2 = 5 + random() % 12;
- const double u = (10 + random() % 90) / 100.0;
- const double v = (random() % 90) / 100.0;
-
- cairo_t *cr;
- int i;
- double t, dt = 2 * M_PI / (petal_count * 2);
- double x1, y1, x2, y2, x3, y3;
- struct rectangle rect;
-
-
- rect.width = item_width;
- rect.height = item_height;
- item->surface = display_create_surface(display, &rect);
-
- item->x = x;
- item->y = y;
-
- cr = cairo_create(item->surface);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 0, 0, 0, 0);
- cairo_paint(cr);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_translate(cr, item_width / 2, item_height / 2);
- t = random();
- cairo_move_to(cr, cos(t) * r1, sin(t) * r1);
- for (i = 0; i < petal_count; i++, t += dt * 2) {
- x1 = cos(t) * r1;
- y1 = sin(t) * r1;
- x2 = cos(t + dt) * r2;
- y2 = sin(t + dt) * r2;
- x3 = cos(t + 2 * dt) * r1;
- y3 = sin(t + 2 * dt) * r1;
-
- cairo_curve_to(cr,
- x1 - y1 * u, y1 + x1 * u,
- x2 + y2 * v, y2 - x2 * v,
- x2, y2);
-
- cairo_curve_to(cr,
- x2 - y2 * v, y2 + x2 * v,
- x3 + y3 * u, y3 - x3 * u,
- x3, y3);
- }
-
- cairo_close_path(cr);
-
- cairo_set_source_rgba(cr,
- 0.5 + (random() % 50) / 49.0,
- 0.5 + (random() % 50) / 49.0,
- 0.5 + (random() % 50) / 49.0,
- 0.5 + (random() % 100) / 99.0);
-
- cairo_fill_preserve(cr);
-
- cairo_set_line_width(cr, 1);
- cairo_set_source_rgba(cr,
- 0.5 + (random() % 50) / 49.0,
- 0.5 + (random() % 50) / 49.0,
- 0.5 + (random() % 50) / 49.0,
- 0.5 + (random() % 100) / 99.0);
- cairo_stroke(cr);
-
- cairo_destroy(cr);
-
- return item;
-}
-
-static void
-dnd_draw(struct dnd *dnd)
-{
- struct rectangle allocation;
- cairo_t *cr;
- cairo_surface_t *surface;
- int i;
-
- window_draw(dnd->window);
-
- surface = window_get_surface(dnd->window);
- cr = cairo_create(surface);
- window_get_child_allocation(dnd->window, &allocation);
- cairo_rectangle(cr, allocation.x, allocation.y,
- allocation.width, allocation.height);
- cairo_clip(cr);
- cairo_push_group(cr);
-
- cairo_translate(cr, allocation.x, allocation.y);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
- cairo_paint(cr);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) {
- if (!dnd->items[i])
- continue;
- cairo_set_source_surface(cr, dnd->items[i]->surface,
- dnd->items[i]->x, dnd->items[i]->y);
- cairo_paint(cr);
- }
-
- cairo_pop_group_to_source(cr);
- cairo_paint(cr);
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
- window_flush(dnd->window);
-}
-
-static void
-redraw_handler(struct window *window, void *data)
-{
- struct dnd *dnd = data;
-
- dnd_draw(dnd);
-}
-
-static void
-keyboard_focus_handler(struct window *window,
- struct input *device, void *data)
-{
- struct dnd *dnd = data;
-
- window_schedule_redraw(dnd->window);
-}
-
-static void
-dnd_offer_destroy(struct dnd_offer *dnd_offer)
-{
- dnd_offer->refcount--;
- if (dnd_offer->refcount == 0) {
- wl_array_release(&dnd_offer->types);
- free(dnd_offer);
- }
-}
-
-static int
-dnd_add_item(struct dnd *dnd, struct item *item)
-{
- int i;
-
- for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) {
- if (dnd->items[i] == 0) {
- dnd->items[i] = item;
- return i;
- }
- }
- return -1;
-}
-
-static struct item *
-dnd_get_item(struct dnd *dnd, int32_t x, int32_t y)
-{
- struct item *item;
- struct rectangle allocation;
- int i;
-
- window_get_child_allocation(dnd->window, &allocation);
-
- x -= allocation.x;
- y -= allocation.y;
-
- for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) {
- item = dnd->items[i];
- if (item &&
- item->x <= x && x < item->x + item_width &&
- item->y <= y && y < item->y + item_height)
- return item;
- }
-
- return NULL;
-}
-
-static void
-drag_target(void *data,
- struct wl_drag *drag, const char *mime_type)
-{
- struct dnd_drag *dnd_drag = data;
- struct dnd *dnd = dnd_drag->dnd;
- struct wl_input_device *device;
- cairo_surface_t *surface;
- struct wl_buffer *buffer;
-
- fprintf(stderr, "target %s\n", mime_type);
- device = input_get_input_device(dnd_drag->input);
- dnd_drag->mime_type = mime_type;
- if (mime_type)
- surface = dnd_drag->opaque;
- else
- surface = dnd_drag->translucent;
-
- buffer = display_get_buffer_for_surface(dnd->display, surface);
- wl_input_device_attach(device, dnd_drag->time, buffer,
- dnd_drag->hotspot_x, dnd_drag->hotspot_y);
-}
-
-static void
-drag_finish(void *data, struct wl_drag *drag, int fd)
-{
- struct dnd_drag *dnd_drag = data;
-
- if (!dnd_drag->mime_type) {
- dnd_add_item(dnd_drag->dnd, dnd_drag->item);
- window_schedule_redraw(dnd_drag->dnd->window);
- return;
- }
-
- struct dnd_flower_message dnd_flower_message;
-
-
- dnd_flower_message.seed = dnd_drag->item->seed;
-
- dnd_flower_message.x_offset = dnd_drag->x_offset;
- dnd_flower_message.y_offset = dnd_drag->y_offset;
-
- fprintf(stderr, "got 'finish', fd %d, sending dnd_flower_message\n", fd);
-
- write(fd, &dnd_flower_message, sizeof dnd_flower_message);
- close(fd);
-
- /* The 'finish' event marks the end of the session on the drag
- * source side and we need to clean up the drag object created
- * and the local state. */
- wl_drag_destroy(drag);
-
- /* Destroy the item that has been dragged out */
- cairo_surface_destroy(dnd_drag->item->surface);
- free(dnd_drag->item);
-
- cairo_surface_destroy(dnd_drag->translucent);
- cairo_surface_destroy(dnd_drag->opaque);
- free(dnd_drag);
-}
-
-static void
-drag_reject(void *data, struct wl_drag *drag)
-{
- struct dnd_drag *dnd_drag = data;
-
- dnd_add_item(dnd_drag->dnd, dnd_drag->item);
- window_schedule_redraw(dnd_drag->dnd->window);
-}
-
-static const struct wl_drag_listener drag_listener = {
- drag_target,
- drag_finish,
- drag_reject
-};
-
-static void
-drag_offer_offer(void *data,
- struct wl_drag_offer *offer, const char *type)
-{
- struct dnd_offer *dnd_offer = data;
- char **p;
-
- p = wl_array_add(&dnd_offer->types, sizeof *p);
- if (p)
- *p = strdup(type);
-}
-
-static void
-drag_offer_pointer_focus(void *data,
- struct wl_drag_offer *offer,
- uint32_t time, struct wl_surface *surface,
- int32_t x, int32_t y,
- int32_t surface_x, int32_t surface_y)
-{
- struct dnd_offer *dnd_offer = data;
- struct window *window;
- char **p, **end;
-
- /* The last event in a dnd session is pointer_focus with a
- * NULL surface, whether or not we get the drop event. We
- * need to clean up the dnd_offer proxy and whatever state we
- * allocated. */
- if (!surface) {
- fprintf(stderr, "pointer focus NULL, session over\n");
- wl_drag_offer_destroy(offer);
- dnd_offer_destroy(dnd_offer);
- return;
- }
-
- fprintf(stderr, "drag pointer focus %p\n", surface);
- fprintf(stderr, "offered types:\n");
- end = dnd_offer->types.data + dnd_offer->types.size;
- for (p = dnd_offer->types.data; p < end; p++)
- fprintf(stderr, "\%s\n", *p);
-
- window = wl_surface_get_user_data(surface);
- dnd_offer->dnd = window_get_user_data(window);
-
- if (!dnd_get_item(dnd_offer->dnd, surface_x, surface_y)) {
- wl_drag_offer_accept(offer, time, "application/x-wayland-dnd-flower");
- dnd_offer->drag_type = "application/x-wayland-dnd-flower";
- dnd_offer->x = surface_x;
- dnd_offer->y = surface_y;
- } else {
- wl_drag_offer_accept(offer, time, NULL);
- dnd_offer->drag_type = NULL;
- }
-}
-
-static void
-drag_offer_motion(void *data,
- struct wl_drag_offer *offer, uint32_t time,
- int32_t x, int32_t y, int32_t surface_x, int32_t surface_y)
-{
- struct dnd_offer *dnd_offer = data;
-
- if (!dnd_get_item(dnd_offer->dnd, surface_x, surface_y)) {
- fprintf(stderr, "drag offer motion %d, %d, accepting\n",
- surface_x, surface_y);
- wl_drag_offer_accept(offer, time, "application/x-wayland-dnd-flower");
- dnd_offer->drag_type = "application/x-wayland-dnd-flower";
- dnd_offer->x = surface_x;
- dnd_offer->y = surface_y;
- } else {
- fprintf(stderr, "drag offer motion %d, %d, declining\n",
- surface_x, surface_y);
- wl_drag_offer_accept(offer, time, NULL);
- dnd_offer->drag_type = NULL;
- }
-}
-
-static gboolean
-drop_io_func(GIOChannel *source, GIOCondition condition, gpointer data)
-{
- struct dnd_offer *dnd_offer = data;
- struct dnd *dnd = dnd_offer->dnd;
- struct dnd_flower_message dnd_flower_message;
- int fd;
- unsigned int len;
- struct item *item;
-
- fd = g_io_channel_unix_get_fd(source);
- len = read(fd, &dnd_flower_message, sizeof dnd_flower_message);
- fprintf(stderr, "read %d bytes\n", len);
-
- close(fd);
- g_source_remove(dnd_offer->tag);
-
- g_io_channel_unref(source);
-
- item = item_create(dnd->display,
- dnd_offer->x - dnd_flower_message.x_offset - 26,
- dnd_offer->y - dnd_flower_message.y_offset - 66,
- dnd_flower_message.seed);
-
- dnd_add_item(dnd, item);
- window_schedule_redraw(dnd->window);
-
- dnd_offer_destroy(dnd_offer);
-
- return TRUE;
-}
-
-static void
-drag_offer_drop(void *data, struct wl_drag_offer *offer)
-{
- struct dnd_offer *dnd_offer = data;
- GIOChannel *channel;
- int p[2];
-
- if (!dnd_offer->drag_type) {
- fprintf(stderr, "got 'drop', but no target\n");
- wl_drag_offer_reject(offer);
- return;
- }
-
- fprintf(stderr, "got 'drop', sending write end of pipe\n");
-
- dnd_offer->refcount++;
- pipe(p);
- wl_drag_offer_receive(offer, p[1]);
- close(p[1]);
-
- channel = g_io_channel_unix_new(p[0]);
- dnd_offer->tag = g_io_add_watch(channel, G_IO_IN,
- drop_io_func, dnd_offer);
-}
-
-static const struct wl_drag_offer_listener drag_offer_listener = {
- drag_offer_offer,
- drag_offer_pointer_focus,
- drag_offer_motion,
- drag_offer_drop,
-};
-
-static void
-global_handler(struct display *display,
- const char *interface, uint32_t id, uint32_t version)
-{
- struct wl_drag_offer *offer;
- struct dnd_offer *dnd_offer;
-
- if (strcmp(interface, "drag_offer") != 0)
- return;
-
- offer = wl_drag_offer_create(display_get_display(display), id);
-
- dnd_offer = malloc(sizeof *dnd_offer);
- if (dnd_offer == NULL)
- return;
-
- dnd_offer->refcount = 1;
-
- wl_drag_offer_add_listener(offer, &drag_offer_listener, dnd_offer);
- wl_array_init(&dnd_offer->types);
-}
-
-static cairo_surface_t *
-create_drag_cursor(struct dnd_drag *dnd_drag,
- struct item *item, int32_t x, int32_t y, double opacity)
-{
- struct dnd *dnd = dnd_drag->dnd;
- cairo_surface_t *surface, *pointer;
- int32_t pointer_width, pointer_height, hotspot_x, hotspot_y;
- struct rectangle rectangle;
- cairo_pattern_t *pattern;
- cairo_t *cr;
-
- pointer = display_get_pointer_surface(dnd->display,
- POINTER_DRAGGING,
- &pointer_width,
- &pointer_height,
- &hotspot_x,
- &hotspot_y);
-
- rectangle.width = item_width + 2 * pointer_width;
- rectangle.height = item_height + 2 * pointer_height;
- surface = display_create_surface(dnd->display, &rectangle);
-
- cr = cairo_create(surface);
- cairo_translate(cr, pointer_width, pointer_height);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 0, 0, 0, 0);
- cairo_paint(cr);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_set_source_surface(cr, item->surface, 0, 0);
- pattern = cairo_pattern_create_rgba(0, 0, 0, opacity);
- cairo_mask(cr, pattern);
- cairo_pattern_destroy(pattern);
-
- cairo_set_source_surface(cr, pointer,
- x - item->x - hotspot_x,
- y - item->y - hotspot_y);
- cairo_surface_destroy(pointer);
- cairo_paint(cr);
- /* FIXME: more cairo-gl brokeness */
- display_flush_cairo_device(dnd->display);
- cairo_destroy(cr);
-
- dnd_drag->hotspot_x = pointer_width + x - item->x;
- dnd_drag->hotspot_y = pointer_height + y - item->y;
-
- return surface;
-}
-
-static void
-dnd_button_handler(struct window *window,
- struct input *input, uint32_t time,
- int button, int state, void *data)
-{
- struct dnd *dnd = data;
- int32_t x, y;
- struct item *item;
- struct rectangle allocation;
- struct dnd_drag *dnd_drag;
- struct wl_drag *drag;
- int i;
-
- window_get_child_allocation(dnd->window, &allocation);
- input_get_position(input, &x, &y);
- item = dnd_get_item(dnd, x, y);
- x -= allocation.x;
- y -= allocation.y;
-
- if (item && state == 1) {
- fprintf(stderr, "start drag, item %p\n", item);
-
- dnd_drag = malloc(sizeof *dnd_drag);
- dnd_drag->dnd = dnd;
- dnd_drag->input = input;
- dnd_drag->time = time;
- dnd_drag->item = item;
- dnd_drag->x_offset = x - item->x;
- dnd_drag->y_offset = y - item->y;
-
- for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) {
- if (item == dnd->items[i]){
- dnd->items[i] = 0;
- break;
- }
- }
-
- dnd_drag->opaque =
- create_drag_cursor(dnd_drag, item, x, y, 1);
- dnd_drag->translucent =
- create_drag_cursor(dnd_drag, item, x, y, 0.2);
-
- drag = window_create_drag(window);
- wl_drag_offer(drag, "application/x-wayland-dnd-flower");
- window_activate_drag(drag, window, input, time);
- wl_drag_add_listener(drag, &drag_listener, dnd_drag);
- window_schedule_redraw(dnd->window);
- }
-}
-
-static int
-dnd_motion_handler(struct window *window,
- struct input *input, uint32_t time,
- int32_t x, int32_t y,
- int32_t sx, int32_t sy, void *data)
-{
- struct dnd *dnd = data;
- struct item *item;
-
- item = dnd_get_item(dnd, sx, sy);
-
- if (item)
- return POINTER_HAND1;
- else
- return POINTER_LEFT_PTR;
-}
-
-static struct dnd *
-dnd_create(struct display *display)
-{
- struct dnd *dnd;
- int i, x, y;
- int32_t width, height;
-
- dnd = malloc(sizeof *dnd);
- if (dnd == NULL)
- return dnd;
- memset(dnd, 0, sizeof *dnd);
-
- dnd->window = window_create(display, 400, 400);
- window_set_title(dnd->window, "Wayland Drag and Drop Demo");
-
- dnd->display = display;
- dnd->key = 100;
-
- for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) {
- x = (i % 4) * (item_width + item_padding) + item_padding;
- y = (i / 4) * (item_height + item_padding) + item_padding;
- if ((i ^ (i >> 2)) & 1)
- dnd->items[i] = item_create(display, x, y, 0);
- else
- dnd->items[i] = NULL;
- }
-
- window_set_user_data(dnd->window, dnd);
- window_set_redraw_handler(dnd->window, redraw_handler);
- window_set_keyboard_focus_handler(dnd->window,
- keyboard_focus_handler);
- window_set_button_handler(dnd->window,
- dnd_button_handler);
-
- window_set_motion_handler(dnd->window,
- dnd_motion_handler);
-
- width = 4 * (item_width + item_padding) + item_padding;
- height = 4 * (item_height + item_padding) + item_padding;
- window_set_child_size(dnd->window, width, height);
-
- dnd_draw(dnd);
-
- return dnd;
-}
-
-static const GOptionEntry option_entries[] = {
- { NULL }
-};
-
-int
-main(int argc, char *argv[])
-{
- struct display *d;
-
- d = display_create(&argc, &argv, option_entries);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
- display_set_global_handler(d, global_handler);
-
- dnd_create(d);
-
- display_run(d);
-
- return 0;
-}
diff --git a/clients/eventdemo.c b/clients/eventdemo.c
deleted file mode 100644
index 8de620a..0000000
--- a/clients/eventdemo.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright © 2011 Tim Wiederhake
- *
- * 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.
- */
-
-/**
- * \file eventdemo.c
- * \brief Demonstrate the use of Wayland's toytoolkit.
- *
- * Heavily commented demo program that can report all events that are
- * dispatched to the window. For other functionality, eg. opengl/egl,
- * drag and drop, etc. have a look at the other demos.
- * \author Tim Wiederhake
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <cairo.h>
-#include <glib.h>
-
-#include "window.h"
-
-/** window title */
-static char *title = "EventDemo";
-
-/** window width */
-static int width = 500;
-
-/** window height */
-static int height = 400;
-
-/** set if window has no borders */
-static int noborder = 0;
-
-/** if non-zero, maximum window width */
-static int width_max = 0;
-
-/** if non-zero, maximum window height */
-static int height_max = 0;
-
-/** set to log redrawing */
-static int log_redraw = 0;
-
-/** set to log resizing */
-static int log_resize = 0;
-
-/** set to log keyboard focus */
-static int log_focus = 0;
-
-/** set to log key events */
-static int log_key = 0;
-
-/** set to log button events */
-static int log_button = 0;
-
-/** set to log motion events */
-static int log_motion = 0;
-
-/**
- * \struct eventdemo
- * \brief Holds all data the program needs per window
- *
- * In this demo the struct holds the position of a
- * red rectangle that is drawn in the window's area.
- */
-struct eventdemo {
- struct window *window;
- struct display *display;
-
- unsigned int x, y, w, h;
-};
-
-/**
- * \brief Redraws the window
- *
- * Draws a red rectangle as demonstration of per-window data.
- */
-static void
-eventdemo_draw(struct eventdemo *e) {
- if (log_redraw)
- printf("redraw\n");
-
- cairo_surface_t *surface;
- cairo_t *cr;
- struct rectangle rect;
-
- window_draw(e->window);
- window_get_child_allocation(e->window, &rect);
- surface = window_get_surface(e->window);
-
- cr = cairo_create(surface);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
-
- cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height);
- cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
- cairo_fill(cr);
-
- cairo_rectangle(cr, e->x, e->y, e->w, e->h);
- cairo_set_source_rgba(cr, 1.0, 0, 0, 1);
- cairo_fill(cr);
-
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
- window_flush(e->window);
-}
-
-/**
- * \brief CALLBACK function, Wayland requests the window to redraw.
- * \param window window to be redrawn
- * \param data user data associated to the window
- */
-static void
-redraw_handler(struct window *window, void *data)
-{
- struct eventdemo *e = data;
- eventdemo_draw(e);
-}
-
-/**
- * \brief CALLBACK function, Wayland requests the window to resize.
- * \param window window to be resized
- * \param width desired width
- * \param height desired height
- * \param data user data associated to the window
- */
-
-static void
-resize_handler(struct window *window,
- int32_t width, int32_t height, void *data)
-{
- struct eventdemo *e = data;
- if (log_resize)
- printf("resize width: %d, height: %d\n", width, height);
-
- /* if a maximum width is set, constrain to it */
- if (width_max && width_max < width)
- width = width_max;
-
- /* if a maximum height is set, constrain to it */
- if (height_max && height_max < height)
- height = height_max;
-
- /* set the new window dimensions */
- window_set_child_size(e->window, width, height);
-
- /* inform Wayland that the window needs to be redrawn */
- window_schedule_redraw(e->window);
-}
-
-/**
- * \brief CALLBACK function, Wayland informs about keyboard focus change
- * \param window window
- * \param device device that caused the focus change
- * \param data user data associated to the window
- */
-static void
-keyboard_focus_handler(struct window *window,
- struct input *device, void *data)
-{
- int32_t x, y;
- struct eventdemo *e = data;
-
- if(log_focus) {
- if(device) {
- input_get_position(device, &x, &y);
- printf("focus x: %d, y: %d\n", x, y);
- } else {
- printf("focus lost\n");
- }
- }
-
- window_schedule_redraw(e->window);
-}
-
-/**
- * \brief CALLBACK function, Wayland informs about key event
- * \param window window
- * \param key keycode
- * \param unicode associated character
- * \param state pressed or released
- * \param modifiers modifiers: ctrl, alt, meta etc.
- * \param data user data associated to the window
- */
-static void
-key_handler(struct window *window, struct input *input, uint32_t time,
- uint32_t key, uint32_t unicode, uint32_t state, void *data)
-{
- uint32_t modifiers = input_get_modifiers(input);
-
- if(!log_key)
- return;
-
- printf("key key: %d, unicode: %d, state: %d, modifiers: %d\n",
- key, unicode, state, modifiers);
-}
-
-/**
- * \brief CALLBACK function, Wayland informs about button event
- * \param window window
- * \param input input device that caused the button event
- * \param time time the event happend
- * \param button button
- * \param state pressed or released
- * \param data user data associated to the window
- */
-static void
-button_handler(struct window *window, struct input *input, uint32_t time,
- int button, int state, void *data)
-{
- int32_t x, y;
-
- if (!log_button)
- return;
-
- input_get_position(input, &x, &y);
- printf("button time: %d, button: %d, state: %d, x: %d, y: %d\n",
- time, button, state, x, y);
-}
-
-/**
- * \brief CALLBACK function, Waylands informs about pointer motion
- * \param window window
- * \param input input device that caused the motion event
- * \param time time the event happend
- * \param x absolute x position
- * \param y absolute y position
- * \param sx x position relative to the window
- * \param sy y position relative to the window
- * \param data user data associated to the window
- *
- * Demonstrates the use of different cursors
- */
-static int
-motion_handler(struct window *window, struct input *input, uint32_t time,
- int32_t x, int32_t y, int32_t sx, int32_t sy, void *data)
-{
- struct eventdemo *e = data;
-
- if (log_motion) {
- printf("motion time: %d, x: %d, y: %d, sx: %d, sy: %d\n",
- time, x, y, sx, sy);
- }
-
- if(sx > e->x && sx < e->x + e->w)
- if(sy > e->y && sy < e->y + e->h)
- return POINTER_HAND1;
-
- return POINTER_LEFT_PTR;
-}
-
-/**
- * \brief Create and initialise a new eventdemo window.
- * \param d associated display
- */
-static struct eventdemo *
-eventdemo_create(struct display *d)
-{
- struct eventdemo *e;
-
- e = malloc(sizeof (struct eventdemo));
- if(e == NULL)
- return NULL;
-
- /* Creates a new window with the given title, width and height.
- * To set the size of the window for a given usable areas width
- * and height in a window decoration agnostic way use:
- * window_set_child_size(struct window *window,
- * int32_t width, int32_t height);
- */
- e->window = window_create(d, width, height);
- window_set_title(e->window, title);
- e->display = d;
-
- /* The eventdemo window draws a red rectangle as a demonstration
- * of per-window data. The dimensions of that rectangle are set
- * here.
- */
- e->x = width * 1.0 / 4.0;
- e->w = width * 2.0 / 4.0;
- e->y = height * 1.0 / 4.0;
- e->h = height * 2.0 / 4.0;
-
- /* Connect the user data to the window */
- window_set_user_data(e->window, e);
-
- /* Set the callback redraw handler for the window */
- window_set_redraw_handler(e->window, redraw_handler);
-
- /* Set the callback resize handler for the window */
- window_set_resize_handler(e->window, resize_handler);
-
- /* Set the callback focus handler for the window */
- window_set_keyboard_focus_handler(e->window,
- keyboard_focus_handler);
-
- /* Set the callback key handler for the window */
- window_set_key_handler(e->window, key_handler);
-
- /* Set the callback button handler for the window */
- window_set_button_handler(e->window, button_handler);
-
- /* Set the callback motion handler for the window */
- window_set_motion_handler(e->window, motion_handler);
-
- /* Demonstrate how to create a borderless window.
- Move windows with META + left mouse button.
- */
- if(noborder) {
- window_set_decoration(e->window, 0);
- }
-
- /* Initial drawing of the window */
- eventdemo_draw(e);
-
- return e;
-}
-/**
- * \brief command line options for eventdemo
- *
- * see
- * http://developer.gimp.org/api/2.0/glib/glib-Commandline-option-parser.html
- */
-static const GOptionEntry option_entries[] = {
- {"title", 0, 0, G_OPTION_ARG_STRING,
- &title, "Set the window title to TITLE", "TITLE"},
- {"width", 'w', 0, G_OPTION_ARG_INT,
- &width, "Set the window's width to W", "W"},
- {"height", 'h', 0, G_OPTION_ARG_INT,
- &height, "Set the window's height to H", "H"},
- {"maxwidth", 0, 0, G_OPTION_ARG_INT,
- &width_max, "Set the window's maximum width to W", "W"},
- {"maxheight", 0, 0, G_OPTION_ARG_INT,
- &height_max, "Set the window's maximum height to H", "H"},
- {"noborder", 'b', 0, G_OPTION_ARG_NONE,
- &noborder, "Don't draw window borders", 0},
- {"log-redraw", 0, 0, G_OPTION_ARG_NONE,
- &log_redraw, "Log redraw events to stdout", 0},
- {"log-resize", 0, 0, G_OPTION_ARG_NONE,
- &log_resize, "Log resize events to stdout", 0},
- {"log-focus", 0, 0, G_OPTION_ARG_NONE,
- &log_focus, "Log keyboard focus events to stdout", 0},
- {"log-key", 0, 0, G_OPTION_ARG_NONE,
- &log_key, "Log key events to stdout", 0},
- {"log-button", 0, 0, G_OPTION_ARG_NONE,
- &log_button, "Log button events to stdout", 0},
- {"log-motion", 0, 0, G_OPTION_ARG_NONE,
- &log_motion, "Log motion events to stdout", 0},
- {NULL}
-};
-
-/**
- * \brief Connects to the display, creates the window and hands over
- * to the main loop.
- */
-int
-main(int argc, char *argv[])
-{
- struct display *d;
- struct eventdemo *e;
-
- /* Connect to the display and have the arguments parsed */
- d = display_create(&argc, &argv, option_entries);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
- /* Create new eventdemo window */
- e = eventdemo_create(d);
- if (e == NULL) {
- fprintf(stderr, "failed to create eventdemo: %m\n");
- return -1;
- }
-
- display_run(d);
-
- return 0;
-}
diff --git a/clients/flower.c b/clients/flower.c
deleted file mode 100644
index a87e20f..0000000
--- a/clients/flower.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-#include <time.h>
-#include <cairo.h>
-#include <sys/time.h>
-#include <glib.h>
-
-#include "wayland-client.h"
-#include "wayland-glib.h"
-#include "window.h"
-
-static void
-set_random_color(cairo_t *cr)
-{
- cairo_set_source_rgba(cr,
- 0.5 + (random() % 50) / 49.0,
- 0.5 + (random() % 50) / 49.0,
- 0.5 + (random() % 50) / 49.0,
- 0.5 + (random() % 100) / 99.0);
-}
-
-
-static void
-draw_stuff(cairo_surface_t *surface, int width, int height)
-{
- const int petal_count = 3 + random() % 5;
- const double r1 = 60 + random() % 35;
- const double r2 = 20 + random() % 40;
- const double u = (10 + random() % 90) / 100.0;
- const double v = (random() % 90) / 100.0;
-
- cairo_t *cr;
- int i;
- double t, dt = 2 * M_PI / (petal_count * 2);
- double x1, y1, x2, y2, x3, y3;
-
- cr = cairo_create(surface);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 0, 0, 0, 0);
- cairo_paint(cr);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_translate(cr, width / 2, height / 2);
- cairo_move_to(cr, cos(0) * r1, sin(0) * r1);
- for (t = 0, i = 0; i < petal_count; i++, t += dt * 2) {
- x1 = cos(t) * r1;
- y1 = sin(t) * r1;
- x2 = cos(t + dt) * r2;
- y2 = sin(t + dt) * r2;
- x3 = cos(t + 2 * dt) * r1;
- y3 = sin(t + 2 * dt) * r1;
-
- cairo_curve_to(cr,
- x1 - y1 * u, y1 + x1 * u,
- x2 + y2 * v, y2 - x2 * v,
- x2, y2);
-
- cairo_curve_to(cr,
- x2 - y2 * v, y2 + x2 * v,
- x3 + y3 * u, y3 - x3 * u,
- x3, y3);
- }
-
- cairo_close_path(cr);
- set_random_color(cr);
- cairo_fill_preserve(cr);
- set_random_color(cr);
- cairo_stroke(cr);
-
- cairo_destroy(cr);
-}
-
-static int
-motion_handler(struct window *window,
- struct input *input, uint32_t time,
- int32_t x, int32_t y,
- int32_t sx, int32_t sy, void *data)
-{
- return POINTER_HAND1;
-}
-
-static void
-button_handler(struct window *window,
- struct input *input, uint32_t time,
- int button, int state, void *data)
-{
- if (state)
- window_move(window, input, time);
-}
-
-struct flower {
- struct display *display;
- struct window *window;
- int width, height;
-};
-
-int main(int argc, char *argv[])
-{
- cairo_surface_t *s;
- struct flower flower;
- struct display *d;
- struct timeval tv;
-
- d = display_create(&argc, &argv, NULL);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
- gettimeofday(&tv, NULL);
- srandom(tv.tv_usec);
-
- flower.width = 200;
- flower.height = 200;
- flower.display = d;
- flower.window = window_create(d, flower.width, flower.height);
-
- window_set_title(flower.window, "flower");
- window_set_decoration(flower.window, 0);
- window_draw(flower.window);
- s = window_get_surface(flower.window);
- if (s == NULL || cairo_surface_status (s) != CAIRO_STATUS_SUCCESS) {
- fprintf(stderr, "failed to create cairo egl surface\n");
- return -1;
- }
-
- draw_stuff(s, flower.width, flower.height);
- cairo_surface_flush(s);
- cairo_surface_destroy(s);
- window_flush(flower.window);
-
- window_set_motion_handler(flower.window, motion_handler);
- window_set_button_handler(flower.window, button_handler);
- window_set_user_data(flower.window, &flower);
- display_run(d);
-
- return 0;
-}
diff --git a/clients/gears.c b/clients/gears.c
deleted file mode 100644
index 8496abb..0000000
--- a/clients/gears.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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 "config.h"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-#include <time.h>
-#include <cairo.h>
-#include <glib.h>
-
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-#include <GL/gl.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include "wayland-util.h"
-#include "wayland-client.h"
-#include "wayland-glib.h"
-
-#include "window.h"
-
-struct gears {
- struct window *window;
-
- struct display *d;
-
- EGLDisplay display;
- EGLContext context;
- GLfloat angle;
- cairo_surface_t *cairo_surface;
-
- GLint gear_list[3];
- GLuint fbo, color_rbo[2], depth_rbo;
- cairo_surface_t *surface[2];
- int current;
-};
-
-struct gear_template {
- GLfloat material[4];
- GLfloat inner_radius;
- GLfloat outer_radius;
- GLfloat width;
- GLint teeth;
- GLfloat tooth_depth;
-};
-
-const static struct gear_template gear_templates[] = {
- { { 0.8, 0.1, 0.0, 1.0 }, 1.0, 4.0, 1.0, 20, 0.7 },
- { { 0.0, 0.8, 0.2, 1.0 }, 0.5, 2.0, 2.0, 10, 0.7 },
- { { 0.2, 0.2, 1.0, 1.0 }, 1.3, 2.0, 0.5, 10, 0.7 },
-};
-
-static GLfloat light_pos[4] = {5.0, 5.0, 10.0, 0.0};
-
-static void die(const char *msg)
-{
- fprintf(stderr, "%s", msg);
- exit(EXIT_FAILURE);
-}
-
-static void
-make_gear(const struct gear_template *t)
-{
- GLint i;
- GLfloat r0, r1, r2;
- GLfloat angle, da;
- GLfloat u, v, len;
-
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, t->material);
-
- r0 = t->inner_radius;
- r1 = t->outer_radius - t->tooth_depth / 2.0;
- r2 = t->outer_radius + t->tooth_depth / 2.0;
-
- da = 2.0 * M_PI / t->teeth / 4.0;
-
- glShadeModel(GL_FLAT);
-
- glNormal3f(0.0, 0.0, 1.0);
-
- /* draw front face */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= t->teeth; i++) {
- angle = i * 2.0 * M_PI / t->teeth;
- glVertex3f(r0 * cos(angle), r0 * sin(angle), t->width * 0.5);
- glVertex3f(r1 * cos(angle), r1 * sin(angle), t->width * 0.5);
- if (i < t->teeth) {
- glVertex3f(r0 * cos(angle), r0 * sin(angle), t->width * 0.5);
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), t->width * 0.5);
- }
- }
- glEnd();
-
- /* draw front sides of teeth */
- glBegin(GL_QUADS);
- da = 2.0 * M_PI / t->teeth / 4.0;
- for (i = 0; i < t->teeth; i++) {
- angle = i * 2.0 * M_PI / t->teeth;
-
- glVertex3f(r1 * cos(angle), r1 * sin(angle), t->width * 0.5);
- glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), t->width * 0.5);
- glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), t->width * 0.5);
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), t->width * 0.5);
- }
- glEnd();
-
- glNormal3f(0.0, 0.0, -1.0);
-
- /* draw back face */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= t->teeth; i++) {
- angle = i * 2.0 * M_PI / t->teeth;
- glVertex3f(r1 * cos(angle), r1 * sin(angle), -t->width * 0.5);
- glVertex3f(r0 * cos(angle), r0 * sin(angle), -t->width * 0.5);
- if (i < t->teeth) {
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -t->width * 0.5);
- glVertex3f(r0 * cos(angle), r0 * sin(angle), -t->width * 0.5);
- }
- }
- glEnd();
-
- /* draw back sides of teeth */
- glBegin(GL_QUADS);
- da = 2.0 * M_PI / t->teeth / 4.0;
- for (i = 0; i < t->teeth; i++) {
- angle = i * 2.0 * M_PI / t->teeth;
-
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -t->width * 0.5);
- glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -t->width * 0.5);
- glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -t->width * 0.5);
- glVertex3f(r1 * cos(angle), r1 * sin(angle), -t->width * 0.5);
- }
- glEnd();
-
- /* draw outward faces of teeth */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i < t->teeth; i++) {
- angle = i * 2.0 * M_PI / t->teeth;
-
- glVertex3f(r1 * cos(angle), r1 * sin(angle), t->width * 0.5);
- glVertex3f(r1 * cos(angle), r1 * sin(angle), -t->width * 0.5);
- u = r2 * cos(angle + da) - r1 * cos(angle);
- v = r2 * sin(angle + da) - r1 * sin(angle);
- len = sqrt(u * u + v * v);
- u /= len;
- v /= len;
- glNormal3f(v, -u, 0.0);
- glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), t->width * 0.5);
- glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -t->width * 0.5);
- glNormal3f(cos(angle), sin(angle), 0.0);
- glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), t->width * 0.5);
- glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -t->width * 0.5);
- u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
- v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
- glNormal3f(v, -u, 0.0);
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), t->width * 0.5);
- glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -t->width * 0.5);
- glNormal3f(cos(angle), sin(angle), 0.0);
- }
-
- glVertex3f(r1 * cos(0), r1 * sin(0), t->width * 0.5);
- glVertex3f(r1 * cos(0), r1 * sin(0), -t->width * 0.5);
-
- glEnd();
-
- glShadeModel(GL_SMOOTH);
-
- /* draw inside radius cylinder */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= t->teeth; i++) {
- angle = i * 2.0 * M_PI / t->teeth;
- glNormal3f(-cos(angle), -sin(angle), 0.0);
- glVertex3f(r0 * cos(angle), r0 * sin(angle), -t->width * 0.5);
- glVertex3f(r0 * cos(angle), r0 * sin(angle), t->width * 0.5);
- }
- glEnd();
-}
-
-static void
-allocate_buffer(struct gears *gears)
-{
- EGLImageKHR image;
- struct rectangle allocation;
-
- window_draw(gears->window);
-
- gears->surface[gears->current] = window_get_surface(gears->window);
-#ifdef HAVE_CAIRO_EGL
- image = display_get_image_for_egl_image_surface(gears->display,
- gears->surface[gears->current]);
-#else /* XXX: hack to make Wayland compile, even if this example doesn't run */
- die("gears cannot allocate buffer: it was compiled without cairo-gl\n");
- return;
-#endif
- if (!eglMakeCurrent(gears->display, NULL, NULL, gears->context))
- die("faile to make context current\n");
-
- glBindRenderbuffer(GL_RENDERBUFFER_EXT,
- gears->color_rbo[gears->current]);
- glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);
-
- glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo);
- window_get_child_allocation(gears->window, &allocation);
- glRenderbufferStorage(GL_RENDERBUFFER_EXT,
- GL_DEPTH_COMPONENT,
- allocation.width + 20 + 32,
- allocation.height + 60 + 32);
-}
-
-static void
-draw_gears(struct gears *gears)
-{
- GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
- struct rectangle allocation;
-
- if (gears->surface[gears->current] == NULL)
- allocate_buffer(gears);
-
- glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_RENDERBUFFER_EXT,
- gears->color_rbo[gears->current]);
-
- window_get_child_allocation(gears->window, &allocation);
- glViewport(allocation.x, allocation.y,
- allocation.width, allocation.height);
- glScissor(allocation.x, allocation.y,
- allocation.width, allocation.height);
-
- glEnable(GL_SCISSOR_TEST);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glPushMatrix();
-
- glTranslatef(0.0, 0.0, -50);
-
- glRotatef(view_rotx, 1.0, 0.0, 0.0);
- glRotatef(view_roty, 0.0, 1.0, 0.0);
- glRotatef(view_rotz, 0.0, 0.0, 1.0);
-
- glPushMatrix();
- glTranslatef(-3.0, -2.0, 0.0);
- glRotatef(gears->angle, 0.0, 0.0, 1.0);
- glCallList(gears->gear_list[0]);
- glPopMatrix();
-
- glPushMatrix();
- glTranslatef(3.1, -2.0, 0.0);
- glRotatef(-2.0 * gears->angle - 9.0, 0.0, 0.0, 1.0);
- glCallList(gears->gear_list[1]);
- glPopMatrix();
-
- glPushMatrix();
- glTranslatef(-3.1, 4.2, 0.0);
- glRotatef(-2.0 * gears->angle - 25.0, 0.0, 0.0, 1.0);
- glCallList(gears->gear_list[2]);
- glPopMatrix();
-
- glPopMatrix();
-
- glFlush();
-
- window_set_surface(gears->window, gears->surface[gears->current]);
- window_flush(gears->window);
-}
-
-static void
-resize_handler(struct window *window,
- int32_t width, int32_t height, void *data)
-{
- struct gears *gears = data;
-
- cairo_surface_destroy(gears->surface[0]);
- gears->surface[0] = NULL;
- cairo_surface_destroy(gears->surface[1]);
- gears->surface[1] = NULL;
-
- /* Constrain child size to be square and at least 300x300 */
- if (width > height)
- height = width;
- else
- width = height;
- if (width < 300) {
- width = 300;
- height = 300;
- }
-
- window_set_child_size(gears->window, width, height);
-}
-
-static void
-keyboard_focus_handler(struct window *window,
- struct input *device, void *data)
-{
- struct gears *gears = data;
- struct rectangle allocation;
-
- window_get_child_allocation(gears->window, &allocation);
- resize_handler(window, allocation.width, allocation.height, gears);
-}
-
-static void
-redraw_handler(struct window *window, void *data)
-{
- struct gears *gears = data;
-
- draw_gears(gears);
-}
-
-static void
-frame_callback(void *data, uint32_t time)
-{
- struct gears *gears = data;
-
- gears->current = 1 - gears->current;
-
- gears->angle = (GLfloat) (time % 8192) * 360 / 8192.0;
-
- window_schedule_redraw(gears->window);
- wl_display_frame_callback(display_get_display(gears->d),
- frame_callback, gears);
-}
-
-static struct gears *
-gears_create(struct display *display)
-{
- const int width = 450, height = 500;
- struct gears *gears;
- int i;
-
- gears = malloc(sizeof *gears);
- memset(gears, 0, sizeof *gears);
- gears->d = display;
- gears->window = window_create(display, width, height);
- window_set_title(gears->window, "Wayland Gears");
-
- gears->display = display_get_egl_display(gears->d);
- if (gears->display == NULL)
- die("failed to create egl display\n");
-
- eglBindAPI(EGL_OPENGL_API);
-
- gears->context = eglCreateContext(gears->display,
- NULL, EGL_NO_CONTEXT, NULL);
- if (gears->context == NULL)
- die("failed to create context\n");
-
- if (!eglMakeCurrent(gears->display, NULL, NULL, gears->context))
- die("faile to make context current\n");
-
- glGenFramebuffers(1, &gears->fbo);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, gears->fbo);
-
- glGenRenderbuffers(2, gears->color_rbo);
- glGenRenderbuffers(1, &gears->depth_rbo);
- glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo);
- glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT,
- GL_DEPTH_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT,
- gears->depth_rbo);
- for (i = 0; i < 3; i++) {
- gears->gear_list[i] = glGenLists(1);
- glNewList(gears->gear_list[i], GL_COMPILE);
- make_gear(&gear_templates[i]);
- glEndList();
- }
-
- glEnable(GL_NORMALIZE);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 200.0);
- glMatrixMode(GL_MODELVIEW);
-
- glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
- glEnable(GL_CULL_FACE);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_DEPTH_TEST);
- glClearColor(0, 0, 0, 0.92);
-
- window_set_user_data(gears->window, gears);
- window_set_resize_handler(gears->window, resize_handler);
- window_set_keyboard_focus_handler(gears->window, keyboard_focus_handler);
- window_set_redraw_handler(gears->window, redraw_handler);
-
- draw_gears(gears);
- wl_display_frame_callback(display_get_display(gears->d),
- frame_callback, gears);
-
- return gears;
-}
-
-int main(int argc, char *argv[])
-{
- struct display *d;
-
- d = display_create(&argc, &argv, NULL);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
- gears_create(d);
- display_run(d);
-
- return 0;
-}
diff --git a/clients/image.c b/clients/image.c
deleted file mode 100644
index 3eada1e..0000000
--- a/clients/image.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- * Copyright © 2009 Chris Wilson
- *
- * 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-#include <time.h>
-#include <cairo.h>
-#include <glib.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-#include "wayland-client.h"
-#include "wayland-glib.h"
-
-#include "window.h"
-
-struct image {
- struct window *window;
- struct display *display;
- uint32_t key;
- gchar *filename;
-};
-
-static void
-set_source_pixbuf(cairo_t *cr,
- const GdkPixbuf *pixbuf,
- double src_x,
- double src_y,
- double src_width,
- double src_height)
-{
- gint width = gdk_pixbuf_get_width (pixbuf);
- gint height = gdk_pixbuf_get_height (pixbuf);
- guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
- int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
- int cairo_stride;
- guchar *cairo_pixels;
- cairo_format_t format;
- cairo_surface_t *surface;
- int j;
-
- if (n_channels == 3)
- format = CAIRO_FORMAT_RGB24;
- else
- format = CAIRO_FORMAT_ARGB32;
-
- surface = cairo_image_surface_create(format, width, height);
- if (cairo_surface_status(surface)) {
- cairo_set_source_surface(cr, surface, 0, 0);
- return;
- }
-
- cairo_stride = cairo_image_surface_get_stride(surface);
- cairo_pixels = cairo_image_surface_get_data(surface);
-
- for (j = height; j; j--) {
- guchar *p = gdk_pixels;
- guchar *q = cairo_pixels;
-
- if (n_channels == 3) {
- guchar *end = p + 3 * width;
-
- while (p < end) {
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- q[0] = p[2];
- q[1] = p[1];
- q[2] = p[0];
-#else
- q[1] = p[0];
- q[2] = p[1];
- q[3] = p[2];
-#endif
- p += 3;
- q += 4;
- }
- } else {
- guchar *end = p + 4 * width;
- guint t1,t2,t3;
-
-#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END
-
- while (p < end) {
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- MULT(q[0], p[2], p[3], t1);
- MULT(q[1], p[1], p[3], t2);
- MULT(q[2], p[0], p[3], t3);
- q[3] = p[3];
-#else
- q[0] = p[3];
- MULT(q[1], p[0], p[3], t1);
- MULT(q[2], p[1], p[3], t2);
- MULT(q[3], p[2], p[3], t3);
-#endif
-
- p += 4;
- q += 4;
- }
-#undef MULT
- }
-
- gdk_pixels += gdk_rowstride;
- cairo_pixels += cairo_stride;
- }
- cairo_surface_mark_dirty(surface);
-
- cairo_set_source_surface(cr, surface,
- src_x + .5 * (src_width - width),
- src_y + .5 * (src_height - height));
- cairo_surface_destroy(surface);
-}
-
-static void
-image_draw(struct image *image)
-{
- struct rectangle allocation;
- GdkPixbuf *pb;
- cairo_t *cr;
- cairo_surface_t *surface;
-
- window_draw(image->window);
-
- window_get_child_allocation(image->window, &allocation);
-
- pb = gdk_pixbuf_new_from_file_at_size(image->filename,
- allocation.width,
- allocation.height,
- NULL);
- if (pb == NULL)
- return;
-
- surface = window_get_surface(image->window);
- cr = cairo_create(surface);
- window_get_child_allocation(image->window, &allocation);
- cairo_rectangle(cr, allocation.x, allocation.y,
- allocation.width, allocation.height);
- cairo_clip(cr);
- cairo_push_group(cr);
- cairo_translate(cr, allocation.x, allocation.y);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 0, 0, 0, 1);
- cairo_paint(cr);
- set_source_pixbuf(cr, pb,
- 0, 0,
- allocation.width, allocation.height);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_paint(cr);
-
- g_object_unref(pb);
-
- cairo_pop_group_to_source(cr);
- cairo_paint(cr);
- cairo_destroy(cr);
-
- window_flush(image->window);
- cairo_surface_destroy(surface);
-}
-
-static void
-redraw_handler(struct window *window, void *data)
-{
- struct image *image = data;
-
- image_draw(image);
-}
-
-static void
-keyboard_focus_handler(struct window *window,
- struct input *device, void *data)
-{
- struct image *image = data;
-
- window_schedule_redraw(image->window);
-}
-
-static struct image *
-image_create(struct display *display, uint32_t key, const char *filename)
-{
- struct image *image;
- gchar *basename;
- gchar *title;
-
- image = malloc(sizeof *image);
- if (image == NULL)
- return image;
- memset(image, 0, sizeof *image);
-
- basename = g_path_get_basename(filename);
- title = g_strdup_printf("Wayland Image - %s", basename);
- g_free(basename);
-
- image->filename = g_strdup(filename);
-
- image->window = window_create(display, 500, 400);
- window_set_title(image->window, title);
- image->display = display;
-
- /* FIXME: Window uses key 1 for moves, need some kind of
- * allocation scheme here. Or maybe just a real toolkit. */
- image->key = key + 100;
-
- window_set_user_data(image->window, image);
- window_set_redraw_handler(image->window, redraw_handler);
- window_set_keyboard_focus_handler(image->window,
- keyboard_focus_handler);
-
- image_draw(image);
-
- return image;
-}
-
-static const GOptionEntry option_entries[] = {
- { NULL }
-};
-
-int
-main(int argc, char *argv[])
-{
- struct display *d;
- int i;
-
- d = display_create(&argc, &argv, option_entries);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
- for (i = 1; i < argc; i++)
- image_create (d, i, argv[i]);
-
- display_run(d);
-
- return 0;
-}
diff --git a/clients/resizor.c b/clients/resizor.c
deleted file mode 100644
index 0ac02f6..0000000
--- a/clients/resizor.c
+++ /dev/null
@@ -1,234 +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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <cairo.h>
-#include <math.h>
-
-#include "wayland-util.h"
-#include "wayland-client.h"
-#include "wayland-glib.h"
-
-#include "window.h"
-
-#include <X11/keysym.h>
-
-struct resizor {
- struct display *display;
- struct window *window;
- struct window *menu;
- int32_t width;
-
- struct {
- double current;
- double target;
- double previous;
- } height;
-};
-
-static void
-frame_callback(void *data, uint32_t time)
-{
- struct resizor *resizor = data;
- double force, height;
-
- height = resizor->height.current;
- force = (resizor->height.target - height) / 10.0 +
- (resizor->height.previous - height);
-
- resizor->height.current =
- height + (height - resizor->height.previous) + force;
- resizor->height.previous = height;
-
- if (resizor->height.current >= 400) {
- resizor->height.current = 400;
- resizor->height.previous = 400;
- }
-
- if (resizor->height.current <= 200) {
- resizor->height.current = 200;
- resizor->height.previous = 200;
- }
-
- window_set_child_size(resizor->window, resizor->width, height + 0.5);
-
- window_schedule_redraw(resizor->window);
-}
-
-static void
-resizor_draw(struct resizor *resizor)
-{
- cairo_surface_t *surface;
- cairo_t *cr;
- struct rectangle allocation;
-
- window_draw(resizor->window);
-
- window_get_child_allocation(resizor->window, &allocation);
-
- surface = window_get_surface(resizor->window);
-
- cr = cairo_create(surface);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_rectangle(cr,
- allocation.x,
- allocation.y,
- allocation.width,
- allocation.height);
- cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
- cairo_fill(cr);
- cairo_destroy(cr);
-
- cairo_surface_destroy(surface);
-
- window_flush(resizor->window);
-
- if (fabs(resizor->height.previous - resizor->height.target) > 0.1) {
- wl_display_frame_callback(display_get_display(resizor->display),
- frame_callback, resizor);
- }
-}
-
-static void
-redraw_handler(struct window *window, void *data)
-{
- struct resizor *resizor = data;
-
- resizor_draw(resizor);
-}
-
-static void
-keyboard_focus_handler(struct window *window,
- struct input *device, void *data)
-{
- struct resizor *resizor = data;
-
- window_schedule_redraw(resizor->window);
-}
-
-static void
-key_handler(struct window *window, struct input *input, uint32_t time,
- uint32_t key, uint32_t sym, uint32_t state, void *data)
-{
- struct resizor *resizor = data;
-
- if (state == 0)
- return;
-
- switch (sym) {
- case XK_Down:
- resizor->height.target = 400;
- frame_callback(resizor, 0);
- break;
- case XK_Up:
- resizor->height.target = 200;
- frame_callback(resizor, 0);
- break;
- }
-}
-
-static void
-show_menu(struct resizor *resizor, struct input *input)
-{
- int32_t x, y, width = 200, height = 200;
-
- input_get_position(input, &x, &y);
- resizor->menu = window_create_transient(resizor->display,
- resizor->window,
- x - 10, y - 10, width, height);
-
- window_draw(resizor->menu);
- window_flush(resizor->menu);
-}
-
-static void
-button_handler(struct window *window,
- struct input *input, uint32_t time,
- int button, int state, void *data)
-{
- struct resizor *resizor = data;
-
- switch (button) {
- case 274:
- if (state)
- show_menu(resizor, input);
- else
- window_destroy(resizor->menu);
- break;
- }
-}
-
-static struct resizor *
-resizor_create(struct display *display)
-{
- struct resizor *resizor;
- int32_t height;
-
- resizor = malloc(sizeof *resizor);
- if (resizor == NULL)
- return resizor;
- memset(resizor, 0, sizeof *resizor);
-
- resizor->window = window_create(display, 500, 400);
- window_set_title(resizor->window, "Wayland Resizor");
- resizor->display = display;
-
- window_set_key_handler(resizor->window, key_handler);
- window_set_user_data(resizor->window, resizor);
- window_set_redraw_handler(resizor->window, redraw_handler);
- window_set_keyboard_focus_handler(resizor->window,
- keyboard_focus_handler);
-
- resizor->width = 300;
- resizor->height.current = 400;
- resizor->height.previous = resizor->height.current;
- resizor->height.target = resizor->height.current;
- height = resizor->height.current + 0.5;
-
- window_set_child_size(resizor->window, resizor->width, height);
- window_set_button_handler(resizor->window, button_handler);
-
- resizor_draw(resizor);
-
- return resizor;
-}
-
-int
-main(int argc, char *argv[])
-{
- struct display *d;
-
- d = display_create(&argc, &argv, NULL);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
- resizor_create (d);
-
- display_run(d);
-
- return 0;
-}
diff --git a/clients/screenshot.c b/clients/screenshot.c
deleted file mode 100644
index 8f44460..0000000
--- a/clients/screenshot.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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 <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <glib.h>
-
-#include "wayland-client.h"
-#include "wayland-glib.h"
-#include "screenshooter-client-protocol.h"
-
-/* The screenshooter is a good example of a custom object exposed by
- * the compositor and serves as a test bed for implementing client
- * side marshalling outside libwayland.so */
-
-static void
-handle_global(struct wl_display *display, uint32_t id,
- const char *interface, uint32_t version, void *data)
-{
- struct wl_screenshooter **screenshooter = data;
-
- if (strcmp(interface, "screenshooter") == 0)
- *screenshooter = wl_screenshooter_create(display, id);
-}
-
-int main(int argc, char *argv[])
-{
- struct wl_display *display;
- GMainLoop *loop;
- GSource *source;
- struct wl_screenshooter *screenshooter;
-
- display = wl_display_connect(NULL);
- if (display == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
- screenshooter = NULL;
- wl_display_add_global_listener(display, handle_global, &screenshooter);
- wl_display_iterate(display, WL_DISPLAY_READABLE);
- if (screenshooter == NULL) {
- fprintf(stderr, "display doesn't support screenshooter\n");
- return -1;
- }
-
- loop = g_main_loop_new(NULL, FALSE);
- source = wl_glib_source_new(display);
- g_source_attach(source, NULL);
-
- wl_screenshooter_shoot(screenshooter);
-
- g_idle_add((GSourceFunc) g_main_loop_quit, loop);
- g_main_loop_run(loop);
-
- return 0;
-}
diff --git a/clients/simple-client.c b/clients/simple-client.c
deleted file mode 100644
index 89718df..0000000
--- a/clients/simple-client.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright © 2011 Benjamin Franzke
- *
- * 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 <stdbool.h>
-#include <math.h>
-#include <assert.h>
-
-#include <wayland-client.h>
-#include <wayland-egl.h>
-
-#include <GLES2/gl2.h>
-#include <EGL/egl.h>
-
-struct display {
- struct wl_display *display;
- struct wl_egl_display *native;
- struct wl_compositor *compositor;
- struct {
- EGLDisplay dpy;
- EGLContext ctx;
- EGLConfig conf;
- } egl;
- uint32_t mask;
-};
-
-struct window {
- struct display *display;
- struct {
- int width, height;
- } geometry;
- struct {
- GLuint fbo;
- GLuint color_rbo;
-
- GLuint program;
- GLuint rotation_uniform;
-
- GLuint pos;
- GLuint col;
- } gl;
-
- struct wl_egl_window *native;
- struct wl_surface *surface;
- EGLSurface egl_surface;
-};
-
-static const char *vert_shader_text =
- "uniform mat4 rotation;\n"
- "attribute vec4 pos;\n"
- "attribute vec4 color;\n"
- "varying vec4 v_color;\n"
- "void main() {\n"
- " gl_Position = rotation * pos;\n"
- " v_color = color;\n"
- "}\n";
-
-static const char *frag_shader_text =
- "precision mediump float;\n"
- "varying vec4 v_color;\n"
- "void main() {\n"
- " gl_FragColor = v_color;\n"
- "}\n";
-
-static void
-init_egl(struct display *display)
-{
- static const EGLint context_attribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
-
- static const EGLint config_attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RED_SIZE, 1,
- EGL_GREEN_SIZE, 1,
- EGL_BLUE_SIZE, 1,
- EGL_DEPTH_SIZE, 1,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_NONE
- };
-
- EGLint major, minor, n;
- EGLBoolean ret;
-
- display->egl.dpy =
- eglGetDisplay(display->native);
- assert(display->egl.dpy);
-
- ret = eglInitialize(display->egl.dpy, &major, &minor);
- assert(ret == EGL_TRUE);
- ret = eglBindAPI(EGL_OPENGL_ES_API);
- assert(ret == EGL_TRUE);
-
- assert(eglChooseConfig(display->egl.dpy, config_attribs,
- &display->egl.conf, 1, &n) && n == 1);
-
- display->egl.ctx = eglCreateContext(display->egl.dpy,
- display->egl.conf,
- EGL_NO_CONTEXT, context_attribs);
- assert(display->egl.ctx);
-
-}
-
-static GLuint
-create_shader(struct window *window, const char *source, GLenum shader_type)
-{
- GLuint shader;
- GLint status;
-
- shader = glCreateShader(shader_type);
- assert(shader != 0);
-
- glShaderSource(shader, 1, (const char **) &source, NULL);
- glCompileShader(shader);
-
- glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
- if (!status) {
- char log[1000];
- GLsizei len;
- glGetShaderInfoLog(shader, 1000, &len, log);
- fprintf(stderr, "Error: compiling %s: %*s\n",
- shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
- len, log);
- exit(1);
- }
-
- return shader;
-}
-
-static void
-init_gl(struct window *window)
-{
- GLuint frag, vert;
- GLint status;
-
- glViewport(0, 0, window->geometry.width, window->geometry.height);
-
- frag = create_shader(window, frag_shader_text, GL_FRAGMENT_SHADER);
- vert = create_shader(window, vert_shader_text, GL_VERTEX_SHADER);
-
- window->gl.program = glCreateProgram();
- glAttachShader(window->gl.program, frag);
- glAttachShader(window->gl.program, vert);
- glLinkProgram(window->gl.program);
-
- glGetProgramiv(window->gl.program, GL_LINK_STATUS, &status);
- if (!status) {
- char log[1000];
- GLsizei len;
- glGetProgramInfoLog(window->gl.program, 1000, &len, log);
- fprintf(stderr, "Error: linking:\n%*s\n", len, log);
- exit(1);
- }
-
- glUseProgram(window->gl.program);
-
- window->gl.pos = 0;
- window->gl.pos = 1;
-
- glBindAttribLocation(window->gl.program, window->gl.pos, "pos");
- glBindAttribLocation(window->gl.program, window->gl.col, "color");
- glLinkProgram(window->gl.program);
-
- window->gl.rotation_uniform =
- glGetUniformLocation(window->gl.program, "rotation");
-}
-
-static void
-create_surface(struct window *window)
-{
- struct display *display = window->display;
- struct wl_visual *visual;
- EGLBoolean ret;
-
- window->surface = wl_compositor_create_surface(display->compositor);
- visual = wl_display_get_premultiplied_argb_visual(display->display);
- window->native =
- wl_egl_window_create(display->native,
- window->surface,
- window->geometry.width,
- window->geometry.height,
- visual);
- window->egl_surface =
- eglCreateWindowSurface(display->egl.dpy,
- display->egl.conf,
- window->native,
- NULL);
-
- wl_surface_map_toplevel(window->surface);
-
- ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface,
- window->egl_surface, window->display->egl.ctx);
- assert(ret == EGL_TRUE);
-}
-
-static void
-redraw(void *data, uint32_t time)
-{
- struct window *window = data;
- static const GLfloat verts[3][2] = {
- { -0.5, -0.5 },
- { 0.5, -0.5 },
- { 0, 0.5 }
- };
- static const GLfloat colors[3][3] = {
- { 1, 0, 0 },
- { 0, 1, 0 },
- { 0, 0, 1 }
- };
- GLfloat angle;
- GLfloat rotation[4][4] = {
- { 1, 0, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 1, 0 },
- { 0, 0, 0, 1 }
- };
- static const int32_t speed_div = 5;
- static uint32_t start_time = 0;
-
- if (start_time == 0)
- start_time = time;
-
- angle = ((time-start_time) / speed_div) % 360 * M_PI / 180.0;
- rotation[0][0] = cos(angle);
- rotation[0][2] = sin(angle);
- rotation[2][0] = -sin(angle);
- rotation[2][2] = cos(angle);
-
- glUniformMatrix4fv(window->gl.rotation_uniform, 1, GL_FALSE,
- (GLfloat *) rotation);
-
- glClearColor(0.0, 0.0, 0.0, 0.5);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glVertexAttribPointer(window->gl.pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
- glVertexAttribPointer(window->gl.col, 3, GL_FLOAT, GL_FALSE, 0, colors);
- glEnableVertexAttribArray(window->gl.pos);
- glEnableVertexAttribArray(window->gl.col);
-
- glDrawArrays(GL_TRIANGLES, 0, 3);
-
- glDisableVertexAttribArray(window->gl.pos);
- glDisableVertexAttribArray(window->gl.col);
-
- glFlush();
-
- eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
- wl_display_frame_callback(window->display->display, redraw, window);
-}
-
-static void
-display_handle_global(struct wl_display *display, uint32_t id,
- const char *interface, uint32_t version, void *data)
-{
- struct display *d = data;
-
- if (strcmp(interface, "compositor") == 0)
- d->compositor = wl_compositor_create(display, id);
-}
-
-static int
-event_mask_update(uint32_t mask, void *data)
-{
- struct display *d = data;
-
- d->mask = mask;
-
- return 0;
-}
-
-int
-main(int argc, char **argv)
-{
- struct display display = { 0 };
- struct window window = { 0 };
-
- memset(&display, 0, sizeof display);
- memset(&window, 0, sizeof window);
-
- window.display = &display;
- window.geometry.width = 250;
- window.geometry.height = 250;
-
- display.display = wl_display_connect(NULL);
- assert(display.display);
-
- wl_display_add_global_listener(display.display,
- display_handle_global, &display);
-
- display.native = wl_egl_display_create(display.display);
-
- init_egl(&display);
- create_surface(&window);
- init_gl(&window);
-
- wl_display_frame_callback(display.display, redraw, &window);
-
- wl_display_get_fd(display.display, event_mask_update, &display);
- while (true)
- wl_display_iterate(display.display, display.mask);
-
- return 0;
-}
diff --git a/clients/smoke.c b/clients/smoke.c
deleted file mode 100644
index 0710b3a..0000000
--- a/clients/smoke.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright © 2010 Kristian Høgsberg
- *
- * 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-#include <time.h>
-#include <cairo.h>
-#include <glib.h>
-
-#include "wayland-client.h"
-#include "wayland-glib.h"
-#include "window.h"
-
-struct smoke {
- struct display *display;
- struct window *window;
- cairo_surface_t *surface;
- int x, y, width, height;
- int offset, current;
- struct { float *d, *u, *v; } b[2];
-};
-
-static void diffuse(struct smoke *smoke, uint32_t time,
- float *source, float *dest)
-{
- float *s, *d;
- int x, y, k, stride;
- float t, a = 0.0002;
-
- stride = smoke->width;
-
- for (k = 0; k < 5; k++) {
- for (y = 1; y < smoke->height - 1; y++) {
- s = source + y * stride;
- d = dest + y * stride;
- for (x = 1; x < smoke->width - 1; x++) {
- t = d[x - 1] + d[x + 1] +
- d[x - stride] + d[x + stride];
- d[x] = (s[x] + a * t) / (1 + 4 * a) * 0.995;
- }
- }
- }
-}
-
-static void advect(struct smoke *smoke, uint32_t time,
- float *uu, float *vv, float *source, float *dest)
-{
- float *s, *d;
- float *u, *v;
- int x, y, stride;
- int i, j;
- float px, py, fx, fy;
-
- stride = smoke->width;
-
- for (y = 1; y < smoke->height - 1; y++) {
- d = dest + y * stride;
- u = uu + y * stride;
- v = vv + y * stride;
-
- for (x = 1; x < smoke->width - 1; x++) {
- px = x - u[x];
- py = y - v[x];
- if (px < 0.5)
- px = 0.5;
- if (py < 0.5)
- py = 0.5;
- if (px > smoke->width - 0.5)
- px = smoke->width - 0.5;
- if (py > smoke->height - 0.5)
- py = smoke->height - 0.5;
- i = (int) px;
- j = (int) py;
- fx = px - i;
- fy = py - j;
- s = source + j * stride + i;
- d[x] = (s[0] * (1 - fx) + s[1] * fx) * (1 - fy) +
- (s[stride] * (1 - fx) + s[stride + 1] * fx) * fy;
- }
- }
-}
-
-static void project(struct smoke *smoke, uint32_t time,
- float *u, float *v, float *p, float *div)
-{
- int x, y, k, l, s;
- float h;
-
- h = 1.0 / smoke->width;
- s = smoke->width;
- memset(p, 0, smoke->height * smoke->width);
- for (y = 1; y < smoke->height - 1; y++) {
- l = y * s;
- for (x = 1; x < smoke->width - 1; x++) {
- div[l + x] = -0.5 * h * (u[l + x + 1] - u[l + x - 1] +
- v[l + x + s] - v[l + x - s]);
- p[l + x] = 0;
- }
- }
-
- for (k = 0; k < 5; k++) {
- for (y = 1; y < smoke->height - 1; y++) {
- l = y * s;
- for (x = 1; x < smoke->width - 1; x++) {
- p[l + x] = (div[l + x] +
- p[l + x - 1] +
- p[l + x + 1] +
- p[l + x - s] +
- p[l + x + s]) / 4;
- }
- }
- }
-
- for (y = 1; y < smoke->height - 1; y++) {
- l = y * s;
- for (x = 1; x < smoke->width - 1; x++) {
- u[l + x] -= 0.5 * (p[l + x + 1] - p[l + x - 1]) / h;
- v[l + x] -= 0.5 * (p[l + x + s] - p[l + x - s]) / h;
- }
- }
-}
-
-static void render(struct smoke *smoke)
-{
- unsigned char *dest;
- int x, y, width, height, stride;
- float *s;
- uint32_t *d, c, a;
-
- dest = cairo_image_surface_get_data (smoke->surface);
- width = cairo_image_surface_get_width (smoke->surface);
- height = cairo_image_surface_get_height (smoke->surface);
- stride = cairo_image_surface_get_stride (smoke->surface);
-
- for (y = 1; y < height - 1; y++) {
- s = smoke->b[smoke->current].d + y * smoke->height;
- d = (uint32_t *) (dest + y * stride);
- for (x = 1; x < width - 1; x++) {
- c = (int) (s[x] * 800);
- if (c > 255)
- c = 255;
- a = c;
- if (a < 0x33)
- a = 0x33;
- d[x] = (a << 24) | (c << 16) | (c << 8) | c;
- }
- }
-}
-
-static void
-frame_callback(void *data, uint32_t time)
-{
- struct smoke *smoke = data;
-
- diffuse(smoke, time / 30, smoke->b[0].u, smoke->b[1].u);
- diffuse(smoke, time / 30, smoke->b[0].v, smoke->b[1].v);
- project(smoke, time / 30,
- smoke->b[1].u, smoke->b[1].v,
- smoke->b[0].u, smoke->b[0].v);
- advect(smoke, time / 30,
- smoke->b[1].u, smoke->b[1].v,
- smoke->b[1].u, smoke->b[0].u);
- advect(smoke, time / 30,
- smoke->b[1].u, smoke->b[1].v,
- smoke->b[1].v, smoke->b[0].v);
- project(smoke, time / 30,
- smoke->b[0].u, smoke->b[0].v,
- smoke->b[1].u, smoke->b[1].v);
-
- diffuse(smoke, time / 30, smoke->b[0].d, smoke->b[1].d);
- advect(smoke, time / 30,
- smoke->b[0].u, smoke->b[0].v,
- smoke->b[1].d, smoke->b[0].d);
-
- render(smoke);
-
- window_damage(smoke->window, 0, 0, smoke->width, smoke->height);
- wl_display_frame_callback(display_get_display(smoke->display),
- frame_callback, smoke);
-}
-
-static int
-smoke_motion_handler(struct window *window,
- struct input *input, uint32_t time,
- int32_t x, int32_t y,
- int32_t surface_x, int32_t surface_y, void *data)
-{
- struct smoke *smoke = data;
- int i, i0, i1, j, j0, j1, k, d = 5;
-
- if (surface_x - d < 1)
- i0 = 1;
- else
- i0 = surface_x - d;
- if (i0 + 2 * d > smoke->width - 1)
- i1 = smoke->width - 1;
- else
- i1 = i0 + 2 * d;
-
- if (surface_y - d < 1)
- j0 = 1;
- else
- j0 = surface_y - d;
- if (j0 + 2 * d > smoke->height - 1)
- j1 = smoke->height - 1;
- else
- j1 = j0 + 2 * d;
-
- for (i = i0; i < i1; i++)
- for (j = j0; j < j1; j++) {
- k = j * smoke->width + i;
- smoke->b[0].u[k] += 256 - (random() & 512);
- smoke->b[0].v[k] += 256 - (random() & 512);
- smoke->b[0].d[k] += 1;
- }
-
- return POINTER_HAND1;
-}
-
-int main(int argc, char *argv[])
-{
- struct timespec ts;
- struct smoke smoke;
- struct display *d;
- int size;
-
- d = display_create(&argc, &argv, NULL);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
- smoke.x = 200;
- smoke.y = 200;
- smoke.width = 200;
- smoke.height = 200;
- smoke.display = d;
- smoke.window = window_create(d, smoke.width, smoke.height);
- window_set_title(smoke.window, "smoke");
-
- window_set_buffer_type(smoke.window, WINDOW_BUFFER_TYPE_SHM);
- clock_gettime(CLOCK_MONOTONIC, &ts);
- srandom(ts.tv_nsec);
- smoke.offset = random();
-
- smoke.current = 0;
- size = smoke.height * smoke.width;
- smoke.b[0].d = calloc(size, sizeof(float));
- smoke.b[0].u = calloc(size, sizeof(float));
- smoke.b[0].v = calloc(size, sizeof(float));
- smoke.b[1].d = calloc(size, sizeof(float));
- smoke.b[1].u = calloc(size, sizeof(float));
- smoke.b[1].v = calloc(size, sizeof(float));
-
- window_set_decoration(smoke.window, 0);
- window_create_surface(smoke.window);
- smoke.surface = window_get_surface(smoke.window);
-
- window_flush(smoke.window);
-
- window_set_motion_handler(smoke.window,
- smoke_motion_handler);
-
- window_set_user_data(smoke.window, &smoke);
- wl_display_frame_callback(display_get_display(d),
- frame_callback, &smoke);
-
- display_run(d);
-
- return 0;
-}
diff --git a/clients/terminal.c b/clients/terminal.c
deleted file mode 100644
index 3573382..0000000
--- a/clients/terminal.c
+++ /dev/null
@@ -1,2398 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-#include <time.h>
-#include <pty.h>
-#include <ctype.h>
-#include <cairo.h>
-#include <glib.h>
-
-#include <X11/keysym.h>
-
-#include "wayland-util.h"
-#include "wayland-client.h"
-#include "wayland-glib.h"
-
-#include "window.h"
-
-static int option_fullscreen;
-
-#define MOD_SHIFT 0x01
-#define MOD_ALT 0x02
-#define MOD_CTRL 0x04
-
-#define ATTRMASK_BOLD 0x01
-#define ATTRMASK_UNDERLINE 0x02
-#define ATTRMASK_BLINK 0x04
-#define ATTRMASK_INVERSE 0x08
-#define ATTRMASK_CONCEALED 0x10
-
-/* Buffer sizes */
-#define MAX_RESPONSE 256
-#define MAX_ESCAPE 255
-
-/* Terminal modes */
-#define MODE_SHOW_CURSOR 0x00000001
-#define MODE_INVERSE 0x00000002
-#define MODE_AUTOWRAP 0x00000004
-#define MODE_AUTOREPEAT 0x00000008
-#define MODE_LF_NEWLINE 0x00000010
-#define MODE_IRM 0x00000020
-#define MODE_DELETE_SENDS_DEL 0x00000040
-#define MODE_ALT_SENDS_ESC 0x00000080
-
-union utf8_char {
- unsigned char byte[4];
- uint32_t ch;
-};
-
-enum utf8_state {
- utf8state_start,
- utf8state_accept,
- utf8state_reject,
- utf8state_expect3,
- utf8state_expect2,
- utf8state_expect1
-};
-
-struct utf8_state_machine {
- enum utf8_state state;
- int len;
- union utf8_char s;
-};
-
-static void
-init_state_machine(struct utf8_state_machine *machine)
-{
- machine->state = utf8state_start;
- machine->len = 0;
- machine->s.ch = 0;
-}
-
-static enum utf8_state
-utf8_next_char(struct utf8_state_machine *machine, char c)
-{
- switch(machine->state) {
- case utf8state_start:
- case utf8state_accept:
- case utf8state_reject:
- machine->s.ch = 0;
- machine->len = 0;
- if(c == 0xC0 || c == 0xC1) {
- /* overlong encoding, reject */
- machine->state = utf8state_reject;
- } else if((c & 0x80) == 0) {
- /* single byte, accept */
- machine->s.byte[machine->len++] = c;
- machine->state = utf8state_accept;
- } else if((c & 0xC0) == 0x80) {
- /* parser out of sync, ignore byte */
- machine->state = utf8state_start;
- } else if((c & 0xE0) == 0xC0) {
- /* start of two byte sequence */
- machine->s.byte[machine->len++] = c;
- machine->state = utf8state_expect1;
- } else if((c & 0xF0) == 0xE0) {
- /* start of three byte sequence */
- machine->s.byte[machine->len++] = c;
- machine->state = utf8state_expect2;
- } else if((c & 0xF8) == 0xF0) {
- /* start of four byte sequence */
- machine->s.byte[machine->len++] = c;
- machine->state = utf8state_expect3;
- } else {
- /* overlong encoding, reject */
- machine->state = utf8state_reject;
- }
- break;
- case utf8state_expect3:
- machine->s.byte[machine->len++] = c;
- if((c & 0xC0) == 0x80) {
- /* all good, continue */
- machine->state = utf8state_expect2;
- } else {
- /* missing extra byte, reject */
- machine->state = utf8state_reject;
- }
- break;
- case utf8state_expect2:
- machine->s.byte[machine->len++] = c;
- if((c & 0xC0) == 0x80) {
- /* all good, continue */
- machine->state = utf8state_expect1;
- } else {
- /* missing extra byte, reject */
- machine->state = utf8state_reject;
- }
- break;
- case utf8state_expect1:
- machine->s.byte[machine->len++] = c;
- if((c & 0xC0) == 0x80) {
- /* all good, accept */
- machine->state = utf8state_accept;
- } else {
- /* missing extra byte, reject */
- machine->state = utf8state_reject;
- }
- break;
- default:
- machine->state = utf8state_reject;
- break;
- }
-
- return machine->state;
-}
-
-struct char_sub {
- union utf8_char match;
- union utf8_char replace;
-};
-/* Set last char_sub match to NULL char */
-typedef struct char_sub *character_set;
-
-struct char_sub CS_US[] = {
- {{{0, }}, {{0, }}}
-};
-static struct char_sub CS_UK[] = {
- {{{'#', 0, }}, {{0xC2, 0xA3, 0, }}},
- {{{0, }}, {{0, }}}
-};
-static struct char_sub CS_SPECIAL[] = {
- {{{'`', 0, }}, {{0xE2, 0x99, 0xA6, 0}}}, /* diamond */
- {{{'a', 0, }}, {{0xE2, 0x96, 0x92, 0}}}, /* 50% cell */
- {{{'b', 0, }}, {{0xE2, 0x90, 0x89, 0}}}, /* HT */
- {{{'c', 0, }}, {{0xE2, 0x90, 0x8C, 0}}}, /* FF */
- {{{'d', 0, }}, {{0xE2, 0x90, 0x8D, 0}}}, /* CR */
- {{{'e', 0, }}, {{0xE2, 0x90, 0x8A, 0}}}, /* LF */
- {{{'f', 0, }}, {{0xC2, 0xB0, 0, }}}, /* Degree */
- {{{'g', 0, }}, {{0xC2, 0xB1, 0, }}}, /* Plus/Minus */
- {{{'h', 0, }}, {{0xE2, 0x90, 0xA4, 0}}}, /* NL */
- {{{'i', 0, }}, {{0xE2, 0x90, 0x8B, 0}}}, /* VT */
- {{{'j', 0, }}, {{0xE2, 0x94, 0x98, 0}}}, /* CN_RB */
- {{{'k', 0, }}, {{0xE2, 0x94, 0x90, 0}}}, /* CN_RT */
- {{{'l', 0, }}, {{0xE2, 0x94, 0x8C, 0}}}, /* CN_LT */
- {{{'m', 0, }}, {{0xE2, 0x94, 0x94, 0}}}, /* CN_RB */
- {{{'n', 0, }}, {{0xE2, 0x94, 0xBC, 0}}}, /* CROSS */
- {{{'o', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
- {{{'p', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
- {{{'q', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
- {{{'r', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
- {{{'s', 0, }}, {{0xE2, 0x94, 0x80, 0}}}, /* H */
- {{{'t', 0, }}, {{0xE2, 0x94, 0x9C, 0}}}, /* TR */
- {{{'u', 0, }}, {{0xE2, 0x94, 0xA4, 0}}}, /* TL */
- {{{'v', 0, }}, {{0xE2, 0x94, 0xB4, 0}}}, /* TU */
- {{{'w', 0, }}, {{0xE2, 0x94, 0xAC, 0}}}, /* TD */
- {{{'x', 0, }}, {{0xE2, 0x94, 0x82, 0}}}, /* V */
- {{{'y', 0, }}, {{0xE2, 0x89, 0xA4, 0}}}, /* LE */
- {{{'z', 0, }}, {{0xE2, 0x89, 0xA5, 0}}}, /* GE */
- {{{'{', 0, }}, {{0xCF, 0x80, 0, }}}, /* PI */
- {{{'|', 0, }}, {{0xE2, 0x89, 0xA0, 0}}}, /* NEQ */
- {{{'}', 0, }}, {{0xC2, 0xA3, 0, }}}, /* POUND */
- {{{'~', 0, }}, {{0xE2, 0x8B, 0x85, 0}}}, /* DOT */
- {{{0, }}, {{0, }}}
-};
-
-static void
-apply_char_set(character_set cs, union utf8_char *utf8)
-{
- int i = 0;
-
- while (cs[i].match.byte[0]) {
- if ((*utf8).ch == cs[i].match.ch) {
- *utf8 = cs[i].replace;
- break;
- }
- i++;
- }
-}
-
-struct key_map {
- int sym;
- int num;
- char escape;
- char code;
-};
-/* Set last key_sub sym to NULL */
-typedef struct key_map *keyboard_mode;
-
-static struct key_map KM_NORMAL[] = {
- {XK_Left, 1, '[', 'D'},
- {XK_Right, 1, '[', 'C'},
- {XK_Up, 1, '[', 'A'},
- {XK_Down, 1, '[', 'B'},
- {XK_Home, 1, '[', 'H'},
- {XK_End, 1, '[', 'F'},
- {0, 0, 0, 0}
-};
-static struct key_map KM_APPLICATION[] = {
- {XK_Left, 1, 'O', 'D'},
- {XK_Right, 1, 'O', 'C'},
- {XK_Up, 1, 'O', 'A'},
- {XK_Down, 1, 'O', 'B'},
- {XK_Home, 1, 'O', 'H'},
- {XK_End, 1, 'O', 'F'},
- {XK_KP_Enter, 1, 'O', 'M'},
- {XK_KP_Multiply, 1, 'O', 'j'},
- {XK_KP_Add, 1, 'O', 'k'},
- {XK_KP_Separator, 1, 'O', 'l'},
- {XK_KP_Subtract, 1, 'O', 'm'},
- {XK_KP_Divide, 1, 'O', 'o'},
- {0, 0, 0, 0}
-};
-
-static int
-function_key_response(char escape, int num, uint32_t modifiers,
- char code, char *response)
-{
- int mod_num = 0;
- int len;
-
- if (modifiers & XKB_COMMON_SHIFT_MASK) mod_num |= 1;
- if (modifiers & XKB_COMMON_MOD1_MASK) mod_num |= 2;
- if (modifiers & XKB_COMMON_CONTROL_MASK) mod_num |= 4;
-
- if (mod_num != 0)
- len = snprintf(response, MAX_RESPONSE, "\e[%d;%d%c",
- num, mod_num + 1, code);
- else if (code != '~')
- len = snprintf(response, MAX_RESPONSE, "\e%c%c",
- escape, code);
- else
- len = snprintf(response, MAX_RESPONSE, "\e%c%d%c",
- escape, num, code);
-
- if (len >= MAX_RESPONSE) return MAX_RESPONSE - 1;
- else return len;
-}
-
-/* returns the number of bytes written into response,
- * which must have room for MAX_RESPONSE bytes */
-static int
-apply_key_map(keyboard_mode mode, int sym, uint32_t modifiers, char *response)
-{
- struct key_map map;
- int len = 0;
- int i = 0;
-
- while (mode[i].sym) {
- map = mode[i++];
- if (sym == map.sym) {
- len = function_key_response(map.escape, map.num,
- modifiers, map.code,
- response);
- break;
- }
- }
-
- return len;
-}
-
-struct terminal_color { double r, g, b, a; };
-struct attr {
- unsigned char fg, bg;
- char a; /* attributes format:
- * 76543210
- * cilub */
- char s; /* in selection */
-};
-struct color_scheme {
- struct terminal_color palette[16];
- char border;
- struct attr default_attr;
-};
-
-static void
-attr_init(struct attr *data_attr, struct attr attr, int n)
-{
- int i;
- for (i = 0; i < n; i++) {
- data_attr[i] = attr;
- }
-}
-
-enum escape_state {
- escape_state_normal = 0,
- escape_state_escape,
- escape_state_dcs,
- escape_state_csi,
- escape_state_osc,
- escape_state_inner_escape,
- escape_state_ignore,
- escape_state_special
-};
-
-#define ESC_FLAG_WHAT 0x01
-#define ESC_FLAG_GT 0x02
-#define ESC_FLAG_BANG 0x04
-#define ESC_FLAG_CASH 0x08
-#define ESC_FLAG_SQUOTE 0x10
-#define ESC_FLAG_DQUOTE 0x20
-#define ESC_FLAG_SPACE 0x40
-
-struct terminal {
- struct window *window;
- struct display *display;
- union utf8_char *data;
- char *tab_ruler;
- struct attr *data_attr;
- struct attr curr_attr;
- uint32_t mode;
- char origin_mode;
- char saved_origin_mode;
- struct attr saved_attr;
- union utf8_char last_char;
- int margin_top, margin_bottom;
- character_set cs, g0, g1;
- character_set saved_cs, saved_g0, saved_g1;
- keyboard_mode key_mode;
- int data_pitch, attr_pitch; /* The width in bytes of a line */
- int width, height, start, row, column;
- int saved_row, saved_column;
- int fd, master;
- GIOChannel *channel;
- uint32_t modifiers;
- char escape[MAX_ESCAPE+1];
- int escape_length;
- enum escape_state state;
- enum escape_state outer_state;
- int escape_flags;
- struct utf8_state_machine state_machine;
- int margin;
- int fullscreen;
- int focused;
- struct color_scheme *color_scheme;
- struct terminal_color color_table[256];
- cairo_font_extents_t extents;
- cairo_scaled_font_t *font_normal, *font_bold;
-
- struct wl_selection *selection;
- struct wl_selection_offer *selection_offer;
- uint32_t selection_offer_has_text;
- int32_t dragging, selection_active;
- int selection_start_x, selection_start_y;
- int selection_end_x, selection_end_y;
-};
-
-/* Create default tab stops, every 8 characters */
-static void
-terminal_init_tabs(struct terminal *terminal)
-{
- int i = 0;
-
- while (i < terminal->width) {
- if (i % 8 == 0)
- terminal->tab_ruler[i] = 1;
- else
- terminal->tab_ruler[i] = 0;
- i++;
- }
-}
-
-static void
-terminal_init(struct terminal *terminal)
-{
- terminal->curr_attr = terminal->color_scheme->default_attr;
- terminal->origin_mode = 0;
- terminal->mode = MODE_SHOW_CURSOR |
- MODE_AUTOREPEAT |
- MODE_ALT_SENDS_ESC |
- MODE_AUTOWRAP;
-
- terminal->row = 0;
- terminal->column = 0;
-
- terminal->g0 = CS_US;
- terminal->g1 = CS_US;
- terminal->cs = terminal->g0;
- terminal->key_mode = KM_NORMAL;
-
- terminal->saved_g0 = terminal->g0;
- terminal->saved_g1 = terminal->g1;
- terminal->saved_cs = terminal->cs;
-
- terminal->saved_attr = terminal->curr_attr;
- terminal->saved_origin_mode = terminal->origin_mode;
- terminal->saved_row = terminal->row;
- terminal->saved_column = terminal->column;
-
- if (terminal->tab_ruler != NULL) terminal_init_tabs(terminal);
-}
-
-static void
-init_color_table(struct terminal *terminal)
-{
- int c, r;
- struct terminal_color *color_table = terminal->color_table;
-
- for (c = 0; c < 256; c ++) {
- if (c < 16) {
- color_table[c] = terminal->color_scheme->palette[c];
- } else if (c < 232) {
- r = c - 16;
- color_table[c].b = ((double)(r % 6) / 6.0); r /= 6;
- color_table[c].g = ((double)(r % 6) / 6.0); r /= 6;
- color_table[c].r = ((double)(r % 6) / 6.0);
- color_table[c].a = 1.0;
- } else {
- r = (c - 232) * 10 + 8;
- color_table[c].r = ((double) r) / 256.0;
- color_table[c].g = color_table[c].r;
- color_table[c].b = color_table[c].r;
- color_table[c].a = 1.0;
- }
- }
-}
-
-static union utf8_char *
-terminal_get_row(struct terminal *terminal, int row)
-{
- int index;
-
- index = (row + terminal->start) % terminal->height;
-
- return &terminal->data[index * terminal->width];
-}
-
-static struct attr*
-terminal_get_attr_row(struct terminal *terminal, int row)
-{
- int index;
-
- index = (row + terminal->start) % terminal->height;
-
- return &terminal->data_attr[index * terminal->width];
-}
-
-union decoded_attr {
- struct attr attr;
- uint32_t key;
-};
-
-static int
-terminal_compare_position(struct terminal *terminal,
- int x, int y, int32_t ref_row, int32_t ref_col)
-{
- struct rectangle allocation;
- int top_margin, side_margin, col, row, ref_x;
-
- window_get_child_allocation(terminal->window, &allocation);
- side_margin = allocation.x + (allocation.width - terminal->width * terminal->extents.max_x_advance) / 2;
- top_margin = allocation.y + (allocation.height - terminal->height * terminal->extents.height) / 2;
-
- col = (x - side_margin) / terminal->extents.max_x_advance;
- row = (y - top_margin) / terminal->extents.height;
-
- ref_x = side_margin + ref_col * terminal->extents.max_x_advance +
- terminal->extents.max_x_advance / 2;
-
- if (row < ref_row)
- return -1;
- if (row == ref_row) {
- if (col < ref_col)
- return -1;
- if (col == ref_col && x < ref_x)
- return -1;
- }
-
- return 1;
-}
-
-static void
-terminal_decode_attr(struct terminal *terminal, int row, int col,
- union decoded_attr *decoded)
-{
- struct attr attr;
- int foreground, background, tmp;
- int start_cmp, end_cmp;
-
- start_cmp =
- terminal_compare_position(terminal,
- terminal->selection_start_x,
- terminal->selection_start_y,
- row, col);
- end_cmp =
- terminal_compare_position(terminal,
- terminal->selection_end_x,
- terminal->selection_end_y,
- row, col);
- decoded->attr.s = 0;
- if (start_cmp < 0 && end_cmp > 0)
- decoded->attr.s = 1;
- else if (end_cmp < 0 && start_cmp > 0)
- decoded->attr.s = 1;
-
- /* get the attributes for this character cell */
- attr = terminal_get_attr_row(terminal, row)[col];
- if ((attr.a & ATTRMASK_INVERSE) ||
- decoded->attr.s ||
- ((terminal->mode & MODE_SHOW_CURSOR) &&
- terminal->focused && terminal->row == row &&
- terminal->column == col)) {
- foreground = attr.bg;
- background = attr.fg;
- if (attr.a & ATTRMASK_BOLD) {
- if (foreground <= 16) foreground |= 0x08;
- if (background <= 16) background &= 0x07;
- }
- } else {
- foreground = attr.fg;
- background = attr.bg;
- }
-
- if (terminal->mode & MODE_INVERSE) {
- tmp = foreground;
- foreground = background;
- background = tmp;
- if (attr.a & ATTRMASK_BOLD) {
- if (foreground <= 16) foreground |= 0x08;
- if (background <= 16) background &= 0x07;
- }
- }
-
- decoded->attr.fg = foreground;
- decoded->attr.bg = background;
- decoded->attr.a = attr.a;
-}
-
-
-static void
-terminal_scroll_buffer(struct terminal *terminal, int d)
-{
- int i;
-
- d = d % (terminal->height + 1);
- terminal->start = (terminal->start + d) % terminal->height;
- if (terminal->start < 0) terminal->start = terminal->height + terminal->start;
- if(d < 0) {
- d = 0 - d;
- for(i = 0; i < d; i++) {
- memset(terminal_get_row(terminal, i), 0, terminal->data_pitch);
- attr_init(terminal_get_attr_row(terminal, i),
- terminal->curr_attr, terminal->width);
- }
- } else {
- for(i = terminal->height - d; i < terminal->height; i++) {
- memset(terminal_get_row(terminal, i), 0, terminal->data_pitch);
- attr_init(terminal_get_attr_row(terminal, i),
- terminal->curr_attr, terminal->width);
- }
- }
-}
-
-static void
-terminal_scroll_window(struct terminal *terminal, int d)
-{
- int i;
- int window_height;
- int from_row, to_row;
-
- // scrolling range is inclusive
- window_height = terminal->margin_bottom - terminal->margin_top + 1;
- d = d % (window_height + 1);
- if(d < 0) {
- d = 0 - d;
- to_row = terminal->margin_bottom;
- from_row = terminal->margin_bottom - d;
-
- for (i = 0; i < (window_height - d); i++) {
- memcpy(terminal_get_row(terminal, to_row - i),
- terminal_get_row(terminal, from_row - i),
- terminal->data_pitch);
- memcpy(terminal_get_attr_row(terminal, to_row - i),
- terminal_get_attr_row(terminal, from_row - i),
- terminal->attr_pitch);
- }
- for (i = terminal->margin_top; i < (terminal->margin_top + d); i++) {
- memset(terminal_get_row(terminal, i), 0, terminal->data_pitch);
- attr_init(terminal_get_attr_row(terminal, i),
- terminal->curr_attr, terminal->width);
- }
- } else {
- to_row = terminal->margin_top;
- from_row = terminal->margin_top + d;
-
- for (i = 0; i < (window_height - d); i++) {
- memcpy(terminal_get_row(terminal, to_row + i),
- terminal_get_row(terminal, from_row + i),
- terminal->data_pitch);
- memcpy(terminal_get_attr_row(terminal, to_row + i),
- terminal_get_attr_row(terminal, from_row + i),
- terminal->attr_pitch);
- }
- for (i = terminal->margin_bottom - d + 1; i <= terminal->margin_bottom; i++) {
- memset(terminal_get_row(terminal, i), 0, terminal->data_pitch);
- attr_init(terminal_get_attr_row(terminal, i),
- terminal->curr_attr, terminal->width);
- }
- }
-}
-
-static void
-terminal_scroll(struct terminal *terminal, int d)
-{
- if(terminal->margin_top == 0 && terminal->margin_bottom == terminal->height - 1)
- terminal_scroll_buffer(terminal, d);
- else
- terminal_scroll_window(terminal, d);
-}
-
-static void
-terminal_shift_line(struct terminal *terminal, int d)
-{
- union utf8_char *row;
- struct attr *attr_row;
-
- row = terminal_get_row(terminal, terminal->row);
- attr_row = terminal_get_attr_row(terminal, terminal->row);
-
- if ((terminal->width + d) <= terminal->column)
- d = terminal->column + 1 - terminal->width;
- if ((terminal->column + d) >= terminal->width)
- d = terminal->width - terminal->column - 1;
-
- if (d < 0) {
- d = 0 - d;
- memmove(&row[terminal->column],
- &row[terminal->column + d],
- (terminal->width - terminal->column - d) * sizeof(union utf8_char));
- memmove(&attr_row[terminal->column], &attr_row[terminal->column + d],
- (terminal->width - terminal->column - d) * sizeof(struct attr));
- memset(&row[terminal->width - d], 0, d * sizeof(union utf8_char));
- attr_init(&attr_row[terminal->width - d], terminal->curr_attr, d);
- } else {
- memmove(&row[terminal->column + d], &row[terminal->column],
- (terminal->width - terminal->column - d) * sizeof(union utf8_char));
- memmove(&attr_row[terminal->column + d], &attr_row[terminal->column],
- (terminal->width - terminal->column - d) * sizeof(struct attr));
- memset(&row[terminal->column], 0, d * sizeof(union utf8_char));
- attr_init(&attr_row[terminal->column], terminal->curr_attr, d);
- }
-}
-
-static void
-terminal_resize(struct terminal *terminal, int width, int height)
-{
- size_t size;
- union utf8_char *data;
- struct attr *data_attr;
- char *tab_ruler;
- int data_pitch, attr_pitch;
- int i, l, total_rows;
- struct rectangle allocation;
- struct winsize ws;
- int32_t pixel_width, pixel_height;
-
- if (width < 1)
- width = 1;
- if (height < 1)
- height = 1;
- if (terminal->width == width && terminal->height == height)
- return;
-
- if (!terminal->fullscreen) {
- pixel_width = width *
- terminal->extents.max_x_advance + 2 * terminal->margin;
- pixel_height = height *
- terminal->extents.height + 2 * terminal->margin;
- window_set_child_size(terminal->window,
- pixel_width, pixel_height);
- }
-
- window_schedule_redraw (terminal->window);
-
- data_pitch = width * sizeof(union utf8_char);
- size = data_pitch * height;
- data = malloc(size);
- attr_pitch = width * sizeof(struct attr);
- data_attr = malloc(attr_pitch * height);
- tab_ruler = malloc(width);
- memset(data, 0, size);
- memset(tab_ruler, 0, width);
- attr_init(data_attr, terminal->curr_attr, width * height);
- if (terminal->data && terminal->data_attr) {
- if (width > terminal->width)
- l = terminal->width;
- else
- l = width;
-
- if (terminal->height > height) {
- total_rows = height;
- } else {
- total_rows = terminal->height;
- }
-
- for (i = 0; i < total_rows; i++) {
- memcpy(&data[width * i],
- terminal_get_row(terminal, i),
- l * sizeof(union utf8_char));
- memcpy(&data_attr[width * i],
- terminal_get_attr_row(terminal, i),
- l * sizeof(struct attr));
- }
-
- free(terminal->data);
- free(terminal->data_attr);
- free(terminal->tab_ruler);
- }
-
- terminal->data_pitch = data_pitch;
- terminal->attr_pitch = attr_pitch;
- terminal->margin_bottom =
- height - (terminal->height - terminal->margin_bottom);
- terminal->width = width;
- terminal->height = height;
- terminal->data = data;
- terminal->data_attr = data_attr;
- terminal->tab_ruler = tab_ruler;
- terminal_init_tabs(terminal);
-
- /* Update the window size */
- ws.ws_row = terminal->height;
- ws.ws_col = terminal->width;
- window_get_child_allocation(terminal->window, &allocation);
- ws.ws_xpixel = allocation.width;
- ws.ws_ypixel = allocation.height;
- ioctl(terminal->master, TIOCSWINSZ, &ws);
-}
-
-struct color_scheme DEFAULT_COLORS = {
- {
- {0, 0, 0, 1}, /* black */
- {0.66, 0, 0, 1}, /* red */
- {0 , 0.66, 0, 1}, /* green */
- {0.66, 0.33, 0, 1}, /* orange (nicer than muddy yellow) */
- {0 , 0 , 0.66, 1}, /* blue */
- {0.66, 0 , 0.66, 1}, /* magenta */
- {0, 0.66, 0.66, 1}, /* cyan */
- {0.66, 0.66, 0.66, 1}, /* light grey */
- {0.22, 0.33, 0.33, 1}, /* dark grey */
- {1, 0.33, 0.33, 1}, /* high red */
- {0.33, 1, 0.33, 1}, /* high green */
- {1, 1, 0.33, 1}, /* high yellow */
- {0.33, 0.33, 1, 1}, /* high blue */
- {1, 0.33, 1, 1}, /* high magenta */
- {0.33, 1, 1, 1}, /* high cyan */
- {1, 1, 1, 1} /* white */
- },
- 0, /* black border */
- {7, 0, 0, } /* bg:black (0), fg:light gray (7) */
-};
-
-static void
-terminal_set_color(struct terminal *terminal, cairo_t *cr, int index)
-{
- cairo_set_source_rgba(cr,
- terminal->color_table[index].r,
- terminal->color_table[index].g,
- terminal->color_table[index].b,
- terminal->color_table[index].a);
-}
-
-static void
-terminal_send_selection(struct terminal *terminal, int fd)
-{
- int row, col;
- union utf8_char *p_row;
- union decoded_attr attr;
- FILE *fp;
- int len;
-
- fp = fdopen(fd, "w");
- for (row = 0; row < terminal->height; row++) {
- p_row = terminal_get_row(terminal, row);
- for (col = 0; col < terminal->width; col++) {
- /* get the attributes for this character cell */
- terminal_decode_attr(terminal, row, col, &attr);
- if (!attr.attr.s)
- continue;
- len = strnlen((char *) p_row[col].byte, 4);
- fwrite(p_row[col].byte, 1, len, fp);
- }
- }
- fclose(fp);
-}
-
-struct glyph_run {
- struct terminal *terminal;
- cairo_t *cr;
- int count;
- union decoded_attr attr;
- cairo_glyph_t glyphs[256], *g;
-};
-
-static void
-glyph_run_init(struct glyph_run *run, struct terminal *terminal, cairo_t *cr)
-{
- run->terminal = terminal;
- run->cr = cr;
- run->g = run->glyphs;
- run->count = 0;
- run->attr.key = 0;
-}
-
-static void
-glyph_run_flush(struct glyph_run *run, union decoded_attr attr)
-{
- cairo_scaled_font_t *font;
-
- if (run->count > ARRAY_LENGTH(run->glyphs) - 10 ||
- (attr.key != run->attr.key)) {
- if (run->attr.attr.a & (ATTRMASK_BOLD | ATTRMASK_BLINK))
- font = run->terminal->font_bold;
- else
- font = run->terminal->font_normal;
- cairo_set_scaled_font(run->cr, font);
- terminal_set_color(run->terminal, run->cr,
- run->attr.attr.fg);
-
- if (!(run->attr.attr.a & ATTRMASK_CONCEALED))
- cairo_show_glyphs (run->cr, run->glyphs, run->count);
- run->g = run->glyphs;
- run->count = 0;
- }
- run->attr = attr;
-}
-
-static void
-glyph_run_add(struct glyph_run *run, int x, int y, union utf8_char *c)
-{
- int num_glyphs;
- cairo_scaled_font_t *font;
-
- num_glyphs = ARRAY_LENGTH(run->glyphs) - run->count;
-
- if (run->attr.attr.a & (ATTRMASK_BOLD | ATTRMASK_BLINK))
- font = run->terminal->font_bold;
- else
- font = run->terminal->font_normal;
-
- cairo_move_to(run->cr, x, y);
- cairo_scaled_font_text_to_glyphs (font, x, y,
- (char *) c->byte, 4,
- &run->g, &num_glyphs,
- NULL, NULL, NULL);
- run->g += num_glyphs;
- run->count += num_glyphs;
-}
-
-static void
-terminal_draw_contents(struct terminal *terminal)
-{
- struct rectangle allocation;
- cairo_t *cr;
- int top_margin, side_margin;
- int row, col;
- union utf8_char *p_row;
- union decoded_attr attr;
- int text_x, text_y;
- cairo_surface_t *surface;
- double d;
- struct glyph_run run;
- cairo_font_extents_t extents;
-
- surface = window_get_surface(terminal->window);
- window_get_child_allocation(terminal->window, &allocation);
- cr = cairo_create(surface);
- cairo_rectangle(cr, allocation.x, allocation.y,
- allocation.width, allocation.height);
- cairo_clip(cr);
- cairo_push_group(cr);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- terminal_set_color(terminal, cr, terminal->color_scheme->border);
- cairo_paint(cr);
-
- cairo_set_scaled_font(cr, terminal->font_normal);
-
- extents = terminal->extents;
- side_margin = (allocation.width - terminal->width * extents.max_x_advance) / 2;
- top_margin = (allocation.height - terminal->height * extents.height) / 2;
-
- cairo_set_line_width(cr, 1.0);
- cairo_translate(cr, allocation.x + side_margin,
- allocation.y + top_margin);
- /* paint the background */
- for (row = 0; row < terminal->height; row++) {
- for (col = 0; col < terminal->width; col++) {
- /* get the attributes for this character cell */
- terminal_decode_attr(terminal, row, col, &attr);
-
- if (attr.attr.bg == terminal->color_scheme->border)
- continue;
-
- terminal_set_color(terminal, cr, attr.attr.bg);
- cairo_move_to(cr, col * extents.max_x_advance,
- row * extents.height);
- cairo_rel_line_to(cr, extents.max_x_advance, 0);
- cairo_rel_line_to(cr, 0, extents.height);
- cairo_rel_line_to(cr, -extents.max_x_advance, 0);
- cairo_close_path(cr);
- cairo_fill(cr);
- }
- }
-
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
-
- /* paint the foreground */
- glyph_run_init(&run, terminal, cr);
- for (row = 0; row < terminal->height; row++) {
- p_row = terminal_get_row(terminal, row);
- for (col = 0; col < terminal->width; col++) {
- /* get the attributes for this character cell */
- terminal_decode_attr(terminal, row, col, &attr);
-
- glyph_run_flush(&run, attr);
-
- text_x = col * extents.max_x_advance;
- text_y = extents.ascent + row * extents.height;
- if (attr.attr.a & ATTRMASK_UNDERLINE) {
- terminal_set_color(terminal, cr, attr.attr.fg);
- cairo_move_to(cr, text_x, (double)text_y + 1.5);
- cairo_line_to(cr, text_x + extents.max_x_advance, (double) text_y + 1.5);
- cairo_stroke(cr);
- }
-
- glyph_run_add(&run, text_x, text_y, &p_row[col]);
- }
- }
-
- attr.key = ~0;
- glyph_run_flush(&run, attr);
-
- if ((terminal->mode & MODE_SHOW_CURSOR) && !terminal->focused) {
- d = 0.5;
-
- cairo_set_line_width(cr, 1);
- cairo_move_to(cr, terminal->column * extents.max_x_advance + d,
- terminal->row * extents.height + d);
- cairo_rel_line_to(cr, extents.max_x_advance - 2 * d, 0);
- cairo_rel_line_to(cr, 0, extents.height - 2 * d);
- cairo_rel_line_to(cr, -extents.max_x_advance + 2 * d, 0);
- cairo_close_path(cr);
-
- cairo_stroke(cr);
- }
-
- cairo_pop_group_to_source(cr);
- cairo_paint(cr);
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
-}
-
-static void
-resize_handler(struct window *window,
- int32_t pixel_width, int32_t pixel_height, void *data)
-{
- struct terminal *terminal = data;
- int32_t width, height;
-
- width = (pixel_width - 2 * terminal->margin) /
- (int32_t) terminal->extents.max_x_advance;
- height = (pixel_height - 2 * terminal->margin) /
- (int32_t) terminal->extents.height;
-
- if (terminal->fullscreen)
- window_set_child_size(terminal->window,
- pixel_width, pixel_height);
-
- terminal_resize(terminal, width, height);
-}
-
-static void
-terminal_draw(struct terminal *terminal)
-{
- window_draw(terminal->window);
- terminal_draw_contents(terminal);
- window_flush(terminal->window);
-}
-
-static void
-redraw_handler(struct window *window, void *data)
-{
- struct terminal *terminal = data;
-
- terminal_draw(terminal);
-}
-
-static void
-terminal_data(struct terminal *terminal, const char *data, size_t length);
-
-static void
-handle_char(struct terminal *terminal, union utf8_char utf8);
-
-static void
-handle_sgr(struct terminal *terminal, int code);
-
-static void
-handle_term_parameter(struct terminal *terminal, int code, int sr)
-{
- int i;
-
- if (terminal->escape_flags & ESC_FLAG_WHAT) {
- switch(code) {
- case 1: /* DECCKM */
- if (sr) terminal->key_mode = KM_APPLICATION;
- else terminal->key_mode = KM_NORMAL;
- break;
- case 2: /* DECANM */
- /* No VT52 support yet */
- terminal->g0 = CS_US;
- terminal->g1 = CS_US;
- terminal->cs = terminal->g0;
- break;
- case 3: /* DECCOLM */
- if (sr)
- terminal_resize(terminal, 132, 24);
- else
- terminal_resize(terminal, 80, 24);
-
- /* set columns, but also home cursor and clear screen */
- terminal->row = 0; terminal->column = 0;
- for (i = 0; i < terminal->height; i++) {
- memset(terminal_get_row(terminal, i),
- 0, terminal->data_pitch);
- attr_init(terminal_get_attr_row(terminal, i),
- terminal->curr_attr, terminal->width);
- }
- break;
- case 5: /* DECSCNM */
- if (sr) terminal->mode |= MODE_INVERSE;
- else terminal->mode &= ~MODE_INVERSE;
- break;
- case 6: /* DECOM */
- terminal->origin_mode = sr;
- if (terminal->origin_mode)
- terminal->row = terminal->margin_top;
- else
- terminal->row = 0;
- terminal->column = 0;
- break;
- case 7: /* DECAWM */
- if (sr) terminal->mode |= MODE_AUTOWRAP;
- else terminal->mode &= ~MODE_AUTOWRAP;
- break;
- case 8: /* DECARM */
- if (sr) terminal->mode |= MODE_AUTOREPEAT;
- else terminal->mode &= ~MODE_AUTOREPEAT;
- break;
- case 25:
- if (sr) terminal->mode |= MODE_SHOW_CURSOR;
- else terminal->mode &= ~MODE_SHOW_CURSOR;
- break;
- case 1037: /* deleteSendsDel */
- if (sr) terminal->mode |= MODE_DELETE_SENDS_DEL;
- else terminal->mode &= ~MODE_DELETE_SENDS_DEL;
- break;
- case 1039: /* altSendsEscape */
- if (sr) terminal->mode |= MODE_ALT_SENDS_ESC;
- else terminal->mode &= ~MODE_ALT_SENDS_ESC;
- break;
- default:
- fprintf(stderr, "Unknown parameter: ?%d\n", code);
- break;
- }
- } else {
- switch(code) {
- case 4: /* IRM */
- if (sr) terminal->mode |= MODE_IRM;
- else terminal->mode &= ~MODE_IRM;
- break;
- case 20: /* LNM */
- if (sr) terminal->mode |= MODE_LF_NEWLINE;
- else terminal->mode &= ~MODE_LF_NEWLINE;
- break;
- default:
- fprintf(stderr, "Unknown parameter: %d\n", code);
- break;
- }
- }
-}
-
-static void
-handle_dcs(struct terminal *terminal)
-{
-}
-
-static void
-handle_osc(struct terminal *terminal)
-{
- char *p;
- int code;
-
- terminal->escape[terminal->escape_length++] = '\0';
- p = &terminal->escape[2];
- code = strtol(p, &p, 10);
- if (*p == ';') p++;
-
- switch (code) {
- case 0: /* Icon name and window title */
- case 1: /* Icon label */
- case 2: /* Window title*/
- window_set_title(terminal->window, p);
- break;
- default:
- fprintf(stderr, "Unknown OSC escape code %d\n", code);
- break;
- }
-}
-
-static void
-handle_escape(struct terminal *terminal)
-{
- union utf8_char *row;
- struct attr *attr_row;
- char *p;
- int i, count, x, y, top, bottom;
- int args[10], set[10] = { 0, };
- char response[MAX_RESPONSE] = {0, };
- struct rectangle allocation;
-
- terminal->escape[terminal->escape_length++] = '\0';
- i = 0;
- p = &terminal->escape[2];
- while ((isdigit(*p) || *p == ';') && i < 10) {
- if (*p == ';') {
- if (!set[i]) {
- args[i] = 0;
- set[i] = 1;
- }
- p++;
- i++;
- } else {
- args[i] = strtol(p, &p, 10);
- set[i] = 1;
- }
- }
-
- switch (*p) {
- case '@': /* ICH */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- terminal_shift_line(terminal, count);
- break;
- case 'A': /* CUU */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- if (terminal->row - count >= terminal->margin_top)
- terminal->row -= count;
- else
- terminal->row = terminal->margin_top;
- break;
- case 'B': /* CUD */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- if (terminal->row + count <= terminal->margin_bottom)
- terminal->row += count;
- else
- terminal->row = terminal->margin_bottom;
- break;
- case 'C': /* CUF */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- if ((terminal->column + count) < terminal->width)
- terminal->column += count;
- else
- terminal->column = terminal->width - 1;
- break;
- case 'D': /* CUB */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- if ((terminal->column - count) >= 0)
- terminal->column -= count;
- else
- terminal->column = 0;
- break;
- case 'E': /* CNL */
- count = set[0] ? args[0] : 1;
- if (terminal->row + count <= terminal->margin_bottom)
- terminal->row += count;
- else
- terminal->row = terminal->margin_bottom;
- terminal->column = 0;
- break;
- case 'F': /* CPL */
- count = set[0] ? args[0] : 1;
- if (terminal->row - count >= terminal->margin_top)
- terminal->row -= count;
- else
- terminal->row = terminal->margin_top;
- terminal->column = 0;
- break;
- case 'G': /* CHA */
- y = set[0] ? args[0] : 1;
- y = y <= 0 ? 1 : y > terminal->width ? terminal->width : y;
-
- terminal->column = y - 1;
- break;
- case 'f': /* HVP */
- case 'H': /* CUP */
- x = (set[1] ? args[1] : 1) - 1;
- x = x < 0 ? 0 :
- (x >= terminal->width ? terminal->width - 1 : x);
-
- y = (set[0] ? args[0] : 1) - 1;
- if (terminal->origin_mode) {
- y += terminal->margin_top;
- y = y < terminal->margin_top ? terminal->margin_top :
- (y > terminal->margin_bottom ? terminal->margin_bottom : y);
- } else {
- y = y < 0 ? 0 :
- (y >= terminal->height ? terminal->height - 1 : y);
- }
-
- terminal->row = y;
- terminal->column = x;
- break;
- case 'I': /* CHT */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- while (count > 0 && terminal->column < terminal->width) {
- if (terminal->tab_ruler[terminal->column]) count--;
- terminal->column++;
- }
- terminal->column--;
- break;
- case 'J': /* ED */
- row = terminal_get_row(terminal, terminal->row);
- attr_row = terminal_get_attr_row(terminal, terminal->row);
- if (!set[0] || args[0] == 0 || args[0] > 2) {
- memset(&row[terminal->column],
- 0, (terminal->width - terminal->column) * sizeof(union utf8_char));
- attr_init(&attr_row[terminal->column],
- terminal->curr_attr, terminal->width - terminal->column);
- for (i = terminal->row + 1; i < terminal->height; i++) {
- memset(terminal_get_row(terminal, i),
- 0, terminal->data_pitch);
- attr_init(terminal_get_attr_row(terminal, i),
- terminal->curr_attr, terminal->width);
- }
- } else if (args[0] == 1) {
- memset(row, 0, (terminal->column+1) * sizeof(union utf8_char));
- attr_init(attr_row, terminal->curr_attr, terminal->column+1);
- for (i = 0; i < terminal->row; i++) {
- memset(terminal_get_row(terminal, i),
- 0, terminal->data_pitch);
- attr_init(terminal_get_attr_row(terminal, i),
- terminal->curr_attr, terminal->width);
- }
- } else if (args[0] == 2) {
- for (i = 0; i < terminal->height; i++) {
- memset(terminal_get_row(terminal, i),
- 0, terminal->data_pitch);
- attr_init(terminal_get_attr_row(terminal, i),
- terminal->curr_attr, terminal->width);
- }
- }
- break;
- case 'K': /* EL */
- row = terminal_get_row(terminal, terminal->row);
- attr_row = terminal_get_attr_row(terminal, terminal->row);
- if (!set[0] || args[0] == 0 || args[0] > 2) {
- memset(&row[terminal->column], 0,
- (terminal->width - terminal->column) * sizeof(union utf8_char));
- attr_init(&attr_row[terminal->column], terminal->curr_attr,
- terminal->width - terminal->column);
- } else if (args[0] == 1) {
- memset(row, 0, (terminal->column+1) * sizeof(union utf8_char));
- attr_init(attr_row, terminal->curr_attr, terminal->column+1);
- } else if (args[0] == 2) {
- memset(row, 0, terminal->data_pitch);
- attr_init(attr_row, terminal->curr_attr, terminal->width);
- }
- break;
- case 'L': /* IL */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- if (terminal->row >= terminal->margin_top &&
- terminal->row < terminal->margin_bottom)
- {
- top = terminal->margin_top;
- terminal->margin_top = terminal->row;
- terminal_scroll(terminal, 0 - count);
- terminal->margin_top = top;
- } else if (terminal->row == terminal->margin_bottom) {
- memset(terminal_get_row(terminal, terminal->row),
- 0, terminal->data_pitch);
- attr_init(terminal_get_attr_row(terminal, terminal->row),
- terminal->curr_attr, terminal->width);
- }
- break;
- case 'M': /* DL */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- if (terminal->row >= terminal->margin_top &&
- terminal->row < terminal->margin_bottom)
- {
- top = terminal->margin_top;
- terminal->margin_top = terminal->row;
- terminal_scroll(terminal, count);
- terminal->margin_top = top;
- } else if (terminal->row == terminal->margin_bottom) {
- memset(terminal_get_row(terminal, terminal->row),
- 0, terminal->data_pitch);
- }
- break;
- case 'P': /* DCH */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- terminal_shift_line(terminal, 0 - count);
- break;
- case 'S': /* SU */
- terminal_scroll(terminal, set[0] ? args[0] : 1);
- break;
- case 'T': /* SD */
- terminal_scroll(terminal, 0 - (set[0] ? args[0] : 1));
- break;
- case 'X': /* ECH */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- if ((terminal->column + count) > terminal->width)
- count = terminal->width - terminal->column;
- row = terminal_get_row(terminal, terminal->row);
- attr_row = terminal_get_attr_row(terminal, terminal->row);
- memset(&row[terminal->column], 0, count * sizeof(union utf8_char));
- attr_init(&attr_row[terminal->column], terminal->curr_attr, count);
- break;
- case 'Z': /* CBT */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- while (count > 0 && terminal->column >= 0) {
- if (terminal->tab_ruler[terminal->column]) count--;
- terminal->column--;
- }
- terminal->column++;
- break;
- case '`': /* HPA */
- y = set[0] ? args[0] : 1;
- y = y <= 0 ? 1 : y > terminal->width ? terminal->width : y;
-
- terminal->column = y - 1;
- break;
- case 'b': /* REP */
- count = set[0] ? args[0] : 1;
- if (count == 0) count = 1;
- if (terminal->last_char.byte[0])
- for (i = 0; i < count; i++)
- handle_char(terminal, terminal->last_char);
- terminal->last_char.byte[0] = 0;
- break;
- case 'c': /* Primary DA */
- write(terminal->master, "\e[?6c", 5);
- break;
- case 'd': /* VPA */
- x = set[0] ? args[0] : 1;
- x = x <= 0 ? 1 : x > terminal->height ? terminal->height : x;
-
- terminal->row = x - 1;
- break;
- case 'g': /* TBC */
- if (!set[0] || args[0] == 0) {
- terminal->tab_ruler[terminal->column] = 0;
- } else if (args[0] == 3) {
- memset(terminal->tab_ruler, 0, terminal->width);
- }
- break;
- case 'h': /* SM */
- for(i = 0; i < 10 && set[i]; i++) {
- handle_term_parameter(terminal, args[i], 1);
- }
- break;
- case 'l': /* RM */
- for(i = 0; i < 10 && set[i]; i++) {
- handle_term_parameter(terminal, args[i], 0);
- }
- break;
- case 'm': /* SGR */
- for(i = 0; i < 10; i++) {
- if (i <= 7 && set[i] && set[i + 1] &&
- set[i + 2] && args[i + 1] == 5)
- {
- if (args[i] == 38) {
- handle_sgr(terminal, args[i + 2] + 256);
- break;
- } else if (args[i] == 48) {
- handle_sgr(terminal, args[i + 2] + 512);
- break;
- }
- }
- if(set[i]) {
- handle_sgr(terminal, args[i]);
- } else if(i == 0) {
- handle_sgr(terminal, 0);
- break;
- } else {
- break;
- }
- }
- break;
- case 'n': /* DSR */
- i = set[0] ? args[0] : 0;
- if (i == 0 || i == 5) {
- write(terminal->master, "\e[0n", 4);
- } else if (i == 6) {
- snprintf(response, MAX_RESPONSE, "\e[%d;%dR",
- terminal->origin_mode ?
- terminal->row+terminal->margin_top : terminal->row+1,
- terminal->column+1);
- write(terminal->master, response, strlen(response));
- }
- break;
- case 'r':
- if(!set[0]) {
- terminal->margin_top = 0;
- terminal->margin_bottom = terminal->height-1;
- terminal->row = 0;
- terminal->column = 0;
- } else {
- top = (set[0] ? args[0] : 1) - 1;
- top = top < 0 ? 0 :
- (top >= terminal->height ? terminal->height - 1 : top);
- bottom = (set[1] ? args[1] : 1) - 1;
- bottom = bottom < 0 ? 0 :
- (bottom >= terminal->height ? terminal->height - 1 : bottom);
- if(bottom > top) {
- terminal->margin_top = top;
- terminal->margin_bottom = bottom;
- } else {
- terminal->margin_top = 0;
- terminal->margin_bottom = terminal->height-1;
- }
- if(terminal->origin_mode)
- terminal->row = terminal->margin_top;
- else
- terminal->row = 0;
- terminal->column = 0;
- }
- break;
- case 's':
- terminal->saved_row = terminal->row;
- terminal->saved_column = terminal->column;
- break;
- case 't': /* windowOps */
- if (!set[0]) break;
- switch (args[0]) {
- case 4: /* resize px */
- if (set[1] && set[2]) {
- window_set_child_size(terminal->window,
- args[2], args[1]);
- resize_handler(terminal->window,
- args[2], args[1], terminal);
- }
- break;
- case 8: /* resize ch */
- if (set[1] && set[2]) {
- terminal_resize(terminal, args[2], args[1]);
- }
- break;
- case 13: /* report position */
- window_get_child_allocation(terminal->window, &allocation);
- snprintf(response, MAX_RESPONSE, "\e[3;%d;%dt",
- allocation.x, allocation.y);
- write(terminal->master, response, strlen(response));
- break;
- case 14: /* report px */
- window_get_child_allocation(terminal->window, &allocation);
- snprintf(response, MAX_RESPONSE, "\e[4;%d;%dt",
- allocation.height, allocation.width);
- write(terminal->master, response, strlen(response));
- break;
- case 18: /* report ch */
- snprintf(response, MAX_RESPONSE, "\e[9;%d;%dt",
- terminal->height, terminal->width);
- write(terminal->master, response, strlen(response));
- break;
- case 21: /* report title */
- snprintf(response, MAX_RESPONSE, "\e]l%s\e\\",
- window_get_title(terminal->window));
- write(terminal->master, response, strlen(response));
- break;
- default:
- if (args[0] >= 24)
- terminal_resize(terminal, terminal->width, args[0]);
- else
- fprintf(stderr, "Unimplemented windowOp %d\n", args[0]);
- break;
- }
- case 'u':
- terminal->row = terminal->saved_row;
- terminal->column = terminal->saved_column;
- break;
- default:
- fprintf(stderr, "Unknown CSI escape: %c\n", *p);
- break;
- }
-}
-
-static void
-handle_non_csi_escape(struct terminal *terminal, char code)
-{
- switch(code) {
- case 'M': /* RI */
- terminal->row -= 1;
- if(terminal->row < terminal->margin_top) {
- terminal->row = terminal->margin_top;
- terminal_scroll(terminal, -1);
- }
- break;
- case 'E': /* NEL */
- terminal->column = 0;
- // fallthrough
- case 'D': /* IND */
- terminal->row += 1;
- if(terminal->row > terminal->margin_bottom) {
- terminal->row = terminal->margin_bottom;
- terminal_scroll(terminal, +1);
- }
- break;
- case 'c': /* RIS */
- terminal_init(terminal);
- break;
- case 'H': /* HTS */
- terminal->tab_ruler[terminal->column] = 1;
- break;
- case '7': /* DECSC */
- terminal->saved_row = terminal->row;
- terminal->saved_column = terminal->column;
- terminal->saved_attr = terminal->curr_attr;
- terminal->saved_origin_mode = terminal->origin_mode;
- terminal->saved_cs = terminal->cs;
- terminal->saved_g0 = terminal->g0;
- terminal->saved_g1 = terminal->g1;
- break;
- case '8': /* DECRC */
- terminal->row = terminal->saved_row;
- terminal->column = terminal->saved_column;
- terminal->curr_attr = terminal->saved_attr;
- terminal->origin_mode = terminal->saved_origin_mode;
- terminal->cs = terminal->saved_cs;
- terminal->g0 = terminal->saved_g0;
- terminal->g1 = terminal->saved_g1;
- break;
- case '=': /* DECPAM */
- terminal->key_mode = KM_APPLICATION;
- break;
- case '>': /* DECPNM */
- terminal->key_mode = KM_NORMAL;
- break;
- default:
- fprintf(stderr, "Unknown escape code: %c\n", code);
- break;
- }
-}
-
-static void
-handle_special_escape(struct terminal *terminal, char special, char code)
-{
- int i, numChars;
-
- if (special == '#') {
- switch(code) {
- case '8':
- /* fill with 'E', no cheap way to do this */
- memset(terminal->data, 0, terminal->data_pitch * terminal->height);
- numChars = terminal->width * terminal->height;
- for(i = 0; i < numChars; i++) {
- terminal->data[i].byte[0] = 'E';
- }
- break;
- default:
- fprintf(stderr, "Unknown HASH escape #%c\n", code);
- break;
- }
- } else if (special == '(' || special == ')') {
- switch(code) {
- case '0':
- if (special == '(')
- terminal->g0 = CS_SPECIAL;
- else
- terminal->g1 = CS_SPECIAL;
- break;
- case 'A':
- if (special == '(')
- terminal->g0 = CS_UK;
- else
- terminal->g1 = CS_UK;
- break;
- case 'B':
- if (special == '(')
- terminal->g0 = CS_US;
- else
- terminal->g1 = CS_US;
- break;
- default:
- fprintf(stderr, "Unknown character set %c\n", code);
- break;
- }
- } else {
- fprintf(stderr, "Unknown special escape %c%c\n", special, code);
- }
-}
-
-static void
-handle_sgr(struct terminal *terminal, int code)
-{
- switch(code) {
- case 0:
- terminal->curr_attr = terminal->color_scheme->default_attr;
- break;
- case 1:
- terminal->curr_attr.a |= ATTRMASK_BOLD;
- if (terminal->curr_attr.fg < 8)
- terminal->curr_attr.fg += 8;
- break;
- case 4:
- terminal->curr_attr.a |= ATTRMASK_UNDERLINE;
- break;
- case 5:
- terminal->curr_attr.a |= ATTRMASK_BLINK;
- break;
- case 8:
- terminal->curr_attr.a |= ATTRMASK_CONCEALED;
- break;
- case 2:
- case 21:
- case 22:
- terminal->curr_attr.a &= ~ATTRMASK_BOLD;
- if (terminal->curr_attr.fg < 16 && terminal->curr_attr.fg >= 8)
- terminal->curr_attr.fg -= 8;
- break;
- case 24:
- terminal->curr_attr.a &= ~ATTRMASK_UNDERLINE;
- break;
- case 25:
- terminal->curr_attr.a &= ~ATTRMASK_BLINK;
- break;
- case 7:
- case 26:
- terminal->curr_attr.a |= ATTRMASK_INVERSE;
- break;
- case 27:
- terminal->curr_attr.a &= ~ATTRMASK_INVERSE;
- break;
- case 28:
- terminal->curr_attr.a &= ~ATTRMASK_CONCEALED;
- break;
- case 39:
- terminal->curr_attr.fg = terminal->color_scheme->default_attr.fg;
- break;
- case 49:
- terminal->curr_attr.bg = terminal->color_scheme->default_attr.bg;
- break;
- default:
- if(code >= 30 && code <= 37) {
- terminal->curr_attr.fg = code - 30;
- if (terminal->curr_attr.a & ATTRMASK_BOLD)
- terminal->curr_attr.fg += 8;
- } else if(code >= 40 && code <= 47) {
- terminal->curr_attr.bg = code - 40;
- } else if (code >= 90 && code <= 97) {
- terminal->curr_attr.fg = code - 90 + 8;
- } else if (code >= 100 && code <= 107) {
- terminal->curr_attr.bg = code - 100 + 8;
- } else if(code >= 256 && code < 512) {
- terminal->curr_attr.fg = code - 256;
- } else if(code >= 512 && code < 768) {
- terminal->curr_attr.bg = code - 512;
- } else {
- fprintf(stderr, "Unknown SGR code: %d\n", code);
- }
- break;
- }
-}
-
-/* Returns 1 if c was special, otherwise 0 */
-static int
-handle_special_char(struct terminal *terminal, char c)
-{
- union utf8_char *row;
- struct attr *attr_row;
-
- row = terminal_get_row(terminal, terminal->row);
- attr_row = terminal_get_attr_row(terminal, terminal->row);
-
- switch(c) {
- case '\r':
- terminal->column = 0;
- break;
- case '\n':
- if (terminal->mode & MODE_LF_NEWLINE) {
- terminal->column = 0;
- }
- /* fallthrough */
- case '\v':
- case '\f':
- terminal->row++;
- if(terminal->row > terminal->margin_bottom) {
- terminal->row = terminal->margin_bottom;
- terminal_scroll(terminal, +1);
- }
-
- break;
- case '\t':
- while (terminal->column < terminal->width) {
- if (terminal->tab_ruler[terminal->column]) break;
- if (terminal->mode & MODE_IRM)
- terminal_shift_line(terminal, +1);
- row[terminal->column].byte[0] = ' ';
- row[terminal->column].byte[1] = '\0';
- attr_row[terminal->column] = terminal->curr_attr;
- terminal->column++;
- }
- if (terminal->column >= terminal->width) {
- terminal->column = terminal->width - 1;
- }
-
- break;
- case '\b':
- if (terminal->column >= terminal->width) {
- terminal->column = terminal->width - 2;
- } else if (terminal->column > 0) {
- terminal->column--;
- } else if (terminal->mode & MODE_AUTOWRAP) {
- terminal->column = terminal->width - 1;
- terminal->row -= 1;
- if (terminal->row < terminal->margin_top) {
- terminal->row = terminal->margin_top;
- terminal_scroll(terminal, -1);
- }
- }
-
- break;
- case '\a':
- /* Bell */
- break;
- case '\x0E': /* SO */
- terminal->cs = terminal->g1;
- break;
- case '\x0F': /* SI */
- terminal->cs = terminal->g0;
- break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static void
-handle_char(struct terminal *terminal, union utf8_char utf8)
-{
- union utf8_char *row;
- struct attr *attr_row;
-
- if (handle_special_char(terminal, utf8.byte[0])) return;
-
- apply_char_set(terminal->cs, &utf8);
-
- /* There are a whole lot of non-characters, control codes,
- * and formatting codes that should probably be ignored,
- * for example: */
- if (strncmp((char*) utf8.byte, "\xEF\xBB\xBF", 3) == 0) {
- /* BOM, ignore */
- return;
- }
-
- /* Some of these non-characters should be translated, e.g.: */
- if (utf8.byte[0] < 32) {
- utf8.byte[0] = utf8.byte[0] + 64;
- }
-
- /* handle right margin effects */
- if (terminal->column >= terminal->width) {
- if (terminal->mode & MODE_AUTOWRAP) {
- terminal->column = 0;
- terminal->row += 1;
- if (terminal->row > terminal->margin_bottom) {
- terminal->row = terminal->margin_bottom;
- terminal_scroll(terminal, +1);
- }
- } else {
- terminal->column--;
- }
- }
-
- row = terminal_get_row(terminal, terminal->row);
- attr_row = terminal_get_attr_row(terminal, terminal->row);
-
- if (terminal->mode & MODE_IRM)
- terminal_shift_line(terminal, +1);
- row[terminal->column] = utf8;
- attr_row[terminal->column++] = terminal->curr_attr;
-
- if (utf8.ch != terminal->last_char.ch)
- terminal->last_char = utf8;
-}
-
-static void
-escape_append_utf8(struct terminal *terminal, union utf8_char utf8)
-{
- int len, i;
-
- if ((utf8.byte[0] & 0x80) == 0x00) len = 1;
- else if ((utf8.byte[0] & 0xE0) == 0xC0) len = 2;
- else if ((utf8.byte[0] & 0xF0) == 0xE0) len = 3;
- else if ((utf8.byte[0] & 0xF8) == 0xF0) len = 4;
- else len = 1; /* Invalid, cannot happen */
-
- if (terminal->escape_length + len <= MAX_ESCAPE) {
- for (i = 0; i < len; i++)
- terminal->escape[terminal->escape_length + i] = utf8.byte[i];
- terminal->escape_length += len;
- } else if (terminal->escape_length < MAX_ESCAPE) {
- terminal->escape[terminal->escape_length++] = 0;
- }
-}
-
-static void
-terminal_data(struct terminal *terminal, const char *data, size_t length)
-{
- int i;
- union utf8_char utf8;
- enum utf8_state parser_state;
-
- for (i = 0; i < length; i++) {
- parser_state =
- utf8_next_char(&terminal->state_machine, data[i]);
- switch(parser_state) {
- case utf8state_accept:
- utf8.ch = terminal->state_machine.s.ch;
- break;
- case utf8state_reject:
- /* the unicode replacement character */
- utf8.byte[0] = 0xEF;
- utf8.byte[1] = 0xBF;
- utf8.byte[2] = 0xBD;
- utf8.byte[3] = 0x00;
- break;
- default:
- continue;
- }
-
- /* assume escape codes never use non-ASCII characters */
- switch (terminal->state) {
- case escape_state_escape:
- escape_append_utf8(terminal, utf8);
- switch (utf8.byte[0]) {
- case 'P': /* DCS */
- terminal->state = escape_state_dcs;
- break;
- case '[': /* CSI */
- terminal->state = escape_state_csi;
- break;
- case ']': /* OSC */
- terminal->state = escape_state_osc;
- break;
- case '#':
- case '(':
- case ')': /* special */
- terminal->state = escape_state_special;
- break;
- case '^': /* PM (not implemented) */
- case '_': /* APC (not implemented) */
- terminal->state = escape_state_ignore;
- break;
- default:
- terminal->state = escape_state_normal;
- handle_non_csi_escape(terminal, utf8.byte[0]);
- break;
- }
- continue;
- case escape_state_csi:
- if (handle_special_char(terminal, utf8.byte[0]) != 0) {
- /* do nothing */
- } else if (utf8.byte[0] == '?') {
- terminal->escape_flags |= ESC_FLAG_WHAT;
- } else if (utf8.byte[0] == '>') {
- terminal->escape_flags |= ESC_FLAG_GT;
- } else if (utf8.byte[0] == '!') {
- terminal->escape_flags |= ESC_FLAG_BANG;
- } else if (utf8.byte[0] == '$') {
- terminal->escape_flags |= ESC_FLAG_CASH;
- } else if (utf8.byte[0] == '\'') {
- terminal->escape_flags |= ESC_FLAG_SQUOTE;
- } else if (utf8.byte[0] == '"') {
- terminal->escape_flags |= ESC_FLAG_DQUOTE;
- } else if (utf8.byte[0] == ' ') {
- terminal->escape_flags |= ESC_FLAG_SPACE;
- } else {
- escape_append_utf8(terminal, utf8);
- if (terminal->escape_length >= MAX_ESCAPE)
- terminal->state = escape_state_normal;
- }
-
- if (isalpha(utf8.byte[0]) || utf8.byte[0] == '@' ||
- utf8.byte[0] == '`')
- {
- terminal->state = escape_state_normal;
- handle_escape(terminal);
- } else {
- }
- continue;
- case escape_state_inner_escape:
- if (utf8.byte[0] == '\\') {
- terminal->state = escape_state_normal;
- if (terminal->outer_state == escape_state_dcs) {
- handle_dcs(terminal);
- } else if (terminal->outer_state == escape_state_osc) {
- handle_osc(terminal);
- }
- } else if (utf8.byte[0] == '\e') {
- terminal->state = terminal->outer_state;
- escape_append_utf8(terminal, utf8);
- if (terminal->escape_length >= MAX_ESCAPE)
- terminal->state = escape_state_normal;
- } else {
- terminal->state = terminal->outer_state;
- if (terminal->escape_length < MAX_ESCAPE)
- terminal->escape[terminal->escape_length++] = '\e';
- escape_append_utf8(terminal, utf8);
- if (terminal->escape_length >= MAX_ESCAPE)
- terminal->state = escape_state_normal;
- }
- continue;
- case escape_state_dcs:
- case escape_state_osc:
- case escape_state_ignore:
- if (utf8.byte[0] == '\e') {
- terminal->outer_state = terminal->state;
- terminal->state = escape_state_inner_escape;
- } else if (utf8.byte[0] == '\a' && terminal->state == escape_state_osc) {
- terminal->state = escape_state_normal;
- handle_osc(terminal);
- } else {
- escape_append_utf8(terminal, utf8);
- if (terminal->escape_length >= MAX_ESCAPE)
- terminal->state = escape_state_normal;
- }
- continue;
- case escape_state_special:
- escape_append_utf8(terminal, utf8);
- terminal->state = escape_state_normal;
- if (isdigit(utf8.byte[0]) || isalpha(utf8.byte[0])) {
- handle_special_escape(terminal, terminal->escape[1],
- utf8.byte[0]);
- }
- continue;
- default:
- break;
- }
-
- /* this is valid, because ASCII characters are never used to
- * introduce a multibyte sequence in UTF-8 */
- if (utf8.byte[0] == '\e') {
- terminal->state = escape_state_escape;
- terminal->outer_state = escape_state_normal;
- terminal->escape[0] = '\e';
- terminal->escape_length = 1;
- terminal->escape_flags = 0;
- } else {
- handle_char(terminal, utf8);
- } /* if */
- } /* for */
-
- window_schedule_redraw(terminal->window);
-}
-
-static void
-selection_listener_send(void *data, struct wl_selection *selection,
- const char *mime_type, int fd)
-{
- struct terminal *terminal = data;
-
- fprintf(stderr, "selection send, fd is %d\n", fd);
- terminal_send_selection(terminal, fd);
- close(fd);
-}
-
-static void
-selection_listener_cancelled(void *data, struct wl_selection *selection)
-{
- fprintf(stderr, "selection cancelled\n");
- wl_selection_destroy(selection);
-}
-
-static const struct wl_selection_listener selection_listener = {
- selection_listener_send,
- selection_listener_cancelled
-};
-
-static int
-handle_bound_key(struct terminal *terminal,
- struct input *input, uint32_t sym, uint32_t time)
-{
- struct wl_shell *shell;
-
- switch (sym) {
- case XK_C:
- shell = display_get_shell(terminal->display);
- terminal->selection = wl_shell_create_selection(shell);
- wl_selection_add_listener(terminal->selection,
- &selection_listener, terminal);
- wl_selection_offer(terminal->selection, "text/plain");
- wl_selection_activate(terminal->selection,
- input_get_input_device(input), time);
-
- return 1;
- case XK_V:
- /* Just pass the master fd of the pty to receive the
- * selection. */
- if (input_offers_mime_type(input, "text/plain"))
- input_receive_mime_type(input, "text/plain",
- terminal->master);
- return 1;
- case XK_X:
- /* cut selection; terminal doesn't do cut */
- return 0;
- default:
- return 0;
- }
-}
-
-static void
-key_handler(struct window *window, struct input *input, uint32_t time,
- uint32_t key, uint32_t sym, uint32_t state, void *data)
-{
- struct terminal *terminal = data;
- char ch[MAX_RESPONSE];
- uint32_t modifiers;
- int len = 0;
-
- modifiers = input_get_modifiers(input);
- if ((modifiers & XKB_COMMON_CONTROL_MASK) &&
- (modifiers & XKB_COMMON_SHIFT_MASK) &&
- state && handle_bound_key(terminal, input, sym, 0))
- return;
-
- switch (sym) {
- case XK_F11:
- if (!state)
- break;
- terminal->fullscreen ^= 1;
- window_set_fullscreen(window, terminal->fullscreen);
- window_schedule_redraw(terminal->window);
- break;
-
- case XK_BackSpace:
- case XK_Tab:
- case XK_Linefeed:
- case XK_Clear:
- case XK_Pause:
- case XK_Scroll_Lock:
- case XK_Sys_Req:
- case XK_Escape:
- ch[len++] = sym & 0x7f;
- break;
-
- case XK_Return:
- if (terminal->mode & MODE_LF_NEWLINE) {
- ch[len++] = 0x0D;
- ch[len++] = 0x0A;
- } else {
- ch[len++] = 0x0D;
- }
- break;
-
- case XK_Shift_L:
- case XK_Shift_R:
- case XK_Control_L:
- case XK_Control_R:
- case XK_Alt_L:
- case XK_Alt_R:
- break;
-
- case XK_Insert:
- len = function_key_response('[', 2, modifiers, '~', ch);
- break;
- case XK_Delete:
- if (terminal->mode & MODE_DELETE_SENDS_DEL) {
- ch[len++] = '\x04';
- } else {
- len = function_key_response('[', 3, modifiers, '~', ch);
- }
- break;
- case XK_Page_Up:
- len = function_key_response('[', 5, modifiers, '~', ch);
- break;
- case XK_Page_Down:
- len = function_key_response('[', 6, modifiers, '~', ch);
- break;
- case XK_F1:
- len = function_key_response('O', 1, modifiers, 'P', ch);
- break;
- case XK_F2:
- len = function_key_response('O', 1, modifiers, 'Q', ch);
- break;
- case XK_F3:
- len = function_key_response('O', 1, modifiers, 'R', ch);
- break;
- case XK_F4:
- len = function_key_response('O', 1, modifiers, 'S', ch);
- break;
- case XK_F5:
- len = function_key_response('[', 15, modifiers, '~', ch);
- break;
- case XK_F6:
- len = function_key_response('[', 17, modifiers, '~', ch);
- break;
- case XK_F7:
- len = function_key_response('[', 18, modifiers, '~', ch);
- break;
- case XK_F8:
- len = function_key_response('[', 19, modifiers, '~', ch);
- break;
- case XK_F9:
- len = function_key_response('[', 20, modifiers, '~', ch);
- break;
- case XK_F10:
- len = function_key_response('[', 21, modifiers, '~', ch);
- break;
- case XK_F12:
- len = function_key_response('[', 24, modifiers, '~', ch);
- break;
- default:
- /* Handle special keys with alternate mappings */
- len = apply_key_map(terminal->key_mode, sym, modifiers, ch);
- if (len != 0) break;
-
- if (modifiers & XKB_COMMON_CONTROL_MASK) {
- if (sym >= '3' && sym <= '7')
- sym = (sym & 0x1f) + 8;
-
- if (!((sym >= '!' && sym <= '/') ||
- (sym >= '8' && sym <= '?') ||
- (sym >= '0' && sym <= '2'))) sym = sym & 0x1f;
- else if (sym == '2') sym = 0x00;
- else if (sym == '/') sym = 0x1F;
- else if (sym == '8' || sym == '?') sym = 0x7F;
- } else if ((terminal->mode & MODE_ALT_SENDS_ESC) &&
- (modifiers & XKB_COMMON_MOD1_MASK))
- {
- ch[len++] = 0x1b;
- } else if (modifiers & XKB_COMMON_MOD1_MASK) {
- sym = sym | 0x80;
- }
-
- if (sym < 256)
- ch[len++] = sym;
- break;
- }
-
- if (state && len > 0)
- write(terminal->master, ch, len);
-}
-
-static void
-keyboard_focus_handler(struct window *window,
- struct input *device, void *data)
-{
- struct terminal *terminal = data;
-
- terminal->focused = (device != NULL);
- window_schedule_redraw(terminal->window);
-}
-
-static void
-button_handler(struct window *window,
- struct input *input, uint32_t time,
- int button, int state, void *data)
-{
- struct terminal *terminal = data;
-
- switch (button) {
- case 272:
- if (state) {
- terminal->dragging = 1;
- terminal->selection_active = 0;
- input_get_position(input,
- &terminal->selection_start_x,
- &terminal->selection_start_y);
- terminal->selection_end_x = terminal->selection_start_x;
- terminal->selection_end_y = terminal->selection_start_y;
- window_schedule_redraw(window);
- } else {
- terminal->dragging = 0;
- }
- break;
- }
-}
-
-static int
-motion_handler(struct window *window,
- struct input *input, uint32_t time,
- int32_t x, int32_t y,
- int32_t sx, int32_t sy, void *data)
-{
- struct terminal *terminal = data;
-
- if (terminal->dragging) {
- terminal->selection_active = 1;
- input_get_position(input,
- &terminal->selection_end_x,
- &terminal->selection_end_y);
- window_schedule_redraw(window);
- }
-
- return POINTER_IBEAM;
-}
-
-static struct terminal *
-terminal_create(struct display *display, int fullscreen)
-{
- struct terminal *terminal;
- cairo_surface_t *surface;
- cairo_t *cr;
-
- terminal = malloc(sizeof *terminal);
- if (terminal == NULL)
- return terminal;
-
- memset(terminal, 0, sizeof *terminal);
- terminal->fullscreen = fullscreen;
- terminal->color_scheme = &DEFAULT_COLORS;
- terminal_init(terminal);
- terminal->margin_top = 0;
- terminal->margin_bottom = -1;
- terminal->window = window_create(display, 500, 400);
- window_set_title(terminal->window, "Wayland Terminal");
-
- init_state_machine(&terminal->state_machine);
- init_color_table(terminal);
-
- terminal->display = display;
- terminal->margin = 5;
-
- window_set_user_data(terminal->window, terminal);
- window_set_redraw_handler(terminal->window, redraw_handler);
- window_set_resize_handler(terminal->window, resize_handler);
-
- window_set_key_handler(terminal->window, key_handler);
- window_set_keyboard_focus_handler(terminal->window,
- keyboard_focus_handler);
- window_set_button_handler(terminal->window, button_handler);
- window_set_motion_handler(terminal->window, motion_handler);
-
- surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
- cr = cairo_create(surface);
- cairo_set_font_size(cr, 14);
- cairo_select_font_face (cr, "mono",
- CAIRO_FONT_SLANT_NORMAL,
- CAIRO_FONT_WEIGHT_BOLD);
- terminal->font_bold = cairo_get_scaled_font (cr);
- cairo_scaled_font_reference(terminal->font_bold);
-
- cairo_select_font_face (cr, "mono",
- CAIRO_FONT_SLANT_NORMAL,
- CAIRO_FONT_WEIGHT_NORMAL);
- terminal->font_normal = cairo_get_scaled_font (cr);
- cairo_scaled_font_reference(terminal->font_normal);
-
- cairo_font_extents(cr, &terminal->extents);
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
-
- terminal_resize(terminal, 80, 24);
- terminal_draw(terminal);
-
- return terminal;
-}
-
-static gboolean
-io_handler(GIOChannel *source,
- GIOCondition condition,
- gpointer data)
-{
- struct terminal *terminal = data;
- gchar buffer[256];
- gsize bytes_read;
- GError *error = NULL;
-
- if(condition == G_IO_HUP)
- exit(0);
-
- g_io_channel_read_chars(source, buffer, sizeof buffer,
- &bytes_read, &error);
-
- terminal_data(terminal, buffer, bytes_read);
-
- return TRUE;
-}
-
-static int
-terminal_run(struct terminal *terminal, const char *path)
-{
- int master;
- pid_t pid;
-
- pid = forkpty(&master, NULL, NULL, NULL);
- if (pid == 0) {
- setenv("TERM", "xterm-256color", 1);
- setenv("COLORTERM", "xterm-256color", 1);
- if (execl(path, path, NULL)) {
- printf("exec failed: %m\n");
- exit(EXIT_FAILURE);
- }
- } else if (pid < 0) {
- fprintf(stderr, "failed to fork and create pty (%m).\n");
- return -1;
- }
-
- terminal->master = master;
- terminal->channel = g_io_channel_unix_new(master);
- fcntl(master, F_SETFL, O_NONBLOCK);
- g_io_add_watch(terminal->channel, G_IO_IN, io_handler, terminal);
- g_io_add_watch(terminal->channel, G_IO_HUP, io_handler, terminal);
-
- return 0;
-}
-
-static const GOptionEntry option_entries[] = {
- { "fullscreen", 'f', 0, G_OPTION_ARG_NONE,
- &option_fullscreen, "Run in fullscreen mode" },
- { NULL }
-};
-
-int main(int argc, char *argv[])
-{
- struct display *d;
- struct terminal *terminal;
-
- d = display_create(&argc, &argv, option_entries);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
- terminal = terminal_create(d, option_fullscreen);
- if (terminal_run(terminal, "/bin/bash"))
- exit(EXIT_FAILURE);
-
- display_run(d);
-
- return 0;
-}
diff --git a/clients/view.c b/clients/view.c
deleted file mode 100644
index 05edf3f..0000000
--- a/clients/view.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- * Copyright © 2009 Chris Wilson
- *
- * 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-#include <time.h>
-#include <cairo.h>
-#include <glib.h>
-#include <linux/input.h>
-
-#include <glib/poppler-document.h>
-#include <glib/poppler-page.h>
-
-#include "wayland-util.h"
-#include "wayland-client.h"
-#include "wayland-glib.h"
-
-#include "window.h"
-
-struct view {
- struct window *window;
- struct display *display;
-
- PopplerDocument *document;
- int page;
- int fullscreen;
-};
-
-static void
-view_draw(struct view *view)
-{
- struct rectangle allocation;
- cairo_surface_t *surface;
- cairo_t *cr;
- PopplerPage *page;
- double width, height, doc_aspect, window_aspect, scale;
-
- window_draw(view->window);
-
- window_get_child_allocation(view->window, &allocation);
-
- surface = window_get_surface(view->window);
-
- cr = cairo_create(surface);
- cairo_rectangle(cr, allocation.x, allocation.y,
- allocation.width, allocation.height);
- cairo_clip(cr);
-
- cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint(cr);
-
- if(!view->document) {
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
- window_flush(view->window);
- return;
- }
-
- page = poppler_document_get_page(view->document, view->page);
- poppler_page_get_size(page, &width, &height);
- doc_aspect = width / height;
- window_aspect = (double) allocation.width / allocation.height;
- if (doc_aspect < window_aspect)
- scale = allocation.height / height;
- else
- scale = allocation.width / width;
- cairo_translate(cr, allocation.x, allocation.y);
- cairo_scale(cr, scale, scale);
- cairo_translate(cr,
- (allocation.width - width * scale) / 2 / scale,
- (allocation.height - height * scale) / 2 / scale);
- cairo_rectangle(cr, 0, 0, width, height);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_fill(cr);
- poppler_page_render(page, cr);
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
- g_object_unref(G_OBJECT(page));
- window_flush(view->window);
-}
-
-static void
-redraw_handler(struct window *window, void *data)
-{
- struct view *view = data;
-
- view_draw(view);
-}
-
-static void
-view_page_up(struct view *view)
-{
- if(view->page <= 0)
- return;
-
- view->page--;
- window_schedule_redraw(view->window);
-}
-
-static void
-view_page_down(struct view *view)
-{
- if(!view->document ||
- view->page >= poppler_document_get_n_pages(view->document) - 1) {
- return;
- }
-
- view->page++;
- window_schedule_redraw(view->window);
-}
-
-static void
-button_handler(struct window *window, struct input *input, uint32_t time,
- int button, int state, void *data)
-{
- struct view *view = data;
-
- if(!state)
- return;
-
- switch(button) {
- case 275:
- view_page_up(view);
- break;
- case 276:
- view_page_down(view);
- break;
- default:
- break;
- }
-}
-
-static void
-key_handler(struct window *window, struct input *input, uint32_t time,
- uint32_t key, uint32_t unicode, uint32_t state, void *data)
-{
- struct view *view = data;
-
- if(!state)
- return;
-
- switch (key) {
- case KEY_F11:
- view->fullscreen ^= 1;
- window_set_fullscreen(window, view->fullscreen);
- window_schedule_redraw(view->window);
- break;
- case KEY_SPACE:
- case KEY_PAGEDOWN:
- case KEY_RIGHT:
- case KEY_DOWN:
- view_page_down(view);
- break;
- case KEY_BACKSPACE:
- case KEY_PAGEUP:
- case KEY_LEFT:
- case KEY_UP:
- view_page_up(view);
- break;
- default:
- break;
- }
-}
-
-static void
-keyboard_focus_handler(struct window *window,
- struct input *device, void *data)
-{
- struct view *view = data;
- window_schedule_redraw(view->window);
-}
-
-static struct view *
-view_create(struct display *display, uint32_t key, const char *filename)
-{
- struct view *view;
- gchar *basename;
- gchar *title;
- GFile *file = NULL;
- GError *error = NULL;
-
- view = malloc(sizeof *view);
- if (view == NULL)
- return view;
- memset(view, 0, sizeof *view);
-
- file = g_file_new_for_commandline_arg(filename);
- basename = g_file_get_basename(file);
- if(!basename) {
- title = "Wayland View";
- } else {
- title = g_strdup_printf("Wayland View - %s", basename);
- g_free(basename);
- }
-
- view->document = poppler_document_new_from_file(g_file_get_uri(file),
- NULL, &error);
-
- if(error) {
- title = "File not found";
- }
-
- view->window = window_create(display, 500, 400);
- window_set_title(view->window, title);
- view->display = display;
-
- window_set_user_data(view->window, view);
- window_set_redraw_handler(view->window, redraw_handler);
- window_set_key_handler(view->window, key_handler);
- window_set_keyboard_focus_handler(view->window,
- keyboard_focus_handler);
- window_set_button_handler(view->window, button_handler);
- view->page = 0;
- view_draw(view);
-
- return view;
-}
-
-static const GOptionEntry option_entries[] = {
- { NULL }
-};
-
-int
-main(int argc, char *argv[])
-{
- struct display *d;
- int i;
-
- d = display_create(&argc, &argv, option_entries);
- if (d == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return -1;
- }
-
- for (i = 1; i < argc; i++)
- view_create (d, i, argv[i]);
-
- display_run(d);
-
- return 0;
-}
diff --git a/clients/wayland-glib.c b/clients/wayland-glib.c
deleted file mode 100644
index fa7a9f5..0000000
--- a/clients/wayland-glib.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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 <stdint.h>
-#include <glib/giochannel.h>
-#include "wayland-client.h"
-#include "wayland-glib.h"
-
-typedef struct _WlSource {
- GSource source;
- GPollFD pfd;
- uint32_t mask;
- struct wl_display *display;
-} WlSource;
-
-static gboolean
-wl_glib_source_prepare(GSource *base, gint *timeout)
-{
- WlSource *source = (WlSource *) base;
-
- *timeout = -1;
-
- /* We have to add/remove the GPollFD if we want to update our
- * poll event mask dynamically. Instead, let's just flush all
- * write on idle instead, which is what this amounts to. */
-
- while (source->mask & WL_DISPLAY_WRITABLE)
- wl_display_iterate(source->display,
- WL_DISPLAY_WRITABLE);
-
- return FALSE;
-}
-
-static gboolean
-wl_glib_source_check(GSource *base)
-{
- WlSource *source = (WlSource *) base;
-
- return source->pfd.revents;
-}
-
-static gboolean
-wl_glib_source_dispatch(GSource *base,
- GSourceFunc callback,
- gpointer data)
-{
- WlSource *source = (WlSource *) base;
-
- wl_display_iterate(source->display,
- WL_DISPLAY_READABLE);
-
- return TRUE;
-}
-
-static GSourceFuncs wl_glib_source_funcs = {
- wl_glib_source_prepare,
- wl_glib_source_check,
- wl_glib_source_dispatch,
- NULL
-};
-
-static int
-wl_glib_source_update(uint32_t mask, void *data)
-{
- WlSource *source = data;
-
- source->mask = mask;
-
- return 0;
-}
-
-GSource *
-wl_glib_source_new(struct wl_display *display)
-{
- WlSource *source;
-
- source = (WlSource *) g_source_new(&wl_glib_source_funcs,
- sizeof (WlSource));
- source->display = display;
- source->pfd.fd = wl_display_get_fd(display,
- wl_glib_source_update, source);
- source->pfd.events = G_IO_IN | G_IO_ERR;
- g_source_add_poll(&source->source, &source->pfd);
-
- return &source->source;
-}
diff --git a/clients/wayland-glib.h b/clients/wayland-glib.h
deleted file mode 100644
index 13ff2ca..0000000
--- a/clients/wayland-glib.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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.
- */
-
-#ifndef _WAYLAND_GLIB_H_
-#define _WAYLAND_GLIB_H_
-
-#include <glib/gmain.h>
-#include <wayland-client.h>
-
-GSource *wl_glib_source_new(struct wl_display *display);
-
-
-#endif
diff --git a/clients/window.c b/clients/window.c
deleted file mode 100644
index 0c93b9c..0000000
--- a/clients/window.c
+++ /dev/null
@@ -1,1741 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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 "../config.h"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <math.h>
-#include <time.h>
-#include <cairo.h>
-#include <glib.h>
-#include <glib-object.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <sys/mman.h>
-
-#include <wayland-egl.h>
-
-#include <GL/gl.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#ifdef HAVE_CAIRO_EGL
-#include <cairo-gl.h>
-#endif
-
-#include <X11/extensions/XKBcommon.h>
-
-#include <linux/input.h>
-#include "wayland-util.h"
-#include "wayland-client.h"
-#include "wayland-glib.h"
-#include "cairo-util.h"
-
-#include "window.h"
-
-struct display {
- struct wl_display *display;
- struct wl_egl_display *native_dpy;
- struct wl_compositor *compositor;
- struct wl_shell *shell;
- struct wl_shm *shm;
- struct wl_output *output;
- struct rectangle screen_allocation;
- int authenticated;
- EGLDisplay dpy;
- EGLContext ctx;
- cairo_device_t *device;
- int fd;
- GMainLoop *loop;
- GSource *source;
- struct wl_list window_list;
- struct wl_list input_list;
- char *device_name;
- cairo_surface_t *active_frame, *inactive_frame, *shadow;
- struct xkb_desc *xkb;
- cairo_surface_t **pointer_surfaces;
-
- display_global_handler_t global_handler;
-
- PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
- PFNEGLCREATEIMAGEKHRPROC create_image;
- PFNEGLDESTROYIMAGEKHRPROC destroy_image;
-};
-
-struct window {
- struct display *display;
- struct window *parent;
- struct wl_surface *surface;
- char *title;
- struct rectangle allocation, saved_allocation, server_allocation;
- int x, y;
- int resize_edges;
- int redraw_scheduled;
- int minimum_width, minimum_height;
- int margin;
- int fullscreen;
- int decoration;
- struct input *grab_device;
- struct input *keyboard_device;
- uint32_t name;
- enum window_buffer_type buffer_type;
-
- EGLImageKHR *image;
- cairo_surface_t *cairo_surface, *pending_surface;
-
- window_resize_handler_t resize_handler;
- window_redraw_handler_t redraw_handler;
- window_key_handler_t key_handler;
- window_button_handler_t button_handler;
- window_keyboard_focus_handler_t keyboard_focus_handler;
- window_motion_handler_t motion_handler;
-
- void *user_data;
- struct wl_list link;
-};
-
-struct input {
- struct display *display;
- struct wl_input_device *input_device;
- struct window *pointer_focus;
- struct window *keyboard_focus;
- struct selection_offer *offer;
- uint32_t current_pointer_image;
- uint32_t modifiers;
- int32_t x, y, sx, sy;
- struct wl_list link;
-};
-
-enum {
- POINTER_DEFAULT = 100,
- POINTER_UNSET
-};
-
-enum window_location {
- WINDOW_INTERIOR = 0,
- WINDOW_RESIZING_TOP = 1,
- WINDOW_RESIZING_BOTTOM = 2,
- WINDOW_RESIZING_LEFT = 4,
- WINDOW_RESIZING_TOP_LEFT = 5,
- WINDOW_RESIZING_BOTTOM_LEFT = 6,
- WINDOW_RESIZING_RIGHT = 8,
- WINDOW_RESIZING_TOP_RIGHT = 9,
- WINDOW_RESIZING_BOTTOM_RIGHT = 10,
- WINDOW_RESIZING_MASK = 15,
- WINDOW_EXTERIOR = 16,
- WINDOW_TITLEBAR = 17,
- WINDOW_CLIENT_AREA = 18,
-};
-
-const char *option_xkb_layout = "us";
-const char *option_xkb_variant = "";
-const char *option_xkb_options = "";
-
-static const GOptionEntry xkb_option_entries[] = {
- { "xkb-layout", 0, 0, G_OPTION_ARG_STRING,
- &option_xkb_layout, "XKB Layout" },
- { "xkb-variant", 0, 0, G_OPTION_ARG_STRING,
- &option_xkb_variant, "XKB Variant" },
- { "xkb-options", 0, 0, G_OPTION_ARG_STRING,
- &option_xkb_options, "XKB Options" },
- { NULL }
-};
-
-static void
-rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, int radius)
-{
- cairo_move_to(cr, x0, y0 + radius);
- cairo_arc(cr, x0 + radius, y0 + radius, radius, M_PI, 3 * M_PI / 2);
- cairo_line_to(cr, x1 - radius, y0);
- cairo_arc(cr, x1 - radius, y0 + radius, radius, 3 * M_PI / 2, 2 * M_PI);
- cairo_line_to(cr, x1, y1 - radius);
- cairo_arc(cr, x1 - radius, y1 - radius, radius, 0, M_PI / 2);
- cairo_line_to(cr, x0 + radius, y1);
- cairo_arc(cr, x0 + radius, y1 - radius, radius, M_PI / 2, M_PI);
- cairo_close_path(cr);
-}
-
-static const cairo_user_data_key_t surface_data_key;
-struct surface_data {
- struct wl_buffer *buffer;
-};
-
-#define MULT(_d,c,a,t) \
- do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0)
-
-#ifdef HAVE_CAIRO_EGL
-
-struct egl_image_surface_data {
- struct surface_data data;
- EGLImageKHR image;
- GLuint texture;
- struct display *display;
- struct wl_egl_pixmap *pixmap;
-};
-
-static void
-egl_image_surface_data_destroy(void *p)
-{
- struct egl_image_surface_data *data = p;
- struct display *d = data->display;
-
- cairo_device_acquire(d->device);
- glDeleteTextures(1, &data->texture);
- cairo_device_release(d->device);
-
- d->destroy_image(d->dpy, data->image);
- wl_buffer_destroy(data->data.buffer);
- wl_egl_pixmap_destroy(data->pixmap);
- free(p);
-}
-
-EGLImageKHR
-display_get_image_for_egl_image_surface(struct display *display,
- cairo_surface_t *surface)
-{
- struct egl_image_surface_data *data;
-
- data = cairo_surface_get_user_data (surface, &surface_data_key);
-
- return data->image;
-}
-
-static cairo_surface_t *
-display_create_egl_image_surface(struct display *display,
- struct rectangle *rectangle)
-{
- struct egl_image_surface_data *data;
- EGLDisplay dpy = display->dpy;
- cairo_surface_t *surface;
- struct wl_visual *visual;
-
- data = malloc(sizeof *data);
- if (data == NULL)
- return NULL;
-
- data->display = display;
-
- visual = wl_display_get_premultiplied_argb_visual(display->display);
- data->pixmap =wl_egl_pixmap_create(display->native_dpy,
- rectangle->width,
- rectangle->height,
- visual, 0);
- if (data->pixmap == NULL) {
- free(data);
- return NULL;
- }
-
- data->image = display->create_image(dpy, NULL,
- EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer) data->pixmap,
- NULL);
- if (data->image == EGL_NO_IMAGE_KHR) {
- wl_egl_pixmap_destroy(data->pixmap);
- free(data);
- return NULL;
- }
-
- data->data.buffer =
- wl_egl_pixmap_create_buffer(display->native_dpy, data->pixmap);
-
- cairo_device_acquire(display->device);
- glGenTextures(1, &data->texture);
- glBindTexture(GL_TEXTURE_2D, data->texture);
- display->image_target_texture_2d(GL_TEXTURE_2D, data->image);
- cairo_device_release(display->device);
-
- surface = cairo_gl_surface_create_for_texture(display->device,
- CAIRO_CONTENT_COLOR_ALPHA,
- data->texture,
- rectangle->width,
- rectangle->height);
-
- cairo_surface_set_user_data (surface, &surface_data_key,
- data, egl_image_surface_data_destroy);
-
- return surface;
-}
-
-static cairo_surface_t *
-display_create_egl_image_surface_from_file(struct display *display,
- const char *filename,
- struct rectangle *rect)
-{
- cairo_surface_t *surface;
- GdkPixbuf *pixbuf;
- GError *error = NULL;
- int stride, i;
- unsigned char *pixels, *p, *end;
- struct egl_image_surface_data *data;
-
- pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
- rect->width, rect->height,
- FALSE, &error);
- if (error != NULL)
- return NULL;
-
- if (!gdk_pixbuf_get_has_alpha(pixbuf) ||
- gdk_pixbuf_get_n_channels(pixbuf) != 4) {
- g_object_unref(pixbuf);
- return NULL;
- }
-
-
- stride = gdk_pixbuf_get_rowstride(pixbuf);
- pixels = gdk_pixbuf_get_pixels(pixbuf);
-
- for (i = 0; i < rect->height; i++) {
- p = pixels + i * stride;
- end = p + rect->width * 4;
- while (p < end) {
- unsigned int t;
-
- MULT(p[0], p[0], p[3], t);
- MULT(p[1], p[1], p[3], t);
- MULT(p[2], p[2], p[3], t);
- p += 4;
-
- }
- }
-
- surface = display_create_egl_image_surface(display, rect);
- if (surface == NULL) {
- g_object_unref(pixbuf);
- return NULL;
- }
-
- data = cairo_surface_get_user_data(surface, &surface_data_key);
-
- cairo_device_acquire(display->device);
- glBindTexture(GL_TEXTURE_2D, data->texture);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rect->width, rect->height,
- GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- cairo_device_release(display->device);
-
- g_object_unref(pixbuf);
-
- return surface;
-}
-
-#endif
-
-struct wl_buffer *
-display_get_buffer_for_surface(struct display *display,
- cairo_surface_t *surface)
-{
- struct surface_data *data;
-
- data = cairo_surface_get_user_data (surface, &surface_data_key);
-
- return data->buffer;
-}
-
-struct shm_surface_data {
- struct surface_data data;
- void *map;
- size_t length;
-};
-
-static void
-shm_surface_data_destroy(void *p)
-{
- struct shm_surface_data *data = p;
-
- wl_buffer_destroy(data->data.buffer);
- munmap(data->map, data->length);
-}
-
-static cairo_surface_t *
-display_create_shm_surface(struct display *display,
- struct rectangle *rectangle)
-{
- struct shm_surface_data *data;
- cairo_surface_t *surface;
- struct wl_visual *visual;
- int stride, fd;
- char filename[] = "/tmp/wayland-shm-XXXXXX";
-
- data = malloc(sizeof *data);
- if (data == NULL)
- return NULL;
-
- stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
- rectangle->width);
- data->length = stride * rectangle->height;
- fd = mkstemp(filename);
- if (fd < 0) {
- fprintf(stderr, "open %s failed: %m\n", filename);
- return NULL;
- }
- if (ftruncate(fd, data->length) < 0) {
- fprintf(stderr, "ftruncate failed: %m\n");
- close(fd);
- return NULL;
- }
-
- data->map = mmap(NULL, data->length,
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- unlink(filename);
-
- if (data->map == MAP_FAILED) {
- fprintf(stderr, "mmap failed: %m\n");
- close(fd);
- return NULL;
- }
-
- surface = cairo_image_surface_create_for_data (data->map,
- CAIRO_FORMAT_ARGB32,
- rectangle->width,
- rectangle->height,
- stride);
-
- cairo_surface_set_user_data (surface, &surface_data_key,
- data, shm_surface_data_destroy);
-
- visual = wl_display_get_premultiplied_argb_visual(display->display);
- data->data.buffer = wl_shm_create_buffer(display->shm,
- fd,
- rectangle->width,
- rectangle->height,
- stride, visual);
-
- close(fd);
-
- return surface;
-}
-
-static cairo_surface_t *
-display_create_shm_surface_from_file(struct display *display,
- const char *filename,
- struct rectangle *rect)
-{
- cairo_surface_t *surface;
- GdkPixbuf *pixbuf;
- GError *error = NULL;
- int stride, i;
- unsigned char *pixels, *p, *end, *dest_data;
- int dest_stride;
- uint32_t *d;
-
- pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
- rect->width, rect->height,
- FALSE, &error);
- if (error != NULL)
- return NULL;
-
- if (!gdk_pixbuf_get_has_alpha(pixbuf) ||
- gdk_pixbuf_get_n_channels(pixbuf) != 4) {
- g_object_unref(pixbuf);
- return NULL;
- }
-
- stride = gdk_pixbuf_get_rowstride(pixbuf);
- pixels = gdk_pixbuf_get_pixels(pixbuf);
-
- surface = display_create_shm_surface(display, rect);
- if (surface == NULL) {
- g_object_unref(pixbuf);
- return NULL;
- }
-
- dest_data = cairo_image_surface_get_data (surface);
- dest_stride = cairo_image_surface_get_stride (surface);
-
- for (i = 0; i < rect->height; i++) {
- d = (uint32_t *) (dest_data + i * dest_stride);
- p = pixels + i * stride;
- end = p + rect->width * 4;
- while (p < end) {
- unsigned int t;
- unsigned char a, r, g, b;
-
- a = p[3];
- MULT(r, p[0], a, t);
- MULT(g, p[1], a, t);
- MULT(b, p[2], a, t);
- p += 4;
- *d++ = (a << 24) | (r << 16) | (g << 8) | b;
- }
- }
-
- g_object_unref(pixbuf);
-
- return surface;
-}
-
-static int
-check_size(struct rectangle *rect)
-{
- if (rect->width && rect->height)
- return 0;
-
- fprintf(stderr, "tried to create surface of "
- "width: %d, height: %d\n", rect->width, rect->height);
- return -1;
-}
-
-cairo_surface_t *
-display_create_surface(struct display *display,
- struct rectangle *rectangle)
-{
- if (check_size(rectangle) < 0)
- return NULL;
-#ifdef HAVE_CAIRO_EGL
- if (display->dpy) {
- return display_create_egl_image_surface(display, rectangle);
- }
-#endif
- return display_create_shm_surface(display, rectangle);
-}
-
-static cairo_surface_t *
-display_create_surface_from_file(struct display *display,
- const char *filename,
- struct rectangle *rectangle)
-{
- if (check_size(rectangle) < 0)
- return NULL;
-#ifdef HAVE_CAIRO_EGL
- if (display->dpy) {
- return display_create_egl_image_surface_from_file(display,
- filename,
- rectangle);
- }
-#endif
- return display_create_shm_surface_from_file(display, filename, rectangle);
-}
- 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 },
- { DATADIR "/wayland/hand1.png", 18, 11 }
-};
-
-static void
-create_pointer_surfaces(struct display *display)
-{
- int i, count;
- const int width = 32, height = 32;
- struct rectangle rect;
-
- count = ARRAY_LENGTH(pointer_images);
- display->pointer_surfaces =
- malloc(count * sizeof *display->pointer_surfaces);
- rect.width = width;
- rect.height = height;
- for (i = 0; i < count; i++) {
- display->pointer_surfaces[i] =
- display_create_surface_from_file(display,
- pointer_images[i].filename,
- &rect);
- }
-
-}
-
-cairo_surface_t *
-display_get_pointer_surface(struct display *display, int pointer,
- int *width, int *height,
- int *hotspot_x, int *hotspot_y)
-{
- cairo_surface_t *surface;
-
- surface = display->pointer_surfaces[pointer];
-#if HAVE_CAIRO_EGL
- *width = cairo_gl_surface_get_width(surface);
- *height = cairo_gl_surface_get_height(surface);
-#else
- *width = cairo_image_surface_get_width(surface);
- *height = cairo_image_surface_get_height(surface);
-#endif
- *hotspot_x = pointer_images[pointer].hotspot_x;
- *hotspot_y = pointer_images[pointer].hotspot_y;
-
- return cairo_surface_reference(surface);
-}
-
-
-static void
-window_attach_surface(struct window *window);
-
-static void
-free_surface(void *data)
-{
- struct window *window = data;
-
- cairo_surface_destroy(window->pending_surface);
- window->pending_surface = NULL;
- if (window->cairo_surface)
- window_attach_surface(window);
-}
-
-static void
-window_attach_surface(struct window *window)
-{
- struct display *display = window->display;
- struct wl_buffer *buffer;
- int32_t x, y;
-
- if (window->pending_surface != NULL)
- return;
-
- window->pending_surface = window->cairo_surface;
- window->cairo_surface = NULL;
-
- buffer = display_get_buffer_for_surface(display,
- window->pending_surface);
- if (window->resize_edges & WINDOW_RESIZING_LEFT)
- x = window->server_allocation.width -
- window->allocation.width;
- else
- x = 0;
-
- if (window->resize_edges & WINDOW_RESIZING_TOP)
- y = window->server_allocation.height -
- window->allocation.height;
- else
- y = 0;
-
- window->server_allocation = window->allocation;
- window->resize_edges = 0;
- wl_surface_attach(window->surface, buffer, x, y);
- wl_display_sync_callback(display->display, free_surface, window);
-
- if (window->fullscreen)
- wl_surface_map_fullscreen(window->surface);
- else if (!window->parent)
- wl_surface_map_toplevel(window->surface);
- else
- wl_surface_map_transient(window->surface,
- window->parent->surface,
- window->x, window->y, 0);
-
- wl_surface_damage(window->surface, 0, 0,
- window->allocation.width,
- window->allocation.height);
-}
-
-void
-window_flush(struct window *window)
-{
- if (window->cairo_surface)
- window_attach_surface(window);
-}
-
-void
-window_set_surface(struct window *window, cairo_surface_t *surface)
-{
- cairo_surface_reference(surface);
-
- if (window->cairo_surface != NULL)
- cairo_surface_destroy(window->cairo_surface);
-
- window->cairo_surface = surface;
-}
-
-void
-window_create_surface(struct window *window)
-{
- cairo_surface_t *surface;
-
- switch (window->buffer_type) {
-#ifdef HAVE_CAIRO_EGL
- case WINDOW_BUFFER_TYPE_EGL_IMAGE:
- surface = display_create_surface(window->display,
- &window->allocation);
- break;
-#endif
- case WINDOW_BUFFER_TYPE_SHM:
- surface = display_create_shm_surface(window->display,
- &window->allocation);
- break;
- default:
- surface = NULL;
- break;
- }
-
- window_set_surface(window, surface);
- cairo_surface_destroy(surface);
-}
-
-static void
-window_draw_menu(struct window *window)
-{
- cairo_t *cr;
- int width, height, r = 5;
-
- window_create_surface(window);
-
- cr = cairo_create(window->cairo_surface);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
- cairo_paint(cr);
-
- width = window->allocation.width;
- height = window->allocation.height;
- rounded_rect(cr, r, r, width - r, height - r, r);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 1.0, 1.0, 0.0, 0.5);
- cairo_fill(cr);
- cairo_destroy(cr);
-}
-
-static void
-window_draw_decorations(struct window *window)
-{
- cairo_t *cr;
- cairo_text_extents_t extents;
- cairo_surface_t *frame;
- int width, height, shadow_dx = 3, shadow_dy = 3;
-
- window_create_surface(window);
-
- width = window->allocation.width;
- height = window->allocation.height;
-
- cr = cairo_create(window->cairo_surface);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 0, 0, 0, 0);
- cairo_paint(cr);
-
- cairo_set_source_rgba(cr, 0, 0, 0, 0.6);
- tile_mask(cr, window->display->shadow,
- shadow_dx, shadow_dy, width, height,
- window->margin + 10 - shadow_dx,
- window->margin + 10 - shadow_dy);
-
- if (window->keyboard_device)
- frame = window->display->active_frame;
- else
- frame = window->display->inactive_frame;
-
- tile_source(cr, frame, 0, 0, width, height,
- window->margin + 10, window->margin + 50);
-
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_set_font_size(cr, 14);
- cairo_text_extents(cr, window->title, &extents);
- cairo_move_to(cr, (width - extents.width) / 2, 32 - extents.y_bearing);
- if (window->keyboard_device)
- cairo_set_source_rgb(cr, 0, 0, 0);
- else
- cairo_set_source_rgb(cr, 0.8, 0.8, 0.8);
- cairo_show_text(cr, window->title);
-
- cairo_destroy(cr);
-
- cairo_device_flush (window->display->device);
-}
-
-void
-window_destroy(struct window *window)
-{
- wl_surface_destroy(window->surface);
- wl_list_remove(&window->link);
- free(window);
-}
-
-void
-display_flush_cairo_device(struct display *display)
-{
- cairo_device_flush (display->device);
-}
-
-void
-window_draw(struct window *window)
-{
- if (window->parent)
- window_draw_menu(window);
- else if (window->fullscreen || !window->decoration)
- window_create_surface(window);
- else
- window_draw_decorations(window);
-}
-
-cairo_surface_t *
-window_get_surface(struct window *window)
-{
- return cairo_surface_reference(window->cairo_surface);
-}
-
-static int
-get_pointer_location(struct window *window, int32_t x, int32_t y)
-{
- int vlocation, hlocation, location;
- const int grip_size = 8;
-
- if (!window->decoration)
- return WINDOW_CLIENT_AREA;
-
- if (x < window->margin)
- hlocation = WINDOW_EXTERIOR;
- else if (window->margin <= x && x < window->margin + grip_size)
- hlocation = WINDOW_RESIZING_LEFT;
- else if (x < window->allocation.width - window->margin - grip_size)
- hlocation = WINDOW_INTERIOR;
- else if (x < window->allocation.width - window->margin)
- hlocation = WINDOW_RESIZING_RIGHT;
- else
- hlocation = WINDOW_EXTERIOR;
-
- if (y < window->margin)
- vlocation = WINDOW_EXTERIOR;
- else if (window->margin <= y && y < window->margin + grip_size)
- vlocation = WINDOW_RESIZING_TOP;
- else if (y < window->allocation.height - window->margin - grip_size)
- vlocation = WINDOW_INTERIOR;
- else if (y < window->allocation.height - window->margin)
- vlocation = WINDOW_RESIZING_BOTTOM;
- else
- vlocation = WINDOW_EXTERIOR;
-
- location = vlocation | hlocation;
- if (location & WINDOW_EXTERIOR)
- location = WINDOW_EXTERIOR;
- if (location == WINDOW_INTERIOR && y < window->margin + 50)
- location = WINDOW_TITLEBAR;
- else if (location == WINDOW_INTERIOR)
- location = WINDOW_CLIENT_AREA;
-
- return location;
-}
-
-static void
-set_pointer_image(struct input *input, uint32_t time, int pointer)
-{
- struct display *display = input->display;
- struct wl_buffer *buffer;
- cairo_surface_t *surface;
- int location;
-
- location = get_pointer_location(input->pointer_focus,
- input->sx, input->sy);
- switch (location) {
- case WINDOW_RESIZING_TOP:
- pointer = POINTER_TOP;
- break;
- case WINDOW_RESIZING_BOTTOM:
- pointer = POINTER_BOTTOM;
- break;
- case WINDOW_RESIZING_LEFT:
- pointer = POINTER_LEFT;
- break;
- case WINDOW_RESIZING_RIGHT:
- pointer = POINTER_RIGHT;
- break;
- case WINDOW_RESIZING_TOP_LEFT:
- pointer = POINTER_TOP_LEFT;
- break;
- case WINDOW_RESIZING_TOP_RIGHT:
- pointer = POINTER_TOP_RIGHT;
- break;
- case WINDOW_RESIZING_BOTTOM_LEFT:
- pointer = POINTER_BOTTOM_LEFT;
- break;
- case WINDOW_RESIZING_BOTTOM_RIGHT:
- pointer = POINTER_BOTTOM_RIGHT;
- break;
- case WINDOW_EXTERIOR:
- case WINDOW_TITLEBAR:
- if (input->current_pointer_image == POINTER_DEFAULT)
- return;
-
- wl_input_device_attach(input->input_device, time, NULL, 0, 0);
- input->current_pointer_image = POINTER_DEFAULT;
- return;
- default:
- break;
- }
-
- if (pointer == input->current_pointer_image)
- return;
-
- input->current_pointer_image = pointer;
- surface = display->pointer_surfaces[pointer];
- buffer = display_get_buffer_for_surface(display, surface);
- wl_input_device_attach(input->input_device, time, buffer,
- pointer_images[pointer].hotspot_x,
- pointer_images[pointer].hotspot_y);
-}
-
-static void
-window_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 input *input = data;
- struct window *window = input->pointer_focus;
- int pointer = POINTER_LEFT_PTR;
-
- input->x = x;
- input->y = y;
- input->sx = sx;
- input->sy = sy;
-
- if (window->motion_handler)
- pointer = (*window->motion_handler)(window, input, time,
- x, y, sx, sy,
- window->user_data);
-
- set_pointer_image(input, time, pointer);
-}
-
-static void
-window_handle_button(void *data,
- struct wl_input_device *input_device,
- uint32_t time, uint32_t button, uint32_t state)
-{
- struct input *input = data;
- struct window *window = input->pointer_focus;
- int location;
-
- location = get_pointer_location(window, input->sx, input->sy);
-
- if (button == BTN_LEFT && state == 1) {
- switch (location) {
- case WINDOW_TITLEBAR:
- wl_shell_move(window->display->shell,
- window->surface, input_device, time);
- break;
- case WINDOW_RESIZING_TOP:
- case WINDOW_RESIZING_BOTTOM:
- case WINDOW_RESIZING_LEFT:
- case WINDOW_RESIZING_RIGHT:
- case WINDOW_RESIZING_TOP_LEFT:
- case WINDOW_RESIZING_TOP_RIGHT:
- case WINDOW_RESIZING_BOTTOM_LEFT:
- case WINDOW_RESIZING_BOTTOM_RIGHT:
- wl_shell_resize(window->display->shell,
- window->surface, input_device, time,
- location);
- break;
- case WINDOW_CLIENT_AREA:
- if (window->button_handler)
- (*window->button_handler)(window,
- input, time,
- button, state,
- window->user_data);
- break;
- }
- } else {
- if (window->button_handler)
- (*window->button_handler)(window,
- input, time,
- button, state,
- window->user_data);
- }
-}
-
-static void
-window_handle_key(void *data, struct wl_input_device *input_device,
- uint32_t time, uint32_t key, uint32_t state)
-{
- struct input *input = data;
- struct window *window = input->keyboard_focus;
- struct display *d = window->display;
- uint32_t code, sym, level;
-
- code = key + d->xkb->min_key_code;
- if (window->keyboard_device != input)
- return;
-
- level = 0;
- if (input->modifiers & XKB_COMMON_SHIFT_MASK &&
- XkbKeyGroupWidth(d->xkb, code, 0) > 1)
- level = 1;
-
- sym = XkbKeySymEntry(d->xkb, code, level, 0);
-
- if (state)
- input->modifiers |= d->xkb->map->modmap[code];
- else
- input->modifiers &= ~d->xkb->map->modmap[code];
-
- if (window->key_handler)
- (*window->key_handler)(window, input, time, key, sym, state,
- window->user_data);
-}
-
-static void
-window_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 input *input = data;
- struct window *window;
- int pointer;
-
- if (surface) {
- input->pointer_focus = wl_surface_get_user_data(surface);
- window = input->pointer_focus;
-
- input->x = x;
- input->y = y;
- input->sx = sx;
- input->sy = sy;
-
- pointer = POINTER_LEFT_PTR;
- if (window->motion_handler)
- pointer = (*window->motion_handler)(window,
- input, time,
- x, y, sx, sy,
- window->user_data);
-
- set_pointer_image(input, time, pointer);
- } else {
- input->pointer_focus = NULL;
- input->current_pointer_image = POINTER_UNSET;
- }
-}
-
-static void
-window_handle_keyboard_focus(void *data,
- struct wl_input_device *input_device,
- uint32_t time,
- struct wl_surface *surface,
- struct wl_array *keys)
-{
- struct input *input = data;
- struct window *window = input->keyboard_focus;
- struct display *d = input->display;
- uint32_t *k, *end;
-
- window = input->keyboard_focus;
- if (window) {
- window->keyboard_device = NULL;
- if (window->keyboard_focus_handler)
- (*window->keyboard_focus_handler)(window, NULL,
- window->user_data);
- }
-
- if (surface)
- input->keyboard_focus = wl_surface_get_user_data(surface);
- else
- input->keyboard_focus = NULL;
-
- end = keys->data + keys->size;
- input->modifiers = 0;
- for (k = keys->data; k < end; k++)
- input->modifiers |= d->xkb->map->modmap[*k];
-
- window = input->keyboard_focus;
- if (window) {
- window->keyboard_device = input;
- if (window->keyboard_focus_handler)
- (*window->keyboard_focus_handler)(window,
- window->keyboard_device,
- window->user_data);
- }
-}
-
-static const struct wl_input_device_listener input_device_listener = {
- window_handle_motion,
- window_handle_button,
- window_handle_key,
- window_handle_pointer_focus,
- window_handle_keyboard_focus,
-};
-
-void
-input_get_position(struct input *input, int32_t *x, int32_t *y)
-{
- *x = input->sx;
- *y = input->sy;
-}
-
-struct wl_input_device *
-input_get_input_device(struct input *input)
-{
- return input->input_device;
-}
-
-uint32_t
-input_get_modifiers(struct input *input)
-{
- return input->modifiers;
-}
-
-struct wl_drag *
-window_create_drag(struct window *window)
-{
- cairo_device_flush (window->display->device);
-
- return wl_shell_create_drag(window->display->shell);
-}
-
-void
-window_move(struct window *window, struct input *input, uint32_t time)
-{
- wl_shell_move(window->display->shell,
- window->surface, input->input_device, time);
-}
-
-void
-window_activate_drag(struct wl_drag *drag, struct window *window,
- struct input *input, uint32_t time)
-{
- wl_drag_activate(drag, window->surface, input->input_device, time);
-}
-
-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)
-{
- struct window *window = wl_surface_get_user_data(surface);
- int32_t child_width, child_height;
-
- /* FIXME: this is probably the wrong place to check for width
- * or height <= 0, but it prevents the compositor from crashing
- */
- if (width <= 0 || height <= 0)
- return;
-
- window->resize_edges = edges;
-
- if (window->resize_handler) {
- child_width = width - 20 - window->margin * 2;
- child_height = height - 60 - window->margin * 2;
-
- (*window->resize_handler)(window,
- child_width, child_height,
- window->user_data);
- } else {
- window->allocation.width = width;
- window->allocation.height = height;
-
- if (window->redraw_handler)
- window_schedule_redraw(window);
- }
-}
-
-static const struct wl_shell_listener shell_listener = {
- handle_configure,
-};
-
-void
-window_get_child_allocation(struct window *window,
- struct rectangle *allocation)
-{
- if (window->fullscreen || !window->decoration) {
- *allocation = window->allocation;
- } else {
- allocation->x = window->margin + 10;
- allocation->y = window->margin + 50;
- allocation->width =
- window->allocation.width - 20 - window->margin * 2;
- allocation->height =
- window->allocation.height - 60 - window->margin * 2;
- }
-}
-
-void
-window_set_child_size(struct window *window, int32_t width, int32_t height)
-{
- if (!window->fullscreen) {
- window->allocation.x = 20 + window->margin;
- window->allocation.y = 60 + window->margin;
- window->allocation.width = width + 20 + window->margin * 2;
- window->allocation.height = height + 60 + window->margin * 2;
- } else {
- window->allocation.x = 0;
- window->allocation.y = 0;
- window->allocation.width = width;
- window->allocation.height = height;
- }
-}
-
-static gboolean
-idle_redraw(void *data)
-{
- struct window *window = data;
-
- window->redraw_handler(window, window->user_data);
-
- window->redraw_scheduled = 0;
-
- return FALSE;
-}
-
-void
-window_schedule_redraw(struct window *window)
-{
- if (!window->redraw_scheduled) {
- g_idle_add(idle_redraw, window);
- window->redraw_scheduled = 1;
- }
-}
-
-void
-window_set_fullscreen(struct window *window, int fullscreen)
-{
- int32_t width, height;
-
- if (window->fullscreen == fullscreen)
- return;
-
- window->fullscreen = fullscreen;
- if (window->fullscreen) {
- window->saved_allocation = window->allocation;
- width = window->display->screen_allocation.width;
- height = window->display->screen_allocation.height;
- } else {
- width = window->saved_allocation.width - 20 - window->margin * 2;
- height = window->saved_allocation.height - 60 - window->margin * 2;
- }
-
- (*window->resize_handler)(window, width, height, window->user_data);
-}
-
-void
-window_set_decoration(struct window *window, int decoration)
-{
- window->decoration = decoration;
-}
-
-void
-window_set_user_data(struct window *window, void *data)
-{
- window->user_data = data;
-}
-
-void *
-window_get_user_data(struct window *window)
-{
- return window->user_data;
-}
-
-void
-window_set_resize_handler(struct window *window,
- window_resize_handler_t handler)
-{
- window->resize_handler = handler;
-}
-
-void
-window_set_redraw_handler(struct window *window,
- window_redraw_handler_t handler)
-{
- window->redraw_handler = handler;
-}
-
-void
-window_set_key_handler(struct window *window,
- window_key_handler_t handler)
-{
- window->key_handler = handler;
-}
-
-void
-window_set_button_handler(struct window *window,
- window_button_handler_t handler)
-{
- window->button_handler = handler;
-}
-
-void
-window_set_motion_handler(struct window *window,
- window_motion_handler_t handler)
-{
- window->motion_handler = handler;
-}
-
-void
-window_set_keyboard_focus_handler(struct window *window,
- window_keyboard_focus_handler_t handler)
-{
- window->keyboard_focus_handler = handler;
-}
-
-void
-window_set_title(struct window *window, const char *title)
-{
- free(window->title);
- window->title = strdup(title);
-}
-
-const char *
-window_get_title(struct window *window)
-{
- return window->title;
-}
-
-void
-window_damage(struct window *window, int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- wl_surface_damage(window->surface, x, y, width, height);
-}
-
-static struct window *
-window_create_internal(struct display *display, struct window *parent,
- int32_t width, int32_t height)
-{
- struct window *window;
-
- window = malloc(sizeof *window);
- if (window == NULL)
- return NULL;
-
- memset(window, 0, sizeof *window);
- window->display = display;
- window->parent = parent;
- window->surface = wl_compositor_create_surface(display->compositor);
- window->allocation.x = 0;
- window->allocation.y = 0;
- window->allocation.width = width;
- window->allocation.height = height;
- window->saved_allocation = window->allocation;
- window->margin = 16;
- window->decoration = 1;
-
- if (display->dpy)
- window->buffer_type = WINDOW_BUFFER_TYPE_EGL_IMAGE;
- else
- window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
-
- wl_surface_set_user_data(window->surface, window);
- wl_list_insert(display->window_list.prev, &window->link);
-
- return window;
-}
-
-struct window *
-window_create(struct display *display, int32_t width, int32_t height)
-{
- struct window *window;
-
- window = window_create_internal(display, NULL, width, height);
- if (!window)
- return NULL;
-
- return window;
-}
-
-struct window *
-window_create_transient(struct display *display, struct window *parent,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- struct window *window;
-
- window = window_create_internal(parent->display,
- parent, width, height);
- if (!window)
- return NULL;
-
- window->x = x;
- window->y = y;
-
- return window;
-}
-
-void
-window_set_buffer_type(struct window *window, enum window_buffer_type type)
-{
- window->buffer_type = type;
-}
-
-static void
-display_handle_geometry(void *data,
- struct wl_output *output,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- struct display *display = data;
-
- display->screen_allocation.x = x;
- display->screen_allocation.y = y;
- display->screen_allocation.width = width;
- display->screen_allocation.height = height;
-}
-
-static const struct wl_output_listener output_listener = {
- display_handle_geometry,
-};
-
-static void
-display_add_input(struct display *d, uint32_t id)
-{
- struct input *input;
-
- input = malloc(sizeof *input);
- if (input == NULL)
- return;
-
- memset(input, 0, sizeof *input);
- input->display = d;
- input->input_device = wl_input_device_create(d->display, id);
- input->pointer_focus = NULL;
- input->keyboard_focus = NULL;
- wl_list_insert(d->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);
-}
-
-struct selection_offer {
- struct display *display;
- struct wl_selection_offer *offer;
- struct wl_array types;
- struct input *input;
-};
-
-int
-input_offers_mime_type(struct input *input, const char *type)
-{
- struct selection_offer *offer = input->offer;
- char **p, **end;
-
- if (offer == NULL)
- return 0;
-
- end = offer->types.data + offer->types.size;
- for (p = offer->types.data; p < end; p++)
- if (strcmp(*p, type) == 0)
- return 1;
-
- return 0;
-}
-
-void
-input_receive_mime_type(struct input *input, const char *type, int fd)
-{
- struct selection_offer *offer = input->offer;
-
- /* FIXME: A number of things can go wrong here: the object may
- * not be the current selection offer any more (which could
- * still work, but the source may have gone away or just
- * destroyed its wl_selection) or the offer may not have the
- * requested type after all (programmer/client error,
- * typically) */
- wl_selection_offer_receive(offer->offer, type, fd);
-}
-
-static void
-selection_offer_offer(void *data,
- struct wl_selection_offer *selection_offer,
- const char *type)
-{
- struct selection_offer *offer = data;
-
- char **p;
-
- p = wl_array_add(&offer->types, sizeof *p);
- if (p)
- *p = strdup(type);
-};
-
-static void
-selection_offer_keyboard_focus(void *data,
- struct wl_selection_offer *selection_offer,
- struct wl_input_device *input_device)
-{
- struct selection_offer *offer = data;
- struct input *input;
- char **p, **end;
-
- if (input_device == NULL) {
- printf("selection offer retracted %p\n", selection_offer);
- input = offer->input;
- input->offer = NULL;
- wl_selection_offer_destroy(selection_offer);
- wl_array_release(&offer->types);
- free(offer);
- return;
- }
-
- input = wl_input_device_get_user_data(input_device);
- printf("new selection offer %p:", selection_offer);
-
- offer->input = input;
- input->offer = offer;
- end = offer->types.data + offer->types.size;
- for (p = offer->types.data; p < end; p++)
- printf(" %s", *p);
-
- printf("\n");
-}
-
-struct wl_selection_offer_listener selection_offer_listener = {
- selection_offer_offer,
- selection_offer_keyboard_focus
-};
-
-static void
-add_selection_offer(struct display *d, uint32_t id)
-{
- struct selection_offer *offer;
-
- offer = malloc(sizeof *offer);
- if (offer == NULL)
- return;
-
- offer->offer = wl_selection_offer_create(d->display, id);
- offer->display = d;
- wl_array_init(&offer->types);
- offer->input = NULL;
-
- wl_selection_offer_add_listener(offer->offer,
- &selection_offer_listener, offer);
-}
-
-static void
-display_handle_global(struct wl_display *display, uint32_t id,
- const char *interface, uint32_t version, void *data)
-{
- struct display *d = data;
-
- if (strcmp(interface, "compositor") == 0) {
- d->compositor = wl_compositor_create(display, id);
- } else if (strcmp(interface, "output") == 0) {
- d->output = wl_output_create(display, id);
- wl_output_add_listener(d->output, &output_listener, d);
- } else if (strcmp(interface, "input_device") == 0) {
- display_add_input(d, id);
- } else if (strcmp(interface, "shell") == 0) {
- d->shell = wl_shell_create(display, id);
- wl_shell_add_listener(d->shell, &shell_listener, d);
- } else if (strcmp(interface, "shm") == 0) {
- d->shm = wl_shm_create(display, id);
- } else if (strcmp(interface, "selection_offer") == 0) {
- add_selection_offer(d, id);
- } else if (d->global_handler) {
- d->global_handler(d, interface, id, version);
- }
-}
-
-static void
-display_render_frame(struct display *d)
-{
- int radius = 8;
- cairo_t *cr;
-
- d->shadow = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
- cr = cairo_create(d->shadow);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_set_source_rgba(cr, 0, 0, 0, 1);
- rounded_rect(cr, 16, 16, 112, 112, radius);
- cairo_fill(cr);
- cairo_destroy(cr);
- blur_surface(d->shadow, 64);
-
- d->active_frame =
- cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
- cr = cairo_create(d->active_frame);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_set_source_rgba(cr, 0.8, 0.8, 0.4, 1);
- rounded_rect(cr, 16, 16, 112, 112, radius);
- cairo_fill(cr);
- cairo_destroy(cr);
-
- d->inactive_frame =
- cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
- cr = cairo_create(d->inactive_frame);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 1);
- rounded_rect(cr, 16, 16, 112, 112, radius);
- cairo_fill(cr);
- cairo_destroy(cr);
-}
-
-static void
-init_xkb(struct display *d)
-{
- struct xkb_rule_names names;
-
- names.rules = "evdev";
- names.model = "pc105";
- names.layout = option_xkb_layout;
- names.variant = option_xkb_variant;
- names.options = option_xkb_options;
-
- d->xkb = xkb_compile_keymap_from_rules(&names);
- if (!d->xkb) {
- fprintf(stderr, "Failed to compile keymap\n");
- exit(1);
- }
-}
-
-static int
-init_egl(struct display *d)
-{
- EGLint major, minor;
-
- d->dpy = eglGetDisplay(d->native_dpy);
- if (!eglInitialize(d->dpy, &major, &minor)) {
- fprintf(stderr, "failed to initialize display\n");
- return -1;
- }
-
- if (!eglBindAPI(EGL_OPENGL_API)) {
- fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
- return -1;
- }
-
- d->ctx = eglCreateContext(d->dpy, NULL, EGL_NO_CONTEXT, NULL);
- if (d->ctx == NULL) {
- fprintf(stderr, "failed to create context\n");
- return -1;
- }
-
- if (!eglMakeCurrent(d->dpy, NULL, NULL, d->ctx)) {
- fprintf(stderr, "failed to make context current\n");
- return -1;
- }
-
-#ifdef HAVE_CAIRO_EGL
- d->device = cairo_egl_device_create(d->dpy, d->ctx);
- if (d->device == NULL) {
- fprintf(stderr, "failed to get cairo egl device\n");
- return -1;
- }
-#endif
-
- return 0;
-}
-
-struct display *
-display_create(int *argc, char **argv[], const GOptionEntry *option_entries)
-{
- struct display *d;
- GOptionContext *context;
- GOptionGroup *xkb_option_group;
- GError *error;
-
- g_type_init();
-
- context = g_option_context_new(NULL);
- if (option_entries)
- g_option_context_add_main_entries(context, option_entries, "Wayland View");
-
- xkb_option_group = g_option_group_new("xkb",
- "Keyboard options",
- "Show all XKB options",
- NULL, NULL);
- g_option_group_add_entries(xkb_option_group, xkb_option_entries);
- g_option_context_add_group (context, xkb_option_group);
-
- if (!g_option_context_parse(context, argc, argv, &error)) {
- fprintf(stderr, "option parsing failed: %s\n", error->message);
- exit(EXIT_FAILURE);
- }
-
- g_option_context_free(context);
-
- d = malloc(sizeof *d);
- if (d == NULL)
- return NULL;
-
- memset(d, 0, sizeof *d);
-
- d->display = wl_display_connect(NULL);
- if (d->display == NULL) {
- fprintf(stderr, "failed to create display: %m\n");
- return NULL;
- }
-
- wl_list_init(&d->input_list);
-
- /* Set up listener so we'll catch all events. */
- wl_display_add_global_listener(d->display,
- display_handle_global, d);
-
- d->native_dpy = wl_egl_display_create(d->display);
-
- /* Process connection events. */
- wl_display_iterate(d->display, WL_DISPLAY_READABLE);
-
- if (init_egl(d) < 0)
- return NULL;
-
- d->image_target_texture_2d =
- (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
- d->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
- d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
-
- create_pointer_surfaces(d);
-
- display_render_frame(d);
-
- d->loop = g_main_loop_new(NULL, FALSE);
- d->source = wl_glib_source_new(d->display);
- g_source_attach(d->source, NULL);
-
- wl_list_init(&d->window_list);
-
- init_xkb(d);
-
- return d;
-}
-
-struct wl_display *
-display_get_display(struct display *display)
-{
- return display->display;
-}
-
-struct wl_compositor *
-display_get_compositor(struct display *display)
-{
- return display->compositor;
-}
-
-EGLDisplay
-display_get_egl_display(struct display *d)
-{
- return d->dpy;
-}
-
-struct wl_shell *
-display_get_shell(struct display *display)
-{
- return display->shell;
-}
-
-void
-display_run(struct display *d)
-{
- g_main_loop_run(d->loop);
-}
-
-void
-display_set_global_handler(struct display *display,
- display_global_handler_t handler)
-{
- display->global_handler = handler;
-}
diff --git a/clients/window.h b/clients/window.h
deleted file mode 100644
index 7073f4a..0000000
--- a/clients/window.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * 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.
- */
-
-#ifndef _WINDOW_H_
-#define _WINDOW_H_
-
-#include <X11/extensions/XKBcommon.h>
-#include <glib.h>
-#include <wayland-client.h>
-
-struct window;
-
-struct rectangle {
- int32_t x;
- int32_t y;
- int32_t width;
- int32_t height;
-};
-
-struct display;
-struct input;
-
-struct display *
-display_create(int *argc, char **argv[], const GOptionEntry *option_entries);
-
-struct wl_display *
-display_get_display(struct display *display);
-
-struct wl_compositor *
-display_get_compositor(struct display *display);
-
-struct wl_shell *
-display_get_shell(struct display *display);
-
-#ifdef EGL_NO_DISPLAY
-EGLDisplay
-display_get_egl_display(struct display *d);
-
-#ifdef HAVE_CAIRO_EGL
-EGLImageKHR
-display_get_image_for_egl_image_surface(struct display *display,
- cairo_surface_t *surface);
-#endif
-#endif
-
-cairo_surface_t *
-display_create_surface(struct display *display,
- struct rectangle *rectangle);
-
-struct wl_buffer *
-display_get_buffer_for_surface(struct display *display,
- cairo_surface_t *surface);
-
-cairo_surface_t *
-display_get_pointer_surface(struct display *display, int pointer,
- int *width, int *height,
- int *hotspot_x, int *hotspot_y);
-
-void
-display_add_drag_listener(struct display *display,
- const struct wl_drag_listener *drag_listener,
- void *data);
-
-void
-display_flush_cairo_device(struct display *display);
-
-void
-display_run(struct display *d);
-
-enum pointer_type {
- POINTER_BOTTOM_LEFT,
- POINTER_BOTTOM_RIGHT,
- POINTER_BOTTOM,
- POINTER_DRAGGING,
- POINTER_LEFT_PTR,
- POINTER_LEFT,
- POINTER_RIGHT,
- POINTER_TOP_LEFT,
- POINTER_TOP_RIGHT,
- POINTER_TOP,
- POINTER_IBEAM,
- POINTER_HAND1,
-};
-
-typedef void (*window_resize_handler_t)(struct window *window,
- int32_t width, int32_t height,
- void *data);
-typedef void (*window_redraw_handler_t)(struct window *window, void *data);
-
-typedef void (*window_key_handler_t)(struct window *window, struct input *input,
- uint32_t time, uint32_t key, uint32_t unicode,
- uint32_t state, void *data);
-
-typedef void (*window_keyboard_focus_handler_t)(struct window *window,
- struct input *device, void *data);
-
-typedef void (*window_button_handler_t)(struct window *window,
- struct input *input, uint32_t time,
- int button, int state, void *data);
-
-typedef int (*window_motion_handler_t)(struct window *window,
- struct input *input, uint32_t time,
- int32_t x, int32_t y,
- int32_t sx, int32_t sy, void *data);
-
-typedef void (*display_global_handler_t)(struct display *display,
- const char *interface,
- uint32_t id,
- uint32_t version);
-
-struct window *
-window_create(struct display *display, int32_t width, int32_t height);
-struct window *
-window_create_transient(struct display *display, struct window *parent,
- int32_t x, int32_t y, int32_t width, int32_t height);
-
-void
-window_destroy(struct window *window);
-
-void
-window_move(struct window *window, struct input *input, uint32_t time);
-
-void
-window_draw(struct window *window);
-void
-window_get_child_allocation(struct window *window,
- struct rectangle *allocation);
-
-void
-window_set_child_size(struct window *window, int32_t width, int32_t height);
-void
-window_schedule_redraw(struct window *window);
-
-void
-window_damage(struct window *window, int32_t x, int32_t y,
- int32_t width, int32_t height);
-
-cairo_surface_t *
-window_get_surface(struct window *window);
-
-void
-window_flush(struct window *window);
-
-void
-window_set_surface(struct window *window, cairo_surface_t *surface);
-
-void
-window_create_surface(struct window *window);
-
-enum window_buffer_type {
- WINDOW_BUFFER_TYPE_EGL_IMAGE,
- WINDOW_BUFFER_TYPE_SHM,
-};
-
-void
-window_set_buffer_type(struct window *window, enum window_buffer_type type);
-
-void
-window_set_fullscreen(struct window *window, int fullscreen);
-
-void
-window_set_user_data(struct window *window, void *data);
-
-void *
-window_get_user_data(struct window *window);
-
-void
-window_set_redraw_handler(struct window *window,
- window_redraw_handler_t handler);
-
-void
-window_set_decoration(struct window *window, int decoration);
-
-void
-window_set_resize_handler(struct window *window,
- window_resize_handler_t handler);
-
-void
-window_set_key_handler(struct window *window,
- window_key_handler_t handler);
-
-void
-window_set_button_handler(struct window *window,
- window_button_handler_t handler);
-
-void
-window_set_motion_handler(struct window *window,
- window_motion_handler_t handler);
-
-void
-window_set_keyboard_focus_handler(struct window *window,
- window_keyboard_focus_handler_t handler);
-
-void
-window_set_title(struct window *window, const char *title);
-
-const char *
-window_get_title(struct window *window);
-
-void
-display_set_global_handler(struct display *display,
- display_global_handler_t handler);
-
-struct wl_drag *
-window_create_drag(struct window *window);
-
-void
-window_activate_drag(struct wl_drag *drag, struct window *window,
- struct input *input, uint32_t time);
-
-void
-input_get_position(struct input *input, int32_t *x, int32_t *y);
-
-uint32_t
-input_get_modifiers(struct input *input);
-
-struct wl_input_device *
-input_get_input_device(struct input *input);
-
-int
-input_offers_mime_type(struct input *input, const char *type);
-void
-input_receive_mime_type(struct input *input, const char *type, int fd);
-
-
-#endif