6480003 Xorg should support virtual console on Solaris
authorAaron Zang <Aaron.Zang@Sun.COM>
Thu, 13 Aug 2009 23:34:52 -0700
changeset 766 ac938085d487
parent 765 a3c7a0790719
child 767 35c92398e120
6480003 Xorg should support virtual console on Solaris
open-src/driver/xf86-input-keyboard/Makefile
open-src/driver/xf86-input-keyboard/sun-kbd-vt.patch
open-src/xserver/xorg/patch-list
open-src/xserver/xorg/sun-src/hw/xfree86/os-support/solaris/sun_VTsw.c
open-src/xserver/xorg/sun-src/os/dtlogin.c
open-src/xserver/xorg/vt.patch
--- a/open-src/driver/xf86-input-keyboard/Makefile	Fri Aug 07 22:52:55 2009 -0700
+++ b/open-src/driver/xf86-input-keyboard/Makefile	Thu Aug 13 23:34:52 2009 -0700
@@ -30,7 +30,7 @@
 # or other dealings in this Software without prior written authorization
 # of the copyright holder.
 #
-# @(#)Makefile	1.8	09/05/15
+# @(#)Makefile	1.9	09/08/14
 #
 
 # Package name used in tarballs
@@ -44,7 +44,8 @@
 	hal-man-page.patch,-p1 \
 	hal-hotplug.patch,-p1 \
 	sun-keymappings.patch,-p1 \
-	sun-kb-autodetect.patch
+	sun-kb-autodetect.patch \
+	sun-kbd-vt.patch
 
 # Regenerate files after patching Makefile.am in sun-kb-autodetect.patch
 AUTORECONF=yes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/driver/xf86-input-keyboard/sun-kbd-vt.patch	Thu Aug 13 23:34:52 2009 -0700
