Compare commits

..

17 Commits

Author SHA1 Message Date
Geoffrey McRae
163a2e5d0a [client] fix failure to build due to broken symlink, fixes #173 2019-07-23 11:06:51 +10:00
Geoffrey McRae
b979752989 [client] added missing include 2019-07-15 18:30:39 +10:00
orcephrye
8ad2d5f949 [client] autodetect monitor refresh rate for fps limit 2019-07-10 05:04:29 +10:00
Rokas Kupstys
745ba66119 Implement option to disable minimizing window on focus loss. Default behavior is not changed - not configuring these options unfocused window is minimized.
* Added config entry win:minimizeOnFocusLoss (default true).
2019-07-09 21:57:47 +10:00
Geoffrey McRae
4cf6dec592 [all] allow disable of backtrace support during build 2019-06-19 09:13:03 +10:00
Geoffrey McRae
d7fa0aeff9 [client] fix typo in SDL_VIDEODRIVER from prior patch, whoops :) 2019-06-19 09:03:15 +10:00
Geoffrey McRae
2def6346e6 [client] don't override SDL_VIDEODRIVER if it is already set 2019-06-19 09:01:28 +10:00
Geoffrey McRae
607539a2af [client] improve streaming texture performance 2019-06-13 08:54:51 +10:00
Geoffrey McRae
6d24dd52d6 [c-host] not all versions of mingw support wcstombs_s
While the _s functions are for security as they avoid exceeding the
supplied buffer, in our case they are not really required as we are
allocating a buffer large enough to store the entire result.

Fixes #171
2019-06-12 15:31:18 +10:00
Omar Pakker
e3343cbd01 Rewrite dkms.conf
1) With the change to the Makefile, this update allows dkms to build and install the module for different kernels.
2) As per dkms documentation, no use of ${dkms_tree}.
3) Removed the use of REMAKE_INITRD as this module is not needed that early in the boot process.
4) Updated version to match what's defined in the module
2019-06-06 13:40:06 +10:00
Omar Pakker
71ffa0a137 Update makefile to allow kernel override 2019-06-06 13:40:06 +10:00
Geoffrey McRae
2b4f8091f9 [client] README.md cosmetics 2019-05-31 16:45:55 +10:00
Geoffrey McRae
113da121e9 [client] updated documentation for new keybinds 2019-05-31 16:44:08 +10:00
Geoffrey McRae
dd7413f973 [client] added keybinds to send Ctrl+Alt+Fn
Fixes #165
2019-05-31 16:39:55 +10:00
Geoffrey McRae
0851fd13e6 [all] made a nicer icon, hopefully just a placeholder for now 2019-05-30 22:21:53 +10:00
Geoffrey McRae
97024041f3 [client] allow the screensaver to run 2019-05-30 20:54:39 +10:00
Geoffrey McRae
22238c3200 [client] fix invalid access on early termination 2019-05-30 20:24:51 +10:00
29 changed files with 298 additions and 114 deletions

View File

@@ -1 +1 @@
B1-rc4-0-g026bdb00f2+1
B1-rc6-6-gb979752989+1

View File

