wl_window.c
Go to the documentation of this file.
1 //========================================================================
2 // GLFW 3.3 Wayland - www.glfw.org
3 //------------------------------------------------------------------------
4 // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 // claim that you wrote the original software. If you use this software
16 // in a product, an acknowledgment in the product documentation would
17 // be appreciated but is not required.
18 //
19 // 2. Altered source versions must be plainly marked as such, and must not
20 // be misrepresented as being the original software.
21 //
22 // 3. This notice may not be removed or altered from any source
23 // distribution.
24 //
25 //========================================================================
26 
27 #define _GNU_SOURCE
28 
29 #include "internal.h"
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <fcntl.h>
37 #include <sys/mman.h>
38 #include <sys/timerfd.h>
39 #include <poll.h>
40 
41 
42 static void shellSurfaceHandlePing(void* data,
43  struct wl_shell_surface* shellSurface,
44  uint32_t serial)
45 {
46  wl_shell_surface_pong(shellSurface, serial);
47 }
48 
50  struct wl_shell_surface* shellSurface,
51  uint32_t edges,
52  int32_t width,
54 {
56  float aspectRatio;
57  float targetRatio;
58 
59  if (!window->monitor)
60  {
61  if (_glfw.wl.viewporter && window->decorated)
62  {
64  height -= _GLFW_DECORATION_VERTICAL;
65  }
66  if (width < 1)
67  width = 1;
68  if (height < 1)
69  height = 1;
70 
71  if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
72  {
73  aspectRatio = (float)width / (float)height;
74  targetRatio = (float)window->numer / (float)window->denom;
75  if (aspectRatio < targetRatio)
76  height = width / targetRatio;
77  else if (aspectRatio > targetRatio)
78  width = height * targetRatio;
79  }
80 
81  if (window->minwidth != GLFW_DONT_CARE && width < window->minwidth)
82  width = window->minwidth;
83  else if (window->maxwidth != GLFW_DONT_CARE && width > window->maxwidth)
84  width = window->maxwidth;
85 
86  if (window->minheight != GLFW_DONT_CARE && height < window->minheight)
87  height = window->minheight;
88  else if (window->maxheight != GLFW_DONT_CARE && height > window->maxheight)
89  height = window->maxheight;
90  }
91 
92  _glfwInputWindowSize(window, width, height);
93  _glfwPlatformSetWindowSize(window, width, height);
94  _glfwInputWindowDamage(window);
95 }
96 
98  struct wl_shell_surface* shellSurface)
99 {
100 }
101 
102 static const struct wl_shell_surface_listener shellSurfaceListener = {
106 };
107 
108 static int createTmpfileCloexec(char* tmpname)
109 {
110  int fd;
111 
112  fd = mkostemp(tmpname, O_CLOEXEC);
113  if (fd >= 0)
114  unlink(tmpname);
115 
116  return fd;
117 }
118 
119 /*
120  * Create a new, unique, anonymous file of the given size, and
121  * return the file descriptor for it. The file descriptor is set
122  * CLOEXEC. The file is immediately suitable for mmap()'ing
123  * the given size at offset zero.
124  *
125  * The file should not have a permanent backing store like a disk,
126  * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
127  *
128  * The file name is deleted from the file system.
129  *
130  * The file is suitable for buffer sharing between processes by
131  * transmitting the file descriptor over Unix sockets using the
132  * SCM_RIGHTS methods.
133  *
134  * posix_fallocate() is used to guarantee that disk space is available
135  * for the file at the given size. If disk space is insufficent, errno
136  * is set to ENOSPC. If posix_fallocate() is not supported, program may
137  * receive SIGBUS on accessing mmap()'ed file contents instead.
138  */
139 static int createAnonymousFile(off_t size)
140 {
141  static const char template[] = "/glfw-shared-XXXXXX";
142  const char* path;
143  char* name;
144  int fd;
145  int ret;
146 
147 #ifdef HAVE_MEMFD_CREATE
148  fd = memfd_create("glfw-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
149  if (fd >= 0)
150  {
151  // We can add this seal before calling posix_fallocate(), as the file
152  // is currently zero-sized anyway.
153  //
154  // There is also no need to check for the return value, we couldn’t do
155  // anything with it anyway.
156  fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
157  }
158  else
159 #endif
160  {
161  path = getenv("XDG_RUNTIME_DIR");
162  if (!path)
163  {
164  errno = ENOENT;
165  return -1;
166  }
167 
168  name = calloc(strlen(path) + sizeof(template), 1);
169  strcpy(name, path);
170  strcat(name, template);
171 
172  fd = createTmpfileCloexec(name);
173  free(name);
174  if (fd < 0)
175  return -1;
176  }
177 
178  ret = posix_fallocate(fd, 0, size);
179  if (ret != 0)
180  {
181  close(fd);
182  errno = ret;
183  return -1;
184  }
185  return fd;
186 }
187 
188 static struct wl_buffer* createShmBuffer(const GLFWimage* image)
189 {
190  struct wl_shm_pool* pool;
191  struct wl_buffer* buffer;
192  int stride = image->width * 4;
193  int length = image->width * image->height * 4;
194  void* data;
195  int fd, i;
196 
197  fd = createAnonymousFile(length);
198  if (fd < 0)
199  {
201  "Wayland: Creating a buffer file for %d B failed: %m",
202  length);
203  return NULL;
204  }
205 
206  data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
207  if (data == MAP_FAILED)
208  {
210  "Wayland: mmap failed: %m");
211  close(fd);
212  return NULL;
213  }
214 
215  pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);
216 
217  close(fd);
218  unsigned char* source = (unsigned char*) image->pixels;
219  unsigned char* target = data;
220  for (i = 0; i < image->width * image->height; i++, source += 4)
221  {
222  unsigned int alpha = source[3];
223 
224  *target++ = (unsigned char) ((source[2] * alpha) / 255);
225  *target++ = (unsigned char) ((source[1] * alpha) / 255);
226  *target++ = (unsigned char) ((source[0] * alpha) / 255);
227  *target++ = (unsigned char) alpha;
228  }
229 
230  buffer =
231  wl_shm_pool_create_buffer(pool, 0,
232  image->width,
233  image->height,
234  stride, WL_SHM_FORMAT_ARGB8888);
235  munmap(data, length);
236  wl_shm_pool_destroy(pool);
237 
238  return buffer;
239 }
240 
241 static void createDecoration(_GLFWdecorationWayland* decoration,
242  struct wl_surface* parent,
243  struct wl_buffer* buffer, GLFWbool opaque,
244  int x, int y,
245  int width, int height)
246 {
247  struct wl_region* region;
248 
249  decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor);
250  decoration->subsurface =
251  wl_subcompositor_get_subsurface(_glfw.wl.subcompositor,
252  decoration->surface, parent);
253  wl_subsurface_set_position(decoration->subsurface, x, y);
254  decoration->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter,
255  decoration->surface);
256  wp_viewport_set_destination(decoration->viewport, width, height);
257  wl_surface_attach(decoration->surface, buffer, 0, 0);
258 
259  if (opaque)
260  {
261  region = wl_compositor_create_region(_glfw.wl.compositor);
262  wl_region_add(region, 0, 0, width, height);
263  wl_surface_set_opaque_region(decoration->surface, region);
264  wl_surface_commit(decoration->surface);
265  wl_region_destroy(region);
266  }
267  else
268  wl_surface_commit(decoration->surface);
269 }
270 
272 {
273  unsigned char data[] = { 224, 224, 224, 255 };
274  const GLFWimage image = { 1, 1, data };
275  GLFWbool opaque = (data[3] == 255);
276 
277  if (!_glfw.wl.viewporter || !window->decorated || window->wl.decorations.serverSide)
278  return;
279 
280  if (!window->wl.decorations.buffer)
281  window->wl.decorations.buffer = createShmBuffer(&image);
282  if (!window->wl.decorations.buffer)
283  return;
284 
285  createDecoration(&window->wl.decorations.top, window->wl.surface,
286  window->wl.decorations.buffer, opaque,
288  window->wl.width, _GLFW_DECORATION_TOP);
289  createDecoration(&window->wl.decorations.left, window->wl.surface,
290  window->wl.decorations.buffer, opaque,
292  _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP);
293  createDecoration(&window->wl.decorations.right, window->wl.surface,
294  window->wl.decorations.buffer, opaque,
295  window->wl.width, -_GLFW_DECORATION_TOP,
296  _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP);
297  createDecoration(&window->wl.decorations.bottom, window->wl.surface,
298  window->wl.decorations.buffer, opaque,
299  -_GLFW_DECORATION_WIDTH, window->wl.height,
301 }
302 
304 {
305  if (decoration->surface)
306  wl_surface_destroy(decoration->surface);
307  if (decoration->subsurface)
308  wl_subsurface_destroy(decoration->subsurface);
309  if (decoration->viewport)
310  wp_viewport_destroy(decoration->viewport);
311  decoration->surface = NULL;
312  decoration->subsurface = NULL;
313  decoration->viewport = NULL;
314 }
315 
317 {
318  destroyDecoration(&window->wl.decorations.top);
319  destroyDecoration(&window->wl.decorations.left);
320  destroyDecoration(&window->wl.decorations.right);
321  destroyDecoration(&window->wl.decorations.bottom);
322 }
323 
325  struct zxdg_toplevel_decoration_v1* decoration,
326  uint32_t mode)
327 {
329 
330  window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
331 
332  if (!window->wl.decorations.serverSide)
333  createDecorations(window);
334 }
335 
336 static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = {
338 };
339 
340 // Makes the surface considered as XRGB instead of ARGB.
342 {
343  struct wl_region* region;
344 
345  region = wl_compositor_create_region(_glfw.wl.compositor);
346  if (!region)
347  return;
348 
349  wl_region_add(region, 0, 0, window->wl.width, window->wl.height);
350  wl_surface_set_opaque_region(window->wl.surface, region);
351  wl_surface_commit(window->wl.surface);
352  wl_region_destroy(region);
353 }
354 
355 
357 {
358  int scale = window->wl.scale;
359  int scaledWidth = window->wl.width * scale;
360  int scaledHeight = window->wl.height * scale;
361  wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
362  if (!window->wl.transparent)
363  setOpaqueRegion(window);
364  _glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
365  _glfwInputWindowContentScale(window, scale, scale);
366 
367  if (!window->wl.decorations.top.surface)
368  return;
369 
370  // Top decoration.
371  wp_viewport_set_destination(window->wl.decorations.top.viewport,
372  window->wl.width, _GLFW_DECORATION_TOP);
373  wl_surface_commit(window->wl.decorations.top.surface);
374 
375  // Left decoration.
376  wp_viewport_set_destination(window->wl.decorations.left.viewport,
377  _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP);
378  wl_surface_commit(window->wl.decorations.left.surface);
379 
380  // Right decoration.
381  wl_subsurface_set_position(window->wl.decorations.right.subsurface,
382  window->wl.width, -_GLFW_DECORATION_TOP);
383  wp_viewport_set_destination(window->wl.decorations.right.viewport,
384  _GLFW_DECORATION_WIDTH, window->wl.height + _GLFW_DECORATION_TOP);
385  wl_surface_commit(window->wl.decorations.right.surface);
386 
387  // Bottom decoration.
388  wl_subsurface_set_position(window->wl.decorations.bottom.subsurface,
389  -_GLFW_DECORATION_WIDTH, window->wl.height);
390  wp_viewport_set_destination(window->wl.decorations.bottom.viewport,
392  wl_surface_commit(window->wl.decorations.bottom.surface);
393 }
394 
396 {
397  int scale = 1;
398  int i;
399  int monitorScale;
400 
401  // Check if we will be able to set the buffer scale or not.
402  if (_glfw.wl.compositorVersion < 3)
403  return;
404 
405  // Get the scale factor from the highest scale monitor.
406  for (i = 0; i < window->wl.monitorsCount; ++i)
407  {
408  monitorScale = window->wl.monitors[i]->wl.scale;
409  if (scale < monitorScale)
410  scale = monitorScale;
411  }
412 
413  // Only change the framebuffer size if the scale changed.
414  if (scale != window->wl.scale)
415  {
416  window->wl.scale = scale;
417  wl_surface_set_buffer_scale(window->wl.surface, scale);
418  resizeWindow(window);
419  }
420 }
421 
422 static void surfaceHandleEnter(void *data,
423  struct wl_surface *surface,
424  struct wl_output *output)
425 {
427  _GLFWmonitor* monitor = wl_output_get_user_data(output);
428 
429  if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)
430  {
431  ++window->wl.monitorsSize;
432  window->wl.monitors =
433  realloc(window->wl.monitors,
434  window->wl.monitorsSize * sizeof(_GLFWmonitor*));
435  }
436 
437  window->wl.monitors[window->wl.monitorsCount++] = monitor;
438 
439  checkScaleChange(window);
440 }
441 
442 static void surfaceHandleLeave(void *data,
443  struct wl_surface *surface,
444  struct wl_output *output)
445 {
447  _GLFWmonitor* monitor = wl_output_get_user_data(output);
448  GLFWbool found;
449  int i;
450 
451  for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
452  {
453  if (monitor == window->wl.monitors[i])
454  found = GLFW_TRUE;
455  if (found)
456  window->wl.monitors[i] = window->wl.monitors[i + 1];
457  }
458  window->wl.monitors[--window->wl.monitorsCount] = NULL;
459 
460  checkScaleChange(window);
461 }
462 
463 static const struct wl_surface_listener surfaceListener = {
466 };
467 
469 {
470  if (enable && !window->wl.idleInhibitor && _glfw.wl.idleInhibitManager)
471  {
472  window->wl.idleInhibitor =
473  zwp_idle_inhibit_manager_v1_create_inhibitor(
474  _glfw.wl.idleInhibitManager, window->wl.surface);
475  if (!window->wl.idleInhibitor)
477  "Wayland: Idle inhibitor creation failed");
478  }
479  else if (!enable && window->wl.idleInhibitor)
480  {
481  zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);
482  window->wl.idleInhibitor = NULL;
483  }
484 }
485 
487  const _GLFWwndconfig* wndconfig)
488 {
489  window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
490  if (!window->wl.surface)
491  return GLFW_FALSE;
492 
493  wl_surface_add_listener(window->wl.surface,
495  window);
496 
497  wl_surface_set_user_data(window->wl.surface, window);
498 
499  window->wl.native = wl_egl_window_create(window->wl.surface,
500  wndconfig->width,
501  wndconfig->height);
502  if (!window->wl.native)
503  return GLFW_FALSE;
504 
505  window->wl.width = wndconfig->width;
506  window->wl.height = wndconfig->height;
507  window->wl.scale = 1;
508 
509  if (!window->wl.transparent)
510  setOpaqueRegion(window);
511 
512  return GLFW_TRUE;
513 }
514 
516  int refreshRate)
517 {
518  if (window->wl.xdg.toplevel)
519  {
520  xdg_toplevel_set_fullscreen(
521  window->wl.xdg.toplevel,
522  monitor->wl.output);
523  }
524  else if (window->wl.shellSurface)
525  {
526  wl_shell_surface_set_fullscreen(
527  window->wl.shellSurface,
528  WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
529  refreshRate * 1000, // Convert Hz to mHz.
530  monitor->wl.output);
531  }
532  setIdleInhibitor(window, GLFW_TRUE);
533  if (!window->wl.decorations.serverSide)
534  destroyDecorations(window);
535 }
536 
538 {
539  if (!_glfw.wl.shell)
540  {
542  "Wayland: wl_shell protocol not available");
543  return GLFW_FALSE;
544  }
545 
546  window->wl.shellSurface = wl_shell_get_shell_surface(_glfw.wl.shell,
547  window->wl.surface);
548  if (!window->wl.shellSurface)
549  {
551  "Wayland: Shell surface creation failed");
552  return GLFW_FALSE;
553  }
554 
555  wl_shell_surface_add_listener(window->wl.shellSurface,
557  window);
558 
559  if (window->wl.title)
560  wl_shell_surface_set_title(window->wl.shellSurface, window->wl.title);
561 
562  if (window->monitor)
563  {
564  setFullscreen(window, window->monitor, 0);
565  }
566  else if (window->wl.maximized)
567  {
568  wl_shell_surface_set_maximized(window->wl.shellSurface, NULL);
569  setIdleInhibitor(window, GLFW_FALSE);
570  createDecorations(window);
571  }
572  else
573  {
574  wl_shell_surface_set_toplevel(window->wl.shellSurface);
575  setIdleInhibitor(window, GLFW_FALSE);
576  createDecorations(window);
577  }
578 
579  wl_surface_commit(window->wl.surface);
580 
581  return GLFW_TRUE;
582 }
583 
585  struct xdg_toplevel* toplevel,
586  int32_t width,
587  int32_t height,
588  struct wl_array* states)
589 {
591  float aspectRatio;
592  float targetRatio;
593  uint32_t* state;
595  GLFWbool fullscreen = GLFW_FALSE;
596  GLFWbool activated = GLFW_FALSE;
597 
598  wl_array_for_each(state, states)
599  {
600  switch (*state)
601  {
602  case XDG_TOPLEVEL_STATE_MAXIMIZED:
603  maximized = GLFW_TRUE;
604  break;
605  case XDG_TOPLEVEL_STATE_FULLSCREEN:
606  fullscreen = GLFW_TRUE;
607  break;
608  case XDG_TOPLEVEL_STATE_RESIZING:
609  break;
610  case XDG_TOPLEVEL_STATE_ACTIVATED:
611  activated = GLFW_TRUE;
612  break;
613  }
614  }
615 
616  if (width != 0 && height != 0)
617  {
618  if (!maximized && !fullscreen)
619  {
620  if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
621  {
622  aspectRatio = (float)width / (float)height;
623  targetRatio = (float)window->numer / (float)window->denom;
624  if (aspectRatio < targetRatio)
625  height = width / targetRatio;
626  else if (aspectRatio > targetRatio)
627  width = height * targetRatio;
628  }
629  }
630 
631  _glfwInputWindowSize(window, width, height);
632  _glfwPlatformSetWindowSize(window, width, height);
633  _glfwInputWindowDamage(window);
634  }
635 
636  if (!window->wl.justCreated && !activated && window->autoIconify)
638  _glfwInputWindowFocus(window, activated);
639  window->wl.justCreated = GLFW_FALSE;
640 }
641 
642 static void xdgToplevelHandleClose(void* data,
643  struct xdg_toplevel* toplevel)
644 {
647 }
648 
649 static const struct xdg_toplevel_listener xdgToplevelListener = {
652 };
653 
654 static void xdgSurfaceHandleConfigure(void* data,
655  struct xdg_surface* surface,
656  uint32_t serial)
657 {
658  xdg_surface_ack_configure(surface, serial);
659 }
660 
661 static const struct xdg_surface_listener xdgSurfaceListener = {
663 };
664 
666 {
667  if (_glfw.wl.decorationManager)
668  {
669  window->wl.xdg.decoration =
670  zxdg_decoration_manager_v1_get_toplevel_decoration(
671  _glfw.wl.decorationManager, window->wl.xdg.toplevel);
672  zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration,
674  window);
675  zxdg_toplevel_decoration_v1_set_mode(
676  window->wl.xdg.decoration,
677  ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
678  }
679  else
680  {
681  window->wl.decorations.serverSide = GLFW_FALSE;
682  createDecorations(window);
683  }
684 }
685 
687 {
688  window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,
689  window->wl.surface);
690  if (!window->wl.xdg.surface)
691  {
693  "Wayland: xdg-surface creation failed");
694  return GLFW_FALSE;
695  }
696 
697  xdg_surface_add_listener(window->wl.xdg.surface,
699  window);
700 
701  window->wl.xdg.toplevel = xdg_surface_get_toplevel(window->wl.xdg.surface);
702  if (!window->wl.xdg.toplevel)
703  {
705  "Wayland: xdg-toplevel creation failed");
706  return GLFW_FALSE;
707  }
708 
709  xdg_toplevel_add_listener(window->wl.xdg.toplevel,
711  window);
712 
713  if (window->wl.title)
714  xdg_toplevel_set_title(window->wl.xdg.toplevel, window->wl.title);
715 
716  if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE)
717  xdg_toplevel_set_min_size(window->wl.xdg.toplevel,
718  window->minwidth, window->minheight);
719  if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE)
720  xdg_toplevel_set_max_size(window->wl.xdg.toplevel,
721  window->maxwidth, window->maxheight);
722 
723  if (window->monitor)
724  {
725  xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel,
726  window->monitor->wl.output);
727  setIdleInhibitor(window, GLFW_TRUE);
728  }
729  else if (window->wl.maximized)
730  {
731  xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
732  setIdleInhibitor(window, GLFW_FALSE);
733  setXdgDecorations(window);
734  }
735  else
736  {
737  setIdleInhibitor(window, GLFW_FALSE);
738  setXdgDecorations(window);
739  }
740 
741  wl_surface_commit(window->wl.surface);
742  wl_display_roundtrip(_glfw.wl.display);
743 
744  return GLFW_TRUE;
745 }
746 
748  _GLFWcursorWayland* cursorWayland)
749 {
750  struct itimerspec timer = {};
751  struct wl_cursor* wlCursor = cursorWayland->cursor;
752  struct wl_cursor_image* image;
753  struct wl_buffer* buffer;
754  struct wl_surface* surface = _glfw.wl.cursorSurface;
755  int scale = 1;
756 
757  if (!wlCursor)
758  buffer = cursorWayland->buffer;
759  else
760  {
761  if (window->wl.scale > 1 && cursorWayland->cursorHiDPI)
762  {
763  wlCursor = cursorWayland->cursorHiDPI;
764  scale = 2;
765  }
766 
767  image = wlCursor->images[cursorWayland->currentImage];
768  buffer = wl_cursor_image_get_buffer(image);
769  if (!buffer)
770  return;
771 
772  timer.it_value.tv_sec = image->delay / 1000;
773  timer.it_value.tv_nsec = (image->delay % 1000) * 1000000;
774  timerfd_settime(_glfw.wl.cursorTimerfd, 0, &timer, NULL);
775 
776  cursorWayland->width = image->width;
777  cursorWayland->height = image->height;
778  cursorWayland->xhot = image->hotspot_x;
779  cursorWayland->yhot = image->hotspot_y;
780  }
781 
782  wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
783  surface,
784  cursorWayland->xhot / scale,
785  cursorWayland->yhot / scale);
786  wl_surface_set_buffer_scale(surface, scale);
787  wl_surface_attach(surface, buffer, 0, 0);
788  wl_surface_damage(surface, 0, 0,
789  cursorWayland->width, cursorWayland->height);
790  wl_surface_commit(surface);
791 }
792 
794 {
795  _GLFWcursor* cursor;
796 
797  if (!window || window->wl.decorations.focus != mainWindow)
798  return;
799 
800  cursor = window->wl.currentCursor;
801  if (cursor && cursor->wl.cursor)
802  {
803  cursor->wl.currentImage += 1;
804  cursor->wl.currentImage %= cursor->wl.cursor->image_count;
805  setCursorImage(window, &cursor->wl);
806  }
807 }
808 
809 static void handleEvents(int timeout)
810 {
811  struct wl_display* display = _glfw.wl.display;
812  struct pollfd fds[] = {
813  { wl_display_get_fd(display), POLLIN },
814  { _glfw.wl.timerfd, POLLIN },
815  { _glfw.wl.cursorTimerfd, POLLIN },
816  };
817  ssize_t read_ret;
818  uint64_t repeats, i;
819 
820  while (wl_display_prepare_read(display) != 0)
821  wl_display_dispatch_pending(display);
822 
823  // If an error different from EAGAIN happens, we have likely been
824  // disconnected from the Wayland session, try to handle that the best we
825  // can.
826  if (wl_display_flush(display) < 0 && errno != EAGAIN)
827  {
829  while (window)
830  {
832  window = window->next;
833  }
834  wl_display_cancel_read(display);
835  return;
836  }
837 
838  if (poll(fds, 3, timeout) > 0)
839  {
840  if (fds[0].revents & POLLIN)
841  {
842  wl_display_read_events(display);
843  wl_display_dispatch_pending(display);
844  }
845  else
846  {
847  wl_display_cancel_read(display);
848  }
849 
850  if (fds[1].revents & POLLIN)
851  {
852  read_ret = read(_glfw.wl.timerfd, &repeats, sizeof(repeats));
853  if (read_ret != 8)
854  return;
855 
856  for (i = 0; i < repeats; ++i)
857  _glfwInputKey(_glfw.wl.keyboardFocus, _glfw.wl.keyboardLastKey,
858  _glfw.wl.keyboardLastScancode, GLFW_REPEAT,
859  _glfw.wl.xkb.modifiers);
860  }
861 
862  if (fds[2].revents & POLLIN)
863  {
864  read_ret = read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats));
865  if (read_ret != 8)
866  return;
867 
868  incrementCursorImage(_glfw.wl.pointerFocus);
869  }
870  }
871  else
872  {
873  wl_display_cancel_read(display);
874  }
875 }
876 
877 // Translates a GLFW standard cursor to a theme cursor name
878 //
879 static char *translateCursorShape(int shape)
880 {
881  switch (shape)
882  {
883  case GLFW_ARROW_CURSOR:
884  return "left_ptr";
885  case GLFW_IBEAM_CURSOR:
886  return "xterm";
888  return "crosshair";
889  case GLFW_HAND_CURSOR:
890  return "grabbing";
891  case GLFW_HRESIZE_CURSOR:
892  return "sb_h_double_arrow";
893  case GLFW_VRESIZE_CURSOR:
894  return "sb_v_double_arrow";
895  }
896  return NULL;
897 }
898 
902 
904  const _GLFWwndconfig* wndconfig,
905  const _GLFWctxconfig* ctxconfig,
906  const _GLFWfbconfig* fbconfig)
907 {
908  window->wl.justCreated = GLFW_TRUE;
909  window->wl.transparent = fbconfig->transparent;
910 
911  if (!createSurface(window, wndconfig))
912  return GLFW_FALSE;
913 
914  if (ctxconfig->client != GLFW_NO_API)
915  {
916  if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||
917  ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
918  {
919  if (!_glfwInitEGL())
920  return GLFW_FALSE;
921  if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
922  return GLFW_FALSE;
923  }
924  else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
925  {
926  if (!_glfwInitOSMesa())
927  return GLFW_FALSE;
928  if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
929  return GLFW_FALSE;
930  }
931  }
932 
933  if (wndconfig->title)
934  window->wl.title = _glfw_strdup(wndconfig->title);
935 
936  if (wndconfig->visible)
937  {
938  if (_glfw.wl.wmBase)
939  {
940  if (!createXdgSurface(window))
941  return GLFW_FALSE;
942  }
943  else
944  {
945  if (!createShellSurface(window))
946  return GLFW_FALSE;
947  }
948 
949  window->wl.visible = GLFW_TRUE;
950  }
951  else
952  {
953  window->wl.xdg.surface = NULL;
954  window->wl.xdg.toplevel = NULL;
955  window->wl.shellSurface = NULL;
956  window->wl.visible = GLFW_FALSE;
957  }
958 
959  window->wl.currentCursor = NULL;
960 
961  window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*));
962  window->wl.monitorsCount = 0;
963  window->wl.monitorsSize = 1;
964 
965  return GLFW_TRUE;
966 }
967 
969 {
970  if (window == _glfw.wl.pointerFocus)
971  {
972  _glfw.wl.pointerFocus = NULL;
974  }
975  if (window == _glfw.wl.keyboardFocus)
976  {
977  _glfw.wl.keyboardFocus = NULL;
979  }
980 
981  if (window->wl.idleInhibitor)
982  zwp_idle_inhibitor_v1_destroy(window->wl.idleInhibitor);
983 
984  if (window->context.destroy)
985  window->context.destroy(window);
986 
987  destroyDecorations(window);
988  if (window->wl.xdg.decoration)
989  zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
990 
991  if (window->wl.decorations.buffer)
992  wl_buffer_destroy(window->wl.decorations.buffer);
993 
994  if (window->wl.native)
995  wl_egl_window_destroy(window->wl.native);
996 
997  if (window->wl.shellSurface)
998  wl_shell_surface_destroy(window->wl.shellSurface);
999 
1000  if (window->wl.xdg.toplevel)
1001  xdg_toplevel_destroy(window->wl.xdg.toplevel);
1002 
1003  if (window->wl.xdg.surface)
1004  xdg_surface_destroy(window->wl.xdg.surface);
1005 
1006  if (window->wl.surface)
1007  wl_surface_destroy(window->wl.surface);
1008 
1009  free(window->wl.title);
1010  free(window->wl.monitors);
1011 }
1012 
1014 {
1015  if (window->wl.title)
1016  free(window->wl.title);
1017  window->wl.title = _glfw_strdup(title);
1018  if (window->wl.xdg.toplevel)
1019  xdg_toplevel_set_title(window->wl.xdg.toplevel, title);
1020  else if (window->wl.shellSurface)
1021  wl_shell_surface_set_title(window->wl.shellSurface, title);
1022 }
1023 
1025  int count, const GLFWimage* images)
1026 {
1028  "Wayland: Setting window icon not supported");
1029 }
1030 
1032 {
1033  // A Wayland client is not aware of its position, so just warn and leave it
1034  // as (0, 0)
1035 
1037  "Wayland: Window position retrieval not supported");
1038 }
1039 
1041 {
1042  // A Wayland client can not set its position, so just warn
1043 
1045  "Wayland: Window position setting not supported");
1046 }
1047 
1049 {
1050  if (width)
1051  *width = window->wl.width;
1052  if (height)
1053  *height = window->wl.height;
1054 }
1055 
1057 {
1058  window->wl.width = width;
1059  window->wl.height = height;
1060  resizeWindow(window);
1061 }
1062 
1064  int minwidth, int minheight,
1065  int maxwidth, int maxheight)
1066 {
1067  if (_glfw.wl.wmBase)
1068  {
1069  if (window->wl.xdg.toplevel)
1070  {
1071  if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)
1072  minwidth = minheight = 0;
1073  if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)
1074  maxwidth = maxheight = 0;
1075  xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight);
1076  xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight);
1077  wl_surface_commit(window->wl.surface);
1078  }
1079  }
1080  else
1081  {
1082  // TODO: find out how to trigger a resize.
1083  // The actual limits are checked in the wl_shell_surface::configure handler.
1084  }
1085 }
1086 
1088  int numer, int denom)
1089 {
1090  // TODO: find out how to trigger a resize.
1091  // The actual limits are checked in the wl_shell_surface::configure handler.
1092 }
1093 
1095  int* width, int* height)
1096 {
1097  _glfwPlatformGetWindowSize(window, width, height);
1098  *width *= window->wl.scale;
1099  *height *= window->wl.scale;
1100 }
1101 
1103  int* left, int* top,
1104  int* right, int* bottom)
1105 {
1106  if (window->decorated && !window->monitor && !window->wl.decorations.serverSide)
1107  {
1108  if (top)
1109  *top = _GLFW_DECORATION_TOP;
1110  if (left)
1111  *left = _GLFW_DECORATION_WIDTH;
1112  if (right)
1113  *right = _GLFW_DECORATION_WIDTH;
1114  if (bottom)
1115  *bottom = _GLFW_DECORATION_WIDTH;
1116  }
1117 }
1118 
1120  float* xscale, float* yscale)
1121 {
1122  if (xscale)
1123  *xscale = (float) window->wl.scale;
1124  if (yscale)
1125  *yscale = (float) window->wl.scale;
1126 }
1127 
1129 {
1130  if (_glfw.wl.wmBase)
1131  {
1132  if (window->wl.xdg.toplevel)
1133  xdg_toplevel_set_minimized(window->wl.xdg.toplevel);
1134  }
1135  else
1136  {
1138  "Wayland: Iconify window not supported on wl_shell");
1139  }
1140 }
1141 
1143 {
1144  if (window->wl.xdg.toplevel)
1145  {
1146  if (window->monitor)
1147  xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
1148  if (window->wl.maximized)
1149  xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
1150  // There is no way to unset minimized, or even to know if we are
1151  // minimized, so there is nothing to do here.
1152  }
1153  else if (window->wl.shellSurface)
1154  {
1155  if (window->monitor || window->wl.maximized)
1156  wl_shell_surface_set_toplevel(window->wl.shellSurface);
1157  }
1158  _glfwInputWindowMonitor(window, NULL);
1159  window->wl.maximized = GLFW_FALSE;
1160 }
1161 
1163 {
1164  if (window->wl.xdg.toplevel)
1165  {
1166  xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
1167  }
1168  else if (window->wl.shellSurface)
1169  {
1170  // Let the compositor select the best output.
1171  wl_shell_surface_set_maximized(window->wl.shellSurface, NULL);
1172  }
1173  window->wl.maximized = GLFW_TRUE;
1174 }
1175 
1177 {
1178  if (!window->wl.visible)
1179  {
1180  if (_glfw.wl.wmBase)
1181  createXdgSurface(window);
1182  else if (!window->wl.shellSurface)
1183  createShellSurface(window);
1184  window->wl.visible = GLFW_TRUE;
1185  }
1186 }
1187 
1189 {
1190  if (window->wl.xdg.toplevel)
1191  {
1192  xdg_toplevel_destroy(window->wl.xdg.toplevel);
1193  xdg_surface_destroy(window->wl.xdg.surface);
1194  window->wl.xdg.toplevel = NULL;
1195  window->wl.xdg.surface = NULL;
1196  }
1197  else if (window->wl.shellSurface)
1198  {
1199  wl_shell_surface_destroy(window->wl.shellSurface);
1200  window->wl.shellSurface = NULL;
1201  }
1202  window->wl.visible = GLFW_FALSE;
1203 }
1204 
1206 {
1207  // TODO
1209  "Wayland: Window attention request not implemented yet");
1210 }
1211 
1213 {
1215  "Wayland: Focusing a window requires user interaction");
1216 }
1217 
1219  _GLFWmonitor* monitor,
1220  int xpos, int ypos,
1221  int width, int height,
1222  int refreshRate)
1223 {
1224  if (monitor)
1225  {
1226  setFullscreen(window, monitor, refreshRate);
1227  }
1228  else
1229  {
1230  if (window->wl.xdg.toplevel)
1231  xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
1232  else if (window->wl.shellSurface)
1233  wl_shell_surface_set_toplevel(window->wl.shellSurface);
1234  setIdleInhibitor(window, GLFW_FALSE);
1235  if (!_glfw.wl.decorationManager)
1236  createDecorations(window);
1237  }
1238  _glfwInputWindowMonitor(window, monitor);
1239 }
1240 
1242 {
1243  return _glfw.wl.keyboardFocus == window;
1244 }
1245 
1247 {
1248  // wl_shell doesn't have any iconified concept, and xdg-shell doesn’t give
1249  // any way to request whether a surface is iconified.
1250  return GLFW_FALSE;
1251 }
1252 
1254 {
1255  return window->wl.visible;
1256 }
1257 
1259 {
1260  return window->wl.maximized;
1261 }
1262 
1264 {
1265  return window->wl.hovered;
1266 }
1267 
1269 {
1270  return window->wl.transparent;
1271 }
1272 
1274 {
1275  // TODO
1277  "Wayland: Window attribute setting not implemented yet");
1278 }
1279 
1281 {
1282  if (!window->monitor)
1283  {
1284  if (enabled)
1285  createDecorations(window);
1286  else
1287  destroyDecorations(window);
1288  }
1289 }
1290 
1292 {
1293  // TODO
1295  "Wayland: Window attribute setting not implemented yet");
1296 }
1297 
1299 {
1300  return 1.f;
1301 }
1302 
1304 {
1305 }
1306 
1308 {
1309  handleEvents(0);
1310 }
1311 
1313 {
1314  handleEvents(-1);
1315 }
1316 
1318 {
1319  handleEvents((int) (timeout * 1e3));
1320 }
1321 
1323 {
1324  wl_display_sync(_glfw.wl.display);
1325 }
1326 
1328 {
1329  if (xpos)
1330  *xpos = window->wl.cursorPosX;
1331  if (ypos)
1332  *ypos = window->wl.cursorPosY;
1333 }
1334 
1336 
1337 void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
1338 {
1339  if (isPointerLocked(window))
1340  {
1341  zwp_locked_pointer_v1_set_cursor_position_hint(
1342  window->wl.pointerLock.lockedPointer,
1343  wl_fixed_from_double(x), wl_fixed_from_double(y));
1344  wl_surface_commit(window->wl.surface);
1345  }
1346 }
1347 
1349 {
1350  _glfwPlatformSetCursor(window, window->wl.currentCursor);
1351 }
1352 
1353 const char* _glfwPlatformGetScancodeName(int scancode)
1354 {
1355  // TODO
1356  return NULL;
1357 }
1358 
1360 {
1361  return _glfw.wl.scancodes[key];
1362 }
1363 
1365  const GLFWimage* image,
1366  int xhot, int yhot)
1367 {
1368  cursor->wl.buffer = createShmBuffer(image);
1369  if (!cursor->wl.buffer)
1370  return GLFW_FALSE;
1371 
1372  cursor->wl.width = image->width;
1373  cursor->wl.height = image->height;
1374  cursor->wl.xhot = xhot;
1375  cursor->wl.yhot = yhot;
1376  return GLFW_TRUE;
1377 }
1378 
1380 {
1381  struct wl_cursor* standardCursor;
1382 
1383  standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
1384  translateCursorShape(shape));
1385  if (!standardCursor)
1386  {
1388  "Wayland: Standard cursor \"%s\" not found",
1389  translateCursorShape(shape));
1390  return GLFW_FALSE;
1391  }
1392 
1393  cursor->wl.cursor = standardCursor;
1394  cursor->wl.currentImage = 0;
1395 
1396  if (_glfw.wl.cursorThemeHiDPI)
1397  {
1398  standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI,
1399  translateCursorShape(shape));
1400  cursor->wl.cursorHiDPI = standardCursor;
1401  }
1402 
1403  return GLFW_TRUE;
1404 }
1405 
1407 {
1408  // If it's a standard cursor we don't need to do anything here
1409  if (cursor->wl.cursor)
1410  return;
1411 
1412  if (cursor->wl.buffer)
1413  wl_buffer_destroy(cursor->wl.buffer);
1414 }
1415 
1417  struct zwp_relative_pointer_v1* pointer,
1418  uint32_t timeHi,
1419  uint32_t timeLo,
1420  wl_fixed_t dx,
1421  wl_fixed_t dy,
1422  wl_fixed_t dxUnaccel,
1423  wl_fixed_t dyUnaccel)
1424 {
1425  _GLFWwindow* window = data;
1426 
1427  if (window->cursorMode != GLFW_CURSOR_DISABLED)
1428  return;
1429 
1430  _glfwInputCursorPos(window,
1431  window->virtualCursorPosX + wl_fixed_to_double(dxUnaccel),
1432  window->virtualCursorPosY + wl_fixed_to_double(dyUnaccel));
1433 }
1434 
1435 static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
1437 };
1438 
1440  struct zwp_locked_pointer_v1* lockedPointer)
1441 {
1442 }
1443 
1444 static void unlockPointer(_GLFWwindow* window)
1445 {
1446  struct zwp_relative_pointer_v1* relativePointer =
1447  window->wl.pointerLock.relativePointer;
1448  struct zwp_locked_pointer_v1* lockedPointer =
1449  window->wl.pointerLock.lockedPointer;
1450 
1451  zwp_relative_pointer_v1_destroy(relativePointer);
1452  zwp_locked_pointer_v1_destroy(lockedPointer);
1453 
1454  window->wl.pointerLock.relativePointer = NULL;
1455  window->wl.pointerLock.lockedPointer = NULL;
1456 }
1457 
1458 static void lockPointer(_GLFWwindow* window);
1459 
1461  struct zwp_locked_pointer_v1* lockedPointer)
1462 {
1463 }
1464 
1465 static const struct zwp_locked_pointer_v1_listener lockedPointerListener = {
1468 };
1469 
1470 static void lockPointer(_GLFWwindow* window)
1471 {
1472  struct zwp_relative_pointer_v1* relativePointer;
1473  struct zwp_locked_pointer_v1* lockedPointer;
1474 
1475  if (!_glfw.wl.relativePointerManager)
1476  {
1478  "Wayland: no relative pointer manager");
1479  return;
1480  }
1481 
1482  relativePointer =
1483  zwp_relative_pointer_manager_v1_get_relative_pointer(
1484  _glfw.wl.relativePointerManager,
1485  _glfw.wl.pointer);
1486  zwp_relative_pointer_v1_add_listener(relativePointer,
1488  window);
1489 
1490  lockedPointer =
1491  zwp_pointer_constraints_v1_lock_pointer(
1492  _glfw.wl.pointerConstraints,
1493  window->wl.surface,
1494  _glfw.wl.pointer,
1495  NULL,
1496  ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
1497  zwp_locked_pointer_v1_add_listener(lockedPointer,
1499  window);
1500 
1501  window->wl.pointerLock.relativePointer = relativePointer;
1502  window->wl.pointerLock.lockedPointer = lockedPointer;
1503 
1504  wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
1505  NULL, 0, 0);
1506 }
1507 
1509 {
1510  return window->wl.pointerLock.lockedPointer != NULL;
1511 }
1512 
1514 {
1515  struct wl_cursor* defaultCursor;
1516  struct wl_cursor* defaultCursorHiDPI = NULL;
1517 
1518  if (!_glfw.wl.pointer)
1519  return;
1520 
1521  window->wl.currentCursor = cursor;
1522 
1523  // If we're not in the correct window just save the cursor
1524  // the next time the pointer enters the window the cursor will change
1525  if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != mainWindow)
1526  return;
1527 
1528  // Unlock possible pointer lock if no longer disabled.
1529  if (window->cursorMode != GLFW_CURSOR_DISABLED && isPointerLocked(window))
1530  unlockPointer(window);
1531 
1532  if (window->cursorMode == GLFW_CURSOR_NORMAL)
1533  {
1534  if (cursor)
1535  setCursorImage(window, &cursor->wl);
1536  else
1537  {
1538  defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
1539  "left_ptr");
1540  if (!defaultCursor)
1541  {
1543  "Wayland: Standard cursor not found");
1544  return;
1545  }
1546  if (_glfw.wl.cursorThemeHiDPI)
1547  defaultCursorHiDPI =
1548  wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI,
1549  "left_ptr");
1550  _GLFWcursorWayland cursorWayland = {
1551  defaultCursor,
1552  defaultCursorHiDPI,
1553  NULL,
1554  0, 0,
1555  0, 0,
1556  0
1557  };
1558  setCursorImage(window, &cursorWayland);
1559  }
1560  }
1561  else if (window->cursorMode == GLFW_CURSOR_DISABLED)
1562  {
1563  if (!isPointerLocked(window))
1564  lockPointer(window);
1565  }
1566  else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
1567  {
1568  wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, NULL, 0, 0);
1569  }
1570 }
1571 
1572 static void dataSourceHandleTarget(void* data,
1573  struct wl_data_source* dataSource,
1574  const char* mimeType)
1575 {
1576  if (_glfw.wl.dataSource != dataSource)
1577  {
1579  "Wayland: Unknown clipboard data source");
1580  return;
1581  }
1582 }
1583 
1584 static void dataSourceHandleSend(void* data,
1585  struct wl_data_source* dataSource,
1586  const char* mimeType,
1587  int fd)
1588 {
1589  const char* string = _glfw.wl.clipboardSendString;
1590  size_t len = _glfw.wl.clipboardSendSize;
1591  int ret;
1592 
1593  if (_glfw.wl.dataSource != dataSource)
1594  {
1596  "Wayland: Unknown clipboard data source");
1597  return;
1598  }
1599 
1600  if (!string)
1601  {
1603  "Wayland: Copy requested from an invalid string");
1604  return;
1605  }
1606 
1607  if (strcmp(mimeType, "text/plain;charset=utf-8") != 0)
1608  {
1610  "Wayland: Wrong MIME type asked from clipboard");
1611  close(fd);
1612  return;
1613  }
1614 
1615  while (len > 0)
1616  {
1617  ret = write(fd, string, len);
1618  if (ret == -1 && errno == EINTR)
1619  continue;
1620  if (ret == -1)
1621  {
1622  // TODO: also report errno maybe.
1624  "Wayland: Error while writing the clipboard");
1625  close(fd);
1626  return;
1627  }
1628  len -= ret;
1629  }
1630  close(fd);
1631 }
1632 
1634  struct wl_data_source* dataSource)
1635 {
1636  wl_data_source_destroy(dataSource);
1637 
1638  if (_glfw.wl.dataSource != dataSource)
1639  {
1641  "Wayland: Unknown clipboard data source");
1642  return;
1643  }
1644 
1645  _glfw.wl.dataSource = NULL;
1646 }
1647 
1648 static const struct wl_data_source_listener dataSourceListener = {
1652 };
1653 
1654 void _glfwPlatformSetClipboardString(const char* string)
1655 {
1656  if (_glfw.wl.dataSource)
1657  {
1658  wl_data_source_destroy(_glfw.wl.dataSource);
1659  _glfw.wl.dataSource = NULL;
1660  }
1661 
1662  if (_glfw.wl.clipboardSendString)
1663  {
1664  free(_glfw.wl.clipboardSendString);
1665  _glfw.wl.clipboardSendString = NULL;
1666  }
1667 
1668  _glfw.wl.clipboardSendString = strdup(string);
1669  if (!_glfw.wl.clipboardSendString)
1670  {
1672  "Wayland: Impossible to allocate clipboard string");
1673  return;
1674  }
1675  _glfw.wl.clipboardSendSize = strlen(string);
1676  _glfw.wl.dataSource =
1677  wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager);
1678  if (!_glfw.wl.dataSource)
1679  {
1681  "Wayland: Impossible to create clipboard source");
1682  free(_glfw.wl.clipboardSendString);
1683  return;
1684  }
1685  wl_data_source_add_listener(_glfw.wl.dataSource,
1687  NULL);
1688  wl_data_source_offer(_glfw.wl.dataSource, "text/plain;charset=utf-8");
1689  wl_data_device_set_selection(_glfw.wl.dataDevice,
1690  _glfw.wl.dataSource,
1691  _glfw.wl.serial);
1692 }
1693 
1695 {
1696  char* clipboard = _glfw.wl.clipboardString;
1697 
1698  clipboard = realloc(clipboard, _glfw.wl.clipboardSize * 2);
1699  if (!clipboard)
1700  {
1702  "Wayland: Impossible to grow clipboard string");
1703  return GLFW_FALSE;
1704  }
1705  _glfw.wl.clipboardString = clipboard;
1706  _glfw.wl.clipboardSize = _glfw.wl.clipboardSize * 2;
1707  return GLFW_TRUE;
1708 }
1709 
1711 {
1712  int fds[2];
1713  int ret;
1714  size_t len = 0;
1715 
1716  if (!_glfw.wl.dataOffer)
1717  {
1719  "No clipboard data has been sent yet");
1720  return NULL;
1721  }
1722 
1723  ret = pipe2(fds, O_CLOEXEC);
1724  if (ret < 0)
1725  {
1726  // TODO: also report errno maybe?
1728  "Wayland: Impossible to create clipboard pipe fds");
1729  return NULL;
1730  }
1731 
1732  wl_data_offer_receive(_glfw.wl.dataOffer, "text/plain;charset=utf-8", fds[1]);
1733  close(fds[1]);
1734 
1735  // XXX: this is a huge hack, this function shouldn’t be synchronous!
1736  handleEvents(-1);
1737 
1738  while (1)
1739  {
1740  // Grow the clipboard if we need to paste something bigger, there is no
1741  // shrink operation yet.
1742  if (len + 4096 > _glfw.wl.clipboardSize)
1743  {
1744  if (!growClipboardString())
1745  {
1746  close(fds[0]);
1747  return NULL;
1748  }
1749  }
1750 
1751  // Then read from the fd to the clipboard, handling all known errors.
1752  ret = read(fds[0], _glfw.wl.clipboardString + len, 4096);
1753  if (ret == 0)
1754  break;
1755  if (ret == -1 && errno == EINTR)
1756  continue;
1757  if (ret == -1)
1758  {
1759  // TODO: also report errno maybe.
1761  "Wayland: Impossible to read from clipboard fd");
1762  close(fds[0]);
1763  return NULL;
1764  }
1765  len += ret;
1766  }
1767  close(fds[0]);
1768  if (len + 1 > _glfw.wl.clipboardSize)
1769  {
1770  if (!growClipboardString())
1771  return NULL;
1772  }
1773  _glfw.wl.clipboardString[len] = '\0';
1774  return _glfw.wl.clipboardString;
1775 }
1776 
1778 {
1779  if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)
1780  return;
1781 
1782  extensions[0] = "VK_KHR_surface";
1783  extensions[1] = "VK_KHR_wayland_surface";
1784 }
1785 
1788  uint32_t queuefamily)
1789 {
1791  vkGetPhysicalDeviceWaylandPresentationSupportKHR =
1793  vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
1794  if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
1795  {
1797  "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
1798  return VK_NULL_HANDLE;
1799  }
1800 
1801  return vkGetPhysicalDeviceWaylandPresentationSupportKHR(device,
1802  queuefamily,
1803  _glfw.wl.display);
1804 }
1805 
1807  _GLFWwindow* window,
1808  const VkAllocationCallbacks* allocator,
1809  VkSurfaceKHR* surface)
1810 {
1811  VkResult err;
1813  PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
1814 
1815  vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)
1816  vkGetInstanceProcAddr(instance, "vkCreateWaylandSurfaceKHR");
1817  if (!vkCreateWaylandSurfaceKHR)
1818  {
1820  "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
1822  }
1823 
1824  memset(&sci, 0, sizeof(sci));
1826  sci.display = _glfw.wl.display;
1827  sci.surface = window->wl.surface;
1828 
1829  err = vkCreateWaylandSurfaceKHR(instance, &sci, allocator, surface);
1830  if (err)
1831  {
1833  "Wayland: Failed to create Vulkan surface: %s",
1835  }
1836 
1837  return err;
1838 }
1839 
1840 
1844 
1845 GLFWAPI struct wl_display* glfwGetWaylandDisplay(void)
1846 {
1848  return _glfw.wl.display;
1849 }
1850 
1852 {
1853  _GLFWwindow* window = (_GLFWwindow*) handle;
1855  return window->wl.surface;
1856 }
1857 
static const struct xdg_surface_listener xdgSurfaceListener
Definition: wl_window.c:661
uint32_t height
Definition: wl_platform.h:83
void _glfwPlatformSetCursor(_GLFWwindow *window, _GLFWcursor *cursor)
Definition: wl_window.c:1513
static void setIdleInhibitor(_GLFWwindow *window, GLFWbool enable)
Definition: wl_window.c:468
#define wl_egl_window_resize
Definition: wl_platform.h:107
GLint y
static void shellSurfaceHandlePing(void *data, struct wl_shell_surface *shellSurface, uint32_t serial)
Definition: wl_window.c:42
static GLFWbool createSurface(_GLFWwindow *window, const _GLFWwndconfig *wndconfig)
Definition: wl_window.c:486
GLenum GLsizei const void * pointer
struct wl_buffer * buffer
Definition: wl_platform.h:351
#define VK_NULL_HANDLE
Definition: vulkan_core.h:49
static GLFWbool growClipboardString(void)
Definition: wl_window.c:1694
int _glfwPlatformWindowHovered(_GLFWwindow *window)
Definition: wl_window.c:1263
GLuint const GLchar * name
VkResult
Definition: vulkan_core.h:122
void _glfwInputWindowCloseRequest(_GLFWwindow *window)
Definition: window.c:131
GLFWwindowcontentscalefun scale
Definition: internal.h:405
unsigned char * pixels
Definition: glfw3.h:1598
GLFWAPI struct wl_surface * glfwGetWaylandWindow(GLFWwindow *handle)
Definition: wl_window.c:1851
#define GLFWAPI
Definition: glfw3.h:240
GLdouble GLdouble GLdouble top
#define wl_cursor_theme_get_cursor
Definition: wl_platform.h:99
VkResult(APIENTRY * PFN_vkCreateWaylandSurfaceKHR)(VkInstance, const VkWaylandSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *)
Definition: wl_platform.h:45
GLFWAPI struct wl_display * glfwGetWaylandDisplay(void)
Definition: wl_window.c:1845
static void setFullscreen(_GLFWwindow *window, _GLFWmonitor *monitor, int refreshRate)
Definition: wl_window.c:515
struct wl_display * display
Definition: wl_platform.h:41
static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener
Definition: wl_window.c:336
static GLFWbool createXdgSurface(_GLFWwindow *window)
Definition: wl_window.c:686
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:10806
static GLFWwindow * window
Definition: joysticks.c:55
GLFWbool _glfwInitOSMesa(void)
void _glfwPlatformPostEmptyEvent(void)
Definition: wl_window.c:1322
GLuint64 GLenum void * handle
Definition: glext.h:7785
void _glfwPlatformSetWindowSize(_GLFWwindow *window, int width, int height)
Definition: wl_window.c:1056
GLsizei const GLchar *const * path
Definition: glext.h:4276
_GLFWdestroycontextfun destroy
Definition: internal.h:353
struct wl_surface * surface
Definition: wl_platform.h:166
void _glfwInputFramebufferSize(_GLFWwindow *window, int width, int height)
Definition: window.c:106
int height
Definition: glfw3.h:1595
static const struct wl_data_source_listener dataSourceListener
Definition: wl_window.c:1648
static void setCursorImage(_GLFWwindow *window, _GLFWcursorWayland *cursorWayland)
Definition: wl_window.c:747
static const struct wl_shell_surface_listener shellSurfaceListener
Definition: wl_window.c:102
static const struct zwp_relative_pointer_v1_listener relativePointerListener
Definition: wl_window.c:1435
void _glfwPlatformHideWindow(_GLFWwindow *window)
Definition: wl_window.c:1188
static void shellSurfaceHandleConfigure(void *data, struct wl_shell_surface *shellSurface, uint32_t edges, int32_t width, int32_t height)
Definition: wl_window.c:49
void _glfwPlatformSetWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
Definition: wl_window.c:1218
#define GLFW_FALSE
Zero.
Definition: glfw3.h:287
int _glfwPlatformWindowFocused(_GLFWwindow *window)
Definition: wl_window.c:1241
struct wl_cursor_image ** images
Definition: wl_platform.h:90
char * _glfw_strdup(const char *source)
Definition: init.c:114
int _glfwPlatformCreateCursor(_GLFWcursor *cursor, const GLFWimage *image, int xhot, int yhot)
Definition: wl_window.c:1364
void _glfwPlatformSetWindowTitle(_GLFWwindow *window, const char *title)
Definition: wl_window.c:1013
const char * _glfwGetVulkanResultString(VkResult result)
Definition: src/vulkan.c:159
struct _GLFWlibrary::@29 vk
#define GLFW_CROSSHAIR_CURSOR
The crosshair shape.
Definition: glfw3.h:1040
static void surfaceHandleEnter(void *data, struct wl_surface *surface, struct wl_output *output)
Definition: wl_window.c:422
static void dataSourceHandleSend(void *data, struct wl_data_source *dataSource, const char *mimeType, int fd)
Definition: wl_window.c:1584
#define GLFW_API_UNAVAILABLE
GLFW could not find support for the requested API on the system.
Definition: glfw3.h:698
#define GLFW_EGL_CONTEXT_API
Definition: glfw3.h:1015
void _glfwPlatformSetWindowResizable(_GLFWwindow *window, GLFWbool enabled)
Definition: wl_window.c:1273
void _glfwPlatformRestoreWindow(_GLFWwindow *window)
Definition: wl_window.c:1142
#define _GLFW_DECORATION_WIDTH
Definition: wl_platform.h:149
void _glfwPlatformWaitEventsTimeout(double timeout)
Definition: wl_window.c:1317
#define GLFW_FORMAT_UNAVAILABLE
The requested format is not supported or available.
Definition: glfw3.h:745
#define GLFW_ARROW_CURSOR
The regular arrow cursor shape.
Definition: glfw3.h:1030
_GLFWcontext context
Definition: internal.h:394
void _glfwPlatformRequestWindowAttention(_GLFWwindow *window)
Definition: wl_window.c:1205
void _glfwPlatformGetCursorPos(_GLFWwindow *window, double *xpos, double *ypos)
Definition: wl_window.c:1327
_GLFWwindow * windowListHead
Definition: internal.h:526
int GLFWbool
Definition: internal.h:61
GLenum GLfloat * buffer
static void xdgDecorationHandleConfigure(void *data, struct zxdg_toplevel_decoration_v1 *decoration, uint32_t mode)
Definition: wl_window.c:324
static void xdgToplevelHandleConfigure(void *data, struct xdg_toplevel *toplevel, int32_t width, int32_t height, struct wl_array *states)
Definition: wl_window.c:584
struct wl_subsurface * subsurface
Definition: wl_platform.h:167
const char * title
Definition: internal.h:258
void _glfwInputWindowDamage(_GLFWwindow *window)
Definition: window.c:123
GLenum GLenum GLsizei void * image
#define GLFW_DONT_CARE
Definition: glfw3.h:1080
void _glfwInputCursorEnter(_GLFWwindow *window, GLFWbool entered)
Definition: input.c:352
static void shellSurfaceHandlePopupDone(void *data, struct wl_shell_surface *shellSurface)
Definition: wl_window.c:97
GLFWbool KHR_surface
Definition: internal.h:553
int _glfwPlatformCreateWindow(_GLFWwindow *window, const _GLFWwndconfig *wndconfig, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
Definition: wl_window.c:903
void _glfwPlatformSetClipboardString(const char *string)
Definition: wl_window.c:1654
GLenum GLsizei len
Definition: glext.h:3285
GLuint64 key
Definition: glext.h:8966
void _glfwPlatformGetRequiredInstanceExtensions(char **extensions)
Definition: wl_window.c:1777
#define GLFW_CURSOR_DISABLED
Definition: glfw3.h:1008
static void lockPointer(_GLFWwindow *window)
Definition: wl_window.c:1470
void _glfwPlatformSetWindowPos(_GLFWwindow *window, int xpos, int ypos)
Definition: wl_window.c:1040
void _glfwPlatformGetWindowFrameSize(_GLFWwindow *window, int *left, int *top, int *right, int *bottom)
Definition: wl_window.c:1102
GLFWbool transparent
Definition: internal.h:328
static const struct zwp_locked_pointer_v1_listener lockedPointerListener
Definition: wl_window.c:1465
uint32_t hotspot_x
Definition: wl_platform.h:84
int maxwidth
Definition: internal.h:382
#define GLFW_VRESIZE_CURSOR
The vertical resize arrow shape.
Definition: glfw3.h:1055
#define _GLFW_REQUIRE_INIT_OR_RETURN(x)
Definition: internal.h:210
int _glfwPlatformWindowIconified(_GLFWwindow *window)
Definition: wl_window.c:1246
GLenum mode
static void resizeWindow(_GLFWwindow *window)
Definition: wl_window.c:356
static int createAnonymousFile(off_t size)
Definition: wl_window.c:139
static void handleEvents(int timeout)
Definition: wl_window.c:809
static void incrementCursorImage(_GLFWwindow *window)
Definition: wl_window.c:793
GLfloat GLfloat GLfloat alpha
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
Definition: wl_window.c:1063
GLsizeiptr size
GLFWbool _glfwCreateContextEGL(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
Definition: egl_context.c:456
#define _GLFW_DECORATION_TOP
Definition: wl_platform.h:150
int maxheight
Definition: internal.h:382
#define GLFW_CURSOR_NORMAL
Definition: glfw3.h:1006
#define GLFW_PLATFORM_ERROR
A platform-specific error occurred that does not match any of the more specific categories.
Definition: glfw3.h:726
#define GLFW_NATIVE_CONTEXT_API
Definition: glfw3.h:1014
_GLFWlibrary _glfw
Definition: init.c:44
float _glfwPlatformGetWindowOpacity(_GLFWwindow *window)
Definition: wl_window.c:1298
uint32_t hotspot_y
Definition: wl_platform.h:85
int _glfwPlatformCreateStandardCursor(_GLFWcursor *cursor, int shape)
Definition: wl_window.c:1379
void _glfwInputWindowFocus(_GLFWwindow *window, GLFWbool focused)
Definition: window.c:43
void _glfwPlatformSetWindowIcon(_GLFWwindow *window, int count, const GLFWimage *images)
Definition: wl_window.c:1024
void _glfwPlatformSetCursorPos(_GLFWwindow *window, double x, double y)
Definition: wl_window.c:1337
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow *window, int numer, int denom)
Definition: wl_window.c:1087
GLdouble x
void * VkInstance
Definition: internal.h:118
#define GLFW_HAND_CURSOR
The hand shape.
Definition: glfw3.h:1045
unsigned int uint32_t
Definition: stdint.h:80
static void lockedPointerHandleUnlocked(void *data, struct zwp_locked_pointer_v1 *lockedPointer)
Definition: wl_window.c:1460
void _glfwInputWindowContentScale(_GLFWwindow *window, float xscale, float yscale)
Definition: window.c:115
int cursorMode
Definition: internal.h:388
void * VkPhysicalDevice
Definition: internal.h:119
GLuint * states
Definition: glext.h:9573
GLint GLsizei GLsizei height
#define _GLFW_DECORATION_HORIZONTAL
Definition: wl_platform.h:152
static void dataSourceHandleTarget(void *data, struct wl_data_source *dataSource, const char *mimeType)
Definition: wl_window.c:1572
static void setXdgDecorations(_GLFWwindow *window)
Definition: wl_window.c:665
struct _GLFWwindow * next
Definition: internal.h:367
GLenum target
Definition: glext.h:1565
static void destroyDecorations(_GLFWwindow *window)
Definition: wl_window.c:316
static void lockedPointerHandleLocked(void *data, struct zwp_locked_pointer_v1 *lockedPointer)
Definition: wl_window.c:1439
unsigned __int64 uint64_t
Definition: stdint.h:90
static GLFWbool createShellSurface(_GLFWwindow *window)
Definition: wl_window.c:537
GLenum GLenum GLsizei const GLuint GLboolean enabled
void _glfwInputKey(_GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: input.c:259
void _glfwPlatformGetWindowContentScale(_GLFWwindow *window, float *xscale, float *yscale)
Definition: wl_window.c:1119
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName)
GLdouble GLdouble GLint stride
GLint left
Definition: glext.h:1963
double virtualCursorPosY
Definition: internal.h:392
uint64_t VkSurfaceKHR
Definition: internal.h:120
#define GLFW_OSMESA_CONTEXT_API
Definition: glfw3.h:1016
struct wp_viewport * viewport
Definition: wl_platform.h:168
static void setOpaqueRegion(_GLFWwindow *window)
Definition: wl_window.c:341
int minwidth
Definition: internal.h:381
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
Definition: wl_window.c:1806
void _glfwInputError(int code, const char *format,...)
Definition: init.c:129
void _glfwPlatformIconifyWindow(_GLFWwindow *window)
Definition: wl_window.c:1128
void _glfwPlatformShowWindow(_GLFWwindow *window)
Definition: wl_window.c:1176
#define wl_egl_window_destroy
Definition: wl_platform.h:106
GLFWbool visible
Definition: internal.h:260
struct wl_cursor * cursor
Definition: wl_platform.h:349
void _glfwInputWindowSize(_GLFWwindow *window, int width, int height)
Definition: window.c:81
VkBool32(APIENTRY * PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice, uint32_t, struct wl_display *)
Definition: wl_platform.h:46
static const struct xdg_toplevel_listener xdgToplevelListener
Definition: wl_window.c:649
#define wl_egl_window_create
Definition: wl_platform.h:105
int _glfwPlatformGetKeyScancode(int key)
Definition: wl_window.c:1359
uint32_t delay
Definition: wl_platform.h:86
void _glfwPlatformPollEvents(void)
Definition: wl_window.c:1307
void _glfwInputWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor)
Definition: window.c:141
int width
Definition: glfw3.h:1592
#define GLFW_TRUE
One.
Definition: glfw3.h:279
void _glfwInputCursorPos(_GLFWwindow *window, double xpos, double ypos)
Definition: input.c:338
void _glfwPlatformSetWindowFloating(_GLFWwindow *window, GLFWbool enabled)
Definition: wl_window.c:1291
GLFWbool autoIconify
Definition: internal.h:372
void _glfwPlatformMaximizeWindow(_GLFWwindow *window)
Definition: wl_window.c:1162
void _glfwPlatformSetWindowDecorated(_GLFWwindow *window, GLFWbool enabled)
Definition: wl_window.c:1280
#define GLFW_CURSOR_HIDDEN
Definition: glfw3.h:1007
static int createTmpfileCloexec(char *tmpname)
Definition: wl_window.c:108
void _glfwPlatformSetCursorMode(_GLFWwindow *window, int mode)
Definition: wl_window.c:1348
static void destroyDecoration(_GLFWdecorationWayland *decoration)
Definition: wl_window.c:303
GLboolean enable
Definition: glext.h:5688
GLdouble right
GLbitfield GLuint64 timeout
static void xdgToplevelHandleClose(void *data, struct xdg_toplevel *toplevel)
Definition: wl_window.c:642
static void createDecoration(_GLFWdecorationWayland *decoration, struct wl_surface *parent, struct wl_buffer *buffer, GLFWbool opaque, int x, int y, int width, int height)
Definition: wl_window.c:241
#define GLFW_HRESIZE_CURSOR
The horizontal resize arrow shape.
Definition: glfw3.h:1050
static double xpos
Definition: splitview.c:33
#define GLFW_IBEAM_CURSOR
The text input I-beam cursor shape.
Definition: glfw3.h:1035
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
static const char * maximized
Definition: model-views.h:183
GLint GLsizei count
int _glfwPlatformWindowMaximized(_GLFWwindow *window)
Definition: wl_window.c:1258
static void relativePointerHandleRelativeMotion(void *data, struct zwp_relative_pointer_v1 *pointer, uint32_t timeHi, uint32_t timeLo, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dxUnaccel, wl_fixed_t dyUnaccel)
Definition: wl_window.c:1416
int _glfwPlatformFramebufferTransparent(_GLFWwindow *window)
Definition: wl_window.c:1268
uint32_t width
Definition: wl_platform.h:82
static void unlockPointer(_GLFWwindow *window)
Definition: wl_window.c:1444
int _glfwPlatformWindowVisible(_GLFWwindow *window)
Definition: wl_window.c:1253
int minheight
Definition: internal.h:381
void _glfwPlatformDestroyWindow(_GLFWwindow *window)
Definition: wl_window.c:968
GLsizei GLsizei GLchar * source
void display(void)
Definition: boing.c:194
static void checkScaleChange(_GLFWwindow *window)
Definition: wl_window.c:395
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
Definition: wl_window.c:1786
#define NULL
Definition: tinycthread.c:47
void _glfwPlatformGetWindowPos(_GLFWwindow *window, int *xpos, int *ypos)
Definition: wl_window.c:1031
int i
GLenum GLuint GLenum GLsizei length
const char * _glfwPlatformGetClipboardString(void)
Definition: wl_window.c:1710
const char * _glfwPlatformGetScancodeName(int scancode)
Definition: wl_window.c:1353
void _glfwPlatformGetFramebufferSize(_GLFWwindow *window, int *width, int *height)
Definition: wl_window.c:1094
static void dataSourceHandleCancelled(void *data, struct wl_data_source *dataSource)
Definition: wl_window.c:1633
static char * translateCursorShape(int shape)
Definition: wl_window.c:879
struct wl_cursor * cursorHiDPI
Definition: wl_platform.h:350
static void createDecorations(_GLFWwindow *window)
Definition: wl_window.c:271
Image data.
Definition: glfw3.h:1588
signed int int32_t
Definition: stdint.h:77
static struct wl_buffer * createShmBuffer(const GLFWimage *image)
Definition: wl_window.c:188
#define _GLFW_DECORATION_VERTICAL
Definition: wl_platform.h:151
static const struct wl_surface_listener surfaceListener
Definition: wl_window.c:463
GLFWbool _glfwInitEGL(void)
Definition: egl_context.c:300
GLuint64 GLenum GLint fd
Definition: glext.h:7768
void _glfwPlatformFocusWindow(_GLFWwindow *window)
Definition: wl_window.c:1212
#define GLFW_REPEAT
The key was held down until it repeated.
Definition: glfw3.h:311
static void surfaceHandleLeave(void *data, struct wl_surface *surface, struct wl_output *output)
Definition: wl_window.c:442
GLboolean * data
double virtualCursorPosX
Definition: internal.h:392
_GLFWmonitor * monitor
Definition: internal.h:378
struct wl_surface * surface
Definition: wl_platform.h:42
GLFWbool decorated
Definition: internal.h:371
#define wl_cursor_image_get_buffer
Definition: wl_platform.h:100
auto device
Definition: pyrs_net.cpp:17
GLFWwindowfocusfun focus
Definition: internal.h:401
void _glfwPlatformSetWindowOpacity(_GLFWwindow *window, float opacity)
Definition: wl_window.c:1303
struct GLFWwindow GLFWwindow
Definition: parser.hpp:150
GLint GLsizei width
static double ypos
Definition: splitview.c:33
void _glfwPlatformDestroyCursor(_GLFWcursor *cursor)
Definition: wl_window.c:1406
#define GLFW_NO_API
Definition: glfw3.h:989
static void xdgSurfaceHandleConfigure(void *data, struct xdg_surface *surface, uint32_t serial)
Definition: wl_window.c:654
static GLFWbool isPointerLocked(_GLFWwindow *window)
Definition: wl_window.c:1508
GLdouble GLdouble bottom
void _glfwPlatformWaitEvents(void)
Definition: wl_window.c:1312
void _glfwPlatformGetWindowSize(_GLFWwindow *window, int *width, int *height)
Definition: wl_window.c:1048


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:50:23