#ifndef EL__TERMINAL_MOUSE_H #define EL__TERMINAL_MOUSE_H #ifdef __cplusplus extern "C" { #endif struct interlink_event; struct itrm; struct session; extern int mouse_enabled; /* The mouse reporting button byte looks like: * * -ss??bbb * || ||| * || +++---> buttons: * || 0 left * || 1 middle * || 2 right * || 3 release OR wheel up [rxvt] * || 4 wheel down [rxvt] * || * ++--------> style: * 1 normalclick (makes sure the whole thing is >= ' ') * 2 doubleclick * 3 mouse wheel move [xterm] * then in bb is 0 for up and 1 for down * * What we translate it to: * -da??bbb * || ||| * || +++---> buttons: * || 0 left * || 1 middle * || 2 right * || 3 wheel up * || 4 wheel down * || * |+--------> action: * | 0 press (B_DOWN) * | 1 release (B_UP) * | * +---------> drag flag (valid only for B_UP) * * (TODO: doubleclick facility? --pasky) * * Let me introduce to the wonderful world of X terminals and their handling of * mouse wheel now. First, one sad fact: reasonable mouse wheel reporting * support has only xterm itself (from everything I tried) - it is relatively * elegant, it shouldn't confuse existing applications too much and it is * generally non-conflicting with the old behaviour. * * All other terminals are doing absolutely terrible things, making it hell on * the hearth to support mouse wheels. rxvt will send the buttons as succeeding * button numbers (3, 4) in normal sequences, but that has a little problem - * button 3 is also alias for button release; welcome to the wonderful world of * X11. But at least, rxvt will send only "press" sequence, but no release * sequence (it really doesn't make sense for wheels anyway, does it?). That * has the advantage that you can do some heuristic (see below) to at least * partially pace with this terrible thing. * * But now, let's see another nice pair of wonderful terminals: aterm and * Eterm. They emit same braindead sequence for wheel up/down as rxvt, but * that's not all. Yes, you guessed it - they send even the release sequence * (immediatelly after press sequence) for the wheels. So, you will see * something like: * * old glasses - * new glasses - * smartglasses1- * smartglasses2- * * But with smartglasses2, you will have a problem with rxvt when someone will * move the wheel multiple times - only half of the times it will be recorded. * Poof. No luck :-(. * * [smartglasses1]: * When user presses some button and then moves the wheel, action for button * release will be done and when he will release the button, action for the * wheel will be done. That's unfortunately inevitable in order to work under * rxvt :-(. */ struct term_event_mouse { int x, y; unsigned int button; }; #define interlink_event_mouse term_event_mouse #define BM_BUTT 7 #define B_LEFT 0 #define B_MIDDLE 1 #define B_RIGHT 2 #define B_WHEEL_UP 3 #define B_WHEEL_DOWN 4 #define BM_ACT 48 #define B_DOWN 0 #define B_UP 16 #define B_DRAG 32 #define B_MOVE 48 #define BM_DRAG 64 #define mouse_get_action(mouse_) ((mouse_)->button & BM_ACT) #define mouse_action_is(mouse_, value) (mouse_get_action(mouse_) == (value)) #define mouse_get_button(mouse_) ((mouse_)->button & BM_BUTT) #define mouse_button_is(mouse_, value) (mouse_get_button(mouse_) == (value)) #define mouse_wheeling(mouse_) (mouse_get_button(mouse_) >= B_WHEEL_UP) #define mouse_is_in_box(mouse_, box) \ is_in_box(box, (mouse_)->x, (mouse_)->y) #define set_mouse(mouse_, x_, y_, button_) do { \ (mouse_)->x = (x_); \ (mouse_)->y = (y_); \ (mouse_)->button = (button_); \ } while (0) void send_mouse_init_sequence(int h); void send_mouse_done_sequence(int h); void disable_mouse(void); void enable_mouse(void); void toggle_mouse(struct session *ses); int decode_terminal_mouse_escape_sequence(struct itrm *itrm, struct interlink_event *ev, int el, int v); int decode_terminal_mouse_escape_sequence_256(struct itrm *itrm, struct interlink_event *ev, int el, int v); #ifdef __cplusplus } #endif #endif