autopilot-gtk-1.4+15.10.20150826/ 0000755 0000153 0000161 00000000000 12567421566 016534 5 ustar pbuser pbgroup 0000000 0000000 autopilot-gtk-1.4+15.10.20150826/lib/ 0000755 0000153 0000161 00000000000 12567421566 017302 5 ustar pbuser pbgroup 0000000 0000000 autopilot-gtk-1.4+15.10.20150826/lib/GtkRootNode.cpp 0000644 0000153 0000161 00000006031 12567421316 022176 0 ustar pbuser pbgroup 0000000 0000000 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2012 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Allan LeSage
*/
#include "GtkRootNode.h"
#include
#include
#include
#include
#include "Variant.h"
GtkRootNode::GtkRootNode()
: GtkNode(NULL) {
}
GVariant* GtkRootNode::Introspect() const {
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
variant::BuilderWrapper builder_wrapper(&builder);
// add our unique autopilot-id
builder_wrapper.add(AP_ID_NAME.c_str(), GetId());
// add the names of our children
builder_wrapper.add("Children", GetChildNodeNames());
return g_variant_builder_end(&builder);
}
int32_t GtkRootNode::GetId() const {
return 1;
}
std::string GtkRootNode::GetName() const {
return "Root";
}
std::string GtkRootNode::GetPath() const {
return "/" + GetName();
}
bool GtkRootNode::MatchIntegerProperty(const std::string& name, int32_t value) const
{
// Root node only matches one property - id:
if (name == "id")
return value == GetId();
return false;
}
bool GtkRootNode::MatchBooleanProperty(const std::string& name, bool value) const
{
return false;
}
bool GtkRootNode::MatchStringProperty(const std::string& name, const std::string& value) const
{
return false;
}
xpathselect::NodeVector GtkRootNode::Children() const {
//g_debug("getting the children of a node");
xpathselect::NodeVector children;
// add all the toplevel nodes as children to the root node
GList* toplevels_list = gtk_window_list_toplevels();
GList* elem;
for (elem = toplevels_list; elem; elem = elem->next) {
GObject *node = reinterpret_cast(elem->data);
children.push_back(std::make_shared(node, shared_from_this()));
// if the AtkObjects are available, expose the Atk hierarchy as well
AtkObject *atk_object = gtk_widget_get_accessible(GTK_WIDGET(node));
if (atk_object != NULL)
children.push_back(std::make_shared(G_OBJECT(atk_object), shared_from_this()));
}
g_list_free(toplevels_list);
return children;
}
GVariant* GtkRootNode::GetChildNodeNames() const {
//g_debug("getting the names of a node's children");
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE_STRING_ARRAY);
for (xpathselect::Node::Ptr child : Children()) {
g_variant_builder_add(&builder, "s", child->GetName().c_str());
}
return g_variant_builder_end(&builder);
}
autopilot-gtk-1.4+15.10.20150826/lib/Variant.cpp 0000644 0000153 0000161 00000020017 12567421316 021403 0 ustar pbuser pbgroup 0000000 0000000 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2010 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Tim Penhey
*/
#include
#include
#include "Variant.h"
#include "autopilot_types.h"
namespace variant
{
BuilderWrapper::BuilderWrapper(GVariantBuilder* builder)
: builder_(builder)
{}
BuilderWrapper& BuilderWrapper::add(char const* name, bool value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_boolean(value));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, char const* value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
if (value)
g_variant_builder_add(&b, "v", g_variant_new_string(value));
else
g_variant_builder_add(&b, "v", g_variant_new_string(""));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, std::string const& value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_string(value.c_str()));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, int value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_int32(value));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, long int value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_int64(value));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, long long int value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_int64(value));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, unsigned int value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_uint32(value));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, long unsigned int value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_uint64(value));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, long long unsigned int value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_uint64(value));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, float value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_double(value));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, double value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", g_variant_new_double(value));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
BuilderWrapper& BuilderWrapper::add(char const* name, GVariant* value)
{
if (value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_PLAIN));
g_variant_builder_add(&b, "v", value);
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
}
return *this;
}
BuilderWrapper& BuilderWrapper::add_gvalue(char const* name, GValue* value)
{
switch (G_VALUE_TYPE(value)) {
case G_TYPE_CHAR:
{
add(name, g_value_get_schar(value));
}
break;
case G_TYPE_UCHAR:
{
add(name, g_value_get_uchar(value));
}
break;
case G_TYPE_BOOLEAN:
{
add(name, (bool) g_value_get_boolean(value));
}
break;
case G_TYPE_INT:
{
add(name, g_value_get_int(value));
}
break;
case G_TYPE_UINT:
{
add(name, g_value_get_uint(value));
}
break;
case G_TYPE_LONG:
{
add(name, g_value_get_long(value));
}
break;
case G_TYPE_ULONG:
{
add(name, g_value_get_ulong(value));
}
break;
case G_TYPE_INT64:
{
add(name, g_value_get_int64(value));
}
break;
case G_TYPE_UINT64:
{
add(name, g_value_get_uint64(value));
}
break;
case G_TYPE_ENUM:
{
add(name, g_value_get_enum(value));
}
break;
case G_TYPE_FLAGS:
{
add(name, g_value_get_flags(value));
}
break;
case G_TYPE_FLOAT:
{
add(name, g_value_get_float(value));
}
break;
case G_TYPE_DOUBLE:
{
add(name, g_value_get_double(value));
}
break;
case G_TYPE_STRING:
{
add(name, g_value_get_string(value));
}
break;
case G_TYPE_POINTER:
{
add(name, g_value_get_pointer(value));
}
break;
case G_TYPE_BOXED:
{
add(name, g_value_get_boxed(value));
}
break;
case G_TYPE_PARAM:
{
add(name, g_value_get_param(value));
}
break;
case G_TYPE_OBJECT:
{
add(name, g_value_get_object(value));
}
break;
default:
g_debug("unsupported type: %s", g_type_name(G_VALUE_TYPE(value)));
{}
break;
}
return *this;
}
BuilderWrapper& BuilderWrapper::BuilderWrapper::add(char const* name, GdkRectangle value)
{
GVariantBuilder b;
g_variant_builder_init(&b, G_VARIANT_TYPE("av"));
g_variant_builder_add(&b, "v", g_variant_new_int32(TYPE_RECT));
g_variant_builder_add(&b, "v", g_variant_new_int32(value.x));
g_variant_builder_add(&b, "v", g_variant_new_int32(value.y));
g_variant_builder_add(&b, "v", g_variant_new_int32(value.width));
g_variant_builder_add(&b, "v", g_variant_new_int32(value.height));
g_variant_builder_add(
builder_,
"{sv}",
name,
g_variant_builder_end(&b)
);
return *this;
}
}
autopilot-gtk-1.4+15.10.20150826/lib/GtkNode.cpp 0000644 0000153 0000161 00000034314 12567421316 021337 0 ustar pbuser pbgroup 0000000 0000000 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2012 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Allan LeSage
*/
#include
#include
#include
#include "GtkNode.h"
#include "Variant.h"
const std::string GtkNode::AP_ID_NAME = "id";
static guint32 cur_obj_id = 2; // start at 2 since 1 is reserved for the root node
GtkNode::GtkNode(GObject* obj, GtkNode::Ptr const& parent)
: object_(obj)
, parent_(parent)
{
std::string parent_path = parent ? parent->GetPath() : "";
full_path_ = parent_path + "/" + GetName();
if (object_ != NULL)
{
g_object_ref(object_);
GQuark OBJ_ID = g_quark_from_static_string("AUTOPILOT_OBJECT_ID");
gpointer val = g_object_get_qdata (object_, OBJ_ID);
if (val == NULL)
{
g_object_set_qdata (object_, OBJ_ID, reinterpret_cast(cur_obj_id++));
}
}
}
GtkNode::GtkNode(GObject* obj)
: object_(obj)
{
full_path_ = "/" + GetName();
if (object_ != NULL)
{
g_object_ref(object_);
GQuark OBJ_ID = g_quark_from_static_string("AUTOPILOT_OBJECT_ID");
gpointer val = g_object_get_qdata (object_, OBJ_ID);
if (val == NULL)
{
g_object_set_qdata (object_, OBJ_ID, reinterpret_cast(cur_obj_id++));
}
}
}
GtkNode::~GtkNode()
{
g_clear_object(&object_);
}
// we cannot represent GEnums, GFlags, etc. through D-BUS and autopilot's API,
// so convert them to strings, ints, and other primitive types
static void convert_value (GParamSpec *pspec, GValue *value)
{
if (G_VALUE_HOLDS_ENUM(value)) {
GEnumValue *ev = g_enum_get_value(G_PARAM_SPEC_ENUM(pspec)->enum_class,
g_value_get_enum(value));
if (ev != NULL) {
//g_debug("attribute %s of type %s holds enum %s", g_param_spec_get_name(pspec),
// g_type_name(pspec->value_type), ev->value_name);
g_value_unset(value);
*value = G_VALUE_INIT;
g_value_init(value, G_TYPE_STRING);
g_value_set_string(value, ev->value_name);
}
}
// representing flags as strings is too unwieldy; let's just represent them
// as integer
if (G_VALUE_HOLDS_FLAGS(value)) {
guint flags = g_value_get_flags(value);
//g_debug("attribute %s of type %s holds flags %x", g_param_spec_get_name(pspec),
// g_type_name(pspec->value_type), flags);
g_value_unset(value);
*value = G_VALUE_INIT;
g_value_init(value, G_TYPE_UINT);
g_value_set_uint(value, flags);
}
if (pspec->value_type == GTK_TYPE_TEXT_BUFFER) {
GtkTextBuffer *buf = GTK_TEXT_BUFFER(g_value_get_object(value));
if (buf != NULL) {
//g_debug("attribute %s of type %s holds GtkTextBuffer", g_param_spec_get_name(pspec),
// g_type_name(pspec->value_type));
GtkTextIter start, end;
gtk_text_buffer_get_start_iter(buf, &start);
gtk_text_buffer_get_end_iter(buf, &end);
gchar* text = gtk_text_iter_get_text(&start, &end);
g_value_unset(value);
*value = G_VALUE_INIT;
g_value_init(value, G_TYPE_STRING);
g_value_set_string(value, (text != NULL) ? text : "");
g_free(text);
}
}
}
GVariant* GtkNode::Introspect() const
{
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
// add a GVariant of all our properties
guint length;
GParamSpec** properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(object_), &length);
variant::BuilderWrapper builder_wrapper(&builder);
for (uint i = 0; i < length; ++i) {
GParamSpec* param_spec = properties[i];
// ATK's accessible-table-* properties generate "invalid property id" warnings
if (g_str_has_prefix(g_param_spec_get_name(param_spec), "accessible-table-"))
continue;
// see Launchpad bug #1108155: GtkTreePath mis-casts while copying, actuates here in "root" property
if (g_strcmp0(g_type_name(param_spec->value_type), "GtkTreePath") != 0) {
// some properties are only writeable; some toxic nodes change their names (?)
if (param_spec->flags & G_PARAM_READABLE) {
GValue value = G_VALUE_INIT;
g_value_init(&value, param_spec->value_type);
g_object_get_property(object_, g_param_spec_get_name(param_spec), &value);
convert_value(param_spec, &value);
builder_wrapper.add_gvalue(param_spec->name, &value);
g_value_unset(&value); //Free the memory acquired by the value object. Absence of this was causig the applications to crash.
}
} else {
//g_debug("skipped %s of type GtkTreePath", g_param_spec_get_name(param_spec));
}
}
g_free(properties);
// add our unique autopilot-id
builder_wrapper.add(AP_ID_NAME.c_str(), GetId());
// add the names of our children
builder_wrapper.add("Children", GetChildNodeNames());
// add the GtkBuilder name
if (GTK_IS_BUILDABLE (object_))
builder_wrapper.add("BuilderName", gtk_buildable_get_name(GTK_BUILDABLE (object_)));
// add the GlobalRect property: "I am a GtkWidget" edition
if (GTK_IS_WIDGET(object_)) {
// FIXME: we'd like to remove this duplication (to GetGlobalRect)
GtkWidget *widget = GTK_WIDGET (object_);
GdkWindow *gdk_window = gtk_widget_get_window(widget);
if (GDK_IS_WINDOW(gdk_window)) {
GdkRectangle rect;
GetGlobalRect(&rect);
builder_wrapper.add("globalRect", rect);
}
} else if (ATK_IS_COMPONENT(object_)) {
AddAtkComponentProperties(builder_wrapper, ATK_COMPONENT(object_));
}
return g_variant_builder_end(&builder);
}
void GtkNode::AddAtkComponentProperties(variant::BuilderWrapper &builder_wrapper,
AtkComponent *atk_component) const
{
AtkStateSet *states = atk_object_ref_state_set(ATK_OBJECT(atk_component));
/* Expose a few states which might be especially interesting for autopilot */
bool visible = atk_state_set_contains_state(states, ATK_STATE_VISIBLE);
builder_wrapper.add("visible", visible);
if (visible) {
gint x, y, width, height;
x = y = width = height = -1;
atk_component_get_extents(atk_component, &x, &y, &width, &height,
ATK_XY_SCREEN);
GdkRectangle r;
r.x = x;
r.y = y;
r.width = width;
r.height = height;
builder_wrapper.add("globalRect", r);
}
builder_wrapper.add("active",
bool(atk_state_set_contains_state(states, ATK_STATE_ACTIVE)));
builder_wrapper.add("checked",
bool(atk_state_set_contains_state(states, ATK_STATE_CHECKED)));
builder_wrapper.add("editable",
bool(atk_state_set_contains_state(states, ATK_STATE_EDITABLE)));
builder_wrapper.add("enabled",
bool(atk_state_set_contains_state(states, ATK_STATE_ENABLED)));
builder_wrapper.add("focused",
bool(atk_state_set_contains_state(states, ATK_STATE_FOCUSED)));
builder_wrapper.add("pressed",
bool(atk_state_set_contains_state(states, ATK_STATE_PRESSED)));
builder_wrapper.add("selected",
bool(atk_state_set_contains_state(states, ATK_STATE_SELECTED)));
builder_wrapper.add("sensitive",
bool(atk_state_set_contains_state(states, ATK_STATE_SENSITIVE)));
builder_wrapper.add("showing",
bool(atk_state_set_contains_state(states, ATK_STATE_SHOWING)));
g_object_unref(G_OBJECT(states));
}
void GtkNode::GetGlobalRect(GdkRectangle* rect) const
{
GtkWidget *widget = GTK_WIDGET(object_);
GdkWindow *gdk_window = gtk_widget_get_window(widget);
GtkAllocation allocation;
gint x, y;
gtk_widget_get_allocation (widget, &allocation);
gdk_window_get_root_coords(gdk_window, allocation.x, allocation.y, &x, &y);
// if we wished to get the root root coords we might do this
//gdk_window_get_root_coords(gdk_window, 0, 0, &x, &y);
//g_debug ("root coords for widget %p(%s): %d %d (size %d %d)\n", widget, G_OBJECT_TYPE_NAME(widget), x, y, allocation.width, allocation.height);
// FIXME: suck this up
rect->x = x;
rect->y = y;
rect->width = allocation.width;
rect->height = allocation.height;
return;
}
std::string GtkNode::GetName() const {
// autopilot uses the name of the GObject type
if (!object_) {
return std::string();
}
return G_OBJECT_TYPE_NAME(object_);
}
std::string GtkNode::GetPath() const {
return full_path_;
}
int32_t GtkNode::GetId() const
{
GQuark OBJ_ID = g_quark_from_static_string("AUTOPILOT_OBJECT_ID");
gpointer val = g_object_get_qdata (object_, OBJ_ID);
// this uglyness is required in order to stop the compiler complaining about the fact
// that we're casting a 64 bit type (gpointer) down to a 32 bit type (gint32) and may
// be truncating the value. It's safe to do, however, since we control what values are
// set in this quark, and they were initial gint32 values anyway.
guint32 id = static_cast(reinterpret_cast(val));
return id;
}
xpathselect::Node::Ptr GtkNode::GetParent() const
{
return parent_;
}
bool GtkNode::MatchStringProperty(const std::string& name,
const std::string& value) const {
if (name == "BuilderName" && GTK_IS_BUILDABLE(object_)) {
const gchar* builder_name = gtk_buildable_get_name(GTK_BUILDABLE (object_));
return builder_name != NULL && value.compare(builder_name) == 0;
}
GObjectClass* klass = G_OBJECT_GET_CLASS(object_);
GParamSpec* pspec = g_object_class_find_property(klass, name.c_str());
if (pspec == NULL)
return false;
// read the property into a GValue
g_debug("Matching property %s of type (%s).", g_param_spec_get_name(pspec),
g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
GValue dest_value = G_VALUE_INIT;
g_value_init(&dest_value, G_PARAM_SPEC_VALUE_TYPE(pspec));
g_object_get_property(object_, name.c_str(), &dest_value);
convert_value(pspec, &dest_value);
if (G_VALUE_TYPE(&dest_value) == G_TYPE_STRING) {
const gchar *str = g_value_get_string(&dest_value);
int result = g_strcmp0 (str, value.c_str());
g_value_unset(&dest_value);
return result == 0;
}
else {
g_debug("Property %s exists, but is not a string (is %s).",
g_param_spec_get_name(pspec),
g_type_name(G_VALUE_TYPE(&dest_value))
);
g_value_unset(&dest_value);
return false;
}
}
bool GtkNode::MatchIntegerProperty(const std::string& name,
int32_t value) const {
if (name == "id")
return value == GetId();
GObjectClass* klass = G_OBJECT_GET_CLASS(object_);
GParamSpec* pspec = g_object_class_find_property(klass, name.c_str());
if (pspec == NULL)
return false;
// read the property into a GValue
g_debug("Matching property %s of type (%s).", g_param_spec_get_name(pspec),
g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
GValue dest_value = G_VALUE_INIT;
g_value_init(&dest_value, G_PARAM_SPEC_VALUE_TYPE(pspec));
g_object_get_property(object_, name.c_str(), &dest_value);
convert_value(pspec, &dest_value);
if (G_VALUE_TYPE(&dest_value) == G_TYPE_INT) {
int v = g_value_get_int(&dest_value);
g_value_unset(&dest_value);
return value == v;
}
else if (G_VALUE_TYPE(&dest_value) == G_TYPE_UINT) {
int v = g_value_get_uint(&dest_value);
g_value_unset(&dest_value);
return value == v;
}
else {
g_debug("Property %s exists, but is not an integer (is %s).",
g_param_spec_get_name(pspec),
g_type_name(G_VALUE_TYPE(&dest_value))
);
g_value_unset(&dest_value);
return false;
}
}
bool GtkNode::MatchBooleanProperty(const std::string& name,
bool value) const {
GObjectClass* klass = G_OBJECT_GET_CLASS(object_);
GParamSpec* pspec = g_object_class_find_property(klass, name.c_str());
if (pspec == NULL)
return false;
// read the property into a GValue
g_debug("Matching property %s of type (%s).", g_param_spec_get_name(pspec),
g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)));
GValue dest_value = G_VALUE_INIT;
g_value_init(&dest_value, G_PARAM_SPEC_VALUE_TYPE(pspec));
g_object_get_property(object_, name.c_str(), &dest_value);
convert_value(pspec, &dest_value);
if (G_VALUE_TYPE(&dest_value) == G_TYPE_BOOLEAN) {
bool v = g_value_get_boolean(&dest_value);
g_value_unset(&dest_value);
return value == v;
}
else {
g_debug("Property %s exists, but is not a boolean (is %s).",
g_param_spec_get_name(pspec),
g_type_name(G_VALUE_TYPE(&dest_value))
);
g_value_unset(&dest_value);
return false;
}
}
xpathselect::NodeVector GtkNode::Children() const {
//g_debug("getting the children of a node");
xpathselect::NodeVector children;
if (GTK_IS_CONTAINER(object_)) {
GList* gtk_children = gtk_container_get_children(GTK_CONTAINER(object_));
for (GList* elem = gtk_children; elem; elem = elem->next) {
children.push_back(std::make_shared(G_OBJECT(elem->data), shared_from_this()));
}
g_list_free(gtk_children);
} else if (ATK_IS_OBJECT(object_)) {
AtkObject *atk_object = ATK_OBJECT(object_);
int n_children = atk_object_get_n_accessible_children(atk_object);
for (int i = 0; i < n_children; i++) {
AtkObject *child = atk_object_ref_accessible_child(atk_object, i);
children.push_back(std::make_shared(G_OBJECT(child), shared_from_this()));
}
}
return children;
}
GVariant* GtkNode::GetChildNodeNames() const {
//g_debug("getting the names of a node's children");
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE_STRING_ARRAY);
for (xpathselect::Node::Ptr child : Children()) {
g_variant_builder_add(&builder, "s", child->GetName().c_str());
}
return g_variant_builder_end(&builder);
}
autopilot-gtk-1.4+15.10.20150826/lib/main.h 0000644 0000153 0000161 00000001531 12567421316 020370 0 ustar pbuser pbgroup 0000000 0000000 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2012 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Allan LeSage
*/
#ifndef MAIN_H
#define MAIN_H
extern "C" {
int gtk_module_init(gint argc, char *argv[]);
}
#endif // MAIN_H
autopilot-gtk-1.4+15.10.20150826/lib/Introspection.cpp 0000644 0000153 0000161 00000010411 12567421316 022634 0 ustar pbuser pbgroup 0000000 0000000 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2012 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Allan LeSage
*/
#include "Introspection.h"
#include
#include
#include
#include
#include
#include "GtkNode.h"
#include "GtkRootNode.h"
std::string AUTOPILOT_INTROSPECTION_OBJECT_PATH = "/com/canonical/Autopilot/Introspection";
void bus_acquired (GObject *object,
GAsyncResult * res,
gpointer user_data)
{
//g_debug("bus acquired");
GDBusConnection *bus;
GError *error = NULL;
bus = g_bus_get_finish (res, &error);
if (!bus) {
//g_warning ("unable to connect to the session bus: %s", error->message);
g_error_free (error);
return;
}
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (autopilot_introspection),
bus,
AUTOPILOT_INTROSPECTION_OBJECT_PATH.c_str(),
&error);
if (error) {
//g_warning ("unable to export autopilot introspection service on dbus: %s", error->message);
g_error_free (error);
return;
}
g_signal_connect (autopilot_introspection,
"handle-get-state",
G_CALLBACK(handle_get_state),
NULL);
g_signal_connect (autopilot_introspection,
"handle-get-version",
G_CALLBACK(handle_get_version),
NULL);
g_object_unref (bus);
}
gboolean handle_get_state (AutopilotIntrospection* introspection_service,
GDBusMethodInvocation* invocation,
const gchar * arg,
gpointer user_data)
{
//g_debug("handling get-state method call");
GVariant* state;
state = Introspect(arg);
autopilot_introspection_complete_get_state(introspection_service,
invocation,
state);
return TRUE;
}
gboolean handle_get_version (AutopilotIntrospection *introspection_service,
GDBusMethodInvocation *invocation)
{
autopilot_introspection_complete_get_version(introspection_service,
invocation,
WIRE_PROTO_VERSION.c_str());
return TRUE;
}
GVariant* Introspect(std::string const& query_string) {
//g_debug("introspecting our current GTK+ context");
GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(sv)"));
std::list node_list = GetNodesThatMatchQuery(query_string);
for (auto node: node_list) {
std::string object_path = node->GetPath();
g_variant_builder_add(builder, "(sv)", object_path.c_str(), node->Introspect());
//g_debug("dumped object '%s'", object_path.c_str());
}
GVariant* state = g_variant_new("a(sv)", builder);
g_variant_builder_unref(builder);
return state;
}
std::list GetNodesThatMatchQuery(std::string const& query_string) {
//g_debug("getting nodes that match query");
std::shared_ptr root = std::make_shared();
//g_debug("selecting nodes");
std::list node_list;
xpathselect::NodeVector selected_nodes_list;
selected_nodes_list = xpathselect::SelectNodes(root, query_string);
//g_debug("finished selecting nodes");
for (auto node : selected_nodes_list) {
// node may be our root node wrapper *or* an ordinary GObject wrapper
auto object_ptr = std::static_pointer_cast(node);
if (object_ptr)
node_list.push_back(object_ptr);
}
return node_list;
}
autopilot-gtk-1.4+15.10.20150826/lib/IntrospectionService.xml 0000644 0000153 0000161 00000000733 12567421316 024201 0 ustar pbuser pbgroup 0000000 0000000
autopilot-gtk-1.4+15.10.20150826/lib/main.cpp 0000644 0000153 0000161 00000006041 12567421316 020724 0 ustar pbuser pbgroup 0000000 0000000 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2012 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Allan LeSage
*/
#include
#include
#include
#include
#include
#include "main.h"
#include "Introspection.h"
#include "IntrospectionService.h"
namespace
{
std::string filename;
GLogLevelFlags levels_to_log;
std::ostream& get_log_stream()
{
if (!filename.empty())
{
static std::ofstream fstream(filename);
return fstream;
}
else
{
return std::cout;
}
}
std::string get_level_name(GLogLevelFlags lvl)
{
switch(lvl)
{
case G_LOG_LEVEL_DEBUG:
return "DEBUG";
case G_LOG_LEVEL_INFO:
return "INFO";
case G_LOG_LEVEL_MESSAGE:
return "MESSAGE";
case G_LOG_LEVEL_WARNING:
return "WARNING";
case G_LOG_LEVEL_CRITICAL:
return "CRITICAL";
case G_LOG_LEVEL_ERROR:
return "ERROR";
default:
return "UNKNOWN";
}
}
}
AutopilotIntrospection* autopilot_introspection = NULL;
void LogHandler (const gchar* log_domain,
GLogLevelFlags log_level,
const gchar* message,
gpointer user_data)
{
if (log_level & levels_to_log)
{
std::string domain = log_domain ? log_domain : "default";
get_log_stream() << "[" << domain << "] " << get_level_name(log_level) << ": " << message << std::endl;
}
}
void initialise_logging()
{
if (getenv("AP_GTK_LOG_VERBOSE"))
{
levels_to_log = (GLogLevelFlags) (
G_LOG_LEVEL_MASK |
G_LOG_FLAG_FATAL |
G_LOG_FLAG_RECURSION);
}
else
{
levels_to_log = (GLogLevelFlags)(
G_LOG_LEVEL_WARNING |
G_LOG_LEVEL_ERROR |
G_LOG_LEVEL_CRITICAL |
G_LOG_FLAG_FATAL |
G_LOG_FLAG_RECURSION);
}
char* fname = getenv("AP_GTK_LOG_FILE");
if (fname && strcmp(fname, "") != 0)
{
filename = fname;
}
g_log_set_default_handler(LogHandler, NULL);
}
int gtk_module_init(gint argc, char *argv[]) {
initialise_logging();
autopilot_introspection = autopilot_introspection_skeleton_new ();
g_bus_get (G_BUS_TYPE_SESSION, NULL, bus_acquired, NULL);
// always log this:
std::cout << "Autopilot GTK interface loaded. Wire protocol version is " << WIRE_PROTO_VERSION << "." << std::endl;
return 0;
}
int display_init_func(GdkDisplay* display) {
// FIXME: module fails to load if this is not defined, but is it necessary?
return 0;
}
autopilot-gtk-1.4+15.10.20150826/lib/Variant.h 0000644 0000153 0000161 00000003506 12567421316 021054 0 ustar pbuser pbgroup 0000000 0000000 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2011 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Tim Penhey
*/
#ifndef VARIANT_H
#define VARIANT_H
#include
#include
#include
#include