Add support for more resources and single pixel buffers

* 12to11.c (HandleCmdline): Handle `-xrm'.
(XLMain): Initialize single pixel buffers.
* 12to11.man: Improve documentation.
* Imakefile (SRCS): Add single_pixel_buffer.c.
(OBJS): Add single_pixel_buffer.o.
(single-pixel-buffer-v1): Add new scanner target.
* README: Document new supported protocol.
* compositor.h (struct _BufferFuncs): Add single pixel buffer
functions.
* egl.c (enum _EglBufferType): New buffer type.
(struct _EglSinglePixelBuffer): New struct.
(struct _EglBuffr): Add EglSinglePixelBuffer.
(struct _CompositeProgram): Add source_color uniform.
(EglCompileCompositeProgram): Look for both uniforms.
(EglCompileShaders): Compile single pixel shader.
(FindProgram, GetTextureTarget, Composite, UpdateTexture)
(EnsureTexture, UpdateBuffer): Handle single pixel buffers.
(BufferFromSinglePixel, FreeSinglePixelBuffer): New functions.
(egl_buffer_funcs): Add new buffer functions.
* picture_renderer.c (BufferFromSinglePixel,
FreeSinglePixelBuffer): New functions.
(picture_buffer_funcs): Add new buffer functions.
* renderer.c (RenderBufferFromSinglePixel)
(RenderUpdateBufferForDamage): New functions.
(ReadRendererResource, PickRenderer): Read resource if no
environment variable was specified.
* shaders.txt (Composite Rectangle Fragment Shader Single
Pixel): New shader.
* text_input.c (struct _TextInput, UpdatePreedit)
(PreeditStartCallback, PreeditCaretCallback): Correctly handle
caret types and style.
(XLInitTextInput): Fix failure message.
This commit is contained in:
oldosfan 2022-10-06 10:46:54 +00:00
parent a5c7565eb0
commit f2e3baad45
10 changed files with 385 additions and 36 deletions

View file

@ -65,9 +65,10 @@ DetermineServerTime (void)
}
static void
HandleCmdline (int argc, char **argv)
HandleCmdline (Display *dpy, int argc, char **argv)
{
int i;
XrmDatabase rdb, initial_rdb;
/* Set the default resource and class names. */
compositor.resource_name = "12to11";
@ -77,6 +78,9 @@ HandleCmdline (int argc, char **argv)
/* There are no arguments to handle. */
return;
/* Obtain the resource database. */
initial_rdb = rdb = XrmGetDatabase (dpy);
/* Determine the instance name based on the executable. First,
remove any leading directory separator from argv[0]. */
compositor.app_name = strrchr (argv[0], '/');
@ -94,7 +98,7 @@ HandleCmdline (int argc, char **argv)
{
print_usage:
fprintf (stderr,
"usage: %s [-name name] [-class class]\n",
"usage: %s [-name name] [-class class] [-xrm resourcestring]...\n",
argv[0]);
exit (!strcmp (argv[i], "-help") ? 0 : 1);
}
@ -120,6 +124,17 @@ HandleCmdline (int argc, char **argv)
compositor.app_name = argv[++i];
}
else if (!strcmp (argv[i], "-xrm"))
{
if (i + 1 >= argc)
{
fprintf (stderr, "%s: option -xrm requires a value\n",
argv[0]);
exit (1);
}
XrmPutLineResource (&rdb, argv[++i]);
}
else
{
fprintf (stderr, "%s: bad command line option \"%s\"\n",
@ -127,6 +142,11 @@ HandleCmdline (int argc, char **argv)
goto print_usage;
}
}
/* In case XrmPutLineResource created a new database, set it as the
display's resource database. */
if (rdb != initial_rdb)
XrmSetDatabase (dpy, rdb);
}
static void
@ -162,7 +182,7 @@ XLMain (int argc, char **argv)
XGetDefault (dpy, "dummmy", "value");
/* Parse command-line arguments. */
HandleCmdline (argc, argv);
HandleCmdline (dpy, argc, argv);
compositor.display = dpy;
compositor.conn = XGetXCBConnection (dpy);
@ -203,6 +223,8 @@ XLMain (int argc, char **argv)
XLInitWpViewporter ();
XLInitDecoration ();
XLInitTextInput ();
XLInitSinglePixelBuffer ();
/* This has to come after the rest of the initialization. */
DetermineServerTime ();
XLRunCompositor ();

View file

@ -3,7 +3,7 @@
12to11 - Wayland to X protocol translator
.SH SYNOPSIS
.B 12to11
[\-\fIclass\fP class] [\-\fIname\fP name]
[\-\fBclass\fP \fIclass\fP] [\-\fBname\fP \fIname\fP] [\-\fBxrm\fP \fIresourcestring\fP]...
.SH DESCRIPTION
.I 12to11
starts a Wayland compositor on the next available socket;
@ -26,11 +26,16 @@ Wayland clients.
.B \-name \fIname\fP
This option specifies the instance name under which resources are to
be obtained. When not set, it defaults to the executable file name.
.TP 8
.TP
.B \-help\fP
This option causes the protocol translator to print a message
describing options it accepts. The protocol translator will then exit
after printing the message.
.TP
.B \-xrm\fP \fIresourcestring\fP
This option specifies a resource string to be used. This is
especially useful for setting resources that do not have separate
command line options.
.SH RESOURCES
\fI12to11\fP understands some resource names and classes that can be
used to specify various settings that affect its behavior. Those
@ -55,26 +60,26 @@ translator.
X input methods can support different editing styles, which affect how
preconversion and status text is displayed while typing. These styles
are named:
.TP
.I overTheSpot
.TP 16
.B overTheSpot
In ``over the spot'', the preedit string is displayed in a window
created by the input method at a location specified by the Wayland
client, typically the text insertion point.
.TP
.I offTheSpot
.B offTheSpot
In ``off the spot'', the preedit string is displayed in a window
created by the input method at some location away from the text
insertion point. Often, this type of window is placed at the bottom
of the preedit window.
.TP
.I rootWindow
.B rootWindow
In the ``root window'' editing style, the preedit string is displayed
in a popup window created by the input method.
.TP
.I onTheSpot
.B onTheSpot
In the ``on the spot'' editing style, the preedit string is displayed
inside the text itself by the Wayland client.
.PP
.IP "" 8
Not all input methods support all editing styles. In the real world,
most only support one or two of the styles listed above. The protocol
translator will search for a style supported by the input method when
@ -82,23 +87,29 @@ initializing input method support. The \fBximStyles\fP resource is
used to control the order in which the protocol translator searches
for input styles, and should be a comma separated list of input names,
which are searched in left-to-right order. For example,
.PP
.IP
.in +4
.EX
\fBoverTheSpot,rootWindow\fP
.EE
.in
.PP
.IP
will result in the protocol translator searching for the ``over the
spot'' input style, and if that is not present, the ``root window''
style. Whitespace must not be present inside the comma-separated
list. When \fBximStyles\fP is not specified, it defaults to:
.PP
.IP
.in +4
.EX
\fBoverTheSpot,offTheSpot,rootWindow,onTheSpot\fP
.EE
.in
.TP
.B renderer \fP (class \fBRenderer\fP)
Specifies the rendering backend the protocol translator uses to
composite the contents of Wayland surfaces onto X windows. This can
either be \fBpicture\fP (the XRender based compositor) or \fBegl\fP
(the OpenGL ES 2.0 based compositor).
.SH ENVIRONMENT
Several environment variables exist that modify the behavior of the
protocol translator in one way or another. Most of these are used for
@ -163,12 +174,49 @@ The
variable, if set, controls the rendering backend used by the
protocol translator. When set to
.I help
it prints a list of available rendering backends instead.
it prints a list of available rendering backends instead. This takes
precedence over the \fBrenderer\fP resource whenever set.
.PP
The
.B RENDER_VISUAL
variable, if set to a number, contains the ID of the visual used
when the EGL rendering backend is in use.
.SH "CONFORMING TO"
The protocol translator aims to comply with the specifications of the
following Wayland interfaces:
.TS H
lb lb
lb n .
Protocol Version
wl_output 2
wl_compositor 5
wl_shm 1
xdg_wm_base 5
wl_subcompositor 1
wl_seat 7
wl_data_device_manager 3
zwp_linux_dmabuf_v1 4
zwp_primary_selection_device_manager_v1 1
wp_viewporter 1
zxdg_decoration_manager_v1 1
zwp_text_input_manager_v3 1
wp_single_pixel_buffer_manager_v1 1
.TE
.PP
When the protocol translator is built with EGL support, the following
protocol is also supported:
.TS H
lb lb
lb n .
Protocol Version
zwp_linux_explicit_synchronization_v1 2
.TE
.PP
However, Wayland clients are allowed to continue to access data from
the \fBCLIPBOARD\fP and \fBPRIMARY\fP selections even when they do not
have the keyboard focus, against the restrictions put out in the
relevant protocol specifications. It is the opinion of the authors
that such ``security'' does not come with any real benefit.
.SH BUGS
There is a hard to catch bug where Wayland programs leaving the
fullscreen or maximized state may abruptly return to their maximized
@ -188,6 +236,10 @@ and
.B _NET_WM_STATE
window manager hints will result in Wayland programs running
incorrectly.
.PP
In addition, surfaces transforms are not supported nor reported. The
vast majority of clients seem not to make use of this feature, and
implementing it would be a lot of trouble.
.SH "SEE ALSO"
X(7), Xorg(1)
.SH AUTHOR

View file

@ -21,7 +21,8 @@ SRCS = 12to11.c run.c alloc.c fns.c output.c compositor.c \
dmabuf.c buffer.c select.c xdata.c xsettings.c dnd.c \
icon_surface.c primary_selection.c renderer.c \
picture_renderer.c explicit_synchronization.c transform.c \
wp_viewporter.c decoration.c text_input.c
wp_viewporter.c decoration.c text_input.c \
single_pixel_buffer.c
OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o \
surface.o region.o shm.o atoms.o subcompositor.o positioner.o \
@ -30,7 +31,8 @@ OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o \
dmabuf.o buffer.o select.o xdata.o xsettings.o dnd.o \
icon_surface.o primary_selection.o renderer.o \
picture_renderer.o explicit_synchronization.o transform.o \
wp_viewporter.o decoration.o text_input.o
wp_viewporter.o decoration.o text_input.o \
single_pixel_buffer.o
GENHEADERS = transfer_atoms.h
@ -112,6 +114,7 @@ ScannerTarget(linux-explicit-synchronization-unstable-v1)
ScannerTarget(viewporter)
ScannerTarget(xdg-decoration-unstable-v1)
ScannerTarget(text-input-unstable-v3)
ScannerTarget(single-pixel-buffer-v1)
/* Make OBJS depend on scanner headers, and depend on both them and SRCS. */
$(OBJS): $(GENHEADERS)

4
README
View file

@ -50,7 +50,8 @@ for the following EGL and GLES extensions to be present at runtime:
GL_EXT_unpack_subimage
After building with EGL support, the renderer must be enabled by
setting the environment variable "RENDERER" to "egl".
setting the environment variable "RENDERER" to "egl", or by setting
the "renderer" resource (class "Renderer") to "egl".
The following Wayland protocols are implemented to a more-or-less
complete degree:
@ -67,6 +68,7 @@ complete degree:
'wp_viewporter', version: 1
'zxdg_decoration_manager_v1', version: 1
'zwp_text_input_manager_v3', version: 1
'wp_single_pixel_buffer_manager_v1', version: 1
When built with EGL, the following Wayland protocol is also supported:

View file

@ -378,12 +378,19 @@ struct _BufferFuncs
Bool (*validate_shm_params) (uint32_t, uint32_t, uint32_t, int32_t,
int32_t, size_t);
/* Create a buffer from the given RGBA color. */
RenderBuffer (*buffer_from_single_pixel) (uint32_t, uint32_t, uint32_t, uint32_t,
Bool *);
/* Free a buffer created from shared memory. */
void (*free_shm_buffer) (RenderBuffer);
/* Free a dma-buf buffer. */
void (*free_dmabuf_buffer) (RenderBuffer);
/* Free a single-pixel buffer. */
void (*free_single_pixel_buffer) (RenderBuffer);
/* Notice that the given buffer has been damaged. May be NULL. If
the given NULL damage, assume that the entire buffer has been
damaged. Must be called at least once before any rendering can
@ -435,8 +442,11 @@ extern void RenderBufferFromDmaBufAsync (DmaBufAttributes *, DmaBufSuccessFunc,
extern RenderBuffer RenderBufferFromShm (SharedMemoryAttributes *, Bool *);
extern Bool RenderValidateShmParams (uint32_t, uint32_t, uint32_t, int32_t,
int32_t, size_t);
extern RenderBuffer RenderBufferFromSinglePixel (uint32_t, uint32_t, uint32_t,
uint32_t, Bool *);
extern void RenderFreeShmBuffer (RenderBuffer);
extern void RenderFreeDmabufBuffer (RenderBuffer);
extern void RenderFreeSinglePixelBuffer (RenderBuffer);
extern void RenderUpdateBufferForDamage (RenderBuffer, pixman_region32_t *,
DrawParams *);
extern Bool RenderCanReleaseNow (RenderBuffer);
@ -1463,6 +1473,10 @@ extern void XLWpViewportReportOutOfBuffer (ViewportExt *);
extern void XLInitDecoration (void);
/* Defined in single_pixel_buffer.c. */
extern void XLInitSinglePixelBuffer (void);
/* Utility functions that don't belong in a specific file. */
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])

124
egl.c
View file

@ -49,6 +49,7 @@ typedef struct _EglBuffer EglBuffer;
typedef struct _EglDmaBufBuffer EglDmaBufBuffer;
typedef struct _EglShmBuffer EglShmBuffer;
typedef struct _EglSinglePixelBuffer EglSinglePixelBuffer;
typedef struct _FormatInfo FormatInfo;
typedef struct _CompositeProgram CompositeProgram;
@ -57,6 +58,7 @@ enum _EglBufferType
{
DmaBufBuffer,
ShmBuffer,
SinglePixelBuffer,
};
struct _EglDmaBufBuffer
@ -86,6 +88,15 @@ struct _EglShmBuffer
FormatInfo *format;
};
struct _EglSinglePixelBuffer
{
/* The type of this buffer. Always DmaBufBuffer. */
EglBufferType type;
/* The red, green, blue and alpha values. */
float r, g, b, a;
};
struct _FormatInfo
{
/* The corresponding Wayland format. */
@ -141,6 +152,9 @@ struct _EglBuffer
/* A shared memory buffer. */
EglShmBuffer shm;
/* A single-pixel buffer. */
EglSinglePixelBuffer single_pixel;
} u;
};
@ -190,6 +204,9 @@ struct _CompositeProgram
/* The index of the invert_y uniform. */
GLuint invert_y;
/* The index of the source_pixel uniform. */
GLuint source_color;
};
/* This macro makes column major order easier to reason about for C
@ -387,6 +404,9 @@ static CompositeProgram xrgb_program;
/* Composition program for external textures. */
static CompositeProgram external_program;
/* Composition program for single pixel buffers. */
static CompositeProgram single_pixel_buffer_program;
/* Whether or not buffer age is supported. */
static Bool have_egl_ext_buffer_age;
@ -885,6 +905,8 @@ EglCompileCompositeProgram (CompositeProgram *program,
"source");
program->invert_y = glGetUniformLocation (program->program,
"invert_y");
program->source_color = glGetUniformLocation (program->program,
"source_color");
/* Now delete the shaders. */
glDeleteShader (vertex);
@ -928,6 +950,8 @@ EglCompileShaders (void)
composite_rectangle_fragment_shader_rgbx);
EglCompileCompositeProgram (&external_program,
composite_rectangle_fragment_shader_external);
EglCompileCompositeProgram (&single_pixel_buffer_program,
composite_rectangle_fragment_shader_single_pixel);
}
/* Forward declaration. */
@ -1276,6 +1300,9 @@ FindProgram (EglBuffer *buffer)
{
switch (buffer->u.type)
{
case SinglePixelBuffer:
/* Use the single-pixel buffer program. */
return &single_pixel_buffer_program;
case DmaBufBuffer:
if (buffer->u.dmabuf.format->flags & NeedExternalTarget)
/* Use the external format compositor program. */
@ -1302,6 +1329,10 @@ GetTextureTarget (EglBuffer *buffer)
case ShmBuffer:
return GL_TEXTURE_2D;
default:
/* This should not be called with a single pixel buffer. */
abort ();
}
/* This is not supposed to happen. */
@ -1356,15 +1387,21 @@ Composite (RenderBuffer buffer, RenderTarget target,
egl_target = target.pointer;
egl_buffer = buffer.pointer;
/* Assert that a texture was generated, since UpdateBuffer should be
called before the buffer is ever used. */
if (egl_buffer->u.type != SinglePixelBuffer)
{
/* Assert that a texture was generated, since UpdateBuffer should
be called before the buffer is ever used. */
XLAssert (egl_buffer->flags & IsTextureGenerated);
/* Find the program to use for compositing. */
program = FindProgram (egl_buffer);
/* Get the texturing target. */
tex_target = GetTextureTarget (egl_buffer);
}
else
/* This value is not actually used. */
tex_target = 0;
/* Find the program to use for compositing. */
program = FindProgram (egl_buffer);
/* Compute the transformation matrix to use to draw the given
buffer. */
@ -1415,15 +1452,30 @@ Composite (RenderBuffer buffer, RenderTarget target,
else
glDisable (GL_BLEND);
/* Single pixel buffers have no textures. */
if (egl_buffer->u.type != SinglePixelBuffer)
{
glActiveTexture (GL_TEXTURE0);
glBindTexture (tex_target, egl_buffer->texture);
glTexParameteri (tex_target, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexParameteri (tex_target, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
}
glUseProgram (program->program);
/* Single pixel buffers have no textures. */
if (egl_buffer->u.type != SinglePixelBuffer)
glUniform1i (program->texture, 0);
else
/* Attach the source color. */
glUniform4f (program->source_color,
egl_buffer->u.single_pixel.r,
egl_buffer->u.single_pixel.g,
egl_buffer->u.single_pixel.b,
egl_buffer->u.single_pixel.a);
glUniformMatrix3fv (program->source, 1, GL_FALSE,
egl_buffer->matrix);
glUniform1i (program->invert_y, egl_buffer->flags & InvertY);
@ -1440,6 +1492,8 @@ Composite (RenderBuffer buffer, RenderTarget target,
glDisableVertexAttribArray (program->position);
glDisableVertexAttribArray (program->texcoord);
/* Single pixel buffers have no textures. */
if (egl_buffer->u.type != SinglePixelBuffer)
glBindTexture (tex_target, 0);
}
@ -1880,6 +1934,35 @@ BufferFromShm (SharedMemoryAttributes *attributes, Bool *error)
return (RenderBuffer) (void *) buffer;
}
static RenderBuffer
BufferFromSinglePixel (uint32_t red, uint32_t green, uint32_t blue,
uint32_t alpha, Bool *error)
{
EglBuffer *buffer;
buffer = XLMalloc (EglBufferSize (EglSinglePixelBuffer));
buffer->flags = 0;
buffer->texture = EGL_NO_TEXTURE;
buffer->width = 1;
buffer->height = 1;
buffer->u.type = SinglePixelBuffer;
/* Copy over the identity transform. */
MatrixIdentity (&buffer->matrix);
/* Record the buffer data. */
buffer->u.single_pixel.r = red / (float) 0xffffffff;
buffer->u.single_pixel.g = green / (float) 0xffffffff;
buffer->u.single_pixel.b = blue / (float) 0xffffffff;
buffer->u.single_pixel.a = alpha / (float) 0xffffffff;
/* An alpha channel is present. */
buffer->flags |= HasAlpha;
/* Return the buffer. */
return (RenderBuffer) (void *) buffer;
}
static void
FreeShmBuffer (RenderBuffer buffer)
{
@ -1911,6 +1994,20 @@ FreeDmabufBuffer (RenderBuffer buffer)
XLFree (buffer.pointer);
}
static void
FreeSinglePixelBuffer (RenderBuffer buffer)
{
EglBuffer *egl_buffer;
egl_buffer = buffer.pointer;
/* Make sure a texture was not created. */
XLAssert (egl_buffer->texture == EGL_NO_TEXTURE);
/* Free the wrapper struct. */
XLFree (buffer.pointer);
}
/* Initialization functions. */
static void
@ -2193,6 +2290,10 @@ UpdateTexture (EglBuffer *buffer)
/* The buffer's been copied to the texture. It can now be
released. */
buffer->flags |= CanRelease;
break;
default:
break;
}
/* Bind the target to nothing. */
@ -2326,6 +2427,10 @@ EnsureTexture (EglBuffer *buffer)
if (buffer->flags & IsTextureGenerated)
return;
/* If the buffer does not need textures, return. */
if (buffer->u.type == SinglePixelBuffer)
return;
/* Generate the name for the texture. */
glGenTextures (1, &buffer->texture);
@ -2344,6 +2449,10 @@ UpdateBuffer (RenderBuffer buffer, pixman_region32_t *damage,
egl_buffer = buffer.pointer;
/* Single pixel buffers don't need updates. */
if (egl_buffer->u.type == SinglePixelBuffer)
return;
if (!(egl_buffer->flags & IsTextureGenerated))
/* No texture has been generated, so just create one and maybe
upload the contents. */
@ -2374,6 +2483,9 @@ UpdateBuffer (RenderBuffer buffer, pixman_region32_t *damage,
/* See comment in !damage branch. */
UpdateTexture (egl_buffer);
break;
default:
break;
}
}
}
@ -2411,8 +2523,10 @@ static BufferFuncs egl_buffer_funcs =
.buffer_from_dma_buf_async = BufferFromDmaBufAsync,
.buffer_from_shm = BufferFromShm,
.validate_shm_params = ValidateShmParams,
.buffer_from_single_pixel = BufferFromSinglePixel,
.free_shm_buffer = FreeShmBuffer,
.free_dmabuf_buffer = FreeDmabufBuffer,
.free_single_pixel_buffer = FreeSinglePixelBuffer,
.update_buffer_for_damage = UpdateBufferForDamage,
.can_release_now = CanReleaseNow,
.init_buffer_funcs = InitBufferFuncs,

View file

@ -1189,6 +1189,45 @@ ValidateShmParams (uint32_t format, uint32_t width, uint32_t height,
return True;
}
static RenderBuffer
BufferFromSinglePixel (uint32_t red, uint32_t green, uint32_t blue,
uint32_t alpha, Bool *error)
{
Picture picture;
Pixmap pixmap;
XRenderPictureAttributes picture_attrs;
XRenderColor color;
PictureBuffer *buffer;
/* Create the pixmap. */
pixmap = XCreatePixmap (compositor.display,
DefaultRootWindow (compositor.display),
1, 1, compositor.n_planes);
/* Create the picture. */
picture = XRenderCreatePicture (compositor.display, pixmap,
compositor.argb_format, 0,
&picture_attrs);
/* Free the pixmap. */
XFreePixmap (compositor.display, pixmap);
/* Fill the picture with the single pixel. */
color.red = red >> 16;
color.green = green >> 16;
color.blue = blue >> 16;
color.alpha = alpha >> 16;
XRenderFillRectangle (compositor.display, PictOpSrc,
picture, &color, 0, 0, 1, 1);
/* Create the wrapper object. */
buffer = XLCalloc (1, sizeof *buffer);
buffer->picture = picture;
/* Return the picture. */
return (RenderBuffer) (void *) buffer;
}
static void
FreeShmBuffer (RenderBuffer buffer)
{
@ -1215,6 +1254,18 @@ FreeDmabufBuffer (RenderBuffer buffer)
XLFree (picture_buffer);
}
static void
FreeSinglePixelBuffer (RenderBuffer buffer)
{
PictureBuffer *picture_buffer;
picture_buffer = buffer.pointer;
XRenderFreePicture (compositor.display,
picture_buffer->picture);
XLFree (picture_buffer);
}
static void
SetupMitShm (void)
{
@ -1340,8 +1391,10 @@ static BufferFuncs picture_buffer_funcs =
.buffer_from_dma_buf_async = BufferFromDmaBufAsync,
.buffer_from_shm = BufferFromShm,
.validate_shm_params = ValidateShmParams,
.buffer_from_single_pixel = BufferFromSinglePixel,
.free_shm_buffer = FreeShmBuffer,
.free_dmabuf_buffer = FreeDmabufBuffer,
.free_single_pixel_buffer = FreeSinglePixelBuffer,
.can_release_now = CanReleaseNow,
.init_buffer_funcs = InitBufferFuncs,
};

View file

@ -227,6 +227,14 @@ RenderValidateShmParams (uint32_t format, uint32_t width, uint32_t height,
offset, stride, pool_size);
}
RenderBuffer
RenderBufferFromSinglePixel (uint32_t red, uint32_t green, uint32_t blue,
uint32_t alpha, Bool *error)
{
return buffer_funcs.buffer_from_single_pixel (red, green, blue,
alpha, error);
}
void
RenderFreeShmBuffer (RenderBuffer buffer)
{
@ -239,6 +247,12 @@ RenderFreeDmabufBuffer (RenderBuffer buffer)
return buffer_funcs.free_dmabuf_buffer (buffer);
}
void
RenderFreeSinglePixelBuffer (RenderBuffer buffer)
{
return buffer_funcs.free_dmabuf_buffer (buffer);
}
void
RenderUpdateBufferForDamage (RenderBuffer buffer, pixman_region32_t *damage,
DrawParams *params)
@ -299,6 +313,36 @@ InstallRenderer (Renderer *renderer)
return True;
}
static const char *
ReadRendererResource (void)
{
XrmDatabase rdb;
XrmName namelist[3];
XrmClass classlist[3];
XrmValue value;
XrmRepresentation type;
rdb = XrmGetDatabase (compositor.display);
if (!rdb)
return NULL;
namelist[1] = XrmStringToQuark ("renderer");
namelist[0] = app_quark;
namelist[2] = NULLQUARK;
classlist[1] = XrmStringToQuark ("Renderer");
classlist[0] = resource_quark;
classlist[2] = NULLQUARK;
if (XrmQGetResource (rdb, namelist, classlist,
&type, &value)
&& type == QString)
return (const char *) value.addr;
return NULL;
}
static void
PickRenderer (void)
{
@ -310,6 +354,9 @@ PickRenderer (void)
selected = getenv ("RENDERER");
if (!selected)
selected = ReadRendererResource ();
if (selected)
{
/* If selected is "help", print each renderer and exit. */

View file

@ -104,3 +104,30 @@ main (void)
gl_FragColor = texture2D (texture, texcoord);
}
//==
//== Composite Rectangle Fragment Shader Single Pixel
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform vec4 source_color;
uniform mat3 source;
uniform bool invert_y;
varying vec2 v_texcoord;
void
main (void)
{
vec2 texcoord;
texcoord = v_texcoord;
if (invert_y)
texcoord = vec2 (texcoord.x, 1.0 - texcoord.y);
if (texcoord.x < 0.0 || texcoord.y < 0.0
|| texcoord.x > 1.0 || texcoord.y > 1.0)
gl_FragColor = vec4 (0.0, 0.0, 0.0, 0.0);
else
gl_FragColor = source_color;
}
//==

View file

@ -177,6 +177,9 @@ struct _TextInput
/* The position of the preedit caret in characters. */
int caret;
/* The style of the caret. */
XIMCaretStyle caret_style;
/* The pending state. */
TextInputState pending_state;
@ -1437,14 +1440,20 @@ UpdatePreedit (TextInput *input)
goto no_buffer;
/* Obtain the caret position. */
if (input->caret_style != XIMIsInvisible)
caret = TextPositionFromCharPosition (buffer, new_text_size,
input->caret);
else
/* The caret is hidden, so don't send any caret position. */
caret.bytepos = -1, caret.charpos = -1;
DebugPrint ("caret position is: char %d, byte: %td",
caret.charpos, caret.bytepos);
PreeditString (input, buffer, new_text_size,
/* caret.bytepos will be -1 if obtaining the
position failed. */
position failed or the caret is hidden. */
caret.bytepos);
XLFree (buffer);
}
@ -1479,6 +1488,9 @@ PreeditStartCallback (XIC ic, XPointer client_data, XPointer call_data)
/* Create the preedit buffer. */
input->buffer = MakePreeditBuffer (locale);
/* Set the default caret style. */
input->caret_style = XIMIsPrimary;
/* There should be no limit on the number of bytes in a preedit
string. We make the string fit in 4000 bytes ourselves. */
return -1;
@ -1597,6 +1609,9 @@ PreeditCaretCallback (XIC ic, XPointer client_data,
/* Return the caret position. */
call_data->position = input->caret;
/* Set the caret style. */
input->caret_style = call_data->style;
/* Send change to the client. */
UpdatePreedit (input);
}
@ -3381,7 +3396,7 @@ XLInitTextInput (void)
InitInputStyles ();
if (im_fontset == NULL)
fprintf (stderr, "Unable to load any usable fontset for input methods");
fprintf (stderr, "Unable to load any usable fontset for input methods\n");
/* Register the IM callback. */
XRegisterIMInstantiateCallback (compositor.display,