static void create_buffer(struct wl_client *client, struct wl_resource *resource, uint32_t id, uint32_t name) { struct wl_gdl_buffer *buffer; buffer = malloc(sizeof (*buffer)); if (!buffer) { wl_resource_post_no_memory(resource); return; } if (gdl_get_surface_info(name, &buffer->surface_info) != GDL_SUCCESS) { wl_resource_post_error(resource, WL_GDL_ERROR_INVALID_NAME, "invalid surface id %u", name); free(buffer); return; } buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, id); if (buffer->resource == NULL) { wl_resource_post_no_memory(resource); free(buffer); return; } wl_resource_set_implementation(buffer->resource, &gdl_buffer_interface, buffer, destroy_buffer); }
struct wlegl_handle * wlegl_handle_create(struct wl_resource *parent, uint32_t id, int32_t num_fds, struct wl_array *ints) { struct wlegl_handle *handle; handle = malloc(sizeof *handle); if (!handle) { wl_resource_post_no_memory(parent); return; } memset(handle, 0, sizeof *handle); handle->resource = wl_resource_create(wl_resource_get_client(parent), &android_wlegl_handle_interface, 1, id); if (!handle->resource) { wl_resource_post_no_memory(parent); free(handle); return; } wl_resource_set_implementation(handle->resource, &wlegl_handle_implementation, handle, destroy_wlegl_handle); wl_array_init(&handle->ints); wl_array_init(&handle->fds); wl_array_copy(&handle->ints, ints); handle->num_fds = num_fds; handle->num_ints = ints->size / sizeof(int); }
static void create_buffer(struct wl_client *client, struct wl_resource *resource, uint32_t id, uint32_t name, int fd, int32_t width, int32_t height, uint32_t format, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2) { struct wl_drm *drm = resource->data; struct wl_drm_buffer *buffer; buffer = calloc(1, sizeof *buffer); if (buffer == NULL) { wl_resource_post_no_memory(resource); return; } buffer->drm = drm; buffer->width = width; buffer->height = height; buffer->format = format; buffer->fd = fd; buffer->offset[0] = offset0; buffer->stride[0] = stride0; buffer->offset[1] = offset1; buffer->stride[1] = stride1; buffer->offset[2] = offset2; buffer->stride[2] = stride2; /* * these are just for hooking into the 'next' drm buffer layer * and thus not needed here drm->callbacks->reference_buffer(drm->user_data, name, fd, buffer); if (buffer->driver_buffer == NULL){ wl_resource_post_error( resource, WL_DRM_ERROR_INVALID_NAME, "invalid name"); return; } */ buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, id); if (!buffer->resource) { wl_resource_post_no_memory(resource); free(buffer); return; } wl_resource_set_implementation( buffer->resource, (void (**)(void)) &drm->buffer_interface, buffer, destroy_buffer ); }
static bool subcomp_defer_handler( struct surface_request* req, struct arcan_shmif_cont* con) { if (!con){ trace(TRACE_SHELL, "reqfail"); wl_resource_post_no_memory(req->target); return false; } struct wl_resource* subsurf = wl_resource_create(req->client->client, &wl_subsurface_interface, wl_resource_get_version(req->target), req->id); if (!subsurf){ trace(TRACE_SHELL, "reqfail"); wl_resource_post_no_memory(req->target); return false; } struct comp_surf* surf = wl_resource_get_user_data(req->target); wl_resource_set_implementation(subsurf, &subsurf_if, surf, NULL); if (!surf){ trace(TRACE_SHELL, "reqfail"); wl_resource_post_no_memory(req->target); return false; } surf->acon = *con; surf->cookie = 0xfeedface; surf->shell_res = subsurf; surf->dispatch = subsurf_shmifev_handler; surf->sub_parent_res = req->parent; snprintf(surf->tracetag, SURF_TAGLEN, "subsurf"); if (req->parent){ struct comp_surf* psurf = wl_resource_get_user_data(req->parent); if (!psurf->acon.addr){ trace(TRACE_ALLOC, "bad subsurface, broken parent"); return false; } surf->viewport.ext.kind = ARCAN_EVENT(VIEWPORT); surf->viewport.ext.viewport.parent = psurf->acon.segment_token; arcan_shmif_enqueue(&surf->acon, &surf->viewport); } trace(TRACE_ALLOC, "subsurface"); return true; }
static void create_prime_buffer(struct wl_client * client, struct wl_resource * resource, uint32_t id, int32_t fd, int32_t width, int32_t height, uint32_t format, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2) { struct wld_buffer * buffer; struct wl_resource * buffer_resource; union wld_object object = { .i = fd }; buffer = wld_import_buffer(swc.drm->context, WLD_DRM_OBJECT_PRIME_FD, object, width, height, format, stride0); close(fd); if (!buffer) goto error0; buffer_resource = swc_wayland_buffer_create_resource (client, wl_resource_get_version(resource), id, buffer); if (!buffer_resource) goto error1; return; error1: wld_buffer_unreference(buffer); error0: wl_resource_post_no_memory(resource); }
static void create_data_source(struct wl_client *client, struct wl_resource *resource, uint32_t id) { struct wl_data_source *source; source = malloc(sizeof *source); if (source == NULL) { wl_resource_post_no_memory(resource); return; } source->resource.destroy = destroy_data_source; source->resource.object.id = id; source->resource.object.interface = &wl_data_source_interface; source->resource.object.implementation = (void (**)(void)) &data_source_interface; source->resource.data = source; wl_list_init(&source->resource.destroy_listener_list); source->offer_interface = &data_offer_interface; source->cancel = data_source_cancel; wl_array_init(&source->mime_types); wl_client_add_resource(client, &source->resource); }
void Screenshooter::shoot(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *outputResource, wl_resource *bufferResource) { weston_output *output = static_cast<weston_output *>(wl_resource_get_user_data(outputResource)); weston_buffer *buffer = weston_buffer_from_resource(bufferResource); if (!buffer) { wl_resource_post_no_memory(resource); return; } struct Screenshot { static void done(void *data, weston_screenshooter_outcome outcome) { Screenshot *ss = static_cast<Screenshot *>(data); switch (outcome) { case WESTON_SCREENSHOOTER_SUCCESS: orbital_screenshot_send_done(ss->resource); break; case WESTON_SCREENSHOOTER_NO_MEMORY: wl_resource_post_no_memory(ss->resource); break; case WESTON_SCREENSHOOTER_BAD_BUFFER: orbital_screenshot_send_failed(ss->resource); break; } wl_resource_destroy(ss->resource); delete ss; } wl_resource *resource; }; auto res = wl_resource_create(client, &orbital_screenshot_interface, 1, id); if (!res) { wl_resource_post_no_memory(resource); return; } Screenshot *ss = new Screenshot { res }; weston_screenshooter_shoot(output, buffer, Screenshot::done, ss); }
static void create_pool(struct wl_client * client, struct wl_resource * resource, uint32_t id, int32_t fd, int32_t size) { struct pool * pool; if (!(pool = malloc(sizeof *pool))) { wl_resource_post_no_memory(resource); return; } pool->resource = wl_resource_create(client, &wl_shm_pool_interface, wl_resource_get_version(resource), id); if (!pool->resource) { wl_resource_post_no_memory(resource); goto error0; } wl_resource_set_implementation(pool->resource, &shm_pool_implementation, pool, &destroy_pool_resource); pool->data = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); if (pool->data == MAP_FAILED) { wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FD, "mmap failed: %s", strerror(errno)); goto error1; } pool->size = size; pool->references = 1; return; error1: wl_resource_destroy(pool->resource); error0: free(pool); }
void CompositorInterface::Private::createRegion(wl_client *client, wl_resource *resource, uint32_t id) { RegionInterface *region = new RegionInterface(q, resource); region->create(display->getConnection(client), wl_resource_get_version(resource), id); if (!region->resource()) { wl_resource_post_no_memory(resource); delete region; return; } emit q->regionCreated(region); }
static void get_xdg_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource) { struct surface *surface = wl_resource_get_user_data(surface_resource); struct xdg_surface *xdg_surface; xdg_surface = xdg_surface_new(client, wl_resource_get_version(resource), id, surface); if (!xdg_surface) wl_resource_post_no_memory(resource); }
static void create_data_source(struct wl_client * client, struct wl_resource * resource, uint32_t id) { struct wl_resource * data_source; data_source = data_source_new(client, wl_resource_get_version(resource), id); if (!data_source) wl_resource_post_no_memory(resource); }
void CompositorInterface::Private::createSurface(wl_client *client, wl_resource *resource, uint32_t id) { SurfaceInterface *surface = new SurfaceInterface(q, resource); surface->create(display->getConnection(client), wl_resource_get_version(resource), id); if (!surface->resource()) { wl_resource_post_no_memory(resource); delete surface; return; } emit q->surfaceCreated(surface); }
static void get_shell_surface(struct wl_client * client, struct wl_resource * resource, uint32_t id, struct wl_resource * surface_resource) { struct swc_surface * surface = wl_resource_get_user_data(surface_resource); struct swc_shell_surface * shell_surface; shell_surface = swc_shell_surface_new(client, id, surface); if (!shell_surface) wl_resource_post_no_memory(resource); }
static void drm_create_buffer(struct wl_client *client, struct wl_resource *resource, uint32_t id, uint32_t name, int32_t width, int32_t height, uint32_t stride, uint32_t format) { struct wl_drm *drm = resource->data; struct wl_drm_buffer *buffer; switch (format) { case WL_DRM_FORMAT_ARGB8888: case WL_DRM_FORMAT_XRGB8888: break; default: wl_resource_post_error(resource, WL_DRM_ERROR_INVALID_FORMAT, "invalid format"); return; } buffer = calloc(1, sizeof *buffer); if (buffer == NULL) { wl_resource_post_no_memory(resource); return; } buffer->drm = drm; buffer->buffer.width = width; buffer->buffer.height = height; buffer->format = format; buffer->driver_buffer = drm->callbacks->reference_buffer(drm->user_data, name, width, height, stride, format); if (buffer->driver_buffer == NULL) { wl_resource_post_error(resource, WL_DRM_ERROR_INVALID_NAME, "invalid name"); return; } buffer->buffer.resource.object.id = id; buffer->buffer.resource.object.interface = &wl_buffer_interface; buffer->buffer.resource.object.implementation = (void (**)(void)) &drm_buffer_interface; buffer->buffer.resource.data = buffer; buffer->buffer.resource.destroy = destroy_buffer; buffer->buffer.resource.client = resource->client; wl_client_add_resource(resource->client, &buffer->buffer.resource); }
static void data_source_offer (struct wl_client *client, struct wl_resource *resource, const char *type) { MetaWaylandDataSource *source = wl_resource_get_user_data (resource); char **p; p = wl_array_add (&source->mime_types, sizeof *p); if (p) *p = strdup (type); if (!p || !*p) wl_resource_post_no_memory (resource); }
static void get_xdg_popup(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource, struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y) { struct surface *surface = wl_resource_get_user_data(surface_resource); struct surface *parent = wl_resource_get_user_data(parent_resource); struct xdg_popup *popup; popup = xdg_popup_new(client, wl_resource_get_version(resource), id, surface, parent, x, y); if (!popup) wl_resource_post_no_memory(resource); }
static void create_buffer(struct wl_client * client, struct wl_resource * resource, uint32_t id, int32_t offset, int32_t width, int32_t height, int32_t stride, uint32_t format) { struct pool * pool = wl_resource_get_user_data(resource); struct pool_reference * reference; struct wld_buffer * buffer; struct wl_resource * buffer_resource; union wld_object object; if (offset > pool->size || offset < 0) { wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_STRIDE, "offset is too big or negative"); return; } object.ptr = (void *)((uintptr_t) pool->data + offset); buffer = wld_import_buffer(swc.shm->context, WLD_OBJECT_DATA, object, width, height, format_shm_to_wld(format), stride); if (!buffer) goto error0; buffer_resource = wayland_buffer_create_resource (client, wl_resource_get_version(resource), id, buffer); if (!buffer_resource) goto error1; if (!(reference = malloc(sizeof *reference))) goto error2; reference->pool = pool; reference->destructor.destroy = &handle_buffer_destroy; wld_buffer_add_destructor(buffer, &reference->destructor); ++pool->references; return; error2: wl_resource_destroy(buffer_resource); error1: wld_buffer_unreference(buffer); error0: wl_resource_post_no_memory(resource); }
void DpmsManagerInterface::Private::getDpmsCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *output) { auto p = Private::cast(resource); auto c = p->display->getConnection(client); OutputInterface *o = OutputInterface::get(output); DpmsInterface *dpms = new DpmsInterface(o, resource, p->q); dpms->create(c, wl_resource_get_version(resource), id); if (!dpms->resource()) { wl_resource_post_no_memory(resource); return; } dpms->sendSupported(); dpms->sendMode(); dpms->sendDone(); }
static void create_buffer(struct wl_client *client, struct wl_resource *resource, uint32_t id, uint32_t name, int fd, int32_t width, int32_t height, uint32_t format, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2) { struct wl_drm *drm = resource->data; struct wl_drm_buffer *buffer; buffer = calloc(1, sizeof *buffer); if (buffer == NULL) { wl_resource_post_no_memory(resource); return; } buffer->drm = drm; buffer->buffer.width = width; buffer->buffer.height = height; buffer->format = format; buffer->offset[0] = offset0; buffer->stride[0] = stride0; buffer->offset[1] = offset1; buffer->stride[1] = stride1; buffer->offset[2] = offset2; buffer->stride[2] = stride2; drm->callbacks->reference_buffer(drm->user_data, name, fd, buffer); if (buffer->driver_buffer == NULL) { wl_resource_post_error(resource, WL_DRM_ERROR_INVALID_NAME, "invalid name"); return; } buffer->buffer.resource.object.id = id; buffer->buffer.resource.object.interface = &wl_buffer_interface; buffer->buffer.resource.object.implementation = (void (**)(void)) &drm_buffer_interface; buffer->buffer.resource.data = buffer; buffer->buffer.resource.destroy = destroy_buffer; buffer->buffer.resource.client = resource->client; wl_client_add_resource(resource->client, &buffer->buffer.resource); }
static void data_device_start_drag(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source_resource, struct wl_resource *origin_resource, struct wl_resource *icon_resource, uint32_t serial) { struct weston_seat *seat = wl_resource_get_user_data(resource); struct weston_data_source *source = NULL; struct weston_surface *icon = NULL; int32_t ret = 0; if ((seat->pointer->button_count == 0 || seat->pointer->grab_serial != serial || !seat->pointer->focus || seat->pointer->focus->surface != wl_resource_get_user_data(origin_resource)) && (seat->touch->grab_serial != serial || !seat->touch->focus || seat->touch->focus->surface != wl_resource_get_user_data(origin_resource))) return; /* FIXME: Check that the data source type array isn't empty. */ if (source_resource) source = wl_resource_get_user_data(source_resource); if (icon_resource) icon = wl_resource_get_user_data(icon_resource); if (icon && icon->configure) { wl_resource_post_error(icon_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "surface->configure already set"); return; } if (seat->pointer->button_count == 1 && seat->pointer->grab_serial == serial && seat->pointer->focus && seat->pointer->focus->surface == wl_resource_get_user_data(origin_resource)) ret = weston_pointer_start_drag(seat->pointer, source, icon, client); else if (seat->touch->grab_serial != serial || seat->touch->focus || seat->touch->focus->surface != wl_resource_get_user_data(origin_resource)) ret = weston_touch_start_drag(seat->touch, source, icon, client); if (ret < 0) wl_resource_post_no_memory(resource); }
static void done(void *data, weston_screenshooter_outcome outcome) { Screenshot *ss = static_cast<Screenshot *>(data); switch (outcome) { case WESTON_SCREENSHOOTER_SUCCESS: orbital_screenshot_send_done(ss->resource); break; case WESTON_SCREENSHOOTER_NO_MEMORY: wl_resource_post_no_memory(ss->resource); break; case WESTON_SCREENSHOOTER_BAD_BUFFER: orbital_screenshot_send_failed(ss->resource); break; } wl_resource_destroy(ss->resource); delete ss; }
static void get_data_device(struct wl_client *client, struct wl_resource *manager_resource, uint32_t id, struct wl_resource *seat_resource) { struct weston_seat *seat = wl_resource_get_user_data(seat_resource); struct wl_resource *resource; resource = wl_resource_create(client, &wl_data_device_interface, 1, id); if (resource == NULL) { wl_resource_post_no_memory(manager_resource); return; } wl_list_insert(&seat->drag_resource_list, wl_resource_get_link(resource)); wl_resource_set_implementation(resource, &data_device_interface, seat, unbind_data_device); }
static void linux_dmabuf_create_params(struct wl_client *client, struct wl_resource *linux_dmabuf_resource, uint32_t params_id) { struct weston_compositor *compositor; struct linux_dmabuf_buffer *buffer; uint32_t version; int i; version = wl_resource_get_version(linux_dmabuf_resource); compositor = wl_resource_get_user_data(linux_dmabuf_resource); buffer = zalloc(sizeof *buffer); if (!buffer) goto err_out; for (i = 0; i < MAX_DMABUF_PLANES; i++) buffer->attributes.fd[i] = -1; buffer->compositor = compositor; buffer->params_resource = wl_resource_create(client, &zwp_linux_buffer_params_v1_interface, version, params_id); if (!buffer->params_resource) goto err_dealloc; wl_resource_set_implementation(buffer->params_resource, &zwp_linux_buffer_params_implementation, buffer, destroy_params); return; err_dealloc: free(buffer); err_out: wl_resource_post_no_memory(linux_dmabuf_resource); }
static void wlegl_handle_add_fd(struct wl_client *client, struct wl_resource *resource, int32_t fd) { struct wlegl_handle *handle = wl_resource_get_user_data(resource); int *next_fd; if (handle->fds.size >= handle->num_fds * sizeof(int)) { wl_resource_post_error(handle->resource, ANDROID_WLEGL_HANDLE_ERROR_TOO_MANY_FDS, "too many file descriptors"); close(fd); return; } next_fd = wl_array_add(&handle->fds, sizeof(int)); if (!next_fd) { wl_resource_post_no_memory(resource); return; } *next_fd = fd; }
static void create_data_source(struct wl_client *client, struct wl_resource *resource, uint32_t id) { struct weston_data_source *source; source = malloc(sizeof *source); if (source == NULL) { wl_resource_post_no_memory(resource); return; } wl_signal_init(&source->destroy_signal); source->accept = client_source_accept; source->send = client_source_send; source->cancel = client_source_cancel; wl_array_init(&source->mime_types); source->resource = wl_resource_create(client, &wl_data_source_interface, 1, id); wl_resource_set_implementation(source->resource, &data_source_interface, source, destroy_data_source); }
static void params_create(struct wl_client *client, struct wl_resource *params_resource, int32_t width, int32_t height, uint32_t format, uint32_t flags) { struct linux_dmabuf_buffer *buffer; int i; buffer = wl_resource_get_user_data(params_resource); if (!buffer) { wl_resource_post_error(params_resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED, "params was already used to create a wl_buffer"); return; } assert(buffer->params_resource == params_resource); assert(!buffer->buffer_resource); /* Switch the linux_dmabuf_buffer object from params resource to * eventually wl_buffer resource. */ wl_resource_set_user_data(buffer->params_resource, NULL); buffer->params_resource = NULL; if (!buffer->attributes.n_planes) { wl_resource_post_error(params_resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, "no dmabuf has been added to the params"); goto err_out; } /* Check for holes in the dmabufs set (e.g. [0, 1, 3]) */ for (i = 0; i < buffer->attributes.n_planes; i++) { if (buffer->attributes.fd[i] == -1) { wl_resource_post_error(params_resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, "no dmabuf has been added for plane %i", i); goto err_out; } } buffer->attributes.width = width; buffer->attributes.height = height; buffer->attributes.format = format; buffer->attributes.flags = flags; if (width < 1 || height < 1) { wl_resource_post_error(params_resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS, "invalid width %d or height %d", width, height); goto err_out; } for (i = 0; i < buffer->attributes.n_planes; i++) { off_t size; if ((uint64_t) buffer->attributes.offset[i] + buffer->attributes.stride[i] > UINT32_MAX) { wl_resource_post_error(params_resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, "size overflow for plane %i", i); goto err_out; } if (i == 0 && (uint64_t) buffer->attributes.offset[i] + (uint64_t) buffer->attributes.stride[i] * height > UINT32_MAX) { wl_resource_post_error(params_resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, "size overflow for plane %i", i); goto err_out; } /* Don't report an error as it might be caused * by the kernel not supporting seeking on dmabuf */ size = lseek(buffer->attributes.fd[i], 0, SEEK_END); if (size == -1) break; if (buffer->attributes.offset[i] >= size) { wl_resource_post_error(params_resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, "invalid offset %i for plane %i", buffer->attributes.offset[i], i); goto err_out; } if (buffer->attributes.offset[i] + buffer->attributes.stride[i] > size) { wl_resource_post_error(params_resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, "invalid stride %i for plane %i", buffer->attributes.stride[i], i); goto err_out; } /* Only valid for first plane as other planes might be * sub-sampled according to fourcc format */ if (i == 0 && buffer->attributes.offset[i] + buffer->attributes.stride[i] * height > size) { wl_resource_post_error(params_resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, "invalid buffer stride or height for plane %i", i); goto err_out; } } /* XXX: Some additional sanity checks could be done with respect * to the fourcc format. A centralized collection (kernel or * libdrm) would be useful to avoid code duplication for these * checks (e.g. drm_format_num_planes). */ if (!weston_compositor_import_dmabuf(buffer->compositor, buffer)) goto err_failed; buffer->buffer_resource = wl_resource_create(client, &wl_buffer_interface, 1, 0); if (!buffer->buffer_resource) { wl_resource_post_no_memory(params_resource); goto err_buffer; } wl_resource_set_implementation(buffer->buffer_resource, &linux_dmabuf_buffer_implementation, buffer, destroy_linux_dmabuf_wl_buffer); zwp_linux_buffer_params_v1_send_created(params_resource, buffer->buffer_resource); return; err_buffer: if (buffer->user_data_destroy_func) buffer->user_data_destroy_func(buffer); err_failed: zwp_linux_buffer_params_v1_send_failed(params_resource); err_out: linux_dmabuf_buffer_destroy(buffer); }