wayland-drm.c revision 58dc1b28d1ef4d1931c52b079d304f2e1546329d
1/* 2 * Copyright © 2011 Kristian Høgsberg 3 * Copyright © 2011 Benjamin Franzke 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 * DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Kristian Høgsberg <krh@bitplanet.net> 27 * Benjamin Franzke <benjaminfranzke@googlemail.com> 28 */ 29 30#include <stdio.h> 31#include <stdlib.h> 32#include <string.h> 33#include <stddef.h> 34 35#include <wayland-server.h> 36#include "wayland-drm.h" 37#include "wayland-drm-server-protocol.h" 38 39struct wl_drm { 40 struct wl_display *display; 41 42 void *user_data; 43 char *device_name; 44 45 struct wayland_drm_callbacks *callbacks; 46}; 47 48struct wl_drm_buffer { 49 struct wl_buffer buffer; 50 struct wl_drm *drm; 51 uint32_t format; 52 53 void *driver_buffer; 54}; 55 56static void 57buffer_damage(struct wl_client *client, struct wl_resource *buffer, 58 int32_t x, int32_t y, int32_t width, int32_t height) 59{ 60} 61 62static void 63destroy_buffer(struct wl_resource *resource) 64{ 65 struct wl_drm_buffer *buffer = resource->data; 66 struct wl_drm *drm = buffer->drm; 67 68 drm->callbacks->release_buffer(drm->user_data, 69 buffer->driver_buffer); 70 free(buffer); 71} 72 73static void 74buffer_destroy(struct wl_client *client, struct wl_resource *resource) 75{ 76 wl_resource_destroy(resource, 0); 77} 78 79const static struct wl_buffer_interface drm_buffer_interface = { 80 buffer_damage, 81 buffer_destroy 82}; 83 84static void 85drm_create_buffer(struct wl_client *client, struct wl_resource *resource, 86 uint32_t id, uint32_t name, int32_t width, int32_t height, 87 uint32_t stride, uint32_t format) 88{ 89 struct wl_drm *drm = resource->data; 90 struct wl_drm_buffer *buffer; 91 92 switch (format) { 93 case WL_DRM_FORMAT_ARGB8888: 94 case WL_DRM_FORMAT_XRGB8888: 95 break; 96 default: 97 wl_resource_post_error(resource, 98 WL_DRM_ERROR_INVALID_FORMAT, 99 "invalid format"); 100 return; 101 } 102 103 buffer = calloc(1, sizeof *buffer); 104 if (buffer == NULL) { 105 wl_resource_post_no_memory(resource); 106 return; 107 } 108 109 buffer->drm = drm; 110 buffer->buffer.width = width; 111 buffer->buffer.height = height; 112 buffer->format = format; 113 114 buffer->driver_buffer = 115 drm->callbacks->reference_buffer(drm->user_data, name, 116 width, height, 117 stride, format); 118 119 if (buffer->driver_buffer == NULL) { 120 wl_resource_post_error(resource, 121 WL_DRM_ERROR_INVALID_NAME, 122 "invalid name"); 123 return; 124 } 125 126 buffer->buffer.resource.object.id = id; 127 buffer->buffer.resource.object.interface = &wl_buffer_interface; 128 buffer->buffer.resource.object.implementation = 129 (void (**)(void)) &drm_buffer_interface; 130 buffer->buffer.resource.data = buffer; 131 132 buffer->buffer.resource.destroy = destroy_buffer; 133 buffer->buffer.resource.client = resource->client; 134 135 wl_client_add_resource(resource->client, &buffer->buffer.resource); 136} 137 138static void 139drm_authenticate(struct wl_client *client, 140 struct wl_resource *resource, uint32_t id) 141{ 142 struct wl_drm *drm = resource->data; 143 144 if (drm->callbacks->authenticate(drm->user_data, id) < 0) 145 wl_resource_post_error(resource, 146 WL_DRM_ERROR_AUTHENTICATE_FAIL, 147 "authenicate failed"); 148 else 149 wl_resource_post_event(resource, WL_DRM_AUTHENTICATED); 150} 151 152const static struct wl_drm_interface drm_interface = { 153 drm_authenticate, 154 drm_create_buffer 155}; 156 157static void 158bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id) 159{ 160 struct wl_drm *drm = data; 161 struct wl_resource *resource; 162 163 resource = wl_client_add_object(client, &wl_drm_interface, 164 &drm_interface, id, data); 165 wl_resource_post_event(resource, WL_DRM_DEVICE, drm->device_name); 166 wl_resource_post_event(resource, WL_DRM_FORMAT, 167 WL_DRM_FORMAT_ARGB8888); 168 wl_resource_post_event(resource, WL_DRM_FORMAT, 169 WL_DRM_FORMAT_XRGB8888); 170} 171 172struct wl_drm * 173wayland_drm_init(struct wl_display *display, char *device_name, 174 struct wayland_drm_callbacks *callbacks, void *user_data) 175{ 176 struct wl_drm *drm; 177 178 drm = malloc(sizeof *drm); 179 180 drm->display = display; 181 drm->device_name = strdup(device_name); 182 drm->callbacks = callbacks; 183 drm->user_data = user_data; 184 185 wl_display_add_global(display, &wl_drm_interface, drm, bind_drm); 186 187 return drm; 188} 189 190void 191wayland_drm_uninit(struct wl_drm *drm) 192{ 193 free(drm->device_name); 194 195 /* FIXME: need wl_display_del_{object,global} */ 196 197 free(drm); 198} 199 200int 201wayland_buffer_is_drm(struct wl_buffer *buffer) 202{ 203 return buffer->resource.object.implementation == 204 (void (**)(void)) &drm_buffer_interface; 205} 206 207uint32_t 208wayland_drm_buffer_get_format(struct wl_buffer *buffer_base) 209{ 210 struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) buffer_base; 211 212 return buffer->format; 213} 214 215void * 216wayland_drm_buffer_get_buffer(struct wl_buffer *buffer_base) 217{ 218 struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) buffer_base; 219 220 return buffer->driver_buffer; 221} 222