[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

xterm mouse events to VT52 emus



to: mint@atari.archive.umich.edu

Here's some code that could be incorporated into GEM VT52/100 terminal
emulators.  It's minimal code to handle xterm mouse mode selection and
forwarding of mouse clicks to process running in the terminal (I added
it to `wterm' and thought that you might like it too :)).

Programs which work with this include Midnight Commander (mc -x),
Emacs (M-x xterm-mouse-mode), Jed, Pine and Tin.


	- Eero

-------------------------------------

#define XTERM_EMU

----- set xterm mouse mode ----------

/* ESC sequence index, xterm mode, font char width, font height */
static short	escstate, xterm, fonw, fonh;
static WWIN	*win;

#ifdef XTERM_EMU

#define MAX_PARAMETERS	4

/* \E[?xxx... xterm terminal parameter handling
 *
 * ATM implements only xterm mouse mode setting
 */
static void esc20(uchar c)
{
  static int i, value, index, parameter[MAX_PARAMETERS];

  /* read next parameter? */
  if (c == ';' && index < MAX_PARAMETERS-1) {
    index++;
    return;
  }

  /* parameter? */
  if (c >= '0' && c <= '9')  {
    parameter[index] *= 10;
    parameter[index] += c - '0';
    return;
  }

  /* h = set mode
   * l = clear (reset) mode
   * r = restore mode (from restored)
   * s = save mode
   */
  if (c == 'h' || c == 'l') {
    value = 0;
    for (i = index; i >= 0; i--) {

      switch(parameter[i]) {

        /* set mouse emulation? */
	case 9:
	  value |= 1;	/* x10 mode */
	  break;
	case 1000:	/* report */
	case 1001:	/* track */
	  value |= 2;
	  break;
      }
    }
    if (c == 'l') {
      xterm &= ~value;
    } else {
      xterm |= value;
    }
  }

  while (index >= 0) {
    parameter[index--] = 0;
  }
  index = 0;
  escstate = 0;
}

/* hopefully this minimal vtxxx '\E[' code handler helps if VT52 isn't
 * enough for your program (at least it will be easier to add xterm
 * compatible functionality).
 */
static void esc10(uchar c)
{
  switch(c) {

    case '?': /* parameters */
      escstate = 20;
      return;

    /* these are already implemented by VT52 code */

    /* case 'A':  cursor up */
    /* case 'B':  cursor down */
    /* case 'C':  cursor right */
    /* case 'D':  cursor left */

    /* case '[':  function keys */
  }
  escstate = 0;
}

#endif /* XTERM_EMU */

---------  ESC key code handling -------

static void esc1(uchar c)	/* various control codes */
{
  escstate = 0;

  switch(c) {

#ifdef XTERM_EMU

/* xterm key codes */

    case '[':
      escstate = 10;
      break;

#endif /* XTERM_EMU */

[...handling of VT52 ESC code]

----- ESC sequence handling --------

static void printc(uchar c)
{
  switch(escstate) {
    case 0:
      esc0(c);	/* no ESC pressed (yet) */
      break;
    case 1:
      esc1(c);	/* ESC pressed */
      break;
#ifdef XTERM_EMU
    case 10:
      esc10(c);
      break;
    case 20:
      break;
#endif /* XTERM_EMU */

[...rest of the ESC sequences]

---- mouse button handling in event loop -------

#ifdef XTERM_EMU
	case EVENT_MPRESS:
	  /* xterm = 0, no emulation
	   * xterm = 1, x10 mode (report only presses)
	   * xterm = 2, x11 mode (report also releases)
	   */
	  if (xterm && ev->win == win) {
	    int button = ' ';

	    switch (ev->key) {
	      case BUTTON_RIGHT:
		button++;
	      case BUTTON_MID:
		button++;
	      case BUTTON_LEFT:
		sprintf(buf, "\e[M%c%c%c", button,
			'!' + ev->x / fonw, '!' + ev->y / fonh);
		break;
	    }
	    write (pipeh, buf, 6);
	  }
	  break;
#endif /* XTERM_EMU */

	case EVENT_MRELEASE:
	  if (isIconified) {
	    iconify ();
	  } else {
#ifdef XTERM_EMU
	    if (xterm > 1) {
	      sprintf(buf, "\e[M#%c%c",	'!' + ev->x / fonw, '!' + ev->y / fonh);
	      write (pipeh, buf, 6);
	    }
#endif /* XTERM_EMU */
	  }
	  break;

---------------------