diff --git a/docs/build.rst b/docs/build.rst index 9277fa942..4032c2631 100644 --- a/docs/build.rst +++ b/docs/build.rst @@ -28,7 +28,7 @@ Build-time dependencies: * gcc or clang * pkg-config * For building on Linux in addition to the above dependencies you might also need to install the ``-dev`` packages for: - ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev`` and ``libxkbcommon-x11-dev``, + ``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev`` and ``libxkbcommon-x11-dev``, if they are not already installed by your distro. Install and run from source diff --git a/glfw/dbus_glfw.c b/glfw/dbus_glfw.c new file mode 100644 index 000000000..92fe73bbc --- /dev/null +++ b/glfw/dbus_glfw.c @@ -0,0 +1,60 @@ +//======================================================================== +// GLFW 3.3 XKB - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2018 Kovid Goyal +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + + +#include "internal.h" +#include "dbus_glfw.h" + +static inline void +report_error(DBusError *err, const char *msg) { + const char *prefix = msg ? msg : "DBUS error occurred"; + _glfwInputError(GLFW_PLATFORM_ERROR, "%s: %s", prefix, err->message); + dbus_error_free(err); +} + + +GLFWbool +glfw_dbus_init(_GLFWDBUSData *dbus) { + DBusError err; + if (!dbus->session_conn) { + dbus_error_init(&err); + dbus->session_conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) { + report_error(&err, "Failed to connect to DBUS system bus"); + return GLFW_FALSE; + } + } + return GLFW_TRUE; +} + +void +glfw_dbus_terminate(_GLFWDBUSData *dbus) { + if (dbus->session_conn) { + dbus_connection_close(dbus->session_conn); + dbus_connection_unref(dbus->session_conn); + dbus->session_conn = NULL; + } +} diff --git a/glfw/dbus_glfw.h b/glfw/dbus_glfw.h new file mode 100644 index 000000000..0d7f51c8c --- /dev/null +++ b/glfw/dbus_glfw.h @@ -0,0 +1,38 @@ +//======================================================================== +// GLFW 3.3 XKB - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2018 Kovid Goyal +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + + +#pragma once + +#include + +typedef struct { + DBusConnection *session_conn; +} _GLFWDBUSData; + + +GLFWbool glfw_dbus_init(_GLFWDBUSData *dbus); +void glfw_dbus_terminate(_GLFWDBUSData *dbus); diff --git a/glfw/glfw.py b/glfw/glfw.py index 64f30a186..681f5311a 100755 --- a/glfw/glfw.py +++ b/glfw/glfw.py @@ -55,7 +55,7 @@ def init_env(env, pkg_config, at_least_version, module='x11'): at_least_version('xkbcommon', 0, 5) if module == 'x11': - for dep in 'x11 xrandr xinerama xcursor xkbcommon xkbcommon-x11 x11-xcb'.split(): + for dep in 'x11 xrandr xinerama xcursor xkbcommon xkbcommon-x11 x11-xcb dbus-1'.split(): ans.cflags.extend(pkg_config(dep, '--cflags-only-I')) ans.ldpaths.extend(pkg_config(dep, '--libs')) @@ -73,7 +73,7 @@ def init_env(env, pkg_config, at_least_version, module='x11'): for p in ans.wayland_protocols: ans.sources.append(wayland_protocol_file_name(p)) ans.all_headers.append(wayland_protocol_file_name(p, 'h')) - for dep in 'wayland-egl wayland-client wayland-cursor xkbcommon'.split(): + for dep in 'wayland-egl wayland-client wayland-cursor xkbcommon dbus-1'.split(): ans.cflags.extend(pkg_config(dep, '--cflags-only-I')) ans.ldpaths.extend(pkg_config(dep, '--libs')) diff --git a/glfw/ibus_glfw.c b/glfw/ibus_glfw.c new file mode 100644 index 000000000..32cf731e3 --- /dev/null +++ b/glfw/ibus_glfw.c @@ -0,0 +1,44 @@ +//======================================================================== +// GLFW 3.3 XKB - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2018 Kovid Goyal +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include +#include + +#include "internal.h" +#include "ibus_glfw.h" + +static inline GLFWbool +has_env_var(const char *name, const char *val) { + const char *q = getenv(name); + return (q && strcmp(q, val)) ? GLFW_TRUE : GLFW_FALSE; +} + +void +glfw_connect_to_ibus(_GLFWIBUSData *ibus, _GLFWDBUSData *dbus) { + if (ibus->ok) return; + if (!has_env_var("XMODIFIERS", "@im=ibus") && !has_env_var("GTK_IM_MODULE", "ibus") && !has_env_var("QT_IM_MODULE", "ibus")) return; + if (!glfw_dbus_init(dbus)) return; +} diff --git a/glfw/ibus_glfw.h b/glfw/ibus_glfw.h new file mode 100644 index 000000000..f1584516e --- /dev/null +++ b/glfw/ibus_glfw.h @@ -0,0 +1,36 @@ +//======================================================================== +// GLFW 3.3 XKB - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2018 Kovid Goyal +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + + +#pragma once + +#include "dbus_glfw.h" + +typedef struct { + GLFWbool ok; +} _GLFWIBUSData; + +void glfw_connect_to_ibus(_GLFWIBUSData *ibus, _GLFWDBUSData *dbus); diff --git a/glfw/source-info.json b/glfw/source-info.json index 61b095144..76339916f 100644 --- a/glfw/source-info.json +++ b/glfw/source-info.json @@ -58,6 +58,8 @@ "posix_time.h", "posix_thread.h", "xkb_glfw.h", + "dbus_glfw.h", + "ibus_glfw.h", "backend_utils.h", "egl_context.h", "osmesa_context.h", @@ -78,6 +80,8 @@ "posix_time.c", "posix_thread.c", "xkb_glfw.c", + "dbus_glfw.c", + "ibus_glfw.c", "egl_context.c", "osmesa_context.c", "linux_joystick.c", @@ -112,6 +116,8 @@ "headers": [ "x11_platform.h", "xkb_glfw.h", + "dbus_glfw.h", + "ibus_glfw.h", "backend_utils.h", "posix_time.h", "posix_thread.h", @@ -126,6 +132,8 @@ "x11_monitor.c", "x11_window.c", "xkb_glfw.c", + "dbus_glfw.c", + "ibus_glfw.c", "posix_time.c", "posix_thread.c", "glx_context.c", diff --git a/glfw/wl_init.c b/glfw/wl_init.c index cd7fa297c..4feada24a 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -669,7 +669,7 @@ int _glfwPlatformInit(void) _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); - if (!glfw_xkb_create_context(&_glfw.wl.xkb)) return GLFW_FALSE; + if (!glfw_xkb_create_context(&_glfw.wl.xkb, &_glfw.wl.dbus)) return GLFW_FALSE; // Sync so we got all registry objects wl_display_roundtrip(_glfw.wl.display); @@ -713,6 +713,7 @@ void _glfwPlatformTerminate(void) } glfw_xkb_release(&_glfw.wl.xkb); + glfw_dbus_terminate(&_glfw.wl.dbus); if (_glfw.wl.cursorTheme) wl_cursor_theme_destroy(_glfw.wl.cursorTheme); diff --git a/glfw/wl_platform.h b/glfw/wl_platform.h index f0e408fe8..21683a849 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -208,6 +208,7 @@ typedef struct _GLFWlibraryWayland _GLFWwindow* keyboardFocus; } keyRepeatInfo; _GLFWXKBData xkb; + _GLFWDBUSData dbus; _GLFWwindow* pointerFocus; _GLFWwindow* keyboardFocus; diff --git a/glfw/x11_init.c b/glfw/x11_init.c index ea5b0f3b2..8660e9196 100644 --- a/glfw/x11_init.c +++ b/glfw/x11_init.c @@ -378,7 +378,7 @@ static GLFWbool initExtensions(void) } if (!glfw_xkb_set_x11_events_mask()) return GLFW_FALSE; - if (!glfw_xkb_create_context(&_glfw.x11.xkb)) return GLFW_FALSE; + if (!glfw_xkb_create_context(&_glfw.x11.xkb, &_glfw.x11.dbus)) return GLFW_FALSE; if (!glfw_xkb_update_x11_keyboard_id(&_glfw.x11.xkb)) return GLFW_FALSE; if (!glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL)) return GLFW_FALSE; @@ -689,6 +689,7 @@ void _glfwPlatformTerminate(void) } glfw_xkb_release(&_glfw.x11.xkb); + glfw_dbus_terminate(&_glfw.x11.dbus); free(_glfw.x11.primarySelectionString); free(_glfw.x11.clipboardString); diff --git a/glfw/x11_platform.h b/glfw/x11_platform.h index 2430065f5..b3faa2b29 100644 --- a/glfw/x11_platform.h +++ b/glfw/x11_platform.h @@ -315,6 +315,7 @@ typedef struct _GLFWlibraryX11 } randr; _GLFWXKBData xkb; + _GLFWDBUSData dbus; struct { int count; diff --git a/glfw/xkb_glfw.c b/glfw/xkb_glfw.c index ef1091cd6..4babb8450 100644 --- a/glfw/xkb_glfw.c +++ b/glfw/xkb_glfw.c @@ -203,7 +203,7 @@ glfw_xkb_release(_GLFWXKBData *xkb) { } GLFWbool -glfw_xkb_create_context(_GLFWXKBData *xkb) { +glfw_xkb_create_context(_GLFWXKBData *xkb, _GLFWDBUSData *dbus) { xkb->context = xkb_context_new(0); if (!xkb->context) { @@ -211,9 +211,11 @@ glfw_xkb_create_context(_GLFWXKBData *xkb) { "Failed to initialize XKB context"); return GLFW_FALSE; } + glfw_connect_to_ibus(&xkb->ibus, dbus); return GLFW_TRUE; } + GLFWbool glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str) { const char* locale = NULL; diff --git a/glfw/xkb_glfw.h b/glfw/xkb_glfw.h index 805aee367..1e251a88f 100644 --- a/glfw/xkb_glfw.h +++ b/glfw/xkb_glfw.h @@ -32,6 +32,8 @@ #include #endif +#include "ibus_glfw.h" + typedef struct { struct xkb_context* context; struct xkb_keymap* keymap; @@ -56,6 +58,7 @@ typedef struct { xkb_mod_mask_t activeUnknownModifiers; unsigned int modifiers; xkb_mod_index_t unknownModifiers[256]; + _GLFWIBUSData ibus; #ifdef _GLFW_X11 int32_t keyboard_device_id; @@ -76,7 +79,7 @@ GLFWbool glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb); #endif void glfw_xkb_release(_GLFWXKBData *xkb); -GLFWbool glfw_xkb_create_context(_GLFWXKBData *xkb); +GLFWbool glfw_xkb_create_context(_GLFWXKBData *xkb, _GLFWDBUSData *dbus); GLFWbool glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str); void glfw_xkb_update_modifiers(_GLFWXKBData *xkb, xkb_mod_mask_t depressed, xkb_mod_mask_t latched, xkb_mod_mask_t locked, xkb_layout_index_t base_group, xkb_layout_index_t latched_group, xkb_layout_index_t locked_group); GLFWbool glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode);