Path: blob/master/platform/linuxbsd/freedesktop_at_spi_monitor.cpp
10277 views
/**************************************************************************/1/* freedesktop_at_spi_monitor.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "freedesktop_at_spi_monitor.h"3132#ifdef DBUS_ENABLED3334#include "core/os/os.h"3536#ifdef SOWRAP_ENABLED37#include "dbus-so_wrap.h"38#else39#include <dbus/dbus.h>40#endif4142#include <unistd.h>4344#define BUS_OBJECT_NAME "org.a11y.Bus"45#define BUS_OBJECT_PATH "/org/a11y/bus"4647#define BUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"4849void FreeDesktopAtSPIMonitor::monitor_thread_func(void *p_userdata) {50FreeDesktopAtSPIMonitor *mon = (FreeDesktopAtSPIMonitor *)p_userdata;5152DBusError error;53dbus_error_init(&error);5455DBusConnection *bus = dbus_bus_get(DBUS_BUS_SESSION, &error);56if (dbus_error_is_set(&error)) {57dbus_error_free(&error);58mon->supported.clear();59return;60}6162static const char *iface = "org.a11y.Status";63static const char *member_ac = "IsEnabled";64static const char *member_sr = "ScreenReaderEnabled";6566while (!mon->exit_thread.is_set()) {67DBusMessage *message = dbus_message_new_method_call(BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE_PROPERTIES, "Get");6869dbus_message_append_args(70message,71DBUS_TYPE_STRING, &iface,72DBUS_TYPE_STRING, &member_ac,73DBUS_TYPE_INVALID);7475DBusMessage *reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error);76dbus_message_unref(message);7778if (!dbus_error_is_set(&error)) {79DBusMessageIter iter, iter_variant, iter_struct;80dbus_bool_t result;81dbus_message_iter_init(reply, &iter);82dbus_message_iter_recurse(&iter, &iter_variant);83switch (dbus_message_iter_get_arg_type(&iter_variant)) {84case DBUS_TYPE_STRUCT: {85dbus_message_iter_recurse(&iter_variant, &iter_struct);86if (dbus_message_iter_get_arg_type(&iter_struct) == DBUS_TYPE_BOOLEAN) {87dbus_message_iter_get_basic(&iter_struct, &result);88if (result) {89mon->ac_enabled.set();90} else {91mon->ac_enabled.clear();92}93}94} break;95case DBUS_TYPE_BOOLEAN: {96dbus_message_iter_get_basic(&iter_variant, &result);97if (result) {98mon->ac_enabled.set();99} else {100mon->ac_enabled.clear();101}102} break;103default:104break;105}106dbus_message_unref(reply);107} else {108dbus_error_free(&error);109}110111message = dbus_message_new_method_call(BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE_PROPERTIES, "Get");112113dbus_message_append_args(114message,115DBUS_TYPE_STRING, &iface,116DBUS_TYPE_STRING, &member_sr,117DBUS_TYPE_INVALID);118119reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error);120dbus_message_unref(message);121122if (!dbus_error_is_set(&error)) {123DBusMessageIter iter, iter_variant, iter_struct;124dbus_bool_t result;125dbus_message_iter_init(reply, &iter);126dbus_message_iter_recurse(&iter, &iter_variant);127switch (dbus_message_iter_get_arg_type(&iter_variant)) {128case DBUS_TYPE_STRUCT: {129dbus_message_iter_recurse(&iter_variant, &iter_struct);130if (dbus_message_iter_get_arg_type(&iter_struct) == DBUS_TYPE_BOOLEAN) {131dbus_message_iter_get_basic(&iter_struct, &result);132if (result) {133mon->sr_enabled.set();134} else {135mon->sr_enabled.clear();136}137}138} break;139case DBUS_TYPE_BOOLEAN: {140dbus_message_iter_get_basic(&iter_variant, &result);141if (result) {142mon->sr_enabled.set();143} else {144mon->sr_enabled.clear();145}146} break;147default:148break;149}150dbus_message_unref(reply);151} else {152dbus_error_free(&error);153}154155usleep(50000);156}157158dbus_connection_unref(bus);159}160161FreeDesktopAtSPIMonitor::FreeDesktopAtSPIMonitor() {162supported.set();163sr_enabled.clear();164exit_thread.clear();165166thread.start(FreeDesktopAtSPIMonitor::monitor_thread_func, this);167}168169FreeDesktopAtSPIMonitor::~FreeDesktopAtSPIMonitor() {170exit_thread.set();171if (thread.is_started()) {172thread.wait_to_finish();173}174}175176#endif // DBUS_ENABLED177178179