@@ -0,0 +1,73 @@
+diff -urp -x '*~' -x '*.orig' src/sun_kbd.c src/sun_kbd.c
+--- src/sun_kbd.c	2009-08-13 13:19:37.444951000 +0800
++++ src/sun_kbd.c	2009-08-13 13:19:37.668124000 +0800
+@@ -63,6 +63,7 @@
+ #include <sys/stropts.h>
+ #include <sys/vuid_event.h>
+ #include <sys/kbd.h>
++#include <sys/usb/clients/hid/hid.h>
+ 
+ static int KbdOn(InputInfoPtr pInfo, int what);
+ 
+@@ -178,6 +179,8 @@ KbdOn(InputInfoPtr pInfo, int what)
+     sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private;
+ 
+     int	ktrans, kdirect, i;
++    int io_get_direct = KIOCGDIRECT;
++    int io_set_direct = KIOCSDIRECT;
+ 
+     if (priv->kbdActive) {
+ 	return Success;
+@@ -190,9 +193,15 @@ KbdOn(InputInfoPtr pInfo, int what)
+ 		    "%s: cannot push module '%s' onto keyboard device: %s\n",
+ 		    pInfo->name, priv->strmod, strerror(errno));
+ 	}
++
++	if (strcmp(priv->strmod, "usbkbm") == 0) {
++	    io_get_direct = HIDIOCKMGDIRECT;
++	    io_set_direct = HIDIOCKMSDIRECT;
++	}
++
+     }
+ 
+-    SYSCALL(i = ioctl(pInfo->fd, KIOCGDIRECT, &kdirect));
++    SYSCALL(i = ioctl(pInfo->fd, io_get_direct, &kdirect));
+     if (i < 0) {
+ 	xf86Msg(X_ERROR, 
+ 		"%s: Unable to determine keyboard direct setting: %s\n", 
+@@ -203,7 +212,7 @@ KbdOn(InputInfoPtr pInfo, int what)
+     priv->odirect = kdirect;
+     kdirect = 1;
+ 
+-    SYSCALL(i = ioctl(pInfo->fd, KIOCSDIRECT, &kdirect));
++    SYSCALL(i = ioctl(pInfo->fd, io_set_direct, &kdirect));
+     if (i < 0) {
+ 	xf86Msg(X_ERROR, "%s: Failed turning keyboard direct mode on: %s\n",
+ 			pInfo->name, strerror(errno));
+@@ -247,6 +256,7 @@ KbdOff(InputInfoPtr pInfo, int what)
+     sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private;
+ 
+     int i;
++    int io_set_direct, kdirect;
+ 
+     if (!priv->kbdActive) {
+ 	return Success;
+@@ -280,8 +290,16 @@ KbdOff(InputInfoPtr pInfo, int what)
+ 	priv->otranslation = -1;
+     }
+ 
+-    if (priv->odirect != -1) {
+-        SYSCALL(i = ioctl(pInfo->fd, KIOCSDIRECT, &priv->odirect));
++    io_set_direct = KIOCSDIRECT;
++    kdirect = priv->odirect;
++
++    if ((priv->strmod != NULL) && (strcmp(priv->strmod, "usbkbm") == 0)) {
++	io_set_direct = HIDIOCKMSDIRECT;
++	kdirect = 0;
++    }
++
++    if (kdirect != -1) {
++        SYSCALL(i = ioctl(pInfo->fd, io_set_direct, &kdirect));
+ 	if (i < 0) {
+ 	    xf86Msg(X_ERROR,
+ 		    "%s: Unable to restore keyboard direct setting: %s\n",
--- a/open-src/xserver/xorg/patch-list	Fri Aug 07 22:52:55 2009 -0700
+++ b/open-src/xserver/xorg/patch-list	Thu Aug 13 23:34:52 2009 -0700
@@ -36,3 +36,4 @@
 dixmods-deps.patch
 sparc-initvisuals.patch
 hotkey.patch
+vt.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/xserver/xorg/sun-src/hw/xfree86/os-support/solaris/sun_VTsw.c	Thu Aug 13 23:34:52 2009 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ */
+
+#pragma ident   "@(#)sun_VTsw.c 1.1     09/08/14 SMI"
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#include <door.h>
+#include <sys/vtdaemon.h>
+
+/*
+ * Handle the VT-switching interface for Solaris 
+ */
+
+void
+xf86VTRequest(int sig)
+{
+	if (xf86Info.vtPendingNum != -1)
+	{
+		ioctl(xf86Info.consoleFd, VT_RELDISP, 1);
+		xf86Info.vtPendingNum = -1;
+
+		return;
+	}
+
+	xf86Info.vtRequestsPending = TRUE;
+	return;
+}
+
+Bool
+xf86VTSwitchPending(void)
+{
+    return(xf86Info.vtRequestsPending ? TRUE : FALSE);
+}
+
+Bool
+xf86VTSwitchAway(void)
+{
+	int door_fd;
+	vt_cmd_arg_t vt_door_arg;
+	door_arg_t door_arg;
+
+	xf86Info.vtRequestsPending = FALSE;
+
+	vt_door_arg.vt_ev = VT_EV_HOTKEYS;
+	vt_door_arg.vt_num = xf86Info.vtPendingNum; 
+	door_arg.data_ptr = (char *)&vt_door_arg;
+	door_arg.data_size = sizeof (vt_cmd_arg_t);
+	door_arg.rbuf = NULL;
+	door_arg.rsize = 0;
+	door_arg.desc_ptr = NULL;
+	door_arg.desc_num = 0;
+
+	if ((door_fd = open(VT_DAEMON_DOOR_FILE, O_RDONLY)) < 0)
+		return (FALSE);
+
+	if (door_call(door_fd, &door_arg) != 0) {
+		close(door_fd);
+		return (FALSE);
+	}
+
+	close(door_fd);
+	return (TRUE);
+}
+
+Bool
+xf86VTSwitchTo(void)
+{
+	xf86Info.vtRequestsPending = FALSE;
+	if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
+	{
+		return(FALSE);
+	}
+	else
+	{
+		return(TRUE);
+	}
+}
--- a/open-src/xserver/xorg/sun-src/os/dtlogin.c	Fri Aug 07 22:52:55 2009 -0700
+++ b/open-src/xserver/xorg/sun-src/os/dtlogin.c	Thu Aug 13 23:34:52 2009 -0700
@@ -26,7 +26,7 @@
  * of the copyright holder.
  */
 
-#pragma ident "@(#)dtlogin.c	1.18	08/05/20   SMI" 
+#pragma ident "@(#)dtlogin.c	1.19	09/08/14   SMI" 
 
 /* Implementation of Display Manager (dtlogin/gdm/xdm/etc.) to X server
  * communication pipe. The Display Manager process will start 
@@ -67,6 +67,7 @@
 #include <sys/task.h>
 #include <ctype.h>
 #include "scrnintstr.h"
+#include <sys/vt.h>
 #ifdef XSUN
 #include "sunIo.h"
 #endif
@@ -76,6 +77,7 @@
 #define BUFLEN 1024
 
 uid_t	root_euid;
+int xf86ConsoleFd = -1;
 
 /* in Xserver/os/auth.c */
 extern const char *GetAuthFilename(void);
@@ -497,4 +499,8 @@
 	if (chdir(dmd->homedir) < 0)
 	    DtloginError("Error in changing working directory");
     }
+
+    /* Inform the kernel that a user has logged in on this VT device */
+    if (xf86ConsoleFd != -1)
+	ioctl(xf86ConsoleFd, VT_SETDISPLOGIN, 1);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/xserver/xorg/vt.patch	Thu Aug 13 23:34:52 2009 -0700
@@ -0,0 +1,460 @@
+diff -urp -x '*~' -x '*.orig' dix/main.c dix/main.c
+--- dix/main.c	2009-07-08 01:48:57.000000000 +0800
++++ dix/main.c	2009-08-13 18:00:45.031810000 +0800
+@@ -79,6 +79,8 @@ Equipment Corporation.
+ #include <dix-config.h>
+ #endif
+ 
++#include <sys/stat.h>
++#include <stdio.h>
+ #include <X11/X.h>
+ #include <X11/Xos.h>   /* for unistd.h  */
+ #include <X11/Xproto.h>
+@@ -233,6 +235,30 @@ static int indexForScanlinePad[ 65 ] = {
+ #define MIN(a,b) (((a) < (b)) ? (a) : (b))
+ #endif
+ 
++#if defined(sun) 
++extern const char * GetAuthFilename(void);
++
++#define LOCK_PREFIX	"/var/xauth/"
++
++/*
++ * Setup /var/xauth/$DISPLAY, which is a symlink to the
++ * actually auth file.
++ */
++static void
++SetupXauthFile(char *filename)
++{
++	struct stat buf;
++	char sym_authfile[40];
++
++	snprintf(sym_authfile, 40, LOCK_PREFIX "%s", display);
++
++	mkdir(LOCK_PREFIX, S_IRWXU);
++
++	remove(sym_authfile);
++	symlink(filename, sym_authfile);
++}
++#endif
++
+ #ifdef XQUARTZ
+ #include <pthread.h>
+ 
+@@ -247,6 +273,9 @@ int main(int argc, char *argv[], char *e
+ {
+     int		i;
+     HWEventQueueType	alwaysCheckForInput[2];
++#if defined(sun) 
++    char *xauthfile = NULL;
++#endif
+ 
+     display = "0";
+ 
+@@ -260,6 +289,12 @@ int main(int argc, char *argv[], char *e
+ 
+     ProcessCommandLine(argc, argv);
+ 
++#if defined(sun)
++    xauthfile = GetAuthFilename();
++    if (xauthfile)
++	SetupXauthFile(xauthfile);
++#endif
++
+     alwaysCheckForInput[0] = 0;
+     alwaysCheckForInput[1] = 1;
+     while(1)
+diff -urp -x '*~' -x '*.orig' hw/xfree86/common/xf86Events.c hw/xfree86/common/xf86Events.c
+--- hw/xfree86/common/xf86Events.c	2009-07-08 01:48:58.000000000 +0800
++++ hw/xfree86/common/xf86Events.c	2009-08-13 18:00:45.030110000 +0800
+@@ -205,16 +205,23 @@ xf86ProcessActionEvent(ActionEvent actio
+ 	if (!xf86Info.dontZoom)
+ 	    xf86ZoomViewport(xf86Info.currentScreen, -1);
+ 	break;
+-#if !defined(__SOL8__) && \
+-    (!defined(sun) || defined(__i386__)) && defined(VT_ACTIVATE)
+     case ACTION_SWITCHSCREEN:
+ 	if (VTSwitchEnabled && !xf86Info.dontVTSwitch && arg) {
+ 	    int vtno = *((int *) arg);
+ #if defined(__SCO__) || defined(__UNIXWARE__)
+ 	    vtno--;
+ #endif
++
++#if defined(sun)
++	    if (vtno == xf86Info.vtno)
++		break;
++
++	    xf86Info.vtRequestsPending = TRUE;
++	    xf86Info.vtPendingNum = vtno;
++#else
+ 	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, vtno) < 0)
+ 		ErrorF("Failed to switch consoles (%s)\n", strerror(errno));
++#endif
+ 	}
+ 	break;
+     case ACTION_SWITCHSCREEN_NEXT:
+@@ -239,7 +246,7 @@ xf86ProcessActionEvent(ActionEvent actio
+ 		ErrorF("Failed to switch consoles (%s)\n", strerror(errno));
+ 	}
+ 	break;
+-#endif
++
+     default:
+ 	break;
+     }
+diff -urp -x '*~' -x '*.orig' hw/xfree86/common/xf86Globals.c hw/xfree86/common/xf86Globals.c
+--- hw/xfree86/common/xf86Globals.c	2009-07-08 01:48:58.000000000 +0800
++++ hw/xfree86/common/xf86Globals.c	2009-08-13 18:00:45.030947000 +0800
+@@ -104,6 +104,9 @@ xf86InfoRec xf86Info = {
+     .ddxSpecialKeys             = SKWhenNeeded,
+     .lastEventTime              = -1,
+     .vtRequestsPending          = FALSE,
++#if defined(sun)
++    .vtPendingNum		= -1,
++#endif
+     .dontVTSwitch               = FALSE,
+     .dontZap                    = FALSE,
+     .dontZoom                   = FALSE,
+diff -urp -x '*~' -x '*.orig' hw/xfree86/common/xf86Privstr.h hw/xfree86/common/xf86Privstr.h
+--- hw/xfree86/common/xf86Privstr.h	2009-07-08 01:48:58.000000000 +0800
++++ hw/xfree86/common/xf86Privstr.h	2009-08-13 18:00:45.030724000 +0800
+@@ -70,6 +70,11 @@ typedef struct {
+     /* event handler part */
+     int			lastEventTime;
+     Bool		vtRequestsPending;
++
++#if defined(sun)
++    int			vtPendingNum;
++#endif
++
+     Bool		dontVTSwitch;
+     Bool		dontZap;
+     Bool		dontZoom;
+diff -urp -x '*~' -x '*.orig' hw/xfree86/os-support/solaris/Makefile.am hw/xfree86/os-support/solaris/Makefile.am
+--- hw/xfree86/os-support/solaris/Makefile.am	2009-08-13 18:00:41.413951000 +0800
++++ hw/xfree86/os-support/solaris/Makefile.am	2009-08-13 18:00:45.028812000 +0800
+@@ -1,9 +1,3 @@
+-if SOLARIS_USL_CONSOLE
+-VTSW_SRC = $(srcdir)/../shared/VTsw_usl.c
+-else
+-VTSW_SRC = $(srcdir)/../shared/VTsw_noop.c
+-endif
+-
+ if AGP
+ AGP_SRC = sun_agp.c
+ else
+@@ -18,13 +12,13 @@ solaris-@[email protected]: solaris
+ 
+ noinst_LTLIBRARIES = libsolaris.la
+ libsolaris_la_SOURCES = sun_init.c \
+-	sun_vid.c sun_bell.c $(AGP_SRC) sun_apm.c \
++	sun_vid.c sun_bell.c $(AGP_SRC) sun_apm.c sun_VTsw.c\
+ 	$(srcdir)/../shared/kmod_noop.c \
+ 	$(srcdir)/../shared/posix_tty.c \
+ 	$(srcdir)/../shared/sigio.c \
+ 	$(srcdir)/../shared/stdResource.c \
+-	$(srcdir)/../shared/vidmem.c \
+-	$(VTSW_SRC)
++	$(srcdir)/../shared/vidmem.c
++
+ nodist_libsolaris_la_SOURCES = $(SOLARIS_INOUT_SRC)
+ 
+ sdk_HEADERS =
+diff -urp -x '*~' -x '*.orig' hw/xfree86/os-support/solaris/sun_init.c hw/xfree86/os-support/solaris/sun_init.c
+--- hw/xfree86/os-support/solaris/sun_init.c	2008-12-16 03:45:40.000000000 +0800
++++ hw/xfree86/os-support/solaris/sun_init.c	2009-08-13 18:00:45.028532000 +0800
+@@ -33,17 +33,18 @@
+ # include <sys/kd.h>
+ #endif
+ 
++/* For use of VT_SETDISPLOGIN in dtlogin.c */
++extern int xf86ConsoleFd;
++
+ static Bool KeepTty = FALSE;
+ static Bool Protect0 = FALSE;
+ #ifdef HAS_USL_VTS
+ static int VTnum = -1;
+ static int xf86StartVT = -1;
+-#endif
+-
+-#if defined(__SOL8__) || (!defined(__i386__) && !defined(__i386))
+-static char fb_dev[PATH_MAX] = "/dev/fb";
++static int vtEnabled = 0;
++static char fb_dev[PATH_MAX] = "/dev/vt/0";
+ #else
+-static char fb_dev[PATH_MAX] = "/dev/console";
++static char fb_dev[PATH_MAX] = "/dev/fb";
+ #endif
+ 
+ void
+@@ -93,51 +94,60 @@ xf86OpenConsole(void)
+ 	/*
+ 	 * Setup the virtual terminal manager
+ 	 */
+-	if (VTnum != -1)
++	if ((fd = open("/dev/vt/0", O_RDWR, 0)) == -1)
+ 	{
+-	    xf86Info.vtno = VTnum;
+-	    from = X_CMDLINE;
++	    xf86ErrorF("xf86OpenConsole: Cannot open /dev/vt/0 (%s)\n",
++			strerror(errno));
++	    vtEnabled = 0;
+ 	}
+ 	else
+ 	{
+-	    if ((fd = open("/dev/vt00",O_RDWR,0)) < 0)
+-		FatalError("xf86OpenConsole: Cannot open /dev/vt00 (%s)\n",
+-		    strerror(errno));
++	    if (ioctl(fd, VT_ENABLED, &vtEnabled) < 0)
++	    {
++		xf86ErrorF("xf86OpenConsole: VT_ENABLED failed (%s)\n",
++			   strerror(errno));
++		vtEnabled = 0;
++	    }
++	}
+ 
++	if (vtEnabled == 0)
++	{
++	    /* VT not enabled - kernel too old or Sparc platforms
++	       without visual_io support */
++	    xf86Msg(from, "VT infrastructure is not available\n");
++
++	    xf86StartVT = 0;
++	    xf86Info.vtno = 0;
++	}
++	else
++	{
+ 	    if (ioctl(fd, VT_GETSTATE, &vtinfo) < 0)
+ 		FatalError("xf86OpenConsole: Cannot determine current VT\n");
+ 
+ 	    xf86StartVT = vtinfo.v_active;
+ 
+-	    /*
+-	     * There is a SEVERE problem with x86's VT's.  The VT_OPENQRY
+-	     * ioctl() will panic the entire system if all 8 (7 VT's+Console)
+-	     * terminals are used.  The only other way I've found to determine
+-	     * if there is a free VT is to try activating all the the available
+-	     * VT's and see if they all succeed - if they do, there there is no
+-	     * free VT, and the Xserver cannot continue without panic'ing the
+-	     * system.  (It's ugly, but it seems to work.)  Note there is a
+-	     * possible race condition here.
+-	     *
+-	     * David Holland 2/23/94
+-	     */
+-
+-	    FreeVTslot = 0;
+-	    for (i = 7; (i >= 0) && !FreeVTslot; i--)
+-		if (ioctl(fd, VT_ACTIVATE, i) != 0)
+-		    FreeVTslot = 1;
+-
+-	    if (!FreeVTslot ||
+-	        (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
+-		(xf86Info.vtno == -1))
+-		FatalError("xf86OpenConsole: Cannot find a free VT\n");
++	    if (VTnum != -1)
++	    {
++		xf86Info.vtno = VTnum;
++		from = X_CMDLINE;
++	    }
++	    else
++	    {
++		if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
++		    (xf86Info.vtno == -1))
++		{
++		    FatalError("xf86OpenConsole: Cannot find a free VT\n");
++		}
++	    }
+ 
+-	    close(fd);
++	    xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
++	    snprintf(fb_dev, PATH_MAX, "/dev/vt/%d", xf86Info.vtno);
+ 	}
+ 
+-	xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+-
+-	sprintf(fb_dev, "/dev/vt%02d", xf86Info.vtno); /* Solaris 2.1 x86 */
++	if (fd != -1)
++	{
++		close(fd);
++	}
+ 
+ #endif /* HAS_USL_VTS */
+ 
+@@ -153,26 +163,34 @@ xf86OpenConsole(void)
+ 	/* Change ownership of the vt */
+ 	chown(fb_dev, getuid(), getgid());
+ 
+-	/*
+-	 * Now get the VT
+-	 */
+-	if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+-	    xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
++	if (vtEnabled)
++	{
++	    /*
++	     * Now get the VT
++	     */
++	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
++	        xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
++
++	    if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
++	        xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
++
++	    if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
++	        FatalError("xf86OpenConsole: VT_GETMODE failed\n");
+ 
+-	if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+-	    xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
++	    OsSignal(SIGUSR1, xf86VTRequest);
+ 
+-	if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
+-	    FatalError("xf86OpenConsole: VT_GETMODE failed\n");
++	    VT.mode = VT_PROCESS;
++	    VT.relsig = SIGUSR1;
++	    VT.acqsig = SIGUSR1;
+ 
+-	signal(SIGUSR1, xf86VTRequest);
++	    if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
++	        FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+ 
+-	VT.mode = VT_PROCESS;
+-	VT.relsig = SIGUSR1;
+-	VT.acqsig = SIGUSR1;
++	    if (ioctl(xf86Info.consoleFd, VT_SETDISPINFO, atoi(display)) < 0)
++		xf86Msg(X_WARNING, "xf86OpenConsole: VT_SETDISINFO failed\n");
+ 
+-	if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
+-	    FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
++	    xf86ConsoleFd = xf86Info.consoleFd;
++	}
+ #endif
+ 
+ #ifdef KDSETMODE
+@@ -187,23 +205,26 @@ xf86OpenConsole(void)
+     else /* serverGeneration != 1 */
+     {
+ #ifdef HAS_USL_VTS
+-	/*
+-	 * Now re-get the VT
+-	 */
+-	if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+-	    xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
++	if (vtEnabled)
++	{
++	    /*
++	     * Now re-get the VT
++	     */
++    	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
++	        xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ 
+-	if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+-	    xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
++	    if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
++	        xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ 
+-	/*
+-	 * If the server doesn't have the VT when the reset occurs,
+-	 * this is to make sure we don't continue until the activate
+-	 * signal is received.
+-	 */
+-	if (!xf86Screens[0]->vtSema)
+-	    sleep(5);
++	    /*
++	     * If the server doesn't have the VT when the reset occurs,
++	     * this is to make sure we don't continue until the activate
++	     * signal is received.
++	     */
++	    if (!xf86Screens[0]->vtSema)
++	        sleep(5);
+ 
++	}
+ #endif /* HAS_USL_VTS */
+ 
+     }
+@@ -268,28 +289,17 @@ xf86CloseConsole(void)
+ 
+ #ifdef HAS_USL_VTS
+ 
+-    /*
+-     * Solaris 2.1 x86 doesn't seem to "switch" back to the console when the VT
+-     * is relinquished and its mode is reset to auto.  Also, Solaris 2.1 seems
+-     * to associate vt00 with the console so I've opened the "console" back up
+-     * and made it the active vt again in text mode and then closed it.  There
+-     * must be a better hack for this but I'm not aware of one at this time.
+-     *
+-     * Doug Anson 11/6/93
+-     * [email protected]
+-     *
+-     * Fixed - 12/5/93 - David Holland - [email protected]
+-     * Did the whole thing similarly to the way linux does it
+-     */
+-
+-    if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
++    if (vtEnabled)
+     {
+-	VT.mode = VT_AUTO;		/* Set default vt handling */
+-	ioctl(xf86Info.consoleFd, VT_SETMODE, &VT);
+-    }
++       if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
++       {
++	    VT.mode = VT_AUTO;		/* Set default vt handling */
++	    ioctl(xf86Info.consoleFd, VT_SETMODE, &VT);
++        }
+ 
+-    /* Activate the VT that X was started on */
+-    ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86StartVT);
++        /* Activate the VT that X was started on */
++        ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86StartVT);
++    }
+ 
+ #endif /* HAS_USL_VTS */
+ 
+@@ -323,7 +333,7 @@ xf86ProcessArgument(int argc, char **arg
+ 
+     if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+     {
+-	if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
++	if (sscanf(argv[i], "vt%d", &VTnum) == 0)
+ 	{
+ 	    UseMsg();
+ 	    VTnum = -1;
+@@ -349,7 +359,7 @@ xf86ProcessArgument(int argc, char **arg
+ void xf86UseMsg()
+ {
+ #ifdef HAS_USL_VTS
+-    ErrorF("vtXX                   Use the specified VT number\n");
++    ErrorF("vtX                   Use the specified VT number\n");
+ #endif
+     ErrorF("-dev <fb>              Framebuffer device\n");
+     ErrorF("-keeptty               Don't detach controlling tty\n");
+diff -urp -x '*~' -x '*.orig' hw/xfree86/os-support/xf86_OSlib.h hw/xfree86/os-support/xf86_OSlib.h
+--- hw/xfree86/os-support/xf86_OSlib.h	2008-11-15 05:27:05.000000000 +0800
++++ hw/xfree86/os-support/xf86_OSlib.h	2009-08-13 18:00:45.029404000 +0800
+@@ -140,9 +140,8 @@
+ #  include <sys/mmap.h>		/* MMAP driver header */
+ # endif
+ 
+-# if !defined(sun) || (!defined(sparc) && !defined(__SOL8__))
+ #  define HAS_USL_VTS
+-# endif
++
+ # if !defined(sun)
+ #  include <sys/emap.h>
+ # endif
+@@ -155,10 +154,14 @@
+ #  define LED_NUM NLKED
+ #  define LED_SCR SLKED
+ # elif defined(HAS_USL_VTS)
+-#  include <sys/at_ansi.h>
++#  if !defined(sun)
++#   include <sys/at_ansi.h>
++#  endif
+ #  include <sys/kd.h>
+ #  include <sys/vt.h>
+-# elif defined(sun)
++# endif
++
++# if defined(sun)
+ #  include <sys/fbio.h>
+ #  include <sys/kbd.h> 
+ #  include <sys/kbio.h>