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 |