forked from 12to11/12to11
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:
parent
a5c7565eb0
commit
f2e3baad45
10 changed files with 385 additions and 36 deletions
28
12to11.c
28
12to11.c
|
@ -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 ();
|
||||
|
|
76
12to11.man
76
12to11.man
|
@ -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
|
||||
|
|
|
@ -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
4
README
|
@ -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:
|
||||
|
||||
|
|
14
compositor.h
14
compositor.h
|
@ -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])
|
||||
|
|
142
egl.c
142
egl.c
|
@ -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,16 +1387,22 @@ 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. */
|
||||
XLAssert (egl_buffer->flags & IsTextureGenerated);
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Get the texturing target. */
|
||||
tex_target = GetTextureTarget (egl_buffer);
|
||||
|
||||
/* Compute the transformation matrix to use to draw the given
|
||||
buffer. */
|
||||
ComputeTransformMatrix (egl_buffer, params);
|
||||
|
@ -1415,15 +1452,30 @@ Composite (RenderBuffer buffer, RenderTarget target,
|
|||
else
|
||||
glDisable (GL_BLEND);
|
||||
|
||||
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);
|
||||
/* 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);
|
||||
|
||||
glUniform1i (program->texture, 0);
|
||||
/* 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,7 +1492,9 @@ Composite (RenderBuffer buffer, RenderTarget target,
|
|||
glDisableVertexAttribArray (program->position);
|
||||
glDisableVertexAttribArray (program->texcoord);
|
||||
|
||||
glBindTexture (tex_target, 0);
|
||||
/* Single pixel buffers have no textures. */
|
||||
if (egl_buffer->u.type != SinglePixelBuffer)
|
||||
glBindTexture (tex_target, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
47
renderer.c
47
renderer.c
|
@ -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. */
|
||||
|
|
27
shaders.txt
27
shaders.txt
|
@ -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;
|
||||
}
|
||||
//==
|
||||
|
|
23
text_input.c
23
text_input.c
|
@ -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. */
|
||||
caret = TextPositionFromCharPosition (buffer, new_text_size,
|
||||
input->caret);
|
||||
|
||||
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,
|
||||
|
|
Loading…
Add table
Reference in a new issue