@@ -14,6 +14,9 @@ if(OPTIMIZE_FOR_NATIVE)
endif()
endif()
option(ENABLE_BACKTRACE "Enable backtrace support on crash" ON)
add_feature_info(ENABLE_BACKTRACE ENABLE_BACKTRACE "Backtrace support.")
add_compile_options(
"-Wall"
"-Werror"

View File

@@ -215,9 +215,8 @@ static bool dxgi_init(void * pointerShape, const unsigned int pointerSize)
IDXGIAdapter1_GetDesc1(this->adapter, &adapterDesc);
const size_t s = (wcslen(adapterDesc.Description)+1) * 2;
size_t unused;
char * desc = malloc(s);
wcstombs_s(&unused, desc, s, adapterDesc.Description, _TRUNCATE);
wcstombs(desc, adapterDesc.Description, s);
if (strstr(desc, optAdapter) == NULL)
{
@@ -238,9 +237,8 @@ static bool dxgi_init(void * pointerShape, const unsigned int pointerSize)
if (optOutput)
{
const size_t s = (wcslen(outputDesc.DeviceName)+1) * 2;
size_t unused;
char * desc = malloc(s);
wcstombs_s(&unused, desc, s, outputDesc.DeviceName, _TRUNCATE);
wcstombs(desc, outputDesc.DeviceName, s);
if (strstr(desc, optOutput) == NULL)
{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,4 +1,4 @@
#include "winuser.h"
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest"
IDI_APPLICATION ICON "icon.ico"
IDI_APPLICATION ICON "../../../resources/icon.ico"

View File

@@ -194,9 +194,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
for(int i = 0; i < app.argc; ++i)
{
const size_t s = (wcslen(wargv[i])+1) * 2;
size_t unused;
app.argv[i] = malloc(s);
wcstombs_s(&unused, app.argv[i], s, wargv[i], _TRUNCATE);
wcstombs(app.argv[i], wargv[i], s);
}
LocalFree(wargv);

View File

@@ -24,6 +24,9 @@ add_feature_info(ENABLE_EGL ENABLE_EGL "EGL renderer.")
option(ENABLE_CB_X11 "Enable X11 clipboard integration" ON)
add_feature_info(ENABLE_CB_X11 ENABLE_CB_X11 "X11 Clipboard Integration.")
option(ENABLE_BACKTRACE "Enable backtrace support on crash" ON)
add_feature_info(ENABLE_BACKTRACE ENABLE_BACKTRACE "Backtrace support.")
add_compile_options(
"-Wall"
"-Werror"

View File

@@ -48,6 +48,20 @@ Below are a list of current key bindings:
| <kbd>ScrLk</kbd>+<kbd>N</kbd> | Toggle night vision mode (EGL renderer only!) |
| <kbd>ScrLk</kbd>+<kbd>Insert</kbd> | Increase mouse sensitivity (in capture mode only) |
| <kbd>ScrLk</kbd>+<kbd>Del</kbd> | Decrease mouse sensitivity (in capture mode only) |
| <kbd>ScrLk</kbd>+<kbd>F1</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F1</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F2</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F2</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F3</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F3</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F4</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F4</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F5</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F5</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F6</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F6</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F7</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F7</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F8</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F8</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F9</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F9</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F10</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F10</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F11</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F11</kbd> to the guest |
| <kbd>ScrLk</kbd>+<kbd>F12</kbd> | Send <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>F12</kbd> to the guest |
### Setting options via command line arguments
@@ -87,24 +101,25 @@ Command line arguments will override any options loaded from the config files.
| app:framePollInterval | | 1000 | How often to check for a frame update in microseconds |
|-------------------------------------------------------------------------------------------------------------------------|
|-------------------------------------------------------------------------------------------------------|
| Long | Short | Value | Description |
|-------------------------------------------------------------------------------------------------------|
| win:title | | Looking Glass (client) | The window title |
| win:position | | center | Initial window position at startup |
| win:size | | 1024x768 | Initial window size at startup |
| win:autoResize | -a | no | Auto resize the window to the guest |
| win:allowResize | -n | yes | Aallow the window to be manually resized |
| win:keepAspect | -r | yes | Maintain the correct aspect ratio |
| win:borderless | -d | no | Borderless mode |
| win:fullScreen | -F | no | Launch in fullscreen borderless mode |
| win:maximize | -T | no | Launch window maximized |
| win:fpsLimit | -K | 200 | Frame rate limit (0 = disable - not recommended) |
| win:showFPS | -k | no | Enable the FPS & UPS display |
| win:ignoreQuit | -Q | no | Ignore requests to quit (ie: Alt+F4) |
| win:noScreensaver | -S | no | Prevent the screensaver from starting |
| win:alerts | -q | yes | Show on screen alert messages |
|-------------------------------------------------------------------------------------------------------|
|-------------------------------------------------------------------------------------------------------------|
| Long | Short | Value | Description |
|-------------------------------------------------------------------------------------------------------------|
| win:title | | Looking Glass (client) | The window title |
| win:position | | center | Initial window position at startup |
| win:size | | 1024x768 | Initial window size at startup |
| win:autoResize | -a | no | Auto resize the window to the guest |
| win:allowResize | -n | yes | Aallow the window to be manually resized |
| win:keepAspect | -r | yes | Maintain the correct aspect ratio |
| win:borderless | -d | no | Borderless mode |
| win:fullScreen | -F | no | Launch in fullscreen borderless mode |
| win:maximize | -T | no | Launch window maximized |
| win:minimizeOnFocusLoss | | yes | Minimize window on focus loss |
| win:fpsLimit | -K | 200 | Frame rate limit (0 = disable - not recommended) |
| win:showFPS | -k | no | Enable the FPS & UPS display |
| win:ignoreQuit | -Q | no | Ignore requests to quit (ie: Alt+F4) |
| win:noScreensaver | -S | no | Prevent the screensaver from starting |
| win:alerts | -q | yes | Show on screen alert messages |
|-------------------------------------------------------------------------------------------------------------|
|---------------------------------------------------------------------------------------------------------------------------------------|
| Long | Short | Value | Description |

View File

@@ -56,6 +56,7 @@ struct EGL_Desktop
struct DesktopShader shader_yuv;
// internals
LG_Lock updateLock;
enum EGL_PixelFormat pixFmt;
unsigned int width, height;
unsigned int pitch;
@@ -140,6 +141,8 @@ bool egl_desktop_init(EGL_Desktop ** desktop)
egl_model_set_default((*desktop)->model);
egl_model_set_texture((*desktop)->model, (*desktop)->texture);
LG_LOCK_INIT((*desktop)->updateLock);
(*desktop)->kbNV = app_register_keybind(SDL_SCANCODE_N, egl_desktop_toggle_nv, *desktop);
(*desktop)->nvMax = option_get_int("egl", "nvGainMax");
@@ -165,6 +168,8 @@ void egl_desktop_free(EGL_Desktop ** desktop)
if (!*desktop)
return;
LG_LOCK_FREE((*desktop)->updateLock);
egl_texture_free(&(*desktop)->texture );
egl_shader_free (&(*desktop)->shader_generic.shader);
egl_shader_free (&(*desktop)->shader_yuv.shader );
@@ -180,6 +185,7 @@ bool egl_desktop_prepare_update(EGL_Desktop * desktop, const bool sourceChanged,
{
if (sourceChanged)
{
LG_LOCK(desktop->updateLock);
switch(format.type)
{
case FRAME_TYPE_BGRA:
@@ -204,24 +210,30 @@ bool egl_desktop_prepare_update(EGL_Desktop * desktop, const bool sourceChanged,
default:
DEBUG_ERROR("Unsupported frame format");
LG_UNLOCK(desktop->updateLock);
return false;
}
desktop->width = format.width;
desktop->height = format.height;
desktop->pitch = format.pitch;
desktop->data = data;
desktop->update = true;
/* defer the actual update as the format has changed and we need to issue GL commands first */
LG_UNLOCK(desktop->updateLock);
return true;
}
desktop->data = data;
desktop->update = true;
return true;
/* update the texture now */
return egl_texture_update(desktop->texture, data);
}
bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged)
void egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged)
{
if (sourceChanged)
{
LG_LOCK(desktop->updateLock);
if (!egl_texture_setup(
desktop->texture,
desktop->pixFmt,
@@ -232,27 +244,26 @@ bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged)
))
{
DEBUG_ERROR("Failed to setup the desktop texture");
return false;
LG_UNLOCK(desktop->updateLock);
return;
}
LG_UNLOCK(desktop->updateLock);
}
if (!desktop->update)
return true;
if (!egl_texture_update(desktop->texture, desktop->data))
if (desktop->update)
{
DEBUG_ERROR("Failed to update the desktop texture");
return false;
desktop->update = false;
egl_texture_update(desktop->texture, desktop->data);
}
desktop->update = false;
return true;
}
void 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)
{
if (!desktop->shader)
return;
return false;
if (egl_texture_process(desktop->texture) != EGL_TEX_STATUS_OK)
return false;
const struct DesktopShader * shader = desktop->shader;
egl_shader_use(shader->shader);
@@ -269,4 +280,5 @@ void egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, con
glUniform1i(shader->uNV, 0);
egl_model_render(desktop->model);
return true;
}

View File

@@ -29,5 +29,5 @@ bool egl_desktop_init(EGL_Desktop ** desktop);
void egl_desktop_free(EGL_Desktop ** desktop);
bool egl_desktop_prepare_update(EGL_Desktop * desktop, const bool sourceChanged, const LG_RendererFormat format, const uint8_t * data);
bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged);
void egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, const bool nearest);
void egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged);
bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, const bool nearest);

