blob: 4654de0f3aa550f13a8624bd351b3f34111277f5 [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øgsberga67a71a2008-10-07 10:10:36 -04008#include <fcntl.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -04009#include <unistd.h>
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040010#include <math.h>
Kristian Høgsberga234e702008-10-11 22:13:51 -040011#include <time.h>
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040012#include <cairo.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040013
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040014#include "wayland-client.h"
15
16static const char gem_device[] = "/dev/dri/card0";
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040017static const char socket_name[] = "\0wayland";
18
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040019static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface)
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040020{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040021 struct drm_i915_gem_create create;
22 struct drm_gem_flink flink;
23 struct drm_i915_gem_pwrite pwrite;
24 int32_t width, height, stride;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040025
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040026 width = cairo_image_surface_get_width(surface);
27 height = cairo_image_surface_get_height(surface);
28 stride = cairo_image_surface_get_stride(surface);
29
30 memset(&create, 0, sizeof(create));
31 create.size = height * stride;
32
33 if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create) != 0) {
34 fprintf(stderr, "gem create failed: %m\n");
35 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040036 }
37
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040038 pwrite.handle = create.handle;
39 pwrite.offset = 0;
40 pwrite.size = height * stride;
41 pwrite.data_ptr = (uint64_t) (uintptr_t)
42 cairo_image_surface_get_data(surface);
43 if (ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite) < 0) {
44 fprintf(stderr, "gem pwrite failed: %m\n");
45 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040046 }
47
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040048 flink.handle = create.handle;
49 if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) {
50 fprintf(stderr, "gem flink failed: %m\n");
51 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040052 }
53
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040054#if 0
55 /* We need to hold on to the handle until the server has received
56 * the attach request... we probably need a confirmation event.
57 * I guess the breadcrumb idea will suffice. */
58 struct drm_gem_close close;
59 close.handle = create.handle;
60 if (ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close) < 0) {
61 fprintf(stderr, "gem close failed: %m\n");
62 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040063 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040064#endif
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040065
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040066 return flink.name;
67}
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040068
Kristian Høgsberga234e702008-10-11 22:13:51 -040069static void
70set_random_color(cairo_t *cr)
71{
72 cairo_set_source_rgba(cr,
Kristian Høgsbergd311e8a2008-10-12 22:58:40 -040073 0.5 + (random() % 50) / 49.0,
74 0.5 + (random() % 50) / 49.0,
75 0.5 + (random() % 50) / 49.0,
76 0.5 + (random() % 100) / 99.0);
Kristian Høgsberga234e702008-10-11 22:13:51 -040077}
78
79
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040080static void *
81draw_stuff(int width, int height)
82{
Kristian Høgsberga234e702008-10-11 22:13:51 -040083 const int petal_count = 3 + random() % 5;
84 const double r1 = 60 + random() % 35;
85 const double r2 = 20 + random() % 40;
86 const double u = (10 + random() % 90) / 100.0;
87 const double v = (random() % 90) / 100.0;
88
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040089 cairo_surface_t *surface;
90 cairo_t *cr;
Kristian Høgsberga234e702008-10-11 22:13:51 -040091 int i;
92 double t, dt = 2 * M_PI / (petal_count * 2);
93 double x1, y1, x2, y2, x3, y3;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040094
95 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
96 width, height);
97
98 cr = cairo_create(surface);
Kristian Høgsberga234e702008-10-11 22:13:51 -040099 cairo_translate(cr, width / 2, height / 2);
100 cairo_move_to(cr, cos(t) * r1, sin(t) * r1);
101 for (t = 0, i = 0; i < petal_count; i++, t += dt * 2) {
102 x1 = cos(t) * r1;
103 y1 = sin(t) * r1;
104 x2 = cos(t + dt) * r2;
105 y2 = sin(t + dt) * r2;
106 x3 = cos(t + 2 * dt) * r1;
107 y3 = sin(t + 2 * dt) * r1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400108
Kristian Høgsberga234e702008-10-11 22:13:51 -0400109 cairo_curve_to(cr,
110 x1 - y1 * u, y1 + x1 * u,
111 x2 + y2 * v, y2 - x2 * v,
112 x2, y2);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400113
Kristian Høgsberga234e702008-10-11 22:13:51 -0400114 cairo_curve_to(cr,
115 x2 - y2 * v, y2 + x2 * v,
116 x3 + y3 * u, y3 - x3 * u,
117 x3, y3);
118 }
119
120 cairo_close_path(cr);
121 set_random_color(cr);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400122 cairo_fill_preserve(cr);
Kristian Høgsberga234e702008-10-11 22:13:51 -0400123 set_random_color(cr);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400124 cairo_stroke(cr);
125
126 cairo_destroy(cr);
127
128 return surface;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400129}
130
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400131static int
132connection_update(struct wl_connection *connection,
133 uint32_t mask, void *data)
134{
135 struct pollfd *p = data;
136
137 p->events = 0;
138 if (mask & WL_CONNECTION_READABLE)
139 p->events |= POLLIN;
140 if (mask & WL_CONNECTION_WRITABLE)
141 p->events |= POLLOUT;
142
143 return 0;
144}
145
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400146int main(int argc, char *argv[])
147{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400148 struct wl_display *display;
149 struct wl_surface *surface;
Kristian Høgsbergf9212892008-10-11 18:40:23 -0400150 const int x = 200, y = 200, width = 200, height = 200;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400151 int fd, i, ret;
152 uint32_t name, mask;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400153 cairo_surface_t *s;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400154 struct pollfd p[1];
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400155
Kristian Høgsberga234e702008-10-11 22:13:51 -0400156 srandom(time(NULL));
157
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400158 fd = open(gem_device, O_RDWR);
159 if (fd < 0) {
160 fprintf(stderr, "drm open failed: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400161 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400162 }
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400163
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400164 display = wl_display_create(socket_name,
165 connection_update, &p[0]);
166 if (display == NULL) {
167 fprintf(stderr, "failed to create display: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400168 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400169 }
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400170 p[0].fd = wl_display_get_fd(display);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400171
172 surface = wl_display_create_surface(display);
173
174 s = draw_stuff(width, height);
175 name = name_cairo_surface(fd, s);
176
177 wl_surface_attach(surface, name, width, height,
178 cairo_image_surface_get_stride(s));
179
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400180 i = 0;
Kristian Høgsberg5ebb3172008-10-11 19:21:35 -0400181 while (ret = poll(p, 1, 20), ret >= 0) {
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400182 if (ret == 0) {
Kristian Høgsberg16eb6752008-10-08 22:51:32 -0400183 wl_surface_map(surface,
Kristian Høgsberga234e702008-10-11 22:13:51 -0400184 x + cos(i / 30.0) * 200,
185 y + sin(i / 31.0) * 200,
Kristian Høgsberg16eb6752008-10-08 22:51:32 -0400186 width, height);
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400187 i++;
188 continue;
189 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400190
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400191 mask = 0;
192 if (p[0].revents & POLLIN)
193 mask |= WL_CONNECTION_READABLE;
194 if (p[0].revents & POLLOUT)
195 mask |= WL_CONNECTION_WRITABLE;
196 if (mask)
197 wl_display_iterate(display, mask);
198 }
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400199
200 return 0;
201}