diff options
Diffstat (limited to 'client.c')
| -rw-r--r-- | client.c | 176 |
1 files changed, 101 insertions, 75 deletions
@@ -1,109 +1,135 @@ -#include <stdlib.h> #include <stdint.h> -#include <stddef.h> #include <stdio.h> -#include <errno.h> +#include <stdlib.h> #include <string.h> +#include <i915_drm.h> +#include <sys/ioctl.h> +#include <fcntl.h> #include <unistd.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <ctype.h> +#include <math.h> +#include <cairo.h> +#include "wayland-client.h" + +static const char gem_device[] = "/dev/dri/card0"; static const char socket_name[] = "\0wayland"; -struct method { - const char *name; - uint32_t opcode; -}; +static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface) +{ + struct drm_i915_gem_create create; + struct drm_gem_flink flink; + struct drm_i915_gem_pwrite pwrite; + int32_t width, height, stride; -static const struct method display_methods[] = { - { "get_interface", 0 }, - { "create_surface", 1 }, - { NULL } -}; + width = cairo_image_surface_get_width(surface); + height = cairo_image_surface_get_height(surface); + stride = cairo_image_surface_get_stride(surface); -static const struct method surface_methods[] = { - { "get_interface", 0 }, - { "post", 1 }, - { NULL } -}; + memset(&create, 0, sizeof(create)); + create.size = height * stride; -struct interface { - const char *name; - const struct method *methods; -}; + if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create) != 0) { + fprintf(stderr, "gem create failed: %m\n"); + return 0; + } -static const struct interface interfaces[] = { - { "display", display_methods }, - { "surface", surface_methods }, - { NULL }, -}; + pwrite.handle = create.handle; + pwrite.offset = 0; + pwrite.size = height * stride; + pwrite.data_ptr = (uint64_t) (uintptr_t) + cairo_image_surface_get_data(surface); + if (ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite) < 0) { + fprintf(stderr, "gem pwrite failed: %m\n"); + return 0; + } -int send_request(int sock, const char *buffer, int buffer_len) -{ - const struct method *methods; - char interface[32], method[32]; - uint32_t request[3], id, new_id; - int i; + flink.handle = create.handle; + if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) { + fprintf(stderr, "gem flink failed: %m\n"); + return 0; + } - if (sscanf(buffer, "%d/%32[^:]:%32s %d\n", - &id, interface, method, &new_id) != 4) { - printf("invalid input, expected <id>/<interface>:<method>\n"); - return -1; +#if 0 + /* We need to hold on to the handle until the server has received + * the attach request... we probably need a confirmation event. + * I guess the breadcrumb idea will suffice. */ + struct drm_gem_close close; + close.handle = create.handle; + if (ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close) < 0) { + fprintf(stderr, "gem close failed: %m\n"); + return 0; } +#endif - printf("got object id %d, interface \"%s\", name \"%s\"\n", - id, interface, method); + return flink.name; +} - for (i = 0; interfaces[i].name != NULL; i++) { - if (strcmp(interfaces[i].name, interface) == 0) - break; - } - if (interfaces[i].name == NULL) { - printf("unknown interface \"%s\"\n", interface); - return -1; - } +static void * +draw_stuff(int width, int height) +{ + cairo_surface_t *surface; + cairo_t *cr; - methods = interfaces[i].methods; - for (i = 0; methods[i].name != NULL; i++) { - if (strcmp(methods[i].name, method) == 0) - break; - } + surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, + width, height); - if (methods[i].name == NULL) { - printf("unknown request \"%s\"\n", method); - return -1; - } + cr = cairo_create(surface); - request[0] = id; - request[1] = methods[i].opcode; - request[2] = new_id; + cairo_arc(cr, width / 2, height / 2, width / 2 - 10, 0, 2 * M_PI); + cairo_set_source_rgb(cr, 1, 0, 0); + cairo_fill_preserve(cr); + cairo_set_source_rgb(cr, 1, 1, 0); + cairo_stroke(cr); - return write(sock, request, sizeof request); + cairo_arc(cr, width / 2, height / 2, width / 4 - 10, 0, 2 * M_PI); + cairo_set_source_rgb(cr, 0, 0, 1); + cairo_fill_preserve(cr); + cairo_set_source_rgb(cr, 1, 1, 0); + cairo_stroke(cr); + + cairo_destroy(cr); + + return surface; } int main(int argc, char *argv[]) { - struct sockaddr_un name; - socklen_t size; - int sock, len; - char buffer[256]; + struct wl_connection *connection; + struct wl_display *display; + struct wl_surface *surface; + int width = 300, height = 300, fd; + uint32_t name; + cairo_surface_t *s; - sock = socket(PF_LOCAL, SOCK_STREAM, 0); - if (sock < 0) + fd = open(gem_device, O_RDWR); + if (fd < 0) { + fprintf(stderr, "drm open failed: %m\n"); return -1; + } - name.sun_family = AF_LOCAL; - memcpy(name.sun_path, socket_name, sizeof socket_name); + connection = wl_connection_create(socket_name); + if (connection == NULL) { + fprintf(stderr, "failed to create connection: %m\n"); + return -1; + } + + display = wl_connection_get_display(connection); - size = offsetof (struct sockaddr_un, sun_path) + sizeof socket_name; + surface = wl_display_create_surface(display); - if (connect (sock, (struct sockaddr *) &name, size) < 0) + s = draw_stuff(width, height); + name = name_cairo_surface(fd, s); + + wl_surface_attach(surface, name, width, height, + cairo_image_surface_get_stride(s)); + + if (wl_connection_flush(connection) < 0) { + fprintf(stderr, "flush error: %m\n"); return -1; + } - while (len = read(STDIN_FILENO, buffer, sizeof buffer), len > 0) - if (send_request(sock, buffer, len) < 0) - break; + while (1) + wl_connection_iterate(connection); return 0; } |
