mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 13:37:22 +00:00
[client] spice: fixed copying large amounts of text to the clipboard
This commit is contained in:
parent
4098db039e
commit
0dfa7425c1
@ -17,7 +17,6 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|||||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "spice.h"
|
#include "spice.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@ -118,6 +117,10 @@ struct Spice
|
|||||||
|
|
||||||
bool cbSupported;
|
bool cbSupported;
|
||||||
bool cbSelection;
|
bool cbSelection;
|
||||||
|
|
||||||
|
char *cbBuffer;
|
||||||
|
uint32_t cbRemain;
|
||||||
|
uint32_t cbSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
// globals
|
// globals
|
||||||
@ -140,9 +143,10 @@ bool spice_on_common_read (struct SpiceChannel * channel, SpiceMiniDataHe
|
|||||||
bool spice_on_main_channel_read ();
|
bool spice_on_main_channel_read ();
|
||||||
bool spice_on_inputs_channel_read();
|
bool spice_on_inputs_channel_read();
|
||||||
|
|
||||||
bool spice_agent_process ();
|
bool spice_agent_process (uint32_t dataSize);
|
||||||
bool spice_agent_connect ();
|
bool spice_agent_connect ();
|
||||||
bool spice_agent_send_caps(bool request);
|
bool spice_agent_send_caps(bool request);
|
||||||
|
bool spice_agent_on_clipboard();
|
||||||
|
|
||||||
// thread safe read/write methods
|
// thread safe read/write methods
|
||||||
bool spice_write_msg (struct SpiceChannel * channel, uint32_t type, const void * buffer, const ssize_t size);
|
bool spice_write_msg (struct SpiceChannel * channel, uint32_t type, const void * buffer, const ssize_t size);
|
||||||
@ -546,6 +550,15 @@ bool spice_on_main_channel_read()
|
|||||||
|
|
||||||
DEBUG_INFO("Spice agent disconnected, error: %u", error);
|
DEBUG_INFO("Spice agent disconnected, error: %u", error);
|
||||||
spice.hasAgent = false;
|
spice.hasAgent = false;
|
||||||
|
|
||||||
|
if (spice.cbBuffer)
|
||||||
|
{
|
||||||
|
free(spice.cbBuffer);
|
||||||
|
spice.cbBuffer = NULL;
|
||||||
|
spice.cbSize = 0;
|
||||||
|
spice.cbRemain = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,7 +573,7 @@ bool spice_on_main_channel_read()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!spice_agent_process())
|
if (!spice_agent_process(header.size))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("failed to process spice agent message");
|
DEBUG_ERROR("failed to process spice agent message");
|
||||||
spice_disconnect();
|
spice_disconnect();
|
||||||
@ -569,6 +582,22 @@ bool spice_on_main_channel_read()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (header.type == SPICE_MSG_MAIN_AGENT_TOKEN)
|
||||||
|
{
|
||||||
|
DEBUG_PROTO("SPICE_MSG_MAIN_AGENT_TOKEN");
|
||||||
|
|
||||||
|
uint32_t num_tokens;
|
||||||
|
if (!spice_read_nl(channel, &num_tokens, sizeof(num_tokens)))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("failed to read agent tokens");
|
||||||
|
spice_disconnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
spice.serverTokens = num_tokens;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_WARN("main channel unhandled message type %u", header.type);
|
DEBUG_WARN("main channel unhandled message type %u", header.type);
|
||||||
spice_discard_nl(channel, header.size);
|
spice_discard_nl(channel, header.size);
|
||||||
return true;
|
return true;
|
||||||
@ -871,8 +900,30 @@ bool spice_agent_connect()
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
bool spice_agent_process()
|
bool spice_agent_process(uint32_t dataSize)
|
||||||
{
|
{
|
||||||
|
if (spice.cbRemain)
|
||||||
|
{
|
||||||
|
const uint32_t r = spice.cbRemain > dataSize ? dataSize : spice.cbRemain;
|
||||||
|
if (!spice_read_nl(&spice.scMain, spice.cbBuffer + spice.cbSize, r))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("failed to read the clipboard data");
|
||||||
|
free(spice.cbBuffer);
|
||||||
|
spice.cbBuffer = NULL;
|
||||||
|
spice.cbRemain = 0;
|
||||||
|
spice.cbSize = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
spice.cbRemain -= r;
|
||||||
|
spice.cbSize += r;
|
||||||
|
|
||||||
|
if (spice.cbRemain == 0)
|
||||||
|
return spice_agent_on_clipboard();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
VDAgentMessage msg;
|
VDAgentMessage msg;
|
||||||
|
|
||||||
#pragma pack(push,1)
|
#pragma pack(push,1)
|
||||||
@ -888,6 +939,7 @@ bool spice_agent_process()
|
|||||||
DEBUG_ERROR("failed to read spice agent message");
|
DEBUG_ERROR("failed to read spice agent message");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
dataSize -= sizeof(msg);
|
||||||
|
|
||||||
if (msg.protocol != VD_AGENT_PROTOCOL)
|
if (msg.protocol != VD_AGENT_PROTOCOL)
|
||||||
{
|
{
|
||||||
@ -942,6 +994,7 @@ bool spice_agent_process()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
remaining -= sizeof(selection);
|
remaining -= sizeof(selection);
|
||||||
|
dataSize -= sizeof(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.type == VD_AGENT_CLIPBOARD_RELEASE)
|
if (msg.type == VD_AGENT_CLIPBOARD_RELEASE)
|
||||||
@ -959,6 +1012,7 @@ bool spice_agent_process()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
remaining -= sizeof(type);
|
remaining -= sizeof(type);
|
||||||
|
dataSize -= sizeof(type);
|
||||||
|
|
||||||
if (msg.type == VD_AGENT_CLIPBOARD)
|
if (msg.type == VD_AGENT_CLIPBOARD)
|
||||||
{
|
{
|
||||||
@ -969,29 +1023,33 @@ bool spice_agent_process()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * text = malloc(remaining + 1);
|
if (spice.cbBuffer)
|
||||||
if (!spice_read_nl(&spice.scMain, text, remaining))
|
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("failed to read the clipboard data");
|
DEBUG_ERROR("cbBuffer was never freed");
|
||||||
free(text);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
text[remaining] = '\0';
|
|
||||||
|
|
||||||
// dos2unix
|
spice.cbSize = 0;
|
||||||
char * out = malloc(remaining + 1);
|
spice.cbRemain = remaining;
|
||||||
char * p = out;
|
spice.cbBuffer = (char *)malloc(remaining);
|
||||||
for(uint32_t i = 0; i < remaining; ++i)
|
const uint32_t r = remaining > dataSize ? dataSize : remaining;
|
||||||
|
|
||||||
|
if (!spice_read_nl(&spice.scMain, spice.cbBuffer, r))
|
||||||
{
|
{
|
||||||
char c = text[i];
|
DEBUG_ERROR("failed to read the clipboard data");
|
||||||
if (c != '\r')
|
free(spice.cbBuffer);
|
||||||
*p++ = c;
|
spice.cbBuffer = NULL;
|
||||||
|
spice.cbRemain = 0;
|
||||||
|
spice.cbSize = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
*p = '\0';
|
|
||||||
SDL_SetClipboardText(out);
|
|
||||||
|
|
||||||
free(text);
|
spice.cbRemain -= r;
|
||||||
free(out);
|
spice.cbSize += r;
|
||||||
|
|
||||||
|
if (spice.cbRemain == 0)
|
||||||
|
return spice_agent_on_clipboard();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1051,6 +1109,29 @@ bool spice_agent_process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
bool spice_agent_on_clipboard()
|
||||||
|
{
|
||||||
|
// dos2unix
|
||||||
|
char * p = spice.cbBuffer;
|
||||||
|
for(uint32_t i = 0; i < spice.cbSize; ++i)
|
||||||
|
{
|
||||||
|
char c = spice.cbBuffer[i];
|
||||||
|
if (c != '\r')
|
||||||
|
*p++ = c;
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
SDL_SetClipboardText(spice.cbBuffer);
|
||||||
|
|
||||||
|
free(spice.cbBuffer);
|
||||||
|
spice.cbBuffer = NULL;
|
||||||
|
spice.cbSize = 0;
|
||||||
|
spice.cbRemain = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
bool spice_agent_send_caps(bool request)
|
bool spice_agent_send_caps(bool request)
|
||||||
|
Loading…
Reference in New Issue
Block a user