blob: 46deb0540da51121ac156931d3ed408f9888b34b [file] [log] [blame]
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -04001#include <stdint.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -04002#include <stdio.h>
Kristian Høgsberga67a71a2008-10-07 10:10:36 -04003#include <stdlib.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -04004#include <string.h>
Kristian Høgsberga67a71a2008-10-07 10:10:36 -04005#include <i915_drm.h>
6#include <sys/ioctl.h>
Kristian Høgsberg427524a2008-10-08 13:32:07 -04007#include <sys/poll.h>
Kristian Høgsbergd3fa34c2008-11-02 15:28:22 -05008#include <sys/timerfd.h>
9#include <time.h>
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040010#include <fcntl.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040011#include <unistd.h>
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040012#include <math.h>
Kristian Høgsberga234e702008-10-11 22:13:51 -040013#include <time.h>
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040014#include <cairo.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040015
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040016#include "wayland-client.h"
17
18static const char gem_device[] = "/dev/dri/card0";
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040019static const char socket_name[] = "\0wayland";
20
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040021static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface)
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040022{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040023 struct drm_i915_gem_create create;
24 struct drm_gem_flink flink;
25 struct drm_i915_gem_pwrite pwrite;
26 int32_t width, height, stride;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040027
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040028 width = cairo_image_surface_get_width(surface);
29 height = cairo_image_surface_get_height(surface);
30 stride = cairo_image_surface_get_stride(surface);
31
32 memset(&create, 0, sizeof(create));
33 create.size = height * stride;
34
35 if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create) != 0) {
36 fprintf(stderr, "gem create failed: %m\n");
37 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040038 }
39
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040040 pwrite.handle = create.handle;
41 pwrite.offset = 0;
42 pwrite.size = height * stride;
43 pwrite.data_ptr = (uint64_t) (uintptr_t)
44 cairo_image_surface_get_data(surface);
45 if (ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite) < 0) {
46 fprintf(stderr, "gem pwrite failed: %m\n");
47 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040048 }
49
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040050 flink.handle = create.handle;
51 if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) {
52 fprintf(stderr, "gem flink failed: %m\n");
53 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040054 }
55
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040056#if 0
57 /* We need to hold on to the handle until the server has received
58 * the attach request... we probably need a confirmation event.
59 * I guess the breadcrumb idea will suffice. */
60 struct drm_gem_close close;
61 close.handle = create.handle;
62 if (ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close) < 0) {
63 fprintf(stderr, "gem close failed: %m\n");
64 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040065 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040066#endif
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040067
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040068 return flink.name;
69}
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040070
Kristian Høgsberga234e702008-10-11 22:13:51 -040071static void
72set_random_color(cairo_t *cr)
73{
74 cairo_set_source_rgba(cr,
Kristian Høgsbergd311e8a2008-10-12 22:58:40 -040075 0.5 + (random() % 50) / 49.0,
76 0.5 + (random() % 50) / 49.0,
77 0.5 + (random() % 50) / 49.0,
78 0.5 + (random() % 100) / 99.0);
Kristian Høgsberga234e702008-10-11 22:13:51 -040079}
80
81
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040082static void *
83draw_stuff(int width, int height)
84{
Kristian Høgsberga234e702008-10-11 22:13:51 -040085 const int petal_count = 3 + random() % 5;
86 const double r1 = 60 + random() % 35;
87 const double r2 = 20 + random() % 40;
88 const double u = (10 + random() % 90) / 100.0;
89 const double v = (random() % 90) / 100.0;
90
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040091 cairo_surface_t *surface;
92 cairo_t *cr;
Kristian Høgsberga234e702008-10-11 22:13:51 -040093 int i;
94 double t, dt = 2 * M_PI / (petal_count * 2);
95 double x1, y1, x2, y2, x3, y3;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040096
97 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
98 width, height);
99
100 cr = cairo_create(surface);
Kristian Høgsberga234e702008-10-11 22:13:51 -0400101 cairo_translate(cr, width / 2, height / 2);
102 cairo_move_to(cr, cos(t) * r1, sin(t) * r1);
103 for (t = 0, i = 0; i < petal_count; i++, t += dt * 2) {
104 x1 = cos(t) * r1;
105 y1 = sin(t) * r1;
106 x2 = cos(t + dt) * r2;
107 y2 = sin(t + dt) * r2;
108 x3 = cos(t + 2 * dt) * r1;
109 y3 = sin(t + 2 * dt) * r1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400110
Kristian Høgsberga234e702008-10-11 22:13:51 -0400111 cairo_curve_to(cr,
112 x1 - y1 * u, y1 + x1 * u,
113 x2 + y2 * v, y2 - x2 * v,
114 x2, y2);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400115
Kristian Høgsberga234e702008-10-11 22:13:51 -0400116 cairo_curve_to(cr,
117 x2 - y2 * v, y2 + x2 * v,
118 x3 + y3 * u, y3 - x3 * u,
119 x3, y3);
120 }
121
122 cairo_close_path(cr);
123 set_random_color(cr);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400124 cairo_fill_preserve(cr);
Kristian Høgsberga234e702008-10-11 22:13:51 -0400125 set_random_color(cr);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400126 cairo_stroke(cr);
127
128 cairo_destroy(cr);
129
130 return surface;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400131}
132
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400133static int
134connection_update(struct wl_connection *connection,
135 uint32_t mask, void *data)
136{
137 struct pollfd *p = data;
138
139 p->events = 0;
140 if (mask & WL_CONNECTION_READABLE)
141 p->events |= POLLIN;
142 if (mask & WL_CONNECTION_WRITABLE)
143 p->events |= POLLOUT;
144
145 return 0;
146}
147
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400148int main(int argc, char *argv[])
149{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400150 struct wl_display *display;
151 struct wl_surface *surface;
Kristian Høgsbergf9212892008-10-11 18:40:23 -0400152 const int x = 200, y = 200, width = 200, height = 200;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400153 int fd, i, ret;
154 uint32_t name, mask;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400155 cairo_surface_t *s;
Kristian Høgsbergd3fa34c2008-11-02 15:28:22 -0500156 struct pollfd p[2];
157 struct timespec ts;
158 struct itimerspec its;
159 uint64_t expires;
Kristian Høgsberga234e702008-10-11 22:13:51 -0400160
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400161 fd = open(gem_device, O_RDWR);
162 if (fd < 0) {
163 fprintf(stderr, "drm open failed: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400164 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400165 }
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400166
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400167 display = wl_display_create(socket_name,
168 connection_update, &p[0]);
169 if (display == NULL) {
170 fprintf(stderr, "failed to create display: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400171 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400172 }
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400173 p[0].fd = wl_display_get_fd(display);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400174
175 surface = wl_display_create_surface(display);
176
Kristian Høgsbergd3fa34c2008-11-02 15:28:22 -0500177 p[1].fd = timerfd_create(CLOCK_MONOTONIC, 0);
178 if (p[1].fd < 0) {
179 fprintf(stderr, "could not create timerfd\n: %m");
180 return -1;
181 }
182
183 p[1].events = POLLIN;
184 clock_gettime(CLOCK_MONOTONIC, &ts);
185 its.it_value = ts;
186 its.it_interval.tv_sec = 0;
187 its.it_interval.tv_nsec = 20 * 1000000;
188 if (timerfd_settime(p[1].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
189 fprintf(stderr, "could not set timerfd\n: %m");
190 return -1;
191 }
192
193 srandom(ts.tv_nsec);
194
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400195 s = draw_stuff(width, height);
196 name = name_cairo_surface(fd, s);
197
198 wl_surface_attach(surface, name, width, height,
199 cairo_image_surface_get_stride(s));
200
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400201 i = 0;
Kristian Høgsbergd3fa34c2008-11-02 15:28:22 -0500202 while (ret = poll(p, 2, -1), ret >= 0) {
203 if (p[1].revents & POLLIN) {
204 read(p[1].fd, &expires, sizeof expires);
Kristian Høgsberg16eb6752008-10-08 22:51:32 -0400205 wl_surface_map(surface,
Kristian Høgsberga234e702008-10-11 22:13:51 -0400206 x + cos(i / 30.0) * 200,
207 y + sin(i / 31.0) * 200,
Kristian Høgsberg16eb6752008-10-08 22:51:32 -0400208 width, height);
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400209 i++;
210 continue;
211 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400212
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400213 mask = 0;
214 if (p[0].revents & POLLIN)
215 mask |= WL_CONNECTION_READABLE;
216 if (p[0].revents & POLLOUT)
217 mask |= WL_CONNECTION_WRITABLE;
218 if (mask)
219 wl_display_iterate(display, mask);
220 }
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400221
222 return 0;
223}