Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libSDL
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PocketInsanity
libSDL
Commits
90a214c4
Commit
90a214c4
authored
Jan 20, 2011
by
Sam Lantinga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Nobody has stepped up to maintain a framebuffer console driver. Bye bye! :)
parent
c14d8951
Changes
25
Show whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
0 additions
and
6092 deletions
+0
-6092
configure.in
configure.in
+0
-28
SDL_config.h.in
include/SDL_config.h.in
+0
-1
SDL_sysvideo.h
src/video/SDL_sysvideo.h
+0
-3
SDL_video.c
src/video/SDL_video.c
+0
-3
3dfx_mmio.h
src/video/fbcon/3dfx_mmio.h
+0
-56
3dfx_regs.h
src/video/fbcon/3dfx_regs.h
+0
-83
SDL_fb3dfx.c
src/video/fbcon/SDL_fb3dfx.c
+0
-225
SDL_fb3dfx.h
src/video/fbcon/SDL_fb3dfx.h
+0
-30
SDL_fbelo.c
src/video/fbcon/SDL_fbelo.c
+0
-462
SDL_fbelo.h
src/video/fbcon/SDL_fbelo.h
+0
-58
SDL_fbevents.c
src/video/fbcon/SDL_fbevents.c
+0
-1391
SDL_fbevents_c.h
src/video/fbcon/SDL_fbevents_c.h
+0
-39
SDL_fbkeys.h
src/video/fbcon/SDL_fbkeys.h
+0
-139
SDL_fbmatrox.c
src/video/fbcon/SDL_fbmatrox.c
+0
-285
SDL_fbmatrox.h
src/video/fbcon/SDL_fbmatrox.h
+0
-30
SDL_fbmouse.c
src/video/fbcon/SDL_fbmouse.c
+0
-35
SDL_fbmouse_c.h
src/video/fbcon/SDL_fbmouse_c.h
+0
-27
SDL_fbriva.c
src/video/fbcon/SDL_fbriva.c
+0
-231
SDL_fbriva.h
src/video/fbcon/SDL_fbriva.h
+0
-37
SDL_fbvideo.c
src/video/fbcon/SDL_fbvideo.c
+0
-1815
SDL_fbvideo.h
src/video/fbcon/SDL_fbvideo.h
+0
-189
matrox_mmio.h
src/video/fbcon/matrox_mmio.h
+0
-51
matrox_regs.h
src/video/fbcon/matrox_regs.h
+0
-376
riva_mmio.h
src/video/fbcon/riva_mmio.h
+0
-455
riva_regs.h
src/video/fbcon/riva_regs.h
+0
-43
No files found.
configure.in
View file @
90a214c4
...
...
@@ -1420,33 +1420,6 @@ AC_HELP_STRING([--enable-video-cocoa], [use Cocoa video driver [[default=yes]]])
fi
}
dnl Find the framebuffer console includes
CheckFBCON()
{
AC_ARG_ENABLE(video-fbcon,
AC_HELP_STRING([--enable-video-fbcon], [use framebuffer console video driver [[default=no]]]),
, enable_video_fbcon=no)
if test x$enable_video = xyes -a x$enable_video_fbcon = xyes; then
AC_MSG_CHECKING(for framebuffer console support)
video_fbcon=no
AC_TRY_COMPILE([
#include <linux/fb.h>
#include <linux/kd.h>
#include <linux/keyboard.h>
],[
],[
video_fbcon=yes
])
AC_MSG_RESULT($video_fbcon)
if test x$video_fbcon = xyes; then
AC_CHECK_FUNCS(getpagesize)
AC_DEFINE(SDL_VIDEO_DRIVER_FBCON)
SOURCES="$SOURCES $srcdir/src/video/fbcon/*.c"
have_video=yes
fi
fi
}
dnl Find DirectFB
CheckDirectFB()
{
...
...
@@ -2300,7 +2273,6 @@ case "$host" in
CheckESD
CheckNAS
CheckX11
CheckFBCON
CheckDirectFB
CheckFusionSound
CheckPS3
...
...
include/SDL_config.h.in
View file @
90a214c4
...
...
@@ -261,7 +261,6 @@
#undef SDL_VIDEO_DRIVER_DIRECTFB
#undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC
#undef SDL_VIDEO_DRIVER_DUMMY
#undef SDL_VIDEO_DRIVER_FBCON
#undef SDL_VIDEO_DRIVER_NDS
#undef SDL_VIDEO_DRIVER_PHOTON
#undef SDL_VIDEO_DRIVER_QNXGF
...
...
src/video/SDL_sysvideo.h
View file @
90a214c4
...
...
@@ -408,9 +408,6 @@ extern VideoBootStrap COCOA_bootstrap;
#if SDL_VIDEO_DRIVER_X11
extern
VideoBootStrap
X11_bootstrap
;
#endif
#if SDL_VIDEO_DRIVER_FBCON
extern
VideoBootStrap
FBCON_bootstrap
;
#endif
#if SDL_VIDEO_DRIVER_DIRECTFB
extern
VideoBootStrap
DirectFB_bootstrap
;
#endif
...
...
src/video/SDL_video.c
View file @
90a214c4
...
...
@@ -62,9 +62,6 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_X11
&
X11_bootstrap
,
#endif
#if SDL_VIDEO_DRIVER_FBCON
&
FBCON_bootstrap
,
#endif
#if SDL_VIDEO_DRIVER_DIRECTFB
&
DirectFB_bootstrap
,
#endif
...
...
src/video/fbcon/3dfx_mmio.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* 3Dfx register definitions */
#include "3dfx_regs.h"
/* 3Dfx control macros */
#define tdfx_in8(reg) *(volatile Uint8 *)(mapped_io + (reg))
#define tdfx_in32(reg) *(volatile Uint32 *)(mapped_io + (reg))
#define tdfx_out8(reg,v) *(volatile Uint8 *)(mapped_io + (reg)) = v;
#define tdfx_out32(reg,v) *(volatile Uint32 *)(mapped_io + (reg)) = v;
/* Wait for fifo space */
#define tdfx_wait(space) \
{ \
while ( (tdfx_in8(TDFX_STATUS) & 0x1F) < space ) \
; \
}
/* Wait for idle accelerator */
#define tdfx_waitidle() \
{ \
int i = 0; \
\
tdfx_wait(1); \
tdfx_out32(COMMAND_3D, COMMAND_3D_NOP); \
do { \
i = (tdfx_in32(TDFX_STATUS) & STATUS_BUSY) ? 0 : i + 1; \
} while ( i != 3 ); \
}
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/3dfx_regs.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#ifndef _3DFX_REGS_H
#define _3DFX_REGS_H
/* This information comes from the public 3Dfx specs for the Voodoo 3000 */
/* mapped_io register offsets */
#define TDFX_STATUS 0x00
#define INTCTRL (0x00100000 + 0x04)
#define CLIP0MIN (0x00100000 + 0x08)
#define CLIP0MAX (0x00100000 + 0x0c)
#define DSTBASE (0x00100000 + 0x10)
#define DSTFORMAT (0x00100000 + 0x14)
#define SRCCOLORKEYMIN (0x00100000 + 0x18)
#define SRCCOLORKEYMAX (0x00100000 + 0x1c)
#define DSTCOLORKEYMIN (0x00100000 + 0x20)
#define DSTCOLORKEYMAX (0x00100000 + 0x24)
#define BRESERROR0 (0x00100000 + 0x28)
#define BRESERROR1 (0x00100000 + 0x2c)
#define ROP_2D (0x00100000 + 0x30)
#define SRCBASE (0x00100000 + 0x34)
#define COMMANDEXTRA_2D (0x00100000 + 0x38)
#define PATTERN0 (0x00100000 + 0x44)
#define PATTERN1 (0x00100000 + 0x48)
#define CLIP1MIN (0x00100000 + 0x4c)
#define CLIP1MAX (0x00100000 + 0x50)
#define SRCFORMAT (0x00100000 + 0x54)
#define SRCSIZE (0x00100000 + 0x58)
#define SRCXY (0x00100000 + 0x5c)
#define COLORBACK (0x00100000 + 0x60)
#define COLORFORE (0x00100000 + 0x64)
#define DSTSIZE (0x00100000 + 0x68)
#define DSTXY (0x00100000 + 0x6c)
#define COMMAND_2D (0x00100000 + 0x70)
#define LAUNCH_2D (0x00100000 + 0x80)
#define PATTERNBASE (0x00100000 + 0x100)
#define COMMAND_3D (0x00200000 + 0x120)
/* register bitfields (not all, only as needed) */
#define BIT(x) (1UL << (x))
#define COMMAND_2D_BITBLT 0x01
#define COMMAND_2D_FILLRECT 0x05
#define COMMAND_2D_LINE 0x06
#define COMMAND_2D_POLYGON_FILL 0x08
#define COMMAND_2D_INITIATE BIT(8)
#define COMMAND_2D_REVERSELINE BIT(9)
#define COMMAND_2D_STIPPLELINE BIT(12)
#define COMMAND_2D_MONOCHROME_PATT BIT(13)
#define COMMAND_2D_MONOCHROME_TRANSP BIT(16)
#define COMMAND_3D_NOP 0x00
#define STATUS_RETRACE BIT(6)
#define STATUS_BUSY BIT(9)
#endif
/* _3DFX_REGS_H */
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fb3dfx.c
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include "SDL_video.h"
#include "../SDL_blit.h"
#include "SDL_fb3dfx.h"
#include "3dfx_mmio.h"
/* Wait for vertical retrace */
static
void
WaitVBL
(
_THIS
)
{
/* find start of retrace */
tdfx_waitidle
();
while
((
tdfx_in32
(
TDFX_STATUS
)
&
STATUS_RETRACE
)
==
STATUS_RETRACE
);
/* wait until we're past the start */
while
((
tdfx_in32
(
TDFX_STATUS
)
&
STATUS_RETRACE
)
==
0
);
}
static
void
WaitIdle
(
_THIS
)
{
tdfx_waitidle
();
}
/* Sets video mem colorkey and accelerated blit function */
static
int
SetHWColorKey
(
_THIS
,
SDL_Surface
*
surface
,
Uint32
key
)
{
return
(
0
);
}
static
int
FillHWRect
(
_THIS
,
SDL_Surface
*
dst
,
SDL_Rect
*
rect
,
Uint32
color
)
{
int
bpp
;
char
*
dst_base
;
Uint32
format
;
int
dstX
,
dstY
;
/* Don't blit to the display surface when switched away */
if
(
switched_away
)
{
return
-
2
;
/* no hardware access */
}
if
(
dst
==
this
->
screen
)
{
SDL_mutexP
(
hw_lock
);
}
/* Set the destination pixel format */
dst_base
=
(
char
*
)
((
char
*
)
dst
->
pixels
-
mapped_mem
);
bpp
=
dst
->
format
->
BitsPerPixel
;
format
=
dst
->
pitch
|
((
bpp
+
((
bpp
==
8
)
?
0
:
8
))
<<
13
);
/* Calculate source and destination base coordinates */
dstX
=
rect
->
x
;
dstY
=
rect
->
y
;
/* Execute the fill command */
tdfx_wait
(
6
);
tdfx_out32
(
DSTBASE
,
(
Uint32
)
dst_base
);
tdfx_out32
(
DSTFORMAT
,
format
);
tdfx_out32
(
COLORFORE
,
color
);
tdfx_out32
(
COMMAND_2D
,
COMMAND_2D_FILLRECT
);
tdfx_out32
(
DSTSIZE
,
rect
->
w
|
(
rect
->
h
<<
16
));
tdfx_out32
(
LAUNCH_2D
,
dstX
|
(
dstY
<<
16
));
FB_AddBusySurface
(
dst
);
if
(
dst
==
this
->
screen
)
{
SDL_mutexV
(
hw_lock
);
}
return
(
0
);
}
static
int
HWAccelBlit
(
SDL_Surface
*
src
,
SDL_Rect
*
srcrect
,
SDL_Surface
*
dst
,
SDL_Rect
*
dstrect
)
{
SDL_VideoDevice
*
this
=
current_video
;
int
bpp
;
Uint32
src_format
;
Uint32
dst_format
;
char
*
src_base
;
char
*
dst_base
;
int
srcX
,
srcY
;
int
dstX
,
dstY
;
Uint32
blitop
;
Uint32
use_colorkey
;
/* Don't blit to the display surface when switched away */
if
(
switched_away
)
{
return
-
2
;
/* no hardware access */
}
if
(
dst
==
this
->
screen
)
{
SDL_mutexP
(
hw_lock
);
}
/* Set the source and destination pixel format */
src_base
=
(
char
*
)
((
char
*
)
src
->
pixels
-
mapped_mem
);
bpp
=
src
->
format
->
BitsPerPixel
;
src_format
=
src
->
pitch
|
((
bpp
+
((
bpp
==
8
)
?
0
:
8
))
<<
13
);
dst_base
=
(
char
*
)
((
char
*
)
dst
->
pixels
-
mapped_mem
);
bpp
=
dst
->
format
->
BitsPerPixel
;
dst_format
=
dst
->
pitch
|
((
bpp
+
((
bpp
==
8
)
?
0
:
8
))
<<
13
);
srcX
=
srcrect
->
x
;
srcY
=
srcrect
->
y
;
dstX
=
dstrect
->
x
;
dstY
=
dstrect
->
y
;
/* Assemble the blit operation */
blitop
=
COMMAND_2D_BITBLT
|
(
0xCC
<<
24
);
if
(
srcX
<=
dstX
)
{
blitop
|=
BIT
(
14
);
srcX
+=
(
dstrect
->
w
-
1
);
dstX
+=
(
dstrect
->
w
-
1
);
}
if
(
srcY
<=
dstY
)
{
blitop
|=
BIT
(
15
);
srcY
+=
(
dstrect
->
h
-
1
);
dstY
+=
(
dstrect
->
h
-
1
);
}
/* Perform the blit! */
if
((
src
->
flags
&
SDL_SRCCOLORKEY
)
==
SDL_SRCCOLORKEY
)
{
tdfx_wait
(
3
);
tdfx_out32
(
SRCCOLORKEYMIN
,
src
->
format
->
colorkey
);
tdfx_out32
(
SRCCOLORKEYMAX
,
src
->
format
->
colorkey
);
tdfx_out32
(
ROP_2D
,
0xAA00
);
use_colorkey
=
1
;
}
else
{
use_colorkey
=
0
;
}
tdfx_wait
(
9
);
tdfx_out32
(
SRCBASE
,
(
Uint32
)
src_base
);
tdfx_out32
(
SRCFORMAT
,
src_format
);
tdfx_out32
(
DSTBASE
,
(
Uint32
)
dst_base
);
tdfx_out32
(
DSTFORMAT
,
src_format
);
tdfx_out32
(
COMMAND_2D
,
blitop
);
tdfx_out32
(
COMMANDEXTRA_2D
,
use_colorkey
);
tdfx_out32
(
DSTSIZE
,
dstrect
->
w
|
(
dstrect
->
h
<<
16
));
tdfx_out32
(
DSTXY
,
dstX
|
(
dstY
<<
16
));
tdfx_out32
(
LAUNCH_2D
,
srcX
|
(
srcY
<<
16
));
FB_AddBusySurface
(
src
);
FB_AddBusySurface
(
dst
);
if
(
dst
==
this
->
screen
)
{
SDL_mutexV
(
hw_lock
);
}
return
(
0
);
}
static
int
CheckHWBlit
(
_THIS
,
SDL_Surface
*
src
,
SDL_Surface
*
dst
)
{
int
accelerated
;
/* Set initial acceleration on */
src
->
flags
|=
SDL_HWACCEL
;
/* Set the surface attributes */
if
((
src
->
flags
&
SDL_SRCALPHA
)
==
SDL_SRCALPHA
)
{
if
(
!
this
->
info
.
blit_hw_A
)
{
src
->
flags
&=
~
SDL_HWACCEL
;
}
}
if
((
src
->
flags
&
SDL_SRCCOLORKEY
)
==
SDL_SRCCOLORKEY
)
{
if
(
!
this
->
info
.
blit_hw_CC
)
{
src
->
flags
&=
~
SDL_HWACCEL
;
}
}
/* Check to see if final surface blit is accelerated */
accelerated
=
!!
(
src
->
flags
&
SDL_HWACCEL
);
if
(
accelerated
)
{
src
->
map
->
hw_blit
=
HWAccelBlit
;
}
return
(
accelerated
);
}
void
FB_3DfxAccel
(
_THIS
,
__u32
card
)
{
/* We have hardware accelerated surface functions */
this
->
CheckHWBlit
=
CheckHWBlit
;
wait_vbl
=
WaitVBL
;
wait_idle
=
WaitIdle
;
/* Reset the 3Dfx controller */
tdfx_out32
(
BRESERROR0
,
0
);
tdfx_out32
(
BRESERROR1
,
0
);
/* The 3Dfx has an accelerated color fill */
this
->
info
.
blit_fill
=
1
;
this
->
FillHWRect
=
FillHWRect
;
/* The 3Dfx has accelerated normal and colorkey blits */
this
->
info
.
blit_hw
=
1
;
this
->
info
.
blit_hw_CC
=
1
;
this
->
SetHWColorKey
=
SetHWColorKey
;
}
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fb3dfx.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* 3Dfx hardware acceleration for the SDL framebuffer console driver */
#include "SDL_fbvideo.h"
/* Set up the driver for 3Dfx acceleration */
extern
void
FB_3DfxAccel
(
_THIS
,
__u32
card
);
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbelo.c
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include <unistd.h>
#include <sys/time.h>
#include <ctype.h>
#include "SDL_stdinc.h"
#include "SDL_fbvideo.h"
#include "SDL_fbelo.h"
/*
calibration default values
values are read from the following environment variables:
SDL_ELO_MIN_X
SDL_ELO_MAX_X
SDL_ELO_MIN_Y
SDL_ELO_MAX_Y
*/
static
int
ELO_MIN_X
=
400
;
static
int
ELO_MAX_X
=
3670
;
static
int
ELO_MIN_Y
=
500
;
static
int
ELO_MAX_Y
=
3540
;
#define ELO_SNAP_SIZE 6
#define ELO_TOUCH_BYTE 'T'
#define ELO_ID 'I'
#define ELO_MODE 'M'
#define ELO_PARAMETER 'P'
#define ELO_REPORT 'B'
#define ELO_ACK 'A'
#define ELO_INIT_CHECKSUM 0xAA
#define ELO_BTN_PRESS 0x01
#define ELO_STREAM 0x02
#define ELO_BTN_RELEASE 0x04
#define ELO_TOUCH_MODE 0x01
#define ELO_STREAM_MODE 0x02
#define ELO_UNTOUCH_MODE 0x04
#define ELO_RANGE_CHECK_MODE 0x40
#define ELO_TRIM_MODE 0x02
#define ELO_CALIB_MODE 0x04
#define ELO_SCALING_MODE 0x08
#define ELO_TRACKING_MODE 0x40
#define ELO_SERIAL_MASK 0xF8
#define ELO_SERIAL_IO '0'
#define ELO_MAX_TRIALS 3
#define ELO_MAX_WAIT 100000
#define ELO_UNTOUCH_DELAY 5
#define ELO_REPORT_DELAY 1
/* eloParsePacket
*/
int
eloParsePacket
(
unsigned
char
*
mousebuf
,
int
*
dx
,
int
*
dy
,
int
*
button_state
)
{
static
int
elo_button
=
0
;
static
int
last_x
=
0
;
static
int
last_y
=
0
;
int
x
,
y
;
/* Check if we have a touch packet */
if
(
mousebuf
[
1
]
!=
ELO_TOUCH_BYTE
)
{
return
0
;
}
x
=
((
mousebuf
[
4
]
<<
8
)
|
mousebuf
[
3
]);
y
=
((
mousebuf
[
6
]
<<
8
)
|
mousebuf
[
5
]);
if
((
SDL_abs
(
x
-
last_x
)
>
ELO_SNAP_SIZE
)
||
(
SDL_abs
(
y
-
last_y
)
>
ELO_SNAP_SIZE
))
{
*
dx
=
((
mousebuf
[
4
]
<<
8
)
|
mousebuf
[
3
]);
*
dy
=
((
mousebuf
[
6
]
<<
8
)
|
mousebuf
[
5
]);
}
else
{
*
dx
=
last_x
;
*
dy
=
last_y
;
}
last_x
=
*
dx
;
last_y
=
*
dy
;
if
((
mousebuf
[
2
]
&
0x07
)
==
ELO_BTN_PRESS
)
{
elo_button
=
1
;
}
if
((
mousebuf
[
2
]
&
0x07
)
==
ELO_BTN_RELEASE
)
{
elo_button
=
0
;
}
*
button_state
=
elo_button
;
return
1
;
}
/* Convert the raw coordinates from the ELO controller
to a screen position.
*/
void
eloConvertXY
(
_THIS
,
int
*
dx
,
int
*
dy
)
{
int
input_x
=
*
dx
;
int
input_y
=
*
dy
;
int
width
=
ELO_MAX_X
-
ELO_MIN_X
;
int
height
=
ELO_MAX_Y
-
ELO_MIN_Y
;
*
dx
=
((
int
)
cache_vinfo
.
xres
-
((
int
)
cache_vinfo
.
xres
*
(
input_x
-
ELO_MIN_X
))
/
width
);
*
dy
=
(
cache_vinfo
.
yres
*
(
input_y
-
ELO_MIN_Y
))
/
height
;
}
/* eloGetPacket
*/
int
eloGetPacket
(
unsigned
char
*
buffer
,
int
*
buffer_p
,
int
*
checksum
,
int
fd
)
{
int
num_bytes
;
int
ok
;
if
(
fd
==
0
)
{
num_bytes
=
ELO_PACKET_SIZE
;
}
else
{
num_bytes
=
read
(
fd
,
(
char
*
)
(
buffer
+
*
buffer_p
),
ELO_PACKET_SIZE
-
*
buffer_p
);
}
if
(
num_bytes
<
0
)
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"System error while reading from Elographics touchscreen.
\n
"
);
#endif
return
0
;
}
while
(
num_bytes
)
{
if
((
*
buffer_p
==
0
)
&&
(
buffer
[
0
]
!=
ELO_START_BYTE
))
{
SDL_memcpy
(
&
buffer
[
0
],
&
buffer
[
1
],
num_bytes
-
1
);
}
else
{
if
(
*
buffer_p
<
ELO_PACKET_SIZE
-
1
)
{
*
checksum
=
*
checksum
+
buffer
[
*
buffer_p
];
*
checksum
=
*
checksum
%
256
;
}
(
*
buffer_p
)
++
;
}
num_bytes
--
;
}
if
(
*
buffer_p
==
ELO_PACKET_SIZE
)
{
ok
=
(
*
checksum
==
buffer
[
ELO_PACKET_SIZE
-
1
]);
*
checksum
=
ELO_INIT_CHECKSUM
;
*
buffer_p
=
0
;
if
(
!
ok
)
{
return
0
;
}
return
1
;
}
else
{
return
0
;
}
}
/* eloSendPacket
*/
int
eloSendPacket
(
unsigned
char
*
packet
,
int
fd
)
{
int
i
,
result
;
int
sum
=
ELO_INIT_CHECKSUM
;
packet
[
0
]
=
ELO_START_BYTE
;
for
(
i
=
0
;
i
<
ELO_PACKET_SIZE
-
1
;
i
++
)
{
sum
+=
packet
[
i
];
sum
&=
0xFF
;
}
packet
[
ELO_PACKET_SIZE
-
1
]
=
sum
;
result
=
write
(
fd
,
packet
,
ELO_PACKET_SIZE
);
if
(
result
!=
ELO_PACKET_SIZE
)
{
#ifdef DEBUG_MOUSE
printf
(
"System error while sending to Elographics touchscreen.
\n
"
);
#endif
return
0
;
}
else
{
return
1
;
}
}
/* eloWaitForInput
*/
int
eloWaitForInput
(
int
fd
,
int
timeout
)
{
fd_set
readfds
;
struct
timeval
to
;
int
r
;
FD_ZERO
(
&
readfds
);
FD_SET
(
fd
,
&
readfds
);
to
.
tv_sec
=
0
;
to
.
tv_usec
=
timeout
;
r
=
select
(
FD_SETSIZE
,
&
readfds
,
NULL
,
NULL
,
&
to
);
return
r
;
}
/* eloWaitReply
*/
int
eloWaitReply
(
unsigned
char
type
,
unsigned
char
*
reply
,
int
fd
)
{
int
ok
;
int
i
,
result
;
int
reply_p
=
0
;
int
sum
=
ELO_INIT_CHECKSUM
;
i
=
ELO_MAX_TRIALS
;
do
{
ok
=
0
;
result
=
eloWaitForInput
(
fd
,
ELO_MAX_WAIT
);
if
(
result
>
0
)
{
ok
=
eloGetPacket
(
reply
,
&
reply_p
,
&
sum
,
fd
);
if
(
ok
&&
reply
[
1
]
!=
type
&&
type
!=
ELO_PARAMETER
)
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Wrong reply received
\n
"
);
#endif
ok
=
0
;
}
}
else
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"No input!
\n
"
);
#endif
}
if
(
result
==
0
)
{
i
--
;
}
}
while
(
!
ok
&&
(
i
>
0
));
return
ok
;
}
/* eloWaitAck
*/
int
eloWaitAck
(
int
fd
)
{
unsigned
char
packet
[
ELO_PACKET_SIZE
];
int
i
,
nb_errors
;
if
(
eloWaitReply
(
ELO_ACK
,
packet
,
fd
))
{
for
(
i
=
0
,
nb_errors
=
0
;
i
<
4
;
i
++
)
{
if
(
packet
[
2
+
i
]
!=
'0'
)
{
nb_errors
++
;
}
}
if
(
nb_errors
!=
0
)
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Elographics acknowledge packet reports %d errors
\n
"
,
nb_errors
);
#endif
}
return
1
;
}
else
{
return
0
;
}
}
/* eloSendQuery --
*/
int
eloSendQuery
(
unsigned
char
*
request
,
unsigned
char
*
reply
,
int
fd
)
{
int
ok
;
if
(
eloSendPacket
(
request
,
fd
))
{
ok
=
eloWaitReply
(
toupper
(
request
[
1
]),
reply
,
fd
);
if
(
ok
)
{
ok
=
eloWaitAck
(
fd
);
}
return
ok
;
}
else
{
return
0
;
}
}
/* eloSendControl
*/
int
eloSendControl
(
unsigned
char
*
control
,
int
fd
)
{
if
(
eloSendPacket
(
control
,
fd
))
{
return
eloWaitAck
(
fd
);
}
else
{
return
0
;
}
}
/* eloInitController
*/
int
eloInitController
(
int
fd
)
{
unsigned
char
req
[
ELO_PACKET_SIZE
];
unsigned
char
reply
[
ELO_PACKET_SIZE
];
const
char
*
buffer
=
NULL
;
int
result
=
0
;
struct
termios
mouse_termios
;
/* try to read the calibration values */
buffer
=
SDL_getenv
(
"SDL_ELO_MIN_X"
);
if
(
buffer
)
{
ELO_MIN_X
=
SDL_atoi
(
buffer
);
}
buffer
=
SDL_getenv
(
"SDL_ELO_MAX_X"
);
if
(
buffer
)
{
ELO_MAX_X
=
SDL_atoi
(
buffer
);
}
buffer
=
SDL_getenv
(
"SDL_ELO_MIN_Y"
);
if
(
buffer
)
{
ELO_MIN_Y
=
SDL_atoi
(
buffer
);
}
buffer
=
SDL_getenv
(
"SDL_ELO_MAX_Y"
);
if
(
buffer
)
{
ELO_MAX_Y
=
SDL_atoi
(
buffer
);
}
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"ELO calibration values:
\n
min_x: %i
\n
max_x: %i
\n
min_y: %i
\n
max_y: %i
\n
"
,
ELO_MIN_X
,
ELO_MAX_X
,
ELO_MIN_Y
,
ELO_MAX_Y
);
#endif
/* set comm params */
SDL_memset
(
&
mouse_termios
,
0
,
sizeof
(
mouse_termios
));
mouse_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
CLOCAL
;
mouse_termios
.
c_cc
[
VMIN
]
=
1
;
result
=
tcsetattr
(
fd
,
TCSANOW
,
&
mouse_termios
);
if
(
result
<
0
)
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Unable to configure Elographics touchscreen port
\n
"
);
#endif
return
0
;
}
SDL_memset
(
req
,
0
,
ELO_PACKET_SIZE
);
req
[
1
]
=
tolower
(
ELO_PARAMETER
);
if
(
!
eloSendQuery
(
req
,
reply
,
fd
))
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Not at the specified rate or model 2310, will continue
\n
"
);
#endif
}
SDL_memset
(
req
,
0
,
ELO_PACKET_SIZE
);
req
[
1
]
=
tolower
(
ELO_ID
);
if
(
eloSendQuery
(
req
,
reply
,
fd
))
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Ok, controller configured!
\n
"
);
#endif
}
else
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Unable to ask Elographics touchscreen identification
\n
"
);
#endif
return
0
;
}
SDL_memset
(
req
,
0
,
ELO_PACKET_SIZE
);
req
[
1
]
=
ELO_MODE
;
req
[
3
]
=
ELO_TOUCH_MODE
|
ELO_STREAM_MODE
|
ELO_UNTOUCH_MODE
;
req
[
4
]
=
ELO_TRACKING_MODE
;
if
(
!
eloSendControl
(
req
,
fd
))
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Unable to change Elographics touchscreen operating mode
\n
"
);
#endif
return
0
;
}
SDL_memset
(
req
,
0
,
ELO_PACKET_SIZE
);
req
[
1
]
=
ELO_REPORT
;
req
[
2
]
=
ELO_UNTOUCH_DELAY
;
req
[
3
]
=
ELO_REPORT_DELAY
;
if
(
!
eloSendControl
(
req
,
fd
))
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Unable to change Elographics touchscreen reports timings
\n
"
);
#endif
return
0
;
}
return
1
;
}
int
eloReadPosition
(
_THIS
,
int
fd
,
int
*
x
,
int
*
y
,
int
*
button_state
,
int
*
realx
,
int
*
realy
)
{
unsigned
char
buffer
[
ELO_PACKET_SIZE
];
int
pointer
=
0
;
int
checksum
=
ELO_INIT_CHECKSUM
;
while
(
pointer
<
ELO_PACKET_SIZE
)
{
if
(
eloGetPacket
(
buffer
,
&
pointer
,
&
checksum
,
fd
))
{
break
;
}
}
if
(
!
eloParsePacket
(
buffer
,
realx
,
realy
,
button_state
))
{
return
0
;
}
*
x
=
*
realx
;
*
y
=
*
realy
;
eloConvertXY
(
this
,
x
,
y
);
return
1
;
}
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbelo.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#ifndef SDL_fbelo_h
#define SDL_fbelo_h
#include "SDL_fbvideo.h"
/* ELO */
#define ELO_PACKET_SIZE 10
#define ELO_START_BYTE 'U'
/* eloConvertXY
Convert the raw coordinates from the ELO controller
to a screen position.
*/
void
eloConvertXY
(
_THIS
,
int
*
dx
,
int
*
dy
);
/* eloInitController(int fd)
Initialize the ELO serial touchscreen controller
*/
int
eloInitController
(
int
fd
);
/* eloParsePacket
extract position and button state from a packet
*/
int
eloParsePacket
(
unsigned
char
*
mousebuf
,
int
*
dx
,
int
*
dy
,
int
*
button_state
);
/* eloReadPosition
read a packet and get the cursor position
*/
int
eloReadPosition
(
_THIS
,
int
fd
,
int
*
x
,
int
*
y
,
int
*
button_state
,
int
*
realx
,
int
*
realy
);
#endif
/* SDL_fbelo_h */
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbevents.c
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* Handle the event stream, converting console events into SDL events */
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
/* For parsing /proc */
#include <dirent.h>
#include <ctype.h>
#include <linux/vt.h>
#include <linux/kd.h>
#include <linux/keyboard.h>
#include "SDL_timer.h"
#include "SDL_mutex.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_sysevents.h"
#include "../../events/SDL_events_c.h"
#include "SDL_fbvideo.h"
#include "SDL_fbevents_c.h"
#include "SDL_fbkeys.h"
#include "SDL_fbelo.h"
#ifndef GPM_NODE_FIFO
#define GPM_NODE_FIFO "/dev/gpmdata"
#endif
/*#define DEBUG_KEYBOARD*/
/*#define DEBUG_MOUSE*/
/* The translation tables from a console scancode to a SDL keysym */
#define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT)
static
Uint16
vga_keymap
[
NUM_VGAKEYMAPS
][
NR_KEYS
];
static
SDLKey
keymap
[
128
];
static
Uint16
keymap_temp
[
128
];
/* only used at startup */
static
SDL_keysym
*
TranslateKey
(
int
scancode
,
SDL_keysym
*
keysym
);
/* Ugh, we have to duplicate the kernel's keysym mapping code...
Oh, it's not so bad. :-)
FIXME: Add keyboard LED handling code
*/
static
void
FB_vgainitkeymaps
(
int
fd
)
{
struct
kbentry
entry
;
int
map
,
i
;
/* Don't do anything if we are passed a closed keyboard */
if
(
fd
<
0
)
{
return
;
}
/* Load all the keysym mappings */
for
(
map
=
0
;
map
<
NUM_VGAKEYMAPS
;
++
map
)
{
SDL_memset
(
vga_keymap
[
map
],
0
,
NR_KEYS
*
sizeof
(
Uint16
));
for
(
i
=
0
;
i
<
NR_KEYS
;
++
i
)
{
entry
.
kb_table
=
map
;
entry
.
kb_index
=
i
;
if
(
ioctl
(
fd
,
KDGKBENT
,
&
entry
)
==
0
)
{
/* fill keytemp. This replaces SDL_fbkeys.h */
if
((
map
==
0
)
&&
(
i
<
128
))
{
keymap_temp
[
i
]
=
entry
.
kb_value
;
}
/* The "Enter" key is a special case */
if
(
entry
.
kb_value
==
K_ENTER
)
{
entry
.
kb_value
=
K
(
KT_ASCII
,
13
);
}
/* Handle numpad specially as well */
if
(
KTYP
(
entry
.
kb_value
)
==
KT_PAD
)
{
switch
(
entry
.
kb_value
)
{
case
K_P0
:
case
K_P1
:
case
K_P2
:
case
K_P3
:
case
K_P4
:
case
K_P5
:
case
K_P6
:
case
K_P7
:
case
K_P8
:
case
K_P9
:
vga_keymap
[
map
][
i
]
=
entry
.
kb_value
;
vga_keymap
[
map
][
i
]
+=
'0'
;
break
;
case
K_PPLUS
:
vga_keymap
[
map
][
i
]
=
K
(
KT_ASCII
,
'+'
);
break
;
case
K_PMINUS
:
vga_keymap
[
map
][
i
]
=
K
(
KT_ASCII
,
'-'
);
break
;
case
K_PSTAR
:
vga_keymap
[
map
][
i
]
=
K
(
KT_ASCII
,
'*'
);
break
;
case
K_PSLASH
:
vga_keymap
[
map
][
i
]
=
K
(
KT_ASCII
,
'/'
);
break
;
case
K_PENTER
:
vga_keymap
[
map
][
i
]
=
K
(
KT_ASCII
,
'\r'
);
break
;
case
K_PCOMMA
:
vga_keymap
[
map
][
i
]
=
K
(
KT_ASCII
,
','
);
break
;
case
K_PDOT
:
vga_keymap
[
map
][
i
]
=
K
(
KT_ASCII
,
'.'
);
break
;
default:
break
;
}
}
/* Do the normal key translation */
if
((
KTYP
(
entry
.
kb_value
)
==
KT_LATIN
)
||
(
KTYP
(
entry
.
kb_value
)
==
KT_ASCII
)
||
(
KTYP
(
entry
.
kb_value
)
==
KT_LETTER
))
{
vga_keymap
[
map
][
i
]
=
entry
.
kb_value
;
}
}
}
}
}
int
FB_InGraphicsMode
(
_THIS
)
{
return
((
keyboard_fd
>=
0
)
&&
(
saved_kbd_mode
>=
0
));
}
int
FB_EnterGraphicsMode
(
_THIS
)
{
struct
termios
keyboard_termios
;
/* Set medium-raw keyboard mode */
if
((
keyboard_fd
>=
0
)
&&
!
FB_InGraphicsMode
(
this
))
{
/* Switch to the correct virtual terminal */
if
(
current_vt
>
0
)
{
struct
vt_stat
vtstate
;
if
(
ioctl
(
keyboard_fd
,
VT_GETSTATE
,
&
vtstate
)
==
0
)
{
saved_vt
=
vtstate
.
v_active
;
}
if
(
ioctl
(
keyboard_fd
,
VT_ACTIVATE
,
current_vt
)
==
0
)
{
ioctl
(
keyboard_fd
,
VT_WAITACTIVE
,
current_vt
);
}
}
/* Set the terminal input mode */
if
(
tcgetattr
(
keyboard_fd
,
&
saved_kbd_termios
)
<
0
)
{
SDL_SetError
(
"Unable to get terminal attributes"
);
if
(
keyboard_fd
>
0
)
{
close
(
keyboard_fd
);
}
keyboard_fd
=
-
1
;
return
(
-
1
);
}
if
(
ioctl
(
keyboard_fd
,
KDGKBMODE
,
&
saved_kbd_mode
)
<
0
)
{
SDL_SetError
(
"Unable to get current keyboard mode"
);
if
(
keyboard_fd
>
0
)
{
close
(
keyboard_fd
);
}
keyboard_fd
=
-
1
;
return
(
-
1
);
}
keyboard_termios
=
saved_kbd_termios
;
keyboard_termios
.
c_lflag
&=
~
(
ICANON
|
ECHO
|
ISIG
);
keyboard_termios
.
c_iflag
&=
~
(
ISTRIP
|
IGNCR
|
ICRNL
|
INLCR
|
IXOFF
|
IXON
);
keyboard_termios
.
c_cc
[
VMIN
]
=
0
;
keyboard_termios
.
c_cc
[
VTIME
]
=
0
;
if
(
tcsetattr
(
keyboard_fd
,
TCSAFLUSH
,
&
keyboard_termios
)
<
0
)
{
FB_CloseKeyboard
(
this
);
SDL_SetError
(
"Unable to set terminal attributes"
);
return
(
-
1
);
}
/* This will fail if we aren't root or this isn't our tty */
if
(
ioctl
(
keyboard_fd
,
KDSKBMODE
,
K_MEDIUMRAW
)
<
0
)
{
FB_CloseKeyboard
(
this
);
SDL_SetError
(
"Unable to set keyboard in raw mode"
);
return
(
-
1
);
}
if
(
ioctl
(
keyboard_fd
,
KDSETMODE
,
KD_GRAPHICS
)
<
0
)
{
FB_CloseKeyboard
(
this
);
SDL_SetError
(
"Unable to set keyboard in graphics mode"
);
return
(
-
1
);
}
/* Prevent switching the virtual terminal */
ioctl
(
keyboard_fd
,
VT_LOCKSWITCH
,
1
);
}
return
(
keyboard_fd
);
}
void
FB_LeaveGraphicsMode
(
_THIS
)
{
if
(
FB_InGraphicsMode
(
this
))
{
ioctl
(
keyboard_fd
,
KDSETMODE
,
KD_TEXT
);
ioctl
(
keyboard_fd
,
KDSKBMODE
,
saved_kbd_mode
);
tcsetattr
(
keyboard_fd
,
TCSAFLUSH
,
&
saved_kbd_termios
);
saved_kbd_mode
=
-
1
;
/* Head back over to the original virtual terminal */
ioctl
(
keyboard_fd
,
VT_UNLOCKSWITCH
,
1
);
if
(
saved_vt
>
0
)
{
ioctl
(
keyboard_fd
,
VT_ACTIVATE
,
saved_vt
);
}
}
}
void
FB_CloseKeyboard
(
_THIS
)
{
if
(
keyboard_fd
>=
0
)
{
FB_LeaveGraphicsMode
(
this
);
if
(
keyboard_fd
>
0
)
{
close
(
keyboard_fd
);
}
}
keyboard_fd
=
-
1
;
}
int
FB_OpenKeyboard
(
_THIS
)
{
/* Open only if not already opened */
if
(
keyboard_fd
<
0
)
{
static
const
char
*
const
tty0
[]
=
{
"/dev/tty0"
,
"/dev/vc/0"
,
NULL
};
static
const
char
*
const
vcs
[]
=
{
"/dev/vc/%d"
,
"/dev/tty%d"
,
NULL
};
int
i
,
tty0_fd
;
/* Try to query for a free virtual terminal */
tty0_fd
=
-
1
;
for
(
i
=
0
;
tty0
[
i
]
&&
(
tty0_fd
<
0
);
++
i
)
{
tty0_fd
=
open
(
tty0
[
i
],
O_WRONLY
,
0
);
}
if
(
tty0_fd
<
0
)
{
tty0_fd
=
dup
(
0
);
/* Maybe stdin is a VT? */
}
ioctl
(
tty0_fd
,
VT_OPENQRY
,
&
current_vt
);
close
(
tty0_fd
);
if
((
geteuid
()
==
0
)
&&
(
current_vt
>
0
))
{
for
(
i
=
0
;
vcs
[
i
]
&&
(
keyboard_fd
<
0
);
++
i
)
{
char
vtpath
[
12
];
SDL_snprintf
(
vtpath
,
SDL_arraysize
(
vtpath
),
vcs
[
i
],
current_vt
);
keyboard_fd
=
open
(
vtpath
,
O_RDWR
,
0
);
#ifdef DEBUG_KEYBOARD
fprintf
(
stderr
,
"vtpath = %s, fd = %d
\n
"
,
vtpath
,
keyboard_fd
);
#endif
/* DEBUG_KEYBOARD */
/* This needs to be our controlling tty
so that the kernel ioctl() calls work
*/
if
(
keyboard_fd
>=
0
)
{
tty0_fd
=
open
(
"/dev/tty"
,
O_RDWR
,
0
);
if
(
tty0_fd
>=
0
)
{
ioctl
(
tty0_fd
,
TIOCNOTTY
,
0
);
close
(
tty0_fd
);
}
}
}
}
if
(
keyboard_fd
<
0
)
{
/* Last resort, maybe our tty is a usable VT */
struct
vt_stat
vtstate
;
keyboard_fd
=
open
(
"/dev/tty"
,
O_RDWR
);
if
(
ioctl
(
keyboard_fd
,
VT_GETSTATE
,
&
vtstate
)
==
0
)
{
current_vt
=
vtstate
.
v_active
;
}
else
{
current_vt
=
0
;
}
}
#ifdef DEBUG_KEYBOARD
fprintf
(
stderr
,
"Current VT: %d
\n
"
,
current_vt
);
#endif
saved_kbd_mode
=
-
1
;
/* Make sure that our input is a console terminal */
{
int
dummy
;
if
(
ioctl
(
keyboard_fd
,
KDGKBMODE
,
&
dummy
)
<
0
)
{
close
(
keyboard_fd
);
keyboard_fd
=
-
1
;
SDL_SetError
(
"Unable to open a console terminal"
);
}
}
/* Set up keymap */
FB_vgainitkeymaps
(
keyboard_fd
);
}
return
(
keyboard_fd
);
}
static
enum
{
MOUSE_NONE
=
-
1
,
MOUSE_MSC
,
/* Note: GPM uses the MSC protocol */
MOUSE_PS2
,
MOUSE_IMPS2
,
MOUSE_MS
,
MOUSE_BM
,
MOUSE_ELO
,
MOUSE_TSLIB
,
NUM_MOUSE_DRVS
}
mouse_drv
=
MOUSE_NONE
;
void
FB_CloseMouse
(
_THIS
)
{
#if SDL_INPUT_TSLIB
if
(
ts_dev
!=
NULL
)
{
ts_close
(
ts_dev
);
ts_dev
=
NULL
;
mouse_fd
=
-
1
;
}
#endif
/* SDL_INPUT_TSLIB */
if
(
mouse_fd
>
0
)
{
close
(
mouse_fd
);
}
mouse_fd
=
-
1
;
}
/* Returns processes listed in /proc with the desired name */
static
int
find_pid
(
DIR
*
proc
,
const
char
*
wanted_name
)
{
struct
dirent
*
entry
;
int
pid
;
/* First scan proc for the gpm process */
pid
=
0
;
while
((
pid
==
0
)
&&
((
entry
=
readdir
(
proc
))
!=
NULL
))
{
if
(
isdigit
(
entry
->
d_name
[
0
]))
{
FILE
*
status
;
char
path
[
PATH_MAX
];
char
name
[
PATH_MAX
];
SDL_snprintf
(
path
,
SDL_arraysize
(
path
),
"/proc/%s/status"
,
entry
->
d_name
);
status
=
fopen
(
path
,
"r"
);
if
(
status
)
{
name
[
0
]
=
'\0'
;
fscanf
(
status
,
"Name: %s"
,
name
);
if
(
SDL_strcmp
(
name
,
wanted_name
)
==
0
)
{
pid
=
SDL_atoi
(
entry
->
d_name
);
}
fclose
(
status
);
}
}
}
return
pid
;
}
/* Returns true if /dev/gpmdata is being written to by gpm */
static
int
gpm_available
(
char
*
proto
,
size_t
protolen
)
{
int
available
;
DIR
*
proc
;
int
pid
;
int
cmdline
,
len
,
arglen
;
char
path
[
PATH_MAX
];
char
args
[
PATH_MAX
],
*
arg
;
/* Don't bother looking if the fifo isn't there */
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"testing gpm
\n
"
);
#endif
if
(
access
(
GPM_NODE_FIFO
,
F_OK
)
<
0
)
{
return
(
0
);
}
available
=
0
;
proc
=
opendir
(
"/proc"
);
if
(
proc
)
{
char
raw_proto
[
10
]
=
{
'\0'
};
char
repeat_proto
[
10
]
=
{
'\0'
};
while
(
!
available
&&
(
pid
=
find_pid
(
proc
,
"gpm"
))
>
0
)
{
SDL_snprintf
(
path
,
SDL_arraysize
(
path
),
"/proc/%d/cmdline"
,
pid
);
cmdline
=
open
(
path
,
O_RDONLY
,
0
);
if
(
cmdline
>=
0
)
{
len
=
read
(
cmdline
,
args
,
sizeof
(
args
));
arg
=
args
;
while
(
len
>
0
)
{
arglen
=
SDL_strlen
(
arg
)
+
1
;
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"gpm arg %s len %d
\n
"
,
arg
,
arglen
);
#endif
if
(
SDL_strcmp
(
arg
,
"-t"
)
==
0
)
{
/* protocol string, keep it for later */
char
*
t
,
*
s
;
t
=
arg
+
arglen
;
s
=
SDL_strchr
(
t
,
' '
);
if
(
s
)
*
s
=
0
;
SDL_strlcpy
(
raw_proto
,
t
,
SDL_arraysize
(
raw_proto
));
if
(
s
)
*
s
=
' '
;
}
if
(
SDL_strncmp
(
arg
,
"-R"
,
2
)
==
0
)
{
char
*
t
,
*
s
;
available
=
1
;
t
=
arg
+
2
;
s
=
SDL_strchr
(
t
,
' '
);
if
(
s
)
*
s
=
0
;
SDL_strlcpy
(
repeat_proto
,
t
,
SDL_arraysize
(
repeat_proto
));
if
(
s
)
*
s
=
' '
;
}
len
-=
arglen
;
arg
+=
arglen
;
}
close
(
cmdline
);
}
}
closedir
(
proc
);
if
(
available
)
{
if
(
SDL_strcmp
(
repeat_proto
,
"raw"
)
==
0
)
{
SDL_strlcpy
(
proto
,
raw_proto
,
protolen
);
}
else
if
(
*
repeat_proto
)
{
SDL_strlcpy
(
proto
,
repeat_proto
,
protolen
);
}
else
{
SDL_strlcpy
(
proto
,
"msc"
,
protolen
);
}
}
}
return
available
;
}
/* rcg06112001 Set up IMPS/2 mode, if possible. This gives
* us access to the mousewheel, etc. Returns zero if
* writes to device failed, but you still need to query the
* device to see which mode it's actually in.
*/
static
int
set_imps2_mode
(
int
fd
)
{
/* If you wanted to control the mouse mode (and we do :) ) ...
Set IMPS/2 protocol:
{0xf3,200,0xf3,100,0xf3,80}
Reset mouse device:
{0xFF}
*/
Uint8
set_imps2
[]
=
{
0xf3
,
200
,
0xf3
,
100
,
0xf3
,
80
};
/*Uint8 reset = 0xff; */
fd_set
fdset
;
struct
timeval
tv
;
int
retval
=
0
;
if
(
write
(
fd
,
&
set_imps2
,
sizeof
(
set_imps2
))
==
sizeof
(
set_imps2
))
{
/* Don't reset it, that'll clear IMPS/2 mode on some mice
if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) {
retval = 1;
}
*/
}
/* Get rid of any chatter from the above */
FD_ZERO
(
&
fdset
);
FD_SET
(
fd
,
&
fdset
);
tv
.
tv_sec
=
0
;
tv
.
tv_usec
=
0
;
while
(
select
(
fd
+
1
,
&
fdset
,
0
,
0
,
&
tv
)
>
0
)
{
char
temp
[
32
];
read
(
fd
,
temp
,
sizeof
(
temp
));
}
return
retval
;
}
/* Returns true if the mouse uses the IMPS/2 protocol */
static
int
detect_imps2
(
int
fd
)
{
int
imps2
;
imps2
=
0
;
if
(
SDL_getenv
(
"SDL_MOUSEDEV_IMPS2"
))
{
imps2
=
1
;
}
if
(
!
imps2
)
{
Uint8
query_ps2
=
0xF2
;
fd_set
fdset
;
struct
timeval
tv
;
/* Get rid of any mouse motion noise */
FD_ZERO
(
&
fdset
);
FD_SET
(
fd
,
&
fdset
);
tv
.
tv_sec
=
0
;
tv
.
tv_usec
=
0
;
while
(
select
(
fd
+
1
,
&
fdset
,
0
,
0
,
&
tv
)
>
0
)
{
char
temp
[
32
];
read
(
fd
,
temp
,
sizeof
(
temp
));
}
/* Query for the type of mouse protocol */
if
(
write
(
fd
,
&
query_ps2
,
sizeof
(
query_ps2
))
==
sizeof
(
query_ps2
))
{
Uint8
ch
=
0
;
/* Get the mouse protocol response */
do
{
FD_ZERO
(
&
fdset
);
FD_SET
(
fd
,
&
fdset
);
tv
.
tv_sec
=
1
;
tv
.
tv_usec
=
0
;
if
(
select
(
fd
+
1
,
&
fdset
,
0
,
0
,
&
tv
)
<
1
)
{
break
;
}
}
while
((
read
(
fd
,
&
ch
,
sizeof
(
ch
))
==
sizeof
(
ch
))
&&
((
ch
==
0xFA
)
||
(
ch
==
0xAA
)));
/* Experimental values (Logitech wheelmouse) */
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Last mouse mode: 0x%x
\n
"
,
ch
);
#endif
if
((
ch
==
3
)
||
(
ch
==
4
))
{
imps2
=
1
;
}
}
}
return
imps2
;
}
int
FB_OpenMouse
(
_THIS
)
{
int
i
;
const
char
*
mousedev
;
const
char
*
mousedrv
;
mousedrv
=
SDL_getenv
(
"SDL_MOUSEDRV"
);
mousedev
=
SDL_getenv
(
"SDL_MOUSEDEV"
);
mouse_fd
=
-
1
;
#if SDL_INPUT_TSLIB
if
(
mousedrv
&&
(
SDL_strcmp
(
mousedrv
,
"TSLIB"
)
==
0
))
{
if
(
mousedev
==
NULL
)
mousedev
=
SDL_getenv
(
"TSLIB_TSDEVICE"
);
if
(
mousedev
!=
NULL
)
{
ts_dev
=
ts_open
(
mousedev
,
1
);
if
((
ts_dev
!=
NULL
)
&&
(
ts_config
(
ts_dev
)
>=
0
))
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Using tslib touchscreen
\n
"
);
#endif
mouse_drv
=
MOUSE_TSLIB
;
mouse_fd
=
ts_fd
(
ts_dev
);
return
mouse_fd
;
}
}
mouse_drv
=
MOUSE_NONE
;
return
mouse_fd
;
}
#endif
/* SDL_INPUT_TSLIB */
/* ELO TOUCHSCREEN SUPPORT */
if
(
mousedrv
&&
(
SDL_strcmp
(
mousedrv
,
"ELO"
)
==
0
))
{
mouse_fd
=
open
(
mousedev
,
O_RDWR
);
if
(
mouse_fd
>=
0
)
{
if
(
eloInitController
(
mouse_fd
))
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Using ELO touchscreen
\n
"
);
#endif
mouse_drv
=
MOUSE_ELO
;
}
}
else
if
(
mouse_fd
<
0
)
{
mouse_drv
=
MOUSE_NONE
;
}
return
(
mouse_fd
);
}
/* STD MICE */
if
(
mousedev
==
NULL
)
{
/* FIXME someday... allow multiple mice in this driver */
static
const
char
*
ps2mice
[]
=
{
"/dev/input/mice"
,
"/dev/usbmouse"
,
"/dev/psaux"
,
NULL
};
/* First try to use GPM in repeater mode */
if
(
mouse_fd
<
0
)
{
char
proto
[
10
];
if
(
gpm_available
(
proto
,
SDL_arraysize
(
proto
)))
{
mouse_fd
=
open
(
GPM_NODE_FIFO
,
O_RDONLY
,
0
);
if
(
mouse_fd
>=
0
)
{
if
(
SDL_strcmp
(
proto
,
"msc"
)
==
0
)
{
mouse_drv
=
MOUSE_MSC
;
}
else
if
(
SDL_strcmp
(
proto
,
"ps2"
)
==
0
)
{
mouse_drv
=
MOUSE_PS2
;
}
else
if
(
SDL_strcmp
(
proto
,
"imps2"
)
==
0
)
{
mouse_drv
=
MOUSE_IMPS2
;
}
else
if
(
SDL_strcmp
(
proto
,
"ms"
)
==
0
||
SDL_strcmp
(
proto
,
"bare"
)
==
0
)
{
mouse_drv
=
MOUSE_MS
;
}
else
if
(
SDL_strcmp
(
proto
,
"bm"
)
==
0
)
{
mouse_drv
=
MOUSE_BM
;
}
else
{
/* Unknown protocol... */
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"GPM mouse using unknown protocol = %s
\n
"
,
proto
);
#endif
close
(
mouse_fd
);
mouse_fd
=
-
1
;
}
}
#ifdef DEBUG_MOUSE
if
(
mouse_fd
>=
0
)
{
fprintf
(
stderr
,
"Using GPM mouse, protocol = %s
\n
"
,
proto
);
}
#endif
/* DEBUG_MOUSE */
}
}
/* Now try to use a modern PS/2 mouse */
for
(
i
=
0
;
(
mouse_fd
<
0
)
&&
ps2mice
[
i
];
++
i
)
{
mouse_fd
=
open
(
ps2mice
[
i
],
O_RDWR
,
0
);
if
(
mouse_fd
<
0
)
{
mouse_fd
=
open
(
ps2mice
[
i
],
O_RDONLY
,
0
);
}
if
(
mouse_fd
>=
0
)
{
/* rcg06112001 Attempt to set IMPS/2 mode */
set_imps2_mode
(
mouse_fd
);
if
(
detect_imps2
(
mouse_fd
))
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Using IMPS2 mouse
\n
"
);
#endif
mouse_drv
=
MOUSE_IMPS2
;
}
else
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Using PS2 mouse
\n
"
);
#endif
mouse_drv
=
MOUSE_PS2
;
}
}
}
/* Next try to use a PPC ADB port mouse */
if
(
mouse_fd
<
0
)
{
mouse_fd
=
open
(
"/dev/adbmouse"
,
O_RDONLY
,
0
);
if
(
mouse_fd
>=
0
)
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Using ADB mouse
\n
"
);
#endif
mouse_drv
=
MOUSE_BM
;
}
}
}
/* Default to a serial Microsoft mouse */
if
(
mouse_fd
<
0
)
{
if
(
mousedev
==
NULL
)
{
mousedev
=
"/dev/mouse"
;
}
mouse_fd
=
open
(
mousedev
,
O_RDONLY
,
0
);
if
(
mouse_fd
>=
0
)
{
struct
termios
mouse_termios
;
/* Set the sampling speed to 1200 baud */
tcgetattr
(
mouse_fd
,
&
mouse_termios
);
mouse_termios
.
c_iflag
=
IGNBRK
|
IGNPAR
;
mouse_termios
.
c_oflag
=
0
;
mouse_termios
.
c_lflag
=
0
;
mouse_termios
.
c_line
=
0
;
mouse_termios
.
c_cc
[
VTIME
]
=
0
;
mouse_termios
.
c_cc
[
VMIN
]
=
1
;
mouse_termios
.
c_cflag
=
CREAD
|
CLOCAL
|
HUPCL
;
mouse_termios
.
c_cflag
|=
CS8
;
mouse_termios
.
c_cflag
|=
B1200
;
tcsetattr
(
mouse_fd
,
TCSAFLUSH
,
&
mouse_termios
);
if
(
mousedrv
&&
(
SDL_strcmp
(
mousedrv
,
"PS2"
)
==
0
))
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Using (user specified) PS2 mouse on %s
\n
"
,
mousedev
);
#endif
mouse_drv
=
MOUSE_PS2
;
}
else
{
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Using (default) MS mouse on %s
\n
"
,
mousedev
);
#endif
mouse_drv
=
MOUSE_MS
;
}
}
}
if
(
mouse_fd
<
0
)
{
mouse_drv
=
MOUSE_NONE
;
}
return
(
mouse_fd
);
}
static
int
posted
=
0
;
void
FB_vgamousecallback
(
int
button
,
int
relative
,
int
dx
,
int
dy
)
{
int
button_1
,
button_3
;
int
button_state
;
int
state_changed
;
int
i
;
Uint8
state
;
if
(
dx
||
dy
)
{
posted
+=
SDL_PrivateMouseMotion
(
0
,
relative
,
dx
,
dy
);
}
/* Swap button 1 and 3 */
button_1
=
(
button
&
0x04
)
>>
2
;
button_3
=
(
button
&
0x01
)
<<
2
;
button
&=
~
0x05
;
button
|=
(
button_1
|
button_3
);
/* See what changed */
button_state
=
SDL_GetMouseState
(
NULL
,
NULL
);
state_changed
=
button_state
^
button
;
for
(
i
=
0
;
i
<
8
;
++
i
)
{
if
(
state_changed
&
(
1
<<
i
))
{
if
(
button
&
(
1
<<
i
))
{
state
=
SDL_PRESSED
;
}
else
{
state
=
SDL_RELEASED
;
}
posted
+=
SDL_PrivateMouseButton
(
state
,
i
+
1
,
0
,
0
);
}
}
}
/* Handle input from tslib */
#if SDL_INPUT_TSLIB
static
void
handle_tslib
(
_THIS
)
{
struct
ts_sample
sample
;
int
button
;
while
(
ts_read
(
ts_dev
,
&
sample
,
1
)
>
0
)
{
button
=
(
sample
.
pressure
>
0
)
?
1
:
0
;
button
<<=
2
;
/* must report it as button 3 */
FB_vgamousecallback
(
button
,
0
,
sample
.
x
,
sample
.
y
);
}
return
;
}
#endif
/* SDL_INPUT_TSLIB */
/* For now, use MSC, PS/2, and MS protocols
Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.)
*/
static
void
handle_mouse
(
_THIS
)
{
static
int
start
=
0
;
static
unsigned
char
mousebuf
[
BUFSIZ
];
static
int
relative
=
1
;
int
i
,
nread
;
int
button
=
0
;
int
dx
=
0
,
dy
=
0
;
int
packetsize
=
0
;
int
realx
,
realy
;
/* Figure out the mouse packet size */
switch
(
mouse_drv
)
{
case
MOUSE_NONE
:
/* Ack! */
read
(
mouse_fd
,
mousebuf
,
BUFSIZ
);
return
;
case
MOUSE_MSC
:
packetsize
=
5
;
break
;
case
MOUSE_IMPS2
:
packetsize
=
4
;
break
;
case
MOUSE_PS2
:
case
MOUSE_MS
:
case
MOUSE_BM
:
packetsize
=
3
;
break
;
case
MOUSE_ELO
:
/* try to read the next packet */
if
(
eloReadPosition
(
this
,
mouse_fd
,
&
dx
,
&
dy
,
&
button
,
&
realx
,
&
realy
))
{
button
=
(
button
&
0x01
)
<<
2
;
FB_vgamousecallback
(
button
,
0
,
dx
,
dy
);
}
return
;
/* nothing left to do */
case
MOUSE_TSLIB
:
#if SDL_INPUT_TSLIB
handle_tslib
(
this
);
#endif
return
;
/* nothing left to do */
default:
/* Uh oh.. */
packetsize
=
0
;
break
;
}
/* Special handling for the quite sensitive ELO controller */
if
(
mouse_drv
==
MOUSE_ELO
)
{
}
/* Read as many packets as possible */
nread
=
read
(
mouse_fd
,
&
mousebuf
[
start
],
BUFSIZ
-
start
);
if
(
nread
<
0
)
{
return
;
}
nread
+=
start
;
#ifdef DEBUG_MOUSE
fprintf
(
stderr
,
"Read %d bytes from mouse, start = %d
\n
"
,
nread
,
start
);
#endif
for
(
i
=
0
;
i
<
(
nread
-
(
packetsize
-
1
));
i
+=
packetsize
)
{
switch
(
mouse_drv
)
{
case
MOUSE_NONE
:
break
;
case
MOUSE_MSC
:
/* MSC protocol has 0x80 in high byte */
if
((
mousebuf
[
i
]
&
0xF8
)
!=
0x80
)
{
/* Go to next byte */
i
-=
(
packetsize
-
1
);
continue
;
}
/* Get current mouse state */
button
=
(
~
mousebuf
[
i
])
&
0x07
;
dx
=
(
signed
char
)
(
mousebuf
[
i
+
1
])
+
(
signed
char
)
(
mousebuf
[
i
+
3
]);
dy
=
-
((
signed
char
)
(
mousebuf
[
i
+
2
])
+
(
signed
char
)
(
mousebuf
[
i
+
4
]));
break
;
case
MOUSE_PS2
:
/* PS/2 protocol has nothing in high byte */
if
((
mousebuf
[
i
]
&
0xC0
)
!=
0
)
{
/* Go to next byte */
i
-=
(
packetsize
-
1
);
continue
;
}
/* Get current mouse state */
button
=
(
mousebuf
[
i
]
&
0x04
)
>>
1
|
/*Middle */
(
mousebuf
[
i
]
&
0x02
)
>>
1
|
/*Right */
(
mousebuf
[
i
]
&
0x01
)
<<
2
;
/*Left */
dx
=
(
mousebuf
[
i
]
&
0x10
)
?
mousebuf
[
i
+
1
]
-
256
:
mousebuf
[
i
+
1
];
dy
=
(
mousebuf
[
i
]
&
0x20
)
?
-
(
mousebuf
[
i
+
2
]
-
256
)
:
-
mousebuf
[
i
+
2
];
break
;
case
MOUSE_IMPS2
:
/* Get current mouse state */
button
=
(
mousebuf
[
i
]
&
0x04
)
>>
1
|
/*Middle */
(
mousebuf
[
i
]
&
0x02
)
>>
1
|
/*Right */
(
mousebuf
[
i
]
&
0x01
)
<<
2
|
/*Left */
(
mousebuf
[
i
]
&
0x40
)
>>
3
|
/* 4 */
(
mousebuf
[
i
]
&
0x80
)
>>
3
;
/* 5 */
dx
=
(
mousebuf
[
i
]
&
0x10
)
?
mousebuf
[
i
+
1
]
-
256
:
mousebuf
[
i
+
1
];
dy
=
(
mousebuf
[
i
]
&
0x20
)
?
-
(
mousebuf
[
i
+
2
]
-
256
)
:
-
mousebuf
[
i
+
2
];
switch
(
mousebuf
[
i
+
3
]
&
0x0F
)
{
case
0x0E
:
/* DX = +1 */
case
0x02
:
/* DX = -1 */
break
;
case
0x0F
:
/* DY = +1 (map button 4) */
FB_vgamousecallback
(
button
|
(
1
<<
3
),
1
,
0
,
0
);
break
;
case
0x01
:
/* DY = -1 (map button 5) */
FB_vgamousecallback
(
button
|
(
1
<<
4
),
1
,
0
,
0
);
break
;
}
break
;
case
MOUSE_MS
:
/* Microsoft protocol has 0x40 in high byte */
if
((
mousebuf
[
i
]
&
0x40
)
!=
0x40
)
{
/* Go to next byte */
i
-=
(
packetsize
-
1
);
continue
;
}
/* Get current mouse state */
button
=
((
mousebuf
[
i
]
&
0x20
)
>>
3
)
|
((
mousebuf
[
i
]
&
0x10
)
>>
4
);
dx
=
(
signed
char
)
(((
mousebuf
[
i
]
&
0x03
)
<<
6
)
|
(
mousebuf
[
i
+
1
]
&
0x3F
));
dy
=
(
signed
char
)
(((
mousebuf
[
i
]
&
0x0C
)
<<
4
)
|
(
mousebuf
[
i
+
2
]
&
0x3F
));
break
;
case
MOUSE_BM
:
/* BusMouse protocol has 0xF8 in high byte */
if
((
mousebuf
[
i
]
&
0xF8
)
!=
0x80
)
{
/* Go to next byte */
i
-=
(
packetsize
-
1
);
continue
;
}
/* Get current mouse state */
button
=
(
~
mousebuf
[
i
])
&
0x07
;
dx
=
(
signed
char
)
mousebuf
[
i
+
1
];
dy
=
-
(
signed
char
)
mousebuf
[
i
+
2
];
break
;
default:
/* Uh oh.. */
dx
=
0
;
dy
=
0
;
break
;
}
FB_vgamousecallback
(
button
,
relative
,
dx
,
dy
);
}
if
(
i
<
nread
)
{
SDL_memcpy
(
mousebuf
,
&
mousebuf
[
i
],
(
nread
-
i
));
start
=
(
nread
-
i
);
}
else
{
start
=
0
;
}
return
;
}
/* Handle switching to another VC, returns when our VC is back */
static
void
switch_vt_prep
(
_THIS
)
{
SDL_Surface
*
screen
=
SDL_VideoSurface
;
SDL_PrivateAppActive
(
0
,
(
SDL_APPACTIVE
|
SDL_APPINPUTFOCUS
|
SDL_APPMOUSEFOCUS
));
/* Save the contents of the screen, and go to text mode */
wait_idle
(
this
);
screen_arealen
=
((
screen
->
h
+
(
2
*
this
->
offset_y
))
*
screen
->
pitch
);
screen_contents
=
(
Uint8
*
)
SDL_malloc
(
screen_arealen
);
if
(
screen_contents
)
{
SDL_memcpy
(
screen_contents
,
screen
->
pixels
,
screen_arealen
);
}
FB_SavePaletteTo
(
this
,
256
,
screen_palette
);
ioctl
(
console_fd
,
FBIOGET_VSCREENINFO
,
&
screen_vinfo
);
ioctl
(
keyboard_fd
,
KDSETMODE
,
KD_TEXT
);
ioctl
(
keyboard_fd
,
VT_UNLOCKSWITCH
,
1
);
}
static
void
switch_vt_done
(
_THIS
)
{
SDL_Surface
*
screen
=
SDL_VideoSurface
;
/* Restore graphics mode and the contents of the screen */
ioctl
(
keyboard_fd
,
VT_LOCKSWITCH
,
1
);
ioctl
(
keyboard_fd
,
KDSETMODE
,
KD_GRAPHICS
);
ioctl
(
console_fd
,
FBIOPUT_VSCREENINFO
,
&
screen_vinfo
);
FB_RestorePaletteFrom
(
this
,
256
,
screen_palette
);
if
(
screen_contents
)
{
SDL_memcpy
(
screen
->
pixels
,
screen_contents
,
screen_arealen
);
SDL_free
(
screen_contents
);
screen_contents
=
NULL
;
}
/* Get updates to the shadow surface while switched away */
if
(
SDL_ShadowSurface
)
{
SDL_UpdateRect
(
SDL_ShadowSurface
,
0
,
0
,
0
,
0
);
}
SDL_PrivateAppActive
(
1
,
(
SDL_APPACTIVE
|
SDL_APPINPUTFOCUS
|
SDL_APPMOUSEFOCUS
));
}
static
void
switch_vt
(
_THIS
,
unsigned
short
which
)
{
struct
vt_stat
vtstate
;
/* Figure out whether or not we're switching to a new console */
if
((
ioctl
(
keyboard_fd
,
VT_GETSTATE
,
&
vtstate
)
<
0
)
||
(
which
==
vtstate
.
v_active
))
{
return
;
}
/* New console, switch to it */
SDL_mutexP
(
hw_lock
);
switch_vt_prep
(
this
);
if
(
ioctl
(
keyboard_fd
,
VT_ACTIVATE
,
which
)
==
0
)
{
ioctl
(
keyboard_fd
,
VT_WAITACTIVE
,
which
);
switched_away
=
1
;
}
else
{
switch_vt_done
(
this
);
}
SDL_mutexV
(
hw_lock
);
}
static
void
handle_keyboard
(
_THIS
)
{
unsigned
char
keybuf
[
BUFSIZ
];
int
i
,
nread
;
int
pressed
;
int
scancode
;
SDL_keysym
keysym
;
nread
=
read
(
keyboard_fd
,
keybuf
,
BUFSIZ
);
for
(
i
=
0
;
i
<
nread
;
++
i
)
{
scancode
=
keybuf
[
i
]
&
0x7F
;
if
(
keybuf
[
i
]
&
0x80
)
{
pressed
=
SDL_RELEASED
;
}
else
{
pressed
=
SDL_PRESSED
;
}
TranslateKey
(
scancode
,
&
keysym
);
/* Handle Ctrl-Alt-FN for vt switch */
switch
(
keysym
.
sym
)
{
case
SDLK_F1
:
case
SDLK_F2
:
case
SDLK_F3
:
case
SDLK_F4
:
case
SDLK_F5
:
case
SDLK_F6
:
case
SDLK_F7
:
case
SDLK_F8
:
case
SDLK_F9
:
case
SDLK_F10
:
case
SDLK_F11
:
case
SDLK_F12
:
if
((
SDL_GetModState
()
&
KMOD_CTRL
)
&&
(
SDL_GetModState
()
&
KMOD_ALT
))
{
if
(
pressed
)
{
switch_vt
(
this
,
(
keysym
.
sym
-
SDLK_F1
)
+
1
);
}
break
;
}
/* Fall through to normal processing */
default:
posted
+=
SDL_PrivateKeyboard
(
pressed
,
&
keysym
);
break
;
}
}
}
void
FB_PumpEvents
(
_THIS
)
{
fd_set
fdset
;
int
max_fd
;
static
struct
timeval
zero
;
do
{
if
(
switched_away
)
{
struct
vt_stat
vtstate
;
SDL_mutexP
(
hw_lock
);
if
((
ioctl
(
keyboard_fd
,
VT_GETSTATE
,
&
vtstate
)
==
0
)
&&
vtstate
.
v_active
==
current_vt
)
{
switched_away
=
0
;
switch_vt_done
(
this
);
}
SDL_mutexV
(
hw_lock
);
}
posted
=
0
;
FD_ZERO
(
&
fdset
);
max_fd
=
0
;
if
(
keyboard_fd
>=
0
)
{
FD_SET
(
keyboard_fd
,
&
fdset
);
if
(
max_fd
<
keyboard_fd
)
{
max_fd
=
keyboard_fd
;
}
}
if
(
mouse_fd
>=
0
)
{
FD_SET
(
mouse_fd
,
&
fdset
);
if
(
max_fd
<
mouse_fd
)
{
max_fd
=
mouse_fd
;
}
}
if
(
select
(
max_fd
+
1
,
&
fdset
,
NULL
,
NULL
,
&
zero
)
>
0
)
{
if
(
keyboard_fd
>=
0
)
{
if
(
FD_ISSET
(
keyboard_fd
,
&
fdset
))
{
handle_keyboard
(
this
);
}
}
if
(
mouse_fd
>=
0
)
{
if
(
FD_ISSET
(
mouse_fd
,
&
fdset
))
{
handle_mouse
(
this
);
}
}
}
}
while
(
posted
);
}
void
FB_InitOSKeymap
(
_THIS
)
{
int
i
;
/* Initialize the Linux key translation table */
/* First get the ascii keys and others not well handled */
for
(
i
=
0
;
i
<
SDL_arraysize
(
keymap
);
++
i
)
{
switch
(
i
)
{
/* These aren't handled by the x86 kernel keymapping (?) */
case
SCANCODE_PRINTSCREEN
:
keymap
[
i
]
=
SDLK_PRINT
;
break
;
case
SCANCODE_BREAK
:
keymap
[
i
]
=
SDLK_BREAK
;
break
;
case
SCANCODE_BREAK_ALTERNATIVE
:
keymap
[
i
]
=
SDLK_PAUSE
;
break
;
case
SCANCODE_LEFTSHIFT
:
keymap
[
i
]
=
SDLK_LSHIFT
;
break
;
case
SCANCODE_RIGHTSHIFT
:
keymap
[
i
]
=
SDLK_RSHIFT
;
break
;
case
SCANCODE_LEFTCONTROL
:
keymap
[
i
]
=
SDLK_LCTRL
;
break
;
case
SCANCODE_RIGHTCONTROL
:
keymap
[
i
]
=
SDLK_RCTRL
;
break
;
case
SCANCODE_RIGHTWIN
:
keymap
[
i
]
=
SDLK_RSUPER
;
break
;
case
SCANCODE_LEFTWIN
:
keymap
[
i
]
=
SDLK_LSUPER
;
break
;
case
SCANCODE_LEFTALT
:
keymap
[
i
]
=
SDLK_LALT
;
break
;
case
SCANCODE_RIGHTALT
:
keymap
[
i
]
=
SDLK_RALT
;
break
;
case
127
:
keymap
[
i
]
=
SDLK_MENU
;
break
;
/* this should take care of all standard ascii keys */
default:
keymap
[
i
]
=
KVAL
(
vga_keymap
[
0
][
i
]);
break
;
}
}
for
(
i
=
0
;
i
<
SDL_arraysize
(
keymap
);
++
i
)
{
switch
(
keymap_temp
[
i
])
{
case
K_F1
:
keymap
[
i
]
=
SDLK_F1
;
break
;
case
K_F2
:
keymap
[
i
]
=
SDLK_F2
;
break
;
case
K_F3
:
keymap
[
i
]
=
SDLK_F3
;
break
;
case
K_F4
:
keymap
[
i
]
=
SDLK_F4
;
break
;
case
K_F5
:
keymap
[
i
]
=
SDLK_F5
;
break
;
case
K_F6
:
keymap
[
i
]
=
SDLK_F6
;
break
;
case
K_F7
:
keymap
[
i
]
=
SDLK_F7
;
break
;
case
K_F8
:
keymap
[
i
]
=
SDLK_F8
;
break
;
case
K_F9
:
keymap
[
i
]
=
SDLK_F9
;
break
;
case
K_F10
:
keymap
[
i
]
=
SDLK_F10
;
break
;
case
K_F11
:
keymap
[
i
]
=
SDLK_F11
;
break
;
case
K_F12
:
keymap
[
i
]
=
SDLK_F12
;
break
;
case
K_DOWN
:
keymap
[
i
]
=
SDLK_DOWN
;
break
;
case
K_LEFT
:
keymap
[
i
]
=
SDLK_LEFT
;
break
;
case
K_RIGHT
:
keymap
[
i
]
=
SDLK_RIGHT
;
break
;
case
K_UP
:
keymap
[
i
]
=
SDLK_UP
;
break
;
case
K_P0
:
keymap
[
i
]
=
SDLK_KP0
;
break
;
case
K_P1
:
keymap
[
i
]
=
SDLK_KP1
;
break
;
case
K_P2
:
keymap
[
i
]
=
SDLK_KP2
;
break
;
case
K_P3
:
keymap
[
i
]
=
SDLK_KP3
;
break
;
case
K_P4
:
keymap
[
i
]
=
SDLK_KP4
;
break
;
case
K_P5
:
keymap
[
i
]
=
SDLK_KP5
;
break
;
case
K_P6
:
keymap
[
i
]
=
SDLK_KP6
;
break
;
case
K_P7
:
keymap
[
i
]
=
SDLK_KP7
;
break
;
case
K_P8
:
keymap
[
i
]
=
SDLK_KP8
;
break
;
case
K_P9
:
keymap
[
i
]
=
SDLK_KP9
;
break
;
case
K_PPLUS
:
keymap
[
i
]
=
SDLK_KP_PLUS
;
break
;
case
K_PMINUS
:
keymap
[
i
]
=
SDLK_KP_MINUS
;
break
;
case
K_PSTAR
:
keymap
[
i
]
=
SDLK_KP_MULTIPLY
;
break
;
case
K_PSLASH
:
keymap
[
i
]
=
SDLK_KP_DIVIDE
;
break
;
case
K_PENTER
:
keymap
[
i
]
=
SDLK_KP_ENTER
;
break
;
case
K_PDOT
:
keymap
[
i
]
=
SDLK_KP_PERIOD
;
break
;
case
K_SHIFT
:
if
(
keymap
[
i
]
!=
SDLK_RSHIFT
)
keymap
[
i
]
=
SDLK_LSHIFT
;
break
;
case
K_SHIFTL
:
keymap
[
i
]
=
SDLK_LSHIFT
;
break
;
case
K_SHIFTR
:
keymap
[
i
]
=
SDLK_RSHIFT
;
break
;
case
K_CTRL
:
if
(
keymap
[
i
]
!=
SDLK_RCTRL
)
keymap
[
i
]
=
SDLK_LCTRL
;
break
;
case
K_CTRLL
:
keymap
[
i
]
=
SDLK_LCTRL
;
break
;
case
K_CTRLR
:
keymap
[
i
]
=
SDLK_RCTRL
;
break
;
case
K_ALT
:
keymap
[
i
]
=
SDLK_LALT
;
break
;
case
K_ALTGR
:
keymap
[
i
]
=
SDLK_RALT
;
break
;
case
K_INSERT
:
keymap
[
i
]
=
SDLK_INSERT
;
break
;
case
K_REMOVE
:
keymap
[
i
]
=
SDLK_DELETE
;
break
;
case
K_PGUP
:
keymap
[
i
]
=
SDLK_PAGEUP
;
break
;
case
K_PGDN
:
keymap
[
i
]
=
SDLK_PAGEDOWN
;
break
;
case
K_FIND
:
keymap
[
i
]
=
SDLK_HOME
;
break
;
case
K_SELECT
:
keymap
[
i
]
=
SDLK_END
;
break
;
case
K_NUM
:
keymap
[
i
]
=
SDLK_NUMLOCK
;
break
;
case
K_CAPS
:
keymap
[
i
]
=
SDLK_CAPSLOCK
;
break
;
case
K_F13
:
keymap
[
i
]
=
SDLK_PRINT
;
break
;
case
K_HOLD
:
keymap
[
i
]
=
SDLK_SCROLLOCK
;
break
;
case
K_PAUSE
:
keymap
[
i
]
=
SDLK_PAUSE
;
break
;
case
127
:
keymap
[
i
]
=
SDLK_BACKSPACE
;
break
;
default:
break
;
}
}
}
static
SDL_keysym
*
TranslateKey
(
int
scancode
,
SDL_keysym
*
keysym
)
{
/* Set the keysym information */
keysym
->
scancode
=
scancode
;
keysym
->
sym
=
keymap
[
scancode
];
keysym
->
mod
=
KMOD_NONE
;
/* If UNICODE is on, get the UNICODE value for the key */
keysym
->
unicode
=
0
;
if
(
SDL_TranslateUNICODE
)
{
int
map
;
SDLMod
modstate
;
modstate
=
SDL_GetModState
();
map
=
0
;
if
(
modstate
&
KMOD_SHIFT
)
{
map
|=
(
1
<<
KG_SHIFT
);
}
if
(
modstate
&
KMOD_CTRL
)
{
map
|=
(
1
<<
KG_CTRL
);
}
if
(
modstate
&
KMOD_LALT
)
{
map
|=
(
1
<<
KG_ALT
);
}
if
(
modstate
&
KMOD_RALT
)
{
map
|=
(
1
<<
KG_ALTGR
);
}
if
(
KTYP
(
vga_keymap
[
map
][
scancode
])
==
KT_LETTER
)
{
if
(
modstate
&
KMOD_CAPS
)
{
map
^=
(
1
<<
KG_SHIFT
);
}
}
if
(
KTYP
(
vga_keymap
[
map
][
scancode
])
==
KT_PAD
)
{
if
(
modstate
&
KMOD_NUM
)
{
keysym
->
unicode
=
KVAL
(
vga_keymap
[
map
][
scancode
]);
}
}
else
{
keysym
->
unicode
=
KVAL
(
vga_keymap
[
map
][
scancode
]);
}
}
return
(
keysym
);
}
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbevents_c.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include "SDL_fbvideo.h"
/* Variables and functions exported by SDL_sysevents.c to other parts
of the native video subsystem (SDL_sysvideo.c)
*/
extern
int
FB_OpenKeyboard
(
_THIS
);
extern
void
FB_CloseKeyboard
(
_THIS
);
extern
int
FB_OpenMouse
(
_THIS
);
extern
void
FB_CloseMouse
(
_THIS
);
extern
int
FB_EnterGraphicsMode
(
_THIS
);
extern
int
FB_InGraphicsMode
(
_THIS
);
extern
void
FB_LeaveGraphicsMode
(
_THIS
);
extern
void
FB_InitOSKeymap
(
_THIS
);
extern
void
FB_PumpEvents
(
_THIS
);
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbkeys.h
deleted
100644 → 0
View file @
c14d8951
/* Scancodes for the Linux framebuffer console
- Taken with thanks from SVGAlib 1.4.0
*/
#define SCANCODE_ESCAPE 1
#define SCANCODE_1 2
#define SCANCODE_2 3
#define SCANCODE_3 4
#define SCANCODE_4 5
#define SCANCODE_5 6
#define SCANCODE_6 7
#define SCANCODE_7 8
#define SCANCODE_8 9
#define SCANCODE_9 10
#define SCANCODE_0 11
#define SCANCODE_MINUS 12
#define SCANCODE_EQUAL 13
#define SCANCODE_BACKSPACE 14
#define SCANCODE_TAB 15
#define SCANCODE_Q 16
#define SCANCODE_W 17
#define SCANCODE_E 18
#define SCANCODE_R 19
#define SCANCODE_T 20
#define SCANCODE_Y 21
#define SCANCODE_U 22
#define SCANCODE_I 23
#define SCANCODE_O 24
#define SCANCODE_P 25
#define SCANCODE_BRACKET_LEFT 26
#define SCANCODE_BRACKET_RIGHT 27
#define SCANCODE_ENTER 28
#define SCANCODE_LEFTCONTROL 29
#define SCANCODE_A 30
#define SCANCODE_S 31
#define SCANCODE_D 32
#define SCANCODE_F 33
#define SCANCODE_G 34
#define SCANCODE_H 35
#define SCANCODE_J 36
#define SCANCODE_K 37
#define SCANCODE_L 38
#define SCANCODE_SEMICOLON 39
#define SCANCODE_APOSTROPHE 40
#define SCANCODE_GRAVE 41
#define SCANCODE_LEFTSHIFT 42
#define SCANCODE_BACKSLASH 43
#define SCANCODE_Z 44
#define SCANCODE_X 45
#define SCANCODE_C 46
#define SCANCODE_V 47
#define SCANCODE_B 48
#define SCANCODE_N 49
#define SCANCODE_M 50
#define SCANCODE_COMMA 51
#define SCANCODE_PERIOD 52
#define SCANCODE_SLASH 53
#define SCANCODE_RIGHTSHIFT 54
#define SCANCODE_KEYPADMULTIPLY 55
#define SCANCODE_LEFTALT 56
#define SCANCODE_SPACE 57
#define SCANCODE_CAPSLOCK 58
#define SCANCODE_F1 59
#define SCANCODE_F2 60
#define SCANCODE_F3 61
#define SCANCODE_F4 62
#define SCANCODE_F5 63
#define SCANCODE_F6 64
#define SCANCODE_F7 65
#define SCANCODE_F8 66
#define SCANCODE_F9 67
#define SCANCODE_F10 68
#define SCANCODE_NUMLOCK 69
#define SCANCODE_SCROLLLOCK 70
#define SCANCODE_KEYPAD7 71
#define SCANCODE_CURSORUPLEFT 71
#define SCANCODE_KEYPAD8 72
#define SCANCODE_CURSORUP 72
#define SCANCODE_KEYPAD9 73
#define SCANCODE_CURSORUPRIGHT 73
#define SCANCODE_KEYPADMINUS 74
#define SCANCODE_KEYPAD4 75
#define SCANCODE_CURSORLEFT 75
#define SCANCODE_KEYPAD5 76
#define SCANCODE_KEYPAD6 77
#define SCANCODE_CURSORRIGHT 77
#define SCANCODE_KEYPADPLUS 78
#define SCANCODE_KEYPAD1 79
#define SCANCODE_CURSORDOWNLEFT 79
#define SCANCODE_KEYPAD2 80
#define SCANCODE_CURSORDOWN 80
#define SCANCODE_KEYPAD3 81
#define SCANCODE_CURSORDOWNRIGHT 81
#define SCANCODE_KEYPAD0 82
#define SCANCODE_KEYPADPERIOD 83
#define SCANCODE_LESS 86
#define SCANCODE_F11 87
#define SCANCODE_F12 88
#define SCANCODE_KEYPADENTER 96
#define SCANCODE_RIGHTCONTROL 97
#define SCANCODE_CONTROL 97
#define SCANCODE_KEYPADDIVIDE 98
#define SCANCODE_PRINTSCREEN 99
#define SCANCODE_RIGHTALT 100
#define SCANCODE_BREAK 101
/* Beware: is 119 */
#define SCANCODE_BREAK_ALTERNATIVE 119
/* on some keyboards! */
#define SCANCODE_HOME 102
#define SCANCODE_CURSORBLOCKUP 103
/* Cursor key block */
#define SCANCODE_PAGEUP 104
#define SCANCODE_CURSORBLOCKLEFT 105
/* Cursor key block */
#define SCANCODE_CURSORBLOCKRIGHT 106
/* Cursor key block */
#define SCANCODE_END 107
#define SCANCODE_CURSORBLOCKDOWN 108
/* Cursor key block */
#define SCANCODE_PAGEDOWN 109
#define SCANCODE_INSERT 110
#define SCANCODE_REMOVE 111
#define SCANCODE_RIGHTWIN 126
#define SCANCODE_LEFTWIN 125
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbmatrox.c
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include "SDL_video.h"
#include "../SDL_blit.h"
#include "SDL_fbmatrox.h"
#include "matrox_mmio.h"
/* Wait for vertical retrace - taken from the XFree86 Matrox driver */
static
void
WaitVBL
(
_THIS
)
{
int
count
;
/* find start of retrace */
mga_waitidle
();
while
((
mga_in8
(
0x1FDA
)
&
0x08
));
while
(
!
(
mga_in8
(
0x1FDA
)
&
0x08
));
/* wait until we're past the start */
count
=
mga_in32
(
0x1E20
)
+
2
;
while
(
mga_in32
(
0x1E20
)
<
count
);
}
static
void
WaitIdle
(
_THIS
)
{
mga_waitidle
();
}
/* Sets video mem colorkey and accelerated blit function */
static
int
SetHWColorKey
(
_THIS
,
SDL_Surface
*
surface
,
Uint32
key
)
{
return
(
0
);
}
/* Sets per surface hardware alpha value */
#if 0
static int
SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 value)
{
return (0);
}
#endif
static
int
FillHWRect
(
_THIS
,
SDL_Surface
*
dst
,
SDL_Rect
*
rect
,
Uint32
color
)
{
int
dstX
,
dstY
;
Uint32
fxbndry
;
Uint32
ydstlen
;
Uint32
fillop
;
/* Don't blit to the display surface when switched away */
if
(
switched_away
)
{
return
-
2
;
/* no hardware access */
}
if
(
dst
==
this
->
screen
)
{
SDL_mutexP
(
hw_lock
);
}
switch
(
dst
->
format
->
BytesPerPixel
)
{
case
1
:
color
|=
(
color
<<
8
);
case
2
:
color
|=
(
color
<<
16
);
break
;
}
/* Set up the X/Y base coordinates */
FB_dst_to_xy
(
this
,
dst
,
&
dstX
,
&
dstY
);
/* Adjust for the current rectangle */
dstX
+=
rect
->
x
;
dstY
+=
rect
->
y
;
/* Set up the X boundaries */
fxbndry
=
(
dstX
|
((
dstX
+
rect
->
w
)
<<
16
));
/* Set up the Y boundaries */
ydstlen
=
(
rect
->
h
|
(
dstY
<<
16
));
/* Set up for color fill operation */
fillop
=
MGADWG_TRAP
|
MGADWG_SOLID
|
MGADWG_ARZERO
|
MGADWG_SGNZERO
|
MGADWG_SHIFTZERO
;
/* Execute the operations! */
mga_wait
(
5
);
mga_out32
(
MGAREG_DWGCTL
,
fillop
|
MGADWG_REPLACE
);
mga_out32
(
MGAREG_FCOL
,
color
);
mga_out32
(
MGAREG_FXBNDRY
,
fxbndry
);
mga_out32
(
MGAREG_YDSTLEN
+
MGAREG_EXEC
,
ydstlen
);
FB_AddBusySurface
(
dst
);
if
(
dst
==
this
->
screen
)
{
SDL_mutexV
(
hw_lock
);
}
return
(
0
);
}
static
int
HWAccelBlit
(
SDL_Surface
*
src
,
SDL_Rect
*
srcrect
,
SDL_Surface
*
dst
,
SDL_Rect
*
dstrect
)
{
SDL_VideoDevice
*
this
=
current_video
;
int
pitch
,
w
,
h
;
int
srcX
,
srcY
;
int
dstX
,
dstY
;
Uint32
sign
;
Uint32
start
,
stop
;
int
skip
;
Uint32
blitop
;
/* FIXME: For now, only blit to display surface */
if
(
dst
->
pitch
!=
SDL_VideoSurface
->
pitch
)
{
return
(
src
->
map
->
sw_blit
(
src
,
srcrect
,
dst
,
dstrect
));
}
/* Don't blit to the display surface when switched away */
if
(
switched_away
)
{
return
-
2
;
/* no hardware access */
}
if
(
dst
==
this
->
screen
)
{
SDL_mutexP
(
hw_lock
);
}
/* Calculate source and destination base coordinates (in pixels) */
w
=
dstrect
->
w
;
h
=
dstrect
->
h
;
FB_dst_to_xy
(
this
,
src
,
&
srcX
,
&
srcY
);
FB_dst_to_xy
(
this
,
dst
,
&
dstX
,
&
dstY
);
/* Adjust for the current blit rectangles */
srcX
+=
srcrect
->
x
;
srcY
+=
srcrect
->
y
;
dstX
+=
dstrect
->
x
;
dstY
+=
dstrect
->
y
;
pitch
=
dst
->
pitch
/
dst
->
format
->
BytesPerPixel
;
/* Set up the blit direction (sign) flags */
sign
=
0
;
if
(
srcX
<
dstX
)
{
sign
|=
1
;
}
if
(
srcY
<
dstY
)
{
sign
|=
4
;
srcY
+=
(
h
-
1
);
dstY
+=
(
h
-
1
);
}
/* Set up the blit source row start, end, and skip (in pixels) */
stop
=
start
=
(
srcY
*
pitch
)
+
srcX
;
if
(
srcX
<
dstX
)
{
start
+=
(
w
-
1
);
}
else
{
stop
+=
(
w
-
1
);
}
if
(
srcY
<
dstY
)
{
skip
=
-
pitch
;
}
else
{
skip
=
pitch
;
}
/* Set up the blit operation */
if
((
src
->
flags
&
SDL_SRCCOLORKEY
)
==
SDL_SRCCOLORKEY
)
{
Uint32
colorkey
;
blitop
=
MGADWG_BFCOL
|
MGADWG_BITBLT
|
MGADWG_SHIFTZERO
|
MGADWG_RSTR
|
(
0x0C
<<
16
)
|
MGADWG_TRANSC
;
colorkey
=
src
->
format
->
colorkey
;
switch
(
dst
->
format
->
BytesPerPixel
)
{
case
1
:
colorkey
|=
(
colorkey
<<
8
);
case
2
:
colorkey
|=
(
colorkey
<<
16
);
break
;
}
mga_wait
(
2
);
mga_out32
(
MGAREG_FCOL
,
colorkey
);
mga_out32
(
MGAREG_BCOL
,
0xFFFFFFFF
);
}
else
{
blitop
=
MGADWG_BFCOL
|
MGADWG_BITBLT
|
MGADWG_SHIFTZERO
|
MGADWG_RSTR
|
(
0x0C
<<
16
);
}
mga_wait
(
7
);
mga_out32
(
MGAREG_SGN
,
sign
);
mga_out32
(
MGAREG_AR3
,
start
);
mga_out32
(
MGAREG_AR0
,
stop
);
mga_out32
(
MGAREG_AR5
,
skip
);
mga_out32
(
MGAREG_FXBNDRY
,
(
dstX
|
((
dstX
+
w
-
1
)
<<
16
)));
mga_out32
(
MGAREG_YDSTLEN
,
(
dstY
<<
16
)
|
h
);
mga_out32
(
MGAREG_DWGCTL
+
MGAREG_EXEC
,
blitop
);
FB_AddBusySurface
(
src
);
FB_AddBusySurface
(
dst
);
if
(
dst
==
this
->
screen
)
{
SDL_mutexV
(
hw_lock
);
}
return
(
0
);
}
static
int
CheckHWBlit
(
_THIS
,
SDL_Surface
*
src
,
SDL_Surface
*
dst
)
{
int
accelerated
;
/* Set initial acceleration on */
src
->
flags
|=
SDL_HWACCEL
;
/* Set the surface attributes */
if
((
src
->
flags
&
SDL_SRCALPHA
)
==
SDL_SRCALPHA
)
{
if
(
!
this
->
info
.
blit_hw_A
)
{
src
->
flags
&=
~
SDL_HWACCEL
;
}
}
if
((
src
->
flags
&
SDL_SRCCOLORKEY
)
==
SDL_SRCCOLORKEY
)
{
if
(
!
this
->
info
.
blit_hw_CC
)
{
src
->
flags
&=
~
SDL_HWACCEL
;
}
}
/* Check to see if final surface blit is accelerated */
accelerated
=
!!
(
src
->
flags
&
SDL_HWACCEL
);
if
(
accelerated
)
{
src
->
map
->
hw_blit
=
HWAccelBlit
;
}
return
(
accelerated
);
}
void
FB_MatroxAccel
(
_THIS
,
__u32
card
)
{
/* We have hardware accelerated surface functions */
this
->
CheckHWBlit
=
CheckHWBlit
;
wait_vbl
=
WaitVBL
;
wait_idle
=
WaitIdle
;
/* The Matrox has an accelerated color fill */
this
->
info
.
blit_fill
=
1
;
this
->
FillHWRect
=
FillHWRect
;
/* The Matrox has accelerated normal and colorkey blits. */
this
->
info
.
blit_hw
=
1
;
/* The Millenium I appears to do the colorkey test a word
at a time, and the transparency is intverted. (?)
*/
if
(
card
!=
FB_ACCEL_MATROX_MGA2064W
)
{
this
->
info
.
blit_hw_CC
=
1
;
this
->
SetHWColorKey
=
SetHWColorKey
;
}
#if 0 /* Not yet implemented? */
/* The Matrox G200/G400 has an accelerated alpha blit */
if ((card == FB_ACCEL_MATROX_MGAG200)
|| (card == FB_ACCEL_MATROX_MGAG400)) {
this->info.blit_hw_A = 1;
this->SetHWAlpha = SetHWAlpha;
}
#endif
}
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbmatrox.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* Matrox hardware acceleration for the SDL framebuffer console driver */
#include "SDL_fbvideo.h"
/* Set up the driver for Matrox acceleration */
extern
void
FB_MatroxAccel
(
_THIS
,
__u32
card
);
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbmouse.c
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include "SDL_mouse.h"
#include "../../events/SDL_events_c.h"
#include "SDL_fbvideo.h"
#include "SDL_fbmouse_c.h"
/* The implementation dependent data for the window manager cursor */
struct
WMcursor
{
int
unused
;
};
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbmouse_c.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include "SDL_fbvideo.h"
/* Functions to be exported */
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbriva.c
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include "SDL_video.h"
#include "../SDL_blit.h"
#include "SDL_fbriva.h"
#include "riva_mmio.h"
#include "riva_regs.h"
static
int
FifoEmptyCount
=
0
;
static
int
FifoFreeCount
=
0
;
/* Wait for vertical retrace */
static
void
WaitVBL
(
_THIS
)
{
volatile
Uint8
*
port
=
(
Uint8
*
)
(
mapped_io
+
PCIO_OFFSET
+
0x3DA
);
while
((
*
port
&
0x08
));
while
(
!
(
*
port
&
0x08
));
}
static
void
NV3WaitIdle
(
_THIS
)
{
RivaRop
*
Rop
=
(
RivaRop
*
)
(
mapped_io
+
ROP_OFFSET
);
while
((
Rop
->
FifoFree
<
FifoEmptyCount
)
||
(
*
(
mapped_io
+
PGRAPH_OFFSET
+
0x000006B0
)
&
0x01
));
}
static
void
NV4WaitIdle
(
_THIS
)
{
RivaRop
*
Rop
=
(
RivaRop
*
)
(
mapped_io
+
ROP_OFFSET
);
while
((
Rop
->
FifoFree
<
FifoEmptyCount
)
||
(
*
(
mapped_io
+
PGRAPH_OFFSET
+
0x00000700
)
&
0x01
));
}
#if 0 /* Not yet implemented? */
/* Sets video mem colorkey and accelerated blit function */
static int
SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key)
{
return (0);
}
/* Sets per surface hardware alpha value */
static int
SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 value)
{
return (0);
}
#endif /* Not yet implemented */
static
int
FillHWRect
(
_THIS
,
SDL_Surface
*
dst
,
SDL_Rect
*
rect
,
Uint32
color
)
{
int
dstX
,
dstY
;
int
dstW
,
dstH
;
RivaBitmap
*
Bitmap
=
(
RivaBitmap
*
)
(
mapped_io
+
BITMAP_OFFSET
);
/* Don't blit to the display surface when switched away */
if
(
switched_away
)
{
return
-
2
;
/* no hardware access */
}
if
(
dst
==
this
->
screen
)
{
SDL_mutexP
(
hw_lock
);
}
/* Set up the X/Y base coordinates */
dstW
=
rect
->
w
;
dstH
=
rect
->
h
;
FB_dst_to_xy
(
this
,
dst
,
&
dstX
,
&
dstY
);
/* Adjust for the current rectangle */
dstX
+=
rect
->
x
;
dstY
+=
rect
->
y
;
RIVA_FIFO_FREE
(
Bitmap
,
1
);
Bitmap
->
Color1A
=
color
;
RIVA_FIFO_FREE
(
Bitmap
,
2
);
Bitmap
->
UnclippedRectangle
[
0
].
TopLeft
=
(
dstX
<<
16
)
|
dstY
;
Bitmap
->
UnclippedRectangle
[
0
].
WidthHeight
=
(
dstW
<<
16
)
|
dstH
;
FB_AddBusySurface
(
dst
);
if
(
dst
==
this
->
screen
)
{
SDL_mutexV
(
hw_lock
);
}
return
(
0
);
}
static
int
HWAccelBlit
(
SDL_Surface
*
src
,
SDL_Rect
*
srcrect
,
SDL_Surface
*
dst
,
SDL_Rect
*
dstrect
)
{
SDL_VideoDevice
*
this
=
current_video
;
int
srcX
,
srcY
;
int
dstX
,
dstY
;
int
dstW
,
dstH
;
RivaScreenBlt
*
Blt
=
(
RivaScreenBlt
*
)
(
mapped_io
+
BLT_OFFSET
);
/* FIXME: For now, only blit to display surface */
if
(
dst
->
pitch
!=
SDL_VideoSurface
->
pitch
)
{
return
(
src
->
map
->
sw_blit
(
src
,
srcrect
,
dst
,
dstrect
));
}
/* Don't blit to the display surface when switched away */
if
(
switched_away
)
{
return
-
2
;
/* no hardware access */
}
if
(
dst
==
this
->
screen
)
{
SDL_mutexP
(
hw_lock
);
}
/* Calculate source and destination base coordinates (in pixels) */
dstW
=
dstrect
->
w
;
dstH
=
dstrect
->
h
;
FB_dst_to_xy
(
this
,
src
,
&
srcX
,
&
srcY
);
FB_dst_to_xy
(
this
,
dst
,
&
dstX
,
&
dstY
);
/* Adjust for the current blit rectangles */
srcX
+=
srcrect
->
x
;
srcY
+=
srcrect
->
y
;
dstX
+=
dstrect
->
x
;
dstY
+=
dstrect
->
y
;
RIVA_FIFO_FREE
(
Blt
,
3
);
Blt
->
TopLeftSrc
=
(
srcY
<<
16
)
|
srcX
;
Blt
->
TopLeftDst
=
(
dstY
<<
16
)
|
dstX
;
Blt
->
WidthHeight
=
(
dstH
<<
16
)
|
dstW
;
FB_AddBusySurface
(
src
);
FB_AddBusySurface
(
dst
);
if
(
dst
==
this
->
screen
)
{
SDL_mutexV
(
hw_lock
);
}
return
(
0
);
}
static
int
CheckHWBlit
(
_THIS
,
SDL_Surface
*
src
,
SDL_Surface
*
dst
)
{
int
accelerated
;
/* Set initial acceleration on */
src
->
flags
|=
SDL_HWACCEL
;
/* Set the surface attributes */
if
((
src
->
flags
&
SDL_SRCALPHA
)
==
SDL_SRCALPHA
)
{
if
(
!
this
->
info
.
blit_hw_A
)
{
src
->
flags
&=
~
SDL_HWACCEL
;
}
}
if
((
src
->
flags
&
SDL_SRCCOLORKEY
)
==
SDL_SRCCOLORKEY
)
{
if
(
!
this
->
info
.
blit_hw_CC
)
{
src
->
flags
&=
~
SDL_HWACCEL
;
}
}
/* Check to see if final surface blit is accelerated */
accelerated
=
!!
(
src
->
flags
&
SDL_HWACCEL
);
if
(
accelerated
)
{
src
->
map
->
hw_blit
=
HWAccelBlit
;
}
return
(
accelerated
);
}
void
FB_RivaAccel
(
_THIS
,
__u32
card
)
{
RivaRop
*
Rop
=
(
RivaRop
*
)
(
mapped_io
+
ROP_OFFSET
);
/* We have hardware accelerated surface functions */
this
->
CheckHWBlit
=
CheckHWBlit
;
wait_vbl
=
WaitVBL
;
switch
(
card
)
{
case
FB_ACCEL_NV3
:
wait_idle
=
NV3WaitIdle
;
break
;
case
FB_ACCEL_NV4
:
wait_idle
=
NV4WaitIdle
;
break
;
default:
/* Hmm... FIXME */
break
;
}
FifoEmptyCount
=
Rop
->
FifoFree
;
/* The Riva has an accelerated color fill */
this
->
info
.
blit_fill
=
1
;
this
->
FillHWRect
=
FillHWRect
;
/* The Riva has accelerated normal and colorkey blits. */
this
->
info
.
blit_hw
=
1
;
#if 0 /* Not yet implemented? */
this->info.blit_hw_CC = 1;
this->SetHWColorKey = SetHWColorKey;
#endif
#if 0 /* Not yet implemented? */
/* The Riva has an accelerated alpha blit */
this->info.blit_hw_A = 1;
this->SetHWAlpha = SetHWAlpha;
#endif
}
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbriva.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* Riva hardware acceleration for the SDL framebuffer console driver */
#include "SDL_fbvideo.h"
#ifndef FB_ACCEL_NV3
#define FB_ACCEL_NV3 27
#endif
#ifndef FB_ACCEL_NV4
#define FB_ACCEL_NV4 28
#endif
/* Set up the driver for Riva acceleration */
extern
void
FB_RivaAccel
(
_THIS
,
__u32
card
);
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbvideo.c
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* Framebuffer console based SDL video driver implementation.
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#ifndef HAVE_GETPAGESIZE
#include <asm/page.h>
/* For definition of PAGE_SIZE */
#endif
#include <linux/vt.h>
#include "SDL_video.h"
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#include "SDL_fbvideo.h"
#include "SDL_fbmouse_c.h"
#include "SDL_fbevents_c.h"
#include "SDL_fb3dfx.h"
#include "SDL_fbmatrox.h"
#include "SDL_fbriva.h"
/*#define FBCON_DEBUG*/
#if defined(i386) && defined(FB_TYPE_VGA_PLANES)
#define VGA16_FBCON_SUPPORT
#include <sys/io.h>
/* For ioperm() */
#ifndef FB_AUX_VGA_PLANES_VGA4
#define FB_AUX_VGA_PLANES_VGA4 0
#endif
/*
static inline void outb (unsigned char value, unsigned short port)
{
__asm__ __volatile__ ("outb %b0,%w1"::"a" (value), "Nd" (port));
}
*/
#endif
/* FB_TYPE_VGA_PLANES */
/* A list of video resolutions that we query for (sorted largest to smallest) */
static
const
SDL_Rect
checkres
[]
=
{
{
0
,
0
,
1600
,
1200
},
/* 16 bpp: 0x11E, or 286 */
{
0
,
0
,
1408
,
1056
},
/* 16 bpp: 0x19A, or 410 */
{
0
,
0
,
1280
,
1024
},
/* 16 bpp: 0x11A, or 282 */
{
0
,
0
,
1152
,
864
},
/* 16 bpp: 0x192, or 402 */
{
0
,
0
,
1024
,
768
},
/* 16 bpp: 0x117, or 279 */
{
0
,
0
,
960
,
720
},
/* 16 bpp: 0x18A, or 394 */
{
0
,
0
,
800
,
600
},
/* 16 bpp: 0x114, or 276 */
{
0
,
0
,
768
,
576
},
/* 16 bpp: 0x182, or 386 */
{
0
,
0
,
720
,
576
},
/* PAL */
{
0
,
0
,
720
,
480
},
/* NTSC */
{
0
,
0
,
640
,
480
},
/* 16 bpp: 0x111, or 273 */
{
0
,
0
,
640
,
400
},
/* 8 bpp: 0x100, or 256 */
{
0
,
0
,
512
,
384
},
{
0
,
0
,
320
,
240
},
{
0
,
0
,
320
,
200
}
};
static
const
struct
{
int
xres
;
int
yres
;
int
pixclock
;
int
left
;
int
right
;
int
upper
;
int
lower
;
int
hslen
;
int
vslen
;
int
sync
;
int
vmode
;
}
vesa_timings
[]
=
{
#ifdef USE_VESA_TIMINGS
/* Only tested on Matrox Millenium I */
{
640
,
400
,
39771
,
48
,
16
,
39
,
8
,
96
,
2
,
2
,
0
},
/* 70 Hz */
{
640
,
480
,
39683
,
48
,
16
,
33
,
10
,
96
,
2
,
0
,
0
},
/* 60 Hz */
{
768
,
576
,
26101
,
144
,
16
,
28
,
6
,
112
,
4
,
0
,
0
},
/* 60 Hz */
{
800
,
600
,
24038
,
144
,
24
,
28
,
8
,
112
,
6
,
0
,
0
},
/* 60 Hz */
{
960
,
720
,
17686
,
144
,
24
,
28
,
8
,
112
,
4
,
0
,
0
},
/* 60 Hz */
{
1024
,
768
,
15386
,
160
,
32
,
30
,
4
,
128
,
4
,
0
,
0
},
/* 60 Hz */
{
1152
,
864
,
12286
,
192
,
32
,
30
,
4
,
128
,
4
,
0
,
0
},
/* 60 Hz */
{
1280
,
1024
,
9369
,
224
,
32
,
32
,
4
,
136
,
4
,
0
,
0
},
/* 60 Hz */
{
1408
,
1056
,
8214
,
256
,
40
,
32
,
5
,
144
,
5
,
0
,
0
},
/* 60 Hz */
{
1600
,
1200
,
/*? */
0
,
272
,
48
,
32
,
5
,
152
,
5
,
0
,
0
},
/* 60 Hz */
#else
/* You can generate these timings from your XF86Config file using
the 'modeline2fb' perl script included with the fbset package.
These timings were generated for Matrox Millenium I, 15" monitor.
*/
{
320
,
200
,
79440
,
16
,
16
,
20
,
4
,
48
,
1
,
0
,
2
},
/* 70 Hz */
{
320
,
240
,
63492
,
16
,
16
,
16
,
4
,
48
,
2
,
0
,
2
},
/* 72 Hz */
{
512
,
384
,
49603
,
48
,
16
,
16
,
1
,
64
,
3
,
0
,
0
},
/* 78 Hz */
{
640
,
400
,
31746
,
96
,
32
,
41
,
1
,
64
,
3
,
2
,
0
},
/* 85 Hz */
{
640
,
480
,
31746
,
120
,
16
,
16
,
1
,
64
,
3
,
0
,
0
},
/* 75 Hz */
{
768
,
576
,
26101
,
144
,
16
,
28
,
6
,
112
,
4
,
0
,
0
},
/* 60 Hz */
{
800
,
600
,
20000
,
64
,
56
,
23
,
37
,
120
,
6
,
3
,
0
},
/* 72 Hz */
{
960
,
720
,
17686
,
144
,
24
,
28
,
8
,
112
,
4
,
0
,
0
},
/* 60 Hz */
{
1024
,
768
,
13333
,
144
,
24
,
29
,
3
,
136
,
6
,
0
,
0
},
/* 70 Hz */
{
1152
,
864
,
12286
,
192
,
32
,
30
,
4
,
128
,
4
,
0
,
0
},
/* 60 Hz */
{
1280
,
1024
,
9369
,
224
,
32
,
32
,
4
,
136
,
4
,
0
,
0
},
/* 60 Hz */
{
1408
,
1056
,
8214
,
256
,
40
,
32
,
5
,
144
,
5
,
0
,
0
},
/* 60 Hz */
{
1600
,
1200
,
/*? */
0
,
272
,
48
,
32
,
5
,
152
,
5
,
0
,
0
},
/* 60 Hz */
#endif
};
/* Initialization/Query functions */
static
int
FB_VideoInit
(
_THIS
,
SDL_PixelFormat
*
vformat
);
static
SDL_Rect
**
FB_ListModes
(
_THIS
,
SDL_PixelFormat
*
format
,
Uint32
flags
);
static
SDL_Surface
*
FB_SetVideoMode
(
_THIS
,
SDL_Surface
*
current
,
int
width
,
int
height
,
int
bpp
,
Uint32
flags
);
#ifdef VGA16_FBCON_SUPPORT
static
SDL_Surface
*
FB_SetVGA16Mode
(
_THIS
,
SDL_Surface
*
current
,
int
width
,
int
height
,
int
bpp
,
Uint32
flags
);
#endif
static
int
FB_SetColors
(
_THIS
,
int
firstcolor
,
int
ncolors
,
SDL_Color
*
colors
);
static
void
FB_VideoQuit
(
_THIS
);
/* Hardware surface functions */
static
int
FB_InitHWSurfaces
(
_THIS
,
SDL_Surface
*
screen
,
char
*
base
,
int
size
);
static
void
FB_FreeHWSurfaces
(
_THIS
);
static
int
FB_AllocHWSurface
(
_THIS
,
SDL_Surface
*
surface
);
static
int
FB_LockHWSurface
(
_THIS
,
SDL_Surface
*
surface
);
static
void
FB_UnlockHWSurface
(
_THIS
,
SDL_Surface
*
surface
);
static
void
FB_FreeHWSurface
(
_THIS
,
SDL_Surface
*
surface
);
static
void
FB_WaitVBL
(
_THIS
);
static
void
FB_WaitIdle
(
_THIS
);
static
int
FB_FlipHWSurface
(
_THIS
,
SDL_Surface
*
surface
);
/* Internal palette functions */
static
void
FB_SavePalette
(
_THIS
,
struct
fb_fix_screeninfo
*
finfo
,
struct
fb_var_screeninfo
*
vinfo
);
static
void
FB_RestorePalette
(
_THIS
);
static
int
SDL_getpagesize
(
void
)
{
#ifdef HAVE_GETPAGESIZE
return
getpagesize
();
#elif defined(PAGE_SIZE)
return
PAGE_SIZE
;
#else
#error Can not determine system page size.
/* this is what it USED to be in Linux... */
return
4096
;
#endif
}
/* Small wrapper for mmap() so we can play nicely with no-mmu hosts
* (non-mmu hosts disallow the MAP_SHARED flag) */
static
void
*
do_mmap
(
void
*
start
,
size_t
length
,
int
prot
,
int
flags
,
int
fd
,
off_t
offset
)
{
void
*
ret
;
ret
=
mmap
(
start
,
length
,
prot
,
flags
,
fd
,
offset
);
if
(
ret
==
(
char
*
)
-
1
&&
(
flags
&
MAP_SHARED
))
{
ret
=
mmap
(
start
,
length
,
prot
,
(
flags
&
~
MAP_SHARED
)
|
MAP_PRIVATE
,
fd
,
offset
);
}
return
ret
;
}
/* FB driver bootstrap functions */
static
int
FB_Available
(
void
)
{
int
console
=
-
1
;
/* Added check for /fb/0 (devfs) */
/* but - use environment variable first... if it fails, still check defaults */
int
idx
=
0
;
const
char
*
SDL_fbdevs
[
4
]
=
{
NULL
,
"/dev/fb0"
,
"/dev/fb/0"
,
NULL
};
SDL_fbdevs
[
0
]
=
SDL_getenv
(
"SDL_FBDEV"
);
if
(
!
SDL_fbdevs
[
0
])
idx
++
;
for
(;
SDL_fbdevs
[
idx
];
idx
++
)
{
console
=
open
(
SDL_fbdevs
[
idx
],
O_RDWR
,
0
);
if
(
console
>=
0
)
{
close
(
console
);
break
;
}
}
return
(
console
>=
0
);
}
static
void
FB_DeleteDevice
(
SDL_VideoDevice
*
device
)
{
SDL_free
(
device
->
hidden
);
SDL_free
(
device
);
}
static
SDL_VideoDevice
*
FB_CreateDevice
(
int
devindex
)
{
SDL_VideoDevice
*
this
;
/* Initialize all variables that we clean on shutdown */
this
=
(
SDL_VideoDevice
*
)
SDL_malloc
(
sizeof
(
SDL_VideoDevice
));
if
(
this
)
{
SDL_memset
(
this
,
0
,
(
sizeof
*
this
));
this
->
hidden
=
(
struct
SDL_PrivateVideoData
*
)
SDL_malloc
((
sizeof
*
this
->
hidden
));
}
if
((
this
==
NULL
)
||
(
this
->
hidden
==
NULL
))
{
SDL_OutOfMemory
();
if
(
this
)
{
SDL_free
(
this
);
}
return
(
0
);
}
SDL_memset
(
this
->
hidden
,
0
,
(
sizeof
*
this
->
hidden
));
wait_vbl
=
FB_WaitVBL
;
wait_idle
=
FB_WaitIdle
;
mouse_fd
=
-
1
;
keyboard_fd
=
-
1
;
/* Set the function pointers */
this
->
VideoInit
=
FB_VideoInit
;
this
->
ListModes
=
FB_ListModes
;
this
->
SetVideoMode
=
FB_SetVideoMode
;
this
->
SetColors
=
FB_SetColors
;
this
->
UpdateRects
=
NULL
;
this
->
VideoQuit
=
FB_VideoQuit
;
this
->
AllocHWSurface
=
FB_AllocHWSurface
;
this
->
CheckHWBlit
=
NULL
;
this
->
FillHWRect
=
NULL
;
this
->
SetHWColorKey
=
NULL
;
this
->
SetHWAlpha
=
NULL
;
this
->
LockHWSurface
=
FB_LockHWSurface
;
this
->
UnlockHWSurface
=
FB_UnlockHWSurface
;
this
->
FlipHWSurface
=
FB_FlipHWSurface
;
this
->
FreeHWSurface
=
FB_FreeHWSurface
;
this
->
SetCaption
=
NULL
;
this
->
SetIcon
=
NULL
;
this
->
IconifyWindow
=
NULL
;
this
->
GrabInput
=
NULL
;
this
->
GetWMInfo
=
NULL
;
this
->
InitOSKeymap
=
FB_InitOSKeymap
;
this
->
PumpEvents
=
FB_PumpEvents
;
this
->
free
=
FB_DeleteDevice
;
return
this
;
}
VideoBootStrap
FBCON_bootstrap
=
{
"fbcon"
,
"Linux Framebuffer Console"
,
FB_Available
,
FB_CreateDevice
};
#define FB_MODES_DB "/etc/fb.modes"
static
int
read_fbmodes_line
(
FILE
*
f
,
char
*
line
,
int
length
)
{
int
blank
;
char
*
c
;
int
i
;
blank
=
0
;
/* find a relevant line */
do
{
if
(
!
fgets
(
line
,
length
,
f
))
return
0
;
c
=
line
;
while
(((
*
c
==
'\t'
)
||
(
*
c
==
' '
))
&&
(
*
c
!=
0
))
c
++
;
if
((
*
c
==
'\n'
)
||
(
*
c
==
'#'
)
||
(
*
c
==
0
))
blank
=
1
;
else
blank
=
0
;
}
while
(
blank
);
/* remove whitespace at the begining of the string */
i
=
0
;
do
{
line
[
i
]
=
c
[
i
];
i
++
;
}
while
(
c
[
i
]
!=
0
);
return
1
;
}
static
int
read_fbmodes_mode
(
FILE
*
f
,
struct
fb_var_screeninfo
*
vinfo
)
{
char
line
[
1024
];
char
option
[
256
];
/* Find a "geometry" */
do
{
if
(
read_fbmodes_line
(
f
,
line
,
sizeof
(
line
))
==
0
)
return
0
;
if
(
SDL_strncmp
(
line
,
"geometry"
,
8
)
==
0
)
break
;
}
while
(
1
);
SDL_sscanf
(
line
,
"geometry %d %d %d %d %d"
,
&
vinfo
->
xres
,
&
vinfo
->
yres
,
&
vinfo
->
xres_virtual
,
&
vinfo
->
yres_virtual
,
&
vinfo
->
bits_per_pixel
);
if
(
read_fbmodes_line
(
f
,
line
,
sizeof
(
line
))
==
0
)
return
0
;
SDL_sscanf
(
line
,
"timings %d %d %d %d %d %d %d"
,
&
vinfo
->
pixclock
,
&
vinfo
->
left_margin
,
&
vinfo
->
right_margin
,
&
vinfo
->
upper_margin
,
&
vinfo
->
lower_margin
,
&
vinfo
->
hsync_len
,
&
vinfo
->
vsync_len
);
vinfo
->
sync
=
0
;
vinfo
->
vmode
=
FB_VMODE_NONINTERLACED
;
/* Parse misc options */
do
{
if
(
read_fbmodes_line
(
f
,
line
,
sizeof
(
line
))
==
0
)
return
0
;
if
(
SDL_strncmp
(
line
,
"hsync"
,
5
)
==
0
)
{
SDL_sscanf
(
line
,
"hsync %s"
,
option
);
if
(
SDL_strncmp
(
option
,
"high"
,
4
)
==
0
)
vinfo
->
sync
|=
FB_SYNC_HOR_HIGH_ACT
;
}
else
if
(
SDL_strncmp
(
line
,
"vsync"
,
5
)
==
0
)
{
SDL_sscanf
(
line
,
"vsync %s"
,
option
);
if
(
SDL_strncmp
(
option
,
"high"
,
4
)
==
0
)
vinfo
->
sync
|=
FB_SYNC_VERT_HIGH_ACT
;
}
else
if
(
SDL_strncmp
(
line
,
"csync"
,
5
)
==
0
)
{
SDL_sscanf
(
line
,
"csync %s"
,
option
);
if
(
SDL_strncmp
(
option
,
"high"
,
4
)
==
0
)
vinfo
->
sync
|=
FB_SYNC_COMP_HIGH_ACT
;
}
else
if
(
SDL_strncmp
(
line
,
"extsync"
,
5
)
==
0
)
{
SDL_sscanf
(
line
,
"extsync %s"
,
option
);
if
(
SDL_strncmp
(
option
,
"true"
,
4
)
==
0
)
vinfo
->
sync
|=
FB_SYNC_EXT
;
}
else
if
(
SDL_strncmp
(
line
,
"laced"
,
5
)
==
0
)
{
SDL_sscanf
(
line
,
"laced %s"
,
option
);
if
(
SDL_strncmp
(
option
,
"true"
,
4
)
==
0
)
vinfo
->
vmode
|=
FB_VMODE_INTERLACED
;
}
else
if
(
SDL_strncmp
(
line
,
"double"
,
6
)
==
0
)
{
SDL_sscanf
(
line
,
"double %s"
,
option
);
if
(
SDL_strncmp
(
option
,
"true"
,
4
)
==
0
)
vinfo
->
vmode
|=
FB_VMODE_DOUBLE
;
}
}
while
(
SDL_strncmp
(
line
,
"endmode"
,
7
)
!=
0
);
return
1
;
}
static
int
FB_CheckMode
(
_THIS
,
struct
fb_var_screeninfo
*
vinfo
,
int
index
,
unsigned
int
*
w
,
unsigned
int
*
h
)
{
int
mode_okay
;
mode_okay
=
0
;
vinfo
->
bits_per_pixel
=
(
index
+
1
)
*
8
;
vinfo
->
xres
=
*
w
;
vinfo
->
xres_virtual
=
*
w
;
vinfo
->
yres
=
*
h
;
vinfo
->
yres_virtual
=
*
h
;
vinfo
->
activate
=
FB_ACTIVATE_TEST
;
if
(
ioctl
(
console_fd
,
FBIOPUT_VSCREENINFO
,
vinfo
)
==
0
)
{
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Checked mode %dx%d at %d bpp, got mode %dx%d at %d bpp
\n
"
,
*
w
,
*
h
,
(
index
+
1
)
*
8
,
vinfo
->
xres
,
vinfo
->
yres
,
vinfo
->
bits_per_pixel
);
#endif
if
((((
vinfo
->
bits_per_pixel
+
7
)
/
8
)
-
1
)
==
index
)
{
*
w
=
vinfo
->
xres
;
*
h
=
vinfo
->
yres
;
mode_okay
=
1
;
}
}
return
mode_okay
;
}
static
int
FB_AddMode
(
_THIS
,
int
index
,
unsigned
int
w
,
unsigned
int
h
,
int
check_timings
)
{
SDL_Rect
*
mode
;
int
i
;
int
next_mode
;
/* Check to see if we already have this mode */
if
(
SDL_nummodes
[
index
]
>
0
)
{
mode
=
SDL_modelist
[
index
][
SDL_nummodes
[
index
]
-
1
];
if
((
mode
->
w
==
w
)
&&
(
mode
->
h
==
h
))
{
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"We already have mode %dx%d at %d bytes per pixel
\n
"
,
w
,
h
,
index
+
1
);
#endif
return
(
0
);
}
}
/* Only allow a mode if we have a valid timing for it */
if
(
check_timings
)
{
int
found_timing
=
0
;
for
(
i
=
0
;
i
<
(
sizeof
(
vesa_timings
)
/
sizeof
(
vesa_timings
[
0
]));
++
i
)
{
if
((
w
==
vesa_timings
[
i
].
xres
)
&&
(
h
==
vesa_timings
[
i
].
yres
)
&&
vesa_timings
[
i
].
pixclock
)
{
found_timing
=
1
;
break
;
}
}
if
(
!
found_timing
)
{
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"No valid timing line for mode %dx%d
\n
"
,
w
,
h
);
#endif
return
(
0
);
}
}
/* Set up the new video mode rectangle */
mode
=
(
SDL_Rect
*
)
SDL_malloc
(
sizeof
*
mode
);
if
(
mode
==
NULL
)
{
SDL_OutOfMemory
();
return
(
-
1
);
}
mode
->
x
=
0
;
mode
->
y
=
0
;
mode
->
w
=
w
;
mode
->
h
=
h
;
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Adding mode %dx%d at %d bytes per pixel
\n
"
,
w
,
h
,
index
+
1
);
#endif
/* Allocate the new list of modes, and fill in the new mode */
next_mode
=
SDL_nummodes
[
index
];
SDL_modelist
[
index
]
=
(
SDL_Rect
**
)
SDL_realloc
(
SDL_modelist
[
index
],
(
1
+
next_mode
+
1
)
*
sizeof
(
SDL_Rect
*
));
if
(
SDL_modelist
[
index
]
==
NULL
)
{
SDL_OutOfMemory
();
SDL_nummodes
[
index
]
=
0
;
SDL_free
(
mode
);
return
(
-
1
);
}
SDL_modelist
[
index
][
next_mode
]
=
mode
;
SDL_modelist
[
index
][
next_mode
+
1
]
=
NULL
;
SDL_nummodes
[
index
]
++
;
return
(
0
);
}
static
int
cmpmodes
(
const
void
*
va
,
const
void
*
vb
)
{
const
SDL_Rect
*
a
=
*
(
const
SDL_Rect
**
)
va
;
const
SDL_Rect
*
b
=
*
(
const
SDL_Rect
**
)
vb
;
if
(
a
->
h
==
b
->
h
)
return
b
->
w
-
a
->
w
;
else
return
b
->
h
-
a
->
h
;
}
static
void
FB_SortModes
(
_THIS
)
{
int
i
;
for
(
i
=
0
;
i
<
NUM_MODELISTS
;
++
i
)
{
if
(
SDL_nummodes
[
i
]
>
0
)
{
SDL_qsort
(
SDL_modelist
[
i
],
SDL_nummodes
[
i
],
sizeof
*
SDL_modelist
[
i
],
cmpmodes
);
}
}
}
static
int
FB_VideoInit
(
_THIS
,
SDL_PixelFormat
*
vformat
)
{
const
int
pagesize
=
SDL_getpagesize
();
struct
fb_fix_screeninfo
finfo
;
struct
fb_var_screeninfo
vinfo
;
int
i
,
j
;
int
current_index
;
unsigned
int
current_w
;
unsigned
int
current_h
;
const
char
*
SDL_fbdev
;
FILE
*
modesdb
;
/* Initialize the library */
SDL_fbdev
=
SDL_getenv
(
"SDL_FBDEV"
);
if
(
SDL_fbdev
==
NULL
)
{
SDL_fbdev
=
"/dev/fb0"
;
}
console_fd
=
open
(
SDL_fbdev
,
O_RDWR
,
0
);
if
(
console_fd
<
0
)
{
SDL_SetError
(
"Unable to open %s"
,
SDL_fbdev
);
return
(
-
1
);
}
#if !SDL_THREADS_DISABLED
/* Create the hardware surface lock mutex */
hw_lock
=
SDL_CreateMutex
();
if
(
hw_lock
==
NULL
)
{
SDL_SetError
(
"Unable to create lock mutex"
);
FB_VideoQuit
(
this
);
return
(
-
1
);
}
#endif
/* Get the type of video hardware */
if
(
ioctl
(
console_fd
,
FBIOGET_FSCREENINFO
,
&
finfo
)
<
0
)
{
SDL_SetError
(
"Couldn't get console hardware info"
);
FB_VideoQuit
(
this
);
return
(
-
1
);
}
switch
(
finfo
.
type
)
{
case
FB_TYPE_PACKED_PIXELS
:
/* Supported, no worries.. */
break
;
#ifdef VGA16_FBCON_SUPPORT
case
FB_TYPE_VGA_PLANES
:
/* VGA16 is supported, but that's it */
if
(
finfo
.
type_aux
==
FB_AUX_VGA_PLANES_VGA4
)
{
if
(
ioperm
(
0x3b4
,
0x3df
-
0x3b4
+
1
,
1
)
<
0
)
{
SDL_SetError
(
"No I/O port permissions"
);
FB_VideoQuit
(
this
);
return
(
-
1
);
}
this
->
SetVideoMode
=
FB_SetVGA16Mode
;
break
;
}
/* Fall through to unsupported case */
#endif
/* VGA16_FBCON_SUPPORT */
default:
SDL_SetError
(
"Unsupported console hardware"
);
FB_VideoQuit
(
this
);
return
(
-
1
);
}
switch
(
finfo
.
visual
)
{
case
FB_VISUAL_TRUECOLOR
:
case
FB_VISUAL_PSEUDOCOLOR
:
case
FB_VISUAL_STATIC_PSEUDOCOLOR
:
case
FB_VISUAL_DIRECTCOLOR
:
break
;
default:
SDL_SetError
(
"Unsupported console hardware"
);
FB_VideoQuit
(
this
);
return
(
-
1
);
}
/* Check if the user wants to disable hardware acceleration */
{
const
char
*
fb_accel
;
fb_accel
=
SDL_getenv
(
"SDL_FBACCEL"
);
if
(
fb_accel
)
{
finfo
.
accel
=
SDL_atoi
(
fb_accel
);
}
}
/* Memory map the device, compensating for buggy PPC mmap() */
mapped_offset
=
(((
long
)
finfo
.
smem_start
)
-
(((
long
)
finfo
.
smem_start
)
&
~
(
pagesize
-
1
)));
mapped_memlen
=
finfo
.
smem_len
+
mapped_offset
;
mapped_mem
=
do_mmap
(
NULL
,
mapped_memlen
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
console_fd
,
0
);
if
(
mapped_mem
==
(
char
*
)
-
1
)
{
SDL_SetError
(
"Unable to memory map the video hardware"
);
mapped_mem
=
NULL
;
FB_VideoQuit
(
this
);
return
(
-
1
);
}
/* Determine the current screen depth */
if
(
ioctl
(
console_fd
,
FBIOGET_VSCREENINFO
,
&
vinfo
)
<
0
)
{
SDL_SetError
(
"Couldn't get console pixel format"
);
FB_VideoQuit
(
this
);
return
(
-
1
);
}
vformat
->
BitsPerPixel
=
vinfo
.
bits_per_pixel
;
if
(
vformat
->
BitsPerPixel
<
8
)
{
/* Assuming VGA16, we handle this via a shadow framebuffer */
vformat
->
BitsPerPixel
=
8
;
}
for
(
i
=
0
;
i
<
vinfo
.
red
.
length
;
++
i
)
{
vformat
->
Rmask
<<=
1
;
vformat
->
Rmask
|=
(
0x00000001
<<
vinfo
.
red
.
offset
);
}
for
(
i
=
0
;
i
<
vinfo
.
green
.
length
;
++
i
)
{
vformat
->
Gmask
<<=
1
;
vformat
->
Gmask
|=
(
0x00000001
<<
vinfo
.
green
.
offset
);
}
for
(
i
=
0
;
i
<
vinfo
.
blue
.
length
;
++
i
)
{
vformat
->
Bmask
<<=
1
;
vformat
->
Bmask
|=
(
0x00000001
<<
vinfo
.
blue
.
offset
);
}
saved_vinfo
=
vinfo
;
/* Save hardware palette, if needed */
FB_SavePalette
(
this
,
&
finfo
,
&
vinfo
);
/* If the I/O registers are available, memory map them so we
can take advantage of any supported hardware acceleration.
*/
vinfo
.
accel_flags
=
0
;
/* Temporarily reserve registers */
ioctl
(
console_fd
,
FBIOPUT_VSCREENINFO
,
&
vinfo
);
if
(
finfo
.
accel
&&
finfo
.
mmio_len
)
{
mapped_iolen
=
finfo
.
mmio_len
;
mapped_io
=
do_mmap
(
NULL
,
mapped_iolen
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
console_fd
,
mapped_memlen
);
if
(
mapped_io
==
(
char
*
)
-
1
)
{
/* Hmm, failed to memory map I/O registers */
mapped_io
=
NULL
;
}
}
/* Query for the list of available video modes */
current_w
=
vinfo
.
xres
;
current_h
=
vinfo
.
yres
;
current_index
=
((
vinfo
.
bits_per_pixel
+
7
)
/
8
)
-
1
;
modesdb
=
fopen
(
FB_MODES_DB
,
"r"
);
for
(
i
=
0
;
i
<
NUM_MODELISTS
;
++
i
)
{
SDL_nummodes
[
i
]
=
0
;
SDL_modelist
[
i
]
=
NULL
;
}
if
(
SDL_getenv
(
"SDL_FB_BROKEN_MODES"
)
!=
NULL
)
{
FB_AddMode
(
this
,
current_index
,
current_w
,
current_h
,
0
);
}
else
if
(
modesdb
)
{
while
(
read_fbmodes_mode
(
modesdb
,
&
vinfo
))
{
for
(
i
=
0
;
i
<
NUM_MODELISTS
;
++
i
)
{
unsigned
int
w
,
h
;
/* See if we are querying for the current mode */
w
=
vinfo
.
xres
;
h
=
vinfo
.
yres
;
if
(
i
==
current_index
)
{
if
((
current_w
>
w
)
||
(
current_h
>
h
))
{
/* Only check once */
FB_AddMode
(
this
,
i
,
current_w
,
current_h
,
0
);
current_index
=
-
1
;
}
}
if
(
FB_CheckMode
(
this
,
&
vinfo
,
i
,
&
w
,
&
h
))
{
FB_AddMode
(
this
,
i
,
w
,
h
,
0
);
}
}
}
fclose
(
modesdb
);
FB_SortModes
(
this
);
}
else
{
for
(
i
=
0
;
i
<
NUM_MODELISTS
;
++
i
)
{
for
(
j
=
0
;
j
<
(
sizeof
(
checkres
)
/
sizeof
(
checkres
[
0
]));
++
j
)
{
unsigned
int
w
,
h
;
/* See if we are querying for the current mode */
w
=
checkres
[
j
].
w
;
h
=
checkres
[
j
].
h
;
if
(
i
==
current_index
)
{
if
((
current_w
>
w
)
||
(
current_h
>
h
))
{
/* Only check once */
FB_AddMode
(
this
,
i
,
current_w
,
current_h
,
0
);
current_index
=
-
1
;
}
}
if
(
FB_CheckMode
(
this
,
&
vinfo
,
i
,
&
w
,
&
h
))
{
FB_AddMode
(
this
,
i
,
w
,
h
,
1
);
}
}
}
}
/* Fill in our hardware acceleration capabilities */
this
->
info
.
current_w
=
current_w
;
this
->
info
.
current_h
=
current_h
;
this
->
info
.
wm_available
=
0
;
this
->
info
.
hw_available
=
1
;
this
->
info
.
video_mem
=
finfo
.
smem_len
/
1024
;
if
(
mapped_io
)
{
switch
(
finfo
.
accel
)
{
case
FB_ACCEL_MATROX_MGA2064W
:
case
FB_ACCEL_MATROX_MGA1064SG
:
case
FB_ACCEL_MATROX_MGA2164W
:
case
FB_ACCEL_MATROX_MGA2164W_AGP
:
case
FB_ACCEL_MATROX_MGAG100
:
/*case FB_ACCEL_MATROX_MGAG200: G200 acceleration broken! */
case
FB_ACCEL_MATROX_MGAG400
:
#ifdef FBACCEL_DEBUG
printf
(
"Matrox hardware accelerator!
\n
"
);
#endif
FB_MatroxAccel
(
this
,
finfo
.
accel
);
break
;
case
FB_ACCEL_3DFX_BANSHEE
:
#ifdef FBACCEL_DEBUG
printf
(
"3DFX hardware accelerator!
\n
"
);
#endif
FB_3DfxAccel
(
this
,
finfo
.
accel
);
break
;
case
FB_ACCEL_NV3
:
case
FB_ACCEL_NV4
:
#ifdef FBACCEL_DEBUG
printf
(
"NVidia hardware accelerator!
\n
"
);
#endif
FB_RivaAccel
(
this
,
finfo
.
accel
);
break
;
default:
#ifdef FBACCEL_DEBUG
printf
(
"Unknown hardware accelerator.
\n
"
);
#endif
break
;
}
}
/* Enable mouse and keyboard support */
if
(
FB_OpenKeyboard
(
this
)
<
0
)
{
FB_VideoQuit
(
this
);
return
(
-
1
);
}
if
(
FB_OpenMouse
(
this
)
<
0
)
{
const
char
*
sdl_nomouse
;
sdl_nomouse
=
SDL_getenv
(
"SDL_NOMOUSE"
);
if
(
!
sdl_nomouse
)
{
SDL_SetError
(
"Unable to open mouse"
);
FB_VideoQuit
(
this
);
return
(
-
1
);
}
}
/* We're done! */
return
(
0
);
}
static
SDL_Rect
**
FB_ListModes
(
_THIS
,
SDL_PixelFormat
*
format
,
Uint32
flags
)
{
return
(
SDL_modelist
[((
format
->
BitsPerPixel
+
7
)
/
8
)
-
1
]);
}
/* Various screen update functions available */
static
void
FB_DirectUpdate
(
_THIS
,
int
numrects
,
SDL_Rect
*
rects
);
#ifdef VGA16_FBCON_SUPPORT
static
void
FB_VGA16Update
(
_THIS
,
int
numrects
,
SDL_Rect
*
rects
);
#endif
#ifdef FBCON_DEBUG
static
void
print_vinfo
(
struct
fb_var_screeninfo
*
vinfo
)
{
fprintf
(
stderr
,
"Printing vinfo:
\n
"
);
fprintf
(
stderr
,
"
\t
xres: %d
\n
"
,
vinfo
->
xres
);
fprintf
(
stderr
,
"
\t
yres: %d
\n
"
,
vinfo
->
yres
);
fprintf
(
stderr
,
"
\t
xres_virtual: %d
\n
"
,
vinfo
->
xres_virtual
);
fprintf
(
stderr
,
"
\t
yres_virtual: %d
\n
"
,
vinfo
->
yres_virtual
);
fprintf
(
stderr
,
"
\t
xoffset: %d
\n
"
,
vinfo
->
xoffset
);
fprintf
(
stderr
,
"
\t
yoffset: %d
\n
"
,
vinfo
->
yoffset
);
fprintf
(
stderr
,
"
\t
bits_per_pixel: %d
\n
"
,
vinfo
->
bits_per_pixel
);
fprintf
(
stderr
,
"
\t
grayscale: %d
\n
"
,
vinfo
->
grayscale
);
fprintf
(
stderr
,
"
\t
nonstd: %d
\n
"
,
vinfo
->
nonstd
);
fprintf
(
stderr
,
"
\t
activate: %d
\n
"
,
vinfo
->
activate
);
fprintf
(
stderr
,
"
\t
height: %d
\n
"
,
vinfo
->
height
);
fprintf
(
stderr
,
"
\t
width: %d
\n
"
,
vinfo
->
width
);
fprintf
(
stderr
,
"
\t
accel_flags: %d
\n
"
,
vinfo
->
accel_flags
);
fprintf
(
stderr
,
"
\t
pixclock: %d
\n
"
,
vinfo
->
pixclock
);
fprintf
(
stderr
,
"
\t
left_margin: %d
\n
"
,
vinfo
->
left_margin
);
fprintf
(
stderr
,
"
\t
right_margin: %d
\n
"
,
vinfo
->
right_margin
);
fprintf
(
stderr
,
"
\t
upper_margin: %d
\n
"
,
vinfo
->
upper_margin
);
fprintf
(
stderr
,
"
\t
lower_margin: %d
\n
"
,
vinfo
->
lower_margin
);
fprintf
(
stderr
,
"
\t
hsync_len: %d
\n
"
,
vinfo
->
hsync_len
);
fprintf
(
stderr
,
"
\t
vsync_len: %d
\n
"
,
vinfo
->
vsync_len
);
fprintf
(
stderr
,
"
\t
sync: %d
\n
"
,
vinfo
->
sync
);
fprintf
(
stderr
,
"
\t
vmode: %d
\n
"
,
vinfo
->
vmode
);
fprintf
(
stderr
,
"
\t
red: %d/%d
\n
"
,
vinfo
->
red
.
length
,
vinfo
->
red
.
offset
);
fprintf
(
stderr
,
"
\t
green: %d/%d
\n
"
,
vinfo
->
green
.
length
,
vinfo
->
green
.
offset
);
fprintf
(
stderr
,
"
\t
blue: %d/%d
\n
"
,
vinfo
->
blue
.
length
,
vinfo
->
blue
.
offset
);
fprintf
(
stderr
,
"
\t
alpha: %d/%d
\n
"
,
vinfo
->
transp
.
length
,
vinfo
->
transp
.
offset
);
}
static
void
print_finfo
(
struct
fb_fix_screeninfo
*
finfo
)
{
fprintf
(
stderr
,
"Printing finfo:
\n
"
);
fprintf
(
stderr
,
"
\t
smem_start = %p
\n
"
,
(
char
*
)
finfo
->
smem_start
);
fprintf
(
stderr
,
"
\t
smem_len = %d
\n
"
,
finfo
->
smem_len
);
fprintf
(
stderr
,
"
\t
type = %d
\n
"
,
finfo
->
type
);
fprintf
(
stderr
,
"
\t
type_aux = %d
\n
"
,
finfo
->
type_aux
);
fprintf
(
stderr
,
"
\t
visual = %d
\n
"
,
finfo
->
visual
);
fprintf
(
stderr
,
"
\t
xpanstep = %d
\n
"
,
finfo
->
xpanstep
);
fprintf
(
stderr
,
"
\t
ypanstep = %d
\n
"
,
finfo
->
ypanstep
);
fprintf
(
stderr
,
"
\t
ywrapstep = %d
\n
"
,
finfo
->
ywrapstep
);
fprintf
(
stderr
,
"
\t
line_length = %d
\n
"
,
finfo
->
line_length
);
fprintf
(
stderr
,
"
\t
mmio_start = %p
\n
"
,
(
char
*
)
finfo
->
mmio_start
);
fprintf
(
stderr
,
"
\t
mmio_len = %d
\n
"
,
finfo
->
mmio_len
);
fprintf
(
stderr
,
"
\t
accel = %d
\n
"
,
finfo
->
accel
);
}
#endif
static
int
choose_fbmodes_mode
(
struct
fb_var_screeninfo
*
vinfo
)
{
int
matched
;
FILE
*
modesdb
;
struct
fb_var_screeninfo
cinfo
;
matched
=
0
;
modesdb
=
fopen
(
FB_MODES_DB
,
"r"
);
if
(
modesdb
)
{
/* Parse the mode definition file */
while
(
read_fbmodes_mode
(
modesdb
,
&
cinfo
))
{
if
((
vinfo
->
xres
==
cinfo
.
xres
&&
vinfo
->
yres
==
cinfo
.
yres
)
&&
(
!
matched
||
(
vinfo
->
bits_per_pixel
==
cinfo
.
bits_per_pixel
)))
{
vinfo
->
pixclock
=
cinfo
.
pixclock
;
vinfo
->
left_margin
=
cinfo
.
left_margin
;
vinfo
->
right_margin
=
cinfo
.
right_margin
;
vinfo
->
upper_margin
=
cinfo
.
upper_margin
;
vinfo
->
lower_margin
=
cinfo
.
lower_margin
;
vinfo
->
hsync_len
=
cinfo
.
hsync_len
;
vinfo
->
vsync_len
=
cinfo
.
vsync_len
;
if
(
matched
)
{
break
;
}
matched
=
1
;
}
}
fclose
(
modesdb
);
}
return
(
matched
);
}
static
int
choose_vesa_mode
(
struct
fb_var_screeninfo
*
vinfo
)
{
int
matched
;
int
i
;
/* Check for VESA timings */
matched
=
0
;
for
(
i
=
0
;
i
<
(
sizeof
(
vesa_timings
)
/
sizeof
(
vesa_timings
[
0
]));
++
i
)
{
if
((
vinfo
->
xres
==
vesa_timings
[
i
].
xres
)
&&
(
vinfo
->
yres
==
vesa_timings
[
i
].
yres
))
{
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Using VESA timings for %dx%d
\n
"
,
vinfo
->
xres
,
vinfo
->
yres
);
#endif
if
(
vesa_timings
[
i
].
pixclock
)
{
vinfo
->
pixclock
=
vesa_timings
[
i
].
pixclock
;
}
vinfo
->
left_margin
=
vesa_timings
[
i
].
left
;
vinfo
->
right_margin
=
vesa_timings
[
i
].
right
;
vinfo
->
upper_margin
=
vesa_timings
[
i
].
upper
;
vinfo
->
lower_margin
=
vesa_timings
[
i
].
lower
;
vinfo
->
hsync_len
=
vesa_timings
[
i
].
hslen
;
vinfo
->
vsync_len
=
vesa_timings
[
i
].
vslen
;
vinfo
->
sync
=
vesa_timings
[
i
].
sync
;
vinfo
->
vmode
=
vesa_timings
[
i
].
vmode
;
matched
=
1
;
break
;
}
}
return
(
matched
);
}
#ifdef VGA16_FBCON_SUPPORT
static
SDL_Surface
*
FB_SetVGA16Mode
(
_THIS
,
SDL_Surface
*
current
,
int
width
,
int
height
,
int
bpp
,
Uint32
flags
)
{
struct
fb_fix_screeninfo
finfo
;
struct
fb_var_screeninfo
vinfo
;
/* Set the terminal into graphics mode */
if
(
FB_EnterGraphicsMode
(
this
)
<
0
)
{
return
(
NULL
);
}
/* Restore the original palette */
FB_RestorePalette
(
this
);
/* Set the video mode and get the final screen format */
if
(
ioctl
(
console_fd
,
FBIOGET_VSCREENINFO
,
&
vinfo
)
<
0
)
{
SDL_SetError
(
"Couldn't get console screen info"
);
return
(
NULL
);
}
cache_vinfo
=
vinfo
;
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Printing actual vinfo:
\n
"
);
print_vinfo
(
&
vinfo
);
#endif
if
(
!
SDL_ReallocFormat
(
current
,
bpp
,
0
,
0
,
0
,
0
))
{
return
(
NULL
);
}
current
->
format
->
palette
->
ncolors
=
16
;
/* Get the fixed information about the console hardware.
This is necessary since finfo.line_length changes.
*/
if
(
ioctl
(
console_fd
,
FBIOGET_FSCREENINFO
,
&
finfo
)
<
0
)
{
SDL_SetError
(
"Couldn't get console hardware info"
);
return
(
NULL
);
}
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Printing actual finfo:
\n
"
);
print_finfo
(
&
finfo
);
#endif
/* Save hardware palette, if needed */
FB_SavePalette
(
this
,
&
finfo
,
&
vinfo
);
/* Set up the new mode framebuffer */
current
->
flags
=
SDL_FULLSCREEN
;
current
->
w
=
vinfo
.
xres
;
current
->
h
=
vinfo
.
yres
;
current
->
pitch
=
current
->
w
;
current
->
pixels
=
SDL_malloc
(
current
->
h
*
current
->
pitch
);
/* Set the update rectangle function */
this
->
UpdateRects
=
FB_VGA16Update
;
/* We're done */
return
(
current
);
}
#endif
/* VGA16_FBCON_SUPPORT */
static
SDL_Surface
*
FB_SetVideoMode
(
_THIS
,
SDL_Surface
*
current
,
int
width
,
int
height
,
int
bpp
,
Uint32
flags
)
{
struct
fb_fix_screeninfo
finfo
;
struct
fb_var_screeninfo
vinfo
;
int
i
;
Uint32
Rmask
;
Uint32
Gmask
;
Uint32
Bmask
;
char
*
surfaces_mem
;
int
surfaces_len
;
/* Set the terminal into graphics mode */
if
(
FB_EnterGraphicsMode
(
this
)
<
0
)
{
return
(
NULL
);
}
/* Restore the original palette */
FB_RestorePalette
(
this
);
/* Set the video mode and get the final screen format */
if
(
ioctl
(
console_fd
,
FBIOGET_VSCREENINFO
,
&
vinfo
)
<
0
)
{
SDL_SetError
(
"Couldn't get console screen info"
);
return
(
NULL
);
}
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Printing original vinfo:
\n
"
);
print_vinfo
(
&
vinfo
);
#endif
if
((
vinfo
.
xres
!=
width
)
||
(
vinfo
.
yres
!=
height
)
||
(
vinfo
.
bits_per_pixel
!=
bpp
)
||
(
flags
&
SDL_DOUBLEBUF
))
{
vinfo
.
activate
=
FB_ACTIVATE_NOW
;
vinfo
.
accel_flags
=
0
;
vinfo
.
bits_per_pixel
=
bpp
;
vinfo
.
xres
=
width
;
vinfo
.
xres_virtual
=
width
;
vinfo
.
yres
=
height
;
if
(
flags
&
SDL_DOUBLEBUF
)
{
vinfo
.
yres_virtual
=
height
*
2
;
}
else
{
vinfo
.
yres_virtual
=
height
;
}
vinfo
.
xoffset
=
0
;
vinfo
.
yoffset
=
0
;
vinfo
.
red
.
length
=
vinfo
.
red
.
offset
=
0
;
vinfo
.
green
.
length
=
vinfo
.
green
.
offset
=
0
;
vinfo
.
blue
.
length
=
vinfo
.
blue
.
offset
=
0
;
vinfo
.
transp
.
length
=
vinfo
.
transp
.
offset
=
0
;
if
(
!
choose_fbmodes_mode
(
&
vinfo
))
{
choose_vesa_mode
(
&
vinfo
);
}
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Printing wanted vinfo:
\n
"
);
print_vinfo
(
&
vinfo
);
#endif
if
(
ioctl
(
console_fd
,
FBIOPUT_VSCREENINFO
,
&
vinfo
)
<
0
)
{
vinfo
.
yres_virtual
=
height
;
if
(
ioctl
(
console_fd
,
FBIOPUT_VSCREENINFO
,
&
vinfo
)
<
0
)
{
SDL_SetError
(
"Couldn't set console screen info"
);
return
(
NULL
);
}
}
}
else
{
int
maxheight
;
/* Figure out how much video memory is available */
if
(
flags
&
SDL_DOUBLEBUF
)
{
maxheight
=
height
*
2
;
}
else
{
maxheight
=
height
;
}
if
(
vinfo
.
yres_virtual
>
maxheight
)
{
vinfo
.
yres_virtual
=
maxheight
;
}
}
cache_vinfo
=
vinfo
;
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Printing actual vinfo:
\n
"
);
print_vinfo
(
&
vinfo
);
#endif
Rmask
=
0
;
for
(
i
=
0
;
i
<
vinfo
.
red
.
length
;
++
i
)
{
Rmask
<<=
1
;
Rmask
|=
(
0x00000001
<<
vinfo
.
red
.
offset
);
}
Gmask
=
0
;
for
(
i
=
0
;
i
<
vinfo
.
green
.
length
;
++
i
)
{
Gmask
<<=
1
;
Gmask
|=
(
0x00000001
<<
vinfo
.
green
.
offset
);
}
Bmask
=
0
;
for
(
i
=
0
;
i
<
vinfo
.
blue
.
length
;
++
i
)
{
Bmask
<<=
1
;
Bmask
|=
(
0x00000001
<<
vinfo
.
blue
.
offset
);
}
if
(
!
SDL_ReallocFormat
(
current
,
vinfo
.
bits_per_pixel
,
Rmask
,
Gmask
,
Bmask
,
0
))
{
return
(
NULL
);
}
/* Get the fixed information about the console hardware.
This is necessary since finfo.line_length changes.
*/
if
(
ioctl
(
console_fd
,
FBIOGET_FSCREENINFO
,
&
finfo
)
<
0
)
{
SDL_SetError
(
"Couldn't get console hardware info"
);
return
(
NULL
);
}
/* Save hardware palette, if needed */
FB_SavePalette
(
this
,
&
finfo
,
&
vinfo
);
/* Set up the new mode framebuffer */
current
->
flags
=
(
SDL_FULLSCREEN
|
SDL_HWSURFACE
);
current
->
w
=
vinfo
.
xres
;
current
->
h
=
vinfo
.
yres
;
current
->
pitch
=
finfo
.
line_length
;
current
->
pixels
=
mapped_mem
+
mapped_offset
;
/* Set up the information for hardware surfaces */
surfaces_mem
=
(
char
*
)
current
->
pixels
+
vinfo
.
yres_virtual
*
current
->
pitch
;
surfaces_len
=
(
mapped_memlen
-
(
surfaces_mem
-
mapped_mem
));
FB_FreeHWSurfaces
(
this
);
FB_InitHWSurfaces
(
this
,
current
,
surfaces_mem
,
surfaces_len
);
/* Let the application know we have a hardware palette */
switch
(
finfo
.
visual
)
{
case
FB_VISUAL_PSEUDOCOLOR
:
current
->
flags
|=
SDL_HWPALETTE
;
break
;
default:
break
;
}
/* Update for double-buffering, if we can */
if
(
flags
&
SDL_DOUBLEBUF
)
{
if
(
vinfo
.
yres_virtual
==
(
height
*
2
))
{
current
->
flags
|=
SDL_DOUBLEBUF
;
flip_page
=
0
;
flip_address
[
0
]
=
(
char
*
)
current
->
pixels
;
flip_address
[
1
]
=
(
char
*
)
current
->
pixels
+
current
->
h
*
current
->
pitch
;
this
->
screen
=
current
;
FB_FlipHWSurface
(
this
,
current
);
this
->
screen
=
NULL
;
}
}
/* Set the update rectangle function */
this
->
UpdateRects
=
FB_DirectUpdate
;
/* We're done */
return
(
current
);
}
#ifdef FBCON_DEBUG
void
FB_DumpHWSurfaces
(
_THIS
)
{
vidmem_bucket
*
bucket
;
printf
(
"Memory left: %d (%d total)
\n
"
,
surfaces_memleft
,
surfaces_memtotal
);
printf
(
"
\n
"
);
printf
(
" Base Size
\n
"
);
for
(
bucket
=
&
surfaces
;
bucket
;
bucket
=
bucket
->
next
)
{
printf
(
"Bucket: %p, %d (%s)
\n
"
,
bucket
->
base
,
bucket
->
size
,
bucket
->
used
?
"used"
:
"free"
);
if
(
bucket
->
prev
)
{
if
(
bucket
->
base
!=
bucket
->
prev
->
base
+
bucket
->
prev
->
size
)
{
printf
(
"Warning, corrupt bucket list! (prev)
\n
"
);
}
}
else
{
if
(
bucket
!=
&
surfaces
)
{
printf
(
"Warning, corrupt bucket list! (!prev)
\n
"
);
}
}
if
(
bucket
->
next
)
{
if
(
bucket
->
next
->
base
!=
bucket
->
base
+
bucket
->
size
)
{
printf
(
"Warning, corrupt bucket list! (next)
\n
"
);
}
}
}
printf
(
"
\n
"
);
}
#endif
static
int
FB_InitHWSurfaces
(
_THIS
,
SDL_Surface
*
screen
,
char
*
base
,
int
size
)
{
vidmem_bucket
*
bucket
;
surfaces_memtotal
=
size
;
surfaces_memleft
=
size
;
if
(
surfaces_memleft
>
0
)
{
bucket
=
(
vidmem_bucket
*
)
SDL_malloc
(
sizeof
(
*
bucket
));
if
(
bucket
==
NULL
)
{
SDL_OutOfMemory
();
return
(
-
1
);
}
bucket
->
prev
=
&
surfaces
;
bucket
->
used
=
0
;
bucket
->
dirty
=
0
;
bucket
->
base
=
base
;
bucket
->
size
=
size
;
bucket
->
next
=
NULL
;
}
else
{
bucket
=
NULL
;
}
surfaces
.
prev
=
NULL
;
surfaces
.
used
=
1
;
surfaces
.
dirty
=
0
;
surfaces
.
base
=
screen
->
pixels
;
surfaces
.
size
=
(
unsigned
int
)
((
long
)
base
-
(
long
)
surfaces
.
base
);
surfaces
.
next
=
bucket
;
screen
->
hwdata
=
(
struct
private_hwdata
*
)
&
surfaces
;
return
(
0
);
}
static
void
FB_FreeHWSurfaces
(
_THIS
)
{
vidmem_bucket
*
bucket
,
*
freeable
;
bucket
=
surfaces
.
next
;
while
(
bucket
)
{
freeable
=
bucket
;
bucket
=
bucket
->
next
;
SDL_free
(
freeable
);
}
surfaces
.
next
=
NULL
;
}
static
int
FB_AllocHWSurface
(
_THIS
,
SDL_Surface
*
surface
)
{
vidmem_bucket
*
bucket
;
int
size
;
int
extra
;
/* Temporarily, we only allow surfaces the same width as display.
Some blitters require the pitch between two hardware surfaces
to be the same. Others have interesting alignment restrictions.
Until someone who knows these details looks at the code...
*/
if
(
surface
->
pitch
>
SDL_VideoSurface
->
pitch
)
{
SDL_SetError
(
"Surface requested wider than screen"
);
return
(
-
1
);
}
surface
->
pitch
=
SDL_VideoSurface
->
pitch
;
size
=
surface
->
h
*
surface
->
pitch
;
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Allocating bucket of %d bytes
\n
"
,
size
);
#endif
/* Quick check for available mem */
if
(
size
>
surfaces_memleft
)
{
SDL_SetError
(
"Not enough video memory"
);
return
(
-
1
);
}
/* Search for an empty bucket big enough */
for
(
bucket
=
&
surfaces
;
bucket
;
bucket
=
bucket
->
next
)
{
if
(
!
bucket
->
used
&&
(
size
<=
bucket
->
size
))
{
break
;
}
}
if
(
bucket
==
NULL
)
{
SDL_SetError
(
"Video memory too fragmented"
);
return
(
-
1
);
}
/* Create a new bucket for left-over memory */
extra
=
(
bucket
->
size
-
size
);
if
(
extra
)
{
vidmem_bucket
*
newbucket
;
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Adding new free bucket of %d bytes
\n
"
,
extra
);
#endif
newbucket
=
(
vidmem_bucket
*
)
SDL_malloc
(
sizeof
(
*
newbucket
));
if
(
newbucket
==
NULL
)
{
SDL_OutOfMemory
();
return
(
-
1
);
}
newbucket
->
prev
=
bucket
;
newbucket
->
used
=
0
;
newbucket
->
base
=
bucket
->
base
+
size
;
newbucket
->
size
=
extra
;
newbucket
->
next
=
bucket
->
next
;
if
(
bucket
->
next
)
{
bucket
->
next
->
prev
=
newbucket
;
}
bucket
->
next
=
newbucket
;
}
/* Set the current bucket values and return it! */
bucket
->
used
=
1
;
bucket
->
size
=
size
;
bucket
->
dirty
=
0
;
#ifdef FBCON_DEBUG
fprintf
(
stderr
,
"Allocated %d bytes at %p
\n
"
,
bucket
->
size
,
bucket
->
base
);
#endif
surfaces_memleft
-=
size
;
surface
->
flags
|=
SDL_HWSURFACE
;
surface
->
pixels
=
bucket
->
base
;
surface
->
hwdata
=
(
struct
private_hwdata
*
)
bucket
;
return
(
0
);
}
static
void
FB_FreeHWSurface
(
_THIS
,
SDL_Surface
*
surface
)
{
vidmem_bucket
*
bucket
,
*
freeable
;
/* Look for the bucket in the current list */
for
(
bucket
=
&
surfaces
;
bucket
;
bucket
=
bucket
->
next
)
{
if
(
bucket
==
(
vidmem_bucket
*
)
surface
->
hwdata
)
{
break
;
}
}
if
(
bucket
&&
bucket
->
used
)
{
/* Add the memory back to the total */
#ifdef DGA_DEBUG
printf
(
"Freeing bucket of %d bytes
\n
"
,
bucket
->
size
);
#endif
surfaces_memleft
+=
bucket
->
size
;
/* Can we merge the space with surrounding buckets? */
bucket
->
used
=
0
;
if
(
bucket
->
next
&&
!
bucket
->
next
->
used
)
{
#ifdef DGA_DEBUG
printf
(
"Merging with next bucket, for %d total bytes
\n
"
,
bucket
->
size
+
bucket
->
next
->
size
);
#endif
freeable
=
bucket
->
next
;
bucket
->
size
+=
bucket
->
next
->
size
;
bucket
->
next
=
bucket
->
next
->
next
;
if
(
bucket
->
next
)
{
bucket
->
next
->
prev
=
bucket
;
}
SDL_free
(
freeable
);
}
if
(
bucket
->
prev
&&
!
bucket
->
prev
->
used
)
{
#ifdef DGA_DEBUG
printf
(
"Merging with previous bucket, for %d total bytes
\n
"
,
bucket
->
prev
->
size
+
bucket
->
size
);
#endif
freeable
=
bucket
;
bucket
->
prev
->
size
+=
bucket
->
size
;
bucket
->
prev
->
next
=
bucket
->
next
;
if
(
bucket
->
next
)
{
bucket
->
next
->
prev
=
bucket
->
prev
;
}
SDL_free
(
freeable
);
}
}
surface
->
pixels
=
NULL
;
surface
->
hwdata
=
NULL
;
}
static
int
FB_LockHWSurface
(
_THIS
,
SDL_Surface
*
surface
)
{
if
(
switched_away
)
{
return
-
2
;
/* no hardware access */
}
if
(
surface
==
this
->
screen
)
{
SDL_mutexP
(
hw_lock
);
if
(
FB_IsSurfaceBusy
(
surface
))
{
FB_WaitBusySurfaces
(
this
);
}
}
else
{
if
(
FB_IsSurfaceBusy
(
surface
))
{
FB_WaitBusySurfaces
(
this
);
}
}
return
(
0
);
}
static
void
FB_UnlockHWSurface
(
_THIS
,
SDL_Surface
*
surface
)
{
if
(
surface
==
this
->
screen
)
{
SDL_mutexV
(
hw_lock
);
}
}
static
void
FB_WaitVBL
(
_THIS
)
{
#ifdef FBIOWAITRETRACE
/* Heheh, this didn't make it into the main kernel */
ioctl
(
console_fd
,
FBIOWAITRETRACE
,
0
);
#endif
return
;
}
static
void
FB_WaitIdle
(
_THIS
)
{
return
;
}
static
int
FB_FlipHWSurface
(
_THIS
,
SDL_Surface
*
surface
)
{
if
(
switched_away
)
{
return
-
2
;
/* no hardware access */
}
/* Wait for vertical retrace and then flip display */
cache_vinfo
.
yoffset
=
flip_page
*
surface
->
h
;
if
(
FB_IsSurfaceBusy
(
this
->
screen
))
{
FB_WaitBusySurfaces
(
this
);
}
wait_vbl
(
this
);
if
(
ioctl
(
console_fd
,
FBIOPAN_DISPLAY
,
&
cache_vinfo
)
<
0
)
{
SDL_SetError
(
"ioctl(FBIOPAN_DISPLAY) failed"
);
return
(
-
1
);
}
flip_page
=
!
flip_page
;
surface
->
pixels
=
flip_address
[
flip_page
];
return
(
0
);
}
static
void
FB_DirectUpdate
(
_THIS
,
int
numrects
,
SDL_Rect
*
rects
)
{
/* The application is already updating the visible video memory */
return
;
}
#ifdef VGA16_FBCON_SUPPORT
/* Code adapted with thanks from the XFree86 VGA16 driver! :) */
#define writeGr(index, value) \
outb(index, 0x3CE); \
outb(value, 0x3CF);
#define writeSeq(index, value) \
outb(index, 0x3C4); \
outb(value, 0x3C5);
static
void
FB_VGA16Update
(
_THIS
,
int
numrects
,
SDL_Rect
*
rects
)
{
SDL_Surface
*
screen
;
int
width
,
height
,
FBPitch
,
left
,
i
,
j
,
SRCPitch
,
phase
;
register
Uint32
m
;
Uint8
s1
,
s2
,
s3
,
s4
;
Uint32
*
src
,
*
srcPtr
;
Uint8
*
dst
,
*
dstPtr
;
if
(
switched_away
)
{
return
;
/* no hardware access */
}
screen
=
this
->
screen
;
FBPitch
=
screen
->
w
>>
3
;
SRCPitch
=
screen
->
pitch
>>
2
;
writeGr
(
0x03
,
0x00
);
writeGr
(
0x05
,
0x00
);
writeGr
(
0x01
,
0x00
);
writeGr
(
0x08
,
0xFF
);
while
(
numrects
--
)
{
left
=
rects
->
x
&
~
7
;
width
=
(
rects
->
w
+
7
)
>>
3
;
height
=
rects
->
h
;
src
=
(
Uint32
*
)
screen
->
pixels
+
(
rects
->
y
*
SRCPitch
)
+
(
left
>>
2
);
dst
=
(
Uint8
*
)
mapped_mem
+
(
rects
->
y
*
FBPitch
)
+
(
left
>>
3
);
if
((
phase
=
(
long
)
dst
&
3L
))
{
phase
=
4
-
phase
;
if
(
phase
>
width
)
phase
=
width
;
width
-=
phase
;
}
while
(
height
--
)
{
writeSeq
(
0x02
,
1
<<
0
);
dstPtr
=
dst
;
srcPtr
=
src
;
i
=
width
;
j
=
phase
;
while
(
j
--
)
{
m
=
(
srcPtr
[
1
]
&
0x01010101
)
|
((
srcPtr
[
0
]
&
0x01010101
)
<<
4
);
*
dstPtr
++
=
(
m
>>
24
)
|
(
m
>>
15
)
|
(
m
>>
6
)
|
(
m
<<
3
);
srcPtr
+=
2
;
}
while
(
i
>=
4
)
{
m
=
(
srcPtr
[
1
]
&
0x01010101
)
|
((
srcPtr
[
0
]
&
0x01010101
)
<<
4
);
s1
=
(
m
>>
24
)
|
(
m
>>
15
)
|
(
m
>>
6
)
|
(
m
<<
3
);
m
=
(
srcPtr
[
3
]
&
0x01010101
)
|
((
srcPtr
[
2
]
&
0x01010101
)
<<
4
);
s2
=
(
m
>>
24
)
|
(
m
>>
15
)
|
(
m
>>
6
)
|
(
m
<<
3
);
m
=
(
srcPtr
[
5
]
&
0x01010101
)
|
((
srcPtr
[
4
]
&
0x01010101
)
<<
4
);
s3
=
(
m
>>
24
)
|
(
m
>>
15
)
|
(
m
>>
6
)
|
(
m
<<
3
);
m
=
(
srcPtr
[
7
]
&
0x01010101
)
|
((
srcPtr
[
6
]
&
0x01010101
)
<<
4
);
s4
=
(
m
>>
24
)
|
(
m
>>
15
)
|
(
m
>>
6
)
|
(
m
<<
3
);
*
((
Uint32
*
)
dstPtr
)
=
s1
|
(
s2
<<
8
)
|
(
s3
<<
16
)
|
(
s4
<<
24
);
srcPtr
+=
8
;
dstPtr
+=
4
;
i
-=
4
;
}
while
(
i
--
)
{
m
=
(
srcPtr
[
1
]
&
0x01010101
)
|
((
srcPtr
[
0
]
&
0x01010101
)
<<
4
);
*
dstPtr
++
=
(
m
>>
24
)
|
(
m
>>
15
)
|
(
m
>>
6
)
|
(
m
<<
3
);
srcPtr
+=
2
;
}
writeSeq
(
0x02
,
1
<<
1
);
dstPtr
=
dst
;
srcPtr
=
src
;
i
=
width
;
j
=
phase
;
while
(
j
--
)
{
m
=
(
srcPtr
[
1
]
&
0x02020202
)
|
((
srcPtr
[
0
]
&
0x02020202
)
<<
4
);
*
dstPtr
++
=
(
m
>>
25
)
|
(
m
>>
16
)
|
(
m
>>
7
)
|
(
m
<<
2
);
srcPtr
+=
2
;
}
while
(
i
>=
4
)
{
m
=
(
srcPtr
[
1
]
&
0x02020202
)
|
((
srcPtr
[
0
]
&
0x02020202
)
<<
4
);
s1
=
(
m
>>
25
)
|
(
m
>>
16
)
|
(
m
>>
7
)
|
(
m
<<
2
);
m
=
(
srcPtr
[
3
]
&
0x02020202
)
|
((
srcPtr
[
2
]
&
0x02020202
)
<<
4
);
s2
=
(
m
>>
25
)
|
(
m
>>
16
)
|
(
m
>>
7
)
|
(
m
<<
2
);
m
=
(
srcPtr
[
5
]
&
0x02020202
)
|
((
srcPtr
[
4
]
&
0x02020202
)
<<
4
);
s3
=
(
m
>>
25
)
|
(
m
>>
16
)
|
(
m
>>
7
)
|
(
m
<<
2
);
m
=
(
srcPtr
[
7
]
&
0x02020202
)
|
((
srcPtr
[
6
]
&
0x02020202
)
<<
4
);
s4
=
(
m
>>
25
)
|
(
m
>>
16
)
|
(
m
>>
7
)
|
(
m
<<
2
);
*
((
Uint32
*
)
dstPtr
)
=
s1
|
(
s2
<<
8
)
|
(
s3
<<
16
)
|
(
s4
<<
24
);
srcPtr
+=
8
;
dstPtr
+=
4
;
i
-=
4
;
}
while
(
i
--
)
{
m
=
(
srcPtr
[
1
]
&
0x02020202
)
|
((
srcPtr
[
0
]
&
0x02020202
)
<<
4
);
*
dstPtr
++
=
(
m
>>
25
)
|
(
m
>>
16
)
|
(
m
>>
7
)
|
(
m
<<
2
);
srcPtr
+=
2
;
}
writeSeq
(
0x02
,
1
<<
2
);
dstPtr
=
dst
;
srcPtr
=
src
;
i
=
width
;
j
=
phase
;
while
(
j
--
)
{
m
=
(
srcPtr
[
1
]
&
0x04040404
)
|
((
srcPtr
[
0
]
&
0x04040404
)
<<
4
);
*
dstPtr
++
=
(
m
>>
26
)
|
(
m
>>
17
)
|
(
m
>>
8
)
|
(
m
<<
1
);
srcPtr
+=
2
;
}
while
(
i
>=
4
)
{
m
=
(
srcPtr
[
1
]
&
0x04040404
)
|
((
srcPtr
[
0
]
&
0x04040404
)
<<
4
);
s1
=
(
m
>>
26
)
|
(
m
>>
17
)
|
(
m
>>
8
)
|
(
m
<<
1
);
m
=
(
srcPtr
[
3
]
&
0x04040404
)
|
((
srcPtr
[
2
]
&
0x04040404
)
<<
4
);
s2
=
(
m
>>
26
)
|
(
m
>>
17
)
|
(
m
>>
8
)
|
(
m
<<
1
);
m
=
(
srcPtr
[
5
]
&
0x04040404
)
|
((
srcPtr
[
4
]
&
0x04040404
)
<<
4
);
s3
=
(
m
>>
26
)
|
(
m
>>
17
)
|
(
m
>>
8
)
|
(
m
<<
1
);
m
=
(
srcPtr
[
7
]
&
0x04040404
)
|
((
srcPtr
[
6
]
&
0x04040404
)
<<
4
);
s4
=
(
m
>>
26
)
|
(
m
>>
17
)
|
(
m
>>
8
)
|
(
m
<<
1
);
*
((
Uint32
*
)
dstPtr
)
=
s1
|
(
s2
<<
8
)
|
(
s3
<<
16
)
|
(
s4
<<
24
);
srcPtr
+=
8
;
dstPtr
+=
4
;
i
-=
4
;
}
while
(
i
--
)
{
m
=
(
srcPtr
[
1
]
&
0x04040404
)
|
((
srcPtr
[
0
]
&
0x04040404
)
<<
4
);
*
dstPtr
++
=
(
m
>>
26
)
|
(
m
>>
17
)
|
(
m
>>
8
)
|
(
m
<<
1
);
srcPtr
+=
2
;
}
writeSeq
(
0x02
,
1
<<
3
);
dstPtr
=
dst
;
srcPtr
=
src
;
i
=
width
;
j
=
phase
;
while
(
j
--
)
{
m
=
(
srcPtr
[
1
]
&
0x08080808
)
|
((
srcPtr
[
0
]
&
0x08080808
)
<<
4
);
*
dstPtr
++
=
(
m
>>
27
)
|
(
m
>>
18
)
|
(
m
>>
9
)
|
m
;
srcPtr
+=
2
;
}
while
(
i
>=
4
)
{
m
=
(
srcPtr
[
1
]
&
0x08080808
)
|
((
srcPtr
[
0
]
&
0x08080808
)
<<
4
);
s1
=
(
m
>>
27
)
|
(
m
>>
18
)
|
(
m
>>
9
)
|
m
;
m
=
(
srcPtr
[
3
]
&
0x08080808
)
|
((
srcPtr
[
2
]
&
0x08080808
)
<<
4
);
s2
=
(
m
>>
27
)
|
(
m
>>
18
)
|
(
m
>>
9
)
|
m
;
m
=
(
srcPtr
[
5
]
&
0x08080808
)
|
((
srcPtr
[
4
]
&
0x08080808
)
<<
4
);
s3
=
(
m
>>
27
)
|
(
m
>>
18
)
|
(
m
>>
9
)
|
m
;
m
=
(
srcPtr
[
7
]
&
0x08080808
)
|
((
srcPtr
[
6
]
&
0x08080808
)
<<
4
);
s4
=
(
m
>>
27
)
|
(
m
>>
18
)
|
(
m
>>
9
)
|
m
;
*
((
Uint32
*
)
dstPtr
)
=
s1
|
(
s2
<<
8
)
|
(
s3
<<
16
)
|
(
s4
<<
24
);
srcPtr
+=
8
;
dstPtr
+=
4
;
i
-=
4
;
}
while
(
i
--
)
{
m
=
(
srcPtr
[
1
]
&
0x08080808
)
|
((
srcPtr
[
0
]
&
0x08080808
)
<<
4
);
*
dstPtr
++
=
(
m
>>
27
)
|
(
m
>>
18
)
|
(
m
>>
9
)
|
m
;
srcPtr
+=
2
;
}
dst
+=
FBPitch
;
src
+=
SRCPitch
;
}
rects
++
;
}
}
#endif
/* VGA16_FBCON_SUPPORT */
void
FB_SavePaletteTo
(
_THIS
,
int
palette_len
,
__u16
*
area
)
{
struct
fb_cmap
cmap
;
cmap
.
start
=
0
;
cmap
.
len
=
palette_len
;
cmap
.
red
=
&
area
[
0
*
palette_len
];
cmap
.
green
=
&
area
[
1
*
palette_len
];
cmap
.
blue
=
&
area
[
2
*
palette_len
];
cmap
.
transp
=
NULL
;
ioctl
(
console_fd
,
FBIOGETCMAP
,
&
cmap
);
}
void
FB_RestorePaletteFrom
(
_THIS
,
int
palette_len
,
__u16
*
area
)
{
struct
fb_cmap
cmap
;
cmap
.
start
=
0
;
cmap
.
len
=
palette_len
;
cmap
.
red
=
&
area
[
0
*
palette_len
];
cmap
.
green
=
&
area
[
1
*
palette_len
];
cmap
.
blue
=
&
area
[
2
*
palette_len
];
cmap
.
transp
=
NULL
;
ioctl
(
console_fd
,
FBIOPUTCMAP
,
&
cmap
);
}
static
void
FB_SavePalette
(
_THIS
,
struct
fb_fix_screeninfo
*
finfo
,
struct
fb_var_screeninfo
*
vinfo
)
{
int
i
;
/* Save hardware palette, if needed */
if
(
finfo
->
visual
==
FB_VISUAL_PSEUDOCOLOR
)
{
saved_cmaplen
=
1
<<
vinfo
->
bits_per_pixel
;
saved_cmap
=
(
__u16
*
)
SDL_malloc
(
3
*
saved_cmaplen
*
sizeof
(
*
saved_cmap
));
if
(
saved_cmap
!=
NULL
)
{
FB_SavePaletteTo
(
this
,
saved_cmaplen
,
saved_cmap
);
}
}
/* Added support for FB_VISUAL_DIRECTCOLOR.
With this mode pixel information is passed through the palette...
Neat fading and gamma correction effects can be had by simply
fooling around with the palette instead of changing the pixel
values themselves... Very neat!
Adam Meyerowitz 1/19/2000
ameyerow@optonline.com
*/
if
(
finfo
->
visual
==
FB_VISUAL_DIRECTCOLOR
)
{
__u16
new_entries
[
3
*
256
];
/* Save the colormap */
saved_cmaplen
=
256
;
saved_cmap
=
(
__u16
*
)
SDL_malloc
(
3
*
saved_cmaplen
*
sizeof
(
*
saved_cmap
));
if
(
saved_cmap
!=
NULL
)
{
FB_SavePaletteTo
(
this
,
saved_cmaplen
,
saved_cmap
);
}
/* Allocate new identity colormap */
for
(
i
=
0
;
i
<
256
;
++
i
)
{
new_entries
[(
0
*
256
)
+
i
]
=
new_entries
[(
1
*
256
)
+
i
]
=
new_entries
[(
2
*
256
)
+
i
]
=
(
i
<<
8
)
|
i
;
}
FB_RestorePaletteFrom
(
this
,
256
,
new_entries
);
}
}
static
void
FB_RestorePalette
(
_THIS
)
{
/* Restore the original palette */
if
(
saved_cmap
)
{
FB_RestorePaletteFrom
(
this
,
saved_cmaplen
,
saved_cmap
);
SDL_free
(
saved_cmap
);
saved_cmap
=
NULL
;
}
}
static
int
FB_SetColors
(
_THIS
,
int
firstcolor
,
int
ncolors
,
SDL_Color
*
colors
)
{
int
i
;
__u16
r
[
256
];
__u16
g
[
256
];
__u16
b
[
256
];
struct
fb_cmap
cmap
;
/* Set up the colormap */
for
(
i
=
0
;
i
<
ncolors
;
i
++
)
{
r
[
i
]
=
colors
[
i
].
r
<<
8
;
g
[
i
]
=
colors
[
i
].
g
<<
8
;
b
[
i
]
=
colors
[
i
].
b
<<
8
;
}
cmap
.
start
=
firstcolor
;
cmap
.
len
=
ncolors
;
cmap
.
red
=
r
;
cmap
.
green
=
g
;
cmap
.
blue
=
b
;
cmap
.
transp
=
NULL
;
if
((
ioctl
(
console_fd
,
FBIOPUTCMAP
,
&
cmap
)
<
0
)
||
!
(
this
->
screen
->
flags
&
SDL_HWPALETTE
))
{
colors
=
this
->
screen
->
format
->
palette
->
colors
;
ncolors
=
this
->
screen
->
format
->
palette
->
ncolors
;
cmap
.
start
=
0
;
cmap
.
len
=
ncolors
;
SDL_memset
(
r
,
0
,
sizeof
(
r
));
SDL_memset
(
g
,
0
,
sizeof
(
g
));
SDL_memset
(
b
,
0
,
sizeof
(
b
));
if
(
ioctl
(
console_fd
,
FBIOGETCMAP
,
&
cmap
)
==
0
)
{
for
(
i
=
ncolors
-
1
;
i
>=
0
;
--
i
)
{
colors
[
i
].
r
=
(
r
[
i
]
>>
8
);
colors
[
i
].
g
=
(
g
[
i
]
>>
8
);
colors
[
i
].
b
=
(
b
[
i
]
>>
8
);
}
}
return
(
0
);
}
return
(
1
);
}
/* Note: If we are terminated, this could be called in the middle of
another SDL video routine -- notably UpdateRects.
*/
static
void
FB_VideoQuit
(
_THIS
)
{
int
i
,
j
;
if
(
this
->
screen
)
{
/* Clear screen and tell SDL not to free the pixels */
if
(
this
->
screen
->
pixels
&&
FB_InGraphicsMode
(
this
))
{
#if defined(__powerpc__) || defined(__ia64__)
/* SIGBUS when using SDL_memset() ?? */
Uint8
*
rowp
=
(
Uint8
*
)
this
->
screen
->
pixels
;
int
left
=
this
->
screen
->
pitch
*
this
->
screen
->
h
;
while
(
left
--
)
{
*
rowp
++
=
0
;
}
#else
SDL_memset
(
this
->
screen
->
pixels
,
0
,
this
->
screen
->
h
*
this
->
screen
->
pitch
);
#endif
}
/* This test fails when using the VGA16 shadow memory */
if
(((
char
*
)
this
->
screen
->
pixels
>=
mapped_mem
)
&&
((
char
*
)
this
->
screen
->
pixels
<
(
mapped_mem
+
mapped_memlen
)))
{
this
->
screen
->
pixels
=
NULL
;
}
}
/* Clear the lock mutex */
if
(
hw_lock
)
{
SDL_DestroyMutex
(
hw_lock
);
hw_lock
=
NULL
;
}
/* Clean up defined video modes */
for
(
i
=
0
;
i
<
NUM_MODELISTS
;
++
i
)
{
if
(
SDL_modelist
[
i
]
!=
NULL
)
{
for
(
j
=
0
;
SDL_modelist
[
i
][
j
];
++
j
)
{
SDL_free
(
SDL_modelist
[
i
][
j
]);
}
SDL_free
(
SDL_modelist
[
i
]);
SDL_modelist
[
i
]
=
NULL
;
}
}
/* Clean up the memory bucket list */
FB_FreeHWSurfaces
(
this
);
/* Close console and input file descriptors */
if
(
console_fd
>
0
)
{
/* Unmap the video framebuffer and I/O registers */
if
(
mapped_mem
)
{
munmap
(
mapped_mem
,
mapped_memlen
);
mapped_mem
=
NULL
;
}
if
(
mapped_io
)
{
munmap
(
mapped_io
,
mapped_iolen
);
mapped_io
=
NULL
;
}
/* Restore the original video mode and palette */
if
(
FB_InGraphicsMode
(
this
))
{
FB_RestorePalette
(
this
);
ioctl
(
console_fd
,
FBIOPUT_VSCREENINFO
,
&
saved_vinfo
);
}
/* We're all done with the framebuffer */
close
(
console_fd
);
console_fd
=
-
1
;
}
FB_CloseMouse
(
this
);
FB_CloseKeyboard
(
this
);
}
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/SDL_fbvideo.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#ifndef _SDL_fbvideo_h
#define _SDL_fbvideo_h
#include <sys/types.h>
#include <termios.h>
#include <linux/fb.h>
#include "SDL_mouse.h"
#include "SDL_mutex.h"
#include "../SDL_sysvideo.h"
#if SDL_INPUT_TSLIB
#include "tslib.h"
#endif
/* Hidden "this" pointer for the video functions */
#define _THIS SDL_VideoDevice *this
/* This is the structure we use to keep track of video memory */
typedef
struct
vidmem_bucket
{
struct
vidmem_bucket
*
prev
;
int
used
;
int
dirty
;
char
*
base
;
unsigned
int
size
;
struct
vidmem_bucket
*
next
;
}
vidmem_bucket
;
/* Private display data */
struct
SDL_PrivateVideoData
{
int
console_fd
;
struct
fb_var_screeninfo
cache_vinfo
;
struct
fb_var_screeninfo
saved_vinfo
;
int
saved_cmaplen
;
__u16
*
saved_cmap
;
int
current_vt
;
int
saved_vt
;
int
keyboard_fd
;
int
saved_kbd_mode
;
struct
termios
saved_kbd_termios
;
int
mouse_fd
;
#if SDL_INPUT_TSLIB
struct
tsdev
*
ts_dev
;
#endif
char
*
mapped_mem
;
int
mapped_memlen
;
int
mapped_offset
;
char
*
mapped_io
;
long
mapped_iolen
;
int
flip_page
;
char
*
flip_address
[
2
];
#define NUM_MODELISTS 4
/* 8, 16, 24, and 32 bits-per-pixel */
int
SDL_nummodes
[
NUM_MODELISTS
];
SDL_Rect
**
SDL_modelist
[
NUM_MODELISTS
];
vidmem_bucket
surfaces
;
int
surfaces_memtotal
;
int
surfaces_memleft
;
SDL_mutex
*
hw_lock
;
int
switched_away
;
struct
fb_var_screeninfo
screen_vinfo
;
Uint32
screen_arealen
;
Uint8
*
screen_contents
;
__u16
screen_palette
[
3
*
256
];
void
(
*
wait_vbl
)
(
_THIS
);
void
(
*
wait_idle
)
(
_THIS
);
};
/* Old variable names */
#define console_fd (this->hidden->console_fd)
#define current_vt (this->hidden->current_vt)
#define saved_vt (this->hidden->saved_vt)
#define keyboard_fd (this->hidden->keyboard_fd)
#define saved_kbd_mode (this->hidden->saved_kbd_mode)
#define saved_kbd_termios (this->hidden->saved_kbd_termios)
#define mouse_fd (this->hidden->mouse_fd)
#if SDL_INPUT_TSLIB
#define ts_dev (this->hidden->ts_dev)
#endif
#define cache_vinfo (this->hidden->cache_vinfo)
#define saved_vinfo (this->hidden->saved_vinfo)
#define saved_cmaplen (this->hidden->saved_cmaplen)
#define saved_cmap (this->hidden->saved_cmap)
#define mapped_mem (this->hidden->mapped_mem)
#define mapped_memlen (this->hidden->mapped_memlen)
#define mapped_offset (this->hidden->mapped_offset)
#define mapped_io (this->hidden->mapped_io)
#define mapped_iolen (this->hidden->mapped_iolen)
#define flip_page (this->hidden->flip_page)
#define flip_address (this->hidden->flip_address)
#define SDL_nummodes (this->hidden->SDL_nummodes)
#define SDL_modelist (this->hidden->SDL_modelist)
#define surfaces (this->hidden->surfaces)
#define surfaces_memtotal (this->hidden->surfaces_memtotal)
#define surfaces_memleft (this->hidden->surfaces_memleft)
#define hw_lock (this->hidden->hw_lock)
#define switched_away (this->hidden->switched_away)
#define screen_vinfo (this->hidden->screen_vinfo)
#define screen_arealen (this->hidden->screen_arealen)
#define screen_contents (this->hidden->screen_contents)
#define screen_palette (this->hidden->screen_palette)
#define wait_vbl (this->hidden->wait_vbl)
#define wait_idle (this->hidden->wait_idle)
/* Accelerator types that are supported by the driver, but are not
necessarily in the kernel headers on the system we compile on.
*/
#ifndef FB_ACCEL_MATROX_MGAG400
#define FB_ACCEL_MATROX_MGAG400 26
/* Matrox G400 */
#endif
#ifndef FB_ACCEL_3DFX_BANSHEE
#define FB_ACCEL_3DFX_BANSHEE 31
/* 3Dfx Banshee */
#endif
/* These functions are defined in SDL_fbvideo.c */
extern
void
FB_SavePaletteTo
(
_THIS
,
int
palette_len
,
__u16
*
area
);
extern
void
FB_RestorePaletteFrom
(
_THIS
,
int
palette_len
,
__u16
*
area
);
/* These are utility functions for working with video surfaces */
static
__inline__
void
FB_AddBusySurface
(
SDL_Surface
*
surface
)
{
((
vidmem_bucket
*
)
surface
->
hwdata
)
->
dirty
=
1
;
}
static
__inline__
int
FB_IsSurfaceBusy
(
SDL_Surface
*
surface
)
{
return
((
vidmem_bucket
*
)
surface
->
hwdata
)
->
dirty
;
}
static
__inline__
void
FB_WaitBusySurfaces
(
_THIS
)
{
vidmem_bucket
*
bucket
;
/* Wait for graphic operations to complete */
wait_idle
(
this
);
/* Clear all surface dirty bits */
for
(
bucket
=
&
surfaces
;
bucket
;
bucket
=
bucket
->
next
)
{
bucket
->
dirty
=
0
;
}
}
static
__inline__
void
FB_dst_to_xy
(
_THIS
,
SDL_Surface
*
dst
,
int
*
x
,
int
*
y
)
{
*
x
=
(
long
)
((
char
*
)
dst
->
pixels
-
mapped_mem
)
%
this
->
screen
->
pitch
;
*
y
=
(
long
)
((
char
*
)
dst
->
pixels
-
mapped_mem
)
/
this
->
screen
->
pitch
;
if
(
dst
==
this
->
screen
)
{
*
x
+=
this
->
offset_x
;
*
y
+=
this
->
offset_y
;
}
}
#endif
/* _SDL_fbvideo_h */
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/matrox_mmio.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/* MGA register definitions */
#include "matrox_regs.h"
/* MGA control macros */
#define mga_in8(reg) *(volatile Uint8 *)(mapped_io + (reg))
#define mga_in32(reg) *(volatile Uint32 *)(mapped_io + (reg))
#define mga_out8(reg,v) *(volatile Uint8 *)(mapped_io + (reg)) = v;
#define mga_out32(reg,v) *(volatile Uint32 *)(mapped_io + (reg)) = v;
/* Wait for fifo space */
#define mga_wait(space) \
{ \
while ( mga_in8(MGAREG_FIFOSTATUS) < space ) \
; \
}
/* Wait for idle accelerator */
#define mga_waitidle() \
{ \
while ( mga_in32(MGAREG_STATUS) & 0x10000 ) \
; \
}
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/matrox_regs.h
deleted
100644 → 0
View file @
c14d8951
/*
* MGA Millennium (MGA2064W) functions
* MGA Mystique (MGA1064SG) functions
*
* Copyright 1996 The XFree86 Project, Inc.
*
* Authors
* Dirk Hohndel
* hohndel@XFree86.Org
* David Dawes
* dawes@XFree86.Org
* Contributors:
* Guy DESBIEF, Aix-en-provence, France
* g.desbief@aix.pacwan.net
* MGA1064SG Mystique register file
*/
#ifndef _MGA_REG_H_
#define _MGA_REG_H_
#define MGAREG_DWGCTL 0x1c00
#define MGAREG_MACCESS 0x1c04
/* the following is a mystique only register */
#define MGAREG_MCTLWTST 0x1c08
#define MGAREG_ZORG 0x1c0c
#define MGAREG_PAT0 0x1c10
#define MGAREG_PAT1 0x1c14
#define MGAREG_PLNWT 0x1c1c
#define MGAREG_BCOL 0x1c20
#define MGAREG_FCOL 0x1c24
#define MGAREG_SRC0 0x1c30
#define MGAREG_SRC1 0x1c34
#define MGAREG_SRC2 0x1c38
#define MGAREG_SRC3 0x1c3c
#define MGAREG_XYSTRT 0x1c40
#define MGAREG_XYEND 0x1c44
#define MGAREG_SHIFT 0x1c50
/* the following is a mystique only register */
#define MGAREG_DMAPAD 0x1c54
#define MGAREG_SGN 0x1c58
#define MGAREG_LEN 0x1c5c
#define MGAREG_AR0 0x1c60
#define MGAREG_AR1 0x1c64
#define MGAREG_AR2 0x1c68
#define MGAREG_AR3 0x1c6c
#define MGAREG_AR4 0x1c70
#define MGAREG_AR5 0x1c74
#define MGAREG_AR6 0x1c78
#define MGAREG_CXBNDRY 0x1c80
#define MGAREG_FXBNDRY 0x1c84
#define MGAREG_YDSTLEN 0x1c88
#define MGAREG_PITCH 0x1c8c
#define MGAREG_YDST 0x1c90
#define MGAREG_YDSTORG 0x1c94
#define MGAREG_YTOP 0x1c98
#define MGAREG_YBOT 0x1c9c
#define MGAREG_CXLEFT 0x1ca0
#define MGAREG_CXRIGHT 0x1ca4
#define MGAREG_FXLEFT 0x1ca8
#define MGAREG_FXRIGHT 0x1cac
#define MGAREG_XDST 0x1cb0
#define MGAREG_DR0 0x1cc0
#define MGAREG_DR1 0x1cc4
#define MGAREG_DR2 0x1cc8
#define MGAREG_DR3 0x1ccc
#define MGAREG_DR4 0x1cd0
#define MGAREG_DR5 0x1cd4
#define MGAREG_DR6 0x1cd8
#define MGAREG_DR7 0x1cdc
#define MGAREG_DR8 0x1ce0
#define MGAREG_DR9 0x1ce4
#define MGAREG_DR10 0x1ce8
#define MGAREG_DR11 0x1cec
#define MGAREG_DR12 0x1cf0
#define MGAREG_DR13 0x1cf4
#define MGAREG_DR14 0x1cf8
#define MGAREG_DR15 0x1cfc
#define MGAREG_SRCORG 0x2cb4
#define MGAREG_DSTORG 0x2cb8
/* add or or this to one of the previous "power registers" to start
the drawing engine */
#define MGAREG_EXEC 0x0100
#define MGAREG_FIFOSTATUS 0x1e10
#define MGAREG_STATUS 0x1e14
#define MGAREG_ICLEAR 0x1e18
#define MGAREG_IEN 0x1e1c
#define MGAREG_VCOUNT 0x1e20
#define MGAREG_Reset 0x1e40
#define MGAREG_OPMODE 0x1e54
/* OPMODE register additives */
#define MGAOPM_DMA_GENERAL (0x00 << 2)
#define MGAOPM_DMA_BLIT (0x01 << 2)
#define MGAOPM_DMA_VECTOR (0x10 << 2)
/* DWGCTL register additives */
/* Lines */
#define MGADWG_LINE_OPEN 0x00
#define MGADWG_AUTOLINE_OPEN 0x01
#define MGADWG_LINE_CLOSE 0x02
#define MGADWG_AUTOLINE_CLOSE 0x03
/* Trapezoids */
#define MGADWG_TRAP 0x04
#define MGADWG_TEXTURE_TRAP 0x05
/* BitBlts */
#define MGADWG_BITBLT 0x08
#define MGADWG_FBITBLT 0x0c
#define MGADWG_ILOAD 0x09
#define MGADWG_ILOAD_SCALE 0x0d
#define MGADWG_ILOAD_FILTER 0x0f
#define MGADWG_IDUMP 0x0a
/* atype access to WRAM */
#define MGADWG_RPL ( 0x00 << 4 )
#define MGADWG_RSTR ( 0x01 << 4 )
#define MGADWG_ZI ( 0x03 << 4 )
#define MGADWG_BLK ( 0x04 << 4 )
#define MGADWG_I ( 0x07 << 4 )
/* specifies whether bit blits are linear or xy */
#define MGADWG_LINEAR ( 0x01 << 7 )
/* z drawing mode. use MGADWG_NOZCMP for always */
#define MGADWG_NOZCMP ( 0x00 << 8 )
#define MGADWG_ZE ( 0x02 << 8 )
#define MGADWG_ZNE ( 0x03 << 8 )
#define MGADWG_ZLT ( 0x04 << 8 )
#define MGADWG_ZLTE ( 0x05 << 8 )
#define MGADWG_GT ( 0x06 << 8 )
#define MGADWG_GTE ( 0x07 << 8 )
/* use this to force colour expansion circuitry to do its stuff */
#define MGADWG_SOLID ( 0x01 << 11 )
/* ar register at zero */
#define MGADWG_ARZERO ( 0x01 << 12 )
#define MGADWG_SGNZERO ( 0x01 << 13 )
#define MGADWG_SHIFTZERO ( 0x01 << 14 )
/* See table on 4-43 for bop ALU operations */
/* See table on 4-44 for translucidity masks */
#define MGADWG_BMONOLEF ( 0x00 << 25 )
#define MGADWG_BMONOWF ( 0x04 << 25 )
#define MGADWG_BPLAN ( 0x01 << 25 )
/* note that if bfcol is specified and you're doing a bitblt, it causes
a fbitblt to be performed, so check that you obey the fbitblt rules */
#define MGADWG_BFCOL ( 0x02 << 25 )
#define MGADWG_BUYUV ( 0x0e << 25 )
#define MGADWG_BU32BGR ( 0x03 << 25 )
#define MGADWG_BU32RGB ( 0x07 << 25 )
#define MGADWG_BU24BGR ( 0x0b << 25 )
#define MGADWG_BU24RGB ( 0x0f << 25 )
#define MGADWG_REPLACE 0x000C0000
/* From Linux kernel sources */
#define MGADWG_PATTERN ( 0x01 << 29 )
#define MGADWG_TRANSC ( 0x01 << 30 )
#define MGADWG_NOCLIP ( 0x01 << 31 )
#define MGAREG_MISC_WRITE 0x3c2
#define MGAREG_MISC_READ 0x3cc
#define MGAREG_MISC_IOADSEL (0x1 << 0)
#define MGAREG_MISC_RAMMAPEN (0x1 << 1)
#define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2)
#define MGAREG_MISC_CLK_SEL_VGA28 (0x1 << 2)
#define MGAREG_MISC_CLK_SEL_MGA_PIX (0x2 << 2)
#define MGAREG_MISC_CLK_SEL_MGA_MSK (0x3 << 2)
#define MGAREG_MISC_VIDEO_DIS (0x1 << 4)
#define MGAREG_MISC_HIGH_PG_SEL (0x1 << 5)
/* MMIO VGA registers */
#define MGAREG_CRTC_INDEX 0x1fd4
#define MGAREG_CRTC_DATA 0x1fd5
#define MGAREG_CRTCEXT_INDEX 0x1fde
#define MGAREG_CRTCEXT_DATA 0x1fdf
/* MGA bits for registers PCI_OPTION_REG */
#define MGA1064_OPT_SYS_CLK_PCI ( 0x00 << 0 )
#define MGA1064_OPT_SYS_CLK_PLL ( 0x01 << 0 )
#define MGA1064_OPT_SYS_CLK_EXT ( 0x02 << 0 )
#define MGA1064_OPT_SYS_CLK_MSK ( 0x03 << 0 )
#define MGA1064_OPT_SYS_CLK_DIS ( 0x01 << 2 )
#define MGA1064_OPT_G_CLK_DIV_1 ( 0x01 << 3 )
#define MGA1064_OPT_M_CLK_DIV_1 ( 0x01 << 4 )
#define MGA1064_OPT_SYS_PLL_PDN ( 0x01 << 5 )
#define MGA1064_OPT_VGA_ION ( 0x01 << 8 )
/* MGA registers in PCI config space */
#define PCI_MGA_INDEX 0x44
#define PCI_MGA_DATA 0x48
#define PCI_MGA_OPTION2 0x50
#define PCI_MGA_OPTION3 0x54
#define RAMDAC_OFFSET 0x3c00
/* TVP3026 direct registers */
#define TVP3026_INDEX 0x00
#define TVP3026_WADR_PAL 0x00
#define TVP3026_COL_PAL 0x01
#define TVP3026_PIX_RD_MSK 0x02
#define TVP3026_RADR_PAL 0x03
#define TVP3026_CUR_COL_ADDR 0x04
#define TVP3026_CUR_COL_DATA 0x05
#define TVP3026_DATA 0x0a
#define TVP3026_CUR_RAM 0x0b
#define TVP3026_CUR_XLOW 0x0c
#define TVP3026_CUR_XHI 0x0d
#define TVP3026_CUR_YLOW 0x0e
#define TVP3026_CUR_YHI 0x0f
/* TVP3026 indirect registers */
#define TVP3026_SILICON_REV 0x01
#define TVP3026_CURSOR_CTL 0x06
#define TVP3026_LATCH_CTL 0x0f
#define TVP3026_TRUE_COLOR_CTL 0x18
#define TVP3026_MUX_CTL 0x19
#define TVP3026_CLK_SEL 0x1a
#define TVP3026_PAL_PAGE 0x1c
#define TVP3026_GEN_CTL 0x1d
#define TVP3026_MISC_CTL 0x1e
#define TVP3026_GEN_IO_CTL 0x2a
#define TVP3026_GEN_IO_DATA 0x2b
#define TVP3026_PLL_ADDR 0x2c
#define TVP3026_PIX_CLK_DATA 0x2d
#define TVP3026_MEM_CLK_DATA 0x2e
#define TVP3026_LOAD_CLK_DATA 0x2f
#define TVP3026_KEY_RED_LOW 0x32
#define TVP3026_KEY_RED_HI 0x33
#define TVP3026_KEY_GREEN_LOW 0x34
#define TVP3026_KEY_GREEN_HI 0x35
#define TVP3026_KEY_BLUE_LOW 0x36
#define TVP3026_KEY_BLUE_HI 0x37
#define TVP3026_KEY_CTL 0x38
#define TVP3026_MCLK_CTL 0x39
#define TVP3026_SENSE_TEST 0x3a
#define TVP3026_TEST_DATA 0x3b
#define TVP3026_CRC_LSB 0x3c
#define TVP3026_CRC_MSB 0x3d
#define TVP3026_CRC_CTL 0x3e
#define TVP3026_ID 0x3f
#define TVP3026_RESET 0xff
/* MGA1064 DAC Register file */
/* MGA1064 direct registers */
#define MGA1064_INDEX 0x00
#define MGA1064_WADR_PAL 0x00
#define MGA1064_COL_PAL 0x01
#define MGA1064_PIX_RD_MSK 0x02
#define MGA1064_RADR_PAL 0x03
#define MGA1064_DATA 0x0a
#define MGA1064_CUR_XLOW 0x0c
#define MGA1064_CUR_XHI 0x0d
#define MGA1064_CUR_YLOW 0x0e
#define MGA1064_CUR_YHI 0x0f
/* MGA1064 indirect registers */
#define MGA1064_CURSOR_BASE_ADR_LOW 0x04
#define MGA1064_CURSOR_BASE_ADR_HI 0x05
#define MGA1064_CURSOR_CTL 0x06
#define MGA1064_CURSOR_COL0_RED 0x08
#define MGA1064_CURSOR_COL0_GREEN 0x09
#define MGA1064_CURSOR_COL0_BLUE 0x0a
#define MGA1064_CURSOR_COL1_RED 0x0c
#define MGA1064_CURSOR_COL1_GREEN 0x0d
#define MGA1064_CURSOR_COL1_BLUE 0x0e
#define MGA1064_CURSOR_COL2_RED 0x010
#define MGA1064_CURSOR_COL2_GREEN 0x011
#define MGA1064_CURSOR_COL2_BLUE 0x012
#define MGA1064_VREF_CTL 0x018
#define MGA1064_MUL_CTL 0x19
#define MGA1064_MUL_CTL_8bits 0x0
#define MGA1064_MUL_CTL_15bits 0x01
#define MGA1064_MUL_CTL_16bits 0x02
#define MGA1064_MUL_CTL_24bits 0x03
#define MGA1064_MUL_CTL_32bits 0x04
#define MGA1064_MUL_CTL_2G8V16bits 0x05
#define MGA1064_MUL_CTL_G16V16bits 0x06
#define MGA1064_MUL_CTL_32_24bits 0x07
#define MGAGDAC_XVREFCTRL 0x18
#define MGA1064_PIX_CLK_CTL 0x1a
#define MGA1064_PIX_CLK_CTL_CLK_DIS ( 0x01 << 2 )
#define MGA1064_PIX_CLK_CTL_CLK_POW_DOWN ( 0x01 << 3 )
#define MGA1064_PIX_CLK_CTL_SEL_PCI ( 0x00 << 0 )
#define MGA1064_PIX_CLK_CTL_SEL_PLL ( 0x01 << 0 )
#define MGA1064_PIX_CLK_CTL_SEL_EXT ( 0x02 << 0 )
#define MGA1064_PIX_CLK_CTL_SEL_MSK ( 0x03 << 0 )
#define MGA1064_GEN_CTL 0x1d
#define MGA1064_MISC_CTL 0x1e
#define MGA1064_MISC_CTL_DAC_POW_DN ( 0x01 << 0 )
#define MGA1064_MISC_CTL_VGA ( 0x01 << 1 )
#define MGA1064_MISC_CTL_DIS_CON ( 0x03 << 1 )
#define MGA1064_MISC_CTL_MAFC ( 0x02 << 1 )
#define MGA1064_MISC_CTL_VGA8 ( 0x01 << 3 )
#define MGA1064_MISC_CTL_DAC_RAM_CS ( 0x01 << 4 )
#define MGA1064_GEN_IO_CTL 0x2a
#define MGA1064_GEN_IO_DATA 0x2b
#define MGA1064_SYS_PLL_M 0x2c
#define MGA1064_SYS_PLL_N 0x2d
#define MGA1064_SYS_PLL_P 0x2e
#define MGA1064_SYS_PLL_STAT 0x2f
#define MGA1064_ZOOM_CTL 0x38
#define MGA1064_SENSE_TST 0x3a
#define MGA1064_CRC_LSB 0x3c
#define MGA1064_CRC_MSB 0x3d
#define MGA1064_CRC_CTL 0x3e
#define MGA1064_COL_KEY_MSK_LSB 0x40
#define MGA1064_COL_KEY_MSK_MSB 0x41
#define MGA1064_COL_KEY_LSB 0x42
#define MGA1064_COL_KEY_MSB 0x43
#define MGA1064_PIX_PLLA_M 0x44
#define MGA1064_PIX_PLLA_N 0x45
#define MGA1064_PIX_PLLA_P 0x46
#define MGA1064_PIX_PLLB_M 0x48
#define MGA1064_PIX_PLLB_N 0x49
#define MGA1064_PIX_PLLB_P 0x4a
#define MGA1064_PIX_PLLC_M 0x4c
#define MGA1064_PIX_PLLC_N 0x4d
#define MGA1064_PIX_PLLC_P 0x4e
#define MGA1064_PIX_PLL_STAT 0x4f
#endif
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/riva_mmio.h
deleted
100644 → 0
View file @
c14d8951
/***************************************************************************\
|* *|
|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
|* *|
|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
|* international laws. Users and possessors of this source code are *|
|* hereby granted a nonexclusive, royalty-free copyright license to *|
|* use this code in individual and commercial software. *|
|* *|
|* Any use of this source code must include, in the user documenta- *|
|* tion and internal comments to the code, notices to the end user *|
|* as follows: *|
|* *|
|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
|* *|
|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
|* SULTING 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 SOURCE CODE. *|
|* *|
|* U.S. Government End Users. This source code is a "commercial *|
|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
|* consisting of "commercial computer software" and "commercial *|
|* computer software documentation," as such terms are used in *|
|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
|* all U.S. Government End Users acquire the source code with only *|
|* those rights set forth herein. *|
|* *|
\***************************************************************************/
#ifndef __RIVA_HW_H__
#define __RIVA_HW_H__
#define RIVA_SW_VERSION 0x00010003
/*
* Typedefs to force certain sized values.
*/
typedef
Uint8
U008
;
typedef
Uint16
U016
;
typedef
Uint32
U032
;
/*
* HW access macros.
*/
#define NV_WR08(p,i,d) (((U008 *)(p))[i]=(d))
#define NV_RD08(p,i) (((U008 *)(p))[i])
#define NV_WR16(p,i,d) (((U016 *)(p))[(i)/2]=(d))
#define NV_RD16(p,i) (((U016 *)(p))[(i)/2])
#define NV_WR32(p,i,d) (((U032 *)(p))[(i)/4]=(d))
#define NV_RD32(p,i) (((U032 *)(p))[(i)/4])
#define VGA_WR08(p,i,d) NV_WR08(p,i,d)
#define VGA_RD08(p,i) NV_RD08(p,i)
/*
* Define supported architectures.
*/
#define NV_ARCH_03 0x03
#define NV_ARCH_04 0x04
#define NV_ARCH_10 0x10
/***************************************************************************\
* *
* FIFO registers. *
* *
\***************************************************************************/
/*
* Raster OPeration. Windows style ROP3.
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
;
U032
reserved01
[
0x0BB
];
U032
Rop3
;
}
RivaRop
;
/*
* 8X8 Monochrome pattern.
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
;
U032
reserved01
[
0x0BD
];
U032
Shape
;
U032
reserved03
[
0x001
];
U032
Color0
;
U032
Color1
;
U032
Monochrome
[
2
];
}
RivaPattern
;
/*
* Scissor clip rectangle.
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
;
U032
reserved01
[
0x0BB
];
U032
TopLeft
;
U032
WidthHeight
;
}
RivaClip
;
/*
* 2D filled rectangle.
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
[
1
];
U032
reserved01
[
0x0BC
];
U032
Color
;
U032
reserved03
[
0x03E
];
U032
TopLeft
;
U032
WidthHeight
;
}
RivaRectangle
;
/*
* 2D screen-screen BLT.
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
;
U032
reserved01
[
0x0BB
];
U032
TopLeftSrc
;
U032
TopLeftDst
;
U032
WidthHeight
;
}
RivaScreenBlt
;
/*
* 2D pixel BLT.
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
[
1
];
U032
reserved01
[
0x0BC
];
U032
TopLeft
;
U032
WidthHeight
;
U032
WidthHeightIn
;
U032
reserved02
[
0x03C
];
U032
Pixels
;
}
RivaPixmap
;
/*
* Filled rectangle combined with monochrome expand. Useful for glyphs.
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
;
U032
reserved01
[
0x0BB
];
U032
reserved03
[(
0x040
)
-
1
];
U032
Color1A
;
struct
{
U032
TopLeft
;
U032
WidthHeight
;
}
UnclippedRectangle
[
64
];
U032
reserved04
[(
0x080
)
-
3
];
struct
{
U032
TopLeft
;
U032
BottomRight
;
}
ClipB
;
U032
Color1B
;
struct
{
U032
TopLeft
;
U032
BottomRight
;
}
ClippedRectangle
[
64
];
U032
reserved05
[(
0x080
)
-
5
];
struct
{
U032
TopLeft
;
U032
BottomRight
;
}
ClipC
;
U032
Color1C
;
U032
WidthHeightC
;
U032
PointC
;
U032
MonochromeData1C
;
U032
reserved06
[(
0x080
)
+
121
];
struct
{
U032
TopLeft
;
U032
BottomRight
;
}
ClipD
;
U032
Color1D
;
U032
WidthHeightInD
;
U032
WidthHeightOutD
;
U032
PointD
;
U032
MonochromeData1D
;
U032
reserved07
[(
0x080
)
+
120
];
struct
{
U032
TopLeft
;
U032
BottomRight
;
}
ClipE
;
U032
Color0E
;
U032
Color1E
;
U032
WidthHeightInE
;
U032
WidthHeightOutE
;
U032
PointE
;
U032
MonochromeData01E
;
}
RivaBitmap
;
/*
* 3D textured, Z buffered triangle.
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
;
U032
reserved01
[
0x0BC
];
U032
TextureOffset
;
U032
TextureFormat
;
U032
TextureFilter
;
U032
FogColor
;
/* This is a problem on LynxOS */
#ifdef Control
#undef Control
#endif
U032
Control
;
U032
AlphaTest
;
U032
reserved02
[
0x339
];
U032
FogAndIndex
;
U032
Color
;
float
ScreenX
;
float
ScreenY
;
float
ScreenZ
;
float
EyeM
;
float
TextureS
;
float
TextureT
;
}
RivaTexturedTriangle03
;
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
;
U032
reserved01
[
0x0BB
];
U032
ColorKey
;
U032
TextureOffset
;
U032
TextureFormat
;
U032
TextureFilter
;
U032
Blend
;
/* This is a problem on LynxOS */
#ifdef Control
#undef Control
#endif
U032
Control
;
U032
FogColor
;
U032
reserved02
[
0x39
];
struct
{
float
ScreenX
;
float
ScreenY
;
float
ScreenZ
;
float
EyeM
;
U032
Color
;
U032
Specular
;
float
TextureS
;
float
TextureT
;
}
Vertex
[
16
];
U032
DrawTriangle3D
;
}
RivaTexturedTriangle05
;
/*
* 2D line.
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
[
1
];
U032
reserved01
[
0x0BC
];
U032
Color
;
/* source color 0304-0307 */
U032
Reserved02
[
0x03e
];
struct
{
/* start aliased methods in array 0400- */
U032
point0
;
/* y_x S16_S16 in pixels 0- 3 */
U032
point1
;
/* y_x S16_S16 in pixels 4- 7 */
}
Lin
[
16
];
/* end of aliased methods in array -047f */
struct
{
/* start aliased methods in array 0480- */
U032
point0X
;
/* in pixels, 0 at left 0- 3 */
U032
point0Y
;
/* in pixels, 0 at top 4- 7 */
U032
point1X
;
/* in pixels, 0 at left 8- b */
U032
point1Y
;
/* in pixels, 0 at top c- f */
}
Lin32
[
8
];
/* end of aliased methods in array -04ff */
U032
PolyLin
[
32
];
/* y_x S16_S16 in pixels 0500-057f */
struct
{
/* start aliased methods in array 0580- */
U032
x
;
/* in pixels, 0 at left 0- 3 */
U032
y
;
/* in pixels, 0 at top 4- 7 */
}
PolyLin32
[
16
];
/* end of aliased methods in array -05ff */
struct
{
/* start aliased methods in array 0600- */
U032
color
;
/* source color 0- 3 */
U032
point
;
/* y_x S16_S16 in pixels 4- 7 */
}
ColorPolyLin
[
16
];
/* end of aliased methods in array -067f */
}
RivaLine
;
/*
* 2D/3D surfaces
*/
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
;
U032
reserved01
[
0x0BE
];
U032
Offset
;
}
RivaSurface
;
typedef
volatile
struct
{
U032
reserved00
[
4
];
U016
FifoFree
;
U016
Nop
;
U032
reserved01
[
0x0BD
];
U032
Pitch
;
U032
RenderBufferOffset
;
U032
ZBufferOffset
;
}
RivaSurface3D
;
/***************************************************************************\
* *
* Virtualized RIVA H/W interface. *
* *
\***************************************************************************/
struct
_riva_hw_inst
;
struct
_riva_hw_state
;
/*
* Virtialized chip interface. Makes RIVA 128 and TNT look alike.
*/
typedef
struct
_riva_hw_inst
{
/*
* Chip specific settings.
*/
U032
Architecture
;
U032
Version
;
U032
CrystalFreqKHz
;
U032
RamAmountKBytes
;
U032
MaxVClockFreqKHz
;
U032
RamBandwidthKBytesPerSec
;
U032
EnableIRQ
;
U032
IO
;
U032
VBlankBit
;
U032
FifoFreeCount
;
U032
FifoEmptyCount
;
/*
* Non-FIFO registers.
*/
volatile
U032
*
PCRTC
;
volatile
U032
*
PRAMDAC
;
volatile
U032
*
PFB
;
volatile
U032
*
PFIFO
;
volatile
U032
*
PGRAPH
;
volatile
U032
*
PEXTDEV
;
volatile
U032
*
PTIMER
;
volatile
U032
*
PMC
;
volatile
U032
*
PRAMIN
;
volatile
U032
*
FIFO
;
volatile
U032
*
CURSOR
;
volatile
U032
*
CURSORPOS
;
volatile
U032
*
VBLANKENABLE
;
volatile
U032
*
VBLANK
;
volatile
U008
*
PCIO
;
volatile
U008
*
PVIO
;
volatile
U008
*
PDIO
;
/*
* Common chip functions.
*/
int
(
*
Busy
)
(
struct
_riva_hw_inst
*
);
void
(
*
CalcStateExt
)
(
struct
_riva_hw_inst
*
,
struct
_riva_hw_state
*
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
int
);
void
(
*
LoadStateExt
)
(
struct
_riva_hw_inst
*
,
struct
_riva_hw_state
*
);
void
(
*
UnloadStateExt
)
(
struct
_riva_hw_inst
*
,
struct
_riva_hw_state
*
);
void
(
*
SetStartAddress
)
(
struct
_riva_hw_inst
*
,
U032
);
void
(
*
SetSurfaces2D
)
(
struct
_riva_hw_inst
*
,
U032
,
U032
);
void
(
*
SetSurfaces3D
)
(
struct
_riva_hw_inst
*
,
U032
,
U032
);
int
(
*
ShowHideCursor
)
(
struct
_riva_hw_inst
*
,
int
);
void
(
*
LockUnlock
)
(
struct
_riva_hw_inst
*
,
int
);
/*
* Current extended mode settings.
*/
struct
_riva_hw_state
*
CurrentState
;
/*
* FIFO registers.
*/
RivaRop
*
Rop
;
RivaPattern
*
Patt
;
RivaClip
*
Clip
;
RivaPixmap
*
Pixmap
;
RivaScreenBlt
*
Blt
;
RivaBitmap
*
Bitmap
;
RivaLine
*
Line
;
RivaTexturedTriangle03
*
Tri03
;
RivaTexturedTriangle05
*
Tri05
;
}
RIVA_HW_INST
;
/*
* Extended mode state information.
*/
typedef
struct
_riva_hw_state
{
U032
bpp
;
U032
width
;
U032
height
;
U032
repaint0
;
U032
repaint1
;
U032
screen
;
U032
pixel
;
U032
horiz
;
U032
arbitration0
;
U032
arbitration1
;
U032
vpll
;
U032
pllsel
;
U032
general
;
U032
config
;
U032
cursor0
;
U032
cursor1
;
U032
cursor2
;
U032
offset0
;
U032
offset1
;
U032
offset2
;
U032
offset3
;
U032
pitch0
;
U032
pitch1
;
U032
pitch2
;
U032
pitch3
;
}
RIVA_HW_STATE
;
/*
* FIFO Free Count. Should attempt to yield processor if RIVA is busy.
*/
#define RIVA_FIFO_FREE(hwptr,cnt) \
{ \
while (FifoFreeCount < (cnt)) \
FifoFreeCount = hwptr->FifoFree >> 2; \
FifoFreeCount -= (cnt); \
}
#endif
/* __RIVA_HW_H__ */
/* vi: set ts=4 sw=4 expandtab: */
src/video/fbcon/riva_regs.h
deleted
100644 → 0
View file @
c14d8951
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#ifndef _RIVA_REGS_H
#define _RIVA_REGS_H
/* This information comes from the XFree86 NVidia hardware driver */
/* mapped_io register offsets */
#define PGRAPH_OFFSET 0x00400000
#define FIFO_OFFSET 0x00800000
#define ROP_OFFSET FIFO_OFFSET+0x00000000
#define CLIP_OFFSET FIFO_OFFSET+0x00002000
#define PATT_OFFSET FIFO_OFFSET+0x00004000
#define PIXMAP_OFFSET FIFO_OFFSET+0x00006000
#define BLT_OFFSET FIFO_OFFSET+0x00008000
#define BITMAP_OFFSET FIFO_OFFSET+0x0000A000
#define LINE_OFFSET FIFO_OFFSET+0x0000C000
#define TRI03_OFFSET FIFO_OFFSET+0x0000E000
#define PCIO_OFFSET 0x00601000
#endif
/* _RIVA_REGS_H */
/* vi: set ts=4 sw=4 expandtab: */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment