Support scrollwheel mice

This commit is contained in:
Kevin Lange 2015-04-26 18:05:14 -07:00
parent c360ca695a
commit 4fd1ae9aa3
5 changed files with 92 additions and 29 deletions

View File

@ -4,7 +4,10 @@
typedef enum {
LEFT_CLICK = 0x01,
RIGHT_CLICK = 0x02,
MIDDLE_CLICK = 0x04
MIDDLE_CLICK = 0x04,
MOUSE_SCROLL_UP = 0x10,
MOUSE_SCROLL_DOWN = 0x20,
} mouse_click_t;
typedef struct {

View File

@ -13,7 +13,7 @@
#include <mouse.h>
static uint8_t mouse_cycle = 0;
static int8_t mouse_byte[3];
static int8_t mouse_byte[4];
#define PACKETS_IN_PIPE 1024
#define DISCARD_POINT 32
@ -28,6 +28,12 @@ static int8_t mouse_byte[3];
#define MOUSE_F_BIT 0x20
#define MOUSE_V_BIT 0x08
#define MOUSE_DEFAULT 0
#define MOUSE_SCROLLWHEEL 1
#define MOUSE_BUTTONS 2
static int8_t mouse_mode = MOUSE_DEFAULT;
static fs_node_t * mouse_pipe;
static void mouse_wait(uint8_t a_type) {
@ -81,34 +87,51 @@ static void mouse_handler(struct regs *r) {
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! */
if (mouse_mode == MOUSE_SCROLLWHEEL || mouse_mode == MOUSE_BUTTONS) {
++mouse_cycle;
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) > (int)(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;
goto finish_packet;
case 3:
mouse_byte[3] = mouse_in;
goto finish_packet;
}
continue;
finish_packet:
mouse_cycle = 0;
/* We now have a full mouse packet ready to use */
if (mouse_byte[0] & 0x80 || mouse_byte[0] & 0x40) {
/* x/y overflow? bad packet! */
continue;
}
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;
}
if (mouse_mode == MOUSE_SCROLLWHEEL && mouse_byte[3]) {
if (mouse_byte[3] > 0) {
packet.buttons |= MOUSE_SCROLL_DOWN;
} else if (mouse_byte[3] < 0) {
packet.buttons |= MOUSE_SCROLL_UP;
}
}
mouse_device_packet_t bitbucket;
while (pipe_size(mouse_pipe) > (int)(DISCARD_POINT * sizeof(packet))) {
read_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&bitbucket);
}
write_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&packet);
}
status = inportb(MOUSE_STATUS);
}
@ -125,7 +148,7 @@ static int ioctl_mouse(fs_node_t * node, int request, void * argp) {
static int mouse_install(void) {
debug_print(NOTICE, "Initializing PS/2 mouse interface");
uint8_t status;
uint8_t status, result;
IRQ_OFF;
mouse_pipe = make_pipe(sizeof(mouse_device_packet_t) * PACKETS_IN_PIPE);
mouse_wait(1);
@ -142,6 +165,30 @@ static int mouse_install(void) {
mouse_read();
mouse_write(0xF4);
mouse_read();
mouse_write(0xF2);
mouse_read();
result = mouse_read();
/* Try to enable scroll wheel (but not buttons) */
mouse_write(0xF3);
mouse_read();
mouse_write(200);
mouse_read();
mouse_write(0xF3);
mouse_read();
mouse_write(100);
mouse_read();
mouse_write(0xF3);
mouse_read();
mouse_write(80);
mouse_read();
mouse_write(0xF2);
mouse_read();
result = mouse_read();
if (result == 3) {
mouse_mode = MOUSE_SCROLLWHEEL;
}
IRQ_RES;
irq_install_handler(MOUSE_IRQ, mouse_handler);

View File

@ -51,11 +51,13 @@ char * modifiers(unsigned int m) {
}
char * mouse_buttons(unsigned char button) {
static char out[] = "...";
static char out[] = "....";
if (button & YUTANI_MOUSE_BUTTON_LEFT) out[0] = 'l'; else out[0] = '.';
if (button & YUTANI_MOUSE_BUTTON_MIDDLE) out[1] = 'm'; else out[1] = '.';
if (button & YUTANI_MOUSE_BUTTON_RIGHT) out[2] = 'r'; else out[2] = '.';
if (button & YUTANI_MOUSE_SCROLL_UP) out[3] = 'u'; else \
if (button & YUTANI_MOUSE_SCROLL_DOWN) out[3] = 'd'; else out[3] = '.';
return out;
}

View File

@ -1030,7 +1030,10 @@ void reinit(int send_sig) {
memset(term_buffer, 0x0, sizeof(term_cell_t) * term_width * term_height);
}
int old_mouse_state = 0;
if (ansi_state) old_mouse_state = ansi_state->mouse_on;
ansi_state = ansi_init(ansi_state, term_width, term_height, &term_callbacks);
ansi_state->mouse_on = old_mouse_state;
draw_fill(ctx, rgba(0,0,0, TERM_DEFAULT_OPAC));
render_decors();
@ -1153,6 +1156,12 @@ void * handle_incoming(void * garbage) {
new_x /= char_width;
new_y /= char_height;
if (me->buttons & YUTANI_MOUSE_SCROLL_UP) {
mouse_event(32+32, new_x, new_y);
} else if (me->buttons & YUTANI_MOUSE_SCROLL_DOWN) {
mouse_event(32+32+1, new_x, new_y);
}
if (me->buttons != button_state) {
/* Figure out what changed */
if (me->buttons & YUTANI_MOUSE_BUTTON_LEFT && !(button_state & YUTANI_MOUSE_BUTTON_LEFT)) mouse_event(0, new_x, new_y);

View File

@ -230,6 +230,8 @@ typedef struct yutani_window {
#define YUTANI_MOUSE_BUTTON_LEFT 0x01
#define YUTANI_MOUSE_BUTTON_RIGHT 0x02
#define YUTANI_MOUSE_BUTTON_MIDDLE 0x04
#define YUTANI_MOUSE_SCROLL_UP 0x10
#define YUTANI_MOUSE_SCROLL_DOWN 0x20
/*
* YUTANI_MOUSE_STATE