blob: d01ed2cf4bed9424ac75d45f5759f312eb6c1ddf [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>
7#include <fcntl.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -04008#include <unistd.h>
Kristian Høgsberga67a71a2008-10-07 10:10:36 -04009#include <math.h>
10#include <cairo.h>
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040011
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040012#include "wayland-client.h"
13
14static const char gem_device[] = "/dev/dri/card0";
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040015static const char socket_name[] = "\0wayland";
16
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040017static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface)
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040018{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040019 struct drm_i915_gem_create create;
20 struct drm_gem_flink flink;
21 struct drm_i915_gem_pwrite pwrite;
22 int32_t width, height, stride;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040023
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040024 width = cairo_image_surface_get_width(surface);
25 height = cairo_image_surface_get_height(surface);
26 stride = cairo_image_surface_get_stride(surface);
27
28 memset(&create, 0, sizeof(create));
29 create.size = height * stride;
30
31 if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create) != 0) {
32 fprintf(stderr, "gem create failed: %m\n");
33 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040034 }
35
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040036 pwrite.handle = create.handle;
37 pwrite.offset = 0;
38 pwrite.size = height * stride;
39 pwrite.data_ptr = (uint64_t) (uintptr_t)
40 cairo_image_surface_get_data(surface);
41 if (ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite) < 0) {
42 fprintf(stderr, "gem pwrite failed: %m\n");
43 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040044 }
45
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040046 flink.handle = create.handle;
47 if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) {
48 fprintf(stderr, "gem flink failed: %m\n");
49 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040050 }
51
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040052#if 0
53 /* We need to hold on to the handle until the server has received
54 * the attach request... we probably need a confirmation event.
55 * I guess the breadcrumb idea will suffice. */
56 struct drm_gem_close close;
57 close.handle = create.handle;
58 if (ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close) < 0) {
59 fprintf(stderr, "gem close failed: %m\n");
60 return 0;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040061 }
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040062#endif
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040063
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040064 return flink.name;
65}
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040066
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040067static void *
68draw_stuff(int width, int height)
69{
70 cairo_surface_t *surface;
71 cairo_t *cr;
72
73 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
74 width, height);
75
76 cr = cairo_create(surface);
77
78 cairo_arc(cr, width / 2, height / 2, width / 2 - 10, 0, 2 * M_PI);
79 cairo_set_source_rgb(cr, 1, 0, 0);
80 cairo_fill_preserve(cr);
81 cairo_set_source_rgb(cr, 1, 1, 0);
82 cairo_stroke(cr);
83
84 cairo_arc(cr, width / 2, height / 2, width / 4 - 10, 0, 2 * M_PI);
85 cairo_set_source_rgb(cr, 0, 0, 1);
86 cairo_fill_preserve(cr);
87 cairo_set_source_rgb(cr, 1, 1, 0);
88 cairo_stroke(cr);
89
90 cairo_destroy(cr);
91
92 return surface;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040093}
94
95int main(int argc, char *argv[])
96{
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040097 struct wl_connection *connection;
98 struct wl_display *display;
99 struct wl_surface *surface;
100 int width = 300, height = 300, fd;
101 uint32_t name;
102 cairo_surface_t *s;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400103
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400104 fd = open(gem_device, O_RDWR);
105 if (fd < 0) {
106 fprintf(stderr, "drm open failed: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400107 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400108 }
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400109
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400110 connection = wl_connection_create(socket_name);
111 if (connection == NULL) {
112 fprintf(stderr, "failed to create connection: %m\n");
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400113 return -1;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400114 }
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400115
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400116 display = wl_connection_get_display(connection);
117
118 surface = wl_display_create_surface(display);
119
120 s = draw_stuff(width, height);
121 name = name_cairo_surface(fd, s);
122
123 wl_surface_attach(surface, name, width, height,
124 cairo_image_surface_get_stride(s));
125
126 if (wl_connection_flush(connection) < 0) {
127 fprintf(stderr, "flush error: %m\n");
128 return -1;
129 }
130
131 while (1)
132 wl_connection_iterate(connection);
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400133
134 return 0;
135}