View File

@@ -318,9 +318,6 @@ bool egl_on_frame_event(void * opaque, const LG_RendererFormat format, const uin
return false;
}
if (!this->waitFadeTime)
this->waitFadeTime = microtime() + SPLASH_FADE_TIME;
return true;
}
@@ -493,8 +490,12 @@ bool egl_render(void * opaque, SDL_Window * window)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
egl_desktop_render(this->desktop, this->translateX, this->translateY, this->scaleX, this->scaleY, this->useNearest);
egl_cursor_render(this->cursor);
if (egl_desktop_render(this->desktop, this->translateX, this->translateY, this->scaleX, this->scaleY, this->useNearest))
{
if (!this->waitFadeTime)
this->waitFadeTime = microtime() + SPLASH_FADE_TIME;
egl_cursor_render(this->cursor);
}
if (!this->waitDone)
{
@@ -535,13 +536,9 @@ bool egl_render(void * opaque, SDL_Window * window)
eglSwapBuffers(this->display, this->surface);
// defer texture uploads until after the flip to avoid stalling
if (!egl_desktop_perform_update(this->desktop, this->sourceChanged))
{
DEBUG_ERROR("Failed to perform the desktop update");
return false;
}
this->sourceChanged = false;
egl_desktop_perform_update(this->desktop, this->sourceChanged);
this->sourceChanged = false;
return true;
}

