Exemplo n.º 1
0
/*
 * Process an event
 */
static errr Term_xtra_cap_event(int v)
{
	int i, arg;
	char buf[2];

	/* Wait */
	if (v)
	{
		/* Wait for one byte */
		i = read(0, buf, 1);

		/* Hack -- Handle "errors" */
		if ((i <= 0) && (errno != EINTR)) exit_game_panic();
	}

	/* Do not wait */
	else
	{
		/* Get the current flags for stdin */
		if ((arg = fcntl(0, F_GETFL, 0)) < 1) return (1);

		/* Tell stdin not to block */
		if (fcntl(0, F_SETFL, arg | O_NDELAY) < 0) return (1);

		/* Read one byte, if possible */
		i = read(0, buf, 1);

		/* Replace the flags for stdin */
		if (fcntl(0, F_SETFL, arg)) return (1);
	}

	/* No keys ready */
	if ((i != 1) || (!buf[0])) return (1);

	/* Enqueue the keypress */
	Term_keypress(buf[0]);

	/* Success */
	return (0);
}
Exemplo n.º 2
0
/*
 * Process events, with optional wait
 */
static errr Term_xtra_gcu_event(int v)
{
	int i, j, k;

	/* Wait */
	if (v)
	{
		/* Get a keypress; we use halfdelay(1) so if the user takes more */
		/* than 0.1 seconds we get a chance to do updates. */
		halfdelay(2);
		i = getch();
		while (i == ERR)
		{
			i = getch();
			idle_update();
		}
		cbreak();

		/* Mega-Hack -- allow graceful "suspend" */
		for (k = 0; (k < 10) && (i == ERR); k++) i = getch();

		/* Broken input is special */
		if (i == ERR) exit_game_panic();
		if (i == EOF) exit_game_panic();
	}

	/* Do not wait */
	else
	{
		/* Do not wait for it */
		nodelay(stdscr, TRUE);

		/* Check for keypresses */
		i = getch();

		/* Wait for it next time */
		nodelay(stdscr, FALSE);

		/* None ready */
		if (i == ERR) return (1);
		if (i == EOF) return (1);
	}

	/* Not sure if this is portable to non-ncurses platforms */
	#ifdef USE_NCURSES
	if (i == KEY_RESIZE)
	{
		/* wait until we go one second (10 deci-seconds) before actually
		 * doing the resizing. users often end up triggering multiple
		 * KEY_RESIZE events while changing window size. */
		halfdelay(10);
		do {
			i = getch();
		} while (i == KEY_RESIZE);
		cbreak();
		do_gcu_resize();
		if (i == ERR) return (1);
	}
	#endif

	/* uncomment to debug keycode issues */
	#if 0
	printw("key %d", i);
	wrefresh(stdscr);
	#endif

	/* This might be a bad idea, but...
	 *
	 * Here we try to second-guess ncurses. In some cases, keypad() mode will
	 * fail to translate multi-byte escape sequences into things like number-
	 * pad actions, function keys, etc. So we can hardcode a small list of some
	 * of the most common sequences here, just in case.
	 *
	 * Notice that we turn nodelay() on. This means, that we won't accidentally
	 * interpret sequences as valid unless all the bytes are immediately
	 * available; this seems like an acceptable risk to fix problems associated
	 * with various terminal emulators (I'm looking at you PuTTY).
	 */
	if (i == 27) /* ESC */
	{
		nodelay(stdscr, TRUE);
		j = getch();
		switch (j)
		{
			case 'O':
			{
				k = getch();
				switch (k)
				{
					/* PuTTY number pad */
					case 'q': i = '1'; break;
					case 'r': i = '2'; break;
					case 's': i = '3'; break;
					case 't': i = '4'; break;
					case 'u': i = '5'; break;
					case 'v': i = '6'; break;
					case 'w': i = '7'; break;
					case 'x': i = '8'; break;
					case 'y': i = '9'; break;

					/* no match */
					case ERR: break;
					default: ungetch(k); ungetch(j);
				}
				break;
			}

			/* no match */
			case ERR: break;
			default: ungetch(j);
		}
		nodelay(stdscr, FALSE);
	}

#ifdef KEY_DOWN
	/* Handle arrow keys */
	switch (i)
	{
		case KEY_DOWN:  i = ARROW_DOWN;  break;
		case KEY_UP:    i = ARROW_UP;    break;
		case KEY_LEFT:  i = ARROW_LEFT;  break;
		case KEY_RIGHT: i = ARROW_RIGHT; break;
		default:
			if (i < KEY_MIN) break;

			/* Mega-Hack -- Fold, spindle, and mutilate
			 * the keys to fit in 7 bits.
			 */

			if (i >= 252) i = KEY_F(63) - (i - 252);
			if (i >= ARROW_DOWN) i += 4;

			i = 128 + (i & 127);
			break;
	}
#endif

	/* Enqueue the keypress */
	Term_keypress(i);

	/* Success */
	return (0);
}
Exemplo n.º 3
0
/*
 * Process events, with optional wait
 */
static errr Term_xtra_gcu_event(int v)
{
   int i, k;

   /* Wait */
   if (v)
   {
      /* Paranoia -- Wait for it */
      nodelay(stdscr, FALSE);

      /* Get a keypress */
      i = getch();

      /* Mega-Hack -- allow graceful "suspend" */
      for (k = 0; (k < 10) && (i == ERR); k++) i = getch();

      /* Broken input is special */
      if (i == ERR) exit_game_panic();
      if (i == EOF) exit_game_panic();
   }

   /* Do not wait */
   else
   {
      /* Do not wait for it */
      nodelay(stdscr, TRUE);

      /* Check for keypresses */
      i = getch();

      /* Wait for it next time */
      nodelay(stdscr, FALSE);

      /* None ready */
      if (i == ERR) return (1);
      if (i == EOF) return (1);
   }

   /* Issue: Currently, we map curses escape sequences via the macro processing system (see pref-gcu.prf).
    * If you don't already know, this is required for things like arrow keys and the numpad and what not.
    * The advantage of this approach is that users can (theoretically) edit the pref file themselves in
    * the event that their terminal is sending a different escape sequence for some reason. All good, right?
    * Well, except for those places in the code that *disable* macro processing! This includes all user prompts,
    * the store UI (TODO) and the autopicker. Now, it's rather disconcerting if arrow keys aren't available in
    * a text editor or if the user can't correct typos with backspace!
    *
    * The idea of translating here is from current Vanilla
    * TODO */

   /* Backspace */
   if (i == 0x7F)
      i = '\b';

    if (i == 27) /* \e is not ansi c */
    {
        /*
        char  buf[255];
        int   cb = _getstr(buf, 255);
        if (cb > 0)
        {
            if (strcmp(buf, "[3~") == 0)
                i = '.';
            else if (strcmp(buf, "[2~") == 0)
                i = '0';
            else if (strcmp(buf, "[4~") == 0)
                i = '1';
            else if (strcmp(buf, "[F") == 0)
                i = '1';
            else if (strcmp(buf, "[B") == 0)
                i = '2';
            ...
            else
                _ungetstr(buf, cb);
        }
        CTK: Actually, I'm not so sure this is going to work. Arrow keys need
        to be known as such by the game engine not translated to numbers. And
        looking at what main-win.c and main-x11.c do to get this working is ...
        uh, a bit overwhelming. So this is on hold for now ...
        */
    }


   /* Enqueue the keypress */
   Term_keypress(i);

   /* Success */
   return (0);
}