mirror of
https://github.com/glfw/glfw.git
synced 2024-12-01 14:27:13 +00:00
Wayland: Implement clipboard paste
This commit is contained in:
parent
3c4b9a7eef
commit
8b54e28c4e
@ -1196,6 +1196,14 @@ int _glfwPlatformInit(void)
|
|||||||
wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
|
wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
|
||||||
_glfw.wl.seat);
|
_glfw.wl.seat);
|
||||||
wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL);
|
wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL);
|
||||||
|
_glfw.wl.clipboardString = malloc(4096);
|
||||||
|
if (!_glfw.wl.clipboardString)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Unable to allocate clipboard memory");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
_glfw.wl.clipboardSize = 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@ -1285,6 +1293,9 @@ void _glfwPlatformTerminate(void)
|
|||||||
close(_glfw.wl.timerfd);
|
close(_glfw.wl.timerfd);
|
||||||
if (_glfw.wl.cursorTimerfd >= 0)
|
if (_glfw.wl.cursorTimerfd >= 0)
|
||||||
close(_glfw.wl.cursorTimerfd);
|
close(_glfw.wl.cursorTimerfd);
|
||||||
|
|
||||||
|
if (_glfw.wl.clipboardString)
|
||||||
|
free(_glfw.wl.clipboardString);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetVersionString(void)
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
|
@ -256,6 +256,8 @@ typedef struct _GLFWlibraryWayland
|
|||||||
int32_t keyboardRepeatDelay;
|
int32_t keyboardRepeatDelay;
|
||||||
int keyboardLastKey;
|
int keyboardLastKey;
|
||||||
int keyboardLastScancode;
|
int keyboardLastScancode;
|
||||||
|
char* clipboardString;
|
||||||
|
size_t clipboardSize;
|
||||||
int timerfd;
|
int timerfd;
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
@ -1576,14 +1576,89 @@ void _glfwPlatformSetClipboardString(const char* string)
|
|||||||
"Wayland: Clipboard setting not implemented yet");
|
"Wayland: Clipboard setting not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLFWbool growClipboardString(void)
|
||||||
|
{
|
||||||
|
char* clipboard = _glfw.wl.clipboardString;
|
||||||
|
|
||||||
|
clipboard = realloc(clipboard, _glfw.wl.clipboardSize * 2);
|
||||||
|
if (!clipboard)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Impossible to grow clipboard string");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
_glfw.wl.clipboardString = clipboard;
|
||||||
|
_glfw.wl.clipboardSize = _glfw.wl.clipboardSize * 2;
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetClipboardString(void)
|
const char* _glfwPlatformGetClipboardString(void)
|
||||||
{
|
{
|
||||||
// TODO
|
int fds[2];
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
int ret;
|
||||||
"Wayland: Clipboard getting not implemented yet");
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (!_glfw.wl.dataOffer)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"No clipboard data has been sent yet");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = pipe2(fds, O_CLOEXEC);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
// TODO: also report errno maybe?
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Impossible to create clipboard pipe fds");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_data_offer_receive(_glfw.wl.dataOffer, "text/plain;charset=utf-8", fds[1]);
|
||||||
|
close(fds[1]);
|
||||||
|
|
||||||
|
// XXX: this is a huge hack, this function shouldn’t be synchronous!
|
||||||
|
handleEvents(-1);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// Grow the clipboard if we need to paste something bigger, there is no
|
||||||
|
// shrink operation yet.
|
||||||
|
if (len + 4096 > _glfw.wl.clipboardSize)
|
||||||
|
{
|
||||||
|
if (!growClipboardString())
|
||||||
|
{
|
||||||
|
close(fds[0]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then read from the fd to the clipboard, handling all known errors.
|
||||||
|
ret = read(fds[0], _glfw.wl.clipboardString + len, 4096);
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
|
if (ret == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
// TODO: also report errno maybe.
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Impossible to read from clipboard fd");
|
||||||
|
close(fds[0]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
len += ret;
|
||||||
|
}
|
||||||
|
close(fds[0]);
|
||||||
|
if (len + 1 > _glfw.wl.clipboardSize)
|
||||||
|
{
|
||||||
|
if (!growClipboardString())
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
_glfw.wl.clipboardString[len] = '\0';
|
||||||
|
return _glfw.wl.clipboardString;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
{
|
{
|
||||||
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)
|
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)
|
||||||
|
Loading…
Reference in New Issue
Block a user