View File

@@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <GL/gl.h>

View File

@@ -32,6 +32,7 @@ struct EGL_Texture
enum EGL_PixelFormat pixFmt;
size_t width, height;
bool streaming;
bool ready;
int textureCount;
GLuint textures[3];
@@ -44,10 +45,12 @@ struct EGL_Texture
bool hasPBO;
GLuint pbo[2];
int pboIndex;
bool needsUpdate;
int pboRIndex;
int pboWIndex;
int pboCount;
size_t pboBufferSize;
void * pboMap[2];
GLsync pboSync[2];
};
bool egl_texture_init(EGL_Texture ** texture)
@@ -81,6 +84,9 @@ void egl_texture_free(EGL_Texture ** texture)
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, (*texture)->pbo[i]);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
if ((*texture)->pboSync[i])
glDeleteSync((*texture)->pboSync[i]);
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glDeleteBuffers(2, (*texture)->pbo);
@@ -98,6 +104,7 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_
texture->width = width;
texture->height = height;
texture->streaming = streaming;
texture->ready = false;
switch(pixFmt)
{
@@ -210,8 +217,7 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_
texture->pboBufferSize,
NULL,
GL_MAP_PERSISTENT_BIT |
GL_MAP_WRITE_BIT |
GL_MAP_COHERENT_BIT
GL_MAP_WRITE_BIT
);
texture->pboMap[i] = glMapBufferRange(
@@ -221,7 +227,8 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_
GL_MAP_PERSISTENT_BIT |
GL_MAP_WRITE_BIT |
GL_MAP_UNSYNCHRONIZED_BIT |
GL_MAP_INVALIDATE_BUFFER_BIT
GL_MAP_INVALIDATE_BUFFER_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT
);
if (!texture->pboMap[i])
@@ -240,22 +247,23 @@ bool egl_texture_update(EGL_Texture * texture, const uint8_t * buffer)
{
if (texture->streaming)
{
if (texture->needsUpdate)
{
DEBUG_ERROR("Previous frame was not consumed");
return false;
}
/* NOTE: DO NOT use any gl commands here as streaming must be thread safe */
if (++texture->pboIndex == 2)
texture->pboIndex = 0;
if (texture->pboCount == 2)
return true;
/* update the GPU buffer */
memcpy(texture->pboMap[texture->pboIndex], buffer, texture->pboBufferSize);
memcpy(texture->pboMap[texture->pboWIndex], buffer, texture->pboBufferSize);
texture->pboSync[texture->pboWIndex] = 0;
texture->needsUpdate = true;
if (++texture->pboWIndex == 2)
texture->pboWIndex = 0;
++texture->pboCount;
}
else
{
/* Non streaming, this is NOT thread safe */
for(int i = 0; i < texture->textureCount; ++i)
{
glBindTexture(GL_TEXTURE_2D, texture->textures[i]);
@@ -268,23 +276,78 @@ bool egl_texture_update(EGL_Texture * texture, const uint8_t * buffer)
return true;
}
void egl_texture_bind(EGL_Texture * texture)
enum EGL_TexStatus egl_texture_process(EGL_Texture * texture)
{
if (texture->streaming && texture->needsUpdate)
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->pbo[texture->pboIndex]);
for(int i = 0; i < texture->textureCount; ++i)
{
glBindTexture(GL_TEXTURE_2D, texture->textures[i]);
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->planes[i][2]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->planes[i][0], texture->planes[i][1],
texture->format, texture->dataType, (const void *)texture->offsets[i]);
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
if (!texture->streaming)
return EGL_TEX_STATUS_OK;
texture->needsUpdate = false;
if (texture->pboCount == 0)
return texture->ready ? EGL_TEX_STATUS_OK : EGL_TEX_STATUS_NOTREADY;
/* process any buffers that have not yet been flushed */
int pos = texture->pboRIndex;
for(int i = 0; i < texture->pboCount; ++i)
{
if (texture->pboSync[pos] == 0)
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->pbo[pos]);
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, texture->pboBufferSize);
texture->pboSync[pos] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}
if (++pos == 2)
pos = 0;
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
/* wait for the buffer to be ready */
pos = texture->pboRIndex;
switch(glClientWaitSync(texture->pboSync[pos], GL_SYNC_FLUSH_COMMANDS_BIT, 0))
{
case GL_ALREADY_SIGNALED:
case GL_CONDITION_SATISFIED:
break;
case GL_TIMEOUT_EXPIRED:
return texture->ready ? EGL_TEX_STATUS_OK : EGL_TEX_STATUS_NOTREADY;
case GL_WAIT_FAILED:
glDeleteSync(texture->pboSync[pos]);
DEBUG_ERROR("glClientWaitSync failed");
return EGL_TEX_STATUS_ERROR;
}
/* delete the sync and bind the buffer */
glDeleteSync(texture->pboSync[pos]);
texture->pboSync[pos] = 0;
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->pbo[pos]);
/* update the textures */
for(int i = 0; i < texture->textureCount; ++i)
{
glBindTexture(GL_TEXTURE_2D, texture->textures[i]);
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->planes[i][2]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->planes[i][0], texture->planes[i][1],
texture->format, texture->dataType, (const void *)texture->offsets[i]);
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
/* advance the read index */
if (++texture->pboRIndex == 2)
texture->pboRIndex = 0;
--texture->pboCount;
texture->ready = true;
return EGL_TEX_STATUS_OK;
}
enum EGL_TexStatus egl_texture_bind(EGL_Texture * texture)
{
/* if there are no new buffers ready, then just bind the textures */
if (texture->streaming && !texture->ready)
return EGL_TEX_STATUS_NOTREADY;
for(int i = 0; i < texture->textureCount; ++i)
{
@@ -292,6 +355,8 @@ void egl_texture_bind(EGL_Texture * texture)
glBindTexture(GL_TEXTURE_2D, texture->textures[i]);
glBindSampler(i, texture->samplers[i]);
}
return EGL_TEX_STATUS_OK;
}
int egl_texture_count(EGL_Texture * texture)

