blob: 5c8e8ed484f905bb8b8d29b8ea380ecd743da018 [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>
11#include <cairo.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040012
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040013#include "wayland-client.h"
14
15static const char gem_device[] = "/dev/dri/card0";
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040016static const char socket_name[] = "\0wayland";
17
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040018static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface)
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040019{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040020 struct drm_i915_gem_create create;
21 struct drm_gem_flink flink;
22 struct drm_i915_gem_pwrite pwrite;
23 int32_t width, height, stride;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040024
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040025 width = cairo_image_surface_get_width(surface);
26 height = cairo_image_surface_get_height(surface);
27 stride = cairo_image_surface_get_stride(surface);
28
29 memset(&create, 0, sizeof(create));
30 create.size = height * stride;
31
32 if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create) != 0) {
33 fprintf(stderr, "gem create failed: %m\n");
34 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040035 }
36
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040037 pwrite.handle = create.handle;
38 pwrite.offset = 0;
39 pwrite.size = height * stride;
40 pwrite.data_ptr = (uint64_t) (uintptr_t)
41 cairo_image_surface_get_data(surface);
42 if (ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite) < 0) {
43 fprintf(stderr, "gem pwrite failed: %m\n");
44 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040045 }
46
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040047 flink.handle = create.handle;
48 if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) {
49 fprintf(stderr, "gem flink 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#if 0
54 /* We need to hold on to the handle until the server has received
55 * the attach request... we probably need a confirmation event.
56 * I guess the breadcrumb idea will suffice. */
57 struct drm_gem_close close;
58 close.handle = create.handle;
59 if (ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close) < 0) {
60 fprintf(stderr, "gem close failed: %m\n");
61 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040062 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040063#endif
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040064
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040065 return flink.name;
66}
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040067
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040068static void *
69draw_stuff(int width, int height)
70{
71 cairo_surface_t *surface;
72 cairo_t *cr;
73
74 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
75 width, height);
76
77 cr = cairo_create(surface);
78
79 cairo_arc(cr, width / 2, height / 2, width / 2 - 10, 0, 2 * M_PI);
80 cairo_set_source_rgb(cr, 1, 0, 0);
81 cairo_fill_preserve(cr);
82 cairo_set_source_rgb(cr, 1, 1, 0);
83 cairo_stroke(cr);
84
85 cairo_arc(cr, width / 2, height / 2, width / 4 - 10, 0, 2 * M_PI);
86 cairo_set_source_rgb(cr, 0, 0, 1);
87 cairo_fill_preserve(cr);
88 cairo_set_source_rgb(cr, 1, 1, 0);
89 cairo_stroke(cr);
90
91 cairo_destroy(cr);
92
93 return surface;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040094}
95
Kristian Høgsberg427524a2008-10-08 13:32:07 -040096static int
97connection_update(struct wl_connection *connection,
98 uint32_t mask, void *data)
99{
100 struct pollfd *p = data;
101
102 p->events = 0;
103 if (mask & WL_CONNECTION_READABLE)
104 p->events |= POLLIN;
105 if (mask & WL_CONNECTION_WRITABLE)
106 p->events |= POLLOUT;
107
108 return 0;
109}
110
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400111int main(int argc, char *argv[])
112{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400113 struct wl_display *display;
114 struct wl_surface *surface;
Kristian Høgsberg16eb6752008-10-08 22:51:32 -0400115 const int x = 200, y = 100, width = 300, height = 300;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400116 int fd, i, ret;
117 uint32_t name, mask;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400118 cairo_surface_t *s;
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400119 struct pollfd p[1];
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400120
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400121 fd = open(gem_device, O_RDWR);
122 if (fd < 0) {
123 fprintf(stderr, "drm open failed: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400124 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400125 }
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400126
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400127 display = wl_display_create(socket_name,
128 connection_update, &p[0]);
129 if (display == NULL) {
130 fprintf(stderr, "failed to create display: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400131 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400132 }
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400133 p[0].fd = wl_display_get_fd(display);
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400134
135 surface = wl_display_create_surface(display);
136
137 s = draw_stuff(width, height);
138 name = name_cairo_surface(fd, s);
139
140 wl_surface_attach(surface, name, width, height,
141 cairo_image_surface_get_stride(s));
142
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400143 i = 0;
Kristian Høgsberg16eb6752008-10-08 22:51:32 -0400144 while (ret = poll(p, 1, 20), ret >= 0) {
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400145 if (ret == 0) {
Kristian Høgsberg16eb6752008-10-08 22:51:32 -0400146 wl_surface_map(surface,
147 x + cos(i / 10.0) * 50,
148 y + sin(i / 10.0) * 50,
149 width, height);
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400150 i++;
151 continue;
152 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400153
Kristian Høgsberg427524a2008-10-08 13:32:07 -0400154 mask = 0;
155 if (p[0].revents & POLLIN)
156 mask |= WL_CONNECTION_READABLE;
157 if (p[0].revents & POLLOUT)
158 mask |= WL_CONNECTION_WRITABLE;
159 if (mask)
160 wl_display_iterate(display, mask);
161 }
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400162
163 return 0;
164}