blob: 4da4053f1f67014cdba6cf76cb45347094b90070 [file] [log] [blame]
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -05001#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -05005#include <fcntl.h>
6#include <unistd.h>
7#include <math.h>
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -05008#include <cairo.h>
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -05009#include <glib.h>
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050010
11#include "wayland-client.h"
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -050012#include "wayland-glib.h"
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050013
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050014#include "cairo-util.h"
15
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050016static const char gem_device[] = "/dev/dri/card0";
17static const char socket_name[] = "\0wayland";
18
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050019static void
20pointer_path(cairo_t *cr, int x, int y)
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050021{
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050022 const int end = 4, tx = 2, ty = 7, dx = 3, dy = 5;
23 const int width = 16, height = 16;
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050024
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050025 cairo_move_to(cr, x, y);
26 cairo_line_to(cr, x + tx, y + ty);
27 cairo_line_to(cr, x + dx, y + dy);
28 cairo_line_to(cr, x + width - end, y + height);
29 cairo_line_to(cr, x + width, y + height - end);
30 cairo_line_to(cr, x + dy, y + dx);
31 cairo_line_to(cr, x + ty, y + tx);
32 cairo_close_path(cr);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050033}
34
35static void *
36draw_pointer(int width, int height)
37{
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050038 const int hotspot_x = 16, hotspot_y = 16;
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050039 cairo_surface_t *surface;
40 cairo_t *cr;
41
42 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
43 width, height);
44
45 cr = cairo_create(surface);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050046 pointer_path(cr, hotspot_x + 3, hotspot_y + 2);
47 cairo_set_line_width (cr, 2);
Kristian Høgsberg30749422008-11-08 16:01:59 -050048 cairo_set_source_rgb(cr, 0, 0, 0);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050049 cairo_stroke_preserve(cr);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050050 cairo_fill(cr);
Kristian Høgsberg10bdd292008-11-08 23:27:27 -050051 blur_surface(surface, INT_MAX);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050052
53 pointer_path(cr, hotspot_x, hotspot_y);
54 cairo_stroke_preserve(cr);
Kristian Høgsberg30749422008-11-08 16:01:59 -050055 cairo_set_source_rgb(cr, 1, 1, 1);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050056 cairo_fill(cr);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050057 cairo_destroy(cr);
58
59 return surface;
60}
61
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050062struct pointer {
63 int width, height;
64 struct wl_surface *surface;
65};
66
Kristian Høgsberg30749422008-11-08 16:01:59 -050067static void
68event_handler(struct wl_display *display,
69 uint32_t opcode,
70 uint32_t arg1, uint32_t arg2, void *data)
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050071{
72 struct pointer *pointer = data;
73
Kristian Høgsberg2a20d832008-11-02 17:22:39 -050074 if (opcode == 0)
75 wl_surface_map(pointer->surface, arg1, arg2, pointer->width, pointer->height);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050076}
77
78int main(int argc, char *argv[])
79{
80 struct wl_display *display;
81 struct pointer pointer;
82 int fd;
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050083 cairo_surface_t *s;
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -050084 GMainLoop *loop;
85 GSource *source;
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -050086 struct buffer *buffer;
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050087
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050088 fd = open(gem_device, O_RDWR);
89 if (fd < 0) {
90 fprintf(stderr, "drm open failed: %m\n");
91 return -1;
92 }
93
Kristian Høgsbergfb590842008-11-07 14:27:23 -050094 display = wl_display_create(socket_name);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -050095 if (display == NULL) {
96 fprintf(stderr, "failed to create display: %m\n");
97 return -1;
98 }
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -050099
100 loop = g_main_loop_new(NULL, FALSE);
101 source = wayland_source_new(display);
102 g_source_attach(source, NULL);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -0500103
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500104 pointer.width = 48;
105 pointer.height = 48;
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -0500106 pointer.surface = wl_display_create_surface(display);
107
108 s = draw_pointer(pointer.width, pointer.height);
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500109 buffer = buffer_create_from_cairo_surface(fd, s);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -0500110
Kristian Høgsberg2f2cfae2008-11-08 22:46:30 -0500111 wl_surface_attach(pointer.surface, buffer->name,
112 buffer->width, buffer->height, buffer->stride);
Kristian Høgsberg2a20d832008-11-02 17:22:39 -0500113 wl_surface_map(pointer.surface, 512, 384, pointer.width, pointer.height);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -0500114
115 wl_display_set_event_handler(display, event_handler, &pointer);
116
Kristian Høgsberg1cbaa6a2008-11-07 15:54:48 -0500117 g_main_loop_run(loop);
Kristian Høgsberg5a27f3e2008-11-02 10:55:25 -0500118
119 return 0;
120}