blob: f74be9d39b2aef4f3524df342fd4c8907168efcc [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øgsbergfb590842008-11-07 14:27:23 -050015#include <glib.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040016
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040017#include "wayland-client.h"
Kristian Høgsbergfb590842008-11-07 14:27:23 -050018#include "wayland-glib.h"
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040019
20static const char gem_device[] = "/dev/dri/card0";
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040021static const char socket_name[] = "\0wayland";
22
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040023static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface)
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040024{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040025 struct drm_i915_gem_create create;
26 struct drm_gem_flink flink;
27 struct drm_i915_gem_pwrite pwrite;
28 int32_t width, height, stride;
Kristian Høgsberg1b2f4392008-11-02 15:50:55 -050029 void *data;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040030
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040031 width = cairo_image_surface_get_width(surface);
32 height = cairo_image_surface_get_height(surface);
33 stride = cairo_image_surface_get_stride(surface);
Kristian Høgsberg1b2f4392008-11-02 15:50:55 -050034 data = cairo_image_surface_get_data(surface);
35
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040036 memset(&create, 0, sizeof(create));
37 create.size = height * stride;
38
39 if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create) != 0) {
40 fprintf(stderr, "gem create failed: %m\n");
41 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040042 }
43
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040044 pwrite.handle = create.handle;
45 pwrite.offset = 0;
46 pwrite.size = height * stride;
Kristian Høgsberg1b2f4392008-11-02 15:50:55 -050047 pwrite.data_ptr = (uint64_t) (uintptr_t) data;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040048 if (ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite) < 0) {
49 fprintf(stderr, "gem pwrite failed: %m\n");
50 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040051 }
52
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040053 flink.handle = create.handle;
54 if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) {
55 fprintf(stderr, "gem flink failed: %m\n");
56 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040057 }
58
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040059#if 0
60 /* We need to hold on to the handle until the server has received
61 * the attach request... we probably need a confirmation event.
62 * I guess the breadcrumb idea will suffice. */
63 struct drm_gem_close close;
64 close.handle = create.handle;
65 if (ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close) < 0) {
66 fprintf(stderr, "gem close failed: %m\n");
67 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040068 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040069#endif
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040070
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040071 return flink.name;
72}
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040073
Kristian Høgsberga234e702008-10-11 22:13:51 -040074static void
75set_random_color(cairo_t *cr)
76{
77 cairo_set_source_rgba(cr,
Kristian Høgsbergd311e8a2008-10-12 22:58:40 -040078 0.5 + (random() % 50) / 49.0,
79 0.5 + (random() % 50) / 49.0,
80 0.5 + (random() % 50) / 49.0,
81 0.5 + (random() % 100) / 99.0);
Kristian Høgsberga234e702008-10-11 22:13:51 -040082}
83
84
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040085static void *
86draw_stuff(int width, int height)
87{
Kristian Høgsberga234e702008-10-11 22:13:51 -040088 const int petal_count = 3 + random() % 5;
89 const double r1 = 60 + random() % 35;
90 const double r2 = 20 + random() % 40;
91 const double u = (10 + random() % 90) / 100.0;
92 const double v = (random() % 90) / 100.0;
93
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040094 cairo_surface_t *surface;
95 cairo_t *cr;
Kristian Høgsberga234e702008-10-11 22:13:51 -040096 int i;
97 double t, dt = 2 * M_PI / (petal_count * 2);
98 double x1, y1, x2, y2, x3, y3;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040099
100 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
101 width, height);
102
103 cr = cairo_create(surface);
Kristian Høgsberga234e702008-10-11 22:13:51 -0400104 cairo_translate(cr, width / 2, height / 2);
105 cairo_move_to(cr, cos(t) * r1, sin(t) * r1);
106 for (t = 0, i = 0; i < petal_count; i++, t += dt * 2) {
107 x1 = cos(t) * r1;
108 y1 = sin(t) * r1;
109 x2 = cos(t + dt) * r2;
110 y2 = sin(t + dt) * r2;
111 x3 = cos(t + 2 * dt) * r1;
112 y3 = sin(t + 2 * dt) * r1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400113
Kristian Høgsberga234e702008-10-11 22:13:51 -0400114 cairo_curve_to(cr,
115 x1 - y1 * u, y1 + x1 * u,
116 x2 + y2 * v, y2 - x2 * v,
117 x2, y2);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400118
Kristian Høgsberga234e702008-10-11 22:13:51 -0400119 cairo_curve_to(cr,
120 x2 - y2 * v, y2 + x2 * v,
121 x3 + y3 * u, y3 - x3 * u,
122 x3, y3);
123 }
124
125 cairo_close_path(cr);
126 set_random_color(cr);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400127 cairo_fill_preserve(cr);
Kristian Høgsberga234e702008-10-11 22:13:51 -0400128 set_random_color(cr);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400129 cairo_stroke(cr);
130
131 cairo_destroy(cr);
132
133 return surface;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400134}
135
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500136struct flower {
137 struct wl_surface *surface;
138 int i;
139 int x, y, width, height;
140};
141
142static gboolean
143move_flower(gpointer data)
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400144{
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500145 struct flower *flower = data;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400146
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500147 wl_surface_map(flower->surface,
148 flower->x + cos(flower->i / 31.0) * 400 - flower->width / 2,
149 flower->y + sin(flower->i / 27.0) * 300 - flower->height / 2,
150 flower->width, flower->height);
151 flower->i++;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400152
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500153 return TRUE;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400154}
155
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400156int main(int argc, char *argv[])
157{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400158 struct wl_display *display;
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500159 int fd;
160 uint32_t name;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400161 cairo_surface_t *s;
Kristian Høgsbergd3fa34c2008-11-02 15:28:22 -0500162 struct timespec ts;
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500163 GMainLoop *loop;
164 GSource *source;
165 struct flower flower;
Kristian Høgsberga234e702008-10-11 22:13:51 -0400166
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400167 fd = open(gem_device, O_RDWR);
168 if (fd < 0) {
169 fprintf(stderr, "drm open failed: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400170 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400171 }
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400172
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500173 loop = g_main_loop_new(NULL, FALSE);
174
175 display = wl_display_create(socket_name);
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400176 if (display == NULL) {
177 fprintf(stderr, "failed to create display: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400178 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400179 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400180
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500181 source = wayland_source_new(display);
182 g_source_attach(source, NULL);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400183
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500184 flower.x = 512;
185 flower.y = 384;
186 flower.width = 200;
187 flower.height = 200;
188 flower.surface = wl_display_create_surface(display);
Kristian Høgsbergd3fa34c2008-11-02 15:28:22 -0500189
Kristian Høgsbergd3fa34c2008-11-02 15:28:22 -0500190 clock_gettime(CLOCK_MONOTONIC, &ts);
Kristian Høgsbergd3fa34c2008-11-02 15:28:22 -0500191 srandom(ts.tv_nsec);
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500192 flower.i = ts.tv_nsec;
Kristian Høgsbergd3fa34c2008-11-02 15:28:22 -0500193
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500194 s = draw_stuff(flower.width, flower.height);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400195 name = name_cairo_surface(fd, s);
196
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500197 wl_surface_attach(flower.surface, name, flower.width, flower.height,
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400198 cairo_image_surface_get_stride(s));
199
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500200 g_timeout_add(20, move_flower, &flower);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400201
Kristian Høgsbergfb590842008-11-07 14:27:23 -0500202 g_main_loop_run(loop);
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400203
204 return 0;
205}