From a5c7565eb02ebe3556ee58cc525a6ec07da02539 Mon Sep 17 00:00:00 2001 From: oldosfan Date: Thu, 6 Oct 2022 10:42:20 +0000 Subject: [PATCH] Check in files for single pixel buffer support * single-pixel-buffer-v1.xml: * single_pixel_buffer.c: New files. --- single-pixel-buffer-v1.xml | 69 +++++++++++ single_pixel_buffer.c | 228 +++++++++++++++++++++++++++++++++++++ 2 files changed, 297 insertions(+) create mode 100644 single-pixel-buffer-v1.xml create mode 100644 single_pixel_buffer.c diff --git a/single-pixel-buffer-v1.xml b/single-pixel-buffer-v1.xml new file mode 100644 index 0000000..b157155 --- /dev/null +++ b/single-pixel-buffer-v1.xml @@ -0,0 +1,69 @@ + + + + Copyright © 2022 Simon Ser + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol extension allows clients to create single-pixel buffers. + + Compositors supporting this protocol extension should also support the + viewporter protocol extension. Clients may use viewporter to scale a + single-pixel buffer to a desired size. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + + The wp_single_pixel_buffer_manager_v1 interface is a factory for + single-pixel buffers. + + + + + Destroy the wp_single_pixel_buffer_manager_v1 object. + + The child objects created via this interface are unaffected. + + + + + + Create a single-pixel buffer from four 32-bit RGBA values. + + Unless specified in another protocol extension, the RGBA values use + pre-multiplied alpha. + + The width and height of the buffer are 1. + + + + + + + + + diff --git a/single_pixel_buffer.c b/single_pixel_buffer.c new file mode 100644 index 0000000..95dee4e --- /dev/null +++ b/single_pixel_buffer.c @@ -0,0 +1,228 @@ +/* Wayland compositor running on top of an X server. + +Copyright (C) 2022 to various contributors. + +This file is part of 12to11. + +12to11 is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +12to11 is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with 12to11. If not, see . */ + +#include "compositor.h" +#include "single-pixel-buffer-v1.h" +#include "string.h" + +typedef struct _Buffer Buffer; + +struct _Buffer +{ + /* The ExtBuffer associated with this buffer. */ + ExtBuffer buffer; + + /* The rendering buffer associated with this buffer. */ + RenderBuffer render_buffer; + + /* The wl_resource corresponding to this buffer. */ + struct wl_resource *resource; + + /* The number of references to this buffer. */ + int refcount; +}; + +/* The global wp_single_pixel_buffer_manager_v1 resource. */ +static struct wl_global *single_pixel_buffer_global; + +static void +DestroyBuffer (struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct wl_buffer_interface single_pixel_buffer_impl = + { + .destroy = DestroyBuffer, + }; + +static void +RetainBuffer (Buffer *buffer) +{ + buffer->refcount++; +} + +static void +DereferenceBuffer (Buffer *buffer) +{ + if (--buffer->refcount) + return; + + RenderFreeSinglePixelBuffer (buffer->render_buffer); + ExtBufferDestroy (&buffer->buffer); + XLFree (buffer); +} + +static void +ReleaseBufferFunc (ExtBuffer *buffer) +{ + if (((Buffer *) buffer)->resource) + wl_buffer_send_release (((Buffer *) buffer)->resource); +} + +static void +RetainBufferFunc (ExtBuffer *buffer) +{ + RetainBuffer ((Buffer *) buffer); +} + +static void +DereferenceBufferFunc (ExtBuffer *buffer) +{ + DereferenceBuffer ((Buffer *) buffer); +} + +static RenderBuffer +GetBufferFunc (ExtBuffer *buffer) +{ + return ((Buffer *) buffer)->render_buffer; +} + +static unsigned int +WidthFunc (ExtBuffer *buffer) +{ + /* Single pixel buffers are always 1x1. */ + return 1; +} + +static unsigned int +HeightFunc (ExtBuffer *buffer) +{ + /* Single pixel buffers are always 1x1. */ + return 1; +} + +static void +PrintBuffer (Buffer *buffer) +{ + /* Not implemented. */ +} + +static void +PrintBufferFunc (ExtBuffer *buffer) +{ + PrintBuffer ((Buffer *) buffer); +} + +static void +HandleResourceDestroy (struct wl_resource *resource) +{ + Buffer *buffer; + + buffer = wl_resource_get_user_data (resource); + buffer->resource = NULL; + + DereferenceBuffer (buffer); +} + + + +static void +Destroy (struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +void +CreateU32RgbaBuffer (struct wl_client *client, struct wl_resource *resource, + uint32_t id, uint32_t r, uint32_t g, uint32_t b, + uint32_t a) +{ + Buffer *buffer; + Bool error; + + buffer = XLSafeMalloc (sizeof *buffer); + + if (!buffer) + { + wl_resource_post_no_memory (resource); + return; + } + + memset (buffer, 0, sizeof *buffer); + buffer->resource = wl_resource_create (client, &wl_buffer_interface, + wl_resource_get_version (resource), + id); + + if (!buffer->resource) + { + out_of_memory: + wl_resource_post_no_memory (resource); + XLFree (buffer); + return; + } + + /* Now, create the render target. */ + error = False; + buffer->render_buffer = RenderBufferFromSinglePixel (r, g, b, a, + &error); + + if (error) + /* We probably ran out of memory. */ + goto out_of_memory; + + buffer->refcount = 1; + + /* Initialize function pointers. */ + buffer->buffer.funcs.retain = RetainBufferFunc; + buffer->buffer.funcs.dereference = DereferenceBufferFunc; + buffer->buffer.funcs.get_buffer = GetBufferFunc; + buffer->buffer.funcs.width = WidthFunc; + buffer->buffer.funcs.height = HeightFunc; + buffer->buffer.funcs.release = ReleaseBufferFunc; + buffer->buffer.funcs.print_buffer = PrintBufferFunc; + + wl_resource_set_implementation (buffer->resource, &single_pixel_buffer_impl, + buffer, HandleResourceDestroy); +} + +static const struct wp_single_pixel_buffer_manager_v1_interface manager_impl = + { + .destroy = Destroy, + .create_u32_rgba_buffer = CreateU32RgbaBuffer, + }; + +static void +HandleBind (struct wl_client *client, void *data, uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, + &wp_single_pixel_buffer_manager_v1_interface, + version, id); + + if (!resource) + { + wl_client_post_no_memory (client); + return; + } + + wl_resource_set_implementation (resource, &manager_impl, + NULL, NULL); +} + +void +XLInitSinglePixelBuffer (void) +{ + single_pixel_buffer_global + = wl_global_create (compositor.wl_display, + &wp_single_pixel_buffer_manager_v1_interface, + 1, NULL, HandleBind); +}