mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-08-09 20:24:14 +00:00
[client] all: properly support guest rotation
If the guest has it's output rotated (ie, landscape) we must rotate and translate the pointer draw location, as well as all the translations of cursor coordinate spaces based on the rotation, along with any local rotations that may also be applied.
This commit is contained in:
@@ -57,7 +57,7 @@ struct EGL_Cursor
|
||||
// cursor state
|
||||
bool visible;
|
||||
float x, y, w, h;
|
||||
int rotate;
|
||||
LG_RendererRotate rotate;
|
||||
int cbMode;
|
||||
|
||||
struct CursorTex norm;
|
||||
@@ -170,8 +170,7 @@ void egl_cursor_free(EGL_Cursor ** cursor)
|
||||
}
|
||||
|
||||
bool egl_cursor_set_shape(EGL_Cursor * cursor, const LG_RendererCursor type,
|
||||
const int width, const int height, const LG_RendererRotate rotate,
|
||||
const int stride, const uint8_t * data)
|
||||
const int width, const int height, const int stride, const uint8_t * data)
|
||||
{
|
||||
LG_LOCK(cursor->lock);
|
||||
|
||||
@@ -179,7 +178,6 @@ bool egl_cursor_set_shape(EGL_Cursor * cursor, const LG_RendererCursor type,
|
||||
cursor->width = width;
|
||||
cursor->height = (type == LG_CURSOR_MONOCHROME ? height / 2 : height);
|
||||
cursor->stride = stride;
|
||||
cursor->rotate = rotate;
|
||||
|
||||
const size_t size = height * stride;
|
||||
if (size > cursor->dataSize)
|
||||
@@ -217,7 +215,7 @@ void egl_cursor_set_state(EGL_Cursor * cursor, const bool visible, const float x
|
||||
cursor->y = y;
|
||||
}
|
||||
|
||||
void egl_cursor_render(EGL_Cursor * cursor)
|
||||
void egl_cursor_render(EGL_Cursor * cursor, LG_RendererRotate rotate)
|
||||
{
|
||||
if (!cursor->visible)
|
||||
return;
|
||||
@@ -270,6 +268,8 @@ void egl_cursor_render(EGL_Cursor * cursor)
|
||||
LG_UNLOCK(cursor->lock);
|
||||
}
|
||||
|
||||
cursor->rotate = rotate;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
switch(cursor->type)
|
||||
{
|
||||
|
@@ -33,10 +33,12 @@ bool egl_cursor_set_shape(
|
||||
const LG_RendererCursor type,
|
||||
const int width,
|
||||
const int height,
|
||||
const LG_RendererRotate rotate,
|
||||
const int stride,
|
||||
const uint8_t * data);
|
||||
|
||||
void egl_cursor_set_size (EGL_Cursor * cursor, const float x, const float y);
|
||||
void egl_cursor_set_state(EGL_Cursor * cursor, const bool visible, const float x, const float y);
|
||||
void egl_cursor_render (EGL_Cursor * cursor);
|
||||
void egl_cursor_set_size(EGL_Cursor * cursor, const float x, const float y);
|
||||
|
||||
void egl_cursor_set_state(EGL_Cursor * cursor, const bool visible,
|
||||
const float x, const float y);
|
||||
|
||||
void egl_cursor_render(EGL_Cursor * cursor, LG_RendererRotate rotate);
|
||||
|
@@ -204,7 +204,6 @@ bool egl_desktop_setup(EGL_Desktop * desktop, const LG_RendererFormat format, bo
|
||||
|
||||
desktop->width = format.width;
|
||||
desktop->height = format.height;
|
||||
desktop->rotate = format.rotate;
|
||||
|
||||
if (!egl_texture_setup(
|
||||
desktop->texture,
|
||||
@@ -246,7 +245,9 @@ bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dm
|
||||
return true;
|
||||
}
|
||||
|
||||
bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, const bool nearest)
|
||||
bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y,
|
||||
const float scaleX, const float scaleY, const bool nearest,
|
||||
LG_RendererRotate rotate)
|
||||
{
|
||||
if (!desktop->shader)
|
||||
return false;
|
||||
@@ -254,7 +255,7 @@ bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, con
|
||||
const struct DesktopShader * shader = desktop->shader;
|
||||
egl_shader_use(shader->shader);
|
||||
glUniform4f(shader->uDesktopPos , x, y, scaleX, scaleY);
|
||||
glUniform1i(shader->uRotate , desktop->rotate);
|
||||
glUniform1i(shader->uRotate , rotate);
|
||||
glUniform1i(shader->uNearest , nearest ? 1 : 0);
|
||||
glUniform2f(shader->uDesktopSize, desktop->width, desktop->height);
|
||||
|
||||
|
@@ -31,4 +31,6 @@ void egl_desktop_free(EGL_Desktop ** desktop);
|
||||
|
||||
bool egl_desktop_setup (EGL_Desktop * desktop, const LG_RendererFormat format, bool useDMA);
|
||||
bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dmaFd);
|
||||
bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, const bool nearest);
|
||||
bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y,
|
||||
const float scaleX, const float scaleY, const bool nearest,
|
||||
LG_RendererRotate rotate);
|
||||
|
@@ -80,8 +80,9 @@ struct Inst
|
||||
bool useCloseFlag;
|
||||
bool closeFlag;
|
||||
|
||||
int width, height;
|
||||
LG_RendererRect destRect;
|
||||
int width, height;
|
||||
LG_RendererRect destRect;
|
||||
LG_RendererRotate rotate; //client side rotation
|
||||
|
||||
float translateX , translateY;
|
||||
float scaleX , scaleY;
|
||||
@@ -263,12 +264,83 @@ void egl_on_restart(void * opaque)
|
||||
this->start = false;
|
||||
}
|
||||
|
||||
void egl_on_resize(void * opaque, const int width, const int height, const LG_RendererRect destRect)
|
||||
static void egl_calc_mouse_size(struct Inst * this)
|
||||
{
|
||||
int w, h;
|
||||
switch(this->format.rotate)
|
||||
{
|
||||
case LG_ROTATE_0:
|
||||
case LG_ROTATE_180:
|
||||
this->mouseScaleX = 2.0f / this->format.width;
|
||||
this->mouseScaleY = 2.0f / this->format.height;
|
||||
w = this->format.width;
|
||||
h = this->format.height;
|
||||
break;
|
||||
|
||||
case LG_ROTATE_90:
|
||||
case LG_ROTATE_270:
|
||||
this->mouseScaleX = 2.0f / this->format.height;
|
||||
this->mouseScaleY = 2.0f / this->format.width;
|
||||
w = this->format.height;
|
||||
h = this->format.width;
|
||||
break;
|
||||
}
|
||||
|
||||
switch((this->format.rotate + this->rotate) % LG_ROTATE_MAX)
|
||||
{
|
||||
case LG_ROTATE_0:
|
||||
case LG_ROTATE_180:
|
||||
egl_cursor_set_size(this->cursor,
|
||||
(this->mouseWidth * (1.0f / w)) * this->scaleX,
|
||||
(this->mouseHeight * (1.0f / h)) * this->scaleY
|
||||
);
|
||||
break;
|
||||
|
||||
case LG_ROTATE_90:
|
||||
case LG_ROTATE_270:
|
||||
egl_cursor_set_size(this->cursor,
|
||||
(this->mouseWidth * (1.0f / w)) * this->scaleY,
|
||||
(this->mouseHeight * (1.0f / h)) * this->scaleX
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void egl_calc_mouse_state(struct Inst * this)
|
||||
{
|
||||
switch((this->format.rotate + this->rotate) % LG_ROTATE_MAX)
|
||||
{
|
||||
case LG_ROTATE_0:
|
||||
case LG_ROTATE_180:
|
||||
egl_cursor_set_state(
|
||||
this->cursor,
|
||||
this->cursorVisible,
|
||||
(((float)this->cursorX * this->mouseScaleX) - 1.0f) * this->scaleX,
|
||||
(((float)this->cursorY * this->mouseScaleY) - 1.0f) * this->scaleY
|
||||
);
|
||||
break;
|
||||
|
||||
case LG_ROTATE_90:
|
||||
case LG_ROTATE_270:
|
||||
egl_cursor_set_state(
|
||||
this->cursor,
|
||||
this->cursorVisible,
|
||||
(((float)this->cursorX * this->mouseScaleX) - 1.0f) * this->scaleY,
|
||||
(((float)this->cursorY * this->mouseScaleY) - 1.0f) * this->scaleX
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void egl_on_resize(void * opaque, const int width, const int height,
|
||||
const LG_RendererRect destRect, LG_RendererRotate rotate)
|
||||
{
|
||||
struct Inst * this = (struct Inst *)opaque;
|
||||
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->rotate = rotate;
|
||||
|
||||
memcpy(&this->destRect, &destRect, sizeof(LG_RendererRect));
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
@@ -281,31 +353,22 @@ void egl_on_resize(void * opaque, const int width, const int height, const LG_Re
|
||||
this->scaleY = (float)destRect.h / (float)height;
|
||||
}
|
||||
|
||||
this->mouseScaleX = 2.0f / this->format.width ;
|
||||
this->mouseScaleY = 2.0f / this->format.height;
|
||||
egl_cursor_set_size(this->cursor,
|
||||
(this->mouseWidth * (1.0f / this->format.width )) * this->scaleX,
|
||||
(this->mouseHeight * (1.0f / this->format.height)) * this->scaleY
|
||||
);
|
||||
egl_calc_mouse_size(this);
|
||||
|
||||
this->splashRatio = (float)width / (float)height;
|
||||
this->screenScaleX = 1.0f / width;
|
||||
this->screenScaleY = 1.0f / height;
|
||||
|
||||
egl_cursor_set_state(
|
||||
this->cursor,
|
||||
this->cursorVisible,
|
||||
(((float)this->cursorX * this->mouseScaleX) - 1.0f) * this->scaleX,
|
||||
(((float)this->cursorY * this->mouseScaleY) - 1.0f) * this->scaleY
|
||||
);
|
||||
egl_calc_mouse_state(this);
|
||||
}
|
||||
|
||||
bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor,
|
||||
const int width, const int height, const LG_RendererRotate rotate,
|
||||
const int width, const int height,
|
||||
const int pitch, const uint8_t * data)
|
||||
{
|
||||
struct Inst * this = (struct Inst *)opaque;
|
||||
if (!egl_cursor_set_shape(this->cursor, cursor, width, height, rotate, pitch, data))
|
||||
|
||||
if (!egl_cursor_set_shape(this->cursor, cursor, width, height, pitch, data))
|
||||
{
|
||||
DEBUG_ERROR("Failed to update the cursor shape");
|
||||
return false;
|
||||
@@ -313,10 +376,7 @@ bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor,
|
||||
|
||||
this->mouseWidth = width;
|
||||
this->mouseHeight = height;
|
||||
egl_cursor_set_size(this->cursor,
|
||||
(this->mouseWidth * (1.0f / this->format.width )) * this->scaleX,
|
||||
(this->mouseHeight * (1.0f / this->format.height)) * this->scaleY
|
||||
);
|
||||
egl_calc_mouse_size(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -327,14 +387,7 @@ bool egl_on_mouse_event(void * opaque, const bool visible, const int x, const in
|
||||
this->cursorVisible = visible;
|
||||
this->cursorX = x;
|
||||
this->cursorY = y;
|
||||
|
||||
egl_cursor_set_state(
|
||||
this->cursor,
|
||||
this->cursorVisible,
|
||||
(((float)this->cursorX * this->mouseScaleX) - 1.0f) * this->scaleX,
|
||||
(((float)this->cursorY * this->mouseScaleY) - 1.0f) * this->scaleY
|
||||
);
|
||||
|
||||
egl_calc_mouse_state(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -621,7 +674,7 @@ bool egl_render_startup(void * opaque, SDL_Window * window)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool egl_render(void * opaque, SDL_Window * window)
|
||||
bool egl_render(void * opaque, SDL_Window * window, LG_RendererRotate rotate)
|
||||
{
|
||||
struct Inst * this = (struct Inst *)opaque;
|
||||
|
||||
@@ -631,7 +684,8 @@ bool egl_render(void * opaque, SDL_Window * window)
|
||||
if (this->start && egl_desktop_render(this->desktop,
|
||||
this->translateX, this->translateY,
|
||||
this->scaleX , this->scaleY ,
|
||||
this->useNearest))
|
||||
this->useNearest,
|
||||
rotate))
|
||||
{
|
||||
if (!this->waitFadeTime)
|
||||
{
|
||||
@@ -640,7 +694,9 @@ bool egl_render(void * opaque, SDL_Window * window)
|
||||
else
|
||||
this->waitDone = true;
|
||||
}
|
||||
egl_cursor_render(this->cursor);
|
||||
|
||||
egl_cursor_render(this->cursor,
|
||||
(this->format.rotate + rotate) % LG_ROTATE_MAX);
|
||||
}
|
||||
|
||||
if (!this->waitDone)
|
||||
|
@@ -316,7 +316,8 @@ void opengl_on_restart(void * opaque)
|
||||
this->waiting = true;
|
||||
}
|
||||
|
||||
void opengl_on_resize(void * opaque, const int width, const int height, const LG_RendererRect destRect)
|
||||
void opengl_on_resize(void * opaque, const int width, const int height,
|
||||
const LG_RendererRect destRect, LG_RendererRotate rotate)
|
||||
{
|
||||
struct Inst * this = (struct Inst *)opaque;
|
||||
|
||||
@@ -346,7 +347,8 @@ void opengl_on_resize(void * opaque, const int width, const int height, const LG
|
||||
}
|
||||
}
|
||||
|
||||
bool opengl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const LG_RendererRotate rotate, const int pitch, const uint8_t * data)
|
||||
bool opengl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor,
|
||||
const int width, const int height, const int pitch, const uint8_t * data)
|
||||
{
|
||||
struct Inst * this = (struct Inst *)opaque;
|
||||
if (!this)
|
||||
@@ -562,7 +564,7 @@ bool opengl_render_startup(void * opaque, SDL_Window * window)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool opengl_render(void * opaque, SDL_Window * window)
|
||||
bool opengl_render(void * opaque, SDL_Window * window, LG_RendererRotate rotate)
|
||||
{
|
||||
struct Inst * this = (struct Inst *)opaque;
|
||||
if (!this)
|
||||
|
Reference in New Issue
Block a user