View File

@@ -34,10 +34,18 @@ enum EGL_PixelFormat
EGL_PF_YUV420
};
enum EGL_TexStatus
{
EGL_TEX_STATUS_NOTREADY,
EGL_TEX_STATUS_OK,
EGL_TEX_STATUS_ERROR
};
bool egl_texture_init(EGL_Texture ** tex);
void egl_texture_free(EGL_Texture ** tex);
bool egl_texture_setup (EGL_Texture * texture, enum EGL_PixelFormat pixfmt, size_t width, size_t height, size_t stride, bool streaming);
bool egl_texture_update(EGL_Texture * texture, const uint8_t * buffer);
void egl_texture_bind (EGL_Texture * texture);
int egl_texture_count (EGL_Texture * texture);
bool egl_texture_setup (EGL_Texture * texture, enum EGL_PixelFormat pixfmt, size_t width, size_t height, size_t stride, bool streaming);
bool egl_texture_update (EGL_Texture * texture, const uint8_t * buffer);
enum EGL_TexStatus egl_texture_process(EGL_Texture * texture);
enum EGL_TexStatus egl_texture_bind (EGL_Texture * texture);
int egl_texture_count (EGL_Texture * texture);

View File

@@ -1 +0,0 @@
.

View File

@@ -17,7 +17,7 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "spice.h"
#include "spice/spice.h"
#include "utils.h"
#include "common/debug.h"

