blob: 7b45005e4ebfe6ce3987e54b3dc2a496a3852a51 [file] [log] [blame]
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -04001/*
2 * Copyright © 2011 Benjamin Franzke
3 * Copyright © 2010 Intel Corporation
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting documentation, and
9 * that the name of the copyright holders not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. The copyright holders make no representations
12 * about the suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 * OF THIS SOFTWARE.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <stdbool.h>
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040028#include <assert.h>
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040029#include <unistd.h>
30#include <sys/mman.h>
31
32#include <wayland-client.h>
33#include <wayland-egl.h>
34
35struct display {
36 struct wl_display *display;
37 struct wl_visual *xrgb_visual;
38 struct wl_compositor *compositor;
39 struct wl_shell *shell;
40 struct wl_shm *shm;
41 uint32_t mask;
42};
43
44struct window {
45 struct display *display;
46 int width, height;
47 struct wl_surface *surface;
48 struct wl_buffer *buffer;
49 void *data;
50};
51
52static struct wl_buffer *
53create_shm_buffer(struct display *display,
54 int width, int height, struct wl_visual *visual,
55 void **data_out)
56{
57 char filename[] = "/tmp/wayland-shm-XXXXXX";
58 struct wl_buffer *buffer;
59 int fd, size, stride;
60 void *data;
61
62 fd = mkstemp(filename);
63 if (fd < 0) {
64 fprintf(stderr, "open %s failed: %m\n", filename);
65 return NULL;
66 }
67 stride = width * 4;
68 size = stride * height;
69 if (ftruncate(fd, size) < 0) {
70 fprintf(stderr, "ftruncate failed: %m\n");
71 close(fd);
72 return NULL;
73 }
74
75 data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
76 unlink(filename);
77
78 if (data == MAP_FAILED) {
79 fprintf(stderr, "mmap failed: %m\n");
80 close(fd);
81 return NULL;
82 }
83
84 buffer = wl_shm_create_buffer(display->shm, fd,
85 width, height, stride, visual);
86
87 close(fd);
88
89 *data_out = data;
90
91 return buffer;
92}
93
94static struct window *
95create_window(struct display *display, int width, int height)
96{
97 struct window *window;
98 struct wl_visual *visual;
99
100 window = malloc(sizeof *window);
101 window->display = display;
102 window->width = width;
103 window->height = height;
104 window->surface = wl_compositor_create_surface(display->compositor);
105 visual = display->xrgb_visual;
106 window->buffer = create_shm_buffer(display,
107 width, height,
108 visual, &window->data);
109
110 wl_shell_set_toplevel(display->shell, window->surface);
111
112 return window;
113}
114
Kristian Høgsberg33418202011-08-16 23:01:28 -0400115static const struct wl_callback_listener frame_listener;
116
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400117static void
Kristian Høgsberg33418202011-08-16 23:01:28 -0400118redraw(void *data, struct wl_callback *callback, uint32_t time)
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400119{
120 struct window *window = data;
121 uint32_t *p;
122 int i, end, offset;
123
124 p = window->data;
125 end = window->width * window->height;
126 offset = time >> 4;
127 for (i = 0; i < end; i++)
128 p[i] = (i + offset) * 0x0080401;
129 wl_buffer_damage(window->buffer, 0, 0, window->width, window->height);
130
131 wl_surface_attach(window->surface, window->buffer, 0, 0);
132 wl_surface_damage(window->surface,
133 0, 0, window->width, window->height);
134
Kristian Høgsberg33418202011-08-16 23:01:28 -0400135 if (callback)
136 wl_callback_destroy(callback);
137
138 callback = wl_surface_frame(window->surface);
139 wl_callback_add_listener(callback, &frame_listener, window);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400140}
141
Kristian Høgsberg33418202011-08-16 23:01:28 -0400142static const struct wl_callback_listener frame_listener = {
143 redraw
144};
145
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400146static void
147compositor_handle_visual(void *data,
148 struct wl_compositor *compositor,
149 uint32_t id, uint32_t token)
150{
151 struct display *d = data;
152
153 switch (token) {
154 case WL_COMPOSITOR_VISUAL_XRGB32:
155 d->xrgb_visual = wl_visual_create(d->display, id, 1);
156 break;
157 }
158}
159
160static const struct wl_compositor_listener compositor_listener = {
161 compositor_handle_visual,
162};
163
164static void
165display_handle_global(struct wl_display *display, uint32_t id,
166 const char *interface, uint32_t version, void *data)
167{
168 struct display *d = data;
169
170 if (strcmp(interface, "wl_compositor") == 0) {
171 d->compositor = wl_compositor_create(display, id, 1);
172 wl_compositor_add_listener(d->compositor,
173 &compositor_listener, d);
174 } else if (strcmp(interface, "wl_shell") == 0) {
175 d->shell = wl_shell_create(display, id, 1);
176 } else if (strcmp(interface, "wl_shm") == 0) {
177 d->shm = wl_shm_create(display, id, 1);
178 }
179}
180
181static int
182event_mask_update(uint32_t mask, void *data)
183{
184 struct display *d = data;
185
186 d->mask = mask;
187
188 return 0;
189}
190
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400191static struct display *
192create_display(void)
193{
194 struct display *display;
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400195
196 display = malloc(sizeof *display);
197 display->display = wl_display_connect(NULL);
Tiago Vignatti79caa752011-07-21 16:35:38 +0300198 assert(display->display);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400199
200 wl_display_add_global_listener(display->display,
201 display_handle_global, display);
202 wl_display_iterate(display->display, WL_DISPLAY_READABLE);
203
204 wl_display_get_fd(display->display, event_mask_update, display);
205
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400206 while (!display->xrgb_visual)
Kristian Høgsberg33418202011-08-16 23:01:28 -0400207 wl_display_roundtrip(display->display);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400208
209 return display;
210}
211
212int
213main(int argc, char **argv)
214{
215 struct display *display;
216 struct window *window;
217
218 display = create_display();
219 window = create_window(display, 250, 250);
220
Kristian Høgsberg33418202011-08-16 23:01:28 -0400221 redraw(window, NULL, 0);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400222
223 while (true)
224 wl_display_iterate(display->display, display->mask);
225
226 return 0;
227}