/* * (C) Copyright 1992, ..., 2014 the "DOSEMU-Development-Team". * * for details see file COPYING in the DOSEMU distribution */ #include #include #include #include #include "emu.h" #include "video.h" #include "env_term.h" #include "mouse.h" #include "utilities.h" #include "vgaemu.h" #include "vc.h" static int use_sgr; /* old XTERM MOUSE suport by M.Laak */ static int xtermmouse_get_event_old(Bit8u *kbp, int kbcount) { int btn; static int last_btn = 0; int x_pos, y_pos; int co, li, li_1; /* Decode Xterm mouse information to a GPM style event */ if (kbcount < 3) return 0; /* Read sizes from BDA because term can be resized. */ co = READ_WORD(BIOS_SCREEN_COLUMNS); li_1 = READ_BYTE(BIOS_ROWS_ON_SCREEN_MINUS_1); li = li_1 + 1; if (!co || !li_1) return 3; x_pos = kbp[1] - 33; y_pos = kbp[2] - 33; m_printf("XTERM MOUSE: movement detected to pos x=%d: y=%d\n", x_pos, y_pos); mouse_move_absolute(x_pos, y_pos, co, li, 1, MOUSE_XTERM); /* Variable btn has following meaning: */ /* 0 = btn1 dn, 1 = btn2 dn, 2 = btn3 dn, 3 = btn up, * 32 = no button state change */ btn = kbp[0] - 32; if (btn < 3) { m_printf("XTERM MOUSE: button %i press\n", btn); mouse_move_button(btn, 1, MOUSE_XTERM); last_btn++; return 3; } switch (btn) { case 3: /* There seems to be no way of knowing which button was released */ /* So we assume all the buttons were released */ if (last_btn) { mouse_move_buttons(0, 0, 0, MOUSE_XTERM); m_printf("XTERM MOUSE: button release detected\n"); last_btn = 0; } break; case 64: m_printf("XTERM MOUSE: wheel UP\n"); mouse_move_wheel(-1, MOUSE_XTERM); break; case 65: m_printf("XTERM MOUSE: wheel DOWN\n"); mouse_move_wheel(1, MOUSE_XTERM); break; } return 3; } static int xtermmouse_get_event_sgr(Bit8u *kbp, int kbcount) { int btn, x_pos, y_pos, cnt; char press; #define IS_PR (press == 'M') char buf[16]; int co, li, li_1; if (kbcount > sizeof(buf) - 1) kbcount = sizeof(buf) - 1; memcpy(buf, kbp, kbcount); buf[kbcount] = 0; cnt = 0; sscanf(buf, "%d;%d;%d%c%n", &btn, &x_pos, &y_pos, &press, &cnt); if (!cnt) return 0; /* Read sizes from BDA because term can be resized. */ co = READ_WORD(BIOS_SCREEN_COLUMNS); li_1 = READ_BYTE(BIOS_ROWS_ON_SCREEN_MINUS_1); li = li_1 + 1; if (!co || !li_1) return cnt; m_printf("XTERM MOUSE: movement detected to pos x=%d: y=%d\n", x_pos, y_pos); mouse_move_absolute(x_pos - 1, y_pos - 1, co, li, 1, MOUSE_XTERM); if (btn == 35) // movement only return cnt; if (btn < 3) { m_printf("XTERM MOUSE: button %i press %i\n", btn, IS_PR); mouse_move_button(btn, IS_PR, MOUSE_XTERM); return cnt; } switch (btn) { case 64: m_printf("XTERM MOUSE: wheel UP\n"); mouse_move_wheel(-1, MOUSE_XTERM); break; case 65: m_printf("XTERM MOUSE: wheel DOWN\n"); mouse_move_wheel(1, MOUSE_XTERM); break; } return cnt; } int xtermmouse_get_event(Bit8u *kbp, int kbcount) { if (use_sgr) return xtermmouse_get_event_sgr(kbp, kbcount); return xtermmouse_get_event_old(kbp, kbcount); } static int has_xterm_mouse_support(void) { const char *km; if (config.vga || on_console()) return 0; term_init(); km = SLtt_tgetstr("Km"); if (!km || strlen(km) < 3) return 0; switch (km[2]) { case 'M': return 1; case '<': use_sgr = 1; return 1; } return 0; } static int xterm_mouse_init(void) { mouse_t *mice = &config.mouse; if (!has_xterm_mouse_support()) return FALSE; mice->type = MOUSE_XTERM; mice->native_cursor = 0; /* we have the xterm cursor */ /* save old highlight mouse tracking */ printf("\033[?1001s"); /* enable mouse tracking */ if (use_sgr) printf("\033[?9h\033[?1000h\033[?1002h\033[?1003h\033[?1006h"); else printf("\033[?9h\033[?1000h\033[?1002h\033[?1003h"); fflush(stdout); m_printf("XTERM MOUSE: tracking enabled, sgr=%i\n", use_sgr); return TRUE; } static void xterm_mouse_close(void) { /* disable mouse tracking */ if (use_sgr) printf("\033[?1006l\033[?1003l\033[?1002l\033[?1000l\033[?9l"); else printf("\033[?1003l\033[?1002l\033[?1000l\033[?9l"); /* restore old highlight mouse tracking */ printf("\033[?1001r\033[?1001l"); fflush(stdout); m_printf("XTERM MOUSE: Mouse tracking deinitialized\n"); } struct mouse_client Mouse_xterm = { "xterm", /* name */ xterm_mouse_init, /* init */ xterm_mouse_close, /* close */ NULL, };