View File

@@ -66,7 +66,7 @@ KeybindHandle app_register_keybind(SDL_Scancode key, SuperEventFn callback, void
void app_release_keybind(KeybindHandle * handle)
{
if (!handle)
if (!*handle)
return;
state.bindings[(*handle)->key] = NULL;

View File

@@ -175,13 +175,20 @@ static struct Option options[] =
.type = OPTION_TYPE_BOOL,
.value.x_bool = false,
},
{
.module = "win",
.name = "minimizeOnFocusLoss",
.description = "Minimize window on focus loss",
.type = OPTION_TYPE_BOOL,
.value.x_bool = true,
},
{
.module = "win",
.name = "fpsLimit",
.description = "Frame rate limit (0 = disable - not recommended)",
.description = "Frame rate limit (0 = disable - not recommended, -1 = auto detect)",
.shortopt = 'K',
.type = OPTION_TYPE_INT,
.value.x_int = 200,
.value.x_int = -1,
},
{
.module = "win",
@@ -396,6 +403,8 @@ bool config_load(int argc, char * argv[])
params.hideMouse = option_get_bool ("input", "hideCursor" );
params.mouseSens = option_get_int ("input", "mouseSens" );
params.minimizeOnFocusLoss = option_get_bool("win", "minimizeOnFocusLoss");
if (option_get_bool("spice", "enable"))
{
params.spiceHost = option_get_string("spice", "host");
@@ -559,4 +568,4 @@ static char * optScancodeToString(struct Option * opt)
char * str;
alloc_sprintf(&str, "%d = %s", opt->value.x_int, SDL_GetScancodeName(opt->value.x_int));
return str;
}
}

View File

@@ -947,18 +947,48 @@ static void mouse_sens_dec(SDL_Scancode key, void * opaque)
free(msg);
}
static void ctrl_alt_fn(SDL_Scancode key, void * opaque)
{
const uint32_t ctrl = mapScancode(SDL_SCANCODE_LCTRL);
const uint32_t alt = mapScancode(SDL_SCANCODE_LALT );
const uint32_t fn = mapScancode(key);
spice_key_down(ctrl);
spice_key_down(alt );
spice_key_down(fn );
spice_key_up(ctrl);
spice_key_up(alt );
spice_key_up(fn );
}
static void register_key_binds()
{
state.kbFS = app_register_keybind(SDL_SCANCODE_F , toggle_fullscreen, NULL);
state.kbInput = app_register_keybind(SDL_SCANCODE_I , toggle_input , NULL);
state.kbMouseSensInc = app_register_keybind(SDL_SCANCODE_INSERT, mouse_sens_inc , NULL);
state.kbMouseSensDec = app_register_keybind(SDL_SCANCODE_DELETE, mouse_sens_dec , NULL);
state.kbCtrlAltFn[0 ] = app_register_keybind(SDL_SCANCODE_F1 , ctrl_alt_fn, NULL);
state.kbCtrlAltFn[1 ] = app_register_keybind(SDL_SCANCODE_F2 , ctrl_alt_fn, NULL);
state.kbCtrlAltFn[2 ] = app_register_keybind(SDL_SCANCODE_F3 , ctrl_alt_fn, NULL);
state.kbCtrlAltFn[3 ] = app_register_keybind(SDL_SCANCODE_F4 , ctrl_alt_fn, NULL);
state.kbCtrlAltFn[4 ] = app_register_keybind(SDL_SCANCODE_F5 , ctrl_alt_fn, NULL);
state.kbCtrlAltFn[5 ] = app_register_keybind(SDL_SCANCODE_F6 , ctrl_alt_fn, NULL);
state.kbCtrlAltFn[6 ] = app_register_keybind(SDL_SCANCODE_F7 , ctrl_alt_fn, NULL);
state.kbCtrlAltFn[7 ] = app_register_keybind(SDL_SCANCODE_F8 , ctrl_alt_fn, NULL);
state.kbCtrlAltFn[8 ] = app_register_keybind(SDL_SCANCODE_F9 , ctrl_alt_fn, NULL);
state.kbCtrlAltFn[9 ] = app_register_keybind(SDL_SCANCODE_F10, ctrl_alt_fn, NULL);
state.kbCtrlAltFn[10] = app_register_keybind(SDL_SCANCODE_F11, ctrl_alt_fn, NULL);
state.kbCtrlAltFn[11] = app_register_keybind(SDL_SCANCODE_F12, ctrl_alt_fn, NULL);
}
static void release_key_binds()
{
app_release_keybind(&state.kbFS);
app_release_keybind(&state.kbInput);
for(int i = 0; i < 12; ++i)
app_release_keybind(&state.kbCtrlAltFn[i]);
}
int run()
@@ -970,7 +1000,6 @@ int run()
state.running = true;
state.scaleX = 1.0f;
state.scaleY = 1.0f;
state.frameTime = 1e9 / params.fpsLimit;
state.mouseSens = params.mouseSens;
if (state.mouseSens < -9) state.mouseSens = -9;
@@ -984,13 +1013,16 @@ int run()
if (strcmp(XDG_SESSION_TYPE, "wayland") == 0)
{
DEBUG_INFO("Wayland detected");
int err = setenv("SDL_VIDEODRIVER", "wayland", 1);
if (err < 0)
if (getenv("SDL_VIDEODRIVER") == NULL)
{
DEBUG_ERROR("Unable to set the env variable SDL_VIDEODRIVER: %d", err);
return -1;
int err = setenv("SDL_VIDEODRIVER", "wayland", 1);
if (err < 0)
{
DEBUG_ERROR("Unable to set the env variable SDL_VIDEODRIVER: %d", err);
return -1;
}
DEBUG_INFO("SDL_VIDEODRIVER has been set to wayland");
}
DEBUG_INFO("SDL_VIDEODRIVER has been set to wayland");
}
// warn about using FPS display until we can fix the font rendering to prevent lag spikes
@@ -1069,11 +1101,14 @@ int run()
return 1;
}
if (params.fullscreen)
if (params.fullscreen || !params.minimizeOnFocusLoss)
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
if (!params.noScreensaver)
{
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1");
SDL_EnableScreenSaver();
}
if (!params.center)
SDL_SetWindowPosition(state.window, params.x, params.y);
@@ -1084,6 +1119,26 @@ int run()
// ensure renderer viewport is aware of the current window size
updatePositionInfo();
//Auto detect active monitor refresh rate for FPS Limit if no FPS Limit was passed.
if (params.fpsLimit == -1)
{
SDL_DisplayMode current;
if (SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(state.window), &current) == 0)
{
state.frameTime = 1e9 / (current.refresh_rate * 2);
}
else
{
DEBUG_WARN("Unable to capture monitor refresh rate using the default FPS Limit: 200");
state.frameTime = 1e9 / 200;
}
}
else
{
DEBUG_INFO("Using the FPS Limit from args: %d", params.fpsLimit);
state.frameTime = 1e9 / params.fpsLimit;
}
register_key_binds();
// set the compositor hint to bypass for low latency
@@ -1341,4 +1396,4 @@ int main(int argc, char * argv[])
config_free();
return ret;
}
}

View File

@@ -68,6 +68,7 @@ struct AppState
KeybindHandle kbInput;
KeybindHandle kbMouseSensInc;
KeybindHandle kbMouseSensDec;
KeybindHandle kbCtrlAltFn[12];
int mouseSens;
float sensX, sensY;
@@ -81,6 +82,7 @@ struct AppParams
bool borderless;
bool fullscreen;
bool maximize;
bool minimizeOnFocusLoss;
bool center;
int x, y;
unsigned int w, h;

View File

@@ -5,6 +5,10 @@ include_directories(
${PROJECT_SOURCE_DIR}/include
)
if(ENABLE_BACKTRACE)
add_definitions(-DENABLE_BACKTRACE)
endif()
set(COMMON_SOURCES
src/stringutils.c
src/stringlist.c
@@ -27,7 +31,9 @@ if(WIN32)
else()
set(SOURCES ${COMMON_SOURCES} ${LINUX_SOURCES})
add_library(lg_common STATIC ${SOURCES})
target_link_libraries(lg_common bfd)
if(ENABLE_BACKTRACE)
target_link_libraries(lg_common bfd)
endif()
endif()
target_include_directories(lg_common

View File

@@ -21,6 +21,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "common/crash.h"
#include "common/debug.h"
#if defined(ENABLE_BACKTRACE)
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
@@ -219,4 +221,13 @@ bool installCrashHandler(const char * exe)
}
return true;
}
}
#else //ENABLE_BACKTRACE
bool installCrashHandler(const char * exe)
{
return true;
}
#endif

View File

@@ -1,11 +1,13 @@
obj-m += kvmfr.o
USER := $(shell whoami)
KVER ?= $(shell uname -r)
KDIR ?= /lib/modules/$(KVER)/build
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
make -C $(KDIR) M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
make -C $(KDIR) M=$(PWD) clean
test: all
grep -q '^uio' /proc/modules || sudo modprobe uio

View File

@@ -1,8 +1,7 @@
PACKAGE_NAME=kvmfr
PACKAGE_VERSION=0.1
BUILT_MODULE_NAME[0]="$PACKAGE_NAME"
MAKE[0]="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build"
CLEAN="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build clean"
DEST_MODULE_LOCATION[0]=/extra
REMAKE_INITRD=yes
AUTOINSTALL=yes
PACKAGE_NAME="kvmfr"
PACKAGE_VERSION="0.0.1"
BUILT_MODULE_NAME[0]="${PACKAGE_NAME}"
MAKE[0]="make KDIR=${kernel_source_dir}"
CLEAN="make KDIR=${kernel_source_dir} clean"
DEST_MODULE_LOCATION[0]="/kernel/drivers/misc"
AUTOINSTALL="yes"

BIN
resources/icon-128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
resources/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB