mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-10 08:38:20 +00:00
[client] wayland: implement cursor handling
This commit adds code to load the looking glass cursor and display it when needed. Otherwise, the cursor is hidden.
This commit is contained in:
parent
081d76268a
commit
265370b0f5
@ -17,6 +17,7 @@ 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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -54,6 +55,7 @@ struct WaylandDSState
|
|||||||
struct wl_surface * surface;
|
struct wl_surface * surface;
|
||||||
struct wl_registry * registry;
|
struct wl_registry * registry;
|
||||||
struct wl_seat * seat;
|
struct wl_seat * seat;
|
||||||
|
struct wl_shm * shm;
|
||||||
struct wl_compositor * compositor;
|
struct wl_compositor * compositor;
|
||||||
|
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
@ -68,6 +70,8 @@ struct WaylandDSState
|
|||||||
struct xdg_surface * xdgSurface;
|
struct xdg_surface * xdgSurface;
|
||||||
struct xdg_toplevel * xdgToplevel;
|
struct xdg_toplevel * xdgToplevel;
|
||||||
|
|
||||||
|
struct wl_surface * cursor;
|
||||||
|
|
||||||
struct wl_data_device_manager * dataDeviceManager;
|
struct wl_data_device_manager * dataDeviceManager;
|
||||||
struct wl_data_device * dataDevice;
|
struct wl_data_device * dataDevice;
|
||||||
|
|
||||||
@ -83,6 +87,8 @@ struct WaylandDSState
|
|||||||
struct zwp_pointer_constraints_v1 * pointerConstraints;
|
struct zwp_pointer_constraints_v1 * pointerConstraints;
|
||||||
struct zwp_relative_pointer_v1 * relativePointer;
|
struct zwp_relative_pointer_v1 * relativePointer;
|
||||||
struct zwp_confined_pointer_v1 * confinedPointer;
|
struct zwp_confined_pointer_v1 * confinedPointer;
|
||||||
|
bool showPointer;
|
||||||
|
uint32_t pointerEnterSerial;
|
||||||
|
|
||||||
struct zwp_idle_inhibit_manager_v1 * idleInhibitManager;
|
struct zwp_idle_inhibit_manager_v1 * idleInhibitManager;
|
||||||
struct zwp_idle_inhibitor_v1 * idleInhibitor;
|
struct zwp_idle_inhibitor_v1 * idleInhibitor;
|
||||||
@ -111,6 +117,49 @@ struct WCBState
|
|||||||
static struct WaylandDSState wm;
|
static struct WaylandDSState wm;
|
||||||
static struct WCBState wcb;
|
static struct WCBState wcb;
|
||||||
|
|
||||||
|
static const uint32_t cursorBitmap[] = {
|
||||||
|
0x000000, 0x000000, 0x000000, 0x000000,
|
||||||
|
0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000,
|
||||||
|
0x000000, 0xFFFFFF, 0xFFFFFF, 0x000000,
|
||||||
|
0x000000, 0x000000, 0x000000, 0x000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct wl_buffer * createCursorBuffer(void)
|
||||||
|
{
|
||||||
|
int fd = memfd_create("lg-cursor", 0);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to create cursor shared memory: %d", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_buffer * result = NULL;
|
||||||
|
|
||||||
|
if (ftruncate(fd, sizeof cursorBitmap) < 0)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to ftruncate cursor shared memory: %d", errno);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * shm_data = mmap(NULL, sizeof cursorBitmap, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (shm_data == MAP_FAILED)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to map memory for cursor: %d", errno);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_shm_pool * pool = wl_shm_create_pool(wm.shm, fd, sizeof cursorBitmap);
|
||||||
|
result = wl_shm_pool_create_buffer(pool, 0, 4, 4, 16, WL_SHM_FORMAT_XRGB8888);
|
||||||
|
wl_shm_pool_destroy(pool);
|
||||||
|
|
||||||
|
memcpy(shm_data, cursorBitmap, sizeof cursorBitmap);
|
||||||
|
munmap(shm_data, sizeof cursorBitmap);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
close(fd);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// XDG WM base listeners.
|
// XDG WM base listeners.
|
||||||
|
|
||||||
static void xdgWmBasePing(void * data, struct xdg_wm_base * xdgWmBase, uint32_t serial)
|
static void xdgWmBasePing(void * data, struct xdg_wm_base * xdgWmBase, uint32_t serial)
|
||||||
@ -129,6 +178,8 @@ static void registryGlobalHandler(void * data, struct wl_registry * registry,
|
|||||||
{
|
{
|
||||||
if (!strcmp(interface, wl_seat_interface.name) && !wm.seat)
|
if (!strcmp(interface, wl_seat_interface.name) && !wm.seat)
|
||||||
wm.seat = wl_registry_bind(wm.registry, name, &wl_seat_interface, 1);
|
wm.seat = wl_registry_bind(wm.registry, name, &wl_seat_interface, 1);
|
||||||
|
else if (!strcmp(interface, wl_shm_interface.name))
|
||||||
|
wm.shm = wl_registry_bind(wm.registry, name, &wl_shm_interface, 1);
|
||||||
else if (!strcmp(interface, wl_compositor_interface.name))
|
else if (!strcmp(interface, wl_compositor_interface.name))
|
||||||
wm.compositor = wl_registry_bind(wm.registry, name, &wl_compositor_interface, 4);
|
wm.compositor = wl_registry_bind(wm.registry, name, &wl_compositor_interface, 4);
|
||||||
else if (!strcmp(interface, xdg_wm_base_interface.name))
|
else if (!strcmp(interface, xdg_wm_base_interface.name))
|
||||||
@ -181,6 +232,9 @@ static void pointerEnterHandler(void * data, struct wl_pointer * pointer,
|
|||||||
{
|
{
|
||||||
app_handleEnterEvent(true);
|
app_handleEnterEvent(true);
|
||||||
|
|
||||||
|
wl_pointer_set_cursor(pointer, serial, wm.showPointer ? wm.cursor : NULL, 0, 0);
|
||||||
|
wm.pointerEnterSerial = serial;
|
||||||
|
|
||||||
if (wm.relativePointer)
|
if (wm.relativePointer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -456,6 +510,14 @@ static bool waylandInit(const LG_DSInitParams params)
|
|||||||
|
|
||||||
wl_surface_commit(wm.surface);
|
wl_surface_commit(wm.surface);
|
||||||
|
|
||||||
|
struct wl_buffer * cursorBuffer = createCursorBuffer();
|
||||||
|
if (cursorBuffer)
|
||||||
|
{
|
||||||
|
wm.cursor = wl_compositor_create_surface(wm.compositor);
|
||||||
|
wl_surface_attach(wm.cursor, cursorBuffer, 0, 0);
|
||||||
|
wl_surface_commit(wm.cursor);
|
||||||
|
}
|
||||||
|
|
||||||
wm.width = params.w;
|
wm.width = params.w;
|
||||||
wm.height = params.h;
|
wm.height = params.h;
|
||||||
|
|
||||||
@ -527,7 +589,8 @@ static void waylandGLSwapBuffers(void)
|
|||||||
|
|
||||||
static void waylandShowPointer(bool show)
|
static void waylandShowPointer(bool show)
|
||||||
{
|
{
|
||||||
// FIXME: implement.
|
wm.showPointer = show;
|
||||||
|
wl_pointer_set_cursor(wm.pointer, wm.pointerEnterSerial, show ? wm.cursor : NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void waylandWait(unsigned int time)
|
static void waylandWait(unsigned int time)
|
||||||
|
Loading…
Reference in New Issue
Block a user