Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / libx / cursor / xcursor.c
bloba7ae5e8d5433fa6be224f1ecc8fc065289d3764d
1 /*
2 * ZeX/OS
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/>.
21 #include <stdio.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <libx/base.h>
26 #include <libx/cursor.h>
28 /* kb mouse */
29 #define ARROWLEFT 75
30 #define ARROWRIGHT 77
31 #define ARROWUP 72
32 #define ARROWDOWN 80
33 #define ENTER 28
34 #define DEL 14
36 static unsigned mouse_accel = 0;
38 /* ps2 mouse */
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 */
47 static int ps2_fd;
49 /* serial mouse */
50 static const int kBaudRate = 1200;
51 static const int kPortBase = 0x3f8;
53 static int cursor_x;
54 static int cursor_y;
55 static int cursor_state;
57 static char mouse_type = -1;
59 static char rs232_read_block ()
61 asm volatile (
62 "movl $37, %%eax;"
63 "int $0x80;"
64 ::: "%eax");
66 char *memptr = (char *) 0x9000;
67 char *ret = memptr;
69 return *ret;
72 static unsigned char inportb (unsigned p)
74 unsigned char *ptr = (unsigned char *) p;
76 return *ptr;
79 static void outportb (unsigned char val, unsigned p)
81 unsigned char *ptr = (unsigned char *) p;
83 *ptr = val;
86 int serial_recieved()
88 return inportb (kPortBase + 5) & 1;
91 static char rs232_read_nonblock ()
93 int r = serial_recieved();
95 if (r == 0)
96 return 0;
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
115 cursor_x = 0;
116 cursor_y = 0;
118 char protocol = rs232_read_block ();
120 if (protocol == 'M')
121 return 1;
123 return 0;
126 static unsigned xcursor_ps2mouse_init ()
128 ps2_fd = open ("/dev/mouseps2", O_RDONLY);
130 if (ps2_fd < 1)
131 return 0;
133 return 1;
136 unsigned xcursor_init ()
138 /* initial cursor position */
139 cursor_x = 0;
140 cursor_y = 0;
142 /* automatic mouse type selection */
143 if (mouse_type != -1)
144 goto manual;
146 if (xcursor_ps2mouse_init ())
147 mouse_type = 0x2;
148 else if (xcursor_serialmouse_init ())
149 mouse_type = 0x1;
150 else
151 mouse_type = 0x0;
153 return 1;
154 manual:
155 switch (mouse_type) {
156 case 0x0:
157 mouse_accel = 1;
158 return 1;
159 case 0x1:
160 /* serial mouse over rs232 */
161 return xcursor_serialmouse_init ();
162 case 0x2:
163 /* ps/2 mouse */
164 return xcursor_ps2mouse_init ();
167 return 0;
170 static void xcursor_ps2mouse_handler ()
172 /* low-level mouse structure */
173 typedef struct {
174 unsigned short flags;
175 short pos_x; /* Difference - horizontal position */
176 short pos_y; /* Difference - vertical position */
177 } dev_mouse_t;
179 dev_mouse_t mouse;
181 int r = read (ps2_fd, &mouse, sizeof (dev_mouse_t));
183 if (!r)
184 return;
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;
195 else
196 cursor_state = 0x0;
199 static void xcursor_serialmouse_handler ()
201 char b1 = rs232_read_nonblock ();
203 if ((b1 & (1 << 6)) == 0)
204 return;
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 ();
220 switch (scancode) {
221 case ARROWLEFT:
222 mouse_accel ++;
223 cursor_x -= mouse_accel;
224 return;
225 case ARROWRIGHT:
226 mouse_accel ++;
227 cursor_x += mouse_accel;
228 return;
229 case ARROWUP:
230 mouse_accel ++;
231 cursor_y -= mouse_accel;
232 return;
233 case ARROWDOWN:
234 mouse_accel ++;
235 cursor_y += mouse_accel;
236 return;
237 case DEL:
238 cursor_state = XCURSOR_STATE_RBUTTON;
239 return;
240 case ENTER:
241 cursor_state = XCURSOR_STATE_LBUTTON;
242 return;
245 mouse_accel = 4;
247 cursor_state = 0x0;
250 int xcursor_update ()
252 switch (mouse_type) {
253 case 0x0:
254 /* TODO: autodetect */
255 xcursor_kbmouse_handler ();
256 break;
257 case 0x1:
258 /* serial mouse over rs232 */
259 xcursor_serialmouse_handler ();
260 break;
261 case 0x2:
262 /* ps/2 mouse */
263 xcursor_ps2mouse_handler ();
264 break;
267 if (cursor_y < 0)
268 cursor_y = 0;
270 if (cursor_y > (signed) (vgafb_res_y-1))
271 cursor_y = (vgafb_res_y-1);
273 if (cursor_x < 0)
274 cursor_x = 0;
276 if (cursor_x > (signed) (vgafb_res_x-1))
277 cursor_x = (vgafb_res_x-1);
279 return cursor_state;
282 void xcursor_getpos (int *x, int *y)
284 *x = cursor_x;
285 *y = cursor_y;
288 unsigned xcursor_settype (unsigned char type)
290 if (mouse_type == type)
291 return 0;
293 mouse_type = type;
295 return 1;