3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include <libx/base.h>
26 #include <libx/cursor.h>
36 static unsigned mouse_accel
= 0;
39 #define MOUSE_FLAG_BUTTON1 0x1 /* Left mouse button */
40 #define MOUSE_FLAG_BUTTON2 0x2 /* Right mouse button */
41 #define MOUSE_FLAG_BUTTON3 0x4 /* Middle mouse button */
42 #define MOUSE_FLAG_BUTTON4 0x8 /* Extra mouse button */
43 #define MOUSE_FLAG_BUTTON5 0x10 /* Extra mouse button */
44 #define MOUSE_FLAG_SCROLLUP 0x20 /* Scroll button/wheel - step up */
45 #define MOUSE_FLAG_SCROLLDOWN 0x40 /* Scroll button/wheel - step down */
50 static const int kBaudRate
= 1200;
51 static const int kPortBase
= 0x3f8;
55 static int cursor_state
;
57 static char mouse_type
= -1;
59 static char rs232_read_block ()
66 char *memptr
= (char *) 0x9000;
72 static unsigned char inportb (unsigned p
)
74 unsigned char *ptr
= (unsigned char *) p
;
79 static void outportb (unsigned char val
, unsigned p
)
81 unsigned char *ptr
= (unsigned char *) p
;
88 return inportb (kPortBase
+ 5) & 1;
91 static char rs232_read_nonblock ()
93 int r
= serial_recieved();
98 return inportb (kPortBase
);
101 static unsigned xcursor_serialmouse_init ()
103 unsigned short divisor
= 115200 / kBaudRate
;
105 outportb (0, kPortBase
+ 1); // No interrupts for now
106 outportb (0, kPortBase
+ 4); // clear DTR and RTS
108 outportb (0x80, kPortBase
+ 3); // load divisor latch
109 outportb ((divisor
& 0xff), kPortBase
); // divisor LSB
110 outportb ((divisor
>> 8), kPortBase
+ 1); // divisor MSB
111 outportb (2, kPortBase
+ 3); // clear DLAB, set up for 7N1
113 outportb (3, kPortBase
+ 4); // Say hello. Raise DTR and RTS
118 char protocol
= rs232_read_block ();
126 static unsigned xcursor_ps2mouse_init ()
128 ps2_fd
= open ("/dev/mouseps2", O_RDONLY
);
136 unsigned xcursor_init ()
138 /* initial cursor position */
142 /* automatic mouse type selection */
143 if (mouse_type
!= -1)
146 if (xcursor_ps2mouse_init ())
148 else if (xcursor_serialmouse_init ())
155 switch (mouse_type
) {
160 /* serial mouse over rs232 */
161 return xcursor_serialmouse_init ();
164 return xcursor_ps2mouse_init ();
170 static void xcursor_ps2mouse_handler ()
172 /* low-level mouse structure */
174 unsigned short flags
;
175 short pos_x
; /* Difference - horizontal position */
176 short pos_y
; /* Difference - vertical position */
181 int r
= read (ps2_fd
, &mouse
, sizeof (dev_mouse_t
));
186 lseek (ps2_fd
, 0, SEEK_SET
);
188 cursor_x
+= mouse
.pos_x
;
189 cursor_y
+= mouse
.pos_y
;
191 if (mouse
.flags
& MOUSE_FLAG_BUTTON2
)
192 cursor_state
= XCURSOR_STATE_RBUTTON
;
193 else if (mouse
.flags
& MOUSE_FLAG_BUTTON1
)
194 cursor_state
= XCURSOR_STATE_LBUTTON
;
199 static void xcursor_serialmouse_handler ()
201 char b1
= rs232_read_nonblock ();
203 if ((b1
& (1 << 6)) == 0)
206 // beginning of packet
207 char b2
= rs232_read_block ();
208 char b3
= rs232_read_block ();
210 cursor_x
+= (int) (char) ((b1
<< 6) | (b2
& 0x3f));
211 cursor_y
+= (int) (char) (((b1
<< 4) & 0xc0) | (b3
& 0x3f));
213 cursor_state
= (b1
>> 4) & 3;
216 static void xcursor_kbmouse_handler ()
218 int scancode
= getkey ();
223 cursor_x
-= mouse_accel
;
227 cursor_x
+= mouse_accel
;
231 cursor_y
-= mouse_accel
;
235 cursor_y
+= mouse_accel
;
238 cursor_state
= XCURSOR_STATE_RBUTTON
;
241 cursor_state
= XCURSOR_STATE_LBUTTON
;
250 int xcursor_update ()
252 switch (mouse_type
) {
254 /* TODO: autodetect */
255 xcursor_kbmouse_handler ();
258 /* serial mouse over rs232 */
259 xcursor_serialmouse_handler ();
263 xcursor_ps2mouse_handler ();
270 if (cursor_y
> (signed) (vgafb_res_y
-1))
271 cursor_y
= (vgafb_res_y
-1);
276 if (cursor_x
> (signed) (vgafb_res_x
-1))
277 cursor_x
= (vgafb_res_x
-1);
282 void xcursor_getpos (int *x
, int *y
)
288 unsigned xcursor_settype (unsigned char type
)
290 if (mouse_type
== type
)