Exemple #1
0
/* go_away:
 *  Performs a switch away.
 */
static void go_away(void)
{
	_switch_out();

	_unix_bg_man->disable_interrupts();
	if ((switch_mode == SWITCH_PAUSE) || (switch_mode == SWITCH_AMNESIA))
		_al_suspend_old_timer_emulation();

	/* Disable input devices while we're away */
	/* __al_linux_suspend_standard_drivers(); */

	_save_switch_state(switch_mode);

	if (gfx_driver && gfx_driver->save_video_state)
		gfx_driver->save_video_state();

	ioctl (__al_linux_console_fd, VT_RELDISP, 1); 
	console_active = 0; 

	__al_linux_switching_blocked--;

	if ((switch_mode == SWITCH_PAUSE) || (switch_mode == SWITCH_AMNESIA)) {
		__al_linux_wait_for_display();
		_al_resume_old_timer_emulation();
	}

	_unix_bg_man->enable_interrupts();
}
Exemple #2
0
/* __al_linux_console_graphics:
 *   Puts the Linux console into graphics mode.
 */
int __al_linux_console_graphics (void)
{
   if (__al_linux_use_console()) return 1;

   if (graphics_mode) return 0;  /* shouldn't happen */

   __al_linux_display_switch_lock(TRUE, TRUE);
   ioctl(__al_linux_console_fd, KDSETMODE, KD_GRAPHICS);
   __al_linux_wait_for_display();

   graphics_mode = 1;

   return 0;
}
Exemple #3
0
/* __al_linux_display_switch_lock:
 *  System driver routine for locking the display around crucial bits of 
 *  code, for example when changing video modes.
 */
void __al_linux_display_switch_lock(int lock, int foreground)
{
	if (__al_linux_console_fd == -1) {
		return;
	}

	if (foreground) {
		__al_linux_wait_for_display();
	}

	if (lock) {
		__al_linux_switching_blocked++;
	}
	else {
		__al_linux_switching_blocked--;
		poll_console_switch();
	}
}
Exemple #4
0
/* init_console:
 *  Initialises this subsystem.
 */
static int init_console(void)
{
   char tmp[256];

   /* Find our tty's VT number */
   __al_linux_vt = get_tty(STDIN_FILENO);

   if (__al_linux_vt < 0) {
      uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Error finding our VT: %s"), ustrerror(errno));
      return 1;
   }

   if (__al_linux_vt != 0) {
      /* Open our current console */
      if ((__al_linux_console_fd = open("/dev/tty", O_RDWR)) < 0) {
	 uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unable to open %s: %s"),
		    uconvert_ascii("/dev/tty", tmp), ustrerror(errno));
	 return 1;
      }
   } else {
      int tty, console_fd, fd, child;
      unsigned short mask;
      char tty_name[16];
      struct vt_stat vts; 

      /* Now we need to find a VT we can use.  It must be readable and
       * writable by us, if we're not setuid root.  VT_OPENQRY itself
       * isn't too useful because it'll only ever come up with one 
       * suggestion, with no guarrantee that we actually have access 
       * to it.
       *
       * At some stage I think this is a candidate for config
       * file overriding, but for now we'll stat the first N consoles
       * to see which ones we can write to (hopefully at least one!),
       * so that we can use that one to do ioctls.  We used to use 
       * /dev/console for that purpose but it looks like it's not 
       * always writable by enough people.
       *
       * Having found and opened a writable device, we query the state
       * of the first sixteen (fifteen really) consoles, and try 
       * opening each unused one in turn.
       */

      if ((console_fd = open ("/dev/console", O_WRONLY)) < 0) {
	 int n;
	 uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii("%s /dev/console: %s", tmp),
		    get_config_text("Unable to open"), ustrerror (errno));
	 /* Try some ttys instead... */
	 for (n = 1; n <= 24; n++) {
	     snprintf (tty_name, sizeof(tty_name), "/dev/tty%d", n);
	     tty_name[sizeof(tty_name)-1] = 0;
	     if ((console_fd = open (tty_name, O_WRONLY)) >= 0) break;
	 }
	 if (n > 24) return 1; /* leave the error message about /dev/console */
      }

      /* Get the state of the console -- in particular, the free VT field */
      if (ioctl (console_fd, VT_GETSTATE, &vts)) {
	 uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii("VT_GETSTATE: %s", tmp), ustrerror (errno));
	 close (console_fd);
	 return 1;
      }

      __al_linux_prev_vt = vts.v_active;

      /* We attempt to set our euid to 0; if we were run with euid 0 to
       * start with, we'll be able to do this now.  Otherwise, we'll just
       * ignore the error returned since it might not be a problem if the
       * ttys we look at are owned by the user running the program. */
      seteuid(0);

      /* tty0 is not really a console, so start counting at 2. */
      fd = -1;
      for (tty = 1, mask = 2; mask; tty++, mask <<= 1) {
	 if (!(vts.v_state & mask)) {
	    snprintf (tty_name, sizeof(tty_name), "/dev/tty%d", tty);
	    tty_name[sizeof(tty_name)-1] = 0;
	    if ((fd = open (tty_name, O_RDWR)) != -1) {
	       close (fd);
	       break;
	    }
	 }
      }

      seteuid (getuid());

      if (!mask) {
	 ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to find a usable VT"));
	 close (console_fd);
	 return 1;
      }

      /* OK, now fork into the background, detach from the current console,
       * and attach to the new one. */
      child = fork();

      if (child < 0) {
	 /* fork failed */
	 uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii ("fork: %s", tmp), ustrerror (errno));
	 close (console_fd);
	 return 1;
      }

      if (child) {
	 /* We're the parent -- write a note to the user saying where the
	  * app went, then quit */
	 fprintf (stderr, "Allegro application is running on VT %d\n", tty);
	 exit (0);
      }

      /* We're the child.  Detach from our controlling terminal, and start
       * a new session. */
      close (console_fd);
      ioctl (0, TIOCNOTTY, 0);
      setsid();

      /* Open the new one again.  It becomes our ctty, because we started a
       * new session above. */
      seteuid(0);
      fd = open (tty_name, O_RDWR);
      seteuid(getuid());

      if (fd == -1) {
	 ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to reopen new console"));
	 return 1;
      }

      /* Try to switch to it -- should succeed, since it's our ctty */
      ioctl (fd, VT_ACTIVATE, tty);

      __al_linux_vt = tty;
      __al_linux_console_fd = fd;

      /* Check we can reliably wait until we have the display */
      if (__al_linux_wait_for_display()) {
	 close (fd);
	 ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("VT_WAITACTIVE failure"));
	 return 1;
      }

      /* dup2 it to stdin, stdout and stderr if necessary */
      if (isatty(0)) dup2 (fd, 0);
      if (isatty(1)) dup2 (fd, 1);
      if (isatty(2)) dup2 (fd, 2);
   }

   /* Get termio settings and make a working copy */
   tcgetattr(__al_linux_console_fd, &__al_linux_startup_termio);
   __al_linux_work_termio = __al_linux_startup_termio;

   return 0;
}