Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:tiwai:grub-mouse
grub2
0004-Refractoring-ps2mouse.c-to-enable-keyboard...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0004-Refractoring-ps2mouse.c-to-enable-keyboard-to-plug-i.patch of Package grub2
From d273962f799b81570f59365e7cfeb32b96ee97ff Mon Sep 17 00:00:00 2001 From: Patrick Plenefisch <simonpatp@gmail.com> Date: Sat, 28 Jul 2012 00:58:19 -0400 Subject: [PATCH 04/13] Refractoring ps2mouse.c to enable keyboard to plug in --- grub-core/term/ps2mouse.c | 243 ++++++++++++++++++++++++++++------------------ include/grub/ps2mouse.h | 8 ++ 2 files changed, 154 insertions(+), 97 deletions(-) diff --git a/grub-core/term/ps2mouse.c b/grub-core/term/ps2mouse.c index d0b5bbfa01d9..aa01d2b02207 100644 --- a/grub-core/term/ps2mouse.c +++ b/grub-core/term/ps2mouse.c @@ -32,18 +32,24 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_uint8_t mouse_cycle=0; //unsigned char +struct MouseState +{ + grub_uint8 left : 1, middle : 1, right : 1, locked : 1; +}; + static grub_int8_t mouse_byte[3]; //signed char -static grub_int32_t mouse_x=0; //signed char -static grub_int8_t mouse_y=0; //signed char -static grub_int8_t mouse_rise=1; //signed char -static grub_int8_t mouse_clicklocked=1; //signed char +static grub_int32_t mouse_y = 0; +static struct MouseState mouse_state = 0; +mouse_state.locked=1; //signed char static grub_uint8_t mouse_mode = MMODE_DEFAULT; static grub_int32_t mouse_movehunk = 20; +#define MOUSE_ISBUTTON_DOWN(btn) ((mouse_byte[0] & (btn)) != 0) +#define MOUSE_GET_X() (mouse_byte[1]) +#define MOUSE_GET_Y() (mouse_byte[2]) -//EVIL hack. +//TODO: EVIL hack. remove when done extern grub_err_t grub_cmd_terminal_input (grub_command_t cmd, int argc, char **args); @@ -52,10 +58,11 @@ grub_cmd_terminal_input (grub_command_t cmd, static inline void mouse_data_wait(void) { - grub_uint32_t _time_out=100000; //unsigned int - while(_time_out--) //Data + grub_uint32_t time_out = 100000; + while(time_out--) { - if((grub_inb(0x64) & 1)==1) + //check if the data flag is present + if(PS2_HAS_DATA(grub_inb(0x64))) { return; } @@ -65,10 +72,11 @@ mouse_data_wait(void) static inline void mouse_command_wait(void) { - grub_uint32_t _time_out=100000; //unsigned int - while(_time_out--) //Signal + grub_uint32_t time_out = 100000; + while(time_out--) { - if((grub_inb(0x64) & 2)==0) + //check if the buffer full flag is not present + if(PS2_COMMAND_ISREADY(grub_inb(0x64))) { return; } @@ -96,31 +104,89 @@ mouse_read(void) return grub_inb(0x60); } - -///////////////////////////////////////////////////////////////////////// - - - //Mouse functions static void mouse_handler(void) { - mouse_byte[0]=grub_inb(0x60); - - grub_dprintf("psmour", "mouseCycle(0) = %d(%d%d%d%d %d%d%d%d)\n", mouse_byte[0], BSPLIT(mouse_byte[0])); + //Read the 3 bytes from the mouse + mouse_byte[0] = mouse_read(); + mouse_byte[1] = mouse_read(); + mouse_byte[2] = mouse_read(); + + //update change + mouse_y = mouse_byte[2]; + mouse_x += mouse_y; + + grub_dprintf("psmous", "mouseCycle\n(0) = %d(%d%d%d%d %d%d%d%d)\n(1) = %d(%d%d%d%d %d%d%d%d)\n(2) = %d(%d%d%d%d %d%d%d%d)\n", mouse_byte[0], BSPLIT(mouse_byte[0]), mouse_byte[1], BSPLIT(mouse_byte[1]), mouse_byte[2], BSPLIT(mouse_byte[2])); +} -mouse_data_wait(); +static int +mouse_finish_scrolling(void) +{ + if (mouse_x > mouse_movehunk) + { + grub_dprintf("psmous", "Sending Up using %d\n", mouse_x); + mouse_x -= mouse_movehunk; + return GRUB_KEYBOARD_KEY_UP; + } + else if (mouse_x < -mouse_movehunk) + { + grub_dprintf("psmous", "Sending Down using %d\n", mouse_x); + mouse_x += mouse_movehunk; + return GRUB_KEYBOARD_KEY_DOWN + } + return GRUB_TERM_NO_KEY; +} - mouse_byte[1]=grub_inb(0x60); - grub_dprintf("psmour", "mouseCycle(1) = %d(%d%d%d%d %d%d%d%d)\n", mouse_byte[1], BSPLIT(mouse_byte[1])); - -mouse_data_wait(); +static int +keyboard_decode(void) +{ + code = grub_inb(0x60); + if (code == 0x9C) //enter key up + return GRUB_KEYBOARD_KEY_ENTER; + return GRUB_TERM_NO_KEY; +} + +static int +mouse_left_click() +{ + grub_dprintf("psmous", "Left click => ENTER using %d, locked: %d\n", mouse_byte[0], mouse_state.locked); + if (!mouse_state.locked) + { + mouse_y = 0; + return GRUB_KEYBOARD_KEY_ENTER; + } + return GRUB_TERM_NO_KEY; +} +static int +mouse_right_click() +{ + grub_dprintf("psmous", "Right click => E using %d, locked: %d\n", mouse_byte[0], mouse_state.locked); + if (!mouse_state.locked) + { + mouse_y = 0; + return GRUB_KEYBOARD_KEY_E; + } + return GRUB_TERM_NO_KEY; +} +static int +mouse_middle_click() +{ + grub_dprintf("psmous", "Middle click => C using %d, locked: %d\n", mouse_byte[0], mouse_state.locked); + if (!mouse_state.locked) + { + mouse_y = 0; + return GRUB_KEYBOARD_KEY_C; + } + return GRUB_TERM_NO_KEY; +} - mouse_byte[2]=grub_inb(0x60); - grub_dprintf("psmour", "mouseCycle(2) = %d(%d%d%d%d %d%d%d%d)\n", mouse_byte[2], BSPLIT(mouse_byte[2])); - mouse_y = mouse_byte[2]; - mouse_x += mouse_y; - mouse_cycle=0; +inline static int +ps2_keymap(int grubcode) +{ + if (grubcode == GRUB_TERM_NO_KEY) + return grubcode; + return grub_term_map_key (grubcode, 0); } /* If there is a character pending, return it; @@ -128,83 +194,66 @@ mouse_data_wait(); static int grub_ps2_getkey (struct grub_term_input *term __attribute__ ((unused))) { - grub_uint8_t code; -begin: - code = grub_inb(0x64); - if((code & 1) != 1) + grub_uint8_t code = grub_inb(0x64); + + //check if the queue is empty + if (PS2_HAS_DATA(code)) { - if (mouse_x > mouse_movehunk) - { - //grub_dprintf("psmous", "Sending Down using %d\n", mouse_x); - mouse_x -= mouse_movehunk; - //return GRUB_TERM_NO_KEY; - return grub_term_map_key (GRUB_KEYBOARD_KEY_UP, 0); - } - else if (mouse_x < -mouse_movehunk) - { - //grub_dprintf("psmous", "Sending Up using %d\n", mouse_x); - mouse_x += mouse_movehunk; - //return GRUB_TERM_NO_KEY; - return grub_term_map_key (GRUB_KEYBOARD_KEY_DOWN, 0); - } - return GRUB_TERM_NO_KEY; + //no keystrokes/movements. Continue any ongoing scrolling + return ps2_keymap (mouse_finish_scrolling()); } - grub_dprintf("psmour", "GetKey() 0x64 = %d(%d%d%d%d %d%d%d%d)\n", code, BSPLIT(code)); - if((code & 0x20) != 0x20) + else if (PS2_ISKEYBOARD_EVENT(code)) //check if this is a non-mouse event { - code = grub_inb(0x60); grub_dprintf("psmous", "GetKey(NON-Mouse) = %d(%d%d%d%d %d%d%d%d)\n", code, BSPLIT(code)); - if (code == 0x9C) //enter key up - { - return grub_term_map_key (GRUB_KEYBOARD_KEY_ENTER, 0); - } - goto begin; + //must be keyboard event; call keyboard handler + return keyboard_decode(); } - mouse_handler(); - if (mouse_cycle != 0) - goto begin; - if ((mouse_byte[0] & 1) == 0) - mouse_rise = 0; - if ((mouse_byte[0] & 0x02) == 0x02) - mouse_clicklocked = 0; - - //grub_dprintf("psmous", " mb's using %d, %d, %d\n", mouse_byte[0], mouse_byte[1], mouse_byte[2]); - if (!mouse_clicklocked && (mouse_byte[0] & 1) == 1 && mouse_byte[0] != -1 && (mouse_rise) == 0) - { - mouse_rise = 1; - grub_dprintf("psmous", "Sending ENTER using %d\n", mouse_byte[0]); - mouse_x = 0; - //return GRUB_TERM_NO_KEY; - return grub_term_map_key (GRUB_KEYBOARD_KEY_ENTER, 0); - } - if ((mouse_byte[0] & 4) == 4) + else //its a mouse! { - grub_dprintf("psmous", "Sending CKEY using %d\n", mouse_byte[0]); - mouse_x = 0; - //return GRUB_TERM_NO_KEY; - return grub_term_map_key (GRUB_KEYBOARD_KEY_C, 0); - } - else - { - code = grub_inb(0x64); - if((code & 1) == 1 && mouse_mode == MMODE_TOUCH && (code & 0x20) != 0x20) - goto begin; //Gather all touch events - if (mouse_x > mouse_movehunk) + grub_dprintf("psmous", "GetKey(Mouse) = %d(%d%d%d%d %d%d%d%d)\n", code, BSPLIT(code)); +rapidfire: + //Read mouse data + mouse_handler(); + + //check for any clicks + if (MOUSE_BUTTON_DOWN(MOUSE_BUTTON_LEFT) != mouse_state.left) { - //grub_printf("Down %d\n", mouse_x); - mouse_x -= mouse_movehunk; - //return GRUB_TERM_NO_KEY; - return grub_term_map_key (GRUB_KEYBOARD_KEY_UP, 0); + mouse_state.left = MOUSE_BUTTON_DOWN(MOUSE_BUTTON_LEFT); + + //If button not pressed anymore, fire click event + if (!mouse_state.left) + { + return ps2_keymap (mouse_left_click()); + } } - else if (mouse_x < -mouse_movehunk) + if (MOUSE_BUTTON_DOWN(MOUSE_BUTTON_RIGHT) != mouse_state.right) { - //grub_printf( " Up %d\n", mouse_x); - mouse_x += mouse_movehunk; - //return GRUB_TERM_NO_KEY; - return grub_term_map_key (GRUB_KEYBOARD_KEY_DOWN, 0); + mouse_state.right = MOUSE_BUTTON_DOWN(MOUSE_BUTTON_RIGHT); + + //If button not pressed anymore, fire click event + if (!mouse_state.right) + { + return ps2_keymap (mouse_right_click()); + } } - else - goto begin; + if (MOUSE_BUTTON_DOWN(MOUSE_BUTTON_MIDDLE) != mouse_state.middle) + { + mouse_state.middle = MOUSE_BUTTON_DOWN(MOUSE_BUTTON_MIDDLE); + + //If button not pressed anymore, fire click event + if (!mouse_state.middle) + { + return ps2_keymap (mouse_middle_click()); + } + } + + //are we in rapid-fire mode? + code = grub_inb(0x64); + if(PS2_HAS_DATA(code) && mouse_mode == MMODE_TOUCH && PS2_ISMOUSE_EVENT(code)) + goto rapidfire; + + //if not, just scroll + return ps2_keymap (mouse_finish_scrolling()); } } diff --git a/include/grub/ps2mouse.h b/include/grub/ps2mouse.h index d411feec6462..e07bbb21d0b8 100644 --- a/include/grub/ps2mouse.h +++ b/include/grub/ps2mouse.h @@ -37,6 +37,14 @@ #define MMODE_MOUSE 1 #define MMODE_TOUCH 2 +#define PS2_HAS_DATA(x) ((x) & 0x01) +#define PS2_COMMAND_ISREADY(x) !((x) & 0x02) +#define PS2_ISMOUSE_EVENT(x) ((x) & 0x20) +#define PS2_ISKEYBOARD_EVENT(x) !((x) & 0x20) + +#define MOUSE_BUTTON_LEFT 1 +#define MOUSE_BUTTON_RIGHT 2 +#define MOUSE_BUTTON_MIDDLE 4 extern void grub_ps2mouse_init (void); extern void grub_ps2mouse_fini (void); -- 2.4.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor