/* * Copyright © 2011 Benjamin Franzke * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include struct display { struct wl_display *display; struct { struct wl_compositor *compositor; struct wl_shm *shm; } interface; uint32_t mask; }; struct window { struct display *display; struct { int width, height; } geometry; struct { struct wl_buffer *buffer; struct wl_surface *surface; uint8_t *data; int length; int stride; } shm_surface; }; static void redraw(struct wl_surface *surface, void *data, uint32_t time) { struct window *window = data; uint32_t *pixel; int x,y; int a; for (y = 0; y < window->geometry.height; ++y) { pixel = (uint32_t *) (window->shm_surface.data + y * window->shm_surface.stride); a = 255 - y; for (x = 0; x < window->geometry.width; ++x, ++pixel) { if (x < 85) *pixel = (a << 24) | ((x + 170) << 16); else if (x < 170) *pixel = (a << 24) | ((x + 85) << 8); else *pixel = (a << 24) | (x); } } wl_buffer_damage(window->shm_surface.buffer, 0, 0, window->geometry.width, window->geometry.height); wl_surface_damage(window->shm_surface.surface, 0, 0, window->geometry.width, window->geometry.height); /* wl_display_frame_callback(window->display->display, redraw, window); */ } static void create_surface(struct window *window) { struct display *display = window->display; struct wl_visual *visual; int fd; char filename[] = "/tmp/wayland-shm-XXXXXX"; window->shm_surface.surface = wl_compositor_create_surface(display->interface.compositor); #if 0 window->shm_surface.stride = window->geometry.width * 4; #else window->shm_surface.stride = window->geometry.width * 4 + 4; #endif window->shm_surface.length = window->shm_surface.stride * window->geometry.height; fd = mkstemp(filename); if (fd < 0) { fprintf(stderr, "open %s failed: %m\n", filename); exit(1); } if (ftruncate(fd, window->shm_surface.length) < 0) { fprintf(stderr, "ftruncate failed: %m"); close(fd); exit(1); } window->shm_surface.data = mmap(NULL, window->shm_surface.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); unlink(filename); if (window->shm_surface.data == MAP_FAILED) { fprintf(stderr, "mmap failed: %m\n"); exit(1); } visual = wl_display_get_argb_visual(display->display); window->shm_surface.buffer = wl_shm_create_buffer(display->interface.shm, fd, window->geometry.width, window->geometry.height, window->shm_surface.stride, visual); close(fd); redraw(window->shm_surface.surface, window, 0); wl_surface_attach(window->shm_surface.surface, window->shm_surface.buffer, 0, 0); wl_surface_map_toplevel(window->shm_surface.surface); } static void display_handle_global(struct wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data) { struct display *d = data; if (strcmp(interface, "wl_compositor") == 0) { d->interface.compositor = wl_compositor_create(display, id, 1); } else if (strcmp(interface, "wl_shm") == 0) { d->interface.shm = wl_shm_create(display, id, 1); } } static int event_mask_update(uint32_t mask, void *data) { struct display *d = data; d->mask = mask; return 0; } int main(int argc, char **argv) { struct display display = { 0 }; struct window window = { 0 }; memset(&display, 0, sizeof display); memset(&window, 0, sizeof window); window.display = &display; window.geometry.width = 256; window.geometry.height = 256; display.display = wl_display_connect(NULL); assert(display.display); wl_display_add_global_listener(display.display, display_handle_global, &display); /* process connection events */ wl_display_iterate(display.display, WL_DISPLAY_READABLE); create_surface(&window); wl_display_get_fd(display.display, event_mask_update, &display); while (true) wl_display_iterate(display.display, display.mask); return 0; }