40#include <sys/timerfd.h>
44static int createTmpfileCloexec(
char* tmpname)
48 fd = mkostemp(tmpname, O_CLOEXEC);
75static int createAnonymousFile(off_t size)
77 static const char template[] =
"/glfw-shared-XXXXXX";
83#ifdef HAVE_MEMFD_CREATE
84 fd = memfd_create(
"glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
92 fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
95#elif defined(SHM_ANON)
96 fd = shm_open(SHM_ANON, O_RDWR | O_CLOEXEC, 0600);
100 path = getenv(
"XDG_RUNTIME_DIR");
107 name = calloc(strlen(path) +
sizeof(
template), 1);
109 strcat(name,
template);
111 fd = createTmpfileCloexec(name);
119 ret = ftruncate(fd, size);
121 ret = posix_fallocate(fd, 0, size);
132static struct wl_buffer* createShmBuffer(
const GLFWimage* image)
134 struct wl_shm_pool* pool;
135 struct wl_buffer* buffer;
136 int stride = image->
width * 4;
141 fd = createAnonymousFile(length);
145 "Wayland: Creating a buffer file for %d B failed: %s",
146 length, strerror(errno));
150 data = mmap(
NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
151 if (data == MAP_FAILED)
154 "Wayland: mmap failed: %s", strerror(errno));
159 pool = wl_shm_create_pool(
_glfw.wl.shm, fd, length);
162 unsigned char* source = (
unsigned char*) image->
pixels;
163 unsigned char* target = data;
164 for (i = 0; i < image->
width * image->
height; i++, source += 4)
166 unsigned int alpha = source[3];
168 *target++ = (
unsigned char) ((source[2] * alpha) / 255);
169 *target++ = (
unsigned char) ((source[1] * alpha) / 255);
170 *target++ = (
unsigned char) ((source[0] * alpha) / 255);
171 *target++ = (
unsigned char) alpha;
175 wl_shm_pool_create_buffer(pool, 0,
178 stride, WL_SHM_FORMAT_ARGB8888);
179 munmap(data, length);
180 wl_shm_pool_destroy(pool);
186 struct wl_surface* parent,
187 struct wl_buffer* buffer,
GLFWbool opaque,
189 int width,
int height)
191 struct wl_region* region;
193 decoration->
surface = wl_compositor_create_surface(
_glfw.wl.compositor);
195 wl_subcompositor_get_subsurface(
_glfw.wl.subcompositor,
197 wl_subsurface_set_position(decoration->
subsurface, x, y);
198 decoration->
viewport = wp_viewporter_get_viewport(
_glfw.wl.viewporter,
200 wp_viewport_set_destination(decoration->
viewport, width, height);
201 wl_surface_attach(decoration->
surface, buffer, 0, 0);
205 region = wl_compositor_create_region(
_glfw.wl.compositor);
206 wl_region_add(region, 0, 0, width, height);
207 wl_surface_set_opaque_region(decoration->
surface, region);
208 wl_surface_commit(decoration->
surface);
209 wl_region_destroy(region);
212 wl_surface_commit(decoration->
surface);
217 unsigned char data[] = { 224, 224, 224, 255 };
221 if (!
_glfw.wl.viewporter || !window->
decorated || window->wl.decorations.serverSide)
224 if (!window->wl.decorations.buffer)
225 window->wl.decorations.buffer = createShmBuffer(&image);
226 if (!window->wl.decorations.buffer)
229 createDecoration(&window->wl.decorations.top, window->wl.surface,
230 window->wl.decorations.buffer, opaque,
233 createDecoration(&window->wl.decorations.left, window->wl.surface,
234 window->wl.decorations.buffer, opaque,
237 createDecoration(&window->wl.decorations.right, window->wl.surface,
238 window->wl.decorations.buffer, opaque,
241 createDecoration(&window->wl.decorations.bottom, window->wl.surface,
242 window->wl.decorations.buffer, opaque,
250 wl_subsurface_destroy(decoration->
subsurface);
252 wl_surface_destroy(decoration->
surface);
254 wp_viewport_destroy(decoration->
viewport);
262 destroyDecoration(&window->wl.decorations.top);
263 destroyDecoration(&window->wl.decorations.left);
264 destroyDecoration(&window->wl.decorations.right);
265 destroyDecoration(&window->wl.decorations.bottom);
268static void xdgDecorationHandleConfigure(
void* data,
269 struct zxdg_toplevel_decoration_v1* decoration,
274 window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
276 if (!window->wl.decorations.serverSide)
277 createDecorations(window);
280static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = {
281 xdgDecorationHandleConfigure,
287 struct wl_region* region;
289 region = wl_compositor_create_region(
_glfw.wl.compositor);
293 wl_region_add(region, 0, 0, window->wl.width, window->wl.height);
294 wl_surface_set_opaque_region(window->wl.surface, region);
295 wl_surface_commit(window->wl.surface);
296 wl_region_destroy(region);
302 int scale = window->wl.
scale;
303 int scaledWidth = window->wl.width * scale;
304 int scaledHeight = window->wl.height * scale;
306 if (!window->wl.transparent)
307 setOpaqueRegion(window);
311 if (!window->wl.decorations.top.surface)
315 wp_viewport_set_destination(window->wl.decorations.top.viewport,
317 wl_surface_commit(window->wl.decorations.top.surface);
320 wp_viewport_set_destination(window->wl.decorations.left.viewport,
322 wl_surface_commit(window->wl.decorations.left.surface);
325 wl_subsurface_set_position(window->wl.decorations.right.subsurface,
327 wp_viewport_set_destination(window->wl.decorations.right.viewport,
329 wl_surface_commit(window->wl.decorations.right.surface);
332 wl_subsurface_set_position(window->wl.decorations.bottom.subsurface,
334 wp_viewport_set_destination(window->wl.decorations.bottom.viewport,
336 wl_surface_commit(window->wl.decorations.bottom.surface);
346 if (
_glfw.wl.compositorVersion < 3)
350 for (i = 0; i < window->wl.monitorsCount; ++i)
352 monitorScale = window->wl.monitors[i]->wl.
scale;
353 if (scale < monitorScale)
354 scale = monitorScale;
358 if (scale != window->wl.
scale)
360 window->wl.
scale = scale;
361 wl_surface_set_buffer_scale(window->wl.surface, scale);
362 resizeWindow(window);
366static void surfaceHandleEnter(
void *data,
367 struct wl_surface *surface,
368 struct wl_output *output)
371 _GLFWmonitor* monitor = wl_output_get_user_data(output);
373 if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)
375 ++window->wl.monitorsSize;
376 window->wl.monitors =
377 realloc(window->wl.monitors,
381 window->wl.monitors[window->wl.monitorsCount++] = monitor;
383 checkScaleChange(window);
386static void surfaceHandleLeave(
void *data,
387 struct wl_surface *surface,
388 struct wl_output *output)
391 _GLFWmonitor* monitor = wl_output_get_user_data(output);
395 for (i = 0, found =
GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
397 if (monitor == window->wl.monitors[i])
400 window->wl.monitors[i] = window->wl.monitors[i + 1];
402 window->wl.monitors[--window->wl.monitorsCount] =
NULL;
404 checkScaleChange(window);
407static const struct wl_surface_listener surfaceListener = {
414 if (enable && !window->wl.idleInhibitor &&
_glfw.wl.idleInhibitManager)
416 window->wl.idleInhibitor =
417 zwp_idle_inhibit_manager_v1_create_inhibitor(
418 _glfw.wl.idleInhibitManager, window->wl.surface);
419 if (!window->wl.idleInhibitor)
421 "Wayland: Idle inhibitor creation failed");
423 else if (!enable && window->wl.idleInhibitor)
425 zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);
426 window->wl.idleInhibitor =
NULL;
433 window->wl.surface = wl_compositor_create_surface(
_glfw.wl.compositor);
434 if (!window->wl.surface)
437 wl_surface_add_listener(window->wl.surface,
441 wl_surface_set_user_data(window->wl.surface, window);
446 if (!window->wl.native)
449 window->wl.width = wndconfig->
width;
450 window->wl.height = wndconfig->
height;
451 window->wl.
scale = 1;
453 if (!window->wl.transparent)
454 setOpaqueRegion(window);
462 if (window->wl.xdg.toplevel)
464 xdg_toplevel_set_fullscreen(
465 window->wl.xdg.toplevel,
469 if (!window->wl.decorations.serverSide)
470 destroyDecorations(window);
473static void xdgToplevelHandleConfigure(
void* data,
474 struct xdg_toplevel* toplevel,
477 struct wl_array* states)
487 wl_array_for_each(state, states)
491 case XDG_TOPLEVEL_STATE_MAXIMIZED:
494 case XDG_TOPLEVEL_STATE_FULLSCREEN:
497 case XDG_TOPLEVEL_STATE_RESIZING:
499 case XDG_TOPLEVEL_STATE_ACTIVATED:
505 if (width != 0 && height != 0)
507 if (!maximized && !fullscreen)
511 aspectRatio = (float)width / (
float)height;
512 targetRatio = (float)window->
numer / (
float)window->
denom;
513 if (aspectRatio < targetRatio)
514 height = width / targetRatio;
515 else if (aspectRatio > targetRatio)
516 width = height * targetRatio;
525 if (window->wl.wasFullscreen && window->
autoIconify)
527 if (!activated || !fullscreen)
533 if (fullscreen && activated)
538static void xdgToplevelHandleClose(
void* data,
539 struct xdg_toplevel* toplevel)
545static const struct xdg_toplevel_listener xdgToplevelListener = {
546 xdgToplevelHandleConfigure,
547 xdgToplevelHandleClose
550static void xdgSurfaceHandleConfigure(
void* data,
551 struct xdg_surface* surface,
554 xdg_surface_ack_configure(surface, serial);
557static const struct xdg_surface_listener xdgSurfaceListener = {
558 xdgSurfaceHandleConfigure
563 if (
_glfw.wl.decorationManager)
565 window->wl.xdg.decoration =
566 zxdg_decoration_manager_v1_get_toplevel_decoration(
567 _glfw.wl.decorationManager, window->wl.xdg.toplevel);
568 zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration,
569 &xdgDecorationListener,
571 zxdg_toplevel_decoration_v1_set_mode(
572 window->wl.xdg.decoration,
573 ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
577 window->wl.decorations.serverSide =
GLFW_FALSE;
578 createDecorations(window);
584 window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(
_glfw.wl.wmBase,
586 if (!window->wl.xdg.surface)
589 "Wayland: xdg-surface creation failed");
593 xdg_surface_add_listener(window->wl.xdg.surface,
597 window->wl.xdg.toplevel = xdg_surface_get_toplevel(window->wl.xdg.surface);
598 if (!window->wl.xdg.toplevel)
601 "Wayland: xdg-toplevel creation failed");
605 xdg_toplevel_add_listener(window->wl.xdg.toplevel,
606 &xdgToplevelListener,
609 if (window->wl.title)
610 xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title);
613 xdg_toplevel_set_min_size(window->wl.xdg.toplevel,
616 xdg_toplevel_set_max_size(window->wl.xdg.toplevel,
621 xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel,
625 else if (window->wl.maximized)
627 xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
629 setXdgDecorations(window);
634 setXdgDecorations(window);
637 wl_surface_commit(window->wl.surface);
638 wl_display_roundtrip(
_glfw.wl.display);
646 struct itimerspec timer = {};
649 struct wl_buffer* buffer;
650 struct wl_surface* surface =
_glfw.wl.cursorSurface;
654 buffer = cursorWayland->
buffer;
668 timer.it_value.tv_sec = image->
delay / 1000;
669 timer.it_value.tv_nsec = (image->
delay % 1000) * 1000000;
670 timerfd_settime(
_glfw.wl.cursorTimerfd, 0, &timer,
NULL);
678 wl_pointer_set_cursor(
_glfw.wl.pointer,
_glfw.wl.serial,
680 cursorWayland->
xhot / scale,
681 cursorWayland->
yhot / scale);
682 wl_surface_set_buffer_scale(surface, scale);
683 wl_surface_attach(surface, buffer, 0, 0);
684 wl_surface_damage(surface, 0, 0,
686 wl_surface_commit(surface);
689static void incrementCursorImage(
_GLFWwindow* window)
696 cursor = window->wl.currentCursor;
697 if (cursor && cursor->wl.cursor)
699 cursor->wl.currentImage += 1;
700 cursor->wl.currentImage %= cursor->wl.cursor->image_count;
701 setCursorImage(window, &cursor->wl);
705static void handleEvents(
int timeout)
707 struct wl_display* display =
_glfw.wl.display;
708 struct pollfd fds[] = {
709 { wl_display_get_fd(display), POLLIN },
710 {
_glfw.wl.timerfd, POLLIN },
711 {
_glfw.wl.cursorTimerfd, POLLIN },
716 while (wl_display_prepare_read(display) != 0)
717 wl_display_dispatch_pending(display);
722 if (wl_display_flush(display) < 0 && errno != EAGAIN)
728 window = window->
next;
730 wl_display_cancel_read(display);
734 if (poll(fds, 3, timeout) > 0)
736 if (fds[0].revents & POLLIN)
738 wl_display_read_events(display);
739 wl_display_dispatch_pending(display);
743 wl_display_cancel_read(display);
746 if (fds[1].revents & POLLIN)
748 read_ret = read(
_glfw.wl.timerfd, &repeats,
sizeof(repeats));
752 if (
_glfw.wl.keyboardFocus)
754 for (i = 0; i < repeats; ++i)
757 _glfw.wl.keyboardLastKey,
758 _glfw.wl.keyboardLastScancode,
760 _glfw.wl.xkb.modifiers);
765 if (fds[2].revents & POLLIN)
767 read_ret = read(
_glfw.wl.cursorTimerfd, &repeats,
sizeof(repeats));
771 incrementCursorImage(
_glfw.wl.pointerFocus);
776 wl_display_cancel_read(display);
791 if (!createSurface(window, wndconfig))
813 if (wndconfig->
title)
818 if (!createXdgSurface(window))
825 window->wl.xdg.surface =
NULL;
826 window->wl.xdg.toplevel =
NULL;
830 window->wl.currentCursor =
NULL;
833 window->wl.monitorsCount = 0;
834 window->wl.monitorsSize = 1;
841 if (window ==
_glfw.wl.pointerFocus)
846 if (window ==
_glfw.wl.keyboardFocus)
852 if (window->wl.idleInhibitor)
853 zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);
858 destroyDecorations(window);
859 if (window->wl.xdg.decoration)
860 zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
862 if (window->wl.decorations.buffer)
863 wl_buffer_destroy(window->wl.decorations.buffer);
865 if (window->wl.native)
868 if (window->wl.xdg.toplevel)
869 xdg_toplevel_destroy(window->wl.xdg.toplevel);
871 if (window->wl.xdg.surface)
872 xdg_surface_destroy(window->wl.xdg.surface);
874 if (window->wl.surface)
875 wl_surface_destroy(window->wl.surface);
877 free(window->wl.title);
878 free(window->wl.monitors);
883 if (window->wl.title)
884 free(window->wl.title);
886 if (window->wl.xdg.toplevel)
887 xdg_toplevel_set_title(window->wl.xdg.toplevel, title);
894 "Wayland: The platform does not support setting the window icon");
903 "Wayland: The platform does not provide the window position");
911 "Wayland: The platform does not support setting the window position");
917 *width = window->wl.width;
919 *height = window->wl.height;
924 window->wl.width = width;
925 window->wl.height = height;
926 resizeWindow(window);
930 int minwidth,
int minheight,
931 int maxwidth,
int maxheight)
933 if (window->wl.xdg.toplevel)
936 minwidth = minheight = 0;
938 maxwidth = maxheight = 0;
939 xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight);
940 xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight);
941 wl_surface_commit(window->wl.surface);
946 int numer,
int denom)
951 "Wayland: Window aspect ratio not yet implemented");
955 int* width,
int* height)
959 *width *= window->wl.
scale;
961 *height *= window->wl.
scale;
966 int* right,
int* bottom)
968 if (window->
decorated && !window->
monitor && !window->wl.decorations.serverSide)
982 float* xscale,
float* yscale)
985 *xscale = (float) window->wl.
scale;
987 *yscale = (float) window->wl.
scale;
992 if (window->wl.xdg.toplevel)
993 xdg_toplevel_set_minimized(window->wl.xdg.toplevel);
998 if (window->wl.xdg.toplevel)
1001 xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
1002 if (window->wl.maximized)
1003 xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
1013 if (window->wl.xdg.toplevel)
1015 xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
1022 if (!window->wl.visible)
1024 createXdgSurface(window);
1031 if (window->wl.xdg.toplevel)
1033 xdg_toplevel_destroy(window->wl.xdg.toplevel);
1034 xdg_surface_destroy(window->wl.xdg.surface);
1035 window->wl.xdg.toplevel =
NULL;
1036 window->wl.xdg.surface =
NULL;
1045 "Wayland: Window attention request not implemented yet");
1051 "Wayland: The platform does not support setting the input focus");
1057 int width,
int height,
1062 setFullscreen(window, monitor, refreshRate);
1066 if (window->wl.xdg.toplevel)
1067 xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
1069 if (!
_glfw.wl.decorationManager)
1070 createDecorations(window);
1077 return _glfw.wl.keyboardFocus == window;
1089 return window->wl.visible;
1094 return window->wl.maximized;
1099 return window->wl.hovered;
1104 return window->wl.transparent;
1111 "Wayland: Window attribute setting not implemented yet");
1119 createDecorations(window);
1121 destroyDecorations(window);
1129 "Wayland: Window attribute setting not implemented yet");
1136 struct wl_region* region = wl_compositor_create_region(
_glfw.wl.compositor);
1137 wl_surface_set_input_region(window->wl.surface, region);
1138 wl_region_destroy(region);
1141 wl_surface_set_input_region(window->wl.surface, 0);
1142 wl_surface_commit(window->wl.surface);
1153 "Wayland: The platform does not support setting the window opacity");
1178 handleEvents((
int) (timeout * 1e3));
1183 wl_display_sync(
_glfw.wl.display);
1189 *xpos = window->wl.cursorPosX;
1191 *ypos = window->wl.cursorPosY;
1198 if (isPointerLocked(window))
1200 zwp_locked_pointer_v1_set_cursor_position_hint(
1201 window->wl.pointerLock.lockedPointer,
1202 wl_fixed_from_double(x), wl_fixed_from_double(y));
1203 wl_surface_commit(window->wl.surface);
1216 "Wayland: Key names not yet implemented");
1222 return _glfw.wl.scancodes[key];
1229 cursor->wl.buffer = createShmBuffer(image);
1230 if (!cursor->wl.buffer)
1233 cursor->wl.width = image->
width;
1234 cursor->wl.height = image->
height;
1235 cursor->wl.xhot = xhot;
1236 cursor->wl.yhot = yhot;
1242 const char* name =
NULL;
1266 name =
"nwse-resize";
1269 name =
"nesw-resize";
1272 name =
"all-scroll";
1275 name =
"not-allowed";
1281 if (
_glfw.wl.cursorThemeHiDPI)
1283 cursor->wl.cursorHiDPI =
1287 if (!cursor->wl.cursor)
1301 name =
"sb_h_double_arrow";
1303 name =
"sb_v_double_arrow";
1308 "Wayland: Standard cursor shape unavailable");
1313 if (!cursor->wl.cursor)
1316 "Wayland: Failed to create standard cursor \"%s\"",
1321 if (
_glfw.wl.cursorThemeHiDPI)
1323 if (!cursor->wl.cursorHiDPI)
1325 cursor->wl.cursorHiDPI =
1337 if (cursor->wl.cursor)
1340 if (cursor->wl.buffer)
1341 wl_buffer_destroy(cursor->wl.buffer);
1344static void relativePointerHandleRelativeMotion(
void* data,
1345 struct zwp_relative_pointer_v1* pointer,
1350 wl_fixed_t dxUnaccel,
1351 wl_fixed_t dyUnaccel)
1362 xpos += wl_fixed_to_double(dxUnaccel);
1363 ypos += wl_fixed_to_double(dyUnaccel);
1367 xpos += wl_fixed_to_double(dx);
1368 ypos += wl_fixed_to_double(dy);
1374static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
1375 relativePointerHandleRelativeMotion
1378static void lockedPointerHandleLocked(
void* data,
1379 struct zwp_locked_pointer_v1* lockedPointer)
1385 struct zwp_relative_pointer_v1* relativePointer =
1386 window->wl.pointerLock.relativePointer;
1387 struct zwp_locked_pointer_v1* lockedPointer =
1388 window->wl.pointerLock.lockedPointer;
1390 zwp_relative_pointer_v1_destroy(relativePointer);
1391 zwp_locked_pointer_v1_destroy(lockedPointer);
1393 window->wl.pointerLock.relativePointer =
NULL;
1394 window->wl.pointerLock.lockedPointer =
NULL;
1399static void lockedPointerHandleUnlocked(
void* data,
1400 struct zwp_locked_pointer_v1* lockedPointer)
1404static const struct zwp_locked_pointer_v1_listener lockedPointerListener = {
1405 lockedPointerHandleLocked,
1406 lockedPointerHandleUnlocked
1411 struct zwp_relative_pointer_v1* relativePointer;
1412 struct zwp_locked_pointer_v1* lockedPointer;
1414 if (!
_glfw.wl.relativePointerManager)
1417 "Wayland: no relative pointer manager");
1422 zwp_relative_pointer_manager_v1_get_relative_pointer(
1423 _glfw.wl.relativePointerManager,
1425 zwp_relative_pointer_v1_add_listener(relativePointer,
1426 &relativePointerListener,
1430 zwp_pointer_constraints_v1_lock_pointer(
1431 _glfw.wl.pointerConstraints,
1435 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
1436 zwp_locked_pointer_v1_add_listener(lockedPointer,
1437 &lockedPointerListener,
1440 window->wl.pointerLock.relativePointer = relativePointer;
1441 window->wl.pointerLock.lockedPointer = lockedPointer;
1443 wl_pointer_set_cursor(
_glfw.wl.pointer,
_glfw.wl.serial,
1449 return window->wl.pointerLock.lockedPointer !=
NULL;
1457 if (!
_glfw.wl.pointer)
1460 window->wl.currentCursor = cursor;
1469 unlockPointer(window);
1474 setCursorImage(window, &cursor->wl);
1482 "Wayland: Standard cursor not found");
1485 if (
_glfw.wl.cursorThemeHiDPI)
1486 defaultCursorHiDPI =
1497 setCursorImage(window, &cursorWayland);
1502 if (!isPointerLocked(window))
1503 lockPointer(window);
1507 wl_pointer_set_cursor(
_glfw.wl.pointer,
_glfw.wl.serial,
NULL, 0, 0);
1511static void dataSourceHandleTarget(
void* data,
1512 struct wl_data_source* dataSource,
1513 const char* mimeType)
1515 if (
_glfw.wl.dataSource != dataSource)
1518 "Wayland: Unknown clipboard data source");
1523static void dataSourceHandleSend(
void* data,
1524 struct wl_data_source* dataSource,
1525 const char* mimeType,
1528 const char*
string =
_glfw.wl.clipboardSendString;
1529 size_t len =
_glfw.wl.clipboardSendSize;
1532 if (
_glfw.wl.dataSource != dataSource)
1535 "Wayland: Unknown clipboard data source");
1542 "Wayland: Copy requested from an invalid string");
1546 if (strcmp(mimeType,
"text/plain;charset=utf-8") != 0)
1549 "Wayland: Wrong MIME type asked from clipboard");
1556 ret = write(fd,
string, len);
1557 if (ret == -1 && errno == EINTR)
1563 "Wayland: Error while writing the clipboard");
1572static void dataSourceHandleCancelled(
void* data,
1573 struct wl_data_source* dataSource)
1575 wl_data_source_destroy(dataSource);
1577 if (
_glfw.wl.dataSource != dataSource)
1580 "Wayland: Unknown clipboard data source");
1587static const struct wl_data_source_listener dataSourceListener = {
1588 dataSourceHandleTarget,
1589 dataSourceHandleSend,
1590 dataSourceHandleCancelled,
1595 if (
_glfw.wl.dataSource)
1597 wl_data_source_destroy(
_glfw.wl.dataSource);
1601 if (
_glfw.wl.clipboardSendString)
1603 free(
_glfw.wl.clipboardSendString);
1607 _glfw.wl.clipboardSendString = strdup(
string);
1608 if (!
_glfw.wl.clipboardSendString)
1611 "Wayland: Impossible to allocate clipboard string");
1614 _glfw.wl.clipboardSendSize = strlen(
string);
1615 _glfw.wl.dataSource =
1616 wl_data_device_manager_create_data_source(
_glfw.wl.dataDeviceManager);
1617 if (!
_glfw.wl.dataSource)
1620 "Wayland: Impossible to create clipboard source");
1621 free(
_glfw.wl.clipboardSendString);
1624 wl_data_source_add_listener(
_glfw.wl.dataSource,
1625 &dataSourceListener,
1627 wl_data_source_offer(
_glfw.wl.dataSource,
"text/plain;charset=utf-8");
1628 wl_data_device_set_selection(
_glfw.wl.dataDevice,
1629 _glfw.wl.dataSource,
1633static GLFWbool growClipboardString(
void)
1635 char* clipboard =
_glfw.wl.clipboardString;
1637 clipboard = realloc(clipboard,
_glfw.wl.clipboardSize * 2);
1641 "Wayland: Impossible to grow clipboard string");
1644 _glfw.wl.clipboardString = clipboard;
1645 _glfw.wl.clipboardSize =
_glfw.wl.clipboardSize * 2;
1655 if (!
_glfw.wl.dataOffer)
1658 "No clipboard data has been sent yet");
1662 ret = pipe2(fds, O_CLOEXEC);
1667 "Wayland: Impossible to create clipboard pipe fds");
1671 wl_data_offer_receive(
_glfw.wl.dataOffer,
"text/plain;charset=utf-8", fds[1]);
1681 if (len + 4096 >
_glfw.wl.clipboardSize)
1683 if (!growClipboardString())
1691 ret = read(fds[0],
_glfw.wl.clipboardString + len, 4096);
1694 if (ret == -1 && errno == EINTR)
1700 "Wayland: Impossible to read from clipboard fd");
1707 if (len + 1 >
_glfw.wl.clipboardSize)
1709 if (!growClipboardString())
1712 _glfw.wl.clipboardString[len] =
'\0';
1713 return _glfw.wl.clipboardString;
1726 return _glfw.wl.display;
1731 return window->wl.native;
1739 extensions[0] =
"VK_KHR_surface";
1740 extensions[1] =
"VK_KHR_wayland_surface";
1748 vkGetPhysicalDeviceWaylandPresentationSupportKHR =
1751 if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
1754 "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
1758 return vkGetPhysicalDeviceWaylandPresentationSupportKHR(device,
1774 if (!vkCreateWaylandSurfaceKHR)
1777 "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
1781 memset(&sci, 0,
sizeof(sci));
1784 sci.
surface = window->wl.surface;
1786 err = vkCreateWaylandSurfaceKHR(instance, &sci, allocator, surface);
1790 "Wayland: Failed to create Vulkan surface: %s",
1805 return _glfw.wl.display;
1812 return window->wl.surface;
GLFWbool _glfwInitEGL(void)
GLFWbool _glfwCreateContextEGL(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
void * EGLNativeDisplayType
void * EGLNativeWindowType
#define EGL_PLATFORM_WAYLAND_EXT
#define GLFW_EGL_CONTEXT_API
#define GLFW_NATIVE_CONTEXT_API
#define GLFW_CURSOR_DISABLED
#define GLFW_CURSOR_HIDDEN
#define GLFW_CURSOR_NORMAL
#define GLFW_OSMESA_CONTEXT_API
#define GLFW_CURSOR_UNAVAILABLE
The specified cursor shape is not available.
#define GLFW_FORMAT_UNAVAILABLE
The requested format is not supported or available.
#define GLFW_FEATURE_UNAVAILABLE
The requested feature is not provided by the platform.
#define GLFW_API_UNAVAILABLE
GLFW could not find support for the requested API on the system.
#define GLFW_FEATURE_UNIMPLEMENTED
The requested feature is not implemented for the platform.
#define GLFW_PLATFORM_ERROR
A platform-specific error occurred that does not match any of the more specific categories.
#define GLFW_RESIZE_EW_CURSOR
The horizontal resize/move arrow shape.
#define GLFW_NOT_ALLOWED_CURSOR
The operation-not-allowed shape.
#define GLFW_IBEAM_CURSOR
The text input I-beam cursor shape.
#define GLFW_RESIZE_ALL_CURSOR
The omni-directional resize/move cursor shape.
#define GLFW_ARROW_CURSOR
The regular arrow cursor shape.
#define GLFW_CROSSHAIR_CURSOR
The crosshair cursor shape.
#define GLFW_RESIZE_NS_CURSOR
The vertical resize/move arrow shape.
#define GLFW_POINTING_HAND_CURSOR
The pointing hand cursor shape.
#define GLFW_RESIZE_NESW_CURSOR
The top-right to bottom-left diagonal resize/move arrow shape.
#define GLFW_RESIZE_NWSE_CURSOR
The top-left to bottom-right diagonal resize/move arrow shape.
struct GLFWwindow GLFWwindow
Opaque window object.
void _glfwInputError(int code, const char *format,...)
char * _glfw_strdup(const char *source)
void _glfwInputFramebufferSize(_GLFWwindow *window, int width, int height)
void _glfwInputWindowSize(_GLFWwindow *window, int width, int height)
void _glfwInputWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor)
#define _GLFW_REQUIRE_INIT_OR_RETURN(x)
const char * _glfwGetVulkanResultString(VkResult result)
void _glfwInputWindowContentScale(_GLFWwindow *window, float xscale, float yscale)
void _glfwInputWindowDamage(_GLFWwindow *window)
void _glfwInputWindowCloseRequest(_GLFWwindow *window)
void _glfwInputWindowFocus(_GLFWwindow *window, GLFWbool focused)
@ VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
GLFWbool _glfwInitOSMesa(void)
unsigned __int64 uint64_t
_GLFWdestroycontextfun destroy
struct wl_buffer * buffer
struct wl_cursor * cursor
struct wl_cursor * cursorHiDPI
struct wl_subsurface * subsurface
struct wp_viewport * viewport
struct wl_surface * surface
GLFWbool EXT_platform_wayland
GLFWbool EXT_platform_base
struct _GLFWlibrary::@25 vk
_GLFWwindow * windowListHead
struct _GLFWwindow * next
GLFWwindowcontentscalefun scale
struct wl_display * display
struct wl_surface * surface
struct wl_cursor_image ** images
@ VK_ERROR_EXTENSION_NOT_PRESENT
#define vkGetInstanceProcAddr
void _glfwPlatformSetWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
void _glfwPlatformSetWindowPos(_GLFWwindow *window, int xpos, int ypos)
void _glfwPlatformGetWindowContentScale(_GLFWwindow *window, float *xscale, float *yscale)
void _glfwPlatformSetCursorPos(_GLFWwindow *window, double x, double y)
void _glfwPlatformSetWindowResizable(_GLFWwindow *window, GLFWbool enabled)
int _glfwPlatformWindowIconified(_GLFWwindow *window)
void _glfwPlatformMaximizeWindow(_GLFWwindow *window)
EGLenum _glfwPlatformGetEGLPlatform(EGLint **attribs)
void _glfwPlatformIconifyWindow(_GLFWwindow *window)
void _glfwPlatformSetWindowSize(_GLFWwindow *window, int width, int height)
void _glfwPlatformWaitEvents(void)
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
void _glfwPlatformGetRequiredInstanceExtensions(char **extensions)
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
int _glfwPlatformFramebufferTransparent(_GLFWwindow *window)
int _glfwPlatformCreateCursor(_GLFWcursor *cursor, const GLFWimage *image, int xhot, int yhot)
void _glfwPlatformPollEvents(void)
void _glfwPlatformGetFramebufferSize(_GLFWwindow *window, int *width, int *height)
int _glfwPlatformWindowVisible(_GLFWwindow *window)
void _glfwPlatformSetCursor(_GLFWwindow *window, _GLFWcursor *cursor)
void _glfwPlatformGetWindowSize(_GLFWwindow *window, int *width, int *height)
GLFWAPI struct wl_surface * glfwGetWaylandWindow(GLFWwindow *handle)
void _glfwPlatformGetWindowFrameSize(_GLFWwindow *window, int *left, int *top, int *right, int *bottom)
void _glfwPlatformSetWindowIcon(_GLFWwindow *window, int count, const GLFWimage *images)
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow *window)
const char * _glfwPlatformGetScancodeName(int scancode)
void _glfwPlatformSetWindowDecorated(_GLFWwindow *window, GLFWbool enabled)
void _glfwPlatformGetWindowPos(_GLFWwindow *window, int *xpos, int *ypos)
void _glfwPlatformSetWindowOpacity(_GLFWwindow *window, float opacity)
float _glfwPlatformGetWindowOpacity(_GLFWwindow *window)
void _glfwPlatformDestroyCursor(_GLFWcursor *cursor)
void _glfwPlatformRestoreWindow(_GLFWwindow *window)
GLFWbool _glfwPlatformRawMouseMotionSupported(void)
void _glfwPlatformSetCursorMode(_GLFWwindow *window, int mode)
int _glfwPlatformWindowHovered(_GLFWwindow *window)
void _glfwPlatformDestroyWindow(_GLFWwindow *window)
void _glfwPlatformWaitEventsTimeout(double timeout)
void _glfwPlatformHideWindow(_GLFWwindow *window)
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
int _glfwPlatformWindowMaximized(_GLFWwindow *window)
void _glfwPlatformSetClipboardString(const char *string)
void _glfwPlatformShowWindow(_GLFWwindow *window)
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
int _glfwPlatformWindowFocused(_GLFWwindow *window)
void _glfwPlatformPostEmptyEvent(void)
int _glfwPlatformGetKeyScancode(int key)
int _glfwPlatformCreateStandardCursor(_GLFWcursor *cursor, int shape)
int _glfwPlatformCreateWindow(_GLFWwindow *window, const _GLFWwndconfig *wndconfig, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow *window, int numer, int denom)
const char * _glfwPlatformGetClipboardString(void)
void _glfwPlatformGetCursorPos(_GLFWwindow *window, double *xpos, double *ypos)
void _glfwPlatformRequestWindowAttention(_GLFWwindow *window)
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void)
void _glfwPlatformSetWindowTitle(_GLFWwindow *window, const char *title)
void _glfwPlatformFocusWindow(_GLFWwindow *window)
GLFWAPI struct wl_display * glfwGetWaylandDisplay(void)
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow *window, GLFWbool enabled)
void _glfwPlatformSetWindowFloating(_GLFWwindow *window, GLFWbool enabled)