To: sdl@libsdl.org
authorRyan C. Gordon <icculus@icculus.org>
Tue, 22 Nov 2005 15:19:50 +0000
changeset 118719d8949b4584
parent 1186 0276947bee66
child 1188 f31856cf29ae
To: sdl@libsdl.org
From: Staffan Ulfberg <staffan@ulfberg.se>
Date: 19 Nov 2005 01:00:48 +0100
Subject: [SDL] New driver for OpenBSD/wscons

Hello,

I've written an SDL driver for OpenBSD/wscons (console mode, somewhat
resembling the functionality of the svga driver for Linux). I use it
for playing MAME on my Sharp Zaurus. The alternative is to play under
X, which is slower.

I asked how to submit the driver a few days ago, and posted a link to
the patch in a follow-up, so maybe it was missed?

Anyway, the patch is on the web at:

http://multivac.fatburen.org/SDL-wscons.patch

Comments?

Staffan
README.wscons
configure.in
src/video/Makefile.am
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/wscons/Makefile.am
src/video/wscons/SDL_wsconsevents.c
src/video/wscons/SDL_wsconsevents_c.h
src/video/wscons/SDL_wsconsmouse.c
src/video/wscons/SDL_wsconsmouse_c.h
src/video/wscons/SDL_wsconsvideo.c
src/video/wscons/SDL_wsconsvideo.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/README.wscons	Tue Nov 22 15:19:50 2005 +0000
     1.3 @@ -0,0 +1,107 @@
     1.4 +==============================================================================
     1.5 +Using the Simple DirectMedia Layer with OpenBSD/wscons
     1.6 +==============================================================================
     1.7 +
     1.8 +The wscons SDL driver can be used to run SDL programs on OpenBSD
     1.9 +without running X.  So far, the driver only runs on the Sharp Zaurus,
    1.10 +but the driver is written to be easily extended for other machines.
    1.11 +The main missing pieces are blitting routines for anything but 16 bit
    1.12 +displays, and keycode maps for other keyboards.  Also, there is no
    1.13 +support for hardware palettes.
    1.14 +
    1.15 +There is currently no mouse support.
    1.16 +
    1.17 +To compile SDL with support for wscons, use the
    1.18 +"--enable-video-wscons" option when running configure.  I used the
    1.19 +following command line:
    1.20 +
    1.21 +./configure --disable-oss --disable-ltdl --enable-pthread-sem \
    1.22 +	    --disable-esd --disable-arts --disable-video-aalib  \
    1.23 +	    --enable-openbsdaudio --enable-video-wscons \
    1.24 +	    --prefix=/usr/local --sysconfdir=/etc
    1.25 +
    1.26 +
    1.27 +Setting the console device to use
    1.28 +=================================
    1.29 +
    1.30 +When starting an SDL program on a wscons console, the driver uses the
    1.31 +current virtual terminal (usually /dev/ttyC0).  To force the driver to
    1.32 +use a specific terminal device, set the environment variable
    1.33 +SDL_WSCONSDEV:
    1.34 +
    1.35 +bash$ SDL_WSCONSDEV=/dev/ttyC1 ./some-sdl-program
    1.36 +
    1.37 +This is especially useful when starting an SDL program from a remote
    1.38 +login prompt (which is great for development).  If you do this, and
    1.39 +want to use keyboard input, you should avoid having some other program
    1.40 +reading from the used virtual console (i.e., do not have a getty
    1.41 +running).
    1.42 +
    1.43 +
    1.44 +Rotating the display
    1.45 +====================
    1.46 +
    1.47 +The display can be rotated by the wscons SDL driver.  This is useful
    1.48 +for the Sharp Zaurus, since the display hardware is wired so that it
    1.49 +is correctly rotated only when the display is folded into "PDA mode."
    1.50 +When using the Zaurus in "normal," or "keyboard" mode, the hardware
    1.51 +screen is rotated 90 degrees anti-clockwise.
    1.52 +
    1.53 +To let the wscons SDL driver rotate the screen, set the environment
    1.54 +variable SDL_VIDEO_WSCONS_ROTATION to "CW", "CCW", or "UD", for
    1.55 +clockwise, counter clockwise, and upside-down rotation respectively.
    1.56 +"CW" makes the screen appear correct on a Sharp Zaurus SL-C3100.
    1.57 +
    1.58 +When using rotation in the driver, a "shadow" frame buffer is used to
    1.59 +hold the intermediary display, before blitting it to the actual
    1.60 +hardware frame buffer.  This slows down performance a bit.
    1.61 +
    1.62 +For completeness, the rotation "NONE" can be specified to use a shadow
    1.63 +frame buffer without actually rotating.  Unsetting
    1.64 +SDL_VIDEO_WSCONS_ROTATION, or setting it to '' turns off the shadow
    1.65 +frame buffer for maximum performance.
    1.66 +
    1.67 +
    1.68 +Running MAME
    1.69 +============
    1.70 +
    1.71 +Since my main motivation for writing the driver was playing MAME on
    1.72 +the Zaurus, I'll give a few hints:
    1.73 +
    1.74 +XMame compiles just fine under OpenBSD.
    1.75 +
    1.76 +I'm not sure this is strictly necessary, but set
    1.77 +
    1.78 +MY_CPU = arm
    1.79 +
    1.80 +in makefile.unix, and
    1.81 +
    1.82 +CFLAGS.arm = -DLSB_FIRST -DALIGN_INTS -DALIGN_SHORTS
    1.83 +
    1.84 +in src/unix/unix.max
    1.85 +
    1.86 +to be sure.
    1.87 +
    1.88 +The latest XMame (0.101 at this writing) is a very large program.
    1.89 +Either tinker with the make files to compile a version without support
    1.90 +for all drivers, or, get an older version of XMame.  My recommendation
    1.91 +would be 0.37b16.
    1.92 +
    1.93 +When running MAME, DO NOT SET SDL_VIDEO_WSCONS_ROTATION!  Performace
    1.94 +is MUCH better without this, and it is COMPLETELY UNNECESSARY, since
    1.95 +MAME can rotate the picture itself while drawing, and does so MUCH
    1.96 +FASTER.
    1.97 +
    1.98 +Use the Xmame command line option "-ror" to rotate the picture to the
    1.99 +right.
   1.100 +
   1.101 +
   1.102 +Acknowledgments
   1.103 +===============
   1.104 +
   1.105 +I studied the wsfb driver for XFree86/Xorg quite a bit before writing
   1.106 +this, so there ought to be some similarities.
   1.107 +
   1.108 +
   1.109 +--
   1.110 +Staffan Ulfberg <staffan@ulfberg.se>
     2.1 --- a/configure.in	Tue Nov 22 15:11:33 2005 +0000
     2.2 +++ b/configure.in	Tue Nov 22 15:19:50 2005 +0000
     2.3 @@ -1645,6 +1645,37 @@
     2.4      fi
     2.5  }
     2.6  
     2.7 +dnl Set up the wscons video driver if enabled
     2.8 +CheckWscons()
     2.9 +{
    2.10 +    AC_ARG_ENABLE(video-wscons,
    2.11 +[  --enable-video-wscons   use wscons video driver [default=no]],
    2.12 +                  , enable_video_wscons=no)
    2.13 +    if test x$enable_video = xyes -a x$enable_video_wscons = xyes; then
    2.14 +        AC_MSG_CHECKING(for wscons support)
    2.15 +        video_wscons=no
    2.16 +        AC_LANG_C
    2.17 +        AC_TRY_COMPILE([
    2.18 +       #include <sys/time.h>
    2.19 +       #include <dev/wscons/wsconsio.h>
    2.20 +        ],[
    2.21 +        ],[
    2.22 +        video_wscons=yes
    2.23 +        ])
    2.24 +        AC_MSG_RESULT($video_wscons)
    2.25 +        if test x$video_wscons = xyes; then
    2.26 +            CFLAGS="$CFLAGS -DENABLE_WSCONS"
    2.27 +            VIDEO_SUBDIRS="$VIDEO_SUBDIRS wscons"
    2.28 +            VIDEO_DRIVERS="$VIDEO_DRIVERS wscons/libvideo_wscons.la"
    2.29 +        else
    2.30 +      AC_MSG_ERROR([
    2.31 +*** Failed to find wscons includes.])
    2.32 +        fi
    2.33 +      AC_LANG_C
    2.34 +    fi
    2.35 +}
    2.36 +
    2.37 +
    2.38  dnl Set up the PicoGUI video driver if enabled
    2.39  CheckPicoGUI()
    2.40  {
    2.41 @@ -2210,6 +2241,7 @@
    2.42          CheckNAS
    2.43          CheckX11
    2.44          CheckAAlib
    2.45 +	CheckWscons
    2.46          CheckOpenGL
    2.47          CheckPTHREAD
    2.48          CheckSIGACTION
    2.49 @@ -3088,6 +3120,7 @@
    2.50  src/video/picogui/Makefile
    2.51  src/video/ps2gs/Makefile
    2.52  src/video/qtopia/Makefile
    2.53 +src/video/wscons/Makefile
    2.54  src/video/quartz/Makefile
    2.55  src/video/riscos/Makefile
    2.56  src/video/svga/Makefile
     3.1 --- a/src/video/Makefile.am	Tue Nov 22 15:11:33 2005 +0000
     3.2 +++ b/src/video/Makefile.am	Tue Nov 22 15:19:50 2005 +0000
     3.3 @@ -9,7 +9,7 @@
     3.4                 wincommon windib windx5 \
     3.5                 maccommon macdsp macrom riscos quartz \
     3.6                 bwindow ps2gs photon cybergfx epoc picogui \
     3.7 -               ataricommon xbios gem dc qtopia XFree86
     3.8 +               ataricommon xbios gem dc qtopia XFree86 wscons
     3.9  
    3.10  DRIVERS = @VIDEO_DRIVERS@
    3.11  
     4.1 --- a/src/video/SDL_sysvideo.h	Tue Nov 22 15:11:33 2005 +0000
     4.2 +++ b/src/video/SDL_sysvideo.h	Tue Nov 22 15:19:50 2005 +0000
     4.3 @@ -411,6 +411,9 @@
     4.4  #ifdef ENABLE_QTOPIA
     4.5  extern VideoBootStrap Qtopia_bootstrap;
     4.6  #endif
     4.7 +#ifdef ENABLE_WSCONS
     4.8 +extern VideoBootStrap WSCONS_bootstrap;
     4.9 +#endif
    4.10  #ifdef ENABLE_PICOGUI
    4.11  extern VideoBootStrap PG_bootstrap;
    4.12  #endif
     5.1 --- a/src/video/SDL_video.c	Tue Nov 22 15:11:33 2005 +0000
     5.2 +++ b/src/video/SDL_video.c	Tue Nov 22 15:19:50 2005 +0000
     5.3 @@ -63,6 +63,9 @@
     5.4  #ifdef ENABLE_QTOPIA
     5.5  	&Qtopia_bootstrap,
     5.6  #endif
     5.7 +#ifdef ENABLE_WSCONS
     5.8 +	&WSCONS_bootstrap,
     5.9 +#endif
    5.10  #ifdef ENABLE_FBCON
    5.11  	&FBCON_bootstrap,
    5.12  #endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/video/wscons/Makefile.am	Tue Nov 22 15:19:50 2005 +0000
     6.3 @@ -0,0 +1,14 @@
     6.4 +## Makefile.am for SDL using the wscons video driver
     6.5 +
     6.6 +noinst_LTLIBRARIES = libvideo_wscons.la
     6.7 +libvideo_wscons_la_SOURCES = $(WSCONS_SRCS)
     6.8 +
     6.9 +# The SDL wscons video driver sources
    6.10 +WSCONS_SRCS = 			\
    6.11 +	SDL_wsconsvideo.h	\
    6.12 +	SDL_wsconsevents.c	\
    6.13 +	SDL_wsconsevents_c.h	\
    6.14 +	SDL_wsconsmouse.c	\
    6.15 +	SDL_wsconsmouse_c.h	\
    6.16 +	SDL_wsconsvideo.c
    6.17 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/video/wscons/SDL_wsconsevents.c	Tue Nov 22 15:19:50 2005 +0000
     7.3 @@ -0,0 +1,236 @@
     7.4 +/*
     7.5 +    SDL - Simple DirectMedia Layer
     7.6 +    Copyright (C) 1997-2004 Sam Lantinga
     7.7 +
     7.8 +    This library is free software; you can redistribute it and/or
     7.9 +    modify it under the terms of the GNU Library General Public
    7.10 +    License as published by the Free Software Foundation; either
    7.11 +    version 2 of the License, or (at your option) any later version.
    7.12 +
    7.13 +    This library is distributed in the hope that it will be useful,
    7.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7.16 +    Library General Public License for more details.
    7.17 +
    7.18 +    You should have received a copy of the GNU Library General Public
    7.19 +    License along with this library; if not, write to the Free
    7.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.21 +
    7.22 +    Sam Lantinga
    7.23 +    slouken@libsdl.org
    7.24 +*/
    7.25 +
    7.26 +#ifdef SAVE_RCSID
    7.27 +static char rcsid =
    7.28 + "@(#) $Id$";
    7.29 +#endif
    7.30 +
    7.31 +#include <sys/types.h>
    7.32 +#include <dev/wscons/wsdisplay_usl_io.h>
    7.33 +#include <sys/ioctl.h>
    7.34 +#include <fcntl.h>    
    7.35 +#include <unistd.h>  
    7.36 +#include <termios.h>
    7.37 +#include <errno.h> 
    7.38 +#include <string.h>
    7.39 +
    7.40 +#include "SDL.h"
    7.41 +#include "SDL_sysevents.h"
    7.42 +#include "SDL_events_c.h"
    7.43 +#include "SDL_wsconsvideo.h"
    7.44 +#include "SDL_wsconsevents_c.h"
    7.45 +
    7.46 +static int posted = 0;
    7.47 +
    7.48 +int WSCONS_InitKeyboard(_THIS)
    7.49 +{
    7.50 +  struct termios tty;
    7.51 +
    7.52 +  if (ioctl(private->fd, WSKBDIO_GTYPE, &private->kbdType) == -1) {
    7.53 +    WSCONS_ReportError("cannot get keyboard type: %s", strerror(errno));
    7.54 +    return -1;
    7.55 +  }
    7.56 +
    7.57 +  if (tcgetattr(private->fd, &private->saved_tty) == -1) {
    7.58 +    WSCONS_ReportError("cannot get terminal attributes: %s", strerror(errno));
    7.59 +    return -1;
    7.60 +  }
    7.61 +  private->did_save_tty = 1;
    7.62 +  tty = private->saved_tty;
    7.63 +  tty.c_iflag = IGNPAR | IGNBRK;
    7.64 +  tty.c_oflag = 0;
    7.65 +  tty.c_cflag = CREAD | CS8;
    7.66 +  tty.c_lflag = 0;
    7.67 +  tty.c_cc[VTIME] = 0;
    7.68 +  tty.c_cc[VMIN] = 1;
    7.69 +  cfsetispeed(&tty, 9600);
    7.70 +  cfsetospeed(&tty, 9600);
    7.71 +  if (tcsetattr(private->fd, TCSANOW, &tty) < 0) {
    7.72 +    WSCONS_ReportError("cannot set terminal attributes: %s", strerror(errno));
    7.73 +    return -1;
    7.74 +  }
    7.75 +  if (ioctl(private->fd, KDSKBMODE, K_RAW) == -1) {
    7.76 +    WSCONS_ReportError("cannot set raw keyboard mode: %s", strerror(errno));
    7.77 +    return -1;
    7.78 +  }
    7.79 +
    7.80 +  return 0;
    7.81 +}
    7.82 +
    7.83 +void WSCONS_ReleaseKeyboard(_THIS)
    7.84 +{
    7.85 +  if (private->fd != -1) {
    7.86 +    if (ioctl(private->fd, KDSKBMODE, K_XLATE) == -1) {
    7.87 +      WSCONS_ReportError("cannot restore keyboard to translated mode: %s",
    7.88 +			 strerror(errno));
    7.89 +    }
    7.90 +    if (private->did_save_tty) {
    7.91 +      if (tcsetattr(private->fd, TCSANOW, &private->saved_tty) < 0) {
    7.92 +	WSCONS_ReportError("cannot restore keynoard attributes: %s",
    7.93 +			   strerror(errno));
    7.94 +      }
    7.95 +    }
    7.96 +  }
    7.97 +}
    7.98 +
    7.99 +static void updateMouse()
   7.100 +{
   7.101 +}
   7.102 +
   7.103 +static SDLKey keymap[128];
   7.104 +
   7.105 +static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
   7.106 +{
   7.107 +  keysym->scancode = scancode;
   7.108 +  keysym->sym = SDLK_UNKNOWN;
   7.109 +  keysym->mod = KMOD_NONE;
   7.110 +
   7.111 +  if (scancode < SDL_TABLESIZE(keymap))
   7.112 +    keysym->sym = keymap[scancode];
   7.113 +
   7.114 +  if (keysym->sym == SDLK_UNKNOWN)
   7.115 +    printf("Unknown mapping for scancode %d\n", scancode);
   7.116 +
   7.117 +  return keysym;
   7.118 +}
   7.119 +
   7.120 +static void updateKeyboard(_THIS)
   7.121 +{
   7.122 +  unsigned char buf[100];
   7.123 +  SDL_keysym keysym;
   7.124 +  int n, i;
   7.125 +
   7.126 +  if ((n = read(private->fd, buf, sizeof(buf))) > 0) {
   7.127 +    for (i = 0; i < n; i++) {
   7.128 +      char c = buf[i] & 0x7f;
   7.129 +      if (c == 224) // special key prefix -- what should we do with it?
   7.130 +	continue;
   7.131 +      int release = (buf[i] & 0x80) != 0;
   7.132 +      posted += SDL_PrivateKeyboard(release ? SDL_RELEASED : SDL_PRESSED,
   7.133 +				    TranslateKey(c, &keysym));
   7.134 +    }
   7.135 +  }
   7.136 +}
   7.137 +
   7.138 +void WSCONS_PumpEvents(_THIS)
   7.139 +{
   7.140 +  do {
   7.141 +    posted = 0;
   7.142 +    updateMouse();
   7.143 +    updateKeyboard(this);
   7.144 +  } while (posted);
   7.145 +}
   7.146 +
   7.147 +void WSCONS_InitOSKeymap(_THIS)
   7.148 +{
   7.149 +  int i;
   7.150 +
   7.151 +  /* Make sure unknown keys are mapped correctly */
   7.152 +  for (i=0; i < SDL_TABLESIZE(keymap); i++) {
   7.153 +    keymap[i] = SDLK_UNKNOWN;
   7.154 +  }
   7.155 +
   7.156 +  switch (private->kbdType) {
   7.157 +  case WSKBD_TYPE_ZAURUS:
   7.158 +    /* top row */
   7.159 +    keymap[2] = SDLK_1;
   7.160 +    keymap[3] = SDLK_2;
   7.161 +    keymap[4] = SDLK_3;
   7.162 +    keymap[5] = SDLK_4;
   7.163 +    keymap[6] = SDLK_5;
   7.164 +    keymap[7] = SDLK_6;
   7.165 +    keymap[8] = SDLK_7;
   7.166 +    keymap[9] = SDLK_8;
   7.167 +    keymap[10] = SDLK_9;
   7.168 +    keymap[11] = SDLK_0;
   7.169 +    keymap[14] = SDLK_BACKSPACE;
   7.170 +    
   7.171 +    /* second row */
   7.172 +    keymap[16] = SDLK_q;
   7.173 +    keymap[17] = SDLK_w;
   7.174 +    keymap[18] = SDLK_e;
   7.175 +    keymap[19] = SDLK_r;
   7.176 +    keymap[20] = SDLK_t;
   7.177 +    keymap[21] = SDLK_y;
   7.178 +    keymap[22] = SDLK_u;
   7.179 +    keymap[23] = SDLK_i;
   7.180 +    keymap[24] = SDLK_o;
   7.181 +    keymap[25] = SDLK_p;
   7.182 +
   7.183 +    /* third row */
   7.184 +    keymap[15] = SDLK_TAB;
   7.185 +    keymap[30] = SDLK_a;
   7.186 +    keymap[31] = SDLK_s;
   7.187 +    keymap[32] = SDLK_d;
   7.188 +    keymap[33] = SDLK_f;
   7.189 +    keymap[34] = SDLK_g;
   7.190 +    keymap[35] = SDLK_h;
   7.191 +    keymap[36] = SDLK_j;
   7.192 +    keymap[37] = SDLK_k;
   7.193 +    keymap[38] = SDLK_l;
   7.194 +
   7.195 +    /* fourth row */
   7.196 +    keymap[42] = SDLK_LSHIFT;
   7.197 +    keymap[44] = SDLK_z;
   7.198 +    keymap[45] = SDLK_x;
   7.199 +    keymap[46] = SDLK_c;
   7.200 +    keymap[47] = SDLK_v;
   7.201 +    keymap[48] = SDLK_b;
   7.202 +    keymap[49] = SDLK_n;
   7.203 +    keymap[50] = SDLK_m;
   7.204 +    keymap[54] = SDLK_RSHIFT;
   7.205 +    keymap[28] = SDLK_RETURN;
   7.206 +
   7.207 +    /* fifth row */
   7.208 +    keymap[56] = SDLK_LALT;
   7.209 +    keymap[29] = SDLK_LCTRL;
   7.210 +    /* keymap[56] = ; */
   7.211 +    keymap[0] = SDLK_LSUPER;
   7.212 +    keymap[12] = SDLK_MINUS;
   7.213 +    keymap[57] = SDLK_SPACE;
   7.214 +    keymap[51] = SDLK_COMMA;
   7.215 +    keymap[52] = SDLK_PERIOD;
   7.216 +
   7.217 +    /* misc */
   7.218 +    keymap[59] = SDLK_F1;
   7.219 +    keymap[60] = SDLK_F2;
   7.220 +    keymap[61] = SDLK_F3;
   7.221 +    keymap[62] = SDLK_F4;
   7.222 +    keymap[63] = SDLK_F5;
   7.223 +    keymap[1] = SDLK_ESCAPE;
   7.224 +    /* keymap[28] = SDLK_KP_ENTER; */
   7.225 +    keymap[72] = SDLK_UP;
   7.226 +    keymap[75] = SDLK_LEFT;
   7.227 +    keymap[77] = SDLK_RIGHT;
   7.228 +    keymap[80] = SDLK_DOWN;
   7.229 +    break;
   7.230 +
   7.231 +  default:
   7.232 +    WSCONS_ReportError("Unable to map keys for keyboard type %u", 
   7.233 +		       private->kbdType);
   7.234 +    break;
   7.235 +  }
   7.236 +}
   7.237 +
   7.238 +/* end of SDL_wsconsevents.c ... */
   7.239 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/video/wscons/SDL_wsconsevents_c.h	Tue Nov 22 15:19:50 2005 +0000
     8.3 @@ -0,0 +1,40 @@
     8.4 +/*
     8.5 +    SDL - Simple DirectMedia Layer
     8.6 +    Copyright (C) 1997-2004 Sam Lantinga
     8.7 +
     8.8 +    This library is free software; you can redistribute it and/or
     8.9 +    modify it under the terms of the GNU Library General Public
    8.10 +    License as published by the Free Software Foundation; either
    8.11 +    version 2 of the License, or (at your option) any later version.
    8.12 +
    8.13 +    This library is distributed in the hope that it will be useful,
    8.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.16 +    Library General Public License for more details.
    8.17 +
    8.18 +    You should have received a copy of the GNU Library General Public
    8.19 +    License along with this library; if not, write to the Free
    8.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.21 +
    8.22 +    Sam Lantinga
    8.23 +    slouken@libsdl.org
    8.24 +*/
    8.25 +
    8.26 +#ifdef SAVE_RCSID
    8.27 +static char rcsid =
    8.28 + "@(#) $Id$";
    8.29 +#endif
    8.30 +
    8.31 +#include "SDL_wsconsvideo.h"
    8.32 +
    8.33 +int WSCONS_InitKeyboard(_THIS);
    8.34 +void WSCONS_ReleaseKeyboard(_THIS);
    8.35 +
    8.36 +/* Variables and functions exported by SDL_sysevents.c to other parts 
    8.37 +   of the native video subsystem (SDL_sysvideo.c)
    8.38 +*/
    8.39 +extern void WSCONS_InitOSKeymap(_THIS);
    8.40 +extern void WSCONS_PumpEvents(_THIS);
    8.41 +
    8.42 +/* end of SDL_wsconsevents_c.h ... */
    8.43 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/video/wscons/SDL_wsconsmouse.c	Tue Nov 22 15:19:50 2005 +0000
     9.3 @@ -0,0 +1,40 @@
     9.4 +/*
     9.5 +    SDL - Simple DirectMedia Layer
     9.6 +    Copyright (C) 1997-2004 Sam Lantinga
     9.7 +
     9.8 +    This library is free software; you can redistribute it and/or
     9.9 +    modify it under the terms of the GNU Library General Public
    9.10 +    License as published by the Free Software Foundation; either
    9.11 +    version 2 of the License, or (at your option) any later version.
    9.12 +
    9.13 +    This library is distributed in the hope that it will be useful,
    9.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.16 +    Library General Public License for more details.
    9.17 +
    9.18 +    You should have received a copy of the GNU Library General Public
    9.19 +    License along with this library; if not, write to the Free
    9.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    9.21 +
    9.22 +    Sam Lantinga
    9.23 +    slouken@libsdl.org
    9.24 +*/
    9.25 +
    9.26 +#ifdef SAVE_RCSID
    9.27 +static char rcsid =
    9.28 + "@(#) $Id$";
    9.29 +#endif
    9.30 +
    9.31 +#include <stdio.h>
    9.32 +
    9.33 +#include "SDL_error.h"
    9.34 +#include "SDL_mouse.h"
    9.35 +#include "SDL_events_c.h"
    9.36 +
    9.37 +#include "SDL_wsconsmouse_c.h"
    9.38 +
    9.39 +
    9.40 +/* The implementation dependent data for the window manager cursor */
    9.41 +struct WMcursor {
    9.42 +	int unused;
    9.43 +};
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/video/wscons/SDL_wsconsmouse_c.h	Tue Nov 22 15:19:50 2005 +0000
    10.3 @@ -0,0 +1,30 @@
    10.4 +/*
    10.5 +    SDL - Simple DirectMedia Layer
    10.6 +    Copyright (C) 1997-2004 Sam Lantinga
    10.7 +
    10.8 +    This library is free software; you can redistribute it and/or
    10.9 +    modify it under the terms of the GNU Library General Public
   10.10 +    License as published by the Free Software Foundation; either
   10.11 +    version 2 of the License, or (at your option) any later version.
   10.12 +
   10.13 +    This library is distributed in the hope that it will be useful,
   10.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   10.16 +    Library General Public License for more details.
   10.17 +
   10.18 +    You should have received a copy of the GNU Library General Public
   10.19 +    License along with this library; if not, write to the Free
   10.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   10.21 +
   10.22 +    Sam Lantinga
   10.23 +    slouken@libsdl.org
   10.24 +*/
   10.25 +
   10.26 +#ifdef SAVE_RCSID
   10.27 +static char rcsid =
   10.28 + "@(#) $Id$";
   10.29 +#endif
   10.30 +
   10.31 +#include "SDL_wsconsvideo.h"
   10.32 +
   10.33 +/* Functions to be exported */
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/video/wscons/SDL_wsconsvideo.c	Tue Nov 22 15:19:50 2005 +0000
    11.3 @@ -0,0 +1,614 @@
    11.4 +/*
    11.5 +    SDL - Simple DirectMedia Layer
    11.6 +    Copyright (C) 1997-2004 Sam Lantinga
    11.7 +
    11.8 +    This library is free software; you can redistribute it and/or
    11.9 +    modify it under the terms of the GNU Library General Public
   11.10 +    License as published by the Free Software Foundation; either
   11.11 +    version 2 of the License, or (at your option) any later version.
   11.12 +
   11.13 +    This library is distributed in the hope that it will be useful,
   11.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   11.16 +    Library General Public License for more details.
   11.17 +
   11.18 +    You should have received a copy of the GNU Library General Public
   11.19 +    License along with this library; if not, write to the Free
   11.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   11.21 +
   11.22 +    Sam Lantinga
   11.23 +    slouken@libsdl.org
   11.24 +*/
   11.25 +
   11.26 +#ifdef SAVE_RCSID
   11.27 +static char rcsid =
   11.28 + "@(#) $Id$";
   11.29 +#endif
   11.30 +
   11.31 +#include <sys/time.h>
   11.32 +#include <sys/mman.h>
   11.33 +#include <sys/ioctl.h>
   11.34 +#include <dev/wscons/wsdisplay_usl_io.h>
   11.35 +#include <fcntl.h>
   11.36 +#include <unistd.h>
   11.37 +#include <stdio.h>
   11.38 +#include <stdlib.h>
   11.39 +#include <string.h>
   11.40 +#include <stdarg.h>
   11.41 +#include <errno.h>
   11.42 +
   11.43 +#include "SDL.h"
   11.44 +#include "SDL_error.h"
   11.45 +#include "SDL_video.h"
   11.46 +#include "SDL_mouse.h"
   11.47 +#include "SDL_sysvideo.h"
   11.48 +#include "SDL_pixels_c.h"
   11.49 +#include "SDL_events_c.h"
   11.50 +
   11.51 +#include "SDL_wsconsvideo.h"
   11.52 +#include "SDL_wsconsevents_c.h"
   11.53 +#include "SDL_wsconsmouse_c.h"
   11.54 +
   11.55 +#define WSCONSVID_DRIVER_NAME "wscons"
   11.56 +enum {
   11.57 +  WSCONS_ROTATE_NONE = 0,
   11.58 +  WSCONS_ROTATE_CCW = 90,
   11.59 +  WSCONS_ROTATE_UD = 180,
   11.60 +  WSCONS_ROTATE_CW = 270
   11.61 +};
   11.62 +
   11.63 +#define min(a,b) ((a)<(b)?(a):(b))
   11.64 +
   11.65 +/* Initialization/Query functions */
   11.66 +static int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat);
   11.67 +static SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
   11.68 +static SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
   11.69 +static int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
   11.70 +static void WSCONS_VideoQuit(_THIS);
   11.71 +
   11.72 +/* Hardware surface functions */
   11.73 +static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface);
   11.74 +static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface);
   11.75 +static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface);
   11.76 +static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface);
   11.77 +
   11.78 +/* etc. */
   11.79 +static WSCONS_bitBlit WSCONS_blit16;
   11.80 +static WSCONS_bitBlit WSCONS_blit16blocked;
   11.81 +static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
   11.82 +
   11.83 +void WSCONS_ReportError(char *fmt, ...)
   11.84 +{
   11.85 +  char message[200];
   11.86 +  
   11.87 +  message[199] = '\0';
   11.88 +  
   11.89 +  va_list vaArgs;
   11.90 +  va_start(vaArgs, fmt);
   11.91 +  vsnprintf(message, 199, fmt, vaArgs);
   11.92 +  va_end(vaArgs);
   11.93 +
   11.94 +  SDL_SetError(message); 
   11.95 +  fprintf(stderr, "WSCONS error: %s\n", message);
   11.96 +}
   11.97 +
   11.98 +/* WSCONS driver bootstrap functions */
   11.99 +
  11.100 +static int WSCONS_Available(void)
  11.101 +{
  11.102 +  return 1;
  11.103 +}
  11.104 +
  11.105 +static void WSCONS_DeleteDevice(SDL_VideoDevice *device)
  11.106 +{
  11.107 +  free(device->hidden);
  11.108 +  free(device);
  11.109 +}
  11.110 +
  11.111 +static SDL_VideoDevice *WSCONS_CreateDevice(int devindex)
  11.112 +{
  11.113 +  SDL_VideoDevice *device;
  11.114 +  
  11.115 +  /* Initialize all variables that we clean on shutdown */
  11.116 +  device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
  11.117 +  if (device == NULL) {
  11.118 +    SDL_OutOfMemory();
  11.119 +    return 0;
  11.120 +  }
  11.121 +  memset(device, 0, (sizeof *device));
  11.122 +  device->hidden = 
  11.123 +    (struct SDL_PrivateVideoData *)malloc((sizeof *device->hidden));
  11.124 +  if (device->hidden == NULL) {
  11.125 +    SDL_OutOfMemory();
  11.126 +    free(device);
  11.127 +    return(0);
  11.128 +  }
  11.129 +  memset(device->hidden, 0, (sizeof *device->hidden));
  11.130 +  device->hidden->fd = -1;
  11.131 +  
  11.132 +  /* Set the function pointers */
  11.133 +  device->VideoInit = WSCONS_VideoInit;
  11.134 +  device->ListModes = WSCONS_ListModes;
  11.135 +  device->SetVideoMode = WSCONS_SetVideoMode;
  11.136 +  device->SetColors = WSCONS_SetColors;
  11.137 +  device->UpdateRects = WSCONS_UpdateRects;
  11.138 +  device->VideoQuit = WSCONS_VideoQuit;
  11.139 +  device->AllocHWSurface = WSCONS_AllocHWSurface;
  11.140 +  device->LockHWSurface = WSCONS_LockHWSurface;
  11.141 +  device->UnlockHWSurface = WSCONS_UnlockHWSurface;
  11.142 +  device->FreeHWSurface = WSCONS_FreeHWSurface;
  11.143 +  device->InitOSKeymap = WSCONS_InitOSKeymap;
  11.144 +  device->PumpEvents = WSCONS_PumpEvents;
  11.145 +  device->free = WSCONS_DeleteDevice;
  11.146 +  
  11.147 +  return device;
  11.148 +}
  11.149 +
  11.150 +VideoBootStrap WSCONS_bootstrap = {
  11.151 +  WSCONSVID_DRIVER_NAME,
  11.152 +  "SDL wscons video driver",
  11.153 +  WSCONS_Available,
  11.154 +  WSCONS_CreateDevice
  11.155 +};
  11.156 +
  11.157 +#define WSCONSDEV_FORMAT "/dev/ttyC%01x"
  11.158 +
  11.159 +int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat)
  11.160 +{
  11.161 +  char devnamebuf[30];
  11.162 +  char *devname;
  11.163 +  char *rotation;
  11.164 +  int wstype;
  11.165 +  int wsmode = WSDISPLAYIO_MODE_DUMBFB;
  11.166 +  size_t len, mapsize;
  11.167 +  int pagemask;
  11.168 +  int width, height;
  11.169 +  
  11.170 +  devname = getenv("SDL_WSCONSDEV");
  11.171 +  if (devname == NULL) {
  11.172 +    int activeVT;
  11.173 +    if (ioctl(STDIN_FILENO, VT_GETACTIVE, &activeVT) == -1) {
  11.174 +      WSCONS_ReportError("Unable to determine active terminal: %s", 
  11.175 +			 strerror(errno));
  11.176 +      return -1;
  11.177 +    }
  11.178 +    snprintf(devnamebuf, sizeof(devnamebuf), WSCONSDEV_FORMAT, activeVT - 1);
  11.179 +    devname = devnamebuf;
  11.180 +  }
  11.181 +
  11.182 +  private->fd = open(devname, O_RDWR | O_NONBLOCK, 0);
  11.183 +  if (private->fd == -1) {
  11.184 +    WSCONS_ReportError("open %s: %s", devname, strerror(errno));
  11.185 +    return -1;
  11.186 +  }
  11.187 +  if (ioctl(private->fd, WSDISPLAYIO_GINFO, &private->info) == -1) {
  11.188 +    WSCONS_ReportError("ioctl WSDISPLAY_GINFO: %s", strerror(errno));
  11.189 +    return -1;
  11.190 +  }
  11.191 +  if (ioctl(private->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) {
  11.192 +    WSCONS_ReportError("ioctl WSDISPLAY_GTYPE: %s", strerror(errno));
  11.193 +    return -1;
  11.194 +  }
  11.195 +  if (ioctl(private->fd, WSDISPLAYIO_LINEBYTES, &private->physlinebytes) == -1) {
  11.196 +    WSCONS_ReportError("ioctl WSDISPLAYIO_LINEBYTES: %s", strerror(errno));
  11.197 +    return -1;
  11.198 +  }
  11.199 +  if (private->info.depth > 8) {
  11.200 +    if (wstype == WSDISPLAY_TYPE_SUN24 ||
  11.201 +	wstype == WSDISPLAY_TYPE_SUNCG12 ||
  11.202 +	wstype == WSDISPLAY_TYPE_SUNCG14 ||
  11.203 +	wstype == WSDISPLAY_TYPE_SUNTCX ||
  11.204 +	wstype == WSDISPLAY_TYPE_SUNFFB) {
  11.205 +      private->redMask = 0x0000ff;
  11.206 +      private->greenMask = 0x00ff00;
  11.207 +      private->blueMask = 0xff0000;
  11.208 +    } else if (wstype == WSDISPLAY_TYPE_PXALCD) {
  11.209 +      private->redMask = 0x1f << 11;
  11.210 +      private->greenMask = 0x3f << 5;
  11.211 +      private->blueMask = 0x1f;
  11.212 +    } else {
  11.213 +      WSCONS_ReportError("Unknown video hardware");
  11.214 +      return -1;
  11.215 +    }
  11.216 +  } else {
  11.217 +    WSCONS_ReportError("Displays with 8 bpp or less are not supported");
  11.218 +    return -1;
  11.219 +  }
  11.220 +  
  11.221 +  private->rotate = WSCONS_ROTATE_NONE;
  11.222 +  rotation = getenv("SDL_VIDEO_WSCONS_ROTATION");
  11.223 +  if (rotation != NULL) {
  11.224 +    if (strlen(rotation) == 0) {
  11.225 +      private->shadowFB = 0;
  11.226 +      private->rotate = WSCONS_ROTATE_NONE;
  11.227 +      printf("Not rotating, no shadow\n");
  11.228 +    } else if (!strcmp(rotation, "NONE")) {
  11.229 +      private->shadowFB = 1;
  11.230 +      private->rotate = WSCONS_ROTATE_NONE;
  11.231 +      printf("Not rotating, but still using shadow\n");
  11.232 +    } else if (!strcmp(rotation, "CW")) {
  11.233 +      private->shadowFB = 1;
  11.234 +      private->rotate = WSCONS_ROTATE_CW;
  11.235 +      printf("Rotating screen clockwise\n");
  11.236 +    } else if (!strcmp(rotation, "CCW")) {
  11.237 +      private->shadowFB = 1;
  11.238 +      private->rotate = WSCONS_ROTATE_CCW;
  11.239 +      printf("Rotating screen counter clockwise\n");
  11.240 +    } else if (!strcmp(rotation, "UD")) {
  11.241 +      private->shadowFB = 1;
  11.242 +      private->rotate = WSCONS_ROTATE_UD;
  11.243 +      printf("Rotating screen upside down\n");
  11.244 +    } else {
  11.245 +      WSCONS_ReportError("\"%s\" is not a valid value for "
  11.246 +			 "SDL_VIDEO_WSCONS_ROTATION", rotation);
  11.247 +      return -1;
  11.248 +    }
  11.249 +  }
  11.250 +
  11.251 +  switch (private->info.depth) {
  11.252 +    case 1:
  11.253 +    case 4:
  11.254 +    case 8:
  11.255 +      len = private->physlinebytes * private->info.height;
  11.256 +      break;
  11.257 +    case 16:
  11.258 +      if (private->physlinebytes == private->info.width) {
  11.259 +	len = private->info.width * private->info.height * sizeof(short);
  11.260 +      } else {
  11.261 +	len = private->physlinebytes * private->info.height;
  11.262 +      }
  11.263 +      if (private->rotate == WSCONS_ROTATE_NONE ||
  11.264 +	  private->rotate == WSCONS_ROTATE_UD) {
  11.265 +	private->blitFunc = WSCONS_blit16;
  11.266 +      } else {
  11.267 +	private->blitFunc = WSCONS_blit16blocked;
  11.268 +      }
  11.269 +      break;
  11.270 +    case 32:
  11.271 +      if (private->physlinebytes == private->info.width) {
  11.272 +	len = private->info.width * private->info.height * sizeof(int);
  11.273 +      } else {
  11.274 +	len = private->physlinebytes * private->info.height;
  11.275 +      }
  11.276 +      break;
  11.277 +    default:
  11.278 +      WSCONS_ReportError("unsupported depth %d", private->info.depth);
  11.279 +      return -1;
  11.280 +  }
  11.281 +
  11.282 +  if (private->shadowFB && private->blitFunc == NULL) {
  11.283 +    WSCONS_ReportError("Using software buffer, but no blitter function is "
  11.284 +		       "available for this %d bpp.", private->info.depth);
  11.285 +    return -1;
  11.286 +  }
  11.287 +
  11.288 +  if (ioctl(private->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) {
  11.289 +    WSCONS_ReportError("ioctl SMODE");
  11.290 +    return -1;
  11.291 +  }
  11.292 +
  11.293 +  pagemask = getpagesize() - 1;
  11.294 +  mapsize = ((int)len + pagemask) & ~pagemask;
  11.295 +  private->physmem = (Uint8 *)mmap(NULL, mapsize,
  11.296 +				   PROT_READ | PROT_WRITE, MAP_SHARED,
  11.297 +				   private->fd, (off_t)0);
  11.298 +  if (private->physmem == (Uint8 *)MAP_FAILED) {
  11.299 +    private->physmem = NULL;
  11.300 +    WSCONS_ReportError("mmap: %s", strerror(errno));
  11.301 +    return -1;
  11.302 +  }
  11.303 +  private->fbmem_len = len;
  11.304 +
  11.305 +  if (private->rotate == WSCONS_ROTATE_CW || 
  11.306 +      private->rotate == WSCONS_ROTATE_CCW) {
  11.307 +    width = private->info.height;
  11.308 +    height = private->info.width;
  11.309 +  } else {
  11.310 +    width = private->info.width;
  11.311 +    height = private->info.height;
  11.312 +  }
  11.313 +
  11.314 +  if (private->shadowFB) {
  11.315 +    private->shadowmem = (Uint8 *)malloc(len);
  11.316 +    if (private->shadowmem == NULL) {
  11.317 +      WSCONS_ReportError("No memory for shadow");
  11.318 +      return -1;
  11.319 +    }
  11.320 +    private->fbstart = private->shadowmem;
  11.321 +    private->fblinebytes = width * ((private->info.depth + 7) / 8);
  11.322 +  } else { 
  11.323 +    private->fbstart = private->physmem;
  11.324 +    private->fblinebytes = private->physlinebytes;
  11.325 +  }
  11.326 +  
  11.327 +  private->SDL_modelist[0] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
  11.328 +  private->SDL_modelist[0]->w = width;
  11.329 +  private->SDL_modelist[0]->h = height;
  11.330 +
  11.331 +  vformat->BitsPerPixel = private->info.depth;
  11.332 +  vformat->BytesPerPixel = private->info.depth / 8;
  11.333 +  
  11.334 +  if (WSCONS_InitKeyboard(this) == -1) {
  11.335 +    return -1;
  11.336 +  }
  11.337 +  
  11.338 +  return 0;
  11.339 +}
  11.340 +
  11.341 +SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
  11.342 +{
  11.343 +  if (format->BitsPerPixel == private->info.depth) {
  11.344 +    return private->SDL_modelist;
  11.345 +  } else {
  11.346 +    return NULL;
  11.347 +  }
  11.348 +}
  11.349 +
  11.350 +SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current,
  11.351 +				 int width, int height, int bpp, Uint32 flags)
  11.352 +{
  11.353 +  if (width != private->SDL_modelist[0]->w || 
  11.354 +      height != private->SDL_modelist[0]->h) {
  11.355 +    WSCONS_ReportError("Requested video mode %dx%d not supported.",
  11.356 +		       width, height);
  11.357 +    return NULL;
  11.358 +  }
  11.359 +  if (bpp != private->info.depth) {
  11.360 +    WSCONS_ReportError("Requested video depth %d bpp not supported.", bpp);
  11.361 +    return NULL;
  11.362 +  }
  11.363 +
  11.364 +  if (!SDL_ReallocFormat(current, 
  11.365 +			 bpp, 
  11.366 +			 private->redMask,
  11.367 +			 private->greenMask,
  11.368 +			 private->blueMask,
  11.369 +			 0)) {
  11.370 +    WSCONS_ReportError("Couldn't allocate new pixel format");
  11.371 +    return NULL;
  11.372 +  }
  11.373 +
  11.374 +  current->flags &= SDL_FULLSCREEN;
  11.375 +  if (private->shadowFB) {
  11.376 +    current->flags |= SDL_SWSURFACE;
  11.377 +  } else {
  11.378 +    current->flags |= SDL_HWSURFACE;
  11.379 +  }
  11.380 +  current->w = width;
  11.381 +  current->h = height;
  11.382 +  current->pitch = private->fblinebytes;
  11.383 +  current->pixels = private->fbstart;
  11.384 +
  11.385 +  memset(private->fbstart, 0, private->fbmem_len);
  11.386 +
  11.387 +  return current;
  11.388 +}
  11.389 +
  11.390 +static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface)
  11.391 +{
  11.392 +  return -1;
  11.393 +}
  11.394 +static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface)
  11.395 +{
  11.396 +}
  11.397 +
  11.398 +static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface)
  11.399 +{
  11.400 +  return 0;
  11.401 +}
  11.402 +
  11.403 +static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface)
  11.404 +{
  11.405 +}
  11.406 +
  11.407 +static void WSCONS_blit16(Uint8 *byte_src_pos,
  11.408 +			  int srcRightDelta, 
  11.409 +			  int srcDownDelta, 
  11.410 +			  Uint8 *byte_dst_pos,
  11.411 +			  int dst_linebytes,
  11.412 +			  int width,
  11.413 +			  int height)
  11.414 +{
  11.415 +  int w;
  11.416 +  Uint16 *src_pos = (Uint16 *)byte_src_pos;
  11.417 +  Uint16 *dst_pos = (Uint16 *)byte_dst_pos;
  11.418 +
  11.419 +  while (height) {
  11.420 +    Uint16 *src = src_pos;
  11.421 +    Uint16 *dst = dst_pos;
  11.422 +    for (w = width; w != 0; w--) {
  11.423 +      *dst = *src;
  11.424 +      src += srcRightDelta;
  11.425 +      dst++;
  11.426 +    }
  11.427 +    dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes);
  11.428 +    src_pos += srcDownDelta;
  11.429 +    height--;
  11.430 +  }
  11.431 +}
  11.432 +
  11.433 +#define BLOCKSIZE_W 32
  11.434 +#define BLOCKSIZE_H 32
  11.435 +
  11.436 +static void WSCONS_blit16blocked(Uint8 *byte_src_pos,
  11.437 +				 int srcRightDelta, 
  11.438 +				 int srcDownDelta, 
  11.439 +				 Uint8 *byte_dst_pos,
  11.440 +				 int dst_linebytes,
  11.441 +				 int width,
  11.442 +				 int height)
  11.443 +{
  11.444 +  int w;
  11.445 +  Uint16 *src_pos = (Uint16 *)byte_src_pos;
  11.446 +  Uint16 *dst_pos = (Uint16 *)byte_dst_pos;
  11.447 +
  11.448 +  while (height > 0) {
  11.449 +    Uint16 *src = src_pos;
  11.450 +    Uint16 *dst = dst_pos;
  11.451 +    for (w = width; w > 0; w -= BLOCKSIZE_W) {
  11.452 +      WSCONS_blit16((Uint8 *)src,
  11.453 +		    srcRightDelta,
  11.454 +		    srcDownDelta,
  11.455 +		    (Uint8 *)dst,
  11.456 +		    dst_linebytes,
  11.457 +		    min(w, BLOCKSIZE_W),
  11.458 +		    min(height, BLOCKSIZE_H));
  11.459 +      src += srcRightDelta * BLOCKSIZE_W;
  11.460 +      dst += BLOCKSIZE_W;
  11.461 +    }
  11.462 +    dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes * BLOCKSIZE_H);
  11.463 +    src_pos += srcDownDelta * BLOCKSIZE_H;
  11.464 +    height -= BLOCKSIZE_H;
  11.465 +  }
  11.466 +}
  11.467 +
  11.468 +static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
  11.469 +{
  11.470 +  int width = private->SDL_modelist[0]->w;
  11.471 +  int height = private->SDL_modelist[0]->h;
  11.472 +  int bytesPerPixel = (private->info.depth + 7) / 8;
  11.473 +  int i;
  11.474 +
  11.475 +  if (!private->shadowFB) {
  11.476 +    return;
  11.477 +  }
  11.478 +
  11.479 +  if (private->info.depth != 16) {
  11.480 +    WSCONS_ReportError("Shadow copy only implemented for 16 bpp");
  11.481 +    return;
  11.482 +  }
  11.483 +
  11.484 +  for (i = 0; i < numrects; i++) {
  11.485 +    int x1, y1, x2, y2;
  11.486 +    int scr_x1, scr_y1, scr_x2, scr_y2;
  11.487 +    int sha_x1, sha_y1;
  11.488 +    int shadowRightDelta;  /* Address change when moving right in dest */
  11.489 +    int shadowDownDelta;   /* Address change when moving down in dest */
  11.490 +    Uint8 *src_start;
  11.491 +    Uint8 *dst_start;
  11.492 +
  11.493 +    x1 = rects[i].x; 
  11.494 +    y1 = rects[i].y;
  11.495 +    x2 = x1 + rects[i].w; 
  11.496 +    y2 = y1 + rects[i].h;
  11.497 +
  11.498 +    if (x1 < 0) {
  11.499 +      x1 = 0;
  11.500 +    } else if (x1 > width) {
  11.501 +      x1 = width;
  11.502 +    }
  11.503 +    if (x2 < 0) {
  11.504 +      x2 = 0;
  11.505 +    } else if (x2 > width) {
  11.506 +      x2 = width;
  11.507 +    }
  11.508 +    if (y1 < 0) {
  11.509 +      y1 = 0;
  11.510 +    } else if (y1 > height) {
  11.511 +      y1 = height;
  11.512 +    }
  11.513 +    if (y2 < 0) {
  11.514 +      y2 = 0;
  11.515 +    } else if (y2 > height) {
  11.516 +      y2 = height;
  11.517 +    }
  11.518 +    if (x2 <= x1 || y2 <= y1) {
  11.519 +      continue;
  11.520 +    }
  11.521 +
  11.522 +    switch (private->rotate) {
  11.523 +      case WSCONS_ROTATE_NONE:
  11.524 +	sha_x1 = scr_x1 = x1;
  11.525 +	sha_y1 = scr_y1 = y1;
  11.526 +	scr_x2 = x2;
  11.527 +	scr_y2 = y2;
  11.528 +	shadowRightDelta = 1;
  11.529 +	shadowDownDelta = width;
  11.530 +	break;
  11.531 +      case WSCONS_ROTATE_CCW:
  11.532 +	scr_x1 = y1;
  11.533 +	scr_y1 = width - x2;
  11.534 +	scr_x2 = y2;
  11.535 +	scr_y2 = width - x1;
  11.536 +	sha_x1 = x2 - 1;
  11.537 +	sha_y1 = y1;
  11.538 +	shadowRightDelta = width;
  11.539 +	shadowDownDelta = -1;
  11.540 +	break;
  11.541 +      case WSCONS_ROTATE_UD:
  11.542 +	scr_x1 = width - x2;
  11.543 +	scr_y1 = height - y2;
  11.544 +	scr_x2 = width - x1;
  11.545 +	scr_y2 = height - y1;
  11.546 +	sha_x1 = x2 - 1;
  11.547 +	sha_y1 = y2 - 1;
  11.548 +	shadowRightDelta = -1;
  11.549 +	shadowDownDelta = -width;
  11.550 +	break;
  11.551 +      case WSCONS_ROTATE_CW:
  11.552 +	scr_x1 = height - y2;
  11.553 +	scr_y1 = x1;
  11.554 +	scr_x2 = height - y1;
  11.555 +	scr_y2 = x2;
  11.556 +	sha_x1 = x1;
  11.557 +	sha_y1 = y2 - 1;
  11.558 +	shadowRightDelta = -width;
  11.559 +	shadowDownDelta = 1;
  11.560 +	break;
  11.561 +      default:
  11.562 +	WSCONS_ReportError("Unknown rotation");
  11.563 +	return;
  11.564 +    }
  11.565 +
  11.566 +    src_start = private->shadowmem + (sha_y1 * width + sha_x1) * bytesPerPixel;
  11.567 +    dst_start = private->physmem + scr_y1 * private->physlinebytes + 
  11.568 +      scr_x1 * bytesPerPixel;
  11.569 +
  11.570 +    private->blitFunc(src_start,
  11.571 +		      shadowRightDelta, 
  11.572 +		      shadowDownDelta, 
  11.573 +		      dst_start,
  11.574 +		      private->physlinebytes,
  11.575 +		      scr_x2 - scr_x1,
  11.576 +		      scr_y2 - scr_y1);
  11.577 +  }
  11.578 +}
  11.579 +
  11.580 +int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
  11.581 +{
  11.582 +  return 0;
  11.583 +}
  11.584 +
  11.585 +/*
  11.586 + * Note: If we are terminated, this could be called in the middle of
  11.587 + * another SDL video routine -- notably UpdateRects.
  11.588 + */
  11.589 +void WSCONS_VideoQuit(_THIS)
  11.590 +{
  11.591 +  int mode = WSDISPLAYIO_MODE_EMUL;
  11.592 +
  11.593 +  if (private->shadowmem != NULL) {
  11.594 +    free(private->shadowmem);
  11.595 +    private->shadowmem = NULL;
  11.596 +  }
  11.597 +  private->fbstart = NULL;
  11.598 +  if (this->screen != NULL) {
  11.599 +    this->screen->pixels = NULL;
  11.600 +  }
  11.601 +
  11.602 +  if (private->SDL_modelist[0] != NULL) {
  11.603 +    free(private->SDL_modelist[0]);
  11.604 +    private->SDL_modelist[0] = NULL;
  11.605 +  }
  11.606 +
  11.607 +  if (ioctl(private->fd, WSDISPLAYIO_SMODE, &mode) == -1) {
  11.608 +    WSCONS_ReportError("ioctl SMODE");
  11.609 +  }
  11.610 +
  11.611 +  WSCONS_ReleaseKeyboard(this);
  11.612 +
  11.613 +  if (private->fd != -1) {
  11.614 +    close(private->fd);
  11.615 +    private->fd = -1;
  11.616 +  }
  11.617 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/video/wscons/SDL_wsconsvideo.h	Tue Nov 22 15:19:50 2005 +0000
    12.3 @@ -0,0 +1,79 @@
    12.4 +/*
    12.5 +    SDL - Simple DirectMedia Layer
    12.6 +    Copyright (C) 1997-2004 Sam Lantinga
    12.7 +
    12.8 +    This library is free software; you can redistribute it and/or
    12.9 +    modify it under the terms of the GNU Library General Public
   12.10 +    License as published by the Free Software Foundation; either
   12.11 +    version 2 of the License, or (at your option) any later version.
   12.12 +
   12.13 +    This library is distributed in the hope that it will be useful,
   12.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12.16 +    Library General Public License for more details.
   12.17 +
   12.18 +    You should have received a copy of the GNU Library General Public
   12.19 +    License along with this library; if not, write to the Free
   12.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   12.21 +
   12.22 +    Sam Lantinga
   12.23 +    slouken@libsdl.org
   12.24 +*/
   12.25 +
   12.26 +#ifdef SAVE_RCSID
   12.27 +static char rcsid =
   12.28 + "@(#) $Id$";
   12.29 +#endif
   12.30 +
   12.31 +#ifndef _SDL_wsconsvideo_h
   12.32 +#define _SDL_wsconsvideo_h
   12.33 +
   12.34 +#include <sys/time.h>
   12.35 +#include <termios.h>
   12.36 +#include <dev/wscons/wsconsio.h>
   12.37 +#include "SDL_mouse.h"
   12.38 +#include "SDL_sysvideo.h"
   12.39 +#include "SDL_mutex.h"
   12.40 +
   12.41 +void WSCONS_ReportError(char *fmt, ...);
   12.42 +
   12.43 +/* Hidden "this" pointer for the video functions */
   12.44 +#define _THIS	SDL_VideoDevice *this
   12.45 +#define private	(this->hidden)
   12.46 +
   12.47 +/* Private display data */
   12.48 +
   12.49 +typedef void WSCONS_bitBlit(Uint8 *src_pos,
   12.50 +			    int srcRightDelta, // pixels, not bytes
   12.51 +			    int srcDownDelta,  // pixels, not bytes
   12.52 +			    Uint8 *dst_pos,
   12.53 +			    int dst_linebytes,
   12.54 +			    int width,
   12.55 +			    int height);
   12.56 +
   12.57 +struct SDL_PrivateVideoData {
   12.58 +  int fd;                       /* file descriptor of open device */
   12.59 +  struct wsdisplay_fbinfo info; /* frame buffer characteristics */
   12.60 +  int physlinebytes;            /* number of bytes per row */
   12.61 +  int redMask, greenMask, blueMask;
   12.62 +
   12.63 +  Uint8 *fbstart;               /* These refer to the surface used, */
   12.64 +  int fblinebytes;              /* physical frame buffer or shadow. */
   12.65 +
   12.66 +  size_t fbmem_len;
   12.67 +  Uint8 *physmem;
   12.68 +  Uint8 *shadowmem;
   12.69 +  int rotate;
   12.70 +  int shadowFB;                 /* Tells whether a shadow is being used. */
   12.71 +
   12.72 +  WSCONS_bitBlit *blitFunc;
   12.73 +
   12.74 +  SDL_Rect *SDL_modelist[2];
   12.75 +
   12.76 +  unsigned int kbdType;
   12.77 +  int did_save_tty;
   12.78 +  struct termios saved_tty;
   12.79 +};
   12.80 +
   12.81 +
   12.82 +#endif /* _SDL_wsconsvideo_h */