This commit is contained in:
Ricardo Vieira 2016-04-27 16:53:05 +00:00
commit 858c32bee8
3 changed files with 230 additions and 13 deletions

View File

@ -28,6 +28,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <stdio.h> #include <stdio.h>
#include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -41,6 +42,76 @@ static inline int min(int n1, int n2)
return n1 < n2 ? n1 : n2; return n1 < n2 ? n1 : n2;
} }
static void dataOfferOffer(void* data,
struct wl_data_offer* offer,
const char* type)
{
if (_glfw.wl.dataOffer)
{
wl_data_offer_destroy(_glfw.wl.dataOffer);
_glfw.wl.dataOffer = NULL;
}
if (strcmp(type, _glfw.wl.clipboardMimeType) == 0)
{
_glfw.wl.dataOffer = offer;
}
}
static const struct wl_data_offer_listener dataOfferListener = {
dataOfferOffer,
};
static void dataDeviceHandleDataOffer(void* data,
struct wl_data_device* dataDevice,
struct wl_data_offer* offer)
{
wl_data_offer_add_listener(offer, &dataOfferListener, NULL);
}
static void dataDeviceHandleEnter(void* data,
struct wl_data_device* dataDevice,
uint32_t serial,
struct wl_surface *surface,
wl_fixed_t sx,
wl_fixed_t sf,
struct wl_data_offer *offer)
{
_glfw.wl.serial = serial;
}
static void dataDeviceHandleLeave(void *data,
struct wl_data_device* dataDevice)
{
}
static void dataDeviceHandleMotion(void *data,
struct wl_data_device* dataDevice,
uint32_t time,
wl_fixed_t sx,
wl_fixed_t sf)
{
}
static void dataDeviceHandleDrop(void *data,
struct wl_data_device* dataDevice)
{
}
static void dataDeviceHandleSelection(void *data,
struct wl_data_device *dataDevice,
struct wl_data_offer *offer)
{
}
static const struct wl_data_device_listener dataDeviceListener = {
dataDeviceHandleDataOffer,
dataDeviceHandleEnter,
dataDeviceHandleLeave,
dataDeviceHandleMotion,
dataDeviceHandleDrop,
dataDeviceHandleSelection
};
static void pointerHandleEnter(void* data, static void pointerHandleEnter(void* data,
struct wl_pointer* pointer, struct wl_pointer* pointer,
uint32_t serial, uint32_t serial,
@ -50,7 +121,7 @@ static void pointerHandleEnter(void* data,
{ {
_GLFWwindow* window = wl_surface_get_user_data(surface); _GLFWwindow* window = wl_surface_get_user_data(surface);
_glfw.wl.pointerSerial = serial; _glfw.wl.serial = serial;
_glfw.wl.pointerFocus = window; _glfw.wl.pointerFocus = window;
_glfwPlatformSetCursor(window, window->wl.currentCursor); _glfwPlatformSetCursor(window, window->wl.currentCursor);
@ -67,7 +138,7 @@ static void pointerHandleLeave(void* data,
if (!window) if (!window)
return; return;
_glfw.wl.pointerSerial = serial; _glfw.wl.serial = serial;
_glfw.wl.pointerFocus = NULL; _glfw.wl.pointerFocus = NULL;
_glfwInputCursorEnter(window, GLFW_FALSE); _glfwInputCursorEnter(window, GLFW_FALSE);
} }
@ -106,6 +177,8 @@ static void pointerHandleButton(void* data,
_GLFWwindow* window = _glfw.wl.pointerFocus; _GLFWwindow* window = _glfw.wl.pointerFocus;
int glfwButton; int glfwButton;
_glfw.wl.serial = serial;
if (!window) if (!window)
return; return;
@ -232,6 +305,7 @@ static void keyboardHandleEnter(void* data,
{ {
_GLFWwindow* window = wl_surface_get_user_data(surface); _GLFWwindow* window = wl_surface_get_user_data(surface);
_glfw.wl.serial = serial;
_glfw.wl.keyboardFocus = window; _glfw.wl.keyboardFocus = window;
_glfwInputWindowFocus(window, GLFW_TRUE); _glfwInputWindowFocus(window, GLFW_TRUE);
} }
@ -246,6 +320,7 @@ static void keyboardHandleLeave(void* data,
if (!window) if (!window)
return; return;
_glfw.wl.serial = serial;
_glfw.wl.keyboardFocus = NULL; _glfw.wl.keyboardFocus = NULL;
_glfwInputWindowFocus(window, GLFW_FALSE); _glfwInputWindowFocus(window, GLFW_FALSE);
} }
@ -272,6 +347,8 @@ static void keyboardHandleKey(void* data,
const xkb_keysym_t *syms; const xkb_keysym_t *syms;
_GLFWwindow* window = _glfw.wl.keyboardFocus; _GLFWwindow* window = _glfw.wl.keyboardFocus;
_glfw.wl.serial = serial;
if (!window) if (!window)
return; return;
@ -308,6 +385,8 @@ static void keyboardHandleModifiers(void* data,
xkb_mod_mask_t mask; xkb_mod_mask_t mask;
unsigned int modifiers = 0; unsigned int modifiers = 0;
_glfw.wl.serial = serial;
if (!_glfw.wl.xkb.keymap) if (!_glfw.wl.xkb.keymap)
return; return;
@ -422,6 +501,14 @@ static void registryHandleGlobal(void* data,
&zwp_pointer_constraints_v1_interface, &zwp_pointer_constraints_v1_interface,
1); 1);
} }
else if (strcmp(interface, "wl_data_device_manager") == 0)
{
_glfw.wl.dataDeviceManager =
wl_registry_bind(registry,
name,
&wl_data_device_manager_interface,
1);
}
} }
static void registryHandleGlobalRemove(void *data, static void registryHandleGlobalRemove(void *data,
@ -608,6 +695,17 @@ int _glfwPlatformInit(void)
_glfwInitTimerPOSIX(); _glfwInitTimerPOSIX();
if (_glfw.wl.dataDeviceManager && _glfw.wl.seat)
{
_glfw.wl.clipboardMimeType = "text/plain;charset=utf-8";
_glfw.wl.dataDevice =
wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
_glfw.wl.seat);
wl_data_device_add_listener(_glfw.wl.dataDevice,
&dataDeviceListener,
NULL);
}
if (_glfw.wl.pointer && _glfw.wl.shm) if (_glfw.wl.pointer && _glfw.wl.shm)
{ {
_glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm); _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm);
@ -630,6 +728,20 @@ void _glfwPlatformTerminate(void)
_glfwTerminateJoysticksLinux(); _glfwTerminateJoysticksLinux();
_glfwTerminateThreadLocalStoragePOSIX(); _glfwTerminateThreadLocalStoragePOSIX();
if (_glfw.wl.dataOffer)
wl_data_offer_destroy(_glfw.wl.dataOffer);
if (_glfw.wl.clipboardString)
free(_glfw.wl.clipboardString);
if (_glfw.wl.dataSource)
{
free(wl_data_source_get_user_data(_glfw.wl.dataSource));
wl_data_source_destroy(_glfw.wl.dataSource);
}
if (_glfw.wl.dataDevice)
wl_data_device_destroy(_glfw.wl.dataDevice);
if (_glfw.wl.dataDeviceManager)
wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager);
if (_glfw.wl.cursorTheme) if (_glfw.wl.cursorTheme)
wl_cursor_theme_destroy(_glfw.wl.cursorTheme); wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
if (_glfw.wl.cursorSurface) if (_glfw.wl.cursorSurface)

View File

@ -115,6 +115,7 @@ typedef struct _GLFWlibraryWayland
struct wl_shell* shell; struct wl_shell* shell;
struct wl_shm* shm; struct wl_shm* shm;
struct wl_seat* seat; struct wl_seat* seat;
struct wl_data_device_manager* dataDeviceManager;
struct wl_pointer* pointer; struct wl_pointer* pointer;
struct wl_keyboard* keyboard; struct wl_keyboard* keyboard;
struct zwp_relative_pointer_manager_v1* relativePointerManager; struct zwp_relative_pointer_manager_v1* relativePointerManager;
@ -122,9 +123,10 @@ typedef struct _GLFWlibraryWayland
int wl_compositor_version; int wl_compositor_version;
struct wl_data_device* dataDevice;
struct wl_cursor_theme* cursorTheme; struct wl_cursor_theme* cursorTheme;
struct wl_surface* cursorSurface; struct wl_surface* cursorSurface;
uint32_t pointerSerial; uint32_t serial;
_GLFWmonitor** monitors; _GLFWmonitor** monitors;
int monitorsCount; int monitorsCount;
@ -143,6 +145,11 @@ typedef struct _GLFWlibraryWayland
unsigned int modifiers; unsigned int modifiers;
} xkb; } xkb;
struct wl_data_offer* dataOffer;
struct wl_data_source* dataSource;
char* clipboardString;
const char* clipboardMimeType;
_GLFWwindow* pointerFocus; _GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus; _GLFWwindow* keyboardFocus;

