use the -newos toolchain even if -elf is present.
[newos.git] / apps / window_server / SerialMouse.cpp
blob4999621a61380967a9ed0e97bb428d107a8d0141
1 #include <i386/io.h>
2 #include <blt/syscall.h>
3 #include <stdio.h>
4 #include "SerialMouse.h"
5 #include "util.h"
7 #define POLL 1
9 const int kBaudRate = 1200;
10 const int kPortBase = 0x3f8;
12 SerialMouse::SerialMouse(int xmax, int ymax)
13 : fXPos(xmax / 2),
14 fYPos(ymax / 2),
15 fXMax(xmax),
16 fYMax(ymax)
18 unsigned short divisor = 115200 / kBaudRate;
20 outb(0, kPortBase + 1); // No interrupts for now
21 outb(0, kPortBase + 4); // clear DTR and RTS
23 outb(0x80, kPortBase + 3); // load divisor latch
24 outb((divisor & 0xff), kPortBase); // divisor LSB
25 outb((divisor >> 8), kPortBase + 1); // divisor MSB
26 outb(2, kPortBase + 3); // clear DLAB, set up for 7N1
28 outb(3, kPortBase + 4); // Say hello. Raise DTR and RTS
29 if (SerialRead() == 'M')
30 printf("Detected MS serial mouse\n");
34 // The data is sent in 3 byte packets in following format:
35 // D7 D6 D5 D4 D3 D2 D1 D0
36 // 1. X 1 LB RB Y7 Y6 X7 X6
37 // 2. X 0 X5 X4 X3 X2 X1 X0
38 // 3. X 0 Y5 Y4 Y3 Y2 Y1 Y0
39 void SerialMouse::GetPos(int *out_x, int *out_y, int *out_buttons)
41 char b1;
43 // loop until we get to the beginning of a packet
44 while (true) {
45 b1 = SerialRead();
46 if ((b1 & (1 << 6)) != 0)
47 break; // beginning of packet
50 char b2 = SerialRead();
51 char b3 = SerialRead();
53 fXPos += (int)(char)((b1 << 6) | (b2 & 0x3f));
54 fYPos += (int)(char)(((b1 << 4) & 0xc0) | (b3 & 0x3f));
56 fXPos = min(fXPos, fXMax);
57 fXPos = max(fXPos, 0);
58 fYPos = min(fYPos, fYMax);
59 fYPos = max(fYPos, 0);
61 *out_buttons = (b1 >> 4) & 3;
62 *out_x = fXPos;
63 *out_y = fYPos;
66 unsigned char SerialMouse::SerialRead()
68 while (true) {
69 #if POLL
70 while ((inb(kPortBase + 5) & 1) == 0)
72 #else
73 os_handle_irq(4);
74 outb(1, kPortBase + 1); // Interrupt on recieve ready
75 os_sleep_irq();
76 int id = inb(kPortBase + 2);
77 if ((id & 1) == 0 || (id >> 1) != 2)
78 continue; // Not for me
79 #endif
81 break;
84 return inb(kPortBase);