blob: f064fcd8753a069ddac86495f3b781c9554bb4dd [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:
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400155 d->xrgb_visual = wl_display_bind(d->display,
156 id, &wl_visual_interface);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400157 break;
158 }
159}
160
161static const struct wl_compositor_listener compositor_listener = {
162 compositor_handle_visual,
163};
164
165static void
166display_handle_global(struct wl_display *display, uint32_t id,
167 const char *interface, uint32_t version, void *data)
168{
169 struct display *d = data;
170
171 if (strcmp(interface, "wl_compositor") == 0) {
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400172 d->compositor =
173 wl_display_bind(display, id, &wl_compositor_interface);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400174 wl_compositor_add_listener(d->compositor,
175 &compositor_listener, d);
176 } else if (strcmp(interface, "wl_shell") == 0) {
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400177 d->shell = wl_display_bind(display, id, &wl_shell_interface);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400178 } else if (strcmp(interface, "wl_shm") == 0) {
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400179 d->shm = wl_display_bind(display, id, &wl_shm_interface);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400180 }
181}
182
183static int
184event_mask_update(uint32_t mask, void *data)
185{
186 struct display *d = data;
187
188 d->mask = mask;
189
190 return 0;
191}
192
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400193static struct display *
194create_display(void)
195{
196 struct display *display;
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400197 int i;
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400198
199 display = malloc(sizeof *display);
200 display->display = wl_display_connect(NULL);
Tiago Vignatti79caa752011-07-21 16:35:38 +0300201 assert(display->display);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400202
203 wl_display_add_global_listener(display->display,
204 display_handle_global, display);
205 wl_display_iterate(display->display, WL_DISPLAY_READABLE);
206
207 wl_display_get_fd(display->display, event_mask_update, display);
208
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400209 while (display->xrgb_visual)
Kristian Høgsberg33418202011-08-16 23:01:28 -0400210 wl_display_roundtrip(display->display);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400211
212 return display;
213}
214
215int
216main(int argc, char **argv)
217{
218 struct display *display;
219 struct window *window;
220
221 display = create_display();
222 window = create_window(display, 250, 250);
223
Kristian Høgsberg33418202011-08-16 23:01:28 -0400224 redraw(window, NULL, 0);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400225
226 while (true)
227 wl_display_iterate(display->display, display->mask);
228
229 return 0;
230}