View File

@ -40,6 +40,7 @@
#include <wayland-egl.h> #include <wayland-egl.h>
#include <wayland-cursor.h> #include <wayland-cursor.h>
#define BUFFER_LEN 500
static void handlePing(void* data, static void handlePing(void* data,
struct wl_shell_surface* shellSurface, struct wl_shell_surface* shellSurface,
@ -149,6 +150,43 @@ static const struct wl_surface_listener surfaceListener = {
handleLeave handleLeave
}; };
static void dataSourceTarget(void* data,
struct wl_data_source* source,
const char* mimeType)
{
}
static void dataSourceSend(void* data,
struct wl_data_source* source,
const char* mimeType,
int32_t fd)
{
ssize_t len;
char* string = wl_data_source_get_user_data(source);
do
{
len = write(fd, string, strlen(string));
string += len;
}
while(len < strlen(string));
}
static void dataSourceCancel(void* data,
struct wl_data_source* source)
{
if (_glfw.wl.dataSource == source)
_glfw.wl.dataSource = NULL;
free(wl_data_source_get_user_data(source));
wl_data_source_destroy(source);
}
static const struct wl_data_source_listener dataSourceListener = {
dataSourceTarget,
dataSourceSend,
dataSourceCancel
};
static GLFWbool createSurface(_GLFWwindow* window, static GLFWbool createSurface(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig) const _GLFWwndconfig* wndconfig)
{ {
@ -749,7 +787,7 @@ static void lockPointer(_GLFWwindow* window)
window->wl.pointerLock.relativePointer = relativePointer; window->wl.pointerLock.relativePointer = relativePointer;
window->wl.pointerLock.lockedPointer = lockedPointer; window->wl.pointerLock.lockedPointer = lockedPointer;
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
NULL, 0, 0); NULL, 0, 0);
} }
@ -801,7 +839,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
buffer = wl_cursor_image_get_buffer(image); buffer = wl_cursor_image_get_buffer(image);
if (!buffer) if (!buffer)
return; return;
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
surface, surface,
image->hotspot_x, image->hotspot_x,
image->hotspot_y); image->hotspot_y);
@ -812,7 +850,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
} }
else else
{ {
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
surface, surface,
cursor->wl.xhot, cursor->wl.xhot,
cursor->wl.yhot); cursor->wl.yhot);
@ -829,22 +867,82 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
} }
else if (window->cursorMode == GLFW_CURSOR_HIDDEN) else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
{ {
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, NULL, 0, 0);
NULL, 0, 0);
} }
} }
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{ {
// TODO if (!_glfw.wl.dataDevice)
fprintf(stderr, "_glfwPlatformSetClipboardString not implemented yet\n"); {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Clipboard could not be set."\
"Data device was not initialized");
return;
}
if (_glfw.wl.dataSource)
{
free(wl_data_source_get_user_data(_glfw.wl.dataSource));
wl_data_source_destroy(_glfw.wl.dataSource);
}
_glfw.wl.dataSource =
wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager);
wl_data_source_offer(_glfw.wl.dataSource,
_glfw.wl.clipboardMimeType);
wl_data_source_add_listener(_glfw.wl.dataSource,
&dataSourceListener,
strdup(string));
wl_data_device_set_selection(_glfw.wl.dataDevice,
_glfw.wl.dataSource,
_glfw.wl.serial);
} }
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
{ {
// TODO int32_t p[2];
fprintf(stderr, "_glfwPlatformGetClipboardString not implemented yet\n"); int len, allocatedLen = 0;
char *aux;
if (!_glfw.wl.dataOffer)
return NULL; return NULL;
if (pipe2(p, O_CLOEXEC) == -1)
return NULL;
wl_data_offer_receive(_glfw.wl.dataOffer,
_glfw.wl.clipboardMimeType,
p[1]);
close(p[1]);
_glfwPlatformWaitEvents();
if (_glfw.wl.clipboardString)
{
free(_glfw.wl.clipboardString);
_glfw.wl.clipboardString = NULL;
}
do
{
allocatedLen += BUFFER_LEN;
_glfw.wl.clipboardString =
realloc(_glfw.wl.clipboardString,
allocatedLen * sizeof(*_glfw.wl.clipboardString));
aux = _glfw.wl.clipboardString + (allocatedLen - BUFFER_LEN);
memset(aux, 0, BUFFER_LEN);
len = read(p[0], aux, BUFFER_LEN);
}
while (len == BUFFER_LEN);
close(p[0]);
if (len < 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Clipboard read error: %d", errno);
return NULL;
}
return _glfw.wl.clipboardString;
} }
char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count) char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count)