[ion/clipboard] Rework clipboard handling

Change the way the clipboard is fetched, so as to preserve the
Poincare/Python translation feature, and remove the cap on the length of
text being imported into the simulator.

Change-Id: I0f3e83c0c8aa4b64eb08d882aa6891b31f191e22
This commit is contained in:
Gabriel Ozouf
2020-10-26 18:06:16 +01:00
committed by Émilie Feral
parent 010b474f77
commit f66bde6d31
15 changed files with 88 additions and 44 deletions

View File

@@ -105,7 +105,12 @@ _mp_hal_input \
_mp_import_name \
_mp_parse_compile_execute \
_get_clipboard_text \
_set_clipboard_text \
__ZN3Ion9Clipboard24fetchFromSystemClipboardEPcm \
__ZN3Ion9Clipboard21sendToSystemClipboardEPKc \
__ZN3Ion9Clipboard4readEPcm \
__ZN3Ion9Clipboard5writeEPKc \
__ZN9Clipboard5storeEPKci \
__ZN9Clipboard10storedTextEv \
__ZN11LayoutField18privateHandleEventEN3Ion6Events5EventE \
__ZN11LayoutField11handleEventEN3Ion6Events5EventE \

View File

@@ -15,7 +15,10 @@ void Clipboard::store(const char * storedText, int length) {
}
const char * Clipboard::storedText() {
Ion::Clipboard::read(m_textBuffer, TextField::maxBufferSize());
const char * systemText = Ion::Clipboard::read();
if (systemText) {
return systemText;
}
/* In order to allow copy/paste of empty formulas, we need to add empty
* layouts between empty system parenthesis. This way, when the expression

View File

@@ -1,16 +1,15 @@
#ifndef ION_CLIPBOARD_H
#define ION_CLIPBOARD_H
#include <stddef.h>
namespace Ion {
namespace Clipboard {
/* Write the text to the system clipboard. */
void write(const char * text);
/* Fill the buffer with text from the system clipboard. */
void read(char * buffer, size_t bufferSize);
/* Returns the system's clipboard text if it differs from the text previously
* copied, and nullptr otherwise. */
const char * read();
}
}

View File

@@ -6,6 +6,6 @@ namespace Ion {
* On the device, the clipboard is fully handled by Escher::Clipboard. */
void Clipboard::write(const char * text) {}
void Clipboard::read(char * buffer, size_t bufferSize) {}
const char * Clipboard::read() { return nullptr; }
}

View File

