12to11/single_pixel_buffer.c

228 lines
5 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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 <https://www.gnu.org/licenses/>. */
#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);
}
static 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);
}