| Index: chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc
|
| diff --git a/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc b/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b4b939ef048ffea94960e1ce187b7b74e67912f1
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc
|
| @@ -0,0 +1,184 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/extensions/api/braille_display_private/brlapi_connection.h"
|
| +
|
| +#include "base/chromeos/chromeos_version.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +
|
| +namespace extensions {
|
| +using base::MessageLoopForIO;
|
| +namespace api {
|
| +namespace braille_display_private {
|
| +
|
| +namespace {
|
| +// Default virtual terminal. This can be overriden by setting the
|
| +// WINDOWPATH environment variable. This is only used when not running
|
| +// under Crhome OS (that is in aura for a Linux desktop).
|
| +// TODO(plundblad): Find a way to detect the controlling terminal of the
|
| +// X server.
|
| +static const int kDefaultTtyLinux = 7;
|
| +#if defined(OS_CHROMEOS)
|
| +// The GUI is always running on vt1 in Chrome OS.
|
| +static const int kDefaultTtyChromeOS = 1;
|
| +#endif
|
| +} // namespace
|
| +
|
| +class BrlapiConnectionImpl : public BrlapiConnection,
|
| + MessageLoopForIO::Watcher {
|
| + public:
|
| + BrlapiConnectionImpl(LibBrlapiLoader* loader) :
|
| + libbrlapi_loader_(loader) {}
|
| +
|
| + virtual ~BrlapiConnectionImpl() {
|
| + Disconnect();
|
| + }
|
| +
|
| + virtual bool Connect(const OnDataReadyCallback& on_data_ready) OVERRIDE;
|
| + virtual void Disconnect() OVERRIDE;
|
| + virtual bool Connected() OVERRIDE { return handle_; }
|
| + virtual brlapi_error_t* BrlapiError() OVERRIDE;
|
| + virtual std::string BrlapiStrError() OVERRIDE;
|
| + virtual bool GetDisplaySize(size_t* size) OVERRIDE;
|
| + virtual bool WriteDots(const unsigned char* cells) OVERRIDE;
|
| + virtual int ReadKey(brlapi_keyCode_t* keyCode) OVERRIDE;
|
| +
|
| + // MessageLoopForIO::Watcher
|
| + virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
|
| + on_data_ready_.Run();
|
| + }
|
| +
|
| + virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
|
| +
|
| + private:
|
| + bool CheckConnected();
|
| +
|
| + LibBrlapiLoader* libbrlapi_loader_;
|
| + scoped_ptr<brlapi_handle_t, base::FreeDeleter> handle_;
|
| + MessageLoopForIO::FileDescriptorWatcher fd_controller_;
|
| + OnDataReadyCallback on_data_ready_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BrlapiConnectionImpl);
|
| +};
|
| +
|
| +BrlapiConnection::BrlapiConnection() {
|
| +}
|
| +
|
| +BrlapiConnection::~BrlapiConnection() {
|
| +}
|
| +
|
| +scoped_ptr<BrlapiConnection> BrlapiConnection::Create(
|
| + LibBrlapiLoader* loader) {
|
| + DCHECK(loader->loaded());
|
| + return scoped_ptr<BrlapiConnection>(new BrlapiConnectionImpl(loader));
|
| +}
|
| +
|
| +bool BrlapiConnectionImpl::Connect(const OnDataReadyCallback& on_data_ready) {
|
| + DCHECK(!handle_);
|
| + handle_.reset((brlapi_handle_t*) malloc(
|
| + libbrlapi_loader_->brlapi_getHandleSize()));
|
| + int fd = libbrlapi_loader_->brlapi__openConnection(handle_.get(), NULL, NULL);
|
| + if (fd < 0) {
|
| + handle_.reset();
|
| + LOG(ERROR) << "Error connecting to brlapi: " << BrlapiStrError();
|
| + return false;
|
| + }
|
| + int path[2] = {0, 0};
|
| + int pathElements = 0;
|
| +#if defined(OS_CHROMEOS)
|
| + if (base::chromeos::IsRunningOnChromeOS())
|
| + path[pathElements++] = kDefaultTtyChromeOS;
|
| +#endif
|
| + if (pathElements == 0 && getenv("WINDOWPATH") == NULL)
|
| + path[pathElements++] = kDefaultTtyLinux;
|
| + if (libbrlapi_loader_->brlapi__enterTtyModeWithPath(
|
| + handle_.get(), path, pathElements, NULL) < 0) {
|
| + LOG(ERROR) << "brlapi: couldn't enter tty mode: " << BrlapiStrError();
|
| + Disconnect();
|
| + return false;
|
| + }
|
| +
|
| + const brlapi_keyCode_t extraKeys[] = {
|
| + BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_OFFLINE,
|
| + };
|
| + if (libbrlapi_loader_->brlapi__acceptKeys(
|
| + handle_.get(), brlapi_rangeType_command, extraKeys,
|
| + arraysize(extraKeys)) < 0) {
|
| + LOG(ERROR) << "Couldn't acceptKeys: " << BrlapiStrError();
|
| + Disconnect();
|
| + return false;
|
| + }
|
| +
|
| + if (!MessageLoopForIO::current()->WatchFileDescriptor(
|
| + fd, true, MessageLoopForIO::WATCH_READ, &fd_controller_, this)) {
|
| + LOG(ERROR) << "Couldn't watch file descriptor " << fd;
|
| + Disconnect();
|
| + return false;
|
| + }
|
| +
|
| + on_data_ready_ = on_data_ready;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +void BrlapiConnectionImpl::Disconnect() {
|
| + if (!handle_) {
|
| + return;
|
| + }
|
| + fd_controller_.StopWatchingFileDescriptor();
|
| + libbrlapi_loader_->brlapi__closeConnection(
|
| + handle_.get());
|
| + handle_.reset();
|
| +}
|
| +
|
| +brlapi_error_t* BrlapiConnectionImpl::BrlapiError() {
|
| + return libbrlapi_loader_->brlapi_error_location();
|
| +}
|
| +
|
| +std::string BrlapiConnectionImpl::BrlapiStrError() {
|
| + return libbrlapi_loader_->brlapi_strerror(BrlapiError());
|
| +}
|
| +
|
| +bool BrlapiConnectionImpl::GetDisplaySize(size_t* size) {
|
| + if (!CheckConnected()) {
|
| + return false;
|
| + }
|
| + unsigned int columns, rows;
|
| + if (libbrlapi_loader_->brlapi__getDisplaySize(
|
| + handle_.get(), &columns, &rows) < 0) {
|
| + LOG(ERROR) << "Couldn't get braille display size " << BrlapiStrError();
|
| + return false;
|
| + }
|
| + *size = columns * rows;
|
| + return true;
|
| +}
|
| +
|
| +bool BrlapiConnectionImpl::WriteDots(const unsigned char* cells) {
|
| + if (!CheckConnected())
|
| + return false;
|
| + if (libbrlapi_loader_->brlapi__writeDots(handle_.get(), cells) < 0) {
|
| + LOG(ERROR) << "Couldn't write to brlapi: " << BrlapiStrError();
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +int BrlapiConnectionImpl::ReadKey(brlapi_keyCode_t* key_code) {
|
| + if (!CheckConnected())
|
| + return -1;
|
| + return libbrlapi_loader_->brlapi__readKey(
|
| + handle_.get(), 0 /*wait*/, key_code);
|
| +}
|
| +
|
| +bool BrlapiConnectionImpl::CheckConnected() {
|
| + if (!handle_) {
|
| + BrlapiError()->brlerrno = BRLAPI_ERROR_ILLEGAL_INSTRUCTION;
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +} // braille_display_private
|
| +} // api
|
| +} // extensions
|
|
|