OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/extensions/api/braille_display_private/brlapi_connectio n.h" | |
6 | |
7 #include "base/chromeos/chromeos_version.h" | |
8 #include "base/message_loop/message_loop.h" | |
9 | |
10 namespace extensions { | |
11 using base::MessageLoopForIO; | |
12 namespace api { | |
13 namespace braille_display_private { | |
14 | |
15 namespace { | |
16 // Default virtual terminal. This can be overriden by setting the | |
17 // WINDOWPATH environment variable. This is only used when not running | |
18 // under CrhomeOS (that is in aura for a Linux desktop). | |
Jorge Lucangeli Obes
2013/09/10 20:37:36
Nit: "Chrome OS"
| |
19 // TODO(plundblad): Find a way to detect the controlling terminal of the | |
20 // X server. | |
21 static const int kDefaultTtyLinux = 7; | |
22 #if defined(OS_CHROMEOS) | |
23 // The GUI is always running on vt1 in ChromeOS. | |
24 static const int kDefaultTtyChromeOS = 1; | |
25 #endif | |
26 } // namespace | |
27 | |
28 class BrlapiConnectionImpl : public BrlapiConnection, | |
29 MessageLoopForIO::Watcher { | |
30 public: | |
31 BrlapiConnectionImpl(LibBrlapiLoader* loader) : | |
32 libbrlapi_loader_(loader) {} | |
33 | |
34 virtual ~BrlapiConnectionImpl() { | |
35 Disconnect(); | |
36 } | |
37 | |
38 virtual bool Connect(const OnDataReadyCallback& onDataReady) OVERRIDE; | |
39 virtual void Disconnect() OVERRIDE; | |
40 virtual bool Connected() OVERRIDE { return handle_; } | |
41 virtual brlapi_error_t* BrlapiError() OVERRIDE; | |
42 virtual std::string BrlapiStrError() OVERRIDE; | |
43 virtual bool GetDisplaySize(size_t* size) OVERRIDE; | |
44 virtual bool WriteDots(const unsigned char* cells) OVERRIDE; | |
45 virtual int ReadKey(brlapi_keyCode_t* keyCode) OVERRIDE; | |
46 | |
47 // MessageLoopForIO::Watcher | |
48 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE { | |
49 onDataReady_.Run(); | |
50 } | |
51 | |
52 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} | |
53 | |
54 private: | |
55 bool CheckConnected(); | |
56 | |
57 LibBrlapiLoader* libbrlapi_loader_; | |
58 scoped_ptr<brlapi_handle_t, base::FreeDeleter> handle_; | |
59 MessageLoopForIO::FileDescriptorWatcher fd_controller_; | |
60 OnDataReadyCallback onDataReady_; | |
dmazzoni
2013/09/10 19:50:08
onDataReady -> on_data_ready
| |
61 | |
62 DISALLOW_COPY_AND_ASSIGN(BrlapiConnectionImpl); | |
63 }; | |
64 | |
65 BrlapiConnection::BrlapiConnection() { | |
66 } | |
67 | |
68 BrlapiConnection::~BrlapiConnection() { | |
69 } | |
70 | |
71 scoped_ptr<BrlapiConnection> BrlapiConnection::Create( | |
72 LibBrlapiLoader* loader) { | |
73 DCHECK(loader->loaded()); | |
74 return scoped_ptr<BrlapiConnection>(new BrlapiConnectionImpl(loader)); | |
75 } | |
76 | |
77 bool BrlapiConnectionImpl::Connect(const OnDataReadyCallback& onDataReady) { | |
78 DCHECK(!handle_); | |
79 handle_.reset((brlapi_handle_t*) malloc( | |
80 libbrlapi_loader_->brlapi_getHandleSize())); | |
81 int fd = libbrlapi_loader_->brlapi__openConnection(handle_.get(), NULL, NULL); | |
82 if (fd < 0) { | |
83 handle_.reset(); | |
84 LOG(ERROR) << "Error connecting to brlapi: " << BrlapiStrError(); | |
85 return false; | |
86 } | |
87 int path[2] = {0, 0}; | |
88 int pathElements = 0; | |
89 #if defined(OS_CHROMEOS) | |
90 if (base::chromeos::IsRunningOnChromeOS()) | |
91 path[pathElements++] = kDefaultTtyChromeOS; | |
92 #endif | |
93 if (pathElements == 0 && getenv("WINDOWPATH") == NULL) | |
94 path[pathElements++] = kDefaultTtyLinux; | |
95 if (libbrlapi_loader_->brlapi__enterTtyModeWithPath( | |
96 handle_.get(), path, pathElements, NULL) < 0) { | |
97 LOG(ERROR) << "brlapi: couldn't enter tty mode: " << BrlapiStrError(); | |
98 Disconnect(); | |
99 return false; | |
100 } | |
101 | |
102 const brlapi_keyCode_t extraKeys[] = { | |
103 BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_OFFLINE, | |
104 }; | |
105 if (libbrlapi_loader_->brlapi__acceptKeys( | |
106 handle_.get(), brlapi_rangeType_command, extraKeys, | |
107 arraysize(extraKeys)) < 0) { | |
108 LOG(ERROR) << "Couldn't acceptKeys: " << BrlapiStrError(); | |
109 Disconnect(); | |
110 return false; | |
111 } | |
112 | |
113 if (!MessageLoopForIO::current()->WatchFileDescriptor( | |
114 fd, true, MessageLoopForIO::WATCH_READ, &fd_controller_, this)) { | |
115 LOG(ERROR) << "Couldn't watch file descriptor " << fd; | |
116 Disconnect(); | |
117 return false; | |
118 } | |
119 | |
120 onDataReady_ = onDataReady; | |
121 | |
122 return true; | |
123 } | |
124 | |
125 void BrlapiConnectionImpl::Disconnect() { | |
126 if (!handle_) { | |
127 return; | |
128 } | |
129 fd_controller_.StopWatchingFileDescriptor(); | |
130 libbrlapi_loader_->brlapi__closeConnection( | |
131 handle_.get()); | |
132 handle_.reset(); | |
133 } | |
134 | |
135 brlapi_error_t* BrlapiConnectionImpl::BrlapiError() { | |
136 return libbrlapi_loader_->brlapi_error_location(); | |
137 } | |
138 | |
139 std::string BrlapiConnectionImpl::BrlapiStrError() { | |
140 return libbrlapi_loader_->brlapi_strerror(BrlapiError()); | |
141 } | |
142 | |
143 bool BrlapiConnectionImpl::GetDisplaySize(size_t* size) { | |
144 if (!CheckConnected()) { | |
145 return false; | |
146 } | |
147 unsigned int columns, rows; | |
148 if (libbrlapi_loader_->brlapi__getDisplaySize( | |
149 handle_.get(), &columns, &rows) < 0) { | |
150 LOG(ERROR) << "Couldn't get braille display size " << BrlapiStrError(); | |
151 return false; | |
152 } | |
153 *size = columns * rows; | |
154 return true; | |
155 } | |
156 | |
157 bool BrlapiConnectionImpl::WriteDots(const unsigned char* cells) { | |
158 if (!CheckConnected()) | |
159 return false; | |
160 if (libbrlapi_loader_->brlapi__writeDots(handle_.get(), cells) < 0) { | |
161 LOG(ERROR) << "Couldn't write to brlapi: " << BrlapiStrError(); | |
162 return false; | |
163 } | |
164 return true; | |
165 } | |
166 | |
167 int BrlapiConnectionImpl::ReadKey(brlapi_keyCode_t* key_code) { | |
168 if (!CheckConnected()) | |
169 return -1; | |
170 return libbrlapi_loader_->brlapi__readKey( | |
171 handle_.get(), 0 /*wait*/, key_code); | |
172 } | |
173 | |
174 bool BrlapiConnectionImpl::CheckConnected() { | |
175 if (!handle_) { | |
176 BrlapiError()->brlerrno = BRLAPI_ERROR_ILLEGAL_INSTRUCTION; | |
177 return false; | |
178 } | |
179 return true; | |
180 } | |
181 | |
182 } // braille_display_private | |
183 } // api | |
184 } // extensions | |
OLD | NEW |