diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 30aa8b7f..00000000 --- a/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -*.o -*.Po -easystroke -easystroke.1 -gui.c -desktop.c -*.swp -debug.mk -po/?? -po/??_?? -po/POTFILES.in -po/*.pot -easystroke.desktop -.clang_complete diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..4d54141b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "exception": "cpp" + } +} \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..03c3660b --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,7 @@ +Copyright (c) 2020, James Ratcliffe + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index 71beaa42..00000000 --- a/Makefile +++ /dev/null @@ -1,156 +0,0 @@ -# Copyright (c) 2008-2009, Thomas Jaeger -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY -# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -DESTDIR = -PREFIX = /usr/local -BINDIR = $(PREFIX)/bin -ICONDIR = $(PREFIX)/share/icons/hicolor/scalable/apps -MENUDIR = $(PREFIX)/share/applications -LOCALEDIR= $(PREFIX)/share/locale -DFLAGS = -OFLAGS = -O2 -AOFLAGS = -O3 -STROKEFLAGS = -Wall -std=c11 $(DFLAGS) -CXXSTD = -std=c++11 -INCLUDES = $(shell pkg-config gtkmm-3.0 dbus-glib-1 --cflags) -CXXFLAGS = $(CXXSTD) -Wall $(DFLAGS) -DLOCALEDIR=\"$(LOCALEDIR)\" $(INCLUDES) -CFLAGS = -std=c11 -Wall $(DFLAGS) -DLOCALEDIR=\"$(LOCALEDIR)\" $(INCLUDES) -DGETTEXT_PACKAGE='"easystroke"' -LDFLAGS = $(DFLAGS) - -LIBS = $(DFLAGS) -lboost_serialization -lX11 -lXext -lXi -lXfixes -lXtst `pkg-config gtkmm-3.0 dbus-glib-1 --libs` - -BINARY = easystroke -ICON = easystroke.svg -MENU = easystroke.desktop -MANPAGE = easystroke.1 - -CCFILES = $(wildcard *.cc) -HFILES = $(wildcard *.h) -OFILES = $(patsubst %.cc,%.o,$(CCFILES)) stroke.o cellrenderertextish.o gui.o desktop.o version.o -POFILES = $(wildcard po/*.po) -MOFILES = $(patsubst po/%.po,po/%/LC_MESSAGES/easystroke.mo,$(POFILES)) -MODIRS = $(patsubst po/%.po,po/%,$(POFILES)) -DEPFILES = $(wildcard *.Po) -GENFILES = gui.c desktop.c po/POTFILES.in easystroke.desktop -GZFILES = $(wildcard *.gz) - -VERSION = $(shell test -e debian/changelog && grep '(.*)' debian/changelog | sed 's/.*(//' | sed 's/).*//' | head -n1 || (test -e version && cat version || git describe)) -GIT = $(wildcard .git/index version) -DIST = easystroke-$(VERSION) - --include debug.mk - -all: $(BINARY) $(MOFILES) - -.PHONY: all clean translate update-translations compile-translations complete - -clean: - $(RM) $(OFILES) $(BINARY) $(GENFILES) $(DEPFILES) $(MANPAGE) $(GZFILES) po/*.pot - $(RM) -r $(MODIRS) - -include $(DEPFILES) - -$(BINARY): $(OFILES) - $(CXX) $(LDFLAGS) -o $@ $(OFILES) $(LIBS) - -stroke.o: stroke.c - $(CC) $(STROKEFLAGS) $(AOFLAGS) -MT $@ -MMD -MP -MF $*.Po -o $@ -c $< - -%.o: %.c - $(CC) $(CFLAGS) $(OFLAGS) -MT $@ -MMD -MP -MF $*.Po -o $@ -c $< - -%.o: %.cc - $(CXX) $(CXXFLAGS) $(OFLAGS) -MT $@ -MMD -MP -MF $*.Po -o $@ -c $< - -version.o: $(GIT) - echo 'const char *version_string = "$(VERSION)";' | $(CXX) -o $@ -c -xc++ - - -gui.c: gui.glade - echo "const char *gui_buffer = \"\\" > $@ - sed 's/"GtkWindow"/"GtkApplicationWindow"/' $< | sed 's/"/\\"/g' | sed 's/ *\(.*\)/\1\\n\\/' >> $@ - echo "\";" >> $@ - -easystroke.desktop: easystroke.desktop.in $(MOFILES) - intltool-merge po/ -d -u $< $@ - -desktop.c: easystroke.desktop - echo "const char *desktop_file = \"\\" > $@ - sed 's/Exec=easystroke/Exec=%1$$s/' $< | sed 's/"/\\"/g' | sed 's/.*/&\\n\\/' >> $@ - echo "\";" >> $@ - -po/POTFILES.in: $(CCFILES) $(HFILES) - $(RM) $@ - for f in `grep -El "\<_\(" $^`; do echo $$f >> $@; done - echo gui.glade >> $@ - echo easystroke.desktop.in >> $@ - -translate: po/POTFILES.in - cd po && XGETTEXT_ARGS="--package-name=easystroke --copyright-holder='Thomas Jaeger '" intltool-update --pot -g messages - -compile-translations: $(MOFILES) - -update-translations: po/POTFILES.in - cd po && for f in $(POFILES); do \ - intltool-update `echo $$f | sed "s|po/\(.*\)\.po$$|\1|"`; \ - done - -strip-translations: - for f in $(POFILES); do \ - grep -v '^#:' $$f > $$f.out; \ - mv $$f.out $$f; \ - done - -po/%/LC_MESSAGES/easystroke.mo: po/%.po - mkdir -p po/$*/LC_MESSAGES - msgfmt -c $< -o $@ - -man: $(MANPAGE) - -$(MANPAGE): $(BINARY) - help2man -N -n "X11 gesture recognition application" ./$(BINARY) > $@ - -install: all - install -Ds $(BINARY) $(DESTDIR)$(BINDIR)/$(BINARY) - install -D -m 644 $(ICON) $(DESTDIR)$(ICONDIR)/$(ICON) - install -D -m 644 $(MENU) $(DESTDIR)$(MENUDIR)/$(MENU) - for f in $(MOFILES); do \ - install -D -m 644 $$f `echo $$f | sed "s|^po/|$(DESTDIR)$(LOCALEDIR)/|"`; \ - done - -uninstall: - $(RM) $(DESTDIR)$(BINDIR)/$(BINARY) - $(RM) $(DESTDIR)$(ICONDIR)/$(ICON) - $(RM) $(DESTDIR)$(MENUDIR)/$(MENU) - for f in $(MOFILES); do \ - $(RM) `echo $$f | sed "s|^po/|$(DESTDIR)$(LOCALEDIR)/|"`; \ - done - -tarball: $(DIST).tar.gz - -tmp/$(DIST): $(GIT) - $(RM) -r tmp - mkdir tmp - git archive --format=tar --prefix=$(DIST)/ HEAD | (cd tmp && tar x) - echo $(VERSION) > $@/version - $(RM) $@/.gitignore $@/release - -$(DIST).tar.gz: tmp/$(DIST) - tar -czf $@ -C tmp/ $(DIST) - $(RM) -r tmp - -complete: .clang_complete - -.clang_complete: Makefile - @echo $(CXXSTD) > $@ - @$(foreach inc,$(INCLUDES),echo $(inc) >> $@;) diff --git a/LICENSE b/NOTICE.md similarity index 71% rename from LICENSE rename to NOTICE.md index 08e60a63..93639f4c 100644 --- a/LICENSE +++ b/NOTICE.md @@ -1,3 +1,13 @@ +# Notices for Easy Gesture + +This project is licensed under the licensing terms described in [./LICENSE.md](./LICENSE.md) + +## Third-party Content + +### easystroke + +This project was based on easystroke by Thomas Jaegar under the following [license](https://github.com/thjaeger/easystroke/blob/master/LICENSE): + Copyright (c) 2008-2009, Thomas Jaeger Permission to use, copy, modify, and/or distribute this software for any diff --git a/README.md b/README.md new file mode 100644 index 00000000..19b8452f --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +Easy Gesture is a gesture-recognition application for X11. Gestures or strokes are movements that you make with you mouse (or your pen, finger etc.) while holding down a specific mouse button. Easy Gesture will execute certain actions if it recognizes the stroke; currently Easy Gesture can emulate key presses, execute shell commands, hold down modifiers and emulate a scroll wheel. The program was designed with Tablet PCs in mind and can be used effectively even without access to a keyboard. Easy Gesture tries to provide an intuitive and efficient user interface, while at the same time being highly configurable and offering many advanced features. + +# Documentation + +[Documentation](./docs/index.md) + +[Tips & Tricks](./docs/tips-and-tricks.md) + +[Build Instructions](./docs/build-instructions.md) + +Easy Gesture is distributed under the [MIT License](./LICENSE.md). + +# How can I help out? + +If you encounter any bugs or problems with Easy Gesture, please report them as a github issue. + +# Author + +Easy Gesture is being developed by [James Ratcliffe](mailto:berkeleybross@gmail.com). Comments, suggestions, bug reports, patches and criticism are very welcome! diff --git a/actiondb.cc b/actiondb.cc deleted file mode 100644 index 6b35f47c..00000000 --- a/actiondb.cc +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (c) 2008-2009, Thomas Jaeger - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include "actiondb.h" -#include "main.h" -#include "win.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -BOOST_CLASS_EXPORT(StrokeSet) - -BOOST_CLASS_EXPORT(Action) -BOOST_CLASS_EXPORT(Command) -BOOST_CLASS_EXPORT(ModAction) -BOOST_CLASS_EXPORT(SendKey) -BOOST_CLASS_EXPORT(SendText) -BOOST_CLASS_EXPORT(Scroll) -BOOST_CLASS_EXPORT(Ignore) -BOOST_CLASS_EXPORT(Button) -BOOST_CLASS_EXPORT(Misc) - -template void Unique::serialize(Archive & ar, const unsigned int version) {} - -template void Action::serialize(Archive & ar, const unsigned int version) {} - -template void Command::serialize(Archive & ar, const unsigned int version) { - ar & boost::serialization::base_object(*this); - ar & cmd; -} - -template void ModAction::serialize(Archive & ar, const unsigned int version) { - ar & boost::serialization::base_object(*this); - ar & mods; -} - -template void SendKey::load(Archive & ar, const unsigned int version) { - guint code; - ar & boost::serialization::base_object(*this); - ar & key; - ar & code; - if (version < 1) { - bool xtest; - ar & xtest; - } -} - -template void SendKey::save(Archive & ar, const unsigned int version) const { - guint code = 0; - ar & boost::serialization::base_object(*this); - ar & key; - ar & code; -} - -template void SendText::load(Archive & ar, const unsigned int version) { - ar & boost::serialization::base_object(*this); - std::string str; - ar & str; - text = str; -} - -template void SendText::save(Archive & ar, const unsigned int version) const { - ar & boost::serialization::base_object(*this); - std::string str(text); - ar & str; -} - -template void Scroll::serialize(Archive & ar, const unsigned int version) { - ar & boost::serialization::base_object(*this); -} - -template void Ignore::serialize(Archive & ar, const unsigned int version) { - ar & boost::serialization::base_object(*this); -} - -template void Button::serialize(Archive & ar, const unsigned int version) { - ar & boost::serialization::base_object(*this); - ar & button; -} - -template void Misc::serialize(Archive & ar, const unsigned int version) { - ar & boost::serialization::base_object(*this); - ar & type; -} - -template void StrokeSet::serialize(Archive & ar, const unsigned int version) { - ar & boost::serialization::base_object >(*this); -} - -template void StrokeInfo::serialize(Archive & ar, const unsigned int version) { - ar & strokes; - ar & action; - if (version == 0) return; - ar & name; -} - -using namespace std; - -void Command::run() { - pid_t pid = fork(); - switch (pid) { - case 0: - execlp("/bin/sh", "sh", "-c", cmd.c_str(), nullptr); - exit(1); - case -1: - printf(_("Error: can't execute command \"%s\": fork() failed\n"), cmd.c_str()); - } -} - -ButtonInfo Button::get_button_info() const { - ButtonInfo bi; - bi.button = button; - bi.state = mods; - return bi; -} - - -const Glib::ustring Button::get_label() const { - return get_button_info().get_button_text(); -} - -const Glib::ustring Misc::get_label() const { return _(types[type]); } - -const char *Misc::types[5] = { N_("None"), N_("Unminimize"), N_("Show/Hide"), N_("Disable (Enable)"), nullptr }; - -template void ActionListDiff::serialize(Archive & ar, const unsigned int version) { - ar & deleted; - ar & added; - ar & name; - ar & children; - ar & app; - if (version == 0) - return; - ar & order; -} - -ActionDB::ActionDB() { - root.name = _("Default"); -} - -template void ActionDB::load(Archive & ar, const unsigned int version) { - if (version >= 2) { - ar & root; - } - if (version == 1) { - std::map strokes; - ar & strokes; - for (std::map::iterator i = strokes.begin(); i != strokes.end(); ++i) - root.add(i->second); - } - if (version == 0) { - std::map strokes; - ar & strokes; - for (std::map::iterator i = strokes.begin(); i != strokes.end(); ++i) { - i->second.name = i->first; - root.add(i->second); - } - } - - root.fix_tree(version == 2); - root.add_apps(apps); - root.name = _("Default"); -} - -template void ActionDB::save(Archive & ar, const unsigned int version) const { - ar & root; -} - -Source action_dummy; - -void update_actions() { - action_dummy.set(false); -} - -void ActionDBWatcher::init() { - std::string filename = config_dir+"actions"; - for (const char **v = actions_versions; *v; v++) - if (is_file(filename + *v)) { - filename += *v; - try { - ifstream ifs(filename.c_str(), ios::binary); - if (!ifs.fail()) { - boost::archive::text_iarchive ia(ifs); - ia >> actions; - if (verbosity >= 2) - printf("Loaded actions.\n"); - } - } catch (exception &e) { - printf(_("Error: Couldn't read action database: %s.\n"), e.what()); - } - break; - } - watch(action_dummy); -} - -void ActionDBWatcher::timeout() { - std::string filename = config_dir+"actions"+actions_versions[0]; - std::string tmp = filename + ".tmp"; - try { - ofstream ofs(tmp.c_str()); - boost::archive::text_oarchive oa(ofs); - oa << (const ActionDB &)actions; - ofs.close(); - if (rename(tmp.c_str(), filename.c_str())) - throw std::runtime_error(_("rename() failed")); - if (verbosity >= 2) - printf("Saved actions.\n"); - } catch (exception &e) { - printf(_("Error: Couldn't save action database: %s.\n"), e.what()); - if (!good_state) - return; - good_state = false; - error_dialog(Glib::ustring::compose(_( "Couldn't save %1. Your changes will be lost. " - "Make sure that \"%2\" is a directory and that you have write access to it. " - "You can change the configuration directory " - "using the -c or --config-dir command line options."), _("actions"), config_dir)); - } -} - - -RStrokeInfo ActionListDiff::get_info(Unique *id, bool *deleted, bool *stroke, bool *name, bool *action) const { - if (deleted) - *deleted = this->deleted.count(id); - if (stroke) - *stroke = false; - if (name) - *name = false; - if (action) - *action = false; - RStrokeInfo si = parent ? parent->get_info(id) : RStrokeInfo(new StrokeInfo); - std::map::const_iterator i = added.find(id); - for (i = added.begin(); i != added.end(); i++) { - if (i->first == id) - break; - } - if (i == added.end()) { - return si; - } - if (i->second.name != "") { - si->name = i->second.name; - if (name) - *name = parent; - } - if (i->second.strokes.size()) { - si->strokes = i->second.strokes; - if (stroke) - *stroke = parent; - } - if (i->second.action) { - si->action = i->second.action; - if (action) - *action = parent; - } - return si; -} - -boost::shared_ptr > ActionListDiff::get_strokes() const { - boost::shared_ptr > strokes = parent ? parent->get_strokes() : - boost::shared_ptr >(new std::map); - for (std::set::const_iterator i = deleted.begin(); i != deleted.end(); i++) - strokes->erase(*i); - for (std::map::const_iterator i = added.begin(); i != added.end(); i++) - if (i->second.strokes.size()) - (*strokes)[i->first] = i->second.strokes; - return strokes; -} - -boost::shared_ptr > ActionListDiff::get_ids(bool include_deleted) const { - boost::shared_ptr > ids = parent ? parent->get_ids(false) : - boost::shared_ptr >(new std::set); - if (!include_deleted) - for (std::set::const_iterator i = deleted.begin(); i != deleted.end(); i++) - ids->erase(*i); - for (std::map::const_iterator i = added.begin(); i != added.end(); i++) - ids->insert(i->first); - return ids; -} - -void ActionListDiff::all_strokes(std::list &strokes) const { - for (std::map::const_iterator i = added.begin(); i != added.end(); i++) - for (std::set::const_iterator j = i->second.strokes.begin(); j != i->second.strokes.end(); j++) - strokes.push_back(*j); - for (std::list::const_iterator i = children.begin(); i != children.end(); i++) - i->all_strokes(strokes); -} - -RAction ActionListDiff::handle(RStroke s, RRanking &r) const { - if (!s) - return RAction(); - r.reset(new Ranking); - r->stroke = s; - r->score = 0.0; - boost::shared_ptr > strokes = get_strokes(); - for (std::map::const_iterator i = strokes->begin(); i!=strokes->end(); i++) { - for (StrokeSet::iterator j = i->second.begin(); j!=i->second.end(); j++) { - double score; - int match = Stroke::compare(s, *j, score); - if (match < 0) - continue; - RStrokeInfo si = get_info(i->first); - r->r.insert(pair > - (score, pair(si->name, *j))); - if (score > r->score) { - r->score = score; - if (match) { - r->name = si->name; - r->action = si->action; - r->best_stroke = *j; - } - } - } - } - if (!r->action && s->trivial()) - return RAction(new Click); - if (r->action) { - if (verbosity >= 1) - printf("Executing Action %s\n", r->name.c_str()); - } else { - if (verbosity >= 1) - printf("Couldn't find matching stroke.\n"); - } - return r->action; -} - -void ActionListDiff::handle_advanced(RStroke s, std::map &as, - std::map &rs, int b1, int b2) const { - if (!s) - return; - boost::shared_ptr > strokes = get_strokes(); - for (std::map::const_iterator i = strokes->begin(); i!=strokes->end(); i++) { - for (StrokeSet::iterator j = i->second.begin(); j!=i->second.end(); j++) { - int b = (*j)->button; - if (!s->timeout && !b) - continue; - s->button = b; - double score; - int match = Stroke::compare(s, *j, score); - if (match < 0) - continue; - Ranking *r; - if (b == b1) - b = b2; - if (rs.count(b)) { - r = rs[b].get(); - } else { - r = new Ranking; - rs[b].reset(r); - r->stroke = RStroke(new Stroke(*s)); - r->score = -1; - } - RStrokeInfo si = get_info(i->first); - r->r.insert(pair > - (score, pair(si->name, *j))); - if (score > r->score) { - r->score = score; - if (match) { - r->name = si->name; - r->action = si->action; - r->best_stroke = *j; - as[b] = si->action; - } - } - } - } -} - -ActionListDiff::~ActionListDiff() { - if (app) - actions.apps.erase(name); -} - -ActionDB actions; diff --git a/actiondb.h b/actiondb.h deleted file mode 100644 index 1189b10c..00000000 --- a/actiondb.h +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2008-2009, Thomas Jaeger - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef __STROKEDB_H__ -#define __STROKEDB_H__ -#include -#include -#include -#include -#include -#include -#include - -#include "gesture.h" -#include "prefdb.h" - -class Action; -class Command; -class SendKey; -class SendText; -class Scroll; -class Ignore; -class Button; -class Misc; -class Ranking; - -typedef boost::shared_ptr RAction; -typedef boost::shared_ptr RCommand; -typedef boost::shared_ptr RSendKey; -typedef boost::shared_ptr RSendText; -typedef boost::shared_ptr RScroll; -typedef boost::shared_ptr RIgnore; -typedef boost::shared_ptr