Mouse improvements (stability, scaling)
This commit is contained in:
parent
1110a119c5
commit
6590b285b5
@ -95,17 +95,22 @@ irq_install() {
|
||||
bfinish(0);
|
||||
}
|
||||
|
||||
void irq_ack(int irq_no) {
|
||||
if (irq_no >= 12) {
|
||||
outportb(0xA0, 0x20);
|
||||
}
|
||||
outportb(0x20, 0x20);
|
||||
}
|
||||
|
||||
void
|
||||
irq_handler(struct regs *r) {
|
||||
IRQ_OFF;
|
||||
void (*handler)(struct regs *r);
|
||||
handler = irq_routines[r->int_no - 32];
|
||||
if (r->int_no >= 40) {
|
||||
outportb(0xA0, 0x20);
|
||||
}
|
||||
outportb(0x20, 0x20);
|
||||
if (handler) {
|
||||
handler(r);
|
||||
} else {
|
||||
irq_ack(r->int_no - 32);
|
||||
}
|
||||
IRQ_RES;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define KEY_PENDING 0x64
|
||||
|
||||
#define KEYBOARD_NOTICES 0
|
||||
#define KEYBOARD_IRQ 1
|
||||
|
||||
/* A bit-map to store the keyboard states */
|
||||
struct keyboard_states {
|
||||
@ -246,6 +247,7 @@ keyboard_handler(
|
||||
unsigned char scancode;
|
||||
keyboard_wait();
|
||||
scancode = inportb(KEY_DEVICE);
|
||||
irq_ack(KEYBOARD_IRQ);
|
||||
if (keyboard_direct_handler) {
|
||||
keyboard_direct_handler(scancode);
|
||||
return;
|
||||
@ -256,6 +258,7 @@ keyboard_handler(
|
||||
if (handler) {
|
||||
handler(scancode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -276,7 +279,7 @@ keyboard_install() {
|
||||
current_process->fds.entries[0] = keyboard_pipe;
|
||||
|
||||
/* Install the interrupt handler */
|
||||
irq_install_handler(1, keyboard_handler);
|
||||
irq_install_handler(KEYBOARD_IRQ, keyboard_handler);
|
||||
|
||||
bfinish(0);
|
||||
}
|
||||
|
@ -12,93 +12,121 @@ int8_t mouse_byte[3];
|
||||
#define PACKETS_IN_PIPE 64
|
||||
#define DISCARD_POINT 32
|
||||
|
||||
#define MOUSE_IRQ 12
|
||||
|
||||
#define MOUSE_PORT 0x60
|
||||
#define MOUSE_STATUS 0x64
|
||||
#define MOUSE_ABIT 0x02
|
||||
#define MOUSE_BBIT 0x01
|
||||
#define MOUSE_WRITE 0xD4
|
||||
#define MOUSE_F_BIT 0x20
|
||||
|
||||
fs_node_t * mouse_pipe;
|
||||
|
||||
void mouse_handler(struct regs *r) {
|
||||
switch (mouse_cycle) {
|
||||
case 0:
|
||||
mouse_byte[0] = inportb(0x60);
|
||||
++mouse_cycle;
|
||||
break;
|
||||
case 1:
|
||||
mouse_byte[1] = inportb(0x60);
|
||||
++mouse_cycle;
|
||||
break;
|
||||
case 2:
|
||||
mouse_byte[2] = inportb(0x60);
|
||||
mouse_device_packet_t packet;
|
||||
packet.magic = MOUSE_MAGIC;
|
||||
packet.x_difference = mouse_byte[1];
|
||||
packet.y_difference = mouse_byte[2];
|
||||
packet.buttons = 0;
|
||||
if (mouse_byte[0] & 0x01) {
|
||||
packet.buttons |= LEFT_CLICK;
|
||||
}
|
||||
if (mouse_byte[0] & 0x02) {
|
||||
packet.buttons |= RIGHT_CLICK;
|
||||
}
|
||||
mouse_cycle = 0;
|
||||
|
||||
mouse_device_packet_t bitbucket;
|
||||
while (pipe_size(mouse_pipe) > (DISCARD_POINT * sizeof(packet))) {
|
||||
read_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&bitbucket);
|
||||
}
|
||||
write_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&packet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mouse_wait(uint8_t a_type) {
|
||||
uint32_t timeout = 100000;
|
||||
if (!a_type) {
|
||||
while (--timeout) {
|
||||
if ((inportb(0x64) & 0x01) == 1) {
|
||||
if ((inportb(MOUSE_STATUS) & MOUSE_BBIT) == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
kprintf("[mouse] timeout\n");
|
||||
return;
|
||||
} else {
|
||||
while (--timeout) {
|
||||
if (!((inportb(0x64) & 0x02))) {
|
||||
if (!((inportb(MOUSE_STATUS) & MOUSE_ABIT))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
kprintf("[mouse] timeout\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void mouse_write(uint8_t write) {
|
||||
mouse_wait(1);
|
||||
outportb(0x64, 0xD4);
|
||||
outportb(MOUSE_STATUS, MOUSE_WRITE);
|
||||
mouse_wait(1);
|
||||
outportb(0x60, write);
|
||||
outportb(MOUSE_PORT, write);
|
||||
}
|
||||
|
||||
uint8_t mouse_read() {
|
||||
mouse_wait(0);
|
||||
char t = inportb(0x60);
|
||||
char t = inportb(MOUSE_PORT);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
void mouse_handler(struct regs *r) {
|
||||
uint8_t status = inportb(MOUSE_STATUS);
|
||||
while (status & MOUSE_BBIT) {
|
||||
int8_t mouse_in = inportb(MOUSE_PORT);
|
||||
if (status & MOUSE_F_BIT) {
|
||||
switch (mouse_cycle) {
|
||||
case 0:
|
||||
mouse_byte[0] = mouse_in;
|
||||
++mouse_cycle;
|
||||
break;
|
||||
case 1:
|
||||
mouse_byte[1] = mouse_in;
|
||||
++mouse_cycle;
|
||||
break;
|
||||
case 2:
|
||||
mouse_byte[2] = mouse_in;
|
||||
/* We now have a full mouse packet ready to use */
|
||||
if (mouse_byte[0] & 0x80 || mouse_byte[0] & 0x40) {
|
||||
/* x/y overflow? bad packet! */
|
||||
break;
|
||||
}
|
||||
mouse_device_packet_t packet;
|
||||
packet.magic = MOUSE_MAGIC;
|
||||
packet.x_difference = mouse_byte[1];
|
||||
packet.y_difference = mouse_byte[2];
|
||||
packet.buttons = 0;
|
||||
if (mouse_byte[0] & 0x01) {
|
||||
packet.buttons |= LEFT_CLICK;
|
||||
}
|
||||
if (mouse_byte[0] & 0x02) {
|
||||
packet.buttons |= RIGHT_CLICK;
|
||||
}
|
||||
if (mouse_byte[0] & 0x04) {
|
||||
packet.buttons |= MIDDLE_CLICK;
|
||||
}
|
||||
mouse_cycle = 0;
|
||||
|
||||
mouse_device_packet_t bitbucket;
|
||||
while (pipe_size(mouse_pipe) > (DISCARD_POINT * sizeof(packet))) {
|
||||
read_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&bitbucket);
|
||||
}
|
||||
write_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&packet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
status = inportb(MOUSE_STATUS);
|
||||
}
|
||||
irq_ack(MOUSE_IRQ);
|
||||
}
|
||||
|
||||
void mouse_install() {
|
||||
LOG(INFO, "Initializing mouse cursor driver");
|
||||
uint8_t status;
|
||||
IRQ_OFF;
|
||||
mouse_pipe = make_pipe(sizeof(mouse_device_packet_t) * PACKETS_IN_PIPE);
|
||||
mouse_wait(1);
|
||||
outportb(0x64,0xA8);
|
||||
outportb(MOUSE_STATUS, 0xA8);
|
||||
mouse_wait(1);
|
||||
outportb(0x64,0x20);
|
||||
outportb(MOUSE_STATUS, 0x20);
|
||||
mouse_wait(0);
|
||||
status = inportb(0x60) | 2;
|
||||
mouse_wait(1);
|
||||
outportb(0x64, 0x60);
|
||||
outportb(MOUSE_STATUS, 0x60);
|
||||
mouse_wait(1);
|
||||
outportb(0x60, status);
|
||||
outportb(MOUSE_PORT, status);
|
||||
mouse_write(0xF6);
|
||||
mouse_read();
|
||||
mouse_write(0xF4);
|
||||
mouse_read();
|
||||
IRQ_RES;
|
||||
irq_install_handler(12, mouse_handler);
|
||||
irq_install_handler(MOUSE_IRQ, mouse_handler);
|
||||
}
|
||||
|
@ -10,11 +10,14 @@
|
||||
#define SERIAL_PORT_C 0x3E8
|
||||
#define SERIAL_PORT_D 0x2E8
|
||||
|
||||
#define SERIAL_IRQ 4
|
||||
|
||||
void
|
||||
serial_handler(
|
||||
struct regs *r
|
||||
) {
|
||||
char serial = serial_recv();
|
||||
irq_ack(SERIAL_IRQ);
|
||||
/*
|
||||
* Fix the serial input assuming it is ascii
|
||||
*/
|
||||
@ -45,7 +48,7 @@ serial_install() {
|
||||
outportb(SERIAL_PORT_A + 3, 0x03);
|
||||
outportb(SERIAL_PORT_A + 2, 0xC7);
|
||||
outportb(SERIAL_PORT_A + 4, 0x0B);
|
||||
irq_install_handler(4, serial_handler); /* Install the serial input handler */
|
||||
irq_install_handler(SERIAL_IRQ, serial_handler); /* Install the serial input handler */
|
||||
outportb(SERIAL_PORT_A + 1, 0x01); /* Enable interrupts on receive */
|
||||
bfinish(0);
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
#define PIT_SCALE 1193180
|
||||
#define PIT_SET 0x36
|
||||
|
||||
#define TIMER_IRQ 0
|
||||
|
||||
/*
|
||||
* Set the phase (in hertz) for the Programmable
|
||||
* Interrupt Timer (PIT).
|
||||
@ -42,6 +44,7 @@ timer_handler(
|
||||
struct regs *r
|
||||
) {
|
||||
++timer_ticks;
|
||||
irq_ack(TIMER_IRQ);
|
||||
switch_task(1);
|
||||
}
|
||||
|
||||
@ -51,7 +54,7 @@ timer_handler(
|
||||
void timer_install() {
|
||||
blog("Installing Programmable Interval Timer...");
|
||||
LOG(INFO,"Initializing interval timer");
|
||||
irq_install_handler(0, timer_handler);
|
||||
irq_install_handler(TIMER_IRQ, timer_handler);
|
||||
timer_phase(100); /* 100Hz */
|
||||
bfinish(0);
|
||||
}
|
||||
|
@ -124,6 +124,7 @@ extern void irq_install();
|
||||
extern void irq_install_handler(int irq, irq_handler_t);
|
||||
extern void irq_uninstall_handler(int irq);
|
||||
extern void irq_gates();
|
||||
extern void irq_ack();
|
||||
|
||||
/* Timer */
|
||||
extern void timer_install();
|
||||
|
@ -37,7 +37,7 @@ void start_terminal() {
|
||||
if (!pid) {
|
||||
#endif
|
||||
char * tokens[] = {
|
||||
"/bin/compositor",
|
||||
"/bin/terminal",
|
||||
NULL
|
||||
};
|
||||
int i = execve(tokens[0], tokens, NULL);
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#define FONT_SIZE 13
|
||||
|
||||
#define MOUSE_SCALE 6
|
||||
|
||||
static unsigned int timer_tick = 0;
|
||||
#define TIMER_TICK 400000
|
||||
|
||||
@ -2995,14 +2997,26 @@ int main(int argc, char ** argv) {
|
||||
int r = read(mfd, buf, 1);
|
||||
goto fail_mouse;
|
||||
}
|
||||
cell_redraw((mouse_x * term_width) / graphics_width, (mouse_y * term_height) / graphics_height);
|
||||
mouse_x += packet->x_difference;
|
||||
mouse_y -= packet->y_difference;
|
||||
cell_redraw(((mouse_x / MOUSE_SCALE) * term_width) / graphics_width, ((mouse_y / MOUSE_SCALE) * term_height) / graphics_height);
|
||||
/* Apply mouse movement */
|
||||
int c, l;
|
||||
c = abs(packet->x_difference);
|
||||
l = 0;
|
||||
while (c >>= 1) {
|
||||
l++;
|
||||
}
|
||||
mouse_x += packet->x_difference * l;
|
||||
c = abs(packet->y_difference);
|
||||
l = 0;
|
||||
while (c >>= 1) {
|
||||
l++;
|
||||
}
|
||||
mouse_y -= packet->y_difference * l;
|
||||
if (mouse_x < 0) mouse_x = 0;
|
||||
if (mouse_y < 0) mouse_y = 0;
|
||||
if (mouse_x >= graphics_width) mouse_x = graphics_width - char_width;
|
||||
if (mouse_y >= graphics_height) mouse_y = graphics_height - char_height;
|
||||
cell_redraw_inverted((mouse_x * term_width) / graphics_width, (mouse_y * term_height) / graphics_height);
|
||||
if (mouse_x >= graphics_width * MOUSE_SCALE) mouse_x = (graphics_width - char_width) * MOUSE_SCALE;
|
||||
if (mouse_y >= graphics_height * MOUSE_SCALE) mouse_y = (graphics_height - char_height) * MOUSE_SCALE;
|
||||
cell_redraw_inverted(((mouse_x / MOUSE_SCALE) * term_width) / graphics_width, ((mouse_y / MOUSE_SCALE) * term_height) / graphics_height);
|
||||
fstat(mfd, &_stat);
|
||||
}
|
||||
fail_mouse:
|
||||
|
Loading…
x
Reference in New Issue
Block a user