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); }
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"); } }
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"); } }
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"); } }
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, ®istryListener, 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; }
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); } } }
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); }
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); }
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; }
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(); }
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); }
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, ®istry_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; }
static void fghInitialiseCursorTheme(void) { fgDisplay.pDisplay.cursor_theme = wl_cursor_theme_load ( "default", 32, fgDisplay.pDisplay.shm ); };
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, ®istryListener, 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; }
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, ®istryListener, 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; }