summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Zang <Aaron.Zang@Sun.COM>2009-08-03 23:21:39 -0700
committerAlan Coopersmith <alan.coopersmith@sun.com>2009-08-13 21:56:06 -0700
commit48ee5558333bd324463b6994735cabb23de262ec (patch)
tree6e9af7f602bb7bd027c9a0767847928d19fb2ce3
parent613e76ff9055d8ac2b1af1130668180646a9e14c (diff)
Add new VT support for OpenSolaris & future Solaris releases
Signed-off-by: Aaron Zang <Aaron.Zang@Sun.COM> Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
-rw-r--r--configure.ac2
-rw-r--r--hw/xfree86/common/xf86Events.c8
-rw-r--r--hw/xfree86/common/xf86Globals.c3
-rw-r--r--hw/xfree86/common/xf86Privstr.h3
-rw-r--r--hw/xfree86/doc/man/Xorg.man.pre2
-rw-r--r--hw/xfree86/os-support/solaris/Makefile.am4
-rw-r--r--hw/xfree86/os-support/solaris/sun_VTsw.c110
-rw-r--r--hw/xfree86/os-support/solaris/sun_init.c177
-rw-r--r--hw/xfree86/os-support/xf86_OSlib.h11
-rw-r--r--include/xorg-config.h.in3
10 files changed, 229 insertions, 94 deletions
diff --git a/configure.ac b/configure.ac
index 3bdfbab02..ff82d0e14 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1443,6 +1443,7 @@ if test "x$XORG" = xyes; then
# use libpciaccess for PCI
xorg_bus_bsdpci="yes"
AC_CHECK_HEADERS([sys/kd.h])
+ AC_CHECK_HEADERS([sys/vt.h], [solaris_vt=yes], [solaris_vt=no])
# Check for minimum supported release
AC_MSG_CHECKING([Solaris version])
OS_MINOR=`echo ${host_os}|sed -e 's/^.*solaris2\.//' -e s'/\..*$//'`
@@ -1603,6 +1604,7 @@ AM_CONDITIONAL([LINUX_IA64], [test "x$linux_ia64" = xyes])
AM_CONDITIONAL([LINUX_ALPHA], [test "x$linux_alpha" = xyes])
AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes])
AM_CONDITIONAL([SOLARIS_ASM_INLINE], [test "x$solaris_asm_inline" = xyes])
+AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])
AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 58ce15bac..9487fe7b2 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -201,8 +201,16 @@ xf86ProcessActionEvent(ActionEvent action, void *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:
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index df0470c48..d8f7f7f27 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -104,6 +104,9 @@ xf86InfoRec xf86Info = {
.vtSysreq = FALSE,
.lastEventTime = -1,
.vtRequestsPending = FALSE,
+#ifdef sun
+ .vtPendingNum = -1,
+#endif
.dontVTSwitch = FALSE,
.dontZap = FALSE,
.dontZoom = FALSE,
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index 1a2f73637..26f822dc4 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -62,6 +62,9 @@ typedef struct {
/* event handler part */
int lastEventTime;
Bool vtRequestsPending;
+#ifdef sun
+ int vtPendingNum;
+#endif
Bool dontVTSwitch;
Bool dontZap;
Bool dontZoom;
diff --git a/hw/xfree86/doc/man/Xorg.man.pre b/hw/xfree86/doc/man/Xorg.man.pre
index ac4897966..2f9ff98c7 100644
--- a/hw/xfree86/doc/man/Xorg.man.pre
+++ b/hw/xfree86/doc/man/Xorg.man.pre
@@ -134,7 +134,7 @@ will use. Without this option,
.B __xservername__
will pick the first available Virtual Terminal that it can locate. This
option applies only to platforms that have virtual terminal support, such
-as Linux, BSD, SVR3, and SVR4.
+as Linux, BSD, OpenSolaris, SVR3, and SVR4.
.TP
.B \-allowMouseOpenFail
Allow the server to start up even if the mouse device can't be opened
diff --git a/hw/xfree86/os-support/solaris/Makefile.am b/hw/xfree86/os-support/solaris/Makefile.am
index c7ac08bce..5163f4423 100644
--- a/hw/xfree86/os-support/solaris/Makefile.am
+++ b/hw/xfree86/os-support/solaris/Makefile.am
@@ -1,5 +1,5 @@
-if SOLARIS_USL_CONSOLE
-VTSW_SRC = $(srcdir)/../shared/VTsw_usl.c
+if SOLARIS_VT
+VTSW_SRC = sun_VTsw.c
else
VTSW_SRC = $(srcdir)/../shared/VTsw_noop.c
endif
diff --git a/hw/xfree86/os-support/solaris/sun_VTsw.c b/hw/xfree86/os-support/solaris/sun_VTsw.c
new file mode 100644
index 000000000..0dc76b8b5
--- /dev/null
+++ b/hw/xfree86/os-support/solaris/sun_VTsw.c
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+#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/OpenSolaris
+ */
+
+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);
+ }
+}
diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c
index 56f5e7c99..44588dd9f 100644
--- a/hw/xfree86/os-support/solaris/sun_init.c
+++ b/hw/xfree86/os-support/solaris/sun_init.c
@@ -38,9 +38,11 @@ static Bool Protect0 = FALSE;
#ifdef HAS_USL_VTS
static int VTnum = -1;
static int xf86StartVT = -1;
-#endif
-
+static int vtEnabled = 0;
+static char fb_dev[PATH_MAX] = "/dev/vt/0";
+#else
static char fb_dev[PATH_MAX] = "/dev/fb";
+#endif
void
xf86OpenConsole(void)
@@ -89,52 +91,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 (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");
+ }
+ }
- if (!FreeVTslot ||
- (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
- (xf86Info.vtno == -1))
- FatalError("xf86OpenConsole: Cannot find a free VT\n");
+ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+ snprintf(fb_dev, PATH_MAX, "/dev/vt/%d", xf86Info.vtno);
+ }
+ if (fd != -1) {
close(fd);
}
- xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
-
- sprintf(fb_dev, "/dev/vt%02d", xf86Info.vtno); /* Solaris 2.1 x86 */
-
#endif /* HAS_USL_VTS */
if (!KeepTty)
@@ -149,26 +159,32 @@ 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_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_GETMODE, &VT) < 0)
- FatalError("xf86OpenConsole: VT_GETMODE failed\n");
+ OsSignal(SIGUSR1, xf86VTRequest);
- signal(SIGUSR1, xf86VTRequest);
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
- VT.mode = VT_PROCESS;
- VT.relsig = SIGUSR1;
- VT.acqsig = SIGUSR1;
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
- if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
- FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+ if (ioctl(xf86Info.consoleFd, VT_SETDISPINFO, atoi(display)) < 0)
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_SETDISPINFO failed\n");
+ }
#endif
#ifdef KDSETMODE
@@ -183,23 +199,24 @@ 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 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 (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);
+ }
#endif /* HAS_USL_VTS */
}
@@ -263,30 +280,16 @@ xf86CloseConsole(void)
#endif
#ifdef HAS_USL_VTS
+ if (vtEnabled == 1) {
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO; /* Set default vt handling */
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT);
+ }
- /*
- * 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
- * danson@lgc.com
- *
- * Fixed - 12/5/93 - David Holland - davidh@dorite.use.com
- * Did the whole thing similarly to the way linux does it
- */
-
- 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 */
close(xf86Info.consoleFd);
@@ -319,7 +322,7 @@ xf86ProcessArgument(int argc, char **argv, int i)
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;
@@ -345,7 +348,7 @@ xf86ProcessArgument(int argc, char **argv, int i)
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 --git a/hw/xfree86/os-support/xf86_OSlib.h b/hw/xfree86/os-support/xf86_OSlib.h
index 35e1303b9..c53fc0dac 100644
--- a/hw/xfree86/os-support/xf86_OSlib.h
+++ b/hw/xfree86/os-support/xf86_OSlib.h
@@ -134,7 +134,7 @@
# include <sys/mmap.h> /* MMAP driver header */
# endif
-# if !defined(sun)
+# if !defined(sun) || defined(HAVE_SYS_VT_H)
# define HAS_USL_VTS
# endif
# if !defined(sun)
@@ -149,10 +149,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>
@@ -194,7 +198,6 @@
# if defined(sun) && defined(HAS_USL_VTS)
# define USE_VT_SYSREQ
-# define VT_SYSREQ_DEFAULT TRUE
# endif
#endif /* (SYSV || SVR4) */
diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
index 5689f3c19..f62db1742 100644
--- a/include/xorg-config.h.in
+++ b/include/xorg-config.h.in
@@ -57,6 +57,9 @@
/* Define to 1 if you have the <sys/kd.h> header file. */
#undef HAVE_SYS_KD_H
+/* Define to 1 if you have the <sys/vt.h> header file. */
+#undef HAVE_SYS_VT_H
+
/* Define to 1 if you have the `walkcontext' function (used on Solaris for
xorg_backtrace in hw/xfree86/common/xf86Events.c */
#undef HAVE_WALKCONTEXT