From 48ee5558333bd324463b6994735cabb23de262ec Mon Sep 17 00:00:00 2001 From: Aaron Zang Date: Mon, 3 Aug 2009 23:21:39 -0700 Subject: Add new VT support for OpenSolaris & future Solaris releases Signed-off-by: Aaron Zang Signed-off-by: Alan Coopersmith --- configure.ac | 2 + hw/xfree86/common/xf86Events.c | 8 ++ hw/xfree86/common/xf86Globals.c | 3 + hw/xfree86/common/xf86Privstr.h | 3 + hw/xfree86/doc/man/Xorg.man.pre | 2 +- hw/xfree86/os-support/solaris/Makefile.am | 4 +- hw/xfree86/os-support/solaris/sun_VTsw.c | 110 +++++++++++++++++++ hw/xfree86/os-support/solaris/sun_init.c | 177 +++++++++++++++--------------- hw/xfree86/os-support/xf86_OSlib.h | 11 +- include/xorg-config.h.in | 3 + 10 files changed, 229 insertions(+), 94 deletions(-) create mode 100644 hw/xfree86/os-support/solaris/sun_VTsw.c 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 +#endif + +#include + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include +#include + +/* + * 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 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 /* 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 +# if !defined(sun) +# include +# endif # include # include -# elif defined(sun) +# endif + +# if defined(sun) # include # include # include @@ -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 header file. */ #undef HAVE_SYS_KD_H +/* Define to 1 if you have the 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 -- cgit v1.2.3