blob: a93c2033754a719af9f87f6abfd051bd514a498f [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;
40 uint32_t mask;
41};
42
43struct window {
44 struct display *display;
45 int width, height;
46 struct wl_surface *surface;
47 struct wl_buffer *buffer;
48 void *data;
49};
50
51static struct wl_buffer *
52create_shm_buffer(struct display *display,
Kristian Høgsbergf389cac2011-08-31 16:21:38 -040053 int width, int height, uint32_t format, void **data_out)
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040054{
55 char filename[] = "/tmp/wayland-shm-XXXXXX";
56 struct wl_buffer *buffer;
57 int fd, size, stride;
58 void *data;
59
60 fd = mkstemp(filename);
61 if (fd < 0) {
62 fprintf(stderr, "open %s failed: %m\n", filename);
63 return NULL;
64 }
65 stride = width * 4;
66 size = stride * height;
67 if (ftruncate(fd, size) < 0) {
68 fprintf(stderr, "ftruncate failed: %m\n");
69 close(fd);
70 return NULL;
71 }
72
73 data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
74 unlink(filename);
75
76 if (data == MAP_FAILED) {
77 fprintf(stderr, "mmap failed: %m\n");
78 close(fd);
79 return NULL;
80 }
81
82 buffer = wl_shm_create_buffer(display->shm, fd,
Kristian Høgsbergf389cac2011-08-31 16:21:38 -040083 width, height, stride, format);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040084
85 close(fd);
86
87 *data_out = data;
88
89 return buffer;
90}
91
92static struct window *
93create_window(struct display *display, int width, int height)
94{
95 struct window *window;
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -040096
97 window = malloc(sizeof *window);
98 window->display = display;
99 window->width = width;
100 window->height = height;
101 window->surface = wl_compositor_create_surface(display->compositor);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400102 window->buffer = create_shm_buffer(display,
103 width, height,
Kristian Høgsbergf389cac2011-08-31 16:21:38 -0400104 WL_SHM_FORMAT_XRGB32,
105 &window->data);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400106
107 wl_shell_set_toplevel(display->shell, window->surface);
108
109 return window;
110}
111
Kristian Høgsberg33418202011-08-16 23:01:28 -0400112static const struct wl_callback_listener frame_listener;
113
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400114static void
Kristian Høgsberg33418202011-08-16 23:01:28 -0400115redraw(void *data, struct wl_callback *callback, uint32_t time)
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400116{
117 struct window *window = data;
118 uint32_t *p;
119 int i, end, offset;
120
121 p = window->data;
122 end = window->width * window->height;
123 offset = time >> 4;
124 for (i = 0; i < end; i++)
125 p[i] = (i + offset) * 0x0080401;
126 wl_buffer_damage(window->buffer, 0, 0, window->width, window->height);
127
128 wl_surface_attach(window->surface, window->buffer, 0, 0);
129 wl_surface_damage(window->surface,
130 0, 0, window->width, window->height);
131
Kristian Høgsberg33418202011-08-16 23:01:28 -0400132 if (callback)
133 wl_callback_destroy(callback);
134
135 callback = wl_surface_frame(window->surface);
136 wl_callback_add_listener(callback, &frame_listener, window);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400137}
138
Kristian Høgsberg33418202011-08-16 23:01:28 -0400139static const struct wl_callback_listener frame_listener = {
140 redraw
141};
142
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400143static void
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400144display_handle_global(struct wl_display *display, uint32_t id,
145 const char *interface, uint32_t version, void *data)
146{
147 struct display *d = data;
148
149 if (strcmp(interface, "wl_compositor") == 0) {
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400150 d->compositor =
151 wl_display_bind(display, id, &wl_compositor_interface);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400152 } else if (strcmp(interface, "wl_shell") == 0) {
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400153 d->shell = wl_display_bind(display, id, &wl_shell_interface);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400154 } else if (strcmp(interface, "wl_shm") == 0) {
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400155 d->shm = wl_display_bind(display, id, &wl_shm_interface);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400156 }
157}
158
159static int
160event_mask_update(uint32_t mask, void *data)
161{
162 struct display *d = data;
163
164 d->mask = mask;
165
166 return 0;
167}
168
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400169static struct display *
170create_display(void)
171{
172 struct display *display;
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400173
174 display = malloc(sizeof *display);
175 display->display = wl_display_connect(NULL);
Tiago Vignatti79caa752011-07-21 16:35:38 +0300176 assert(display->display);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400177
178 wl_display_add_global_listener(display->display,
179 display_handle_global, display);
180 wl_display_iterate(display->display, WL_DISPLAY_READABLE);
181
182 wl_display_get_fd(display->display, event_mask_update, display);
183
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400184 return display;
185}
186
187int
188main(int argc, char **argv)
189{
190 struct display *display;
191 struct window *window;
192
193 display = create_display();
194 window = create_window(display, 250, 250);
195
Kristian Høgsberg33418202011-08-16 23:01:28 -0400196 redraw(window, NULL, 0);
Kristian Høgsberg97ba2e62011-07-06 11:58:45 -0400197
198 while (true)
199 wl_display_iterate(display->display, display->mask);
200
201 return 0;
202}