@@ -8,6 +8,7 @@ ion_src += $(addprefix ion/src/simulator/shared/, \
dummy/serial_number.cpp \
dummy/stack.cpp \
dummy/usb.cpp \
clipboard.cpp \
console_stdio.cpp:-consoledisplay \
crc32.cpp \
display.cpp:-headless \

View File

@@ -6,7 +6,7 @@ ion_src += $(addprefix ion/src/simulator/android/src/cpp/, \
ion_src += $(addprefix ion/src/simulator/shared/, \
dummy/callback.cpp \
dummy/language.cpp \
clipboard.cpp \
clipboard_helper.cpp \
haptics.cpp \
)

View File

@@ -6,7 +6,7 @@ ion_src += $(addprefix ion/src/simulator/shared/, \
apple/language.m \
dummy/callback.cpp \
dummy/haptics_enabled.cpp \
clipboard.cpp \
clipboard_helper.cpp \
haptics.cpp \
)

View File

@@ -16,7 +16,7 @@ ion_src += $(addprefix ion/src/simulator/linux/, \
ion_src += $(addprefix ion/src/simulator/shared/, \
dummy/callback.cpp \
dummy/haptics_enabled.cpp \
clipboard.cpp \
clipboard_helper.cpp \
collect_registers_x86_64.s \
collect_registers.cpp \
haptics.cpp \

View File

@@ -6,7 +6,7 @@ ion_src += $(addprefix ion/src/simulator/shared/, \
apple/language.m \
dummy/callback.cpp \
dummy/haptics_enabled.cpp \
clipboard.cpp \
clipboard_helper.cpp \
collect_registers_x86_64.s \
collect_registers.cpp \
haptics.cpp \

View File

@@ -1,27 +1,33 @@
#include <ion/clipboard.h>
#include <SDL.h>
#include "clipboard_helper.h"
#include <ion.h>
#include <string.h>
/* This file implements the methods to access the system clipboard on all
* targets but the web simulator. */
namespace Ion {
namespace Clipboard {
void Clipboard::write(const char * text) {
uint32_t localClipboardVersion;
void write(const char * text) {
/* FIXME : Handle the error if need be. */
SDL_SetClipboardText(text);
sendToSystemClipboard(text);
localClipboardVersion = crc32Byte(reinterpret_cast<const uint8_t *>(text), strlen(text));
}
void Clipboard::read(char * buffer, size_t bufferSize) {
if (!SDL_HasClipboardText()) {
buffer[0] = '\0';
return;
const char * read() {
constexpr size_t bufferSize = 32768;
static char buffer[bufferSize];
fetchFromSystemClipboard(buffer, bufferSize);
if (buffer[0] == '\0') {
return nullptr;
}
char * text = SDL_GetClipboardText();
if (text) {
strlcpy(buffer, text, bufferSize);
SDL_free(text);
uint32_t version = crc32Byte(reinterpret_cast<const uint8_t *>(buffer), strlen(buffer));
if (version == localClipboardVersion) {
return nullptr;
}
return buffer;
}
}
}

View File

@@ -0,0 +1,28 @@
#include "clipboard_helper.h"
#include <SDL.h>
#include <string.h>
namespace Ion {
namespace Clipboard {
void sendToSystemClipboard(const char * text) {
SDL_SetClipboardText(text);
}
void fetchFromSystemClipboard(char * buffer, size_t bufferSize) {
if (!SDL_HasClipboardText()) {
buffer[0] = '\0';
return;
}
char * text = SDL_GetClipboardText();
if (text) {
strlcpy(buffer, text, bufferSize);
} else {
buffer[0] = '\0';
}
SDL_free(text);
}
}
}

View File

@@ -0,0 +1,15 @@
#ifndef ION_CLIPBOARD_HELPER_H
#define ION_CLIPBOARD_HELPER_H
#include <stddef.h>
namespace Ion {
namespace Clipboard {
void sendToSystemClipboard(const char * text);
void fetchFromSystemClipboard(char * buffer, size_t bufferSize);
}
}
#endif

View File

@@ -15,7 +15,7 @@ LDFLAGS += --pre-js ion/src/simulator/web/preamble_env.js
ion_src += $(addprefix ion/src/simulator/web/, \
callback.cpp \
clipboard.cpp \
clipboard_helper.cpp \
helpers.cpp \
)

View File

@@ -1,4 +1,4 @@
#include <ion/clipboard.h>
#include "../shared/clipboard_helper.h"
#include <emscripten.h>
#include <SDL.h>
#include <assert.h>
@@ -48,20 +48,17 @@ EM_JS(void, get_clipboard_text, (char * buffer, uint32_t bufferSize, AsyncStatus
});
namespace Ion {
namespace Clipboard {
void Clipboard::write(const char * text) {
/* FIXME : Handle the error if need be. */
void sendToSystemClipboard(const char * text) {
/* As the rest of the execution does not depend on the system clipboard being
* properly filled at this point, the call to set_clipboard_text does not
* need to be made synchronous. */
AsyncStatus lock;
set_clipboard_text(text, &lock, AsyncStatus::Failure, AsyncStatus::Success);
/* Store a local copy of the text in case the browser does not grant access
* to the clipboard. */
SDL_SetClipboardText(text);
}
void Clipboard::read(char * buffer, size_t bufferSize) {
void fetchFromSystemClipboard(char * buffer, size_t bufferSize) {
AsyncStatus lock = AsyncStatus::Pending;
static_assert(sizeof(size_t) <= sizeof(uint32_t), "Cast from size_t to uint32_t may overflow.");
get_clipboard_text(buffer, static_cast<uint32_t>(bufferSize), &lock, AsyncStatus::Failure, AsyncStatus::Success);
@@ -71,17 +68,7 @@ void Clipboard::read(char * buffer, size_t bufferSize) {
if (lock == AsyncStatus::Success) {
return;
}
/* If the browser does not grant access to the clipboard, read from a local
* copy to at least maintain the basic copy-paste functionnality. */
if (!SDL_HasClipboardText()) {
buffer[0] = '\0';
return;
}
char * text = SDL_GetClipboardText();
if (text) {
strlcpy(buffer, text, bufferSize);
SDL_free(text);
}
}
}
}

View File

@@ -7,7 +7,7 @@ ion_src += $(addprefix ion/src/simulator/windows/, \
ion_src += $(addprefix ion/src/simulator/shared/, \
dummy/callback.cpp \
dummy/haptics_enabled.cpp \
clipboard.cpp \
clipboard_helper.cpp \
haptics.cpp \
)