This is just a hacked version of clickdot that responds to tablet events
instead of cursor events

Signed-off-by: Stephen Chandler Paul <[email protected]>
---
 .gitignore       |   1 +
 Makefile.am      |   8 ++
 clients/tablet.c | 341 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 350 insertions(+)
 create mode 100644 clients/tablet.c

diff --git a/.gitignore b/.gitignore
index fbffaa5..c3f473a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,7 @@ weston-simple-damage
 weston-smoke
 weston-stacking
 weston-subsurfaces
+weston-tablet
 weston-transformed
 weston-view
 
diff --git a/Makefile.am b/Makefile.am
index cb22509..8165969 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -500,6 +500,14 @@ weston_scaler_SOURCES = clients/scaler.c
 weston_scaler_LDADD = libtoytoolkit.la
 weston_scaler_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
 
+if ENABLE_LIBINPUT_BACKEND
+demo_clients += weston-tablet
+weston_tablet_SOURCES = clients/tablet.c
+weston_tablet_LDADD = libtoytoolkit.la
+weston_tablet_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
+
+endif
+
 if HAVE_CAIRO_GLESV2
 demo_clients += weston-nested weston-nested-client
 
diff --git a/clients/tablet.c b/clients/tablet.c
new file mode 100644
index 0000000..c5c2182
--- /dev/null
+++ b/clients/tablet.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright © 2014 Lyude
+ *
+ * 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 <cairo.h>
+#include <math.h>
+#include <assert.h>
+
+#include <linux/input.h>
+#include <wayland-client.h>
+
+#include "window.h"
+
+struct tablet_view {
+       struct display *display;
+       struct window *window;
+       struct widget *widget;
+
+       int cursor;
+
+       cairo_surface_t *buffer;
+
+       enum {
+               TABLET_TOOL_UP = 0,
+               TABLET_TOOL_DOWN = 1,
+       } tablet_contact_status;
+
+       struct {
+               int32_t x, y;
+       } dot;
+
+       struct {
+               int32_t x, y;
+               int32_t old_x, old_y;
+       } line;
+
+       int reset;
+};
+
+static void
+draw_line(struct tablet_view *tablet_view, cairo_t *cr,
+         struct rectangle *allocation)
+{
+       cairo_t *bcr;
+       cairo_surface_t *tmp_buffer = NULL;
+
+       if (tablet_view->reset) {
+               tmp_buffer = tablet_view->buffer;
+               tablet_view->buffer = NULL;
+               tablet_view->line.x = -1;
+               tablet_view->line.y = -1;
+               tablet_view->line.old_x = -1;
+               tablet_view->line.old_y = -1;
+               tablet_view->reset = 0;
+       }
+
+       if (tablet_view->buffer == NULL) {
+               tablet_view->buffer =
+                       cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+                                                  allocation->width,
+                                                  allocation->height);
+               bcr = cairo_create(tablet_view->buffer);
+               cairo_set_source_rgba(bcr, 0, 0, 0, 0);
+               cairo_rectangle(bcr,
+                               0, 0,
+                               allocation->width, allocation->height);
+               cairo_fill(bcr);
+       }
+       else
+               bcr = cairo_create(tablet_view->buffer);
+
+       if (tmp_buffer) {
+               cairo_set_source_surface(bcr, tmp_buffer, 0, 0);
+               cairo_rectangle(bcr, 0, 0,
+                               allocation->width, allocation->height);
+               cairo_clip(bcr);
+               cairo_paint(bcr);
+
+               cairo_surface_destroy(tmp_buffer);
+       }
+
+       if (tablet_view->line.x != -1 && tablet_view->line.y != -1) {
+               if (tablet_view->line.old_x != -1 &&
+                   tablet_view->line.old_y != -1) {
+                       cairo_set_line_width(bcr, 2.0);
+                       cairo_set_source_rgb(bcr, 1, 1, 1);
+                       cairo_translate(bcr,
+                                       -allocation->x, -allocation->y);
+
+                       cairo_move_to(bcr,
+                                     tablet_view->line.old_x,
+                                     tablet_view->line.old_y);
+                       cairo_line_to(bcr,
+                                     tablet_view->line.x,
+                                     tablet_view->line.y);
+
+                       cairo_stroke(bcr);
+               }
+
+               tablet_view->line.old_x = tablet_view->line.x;
+               tablet_view->line.old_y = tablet_view->line.y;
+       }
+       cairo_destroy(bcr);
+
+       cairo_set_source_surface(cr, tablet_view->buffer,
+                                allocation->x, allocation->y);
+       cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
+       cairo_rectangle(cr,
+                       allocation->x, allocation->y,
+                       allocation->width, allocation->height);
+       cairo_clip(cr);
+       cairo_paint(cr);
+}
+
+static void
+redraw_handler(struct widget *widget, void *data)
+{
+       static const double r = 10.0;
+       struct tablet_view *tablet_view = data;
+       cairo_surface_t *surface;
+       cairo_t *cr;
+       struct rectangle allocation;
+
+       widget_get_allocation(tablet_view->widget, &allocation);
+
+       surface = window_get_surface(tablet_view->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);
+
+       draw_line(tablet_view, cr, &allocation);
+
+       cairo_translate(cr, tablet_view->dot.x + 0.5, tablet_view->dot.y + 0.5);
+       cairo_set_line_width(cr, 1.0);
+       cairo_set_source_rgb(cr, 0.1, 0.9, 0.9);
+       cairo_move_to(cr, 0.0, -r);
+       cairo_line_to(cr, 0.0, r);
+       cairo_move_to(cr, -r, 0.0);
+       cairo_line_to(cr, r, 0.0);
+       cairo_arc(cr, 0.0, 0.0, r, 0.0, 2.0 * M_PI);
+       cairo_stroke(cr);
+
+       cairo_destroy(cr);
+
+       cairo_surface_destroy(surface);
+}
+
+static void
+keyboard_focus_handler(struct window *window,
+                      struct input *device, void *data)
+{
+       struct tablet_view *tablet_view = data;
+
+       window_schedule_redraw(tablet_view->window);
+}
+
+static void
+key_handler(struct window *window, struct input *input, uint32_t time,
+           uint32_t key, uint32_t sym,
+           enum wl_keyboard_key_state state, void *data)
+{
+       struct tablet_view *tablet_view = data;
+
+       if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
+               return;
+
+       switch (sym) {
+       case XKB_KEY_Escape:
+               display_exit(tablet_view->display);
+               break;
+       }
+}
+
+static void
+button_handler(struct widget *widget, struct tablet *tablet, uint32_t button,
+              enum wl_tablet_button_state state, uint32_t time, void *data)
+{
+       struct tablet_view *tablet_view = data;
+
+       if (state == WL_TABLET_BUTTON_STATE_PRESSED && button == BTN_STYLUS)
+               tablet_get_position(tablet,
+                                   &tablet_view->dot.x, &tablet_view->dot.y);
+
+       widget_schedule_redraw(widget);
+}
+
+static int
+motion_handler(struct widget *widget, struct tablet *tablet, float x, float y,
+              uint32_t time, void *data)
+{
+       struct tablet_view *tablet_view = data;
+
+       if (tablet_view->tablet_contact_status == TABLET_TOOL_DOWN) {
+               tablet_view->line.x = x;
+               tablet_view->line.y = y;
+
+               window_schedule_redraw(tablet_view->window);
+       }
+
+       return tablet_view->cursor;
+}
+
+static void
+resize_handler(struct widget *widget,
+              int32_t width, int32_t height,
+              void *data)
+{
+       struct tablet_view *tablet_view = data;
+
+       tablet_view->reset = 1;
+}
+
+static void
+down_handler(struct widget *widget, struct tablet *tablet, uint32_t time,
+            void *data)
+{
+       struct tablet_view *tablet_view = data;
+
+       tablet_view->tablet_contact_status = TABLET_TOOL_DOWN;
+}
+
+static void
+up_handler(struct widget *widget, struct tablet *tablet, uint32_t time,
+          void *data)
+{
+       struct tablet_view *tablet_view = data;
+
+       tablet_view->tablet_contact_status = TABLET_TOOL_UP;
+}
+
+static void
+proximity_in_handler(struct widget *widget, struct tablet *tablet,
+                    struct tablet_tool *tool, void *data)
+{
+       struct tablet_view *tablet_view = data;
+
+       if (tablet_tool_get_type(tool) == WL_TABLET_TOOL_TYPE_PEN)
+               tablet_view->cursor = CURSOR_HAND1;
+       else
+               tablet_view->cursor = CURSOR_LEFT;
+}
+
+static struct tablet_view *
+tablet_view_create(struct display *display)
+{
+       struct tablet_view *tablet_view;
+
+       tablet_view = xzalloc(sizeof *tablet_view);
+       tablet_view->window = window_create(display);
+       tablet_view->widget = window_frame_create(tablet_view->window, 
tablet_view);
+       window_set_title(tablet_view->window, "Wayland Tablet");
+       tablet_view->display = display;
+       tablet_view->buffer = NULL;
+
+       window_set_key_handler(tablet_view->window, key_handler);
+       window_set_user_data(tablet_view->window, tablet_view);
+       window_set_keyboard_focus_handler(tablet_view->window,
+                                         keyboard_focus_handler);
+
+       widget_set_redraw_handler(tablet_view->widget, redraw_handler);
+       widget_set_tablet_button_handler(tablet_view->widget, button_handler);
+       widget_set_tablet_motion_handler(tablet_view->widget, motion_handler);
+       widget_set_resize_handler(tablet_view->widget, resize_handler);
+       widget_set_tablet_down_handler(tablet_view->widget, down_handler);
+       widget_set_tablet_up_handler(tablet_view->widget, up_handler);
+       widget_set_tablet_proximity_in_handler(tablet_view->widget,
+                                              proximity_in_handler);
+
+       widget_schedule_resize(tablet_view->widget, 1000, 800);
+       tablet_view->dot.x = 250;
+       tablet_view->dot.y = 200;
+       tablet_view->line.x = -1;
+       tablet_view->line.y = -1;
+       tablet_view->line.old_x = -1;
+       tablet_view->line.old_y = -1;
+       tablet_view->reset = 0;
+
+       return tablet_view;
+}
+
+static void
+tablet_view_destroy(struct tablet_view *tablet_view)
+{
+       if (tablet_view->buffer)
+               cairo_surface_destroy(tablet_view->buffer);
+       widget_destroy(tablet_view->widget);
+       window_destroy(tablet_view->window);
+       free(tablet_view);
+}
+
+int
+main(int argc, char *argv[])
+{
+       struct display *display;
+       struct tablet_view *tablet_view;
+
+       display = display_create(&argc, argv);
+       if (display == NULL) {
+               fprintf(stderr, "failed to create display: %m\n");
+               return -1;
+       }
+
+       tablet_view = tablet_view_create(display);
+
+       display_run(display);
+
+       tablet_view_destroy(tablet_view);
+       display_destroy(display);
+
+       return 0;
+}
-- 
1.8.5.5

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to