blob: c112303f2813b100950895a866ca020c72ea0ae4 [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;
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040037 struct wl_compositor *compositor;
38 struct wl_shell *shell;
39 struct wl_shm *shm;
Kristian Høgsberga3cdf592011-11-17 10:27:17 -050040 uint32_t formats;
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040041 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,
Kristian Høgsbergf389cac2011-08-31 16:21:38 -040054 int width, int height, uint32_t format, void **data_out)
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040055{
56 char filename[] = "/tmp/wayland-shm-XXXXXX";
57 struct wl_buffer *buffer;
58 int fd, size, stride;
59 void *data;
60
61 fd = mkstemp(filename);
62 if (fd < 0) {
63 fprintf(stderr, "open %s failed: %m\n", filename);
64 return NULL;
65 }
66 stride = width * 4;
67 size = stride * height;
68 if (ftruncate(fd, size) < 0) {
69 fprintf(stderr, "ftruncate failed: %m\n");
70 close(fd);
71 return NULL;
72 }
73
74 data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
75 unlink(filename);
76
77 if (data == MAP_FAILED) {
78 fprintf(stderr, "mmap failed: %m\n");
79 close(fd);
80 return NULL;
81 }
82
83 buffer = wl_shm_create_buffer(display->shm, fd,
Kristian Høgsbergf389cac2011-08-31 16:21:38 -040084 width, height, stride, format);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040085
86 close(fd);
87
88 *data_out = data;
89
90 return buffer;
91}
92
93static struct window *
94create_window(struct display *display, int width, int height)
95{
96 struct window *window;
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040097
98 window = malloc(sizeof *window);
99 window->display = display;
100 window->width = width;
101 window->height = height;
102 window->surface = wl_compositor_create_surface(display->compositor);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400103 window->buffer = create_shm_buffer(display,
104 width, height,
Kristian Høgsbergf389cac2011-08-31 16:21:38 -0400105 WL_SHM_FORMAT_XRGB32,
106 &window->data);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400107
108 wl_shell_set_toplevel(display->shell, window->surface);
109
110 return window;
111}
112
Kristian Høgsberg33418202011-08-16 23:01:28 -0400113static const struct wl_callback_listener frame_listener;
114
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400115static void
Kristian Høgsberg33418202011-08-16 23:01:28 -0400116redraw(void *data, struct wl_callback *callback, uint32_t time)
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400117{
118 struct window *window = data;
119 uint32_t *p;
120 int i, end, offset;
121
122 p = window->data;
123 end = window->width * window->height;
124 offset = time >> 4;
125 for (i = 0; i < end; i++)
126 p[i] = (i + offset) * 0x0080401;
127 wl_buffer_damage(window->buffer, 0, 0, window->width, window->height);
128
129 wl_surface_attach(window->surface, window->buffer, 0, 0);
130 wl_surface_damage(window->surface,
131 0, 0, window->width, window->height);
132
Kristian Høgsberg33418202011-08-16 23:01:28 -0400133 if (callback)
134 wl_callback_destroy(callback);
135
136 callback = wl_surface_frame(window->surface);
137 wl_callback_add_listener(callback, &frame_listener, window);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400138}
139
Kristian Høgsberg33418202011-08-16 23:01:28 -0400140static const struct wl_callback_listener frame_listener = {
141 redraw
142};
143
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400144static void
Kristian Høgsberga3cdf592011-11-17 10:27:17 -0500145shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
146{
147 struct display *d = data;
148
149 d->formats |= (1 << format);
150}
151
152struct wl_shm_listener shm_listenter = {
153 shm_format
154};
155
156static void
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400157display_handle_global(struct wl_display *display, uint32_t id,
158 const char *interface, uint32_t version, void *data)
159{
160 struct display *d = data;
161
162 if (strcmp(interface, "wl_compositor") == 0) {
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400163 d->compositor =
164 wl_display_bind(display, id, &wl_compositor_interface);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400165 } else if (strcmp(interface, "wl_shell") == 0) {
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400166 d->shell = wl_display_bind(display, id, &wl_shell_interface);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400167 } else if (strcmp(interface, "wl_shm") == 0) {
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400168 d->shm = wl_display_bind(display, id, &wl_shm_interface);
Kristian Høgsberga3cdf592011-11-17 10:27:17 -0500169 wl_shm_add_listener(d->shm, &shm_listenter, d);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400170 }
171}
172
173static int
174event_mask_update(uint32_t mask, void *data)
175{
176 struct display *d = data;
177
178 d->mask = mask;
179
180 return 0;
181}
182
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400183static struct display *
184create_display(void)
185{
186 struct display *display;
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400187
188 display = malloc(sizeof *display);
189 display->display = wl_display_connect(NULL);
Tiago Vignatti79caa752011-07-21 16:35:38 +0300190 assert(display->display);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400191
Kristian Høgsberga3cdf592011-11-17 10:27:17 -0500192 display->formats = 0;
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400193 wl_display_add_global_listener(display->display,
194 display_handle_global, display);
195 wl_display_iterate(display->display, WL_DISPLAY_READABLE);
Kristian Høgsberga3cdf592011-11-17 10:27:17 -0500196 wl_display_roundtrip(display->display);
197
198 if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB32))) {
199 fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n");
200 exit(1);
201 }
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400202
203 wl_display_get_fd(display->display, event_mask_update, display);
204
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400205 return display;
206}
207
208int
209main(int argc, char **argv)
210{
211 struct display *display;
212 struct window *window;
213
214 display = create_display();
215 window = create_window(display, 250, 250);
216
Kristian Høgsberg33418202011-08-16 23:01:28 -0400217 redraw(window, NULL, 0);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400218
219 while (true)
220 wl_display_iterate(display->display, display->mask);
221
222 return 0;
223}