The Pedigree Project  0.1
Ps2Mouse.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "Ps2Mouse.h"
21 #include "pedigree/kernel/machine/InputManager.h"
22 #include "pedigree/kernel/process/Thread.h"
23 #include "pedigree/kernel/processor/Processor.h"
24 #include "pedigree/kernel/processor/ProcessorInformation.h"
25 #include "pedigree/kernel/utilities/new"
26 #include "system/kernel/machine/mach_pc/Ps2Controller.h"
27 
28 class Process;
29 
30 Ps2Mouse::Ps2Mouse(Device *pDev)
31  : m_pController(0), m_Buffer(), m_BufferIndex(0), m_BufferLock(),
32  m_IrqWait(0)
33 {
34  setSpecificType(String("ps2-mouse"));
35 
36  for (size_t i = 0; i < m_nHandlers; ++i)
37  {
38  m_Handlers[i] = nullptr;
39  m_HandlerParams[i] = nullptr;
40  }
41 }
42 
43 Ps2Mouse::~Ps2Mouse()
44 {
45 }
46 
48 {
49  m_pController = pController;
50 
52 
53  // Set up the mouse.
54  uint8_t result = 0;
55  m_pController->writeSecondPort(SetDefaults);
56  m_pController->readSecondPort(result);
57  m_pController->writeSecondPort(MouseStream);
58  m_pController->readSecondPort(result);
59 
60  // Finally, enable IRQs for the mouse
61  m_pController->setIrqEnable(true, true);
62 
63  Process *pProcess =
64  Processor::information().getCurrentThread()->getParent();
65  Thread *pThread = new Thread(pProcess, readerThreadTrampoline, this);
66  pThread->detach();
67 
68  return true;
69 }
70 
71 void Ps2Mouse::write(const char *bytes, size_t len)
72 {
73  for (size_t i = 0; i < len; ++i)
74  {
75  m_pController->writeSecondPort(bytes[i]);
76  }
77 }
78 
79 void Ps2Mouse::subscribe(MouseHandlerFunction handler, void *param)
80 {
81  for (size_t i = 0; i < m_nHandlers; ++i)
82  {
83  if (m_Handlers[i])
84  {
85  continue;
86  }
87 
88  m_Handlers[i] = handler;
89  m_HandlerParams[i] = param;
90  break;
91  }
92 }
93 
94 void Ps2Mouse::updateSubscribers(const void *buffer, size_t len)
95 {
96  for (size_t i = 0; i < m_nHandlers; ++i)
97  {
98  if (!m_Handlers[i])
99  {
100  continue;
101  }
102 
103  m_Handlers[i](m_HandlerParams[i], buffer, len);
104  }
105 }
106 
107 int Ps2Mouse::readerThreadTrampoline(void *param)
108 {
109  Ps2Mouse *instance = reinterpret_cast<Ps2Mouse *>(param);
110  instance->readerThread();
111 }
112 
113 void Ps2Mouse::readerThread()
114 {
115  while (true)
116  {
117  uint8_t byte;
118  if (!m_pController->readSecondPort(byte))
119  {
120  continue;
121  }
122 
123  updateSubscribers(&byte, 1);
124 
125  if (byte == 0xFA || byte == 0xFE)
126  {
127  // ignore for now
128  continue;
129  }
130 
131  ssize_t xrel = 0;
132  ssize_t yrel = 0;
133  uint32_t buttons = 0;
134  bool needUpdate = false;
135  {
136  m_BufferLock.acquire();
137  m_Buffer[m_BufferIndex++] = byte;
138  needUpdate = m_BufferIndex == 3;
139  if (needUpdate)
140  {
141  xrel = static_cast<ssize_t>(static_cast<int8_t>(m_Buffer[1]));
142  yrel = static_cast<ssize_t>(static_cast<int8_t>(m_Buffer[2]));
143  buttons = static_cast<uint32_t>(m_Buffer[0]) & 0x3;
144  m_BufferIndex = 0;
145  }
146  m_BufferLock.release();
147  }
148 
149  // lock no longer taken, safe to send the update
150  if (needUpdate)
151  {
152  InputManager::instance().mouseUpdate(xrel, yrel, 0, buttons);
153  }
154  }
155 }
virtual bool initialise(Ps2Controller *pController)
Definition: Ps2Mouse.cc:47
void mouseUpdate(ssize_t relX, ssize_t relY, ssize_t relZ, uint32_t buttonBitmap)
Called whenever mouse input comes in.
Definition: String.h:49
static ProcessorInformation & information()
Definition: Processor.cc:45
Definition: Device.h:43
virtual void setSpecificType(String str)
Definition: Device.h:174
EXPORTED_PUBLIC void writeSecondPort(uint8_t byte)
Send a byte to the second port of the PS/2 controller.
static InputManager & instance()
Singleton design.
Definition: InputManager.h:107
Definition: Thread.h:54
bool detach()
Definition: Thread.cc:885