forked from 12to11/12to11
Improve handling buffer scale factors
* compositor.h (struct _DrawParams): New structure. (struct _RenderFuncs): Remove `apply_transform' and `reset_transform'. Make `composite' accept DrawParams. (struct _BufferFuncs): Give scale to update_buffer_for_damage. (struct _Surface): New field `factor'. (struct _RoleFuncs): New callback `parent_rescale'. * dnd.c (HandleMotion): Fix some aspects of scale handling. * egl.c (struct _EglBuffer): Remove `scale' field. (ApplyTransform): Delete function. (Composite): Pass scale specified in params as uniform to program. (ResetTransform): Delete function. (egl_render_funcs): Delete apply_transform and reset_transform. (BufferFromDmaBuf, BufferFromShm): Stop setting scale attribute. (UpdateBufferForDamage): Accept new arg `scale' and use it. * picture_renderer.c (struct _PictureBuffer): New structure. Store picture and last seen draw parameters. (ApplyTransform): Delete function. (GetScale): New function. (MaybeApplyTransform): New function. (Composite): Recompute and set pictures if draw parameters change. (ResetTransform): Delete function. (picture_render_funcs): Remove unused hooks. (BufferFromDmaBuf, FinishDmaBufRecord, BufferFromShm) (FreeShmBuffer, FreeDmabufBuffer): Replace xid with wrapper structure. * positioner.c (TryFlipX, TryFlipY, GetAdjustmentOffset) (ApplyConstraintAdjustment): * renderer.c (RenderApplyTransform, RenderComposite) (RenderResetTransform, RenderFinishRender) (RenderUpdateBufferForDamage): * seat.c (UpdateCursorOutput, ComputeHotspot, HandleRawButton) (TransformToView, DispatchEntryExit, DispatchMotion, CancelGrab) (DispatchButton, ForceEntry): * subcompositor.c (GetTxTy, ViewApplyTransform, ViewHaveTransform) (ViewComputeTransform, SubcompositorUpdate, SubcompositorExpose): * subsurface.c (MaybeUpdateOutputs, AfterParentCommit, Rescale) (Teardown, GetSubsurface, XLUpdateOutputsForChildren): Use surface-specific scale factors. * surface.c (ApplyScale): Compute a new scale factor to convert between window and surface scale. (ApplyOpaqueRegion, ApplyInputRegion, HandleScaleChanged) (ApplySurfaceDamage, InternalCommit, XLCreateSurface): Use new factors instead. * xdg_popup.c (MoveWindow): * xdg_surface.c (GetResizeDimensions, XLXdgRoleCalcNewWindowSize): * xdg_toplevel.c (NoteConfigureTime, SendStates, RecordStateSize) (HandleWindowGeometryChange, NoteWindowPreResize): Use surface-specific scale factors.
This commit is contained in:
parent
0f07b2205b
commit
7f33ba9ae3
13 changed files with 443 additions and 235 deletions
47
compositor.h
47
compositor.h
|
@ -103,6 +103,8 @@ typedef union _RenderTarget RenderTarget;
|
||||||
typedef union _RenderBuffer RenderBuffer;
|
typedef union _RenderBuffer RenderBuffer;
|
||||||
typedef union _RenderFence RenderFence;
|
typedef union _RenderFence RenderFence;
|
||||||
|
|
||||||
|
typedef struct _DrawParams DrawParams;
|
||||||
|
|
||||||
typedef struct _DmaBufAttributes DmaBufAttributes;
|
typedef struct _DmaBufAttributes DmaBufAttributes;
|
||||||
typedef struct _SharedMemoryAttributes SharedMemoryAttributes;
|
typedef struct _SharedMemoryAttributes SharedMemoryAttributes;
|
||||||
|
|
||||||
|
@ -120,6 +122,21 @@ enum _Operation
|
||||||
OperationSource,
|
OperationSource,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/* Scale has been set. */
|
||||||
|
ScaleSet = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _DrawParams
|
||||||
|
{
|
||||||
|
/* Which fields are set. */
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
/* A scale factor to apply to the buffer. */
|
||||||
|
double scale;
|
||||||
|
};
|
||||||
|
|
||||||
struct _SharedMemoryAttributes
|
struct _SharedMemoryAttributes
|
||||||
{
|
{
|
||||||
/* The format of the buffer. */
|
/* The format of the buffer. */
|
||||||
|
@ -241,18 +258,12 @@ struct _RenderFuncs
|
||||||
/* Clear the given rectangle. */
|
/* Clear the given rectangle. */
|
||||||
void (*clear_rectangle) (RenderTarget, int, int, int, int);
|
void (*clear_rectangle) (RenderTarget, int, int, int, int);
|
||||||
|
|
||||||
/* Apply a projective transform to the given buffer. The first
|
|
||||||
argument is a scale factor. */
|
|
||||||
void (*apply_transform) (RenderBuffer, double);
|
|
||||||
|
|
||||||
/* Composite width, height, from the given buffer onto the given
|
/* Composite width, height, from the given buffer onto the given
|
||||||
target, at x, y. The arguments are: buffer, target, operation,
|
target, at x, y. The arguments are: buffer, target, operation,
|
||||||
source_x, source_y, x, y, width, height. */
|
source_x, source_y, x, y, width, height, params. params
|
||||||
|
describes how to transform the given buffer. */
|
||||||
void (*composite) (RenderBuffer, RenderTarget, Operation, int, int,
|
void (*composite) (RenderBuffer, RenderTarget, Operation, int, int,
|
||||||
int, int, int, int);
|
int, int, int, int, DrawParams *);
|
||||||
|
|
||||||
/* Reset the transform for the given buffer. */
|
|
||||||
void (*reset_transform) (RenderBuffer);
|
|
||||||
|
|
||||||
/* Finish rendering, and swap changes to display. May be NULL. */
|
/* Finish rendering, and swap changes to display. May be NULL. */
|
||||||
void (*finish_render) (RenderTarget);
|
void (*finish_render) (RenderTarget);
|
||||||
|
@ -349,8 +360,10 @@ struct _BufferFuncs
|
||||||
/* Notice that the given buffer has been damaged. May be NULL. If
|
/* Notice that the given buffer has been damaged. May be NULL. If
|
||||||
the given NULL damage, assume that the entire buffer has been
|
the given NULL damage, assume that the entire buffer has been
|
||||||
damaged. Must be called at least once before any rendering can
|
damaged. Must be called at least once before any rendering can
|
||||||
be performed on the buffer. */
|
be performed on the buffer. 3rd arg is the scale by which to
|
||||||
void (*update_buffer_for_damage) (RenderBuffer, pixman_region32_t *);
|
divide the buffer. */
|
||||||
|
void (*update_buffer_for_damage) (RenderBuffer, pixman_region32_t *,
|
||||||
|
float);
|
||||||
|
|
||||||
/* Return whether or not the buffer contents can be released early,
|
/* Return whether or not the buffer contents can be released early,
|
||||||
by being copied to an offscreen buffer. */
|
by being copied to an offscreen buffer. */
|
||||||
|
@ -376,10 +389,8 @@ extern void RenderStartRender (RenderTarget);
|
||||||
extern void RenderFillBoxesWithTransparency (RenderTarget, pixman_box32_t *,
|
extern void RenderFillBoxesWithTransparency (RenderTarget, pixman_box32_t *,
|
||||||
int, int, int);
|
int, int, int);
|
||||||
extern void RenderClearRectangle (RenderTarget, int, int, int, int);
|
extern void RenderClearRectangle (RenderTarget, int, int, int, int);
|
||||||
extern void RenderApplyTransform (RenderBuffer, double);
|
|
||||||
extern void RenderComposite (RenderBuffer, RenderTarget, Operation, int,
|
extern void RenderComposite (RenderBuffer, RenderTarget, Operation, int,
|
||||||
int, int, int, int, int);
|
int, int, int, int, int, DrawParams *);
|
||||||
extern void RenderResetTransform (RenderBuffer);
|
|
||||||
extern void RenderFinishRender (RenderTarget);
|
extern void RenderFinishRender (RenderTarget);
|
||||||
extern int RenderTargetAge (RenderTarget);
|
extern int RenderTargetAge (RenderTarget);
|
||||||
extern RenderFence RenderImportFdFence (int, Bool *);
|
extern RenderFence RenderImportFdFence (int, Bool *);
|
||||||
|
@ -398,7 +409,8 @@ extern Bool RenderValidateShmParams (uint32_t, uint32_t, uint32_t, int32_t,
|
||||||
int32_t, size_t);
|
int32_t, size_t);
|
||||||
extern void RenderFreeShmBuffer (RenderBuffer);
|
extern void RenderFreeShmBuffer (RenderBuffer);
|
||||||
extern void RenderFreeDmabufBuffer (RenderBuffer);
|
extern void RenderFreeDmabufBuffer (RenderBuffer);
|
||||||
extern void RenderUpdateBufferForDamage (RenderBuffer, pixman_region32_t *);
|
extern void RenderUpdateBufferForDamage (RenderBuffer, pixman_region32_t *,
|
||||||
|
float);
|
||||||
extern Bool RenderCanReleaseNow (RenderBuffer);
|
extern Bool RenderCanReleaseNow (RenderBuffer);
|
||||||
|
|
||||||
/* Defined in run.c. */
|
/* Defined in run.c. */
|
||||||
|
@ -832,6 +844,10 @@ struct _Surface
|
||||||
|
|
||||||
/* The associated sync acquire fd, or -1. */
|
/* The associated sync acquire fd, or -1. */
|
||||||
int acquire_fence;
|
int acquire_fence;
|
||||||
|
|
||||||
|
/* The scale factor used to convert from surface coordinates to
|
||||||
|
window coordinates. */
|
||||||
|
double factor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _RoleFuncs
|
struct _RoleFuncs
|
||||||
|
@ -851,6 +867,7 @@ struct _RoleFuncs
|
||||||
void (*post_resize) (Surface *, Role *, int, int, int, int);
|
void (*post_resize) (Surface *, Role *, int, int, int, int);
|
||||||
void (*move_by) (Surface *, Role *, int, int);
|
void (*move_by) (Surface *, Role *, int, int);
|
||||||
void (*rescale) (Surface *, Role *);
|
void (*rescale) (Surface *, Role *);
|
||||||
|
void (*parent_rescale) (Surface *, Role *);
|
||||||
void (*note_desync_child) (Surface *, Role *);
|
void (*note_desync_child) (Surface *, Role *);
|
||||||
void (*note_child_synced) (Surface *, Role *);
|
void (*note_child_synced) (Surface *, Role *);
|
||||||
};
|
};
|
||||||
|
|
19
dnd.c
19
dnd.c
|
@ -885,11 +885,24 @@ HandleMotion (Surface *toplevel, int x, int y, uint32_t action,
|
||||||
/* Find the view underneath the subcompositor. */
|
/* Find the view underneath the subcompositor. */
|
||||||
view = SubcompositorLookupView (subcompositor, x, y,
|
view = SubcompositorLookupView (subcompositor, x, y,
|
||||||
&x_off, &y_off);
|
&x_off, &y_off);
|
||||||
child = ViewGetData (view);
|
|
||||||
|
if (view)
|
||||||
|
child = ViewGetData (view);
|
||||||
|
else
|
||||||
|
/* No child was found. This should be impossible in theory, but
|
||||||
|
other clients don't respect the window shape when sending DND
|
||||||
|
events. */
|
||||||
|
child = NULL;
|
||||||
|
|
||||||
/* Compute the surface-relative coordinates and scale them. */
|
/* Compute the surface-relative coordinates and scale them. */
|
||||||
*x_out = (x - x_off) / global_scale_factor;
|
|
||||||
*y_out = (y - y_off) / global_scale_factor;
|
if (child)
|
||||||
|
{
|
||||||
|
/* x_out and y_out are only used if dnd_state.child ends up
|
||||||
|
non-NULL. */
|
||||||
|
*x_out = (x - x_off) / child->factor;
|
||||||
|
*y_out = (y - y_off) / child->factor;
|
||||||
|
}
|
||||||
|
|
||||||
if (dnd_state.child == child)
|
if (dnd_state.child == child)
|
||||||
/* If nothing changed, don't do anything. */
|
/* If nothing changed, don't do anything. */
|
||||||
|
|
45
egl.c
45
egl.c
|
@ -126,9 +126,6 @@ struct _EglBuffer
|
||||||
/* The width and height of the buffer. */
|
/* The width and height of the buffer. */
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
/* The projective scale factor. */
|
|
||||||
GLfloat scale;
|
|
||||||
|
|
||||||
/* Various different buffers. */
|
/* Various different buffers. */
|
||||||
union {
|
union {
|
||||||
/* The type of the buffer. */
|
/* The type of the buffer. */
|
||||||
|
@ -1128,15 +1125,6 @@ ClearRectangle (RenderTarget target, int x, int y, int width, int height)
|
||||||
FillBoxesWithTransparency (target, &box, 1, 0, 0);
|
FillBoxesWithTransparency (target, &box, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ApplyTransform (RenderBuffer buffer, double divisor)
|
|
||||||
{
|
|
||||||
EglBuffer *egl_buffer;
|
|
||||||
|
|
||||||
egl_buffer = buffer.pointer;
|
|
||||||
egl_buffer->scale = 1.0f / (GLfloat) divisor;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CompositeProgram *
|
static CompositeProgram *
|
||||||
FindProgram (EglBuffer *buffer)
|
FindProgram (EglBuffer *buffer)
|
||||||
{
|
{
|
||||||
|
@ -1177,7 +1165,7 @@ GetTextureTarget (EglBuffer *buffer)
|
||||||
static void
|
static void
|
||||||
Composite (RenderBuffer buffer, RenderTarget target,
|
Composite (RenderBuffer buffer, RenderTarget target,
|
||||||
Operation op, int src_x, int src_y, int x, int y,
|
Operation op, int src_x, int src_y, int x, int y,
|
||||||
int width, int height)
|
int width, int height, DrawParams *params)
|
||||||
{
|
{
|
||||||
GLfloat verts[8], texcoord[8];
|
GLfloat verts[8], texcoord[8];
|
||||||
GLfloat x1, x2, y1, y2;
|
GLfloat x1, x2, y1, y2;
|
||||||
|
@ -1185,6 +1173,7 @@ Composite (RenderBuffer buffer, RenderTarget target,
|
||||||
EglBuffer *egl_buffer;
|
EglBuffer *egl_buffer;
|
||||||
CompositeProgram *program;
|
CompositeProgram *program;
|
||||||
GLenum tex_target;
|
GLenum tex_target;
|
||||||
|
GLfloat scale;
|
||||||
|
|
||||||
egl_target = target.pointer;
|
egl_target = target.pointer;
|
||||||
egl_buffer = buffer.pointer;
|
egl_buffer = buffer.pointer;
|
||||||
|
@ -1244,13 +1233,18 @@ Composite (RenderBuffer buffer, RenderTarget target,
|
||||||
else
|
else
|
||||||
glDisable (GL_BLEND);
|
glDisable (GL_BLEND);
|
||||||
|
|
||||||
|
if (params->flags & ScaleSet)
|
||||||
|
scale = params->scale;
|
||||||
|
else
|
||||||
|
scale = 1.0f;
|
||||||
|
|
||||||
glActiveTexture (GL_TEXTURE0);
|
glActiveTexture (GL_TEXTURE0);
|
||||||
glBindTexture (tex_target, egl_buffer->texture);
|
glBindTexture (tex_target, egl_buffer->texture);
|
||||||
glTexParameteri (tex_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri (tex_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glUseProgram (program->program);
|
glUseProgram (program->program);
|
||||||
|
|
||||||
glUniform1i (program->texture, 0);
|
glUniform1i (program->texture, 0);
|
||||||
glUniform1f (program->scale, egl_buffer->scale);
|
glUniform1f (program->scale, scale);
|
||||||
glUniform1i (program->invert_y, egl_buffer->flags & InvertY);
|
glUniform1i (program->invert_y, egl_buffer->flags & InvertY);
|
||||||
glVertexAttribPointer (program->position, 2, GL_FLOAT,
|
glVertexAttribPointer (program->position, 2, GL_FLOAT,
|
||||||
GL_FALSE, 0, verts);
|
GL_FALSE, 0, verts);
|
||||||
|
@ -1268,12 +1262,6 @@ Composite (RenderBuffer buffer, RenderTarget target,
|
||||||
glBindTexture (tex_target, 0);
|
glBindTexture (tex_target, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ResetTransform (RenderBuffer buffer)
|
|
||||||
{
|
|
||||||
/* TODO... */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FinishRender (RenderTarget target)
|
FinishRender (RenderTarget target)
|
||||||
{
|
{
|
||||||
|
@ -1421,9 +1409,7 @@ static RenderFuncs egl_render_funcs =
|
||||||
.start_render = StartRender,
|
.start_render = StartRender,
|
||||||
.fill_boxes_with_transparency = FillBoxesWithTransparency,
|
.fill_boxes_with_transparency = FillBoxesWithTransparency,
|
||||||
.clear_rectangle = ClearRectangle,
|
.clear_rectangle = ClearRectangle,
|
||||||
.apply_transform = ApplyTransform,
|
|
||||||
.composite = Composite,
|
.composite = Composite,
|
||||||
.reset_transform = ResetTransform,
|
|
||||||
.finish_render = FinishRender,
|
.finish_render = FinishRender,
|
||||||
.target_age = TargetAge,
|
.target_age = TargetAge,
|
||||||
.import_fd_fence = ImportFdFence,
|
.import_fd_fence = ImportFdFence,
|
||||||
|
@ -1514,7 +1500,6 @@ BufferFromDmaBuf (DmaBufAttributes *attributes, Bool *error)
|
||||||
buffer->texture = EGL_NO_TEXTURE;
|
buffer->texture = EGL_NO_TEXTURE;
|
||||||
buffer->width = attributes->width;
|
buffer->width = attributes->width;
|
||||||
buffer->height = attributes->height;
|
buffer->height = attributes->height;
|
||||||
buffer->scale = 1.0f;
|
|
||||||
buffer->u.type = DmaBufBuffer;
|
buffer->u.type = DmaBufBuffer;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
|
@ -1664,7 +1649,6 @@ BufferFromShm (SharedMemoryAttributes *attributes, Bool *error)
|
||||||
buffer->texture = EGL_NO_TEXTURE;
|
buffer->texture = EGL_NO_TEXTURE;
|
||||||
buffer->width = attributes->width;
|
buffer->width = attributes->width;
|
||||||
buffer->height = attributes->height;
|
buffer->height = attributes->height;
|
||||||
buffer->scale = 1.0f;
|
|
||||||
buffer->u.type = ShmBuffer;
|
buffer->u.type = ShmBuffer;
|
||||||
|
|
||||||
/* Record the buffer data. */
|
/* Record the buffer data. */
|
||||||
|
@ -2134,22 +2118,19 @@ UpdateBuffer (RenderBuffer buffer, pixman_region32_t *damage)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
UpdateBufferForDamage (RenderBuffer buffer, pixman_region32_t *damage)
|
UpdateBufferForDamage (RenderBuffer buffer, pixman_region32_t *damage,
|
||||||
|
float scale)
|
||||||
{
|
{
|
||||||
EglBuffer *egl_buffer;
|
|
||||||
pixman_region32_t region;
|
pixman_region32_t region;
|
||||||
|
|
||||||
egl_buffer = buffer.pointer;
|
if (scale != 1.0f && damage)
|
||||||
|
|
||||||
if (egl_buffer->scale != 1.0f && damage)
|
|
||||||
{
|
{
|
||||||
/* Scale the damage, specified in scaled coordinates, down to
|
/* Scale the damage, specified in scaled coordinates, down to
|
||||||
texture coordinates. */
|
texture coordinates. */
|
||||||
|
|
||||||
pixman_region32_init (®ion);
|
pixman_region32_init (®ion);
|
||||||
XLScaleRegion (®ion, damage,
|
XLScaleRegion (®ion, damage, 1.0f / scale,
|
||||||
1.0f / egl_buffer->scale,
|
1.0f / scale);
|
||||||
1.0f / egl_buffer->scale);
|
|
||||||
UpdateBuffer (buffer, ®ion);
|
UpdateBuffer (buffer, ®ion);
|
||||||
pixman_region32_fini (®ion);
|
pixman_region32_fini (®ion);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,17 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
typedef struct _DrmFormatInfo DrmFormatInfo;
|
typedef struct _DrmFormatInfo DrmFormatInfo;
|
||||||
typedef struct _DmaBufRecord DmaBufRecord;
|
typedef struct _DmaBufRecord DmaBufRecord;
|
||||||
|
|
||||||
|
typedef struct _PictureBuffer PictureBuffer;
|
||||||
|
|
||||||
|
struct _PictureBuffer
|
||||||
|
{
|
||||||
|
/* The XID of the picture. */
|
||||||
|
Picture picture;
|
||||||
|
|
||||||
|
/* The last draw params associated with the picture. */
|
||||||
|
DrawParams params;
|
||||||
|
};
|
||||||
|
|
||||||
struct _DrmFormatInfo
|
struct _DrmFormatInfo
|
||||||
{
|
{
|
||||||
/* The DRM format code. */
|
/* The DRM format code. */
|
||||||
|
@ -290,21 +301,6 @@ ClearRectangle (RenderTarget target, int x, int y, int width, int height)
|
||||||
target.xid, &color, x, y, width, height);
|
target.xid, &color, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ApplyTransform (RenderBuffer buffer, double divisor)
|
|
||||||
{
|
|
||||||
XTransform transform;
|
|
||||||
|
|
||||||
memset (&transform, 0, sizeof transform);
|
|
||||||
|
|
||||||
transform.matrix[0][0] = XDoubleToFixed (divisor);
|
|
||||||
transform.matrix[1][1] = XDoubleToFixed (divisor);
|
|
||||||
transform.matrix[2][2] = XDoubleToFixed (1);
|
|
||||||
|
|
||||||
XRenderSetPictureTransform (compositor.display, buffer.xid,
|
|
||||||
&transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ConvertOperation (Operation op)
|
ConvertOperation (Operation op)
|
||||||
{
|
{
|
||||||
|
@ -320,26 +316,70 @@ ConvertOperation (Operation op)
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double
|
||||||
|
GetScale (DrawParams *params)
|
||||||
|
{
|
||||||
|
if (params->flags & ScaleSet)
|
||||||
|
return params->scale;
|
||||||
|
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
MaybeApplyTransform (PictureBuffer *buffer, DrawParams *params)
|
||||||
|
{
|
||||||
|
XTransform transform;
|
||||||
|
|
||||||
|
if (GetScale (params) == GetScale (&buffer->params))
|
||||||
|
/* Nothing changed. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Otherwise, compute and apply the new transform. */
|
||||||
|
if (!params->flags)
|
||||||
|
/* No transform of any kind is set, use the identity matrix. */
|
||||||
|
XRenderSetPictureTransform (compositor.display,
|
||||||
|
buffer->picture,
|
||||||
|
&identity_transform);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset (&transform, 0, sizeof transform);
|
||||||
|
|
||||||
|
transform.matrix[0][0] = XDoubleToFixed (1.0 / params->scale);
|
||||||
|
transform.matrix[1][1] = XDoubleToFixed (1.0 / params->scale);
|
||||||
|
transform.matrix[2][2] = XDoubleToFixed (1);
|
||||||
|
|
||||||
|
XRenderSetPictureTransform (compositor.display,
|
||||||
|
buffer->picture,
|
||||||
|
&transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the parameters into buffer. */
|
||||||
|
buffer->params = *params;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Composite (RenderBuffer buffer, RenderTarget target,
|
Composite (RenderBuffer buffer, RenderTarget target,
|
||||||
Operation op, int src_x, int src_y, int x, int y,
|
Operation op, int src_x, int src_y, int x, int y,
|
||||||
int width, int height)
|
int width, int height, DrawParams *draw_params)
|
||||||
{
|
{
|
||||||
|
PictureBuffer *picture_buffer;
|
||||||
|
|
||||||
|
picture_buffer = buffer.pointer;
|
||||||
|
|
||||||
|
/* Maybe set the transform if the parameters changed. (draw_params
|
||||||
|
specifies a transform to apply to the buffer, not to the
|
||||||
|
target.) */
|
||||||
|
MaybeApplyTransform (picture_buffer, draw_params);
|
||||||
|
|
||||||
|
/* Do the compositing. */
|
||||||
XRenderComposite (compositor.display, ConvertOperation (op),
|
XRenderComposite (compositor.display, ConvertOperation (op),
|
||||||
buffer.xid, None, target.xid,
|
picture_buffer->picture, None, target.xid,
|
||||||
/* src-x, src-y, mask-x, mask-y. */
|
/* src-x, src-y, mask-x, mask-y. */
|
||||||
src_x, src_y, 0, 0,
|
src_x, src_y, 0, 0,
|
||||||
/* dst-x, dst-y, width, height. */
|
/* dst-x, dst-y, width, height. */
|
||||||
x, y, width, height);
|
x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ResetTransform (RenderBuffer buffer)
|
|
||||||
{
|
|
||||||
XRenderSetPictureTransform (compositor.display, buffer.xid,
|
|
||||||
&identity_transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
TargetAge (RenderTarget target)
|
TargetAge (RenderTarget target)
|
||||||
{
|
{
|
||||||
|
@ -388,9 +428,7 @@ static RenderFuncs picture_render_funcs =
|
||||||
.destroy_render_target = DestroyRenderTarget,
|
.destroy_render_target = DestroyRenderTarget,
|
||||||
.fill_boxes_with_transparency = FillBoxesWithTransparency,
|
.fill_boxes_with_transparency = FillBoxesWithTransparency,
|
||||||
.clear_rectangle = ClearRectangle,
|
.clear_rectangle = ClearRectangle,
|
||||||
.apply_transform = ApplyTransform,
|
|
||||||
.composite = Composite,
|
.composite = Composite,
|
||||||
.reset_transform = ResetTransform,
|
|
||||||
.target_age = TargetAge,
|
.target_age = TargetAge,
|
||||||
.import_fd_fence = ImportFdFence,
|
.import_fd_fence = ImportFdFence,
|
||||||
.wait_fence = WaitFence,
|
.wait_fence = WaitFence,
|
||||||
|
@ -746,6 +784,7 @@ BufferFromDmaBuf (DmaBufAttributes *attributes, Bool *error)
|
||||||
xcb_generic_error_t *xerror;
|
xcb_generic_error_t *xerror;
|
||||||
XRenderPictFormat *format;
|
XRenderPictFormat *format;
|
||||||
XRenderPictureAttributes picture_attrs;
|
XRenderPictureAttributes picture_attrs;
|
||||||
|
PictureBuffer *buffer;
|
||||||
|
|
||||||
/* Find the depth and bpp corresponding to the format. */
|
/* Find the depth and bpp corresponding to the format. */
|
||||||
depth = DepthForDmabufFormat (attributes->drm_format, &bpp);
|
depth = DepthForDmabufFormat (attributes->drm_format, &bpp);
|
||||||
|
@ -791,12 +830,16 @@ BufferFromDmaBuf (DmaBufAttributes *attributes, Bool *error)
|
||||||
format, 0, &picture_attrs);
|
format, 0, &picture_attrs);
|
||||||
XFreePixmap (compositor.display, pixmap);
|
XFreePixmap (compositor.display, pixmap);
|
||||||
|
|
||||||
return (RenderBuffer) picture;
|
/* Create the wrapper object. */
|
||||||
|
buffer = XLCalloc (1, sizeof *buffer);
|
||||||
|
buffer->picture = picture;
|
||||||
|
|
||||||
|
return (RenderBuffer) (void *) buffer;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
CloseFileDescriptors (attributes);
|
CloseFileDescriptors (attributes);
|
||||||
*error = True;
|
*error = True;
|
||||||
return (RenderBuffer) (XID) None;
|
return (RenderBuffer) NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -832,6 +875,7 @@ FinishDmaBufRecord (DmaBufRecord *pending, Bool success)
|
||||||
{
|
{
|
||||||
Picture picture;
|
Picture picture;
|
||||||
XRenderPictureAttributes picture_attrs;
|
XRenderPictureAttributes picture_attrs;
|
||||||
|
PictureBuffer *buffer;
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
|
@ -844,8 +888,12 @@ FinishDmaBufRecord (DmaBufRecord *pending, Bool success)
|
||||||
&picture_attrs);
|
&picture_attrs);
|
||||||
XFreePixmap (compositor.display, pending->pixmap);
|
XFreePixmap (compositor.display, pending->pixmap);
|
||||||
|
|
||||||
|
/* Create the wrapper structure. */
|
||||||
|
buffer = XLCalloc (1, sizeof *buffer);
|
||||||
|
buffer->picture = picture;
|
||||||
|
|
||||||
/* Call the creation success function with the new picture. */
|
/* Call the creation success function with the new picture. */
|
||||||
pending->success_func ((RenderBuffer) picture,
|
pending->success_func ((RenderBuffer) (void *) buffer,
|
||||||
pending->data);
|
pending->data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -989,6 +1037,7 @@ BufferFromShm (SharedMemoryAttributes *attributes, Bool *error)
|
||||||
Pixmap pixmap;
|
Pixmap pixmap;
|
||||||
Picture picture;
|
Picture picture;
|
||||||
int fd, depth, format, bpp;
|
int fd, depth, format, bpp;
|
||||||
|
PictureBuffer *buffer;
|
||||||
|
|
||||||
depth = DepthForFormat (attributes->format, &bpp);
|
depth = DepthForFormat (attributes->format, &bpp);
|
||||||
format = attributes->format;
|
format = attributes->format;
|
||||||
|
@ -1000,7 +1049,7 @@ BufferFromShm (SharedMemoryAttributes *attributes, Bool *error)
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
*error = True;
|
*error = True;
|
||||||
return (RenderBuffer) (XID) None;
|
return (RenderBuffer) NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, allocate the XIDs for the shm segment and pixmap. */
|
/* Now, allocate the XIDs for the shm segment and pixmap. */
|
||||||
|
@ -1021,8 +1070,12 @@ BufferFromShm (SharedMemoryAttributes *attributes, Bool *error)
|
||||||
0, &picture_attrs);
|
0, &picture_attrs);
|
||||||
XFreePixmap (compositor.display, pixmap);
|
XFreePixmap (compositor.display, pixmap);
|
||||||
|
|
||||||
|
/* Create the wrapper object. */
|
||||||
|
buffer = XLCalloc (1, sizeof *buffer);
|
||||||
|
buffer->picture = picture;
|
||||||
|
|
||||||
/* Return the picture. */
|
/* Return the picture. */
|
||||||
return (RenderBuffer) picture;
|
return (RenderBuffer) (void *) buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1086,15 +1139,27 @@ ValidateShmParams (uint32_t format, uint32_t width, uint32_t height,
|
||||||
static void
|
static void
|
||||||
FreeShmBuffer (RenderBuffer buffer)
|
FreeShmBuffer (RenderBuffer buffer)
|
||||||
{
|
{
|
||||||
XRenderFreePicture (compositor.display, buffer.xid);
|
PictureBuffer *picture_buffer;
|
||||||
|
|
||||||
|
picture_buffer = buffer.pointer;
|
||||||
|
|
||||||
|
XRenderFreePicture (compositor.display,
|
||||||
|
picture_buffer->picture);
|
||||||
|
XLFree (picture_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FreeDmabufBuffer (RenderBuffer buffer)
|
FreeDmabufBuffer (RenderBuffer buffer)
|
||||||
{
|
{
|
||||||
|
PictureBuffer *picture_buffer;
|
||||||
|
|
||||||
|
picture_buffer = buffer.pointer;
|
||||||
|
|
||||||
/* N.B. that the picture is the only reference to the pixmap
|
/* N.B. that the picture is the only reference to the pixmap
|
||||||
here. */
|
here. */
|
||||||
XRenderFreePicture (compositor.display, buffer.xid);
|
XRenderFreePicture (compositor.display,
|
||||||
|
picture_buffer->picture);
|
||||||
|
XLFree (picture_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
31
positioner.c
31
positioner.c
|
@ -60,6 +60,9 @@ struct _Positioner
|
||||||
int refcount;
|
int refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Scale factor used during constraint adjustment calculation. */
|
||||||
|
static double scale_adjustment_factor;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Destroy (struct wl_client *client, struct wl_resource *resource)
|
Destroy (struct wl_client *client, struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
|
@ -502,7 +505,7 @@ TryFlipX (Positioner *positioner, int x, int width, int cx, int cwidth,
|
||||||
CalculatePosition (&new, &new_x, NULL);
|
CalculatePosition (&new, &new_x, NULL);
|
||||||
|
|
||||||
/* Scale that position. */
|
/* Scale that position. */
|
||||||
new_x *= global_scale_factor;
|
new_x *= scale_adjustment_factor;
|
||||||
|
|
||||||
/* If new_x is still constrained, use the previous position. */
|
/* If new_x is still constrained, use the previous position. */
|
||||||
if (new_x + offset < cx
|
if (new_x + offset < cx
|
||||||
|
@ -598,7 +601,7 @@ TryFlipY (Positioner *positioner, int y, int height, int cy, int cheight,
|
||||||
CalculatePosition (&new, NULL, &new_y);
|
CalculatePosition (&new, NULL, &new_y);
|
||||||
|
|
||||||
/* Scale that position. */
|
/* Scale that position. */
|
||||||
new_y *= global_scale_factor;
|
new_y *= scale_adjustment_factor;
|
||||||
|
|
||||||
/* If new_y is still constrained, use the previous position. */
|
/* If new_y is still constrained, use the previous position. */
|
||||||
if (new_y + offset < cy
|
if (new_y + offset < cy
|
||||||
|
@ -670,8 +673,8 @@ GetAdjustmentOffset (Role *parent, int *off_x, int *off_y)
|
||||||
&parent_gy, NULL, NULL);
|
&parent_gy, NULL, NULL);
|
||||||
XLXdgRoleCurrentRootPosition (parent, &root_x, &root_y);
|
XLXdgRoleCurrentRootPosition (parent, &root_x, &root_y);
|
||||||
|
|
||||||
*off_x = root_x + parent_gx * global_scale_factor;
|
*off_x = root_x + parent_gx * parent->surface->factor;
|
||||||
*off_y = root_y + parent_gy * global_scale_factor;
|
*off_y = root_y + parent_gy * parent->surface->factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -681,13 +684,17 @@ ApplyConstraintAdjustment (Positioner *positioner, Role *parent, int x,
|
||||||
{
|
{
|
||||||
int width, height, cx, cy, cwidth, cheight, off_x, off_y;
|
int width, height, cx, cy, cwidth, cheight, off_x, off_y;
|
||||||
|
|
||||||
width = positioner->width * global_scale_factor;
|
width = positioner->width * scale_adjustment_factor;
|
||||||
height = positioner->height * global_scale_factor;
|
height = positioner->height * scale_adjustment_factor;
|
||||||
|
|
||||||
|
/* Set the factor describing how to convert surface coordinates to
|
||||||
|
window ones. */
|
||||||
|
scale_adjustment_factor = parent->surface->factor;
|
||||||
|
|
||||||
/* Constraint calculations are simplest if we use scaled
|
/* Constraint calculations are simplest if we use scaled
|
||||||
coordinates, and then unscale them later. */
|
coordinates, and then unscale them later. */
|
||||||
x *= global_scale_factor;
|
x *= scale_adjustment_factor;
|
||||||
y *= global_scale_factor;
|
y *= scale_adjustment_factor;
|
||||||
|
|
||||||
if (positioner->constraint_adjustment
|
if (positioner->constraint_adjustment
|
||||||
== XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE)
|
== XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE)
|
||||||
|
@ -733,10 +740,10 @@ ApplyConstraintAdjustment (Positioner *positioner, Role *parent, int x,
|
||||||
off_y, &y, &height);
|
off_y, &y, &height);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
*x_out = x / global_scale_factor;
|
*x_out = x / scale_adjustment_factor;
|
||||||
*y_out = y / global_scale_factor;
|
*y_out = y / scale_adjustment_factor;
|
||||||
*width_out = width / global_scale_factor;
|
*width_out = width / scale_adjustment_factor;
|
||||||
*height_out = height / global_scale_factor;
|
*height_out = height / scale_adjustment_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
22
renderer.c
22
renderer.c
|
@ -129,24 +129,13 @@ RenderClearRectangle (RenderTarget target, int x, int y, int width, int height)
|
||||||
render_funcs.clear_rectangle (target, x, y, width, height);
|
render_funcs.clear_rectangle (target, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
RenderApplyTransform (RenderBuffer buffer, double divisor)
|
|
||||||
{
|
|
||||||
render_funcs.apply_transform (buffer, divisor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RenderComposite (RenderBuffer source, RenderTarget target, Operation op,
|
RenderComposite (RenderBuffer source, RenderTarget target, Operation op,
|
||||||
int src_x, int src_y, int x, int y, int width, int height)
|
int src_x, int src_y, int x, int y, int width, int height,
|
||||||
|
DrawParams *draw_params)
|
||||||
{
|
{
|
||||||
render_funcs.composite (source, target, op, src_x, src_y, x, y,
|
render_funcs.composite (source, target, op, src_x, src_y, x, y,
|
||||||
width, height);
|
width, height, draw_params);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RenderResetTransform (RenderBuffer buffer)
|
|
||||||
{
|
|
||||||
render_funcs.reset_transform (buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -251,12 +240,13 @@ RenderFreeDmabufBuffer (RenderBuffer buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RenderUpdateBufferForDamage (RenderBuffer buffer, pixman_region32_t *damage)
|
RenderUpdateBufferForDamage (RenderBuffer buffer, pixman_region32_t *damage,
|
||||||
|
float scale)
|
||||||
{
|
{
|
||||||
if (!buffer_funcs.update_buffer_for_damage)
|
if (!buffer_funcs.update_buffer_for_damage)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
buffer_funcs.update_buffer_for_damage (buffer, damage);
|
buffer_funcs.update_buffer_for_damage (buffer, damage, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
|
|
62
seat.c
62
seat.c
|
@ -779,9 +779,10 @@ UpdateCursorOutput (SeatCursor *cursor, int root_x, int root_y)
|
||||||
{
|
{
|
||||||
int hotspot_x, hotspot_y;
|
int hotspot_x, hotspot_y;
|
||||||
|
|
||||||
/* Scale the hotspot coordinates up by the scale. */
|
/* Scale the hotspot coordinates up by the scale factor specified in
|
||||||
hotspot_x = cursor->hotspot_x * global_scale_factor;
|
the surface. */
|
||||||
hotspot_y = cursor->hotspot_y * global_scale_factor;
|
hotspot_x = cursor->hotspot_x * cursor->role.surface->factor;
|
||||||
|
hotspot_y = cursor->hotspot_y * cursor->role.surface->factor;
|
||||||
|
|
||||||
/* We use a rectangle 1 pixel wide and tall, originating from the
|
/* We use a rectangle 1 pixel wide and tall, originating from the
|
||||||
hotspot of the pointer. */
|
hotspot of the pointer. */
|
||||||
|
@ -991,20 +992,18 @@ ComputeHotspot (SeatCursor *cursor, int min_x, int min_y,
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
int hotspot_x, hotspot_y;
|
int hotspot_x, hotspot_y;
|
||||||
|
|
||||||
|
if (!cursor->role.surface)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Scale the hotspot coordinates up by the scale. */
|
/* Scale the hotspot coordinates up by the scale. */
|
||||||
hotspot_x = cursor->hotspot_x * global_scale_factor;
|
hotspot_x = cursor->hotspot_x * cursor->role.surface->factor;
|
||||||
hotspot_y = cursor->hotspot_y * global_scale_factor;
|
hotspot_y = cursor->hotspot_y * cursor->role.surface->factor;
|
||||||
|
|
||||||
/* Apply the surface offsets to the hotspot as well. */
|
/* Apply the surface offsets to the hotspot as well. */
|
||||||
dx = dy = 0;
|
dx = (cursor->role.surface->current_state.x
|
||||||
|
* cursor->role.surface->factor);
|
||||||
if (cursor->role.surface)
|
dy = (cursor->role.surface->current_state.y
|
||||||
{
|
* cursor->role.surface->factor);
|
||||||
dx = (cursor->role.surface->current_state.x
|
|
||||||
* global_scale_factor);
|
|
||||||
dy = (cursor->role.surface->current_state.y
|
|
||||||
* global_scale_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
*x = min_x + hotspot_x - dx;
|
*x = min_x + hotspot_x - dx;
|
||||||
*y = min_y + hotspot_y - dy;
|
*y = min_y + hotspot_y - dy;
|
||||||
|
@ -2369,7 +2368,7 @@ HandleResizeComplete (Seat *seat)
|
||||||
/* Forward declarations. */
|
/* Forward declarations. */
|
||||||
|
|
||||||
static int GetXButton (int);
|
static int GetXButton (int);
|
||||||
static void TransformToView (View *, double, double, double *, double *);
|
static void TransformToSurface (Surface *, double, double, double *, double *);
|
||||||
static void SendButton (Seat *, Surface *, Time, uint32_t, uint32_t,
|
static void SendButton (Seat *, Surface *, Time, uint32_t, uint32_t,
|
||||||
double, double);
|
double, double);
|
||||||
|
|
||||||
|
@ -2421,8 +2420,8 @@ HandleRawButton (XIRawEvent *event)
|
||||||
{
|
{
|
||||||
/* Otherwise, the pointer is on a different screen! */
|
/* Otherwise, the pointer is on a different screen! */
|
||||||
|
|
||||||
TransformToView (seat->last_seen_surface->view,
|
TransformToSurface (seat->last_seen_surface,
|
||||||
win_x, win_y, &dispatch_x, &dispatch_y);
|
win_x, win_y, &dispatch_x, &dispatch_y);
|
||||||
SendButton (seat, seat->last_seen_surface, event->time,
|
SendButton (seat, seat->last_seen_surface, event->time,
|
||||||
button, WL_POINTER_BUTTON_STATE_RELEASED,
|
button, WL_POINTER_BUTTON_STATE_RELEASED,
|
||||||
dispatch_x, dispatch_y);
|
dispatch_x, dispatch_y);
|
||||||
|
@ -3258,11 +3257,15 @@ EnteredSurface (Seat *seat, Surface *surface, Time time,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
TransformToView (View *view, double event_x, double event_y,
|
TransformToSurface (Surface *surface, double event_x, double event_y,
|
||||||
double *view_x_out, double *view_y_out)
|
double *view_x_out, double *view_y_out)
|
||||||
{
|
{
|
||||||
int int_x, int_y, x, y;
|
int int_x, int_y, x, y;
|
||||||
double view_x, view_y;
|
double view_x, view_y;
|
||||||
|
View *view;
|
||||||
|
|
||||||
|
/* Use the surface's view. */
|
||||||
|
view = surface->view;
|
||||||
|
|
||||||
/* Even though event_x and event_y are doubles, they cannot exceed
|
/* Even though event_x and event_y are doubles, they cannot exceed
|
||||||
65535.0, so this cannot overflow. */
|
65535.0, so this cannot overflow. */
|
||||||
|
@ -3277,8 +3280,8 @@ TransformToView (View *view, double event_x, double event_y,
|
||||||
|
|
||||||
/* Finally, transform the coordinates by the global output
|
/* Finally, transform the coordinates by the global output
|
||||||
scale. */
|
scale. */
|
||||||
*view_x_out = view_x / global_scale_factor;
|
*view_x_out = view_x / surface->factor;
|
||||||
*view_y_out = view_y / global_scale_factor;
|
*view_y_out = view_y / surface->factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
|
@ -3411,9 +3414,7 @@ DispatchEntryExit (Subcompositor *subcompositor, XIEnterEvent *event)
|
||||||
|
|
||||||
after_dispatch_set:
|
after_dispatch_set:
|
||||||
|
|
||||||
TransformToView (dispatch->view, event_x,
|
TransformToSurface (dispatch, event_x, event_y, &x, &y);
|
||||||
event_y, &x, &y);
|
|
||||||
|
|
||||||
EnteredSurface (seat, dispatch, event->time, x, y, False);
|
EnteredSurface (seat, dispatch, event->time, x, y, False);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3688,8 +3689,7 @@ DispatchMotion (Subcompositor *subcompositor, XIDeviceEvent *xev)
|
||||||
/* Inside a surface; cancel external drag and drop. */
|
/* Inside a surface; cancel external drag and drop. */
|
||||||
XLDoDragLeave (seat);
|
XLDoDragLeave (seat);
|
||||||
|
|
||||||
TransformToView (dispatch->view, event_x, event_y,
|
TransformToSurface (dispatch, event_x, event_y, &x, &y);
|
||||||
&x, &y);
|
|
||||||
EnteredSurface (seat, dispatch, xev->time, x, y, False);
|
EnteredSurface (seat, dispatch, xev->time, x, y, False);
|
||||||
|
|
||||||
if (!HandleValuatorMotion (seat, dispatch, x, y, xev))
|
if (!HandleValuatorMotion (seat, dispatch, x, y, xev))
|
||||||
|
@ -3753,8 +3753,8 @@ CancelGrab (Seat *seat, Time time, Window source,
|
||||||
|
|
||||||
/* Finally, translate the coordinates to the target
|
/* Finally, translate the coordinates to the target
|
||||||
view. */
|
view. */
|
||||||
TransformToView (seat->pointer_unlock_surface->view,
|
TransformToSurface (seat->pointer_unlock_surface,
|
||||||
x, y, &x, &y);
|
x, y, &x, &y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3925,8 +3925,8 @@ DispatchButton (Subcompositor *subcompositor, XIDeviceEvent *xev)
|
||||||
|
|
||||||
after_dispatch_set:
|
after_dispatch_set:
|
||||||
|
|
||||||
TransformToView (dispatch->view, xev->event_x,
|
TransformToSurface (dispatch, xev->event_x, xev->event_y,
|
||||||
xev->event_y, &x, &y);
|
&x, &y);
|
||||||
EnteredSurface (seat, dispatch, xev->time, x, y,
|
EnteredSurface (seat, dispatch, xev->time, x, y,
|
||||||
False);
|
False);
|
||||||
|
|
||||||
|
@ -4891,7 +4891,7 @@ ForceEntry (Seat *seat, Window source, double x, double y)
|
||||||
|
|
||||||
/* Finally, translate the coordinates to the target
|
/* Finally, translate the coordinates to the target
|
||||||
view. */
|
view. */
|
||||||
TransformToView (surface->view, x, y, &x, &y);
|
TransformToSurface (surface, x, y, &x, &y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1582,30 +1582,26 @@ ViewSetScale (View *view, int scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
GetTxTy (int scale)
|
GetContentScale (int scale)
|
||||||
{
|
{
|
||||||
if (scale > 0)
|
if (scale > 0)
|
||||||
return scale + 1;
|
return 1.0 / (scale + 1);
|
||||||
|
|
||||||
return 1.0 / (-scale + 1);
|
return -scale + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ViewApplyTransform (View *view, RenderBuffer buffer)
|
ViewComputeTransform (View *view, DrawParams *params)
|
||||||
{
|
{
|
||||||
RenderApplyTransform (buffer, GetTxTy (view->scale));
|
/* First, there is no transform. */
|
||||||
}
|
params->flags = 0;
|
||||||
|
|
||||||
/* TODO: the callers of this can be optimized by setting the picture
|
if (view->scale)
|
||||||
transform on the attached buffer if that buffer is not attached to
|
{
|
||||||
any other view. */
|
/* There is a scale, so set it. */
|
||||||
|
params->flags |= ScaleSet;
|
||||||
static Bool
|
params->scale = GetContentScale (view->scale);
|
||||||
ViewHaveTransform (View *view)
|
}
|
||||||
{
|
|
||||||
/* view->scale is the amount by which to scale _down_ the view. If
|
|
||||||
it is 0, then no scaling will be performed. */
|
|
||||||
return view->scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1763,6 +1759,7 @@ SubcompositorUpdate (Subcompositor *subcompositor)
|
||||||
RenderBuffer buffer;
|
RenderBuffer buffer;
|
||||||
int min_x, min_y;
|
int min_x, min_y;
|
||||||
int age;
|
int age;
|
||||||
|
DrawParams draw_params;
|
||||||
|
|
||||||
/* Just return if no target was specified. */
|
/* Just return if no target was specified. */
|
||||||
if (!IsTargetAttached (subcompositor))
|
if (!IsTargetAttached (subcompositor))
|
||||||
|
@ -1946,7 +1943,8 @@ SubcompositorUpdate (Subcompositor *subcompositor)
|
||||||
when the damage region is empty. */
|
when the damage region is empty. */
|
||||||
|
|
||||||
buffer = XLRenderBufferFromBuffer (view->buffer);
|
buffer = XLRenderBufferFromBuffer (view->buffer);
|
||||||
RenderUpdateBufferForDamage (buffer, &list->view->damage);
|
RenderUpdateBufferForDamage (buffer, &list->view->damage,
|
||||||
|
GetContentScale (list->view->scale));
|
||||||
|
|
||||||
if (pixman_region32_not_empty (&list->view->damage))
|
if (pixman_region32_not_empty (&list->view->damage))
|
||||||
{
|
{
|
||||||
|
@ -2115,11 +2113,12 @@ SubcompositorUpdate (Subcompositor *subcompositor)
|
||||||
|
|
||||||
Note that if the subcompositor is not garbaged, then this
|
Note that if the subcompositor is not garbaged, then this
|
||||||
has already been done. */
|
has already been done. */
|
||||||
RenderUpdateBufferForDamage (buffer, NULL);
|
RenderUpdateBufferForDamage (buffer, NULL, 0.0f);
|
||||||
else if (age < 0 || age > 3)
|
else if (age < 0 || age > 3)
|
||||||
/* The target contents are too old, but the damage can be
|
/* The target contents are too old, but the damage can be
|
||||||
trusted. */
|
trusted. */
|
||||||
RenderUpdateBufferForDamage (buffer, &view->damage);
|
RenderUpdateBufferForDamage (buffer, &view->damage,
|
||||||
|
GetContentScale (list->view->scale));
|
||||||
|
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
|
@ -2174,8 +2173,8 @@ SubcompositorUpdate (Subcompositor *subcompositor)
|
||||||
|
|
||||||
first = view;
|
first = view;
|
||||||
|
|
||||||
if (ViewHaveTransform (view))
|
/* Compute the transform and put it in draw_params. */
|
||||||
ViewApplyTransform (view, buffer);
|
ViewComputeTransform (view, &draw_params);
|
||||||
|
|
||||||
if (!IsGarbaged (subcompositor) && (age >= 0 && age < 3))
|
if (!IsGarbaged (subcompositor) && (age >= 0 && age < 3))
|
||||||
{
|
{
|
||||||
|
@ -2206,8 +2205,8 @@ SubcompositorUpdate (Subcompositor *subcompositor)
|
||||||
BoxStartY (temp_boxes) - min_y + ty,
|
BoxStartY (temp_boxes) - min_y + ty,
|
||||||
/* width. */
|
/* width. */
|
||||||
BoxWidth (temp_boxes),
|
BoxWidth (temp_boxes),
|
||||||
/* height. */
|
/* height, draw-params. */
|
||||||
BoxHeight (temp_boxes));
|
BoxHeight (temp_boxes), &draw_params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2228,8 +2227,8 @@ SubcompositorUpdate (Subcompositor *subcompositor)
|
||||||
view->abs_y - min_y + ty,
|
view->abs_y - min_y + ty,
|
||||||
/* width. */
|
/* width. */
|
||||||
ViewWidth (view),
|
ViewWidth (view),
|
||||||
/* height. */
|
/* height, draw-params. */
|
||||||
ViewHeight (view));
|
ViewHeight (view), &draw_params);
|
||||||
|
|
||||||
/* Also adjust the opaque and input regions here. */
|
/* Also adjust the opaque and input regions here. */
|
||||||
|
|
||||||
|
@ -2282,9 +2281,6 @@ SubcompositorUpdate (Subcompositor *subcompositor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ViewHaveTransform (view))
|
|
||||||
RenderResetTransform (buffer);
|
|
||||||
|
|
||||||
next_1:
|
next_1:
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
@ -2358,6 +2354,7 @@ SubcompositorExpose (Subcompositor *subcompositor, XEvent *event)
|
||||||
Operation op;
|
Operation op;
|
||||||
pixman_region32_t temp;
|
pixman_region32_t temp;
|
||||||
RenderBuffer buffer;
|
RenderBuffer buffer;
|
||||||
|
DrawParams draw_params;
|
||||||
|
|
||||||
/* Graphics exposures are not yet handled. */
|
/* Graphics exposures are not yet handled. */
|
||||||
if (event->type == GraphicsExpose)
|
if (event->type == GraphicsExpose)
|
||||||
|
@ -2438,11 +2435,12 @@ SubcompositorExpose (Subcompositor *subcompositor, XEvent *event)
|
||||||
buffer = XLRenderBufferFromBuffer (view->buffer);
|
buffer = XLRenderBufferFromBuffer (view->buffer);
|
||||||
boxes = pixman_region32_rectangles (&temp, &nboxes);
|
boxes = pixman_region32_rectangles (&temp, &nboxes);
|
||||||
|
|
||||||
/* Update the attached buffer from any damage. */
|
/* Compute the transform. */
|
||||||
RenderUpdateBufferForDamage (buffer, &list->view->damage);
|
ViewComputeTransform (view, &draw_params);
|
||||||
|
|
||||||
if (ViewHaveTransform (view))
|
/* Update the attached buffer from any damage. */
|
||||||
ViewApplyTransform (view, buffer);
|
RenderUpdateBufferForDamage (buffer, &list->view->damage,
|
||||||
|
GetContentScale (list->view->scale));
|
||||||
|
|
||||||
for (i = 0; i < nboxes; ++i)
|
for (i = 0; i < nboxes; ++i)
|
||||||
RenderComposite (buffer, subcompositor->target, op,
|
RenderComposite (buffer, subcompositor->target, op,
|
||||||
|
@ -2455,11 +2453,9 @@ SubcompositorExpose (Subcompositor *subcompositor, XEvent *event)
|
||||||
/* dst-y. */
|
/* dst-y. */
|
||||||
BoxStartY (boxes[i]) - min_y + ty,
|
BoxStartY (boxes[i]) - min_y + ty,
|
||||||
/* width, height. */
|
/* width, height. */
|
||||||
BoxWidth (boxes[i]), BoxHeight (boxes[i]));
|
BoxWidth (boxes[i]), BoxHeight (boxes[i]),
|
||||||
|
/* draw-params. */
|
||||||
/* Undo transforms that were applied. */
|
&draw_params);
|
||||||
if (ViewHaveTransform (view))
|
|
||||||
RenderResetTransform (buffer);
|
|
||||||
|
|
||||||
/* Free the scratch region used to compute the intersection. */
|
/* Free the scratch region used to compute the intersection. */
|
||||||
pixman_region32_fini (&temp);
|
pixman_region32_fini (&temp);
|
||||||
|
|
30
subsurface.c
30
subsurface.c
|
@ -488,9 +488,13 @@ MaybeUpdateOutputs (Subsurface *subsurface)
|
||||||
/* Valid base coordinates are not yet available. */
|
/* Valid base coordinates are not yet available. */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!subsurface->parent)
|
||||||
|
/* A valid scale factor is not available. */
|
||||||
|
return;
|
||||||
|
|
||||||
/* Compute the positions relative to the parent. */
|
/* Compute the positions relative to the parent. */
|
||||||
x = subsurface->current_substate.x * global_scale_factor;
|
x = subsurface->current_substate.x * subsurface->parent->factor;
|
||||||
y = subsurface->current_substate.y * global_scale_factor;
|
y = subsurface->current_substate.y * subsurface->parent->factor;
|
||||||
|
|
||||||
/* And the base X and Y. */
|
/* And the base X and Y. */
|
||||||
base_x = subsurface->role.surface->output_x;
|
base_x = subsurface->role.surface->output_x;
|
||||||
|
@ -541,12 +545,12 @@ AfterParentCommit (Surface *surface, void *data)
|
||||||
subsurface->current_substate.y
|
subsurface->current_substate.y
|
||||||
= subsurface->pending_substate.y;
|
= subsurface->pending_substate.y;
|
||||||
|
|
||||||
/* The X and Y coordinates here are also surface-local and must
|
/* The X and Y coordinates here are also parent-local and must
|
||||||
be scaled by the global scale factor. */
|
be scaled by the global scale factor. */
|
||||||
|
|
||||||
ViewMove (subsurface->role.surface->view,
|
ViewMove (subsurface->role.surface->view,
|
||||||
subsurface->current_substate.x * global_scale_factor,
|
subsurface->current_substate.x * subsurface->parent->factor,
|
||||||
subsurface->current_substate.y * global_scale_factor);
|
subsurface->current_substate.y * subsurface->parent->factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And any cached surface state too. */
|
/* And any cached surface state too. */
|
||||||
|
@ -695,8 +699,15 @@ Rescale (Surface *surface, Role *role)
|
||||||
position. */
|
position. */
|
||||||
|
|
||||||
ViewMove (surface->view,
|
ViewMove (surface->view,
|
||||||
subsurface->current_substate.x * global_scale_factor,
|
subsurface->current_substate.x * subsurface->parent->factor,
|
||||||
subsurface->current_substate.y * global_scale_factor);
|
subsurface->current_substate.y * subsurface->parent->factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ParentRescale (Surface *surface, Role *role)
|
||||||
|
{
|
||||||
|
/* This is called when the scale factor of the parent changes. */
|
||||||
|
Rescale (surface, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -843,6 +854,7 @@ GetSubsurface (struct wl_client *client, struct wl_resource *resource,
|
||||||
subsurface->role.funcs.early_commit = EarlyCommit;
|
subsurface->role.funcs.early_commit = EarlyCommit;
|
||||||
subsurface->role.funcs.get_window = GetWindow;
|
subsurface->role.funcs.get_window = GetWindow;
|
||||||
subsurface->role.funcs.rescale = Rescale;
|
subsurface->role.funcs.rescale = Rescale;
|
||||||
|
subsurface->role.funcs.parent_rescale = ParentRescale;
|
||||||
subsurface->role.funcs.note_child_synced = NoteChildSynced;
|
subsurface->role.funcs.note_child_synced = NoteChildSynced;
|
||||||
subsurface->role.funcs.note_desync_child = NoteDesyncChild;
|
subsurface->role.funcs.note_desync_child = NoteDesyncChild;
|
||||||
|
|
||||||
|
@ -937,9 +949,9 @@ XLUpdateOutputsForChildren (Surface *parent, int base_x, int base_y)
|
||||||
child = item->data;
|
child = item->data;
|
||||||
subsurface = SubsurfaceFromRole (child->role);
|
subsurface = SubsurfaceFromRole (child->role);
|
||||||
output_x = (subsurface->current_substate.x
|
output_x = (subsurface->current_substate.x
|
||||||
* global_scale_factor);
|
* parent->factor);
|
||||||
output_y = (subsurface->current_substate.y
|
output_y = (subsurface->current_substate.y
|
||||||
* global_scale_factor);
|
* parent->factor);
|
||||||
output_width = ViewWidth (child->view);
|
output_width = ViewWidth (child->view);
|
||||||
output_height = ViewHeight (child->view);
|
output_height = ViewHeight (child->view);
|
||||||
|
|
||||||
|
|
107
surface.c
107
surface.c
|
@ -509,11 +509,92 @@ static void
|
||||||
ApplyScale (Surface *surface)
|
ApplyScale (Surface *surface)
|
||||||
{
|
{
|
||||||
int scale, effective;
|
int scale, effective;
|
||||||
|
double b, g, e, d;
|
||||||
|
XLList *subsurface;
|
||||||
|
Role *role;
|
||||||
|
|
||||||
scale = surface->current_state.buffer_scale;
|
scale = surface->current_state.buffer_scale;
|
||||||
effective = GetEffectiveScale (scale);
|
effective = GetEffectiveScale (scale);
|
||||||
|
|
||||||
ViewSetScale (surface->view, effective);
|
ViewSetScale (surface->view, effective);
|
||||||
|
|
||||||
|
/* Now calculate the surface factor, a factor used to scale surface
|
||||||
|
coordinates to view (X window) coordinates.
|
||||||
|
|
||||||
|
The scale we want is the width of the view (area on the X screen)
|
||||||
|
divided by the surface width, which is the width of the buffer
|
||||||
|
after it has been shrunk B - 1 times, B being the buffer scale.
|
||||||
|
|
||||||
|
However, the size of the view is not available during computation.
|
||||||
|
So, computing the scale looks something like this:
|
||||||
|
|
||||||
|
A = width of buffer <-------------+-- we must reduce these out
|
||||||
|
B = buffer scale |
|
||||||
|
C = width of view <---------------+
|
||||||
|
L = surface width <---------------+
|
||||||
|
G = global scale
|
||||||
|
E = scale after accounting for difference between the global
|
||||||
|
and buffer scales
|
||||||
|
D = desired scale, otherwise C / surface width
|
||||||
|
|
||||||
|
A = 2004
|
||||||
|
B = 3
|
||||||
|
G = 2
|
||||||
|
|
||||||
|
L = A / B
|
||||||
|
E = G - B
|
||||||
|
|
||||||
|
if E is not less than 0
|
||||||
|
|
||||||
|
E = E + 1
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
E = 1 / abs (E - 1)
|
||||||
|
|
||||||
|
finally
|
||||||
|
|
||||||
|
C = A * E
|
||||||
|
D = C / L
|
||||||
|
|
||||||
|
D = (A * E) / (A / B)
|
||||||
|
D = B * E
|
||||||
|
|
||||||
|
Phew. */
|
||||||
|
|
||||||
|
b = scale;
|
||||||
|
g = global_scale_factor;
|
||||||
|
e = g - b;
|
||||||
|
|
||||||
|
if (e >= 0.0)
|
||||||
|
e = e + 1;
|
||||||
|
else
|
||||||
|
e = 1.0 / fabs (e - 1);
|
||||||
|
|
||||||
|
d = b * e;
|
||||||
|
|
||||||
|
if (surface->factor != d)
|
||||||
|
{
|
||||||
|
/* The scale factor changed. */
|
||||||
|
surface->factor = d;
|
||||||
|
|
||||||
|
/* Notify all subsurfaces to move themselves to a more correct
|
||||||
|
location. */
|
||||||
|
subsurface = surface->subsurfaces;
|
||||||
|
for (; subsurface; subsurface = subsurface->next)
|
||||||
|
{
|
||||||
|
/* Get the subsurface role. */
|
||||||
|
role = subsurface->data;
|
||||||
|
|
||||||
|
/* Make sure it still has a surface, since it should not be
|
||||||
|
in surface->subsurfaces otherwise. */
|
||||||
|
XLAssert (role->surface != NULL);
|
||||||
|
|
||||||
|
/* Call the parent rescale hook. */
|
||||||
|
if (role->funcs.rescale)
|
||||||
|
role->funcs.rescale (role->surface, role);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -530,7 +611,7 @@ ApplyOpaqueRegion (Surface *surface)
|
||||||
{
|
{
|
||||||
pixman_region32_init (&temp);
|
pixman_region32_init (&temp);
|
||||||
XLScaleRegion (&temp, &surface->current_state.opaque,
|
XLScaleRegion (&temp, &surface->current_state.opaque,
|
||||||
global_scale_factor, global_scale_factor);
|
surface->factor, surface->factor);
|
||||||
ViewSetOpaque (surface->view, &temp);
|
ViewSetOpaque (surface->view, &temp);
|
||||||
pixman_region32_fini (&temp);
|
pixman_region32_fini (&temp);
|
||||||
}
|
}
|
||||||
|
@ -550,7 +631,7 @@ ApplyInputRegion (Surface *surface)
|
||||||
{
|
{
|
||||||
pixman_region32_init (&temp);
|
pixman_region32_init (&temp);
|
||||||
XLScaleRegion (&temp, &surface->current_state.input,
|
XLScaleRegion (&temp, &surface->current_state.input,
|
||||||
global_scale_factor, global_scale_factor);
|
surface->factor, surface->factor);
|
||||||
ViewSetInput (surface->view, &temp);
|
ViewSetInput (surface->view, &temp);
|
||||||
pixman_region32_fini (&temp);
|
pixman_region32_fini (&temp);
|
||||||
}
|
}
|
||||||
|
@ -566,9 +647,9 @@ HandleScaleChanged (void *data, int new_scale)
|
||||||
|
|
||||||
/* First, reapply various regions that depend on the surface
|
/* First, reapply various regions that depend on the surface
|
||||||
scale. */
|
scale. */
|
||||||
|
ApplyScale (surface);
|
||||||
ApplyInputRegion (surface);
|
ApplyInputRegion (surface);
|
||||||
ApplyOpaqueRegion (surface);
|
ApplyOpaqueRegion (surface);
|
||||||
ApplyScale (surface);
|
|
||||||
|
|
||||||
/* Next, call any role-specific hooks. */
|
/* Next, call any role-specific hooks. */
|
||||||
if (surface->role && surface->role->funcs.rescale)
|
if (surface->role && surface->role->funcs.rescale)
|
||||||
|
@ -639,7 +720,7 @@ ApplySurfaceDamage (Surface *surface)
|
||||||
{
|
{
|
||||||
pixman_region32_init (&temp);
|
pixman_region32_init (&temp);
|
||||||
XLScaleRegion (&temp, &surface->current_state.surface,
|
XLScaleRegion (&temp, &surface->current_state.surface,
|
||||||
global_scale_factor, global_scale_factor);
|
surface->factor, surface->factor);
|
||||||
ViewDamage (surface->view, &temp);
|
ViewDamage (surface->view, &temp);
|
||||||
pixman_region32_fini (&temp);
|
pixman_region32_fini (&temp);
|
||||||
}
|
}
|
||||||
|
@ -788,6 +869,12 @@ InternalCommit (Surface *surface, State *pending)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pending->pending & PendingBufferScale)
|
||||||
|
{
|
||||||
|
surface->current_state.buffer_scale = pending->buffer_scale;
|
||||||
|
ApplyScale (surface);
|
||||||
|
}
|
||||||
|
|
||||||
if (pending->pending & PendingInputRegion)
|
if (pending->pending & PendingInputRegion)
|
||||||
{
|
{
|
||||||
pixman_region32_copy (&surface->current_state.input,
|
pixman_region32_copy (&surface->current_state.input,
|
||||||
|
@ -802,12 +889,6 @@ InternalCommit (Surface *surface, State *pending)
|
||||||
ApplyOpaqueRegion (surface);
|
ApplyOpaqueRegion (surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pending->pending & PendingBufferScale)
|
|
||||||
{
|
|
||||||
surface->current_state.buffer_scale = pending->buffer_scale;
|
|
||||||
ApplyScale (surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pending->pending & PendingAttachments)
|
if (pending->pending & PendingAttachments)
|
||||||
{
|
{
|
||||||
surface->current_state.x = pending->x;
|
surface->current_state.x = pending->x;
|
||||||
|
@ -1151,13 +1232,13 @@ XLCreateSurface (struct wl_client *client,
|
||||||
InitState (&surface->current_state);
|
InitState (&surface->current_state);
|
||||||
InitState (&surface->cached_state);
|
InitState (&surface->cached_state);
|
||||||
|
|
||||||
|
/* Apply the scale to initialize the default. */
|
||||||
|
ApplyScale (surface);
|
||||||
|
|
||||||
/* Now the default input has been initialized, so apply it to the
|
/* Now the default input has been initialized, so apply it to the
|
||||||
view. */
|
view. */
|
||||||
ApplyInputRegion (surface);
|
ApplyInputRegion (surface);
|
||||||
|
|
||||||
/* Likewise for the scale. */
|
|
||||||
ApplyScale (surface);
|
|
||||||
|
|
||||||
/* Initially, allow surfaces to accept any kind of role. */
|
/* Initially, allow surfaces to accept any kind of role. */
|
||||||
surface->role_type = AnythingType;
|
surface->role_type = AnythingType;
|
||||||
|
|
||||||
|
|
27
xdg_popup.c
27
xdg_popup.c
|
@ -278,6 +278,7 @@ MoveWindow (XdgPopup *popup)
|
||||||
int root_x, root_y, parent_gx, parent_gy;
|
int root_x, root_y, parent_gx, parent_gy;
|
||||||
int geometry_x, geometry_y, x, y;
|
int geometry_x, geometry_y, x, y;
|
||||||
Window window;
|
Window window;
|
||||||
|
double parent_scale, current_scale;
|
||||||
|
|
||||||
/* No parent was specified. */
|
/* No parent was specified. */
|
||||||
if (!popup->parent)
|
if (!popup->parent)
|
||||||
|
@ -286,6 +287,14 @@ MoveWindow (XdgPopup *popup)
|
||||||
if (!popup->role || !popup->parent)
|
if (!popup->role || !popup->parent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!popup->role->surface || !popup->parent->surface)
|
||||||
|
/* No surface being available means we cannot obtain the window
|
||||||
|
scale. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
parent_scale = popup->parent->surface->factor;
|
||||||
|
current_scale = popup->role->surface->factor;
|
||||||
|
|
||||||
window = XLWindowFromXdgRole (popup->role);
|
window = XLWindowFromXdgRole (popup->role);
|
||||||
|
|
||||||
XLXdgRoleGetCurrentGeometry (popup->parent, &parent_gx,
|
XLXdgRoleGetCurrentGeometry (popup->parent, &parent_gx,
|
||||||
|
@ -295,12 +304,18 @@ MoveWindow (XdgPopup *popup)
|
||||||
XLXdgRoleCurrentRootPosition (popup->parent, &root_x,
|
XLXdgRoleCurrentRootPosition (popup->parent, &root_x,
|
||||||
&root_y);
|
&root_y);
|
||||||
|
|
||||||
parent_gx *= global_scale_factor;
|
/* Parent geometry is relative to the parent coordinate system. */
|
||||||
parent_gy *= global_scale_factor;
|
parent_gx *= parent_scale;
|
||||||
geometry_x *= global_scale_factor;
|
parent_gy *= parent_scale;
|
||||||
geometry_y *= global_scale_factor;
|
|
||||||
x = popup->x * global_scale_factor;
|
/* geometry_x and geometry_y are relative to the local coordinate
|
||||||
y = popup->y * global_scale_factor;
|
system. */
|
||||||
|
geometry_x *= current_scale;
|
||||||
|
geometry_y *= current_scale;
|
||||||
|
|
||||||
|
/* X and Y are relative to the parent coordinate system. */
|
||||||
|
x = popup->x * parent_scale;
|
||||||
|
y = popup->y * parent_scale;
|
||||||
|
|
||||||
XMoveWindow (compositor.display, window,
|
XMoveWindow (compositor.display, window,
|
||||||
x + root_x + parent_gx - geometry_x,
|
x + root_x + parent_gx - geometry_x,
|
||||||
|
|
|
@ -1167,8 +1167,8 @@ GetResizeDimensions (Surface *surface, Role *role, int *x_out,
|
||||||
{
|
{
|
||||||
XLXdgRoleGetCurrentGeometry (role, NULL, NULL, x_out, y_out);
|
XLXdgRoleGetCurrentGeometry (role, NULL, NULL, x_out, y_out);
|
||||||
|
|
||||||
*x_out *= global_scale_factor;
|
*x_out *= surface->factor;
|
||||||
*y_out *= global_scale_factor;
|
*y_out *= surface->factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1467,7 +1467,10 @@ XLXdgRoleCalcNewWindowSize (Role *role, int width, int height,
|
||||||
|
|
||||||
xdg_role = XdgRoleFromRole (role);
|
xdg_role = XdgRoleFromRole (role);
|
||||||
|
|
||||||
if (!xdg_role->current_state.window_geometry_width)
|
if (!xdg_role->current_state.window_geometry_width
|
||||||
|
/* If no surface exists, we might as well return immediately,
|
||||||
|
since the scale factor will not be obtainable. */
|
||||||
|
|| !role->surface)
|
||||||
{
|
{
|
||||||
*new_width = width;
|
*new_width = width;
|
||||||
*new_height = height;
|
*new_height = height;
|
||||||
|
@ -1480,8 +1483,8 @@ XLXdgRoleCalcNewWindowSize (Role *role, int width, int height,
|
||||||
|
|
||||||
/* Adjust the current_width and current_height by the global scale
|
/* Adjust the current_width and current_height by the global scale
|
||||||
factor. */
|
factor. */
|
||||||
current_width = (max_x - min_x + 1) / global_scale_factor;
|
current_width = (max_x - min_x + 1) / role->surface->factor;
|
||||||
current_height = (max_y - min_y + 1) / global_scale_factor;
|
current_height = (max_y - min_y + 1) / role->surface->factor;
|
||||||
|
|
||||||
XLXdgRoleGetCurrentGeometry (role, NULL, NULL, &geometry_width,
|
XLXdgRoleGetCurrentGeometry (role, NULL, NULL, &geometry_width,
|
||||||
&geometry_height);
|
&geometry_height);
|
||||||
|
|
|
@ -362,9 +362,14 @@ NoteConfigureTime (Timer *timer, void *data, struct timespec time)
|
||||||
{
|
{
|
||||||
XdgToplevel *toplevel;
|
XdgToplevel *toplevel;
|
||||||
int width, height, effective_width, effective_height;
|
int width, height, effective_width, effective_height;
|
||||||
|
double factor;
|
||||||
|
|
||||||
toplevel = data;
|
toplevel = data;
|
||||||
|
|
||||||
|
/* Obtain the scale factor. toplevel->role->surface should not be
|
||||||
|
NULL here, as the timer is cancelled upon role detachment. */
|
||||||
|
factor = toplevel->role->surface->factor;
|
||||||
|
|
||||||
/* If only the window state changed, call SendStates. */
|
/* If only the window state changed, call SendStates. */
|
||||||
if (!(toplevel->state & StatePendingConfigureSize))
|
if (!(toplevel->state & StatePendingConfigureSize))
|
||||||
SendStates (toplevel);
|
SendStates (toplevel);
|
||||||
|
@ -374,8 +379,8 @@ NoteConfigureTime (Timer *timer, void *data, struct timespec time)
|
||||||
if (toplevel->state & StatePendingConfigureStates)
|
if (toplevel->state & StatePendingConfigureStates)
|
||||||
WriteStates (toplevel);
|
WriteStates (toplevel);
|
||||||
|
|
||||||
effective_width = toplevel->configure_width / global_scale_factor;
|
effective_width = toplevel->configure_width / factor;
|
||||||
effective_height = toplevel->configure_height / global_scale_factor;
|
effective_height = toplevel->configure_height / factor;
|
||||||
|
|
||||||
/* Compute the geometry for the configure event based on the
|
/* Compute the geometry for the configure event based on the
|
||||||
current size of the toplevel. */
|
current size of the toplevel. */
|
||||||
|
@ -477,9 +482,14 @@ static void
|
||||||
SendStates (XdgToplevel *toplevel)
|
SendStates (XdgToplevel *toplevel)
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
|
double factor;
|
||||||
|
|
||||||
WriteStates (toplevel);
|
WriteStates (toplevel);
|
||||||
|
|
||||||
|
/* Obtain the scale factor. toplevel->role->surface should not be
|
||||||
|
NULL here. */
|
||||||
|
factor = toplevel->role->surface->factor;
|
||||||
|
|
||||||
/* Adjust the width and height we're sending by the window
|
/* Adjust the width and height we're sending by the window
|
||||||
geometry. */
|
geometry. */
|
||||||
if (toplevel->state & StateMissingState)
|
if (toplevel->state & StateMissingState)
|
||||||
|
@ -487,8 +497,8 @@ SendStates (XdgToplevel *toplevel)
|
||||||
&width, &height);
|
&width, &height);
|
||||||
else
|
else
|
||||||
XLXdgRoleCalcNewWindowSize (toplevel->role,
|
XLXdgRoleCalcNewWindowSize (toplevel->role,
|
||||||
toplevel->width / global_scale_factor,
|
toplevel->width / factor,
|
||||||
toplevel->height / global_scale_factor,
|
toplevel->height / factor,
|
||||||
&width, &height);
|
&width, &height);
|
||||||
|
|
||||||
SendConfigure (toplevel, width, height);
|
SendConfigure (toplevel, width, height);
|
||||||
|
@ -505,6 +515,14 @@ RecordStateSize (XdgToplevel *toplevel)
|
||||||
{
|
{
|
||||||
Bool a, b;
|
Bool a, b;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
double factor;
|
||||||
|
|
||||||
|
if (!toplevel->role->surface)
|
||||||
|
/* We can't get the scale factor in this case. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Obtain the scale factor. */
|
||||||
|
factor = toplevel->role->surface->factor;
|
||||||
|
|
||||||
/* Record the last known size of a toplevel before its state is
|
/* Record the last known size of a toplevel before its state is
|
||||||
changed. That way, we can send xdg_toplevel::configure with the
|
changed. That way, we can send xdg_toplevel::configure with the
|
||||||
|
@ -521,8 +539,8 @@ RecordStateSize (XdgToplevel *toplevel)
|
||||||
upon minimization. */
|
upon minimization. */
|
||||||
XLXdgRoleGetCurrentGeometry (toplevel->role, NULL, NULL,
|
XLXdgRoleGetCurrentGeometry (toplevel->role, NULL, NULL,
|
||||||
&width, &height);
|
&width, &height);
|
||||||
width *= global_scale_factor;
|
width *= factor;
|
||||||
height *= global_scale_factor;
|
height *= factor;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -778,10 +796,10 @@ HandleWindowGeometryChange (XdgToplevel *toplevel)
|
||||||
XLXdgRoleGetCurrentGeometry (toplevel->role, &x, &y,
|
XLXdgRoleGetCurrentGeometry (toplevel->role, &x, &y,
|
||||||
&width, &height);
|
&width, &height);
|
||||||
|
|
||||||
width *= global_scale_factor;
|
width *= toplevel->role->surface->factor;
|
||||||
height *= global_scale_factor;
|
height *= toplevel->role->surface->factor;
|
||||||
x *= global_scale_factor;
|
x *= toplevel->role->surface->factor;
|
||||||
y *= global_scale_factor;
|
y *= toplevel->role->surface->factor;
|
||||||
|
|
||||||
dx = SubcompositorWidth (subcompositor) - width;
|
dx = SubcompositorWidth (subcompositor) - width;
|
||||||
dy = SubcompositorHeight (subcompositor) - height;
|
dy = SubcompositorHeight (subcompositor) - height;
|
||||||
|
@ -795,25 +813,35 @@ HandleWindowGeometryChange (XdgToplevel *toplevel)
|
||||||
/* Initially, specify PSize. After the first MapNotify, also
|
/* Initially, specify PSize. After the first MapNotify, also
|
||||||
specify PPosition so that subsurfaces won't move the window. */
|
specify PPosition so that subsurfaces won't move the window. */
|
||||||
|
|
||||||
hints->min_width = toplevel->min_width * global_scale_factor + dx;
|
hints->min_width = (toplevel->min_width
|
||||||
hints->min_height = toplevel->min_height * global_scale_factor + dy;
|
* toplevel->role->surface->factor
|
||||||
|
+ dx);
|
||||||
|
hints->min_height = (toplevel->min_height
|
||||||
|
* toplevel->role->surface->factor
|
||||||
|
+ dy);
|
||||||
|
|
||||||
if (toplevel->max_width)
|
if (toplevel->max_width)
|
||||||
{
|
{
|
||||||
hints->max_width = toplevel->max_width * global_scale_factor + dx;
|
hints->max_width = (toplevel->max_width
|
||||||
hints->max_height = toplevel->max_height * global_scale_factor + dy;
|
* toplevel->role->surface->factor
|
||||||
|
+ dx);
|
||||||
|
hints->max_height = (toplevel->max_height
|
||||||
|
* toplevel->role->surface->factor
|
||||||
|
+ dy);
|
||||||
hints->flags |= PMaxSize;
|
hints->flags |= PMaxSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hints->flags &= ~PMaxSize;
|
hints->flags &= ~PMaxSize;
|
||||||
|
|
||||||
/* If a global scale factor is set, also set the resize increment to
|
/* If a scale factor is set, also set the resize increment to the
|
||||||
the scale factor. */
|
scale factor. */
|
||||||
|
|
||||||
if (global_scale_factor != 1)
|
if (toplevel->role->surface->factor != 1)
|
||||||
{
|
{
|
||||||
hints->width_inc = global_scale_factor;
|
/* Take the ceiling value, there is no good way of dealing with
|
||||||
hints->height_inc = global_scale_factor;
|
cases where the scale ends up a non-integer value. */
|
||||||
|
hints->width_inc = ceil (toplevel->role->surface->factor);
|
||||||
|
hints->height_inc = ceil (toplevel->role->surface->factor);
|
||||||
hints->flags |= PResizeInc;
|
hints->flags |= PResizeInc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1345,10 +1373,10 @@ NoteWindowPreResize (Role *role, XdgRoleImplementation *impl,
|
||||||
XLXdgRoleGetCurrentGeometry (toplevel->role, &x, &y,
|
XLXdgRoleGetCurrentGeometry (toplevel->role, &x, &y,
|
||||||
&gwidth, &gheight);
|
&gwidth, &gheight);
|
||||||
|
|
||||||
dx = width - gwidth * global_scale_factor;
|
dx = width - gwidth * toplevel->role->surface->factor;
|
||||||
dy = height - gheight * global_scale_factor;
|
dy = height - gheight * toplevel->role->surface->factor;
|
||||||
x *= global_scale_factor;
|
x *= toplevel->role->surface->factor;
|
||||||
y *= global_scale_factor;
|
y *= toplevel->role->surface->factor;
|
||||||
|
|
||||||
ApplyGtkFrameExtents (toplevel, x, y, dx - x, dy - y);
|
ApplyGtkFrameExtents (toplevel, x, y, dx - x, dy - y);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue