static void
clutter_backend_wayland_load_cursor (ClutterBackendWayland *backend_wayland)
{
  struct wl_cursor *cursor;

  backend_wayland->cursor_theme =
    wl_cursor_theme_load (NULL, /* default */
                          32,
                          backend_wayland->wayland_shm);

  cursor = wl_cursor_theme_get_cursor (backend_wayland->cursor_theme,
                                       "left_ptr");

  backend_wayland->cursor_buffer =
    wl_cursor_image_get_buffer (cursor->images[0]);

  if (backend_wayland->cursor_buffer)
    {
      backend_wayland->cursor_x = cursor->images[0]->hotspot_x;
      backend_wayland->cursor_y = cursor->images[0]->hotspot_y;
    }

  backend_wayland->cursor_surface =
    wl_compositor_create_surface (backend_wayland->wayland_compositor);
}
Esempio n. 2
0
static void
registry_handle_global(void *data, struct wl_registry *registry,
		       uint32_t name, const char *interface, uint32_t version)
{
	struct display *d = data;

	if (strcmp(interface, "wl_compositor") == 0) {
		d->compositor =
			wl_registry_bind(registry, name,
					 &wl_compositor_interface, 1);
	} else if (strcmp(interface, "xdg_shell") == 0) {
		d->shell = wl_registry_bind(registry, name,
					    &xdg_shell_interface, 1);
		xdg_shell_add_listener(d->shell, &xdg_shell_listener, d);
		xdg_shell_use_unstable_version(d->shell, XDG_VERSION);
	} else if (strcmp(interface, "wl_seat") == 0) {
		d->seat = wl_registry_bind(registry, name,
					   &wl_seat_interface, 1);
		wl_seat_add_listener(d->seat, &seat_listener, d);
	} else if (strcmp(interface, "wl_shm") == 0) {
		d->shm = wl_registry_bind(registry, name,
					  &wl_shm_interface, 1);
		d->cursor_theme = wl_cursor_theme_load(NULL, 32, d->shm);
		d->default_cursor =
			wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
	}
}
Esempio n. 3
0
static void
registry_handle_global(void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version)
{
	if (strcmp(interface, "wl_compositor") == 0) {
		GLWin.wl_compositor = (wl_compositor *)
			wl_registry_bind(registry, name,
			&wl_compositor_interface, 1);
	}
	else if (strcmp(interface, "wl_shell") == 0) {
		GLWin.wl_shell = (wl_shell *)wl_registry_bind(registry, name,
			&wl_shell_interface, 1);
	}
	else if (strcmp(interface, "wl_seat") == 0) {
		GLWin.wl_seat = (wl_seat *)wl_registry_bind(registry, name,
			&wl_seat_interface, 1);
		wl_seat_add_listener(GLWin.wl_seat, &seat_listener, 0);
	}
	else if (strcmp(interface, "wl_shm") == 0) {
		GLWin.wl_shm = (wl_shm *)wl_registry_bind(registry, name,
			&wl_shm_interface, 1);
		GLWin.wl_cursor_theme = (wl_cursor_theme *)wl_cursor_theme_load(nullptr, 32, GLWin.wl_shm);
		GLWin.wl_cursor = (wl_cursor *)
			wl_cursor_theme_get_cursor(GLWin.wl_cursor_theme, "left_ptr");
	}
}
Esempio n. 4
0
struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height, bool shell_surface) {
	struct window *window = malloc(sizeof(struct window));
	memset(window, 0, sizeof(struct window));
	window->width = width;
	window->height = height;
	window->registry = registry;

	window->surface = wl_compositor_create_surface(registry->compositor);
	if (shell_surface) {
		window->shell_surface = wl_shell_get_shell_surface(registry->shell, window->surface);
		wl_shell_surface_add_listener(window->shell_surface, &surface_listener, window);
		wl_shell_surface_set_toplevel(window->shell_surface);
	}
	if (registry->pointer) {
		wl_pointer_add_listener(registry->pointer, &pointer_listener, window);
	}

	window->cursor.cursor_theme = wl_cursor_theme_load("default", 32, registry->shm); // TODO: let you customize this
	window->cursor.cursor = wl_cursor_theme_get_cursor(window->cursor.cursor_theme, "left_ptr");
	window->cursor.surface = wl_compositor_create_surface(registry->compositor);

	struct wl_cursor_image *image = window->cursor.cursor->images[0];
	struct wl_buffer *cursor_buf = wl_cursor_image_get_buffer(image);
	wl_surface_attach(window->cursor.surface, cursor_buf, 0, 0);
	wl_surface_damage(window->cursor.surface, 0, 0, image->width, image->height);
	wl_surface_commit(window->cursor.surface);

	return window;
}
static void
registry_handle_global (void *data, struct wl_registry *registry,
    uint32_t name, const char *interface, uint32_t version)
{
  GstGLWindowWaylandEGL *window_egl = data;
  struct display *d = &window_egl->display;

  GST_TRACE_OBJECT (window_egl, "registry_handle_global with registry %p, "
      "interface %s, version %u", registry, interface, version);

  if (g_strcmp0 (interface, "wl_compositor") == 0) {
    d->compositor =
        wl_registry_bind (registry, name, &wl_compositor_interface, 1);
  } else if (g_strcmp0 (interface, "wl_shell") == 0) {
    d->shell = wl_registry_bind (registry, name, &wl_shell_interface, 1);
  } else if (g_strcmp0 (interface, "wl_seat") == 0) {
    d->seat = wl_registry_bind (registry, name, &wl_seat_interface, 1);
    wl_seat_add_listener (d->seat, &seat_listener, window_egl);
  } else if (g_strcmp0 (interface, "wl_shm") == 0) {
    d->shm = wl_registry_bind (registry, name, &wl_shm_interface, 1);
    d->cursor_theme = wl_cursor_theme_load (NULL, 32, d->shm);
    d->default_cursor =
        wl_cursor_theme_get_cursor (d->cursor_theme, "left_ptr");
  }
}
Esempio n. 6
0
int _glfwPlatformInit(void)
{
    _glfw.wl.display = wl_display_connect(NULL);
    if (!_glfw.wl.display)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to connect to display");
        return GLFW_FALSE;
    }

    _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
    wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);

    _glfw.wl.monitors = calloc(4, sizeof(_GLFWmonitor*));
    _glfw.wl.monitorsSize = 4;

    _glfw.wl.xkb.context = xkb_context_new(0);
    if (!_glfw.wl.xkb.context)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to initialize xkb context");
        return GLFW_FALSE;
    }

    // Sync so we got all registry objects
    wl_display_roundtrip(_glfw.wl.display);

    // Sync so we got all initial output events
    wl_display_roundtrip(_glfw.wl.display);

    if (!_glfwInitContextAPI())
        return GLFW_FALSE;

    _glfwInitTimer();
    _glfwInitJoysticks();

    if (_glfw.wl.pointer && _glfw.wl.shm)
    {
        _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm);
        if (!_glfw.wl.cursorTheme)
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "Wayland: Unable to load default cursor theme\n");
            return GLFW_FALSE;
        }
        _glfw.wl.defaultCursor =
            wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, "left_ptr");
        if (!_glfw.wl.defaultCursor)
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "Wayland: Unable to load default left pointer\n");
            return GLFW_FALSE;
        }
        _glfw.wl.cursorSurface =
            wl_compositor_create_surface(_glfw.wl.compositor);
    }

    return GLFW_TRUE;
}
Esempio n. 7
0
static void
_eventd_nd_wl_registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
{
    EventdNdBackendContext *self = data;

    if ( g_strcmp0(interface, "wl_compositor") == 0 )
    {
        self->global_names[EVENTD_ND_WL_GLOBAL_COMPOSITOR] = name;
        self->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, MIN(version, WL_COMPOSITOR_INTERFACE_VERSION));
    }
    else if ( g_strcmp0(interface, "zww_notification_area_v1") == 0 )
    {
        self->global_names[EVENTD_ND_WL_GLOBAL_NOTIFICATION_DAEMON] = name;
        self->notification_area = wl_registry_bind(registry, name, &zww_notification_area_v1_interface, WW_NOTIFICATION_AREA_INTERFACE_VERSION);
        zww_notification_area_v1_add_listener(self->notification_area, &_eventd_nd_wl_notification_area_listener, self);
    }
    else if ( g_strcmp0(interface, "wl_shm") == 0 )
    {
        self->global_names[EVENTD_ND_WL_GLOBAL_SHM] = name;
        self->shm = wl_registry_bind(registry, name, &wl_shm_interface, MIN(version, WL_SHM_INTERFACE_VERSION));
        wl_shm_add_listener(self->shm, &_eventd_nd_wl_shm_listener, self);
    }
    else if ( g_strcmp0(interface, "wl_seat") == 0 )
    {
        EventdNdWlSeat *seat = g_slice_new0(EventdNdWlSeat);
        seat->context = self;
        seat->global_name = name;
        seat->seat = wl_registry_bind(registry, name, &wl_seat_interface, MIN(version, WL_SEAT_INTERFACE_VERSION));

        seat->link = self->seats = g_slist_prepend(self->seats, seat);

        wl_seat_add_listener(seat->seat, &_eventd_nd_wl_seat_listener, seat);
    }

    if ( ( self->cursor.theme == NULL ) && ( self->compositor != NULL ) && ( self->shm != NULL ) )
    {
        self->cursor.theme = wl_cursor_theme_load(self->cursor.theme_name, 32, self->shm);
        if ( self->cursor.theme != NULL )
        {
            const gchar * const *cname = (const gchar * const *) self->cursor.name;
            for ( cname = ( cname != NULL ) ? cname : _eventd_nd_cursor_names ; ( self->cursor.cursor == NULL ) && ( *cname != NULL ) ; ++cname )
                self->cursor.cursor = wl_cursor_theme_get_cursor(self->cursor.theme, *cname);
            if ( self->cursor.cursor == NULL )
            {
                wl_cursor_theme_destroy(self->cursor.theme);
                self->cursor.theme = NULL;
            }
            else
                self->cursor.surface = wl_compositor_create_surface(self->compositor);
        }
    }
}
Esempio n. 8
0
EAPI void
ecore_wl_input_cursor_size_set(Ecore_Wl_Input *input, const int size)
{
   LOGFN(__FILE__, __LINE__, __FUNCTION__);

   if (!input) return;

   input->cursor_size = size;

   EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm);

   input->display->cursor_theme =
     wl_cursor_theme_load(NULL, input->cursor_size, input->display->wl.shm);
}
Esempio n. 9
0
EAPI void
ecore_wl_input_cursor_theme_name_set(Ecore_Wl_Input *input, const char *cursor_theme_name)
{
   LOGFN(__FILE__, __LINE__, __FUNCTION__);

   if (!input) return;

   eina_stringshare_replace(&input->cursor_theme_name, cursor_theme_name);

   EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm);

   input->display->cursor_theme =
     wl_cursor_theme_load(input->cursor_theme_name, input->cursor_size,
                          input->display->wl.shm);
}
Esempio n. 10
0
struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height,
		int32_t scale, bool shell_surface) {
	struct window *window = malloc(sizeof(struct window));
	memset(window, 0, sizeof(struct window));
	window->width = width;
	window->height = height;
	window->scale = scale;
	window->registry = registry;
	window->font = "monospace 10";

	window->surface = wl_compositor_create_surface(registry->compositor);
	if (shell_surface) {
		window_make_shell(window);
	}
	if (registry->pointer) {
		wl_pointer_add_listener(registry->pointer, &pointer_listener, window);
	}

	get_next_buffer(window);

	if (registry->pointer) {
		char *cursor_theme = getenv("SWAY_CURSOR_THEME");
		if (!cursor_theme) {
			cursor_theme = "default";
		}
		char *cursor_size = getenv("SWAY_CURSOR_SIZE");
		if (!cursor_size) {
			cursor_size = "16";
		}

		sway_log(L_DEBUG, "Cursor scale: %d", scale);
		window->cursor.cursor_theme = wl_cursor_theme_load(cursor_theme,
				atoi(cursor_size) * scale, registry->shm);
		window->cursor.cursor = wl_cursor_theme_get_cursor(window->cursor.cursor_theme, "left_ptr");
		window->cursor.surface = wl_compositor_create_surface(registry->compositor);

		struct wl_cursor_image *image = window->cursor.cursor->images[0];
		struct wl_buffer *cursor_buf = wl_cursor_image_get_buffer(image);
		wl_surface_attach(window->cursor.surface, cursor_buf, 0, 0);
		wl_surface_set_buffer_scale(window->cursor.surface, scale);
		wl_surface_damage(window->cursor.surface, 0, 0,
				image->width, image->height);
		wl_surface_commit(window->cursor.surface);
	}

	return window;
}
Esempio n. 11
0
QT_USE_NAMESPACE

QWaylandCursor::QWaylandCursor(QWaylandScreen *screen)
    : mDisplay(screen->display())
{
    //TODO: Make wl_cursor_theme_load arguments configurable here
    QByteArray cursorTheme = qgetenv("XCURSOR_THEME");
    if (cursorTheme.isEmpty())
        cursorTheme = QByteArray("default");
    QByteArray cursorSizeFromEnv = qgetenv("XCURSOR_SIZE");
    bool hasCursorSize = false;
    int cursorSize = cursorSizeFromEnv.toInt(&hasCursorSize);
    if (!hasCursorSize || cursorSize <= 0)
        cursorSize = 32;
    mCursorTheme = wl_cursor_theme_load(cursorTheme, cursorSize, mDisplay->shm());
    initCursorMap();
}
Esempio n. 12
0
int
main(int argc, char **argv)
{
    int i, ret = 0, cursor_count = argc - 3;
    struct sigaction sigint;
    struct cursor_viewer *viewer;
    struct cursor_surface **cursors;

    if (argc < 4) {
        printf("Usage: %s CURSOR_THEME SIZE CURSOR_NAMES...\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    sigint.sa_handler = signal_int;
    sigemptyset(&sigint.sa_mask);
    sigint.sa_flags = SA_RESETHAND;
    sigaction(SIGINT, &sigint, NULL);

    viewer = cursor_viewer_create();

    viewer->cursor_theme =
        wl_cursor_theme_load(argv[1], atoi(argv[2]), viewer->shm);
    if (!viewer->cursor_theme)
        die("Failed to load default cursor theme\n");

    cursors = calloc(1, sizeof (struct cursor_surface *) * cursor_count);

    for (i = 3; i < argc; ++i) {
        struct cursor_surface *cursor =
            cursor_viewer_show_cursor(viewer, argv[i]);

        cursors[i - 3] = cursor;
    }

    while (running && ret != -1)
        ret = wl_display_dispatch(viewer->display);

    for (i = 0; i < cursor_count; ++i)
        cursor_surface_destroy(cursors[i]);
    free(cursors);

    cursor_viewer_destroy(viewer);

    exit(EXIT_SUCCESS);
}
Esempio n. 13
0
static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver)
{
#ifdef HAVE_OPENGL
   static const EGLint egl_attribs_gl[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
      EGL_NONE,
   };
#endif

#ifdef HAVE_OPENGLES
#ifdef HAVE_OPENGLES2
   static const EGLint egl_attribs_gles[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL_NONE,
   };
#endif

#ifdef HAVE_OPENGLES3
#ifdef EGL_KHR_create_context
   static const EGLint egl_attribs_gles3[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
      EGL_NONE,
   };
#endif
#endif

#endif

#ifdef HAVE_EGL
   static const EGLint egl_attribs_vg[] = {
      WL_EGL_ATTRIBS_BASE,
      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
      EGL_NONE,
   };

   EGLint major = 0, minor = 0;
   EGLint n;
   const EGLint *attrib_ptr = NULL;
#endif
   gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)
      calloc(1, sizeof(gfx_ctx_wayland_data_t));

   if (!wl)
      return NULL;

   (void)video_driver;

#ifdef HAVE_EGL
   switch (wl_api)
   {
      case GFX_CTX_OPENGL_API:
#ifdef HAVE_OPENGL
         attrib_ptr = egl_attribs_gl;
#endif
         break;
      case GFX_CTX_OPENGL_ES_API:
#ifdef HAVE_OPENGLES
#ifdef HAVE_OPENGLES3
#ifdef EGL_KHR_create_context
         if (g_egl_major >= 3)
            attrib_ptr = egl_attribs_gles3;
         else
#endif
#endif
#ifdef HAVE_OPENGLES2
            attrib_ptr = egl_attribs_gles;
#endif
#endif
         break;
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_VG
         attrib_ptr = egl_attribs_vg;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }
#endif

   frontend_driver_destroy_signal_handler_state();

   wl->input.dpy = wl_display_connect(NULL);
   wl->buffer_scale = 1;

   if (!wl->input.dpy)
   {
      RARCH_ERR("[Wayland]: Failed to connect to Wayland server.\n");
      goto error;
   }

   frontend_driver_install_signal_handler();

   wl->registry = wl_display_get_registry(wl->input.dpy);
   wl_registry_add_listener(wl->registry, &registry_listener, wl);
   wl_display_roundtrip(wl->input.dpy);

   if (!wl->compositor)
   {
      RARCH_ERR("[Wayland]: Failed to create compositor.\n");
      goto error;
   }

   if (!wl->shm)
   {
      RARCH_ERR("[Wayland]: Failed to create shm.\n");
      goto error;
   }

   if (!wl->shell)
   {
      RARCH_ERR("[Wayland]: Failed to create shell.\n");
      goto error;
   }

   wl->input.fd = wl_display_get_fd(wl->input.dpy);

   switch (wl_api)
   {
      case GFX_CTX_OPENGL_API:
      case GFX_CTX_OPENGL_ES_API:
      case GFX_CTX_OPENVG_API:
#ifdef HAVE_EGL
         if (!egl_init_context(&wl->egl,
                  EGL_PLATFORM_WAYLAND_KHR,
                  (EGLNativeDisplayType)wl->input.dpy,
                  &major, &minor, &n, attrib_ptr))
         {
            egl_report_error();
            goto error;
         }

         if (n == 0 || !egl_has_config(&wl->egl))
            goto error;
#endif
         break;
      case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
         if (!vulkan_context_init(&wl->vk, VULKAN_WSI_WAYLAND))
            goto error;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   wl->input.keyboard_focus = true;
   wl->input.mouse.focus = true;

   wl->cursor.surface = wl_compositor_create_surface(wl->compositor);
   wl->cursor.theme = wl_cursor_theme_load(NULL, 16, wl->shm);
   wl->cursor.default_cursor = wl_cursor_theme_get_cursor(wl->cursor.theme, "left_ptr");
   flush_wayland_fd(&wl->input);

   return wl;

error:
   gfx_ctx_wl_destroy_resources(wl);

   if (wl)
      free(wl);

   return NULL;
}
Esempio n. 14
0
static void fghInitialiseCursorTheme(void)
{
    fgDisplay.pDisplay.cursor_theme = wl_cursor_theme_load (
                                        "default", 32,
                                        fgDisplay.pDisplay.shm );
};
Esempio n. 15
0
int _glfwPlatformInit(void)
{
    _glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
    if (!_glfw.wl.cursor.handle)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to open libwayland-cursor");
        return GLFW_FALSE;
    }

    _glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load)
        _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_load");
    _glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy)
        _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
    _glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor)
        _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
    _glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer)
        _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");

    _glfw.wl.egl.handle = _glfw_dlopen("libwayland-egl.so.1");
    if (!_glfw.wl.egl.handle)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to open libwayland-egl");
        return GLFW_FALSE;
    }

    _glfw.wl.egl.window_create = (PFN_wl_egl_window_create)
        _glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_create");
    _glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy)
        _glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_destroy");
    _glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize)
        _glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_resize");

    _glfw.wl.xkb.handle = _glfw_dlopen("libxkbcommon.so.0");
    if (!_glfw.wl.xkb.handle)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to open libxkbcommon");
        return GLFW_FALSE;
    }

    _glfw.wl.xkb.context_new = (PFN_xkb_context_new)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_context_new");
    _glfw.wl.xkb.context_unref = (PFN_xkb_context_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_context_unref");
    _glfw.wl.xkb.keymap_new_from_string = (PFN_xkb_keymap_new_from_string)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_new_from_string");
    _glfw.wl.xkb.keymap_unref = (PFN_xkb_keymap_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_unref");
    _glfw.wl.xkb.keymap_mod_get_index = (PFN_xkb_keymap_mod_get_index)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
    _glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
    _glfw.wl.xkb.state_new = (PFN_xkb_state_new)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_new");
    _glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_unref");
    _glfw.wl.xkb.state_key_get_syms = (PFN_xkb_state_key_get_syms)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_key_get_syms");
    _glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_update_mask");
    _glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_serialize_mods");

#ifdef HAVE_XKBCOMMON_COMPOSE_H
    _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
    _glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_unref");
    _glfw.wl.xkb.compose_state_new = (PFN_xkb_compose_state_new)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_new");
    _glfw.wl.xkb.compose_state_unref = (PFN_xkb_compose_state_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_unref");
    _glfw.wl.xkb.compose_state_feed = (PFN_xkb_compose_state_feed)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_feed");
    _glfw.wl.xkb.compose_state_get_status = (PFN_xkb_compose_state_get_status)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
    _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
#endif

    _glfw.wl.display = wl_display_connect(NULL);
    if (!_glfw.wl.display)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to connect to display");
        return GLFW_FALSE;
    }

    _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
    wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);

    createKeyTables();

    _glfw.wl.xkb.context = xkb_context_new(0);
    if (!_glfw.wl.xkb.context)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to initialize xkb context");
        return GLFW_FALSE;
    }

    // Sync so we got all registry objects
    wl_display_roundtrip(_glfw.wl.display);

    // Sync so we got all initial output events
    wl_display_roundtrip(_glfw.wl.display);

    if (!_glfwInitJoysticksLinux())
        return GLFW_FALSE;

    _glfwInitTimerPOSIX();

    _glfw.wl.timerfd = -1;
    if (_glfw.wl.seatVersion >= 4)
        _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);

    if (_glfw.wl.pointer && _glfw.wl.shm)
    {
        _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm);
        if (!_glfw.wl.cursorTheme)
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "Wayland: Unable to load default cursor theme");
            return GLFW_FALSE;
        }
        _glfw.wl.cursorSurface =
            wl_compositor_create_surface(_glfw.wl.compositor);
    }

    return GLFW_TRUE;
}
Esempio n. 16
0
int _glfwPlatformInit(void)
{
    const char *cursorTheme;
    const char *cursorSizeStr;
    char *cursorSizeEnd;
    long cursorSizeLong;
    int cursorSize;

    _glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
    if (!_glfw.wl.cursor.handle)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to open libwayland-cursor");
        return GLFW_FALSE;
    }

    _glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load)
        _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_load");
    _glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy)
        _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
    _glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor)
        _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
    _glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer)
        _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");

    _glfw.wl.egl.handle = _glfw_dlopen("libwayland-egl.so.1");
    if (!_glfw.wl.egl.handle)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to open libwayland-egl");
        return GLFW_FALSE;
    }

    _glfw.wl.egl.window_create = (PFN_wl_egl_window_create)
        _glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_create");
    _glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy)
        _glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_destroy");
    _glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize)
        _glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_resize");

    _glfw.wl.xkb.handle = _glfw_dlopen("libxkbcommon.so.0");
    if (!_glfw.wl.xkb.handle)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to open libxkbcommon");
        return GLFW_FALSE;
    }

    _glfw.wl.xkb.context_new = (PFN_xkb_context_new)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_context_new");
    _glfw.wl.xkb.context_unref = (PFN_xkb_context_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_context_unref");
    _glfw.wl.xkb.keymap_new_from_string = (PFN_xkb_keymap_new_from_string)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_new_from_string");
    _glfw.wl.xkb.keymap_unref = (PFN_xkb_keymap_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_unref");
    _glfw.wl.xkb.keymap_mod_get_index = (PFN_xkb_keymap_mod_get_index)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
    _glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
    _glfw.wl.xkb.state_new = (PFN_xkb_state_new)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_new");
    _glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_unref");
    _glfw.wl.xkb.state_key_get_syms = (PFN_xkb_state_key_get_syms)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_key_get_syms");
    _glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_update_mask");
    _glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_serialize_mods");

#ifdef HAVE_XKBCOMMON_COMPOSE_H
    _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
    _glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_unref");
    _glfw.wl.xkb.compose_state_new = (PFN_xkb_compose_state_new)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_new");
    _glfw.wl.xkb.compose_state_unref = (PFN_xkb_compose_state_unref)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_unref");
    _glfw.wl.xkb.compose_state_feed = (PFN_xkb_compose_state_feed)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_feed");
    _glfw.wl.xkb.compose_state_get_status = (PFN_xkb_compose_state_get_status)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
    _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
        _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
#endif

    _glfw.wl.display = wl_display_connect(NULL);
    if (!_glfw.wl.display)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to connect to display");
        return GLFW_FALSE;
    }

    _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
    wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);

    createKeyTables();

    _glfw.wl.xkb.context = xkb_context_new(0);
    if (!_glfw.wl.xkb.context)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Wayland: Failed to initialize xkb context");
        return GLFW_FALSE;
    }

    // Sync so we got all registry objects
    wl_display_roundtrip(_glfw.wl.display);

    // Sync so we got all initial output events
    wl_display_roundtrip(_glfw.wl.display);

#ifdef __linux__
    if (!_glfwInitJoysticksLinux())
        return GLFW_FALSE;
#endif

    _glfwInitTimerPOSIX();

    _glfw.wl.timerfd = -1;
    if (_glfw.wl.seatVersion >= 4)
        _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);

    if (_glfw.wl.pointer && _glfw.wl.shm)
    {
        cursorTheme = getenv("XCURSOR_THEME");
        cursorSizeStr = getenv("XCURSOR_SIZE");
        cursorSize = 32;
        if (cursorSizeStr)
        {
            errno = 0;
            cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10);
            if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX)
                cursorSize = (int)cursorSizeLong;
        }
        _glfw.wl.cursorTheme =
            wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm);
        if (!_glfw.wl.cursorTheme)
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "Wayland: Unable to load default cursor theme");
            return GLFW_FALSE;
        }
        // If this happens to be NULL, we just fallback to the scale=1 version.
        _glfw.wl.cursorThemeHiDPI =
            wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm);
        _glfw.wl.cursorSurface =
            wl_compositor_create_surface(_glfw.wl.compositor);
        _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
    }

    if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
    {
        _glfw.wl.dataDevice =
            wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
                                                   _glfw.wl.seat);
        wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL);
        _glfw.wl.clipboardString = malloc(4096);
        if (!_glfw.wl.clipboardString)
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "Wayland: Unable to allocate clipboard memory");
            return GLFW_FALSE;
        }
        _glfw.wl.clipboardSize = 4096;
    }

    return GLFW_TRUE;
}