#include "sun.h"
#include "gcstruct.h"
#include "mi.h"
#include "mibstore.h"
#include "cfb.h"
#include "cfb16.h"
#include "cfb32.h"
#ifndef SUNMAXDEPTH
#define SUNMAXDEPTH 8
#endif
#ifdef i386
#define BW2I NULL
#else
extern Bool sunBW2Init(
int ,
ScreenPtr ,
int ,
char**
);
#define BW2I sunBW2Init
#endif
#ifdef LOWMEMFTPT
#define BW2I NULL
#endif
#if SUNMAXDEPTH == 1
#define CG2I NULL
#define CG3I NULL
#define CG4I NULL
#define CG6I NULL
#define CG8I NULL
#define TCXI NULL
#else
extern Bool sunCG3Init(
int ,
ScreenPtr ,
int ,
char**
);
#define CG3I sunCG3Init
#if defined(i386) || defined(__bsdi__)
#define CG2I NULL
#define CG4I NULL
#else
#ifdef INCLUDE_CG2_HEADER
extern Bool sunCG2Init(
int ,
ScreenPtr ,
int ,
char**
);
#define CG2I sunCG2Init
#endif
extern Bool sunCG4Init(
int ,
ScreenPtr ,
int ,
char**
);
#define CG4I sunCG4Init
#endif
#ifdef FBTYPE_SUNFAST_COLOR
extern Bool sunCG6Init(
int ,
ScreenPtr ,
int ,
char**
);
#define CG6I sunCG6Init
#else
#define CG6I NULL
#endif
#ifdef XFBTYPE_TCX
extern Bool sunTCXInit(
int ,
ScreenPtr ,
int ,
char**
);
#define TCXI sunTCXInit
#else
#define TCXI NULL
#endif
#if SUNMAXDEPTH > 8
#ifdef FBTYPE_MEMCOLOR
extern Bool sunCG8Init(
int ,
ScreenPtr ,
int ,
char**
);
#define CG8I sunCG8Init
#else
#define CG8I NULL
#endif
#else
#define CG8I NULL
#endif
#endif
extern KeySymsRec sunKeySyms[];
extern SunModmapRec *sunModMaps[];
extern int sunMaxLayout;
extern KeySym* sunType4KeyMaps[];
extern SunModmapRec* sunType4ModMaps[];
static Bool sunDevsInited = FALSE;
Bool sunAutoRepeatHandlersInstalled;
Bool sunSwapLkeys = FALSE;
Bool sunFlipPixels = FALSE;
Bool sunFbInfo = FALSE;
Bool sunCG4Frob = FALSE;
Bool sunNoGX = FALSE;
sunKbdPrivRec sunKbdPriv = {
-1,
-1,
-1,
0,
(Leds)0,
};
sunPtrPrivRec sunPtrPriv = {
-1,
0
};
sunFbDataRec sunFbData[XFBTYPE_LASTPLUSONE] = {
{ NULL, "SUN1BW (bw1)" },
{ NULL, "SUN1COLOR (cg1)" },
{ BW2I, "SUN2BW (bw2)" },
#ifdef INCLUDE_CG2_HEADER
{ CG2I, "SUN2COLOR (cg2)" },
#endif
{ NULL, "SUN2GP (gp1/gp2)" },
{ NULL, "SUN5COLOR (cg5/386i accel)" },
{ CG3I, "SUN3COLOR (cg3)" },
{ CG8I, "MEMCOLOR (cg8)" },
{ CG4I, "SUN4COLOR (cg4)" },
{ NULL, "NOTSUN1" },
{ NULL, "NOTSUN2" },
{ NULL, "NOTSUN3" }
#ifndef i386
,{ CG6I, "SUNFAST_COLOR (cg6/gx)" },
{ NULL, "SUNROP_COLOR (cg9)" },
{ NULL, "SUNFB_VIDEO" },
{ NULL, "SUNGIFB" },
{ NULL, "SUNPLAS" },
#ifdef FBTYPE_SUNGP3
{ NULL, "SUNGP3 (cg12/gs)" },
#endif
#ifdef FBTYPE_SUNGT
{ NULL, "SUNGT (gt)" },
#endif
#ifdef FBTYPE_SUNLEO
{ NULL, "SUNLEO (zx)" },
#endif
#ifdef FBTYPE_MDICOLOR
{ NULL, "MDICOLOR (cgfourteen)" },
#endif
#ifdef XFBTYPE_TCX
{ TCXI, "TCX (tcx)" },
#endif
#endif
};
#if SUNMAXDEPTH == 1
static char *fallbackList[] = {
BWTWO0DEV, BWTWO1DEV, BWTWO2DEV
};
#else
static char *fallbackList[] = {
#ifndef i386
CGTWO0DEV, CGTWO1DEV, CGTWO2DEV,
#if (MAXSCREENS == 4)
CGTWO3DEV,
#endif
#endif
CGTHREE0DEV,
#ifndef i386
CGTHREE1DEV, CGTHREE2DEV,
#if (MAXSCREENS == 4)
CGTHREE3DEV,
#endif
#endif
#ifdef FBTYPE_SUNFAST_COLOR
CGSIX0DEV, CGSIX1DEV, CGSIX2DEV,
#if (MAXSCREENS == 4)
CGSIX3DEV,
#endif
#endif
#ifndef i386
CGFOUR0DEV, BWTWO0DEV, BWTWO1DEV, BWTWO2DEV,
#if (MAXSCREENS == 4)
BWTWO3DEV,
#endif
#endif
#if SUNMAXDEPTH > 8
CGEIGHT0DEV,
#if 0
#ifdef XFBTYPE_TCX
TCX0DEV,
#endif
#endif
#endif
"/dev/fb"
};
#endif
#define FALLBACK_LIST_LEN sizeof fallbackList / sizeof fallbackList[0]
fbFd sunFbs[MAXSCREENS];
static PixmapFormatRec formats[] = {
{ 1, 1, BITMAP_SCANLINE_PAD }
#if SUNMAXDEPTH > 1
,{ 8, 8, BITMAP_SCANLINE_PAD}
#if SUNMAXDEPTH > 8
,{ 12, 24, BITMAP_SCANLINE_PAD }
,{ 24, 32, BITMAP_SCANLINE_PAD }
#endif
#endif
};
#define NUMFORMATS (sizeof formats)/(sizeof formats[0])
static int OpenFrameBuffer(device, screen)
char *device;
int screen;
{
int ret = TRUE;
struct fbgattr *fbattr;
static int devFbUsed;
sunFbs[screen].fd = -1;
if (strcmp (device, "/dev/fb") == 0 && devFbUsed)
return FALSE;
if (access (device, R_OK | W_OK) == -1)
return FALSE;
if ((sunFbs[screen].fd = open(device, O_RDWR, 0)) == -1)
ret = FALSE;
else {
fbattr = (struct fbgattr *) xalloc (sizeof (struct fbgattr));
if (ioctl(sunFbs[screen].fd, FBIOGATTR, fbattr) == -1) {
xfree (fbattr);
fbattr = NULL;
if (ioctl(sunFbs[screen].fd, FBIOGTYPE, &sunFbs[screen].info) == -1) {
Error("unable to get frame buffer attributes");
(void) close(sunFbs[screen].fd);
sunFbs[screen].fd = -1;
return FALSE;
}
}
if (ret) {
devFbUsed = TRUE;
if (fbattr) {
if (fbattr->fbtype.fb_type >= XFBTYPE_LASTPLUSONE) {
ErrorF ("%s is an unknown framebuffer type\n", device);
(void) close(sunFbs[screen].fd);
sunFbs[screen].fd = -1;
return FALSE;
}
sunFbs[screen].info = fbattr->fbtype;
}
sunFbs[screen].fbPriv = (pointer) fbattr;
if (fbattr && !sunFbData[fbattr->fbtype.fb_type].init) {
int _i;
ret = FALSE;
for (_i = 0; _i < FB_ATTR_NEMUTYPES; _i++) {
if (sunFbData[fbattr->emu_types[_i]].init) {
sunFbs[screen].info.fb_type = fbattr->emu_types[_i];
ret = TRUE;
if (sunFbInfo)
ErrorF ("%s is emulating a %s\n", device,
sunFbData[fbattr->fbtype.fb_type].name);
break;
}
}
}
if (sunFbInfo)
ErrorF ("%s is really a %s\n", device,
sunFbData[fbattr ? fbattr->fbtype.fb_type : sunFbs[screen].info.fb_type].name);
}
}
if (!ret)
sunFbs[screen].fd = -1;
return ret;
}
static void SigIOHandler(sig)
int sig;
{
int olderrno = errno;
sunEnqueueEvents ();
errno = olderrno;
}
void sunNonBlockConsoleOff(
#if defined(SVR4) || defined(CSRG_BASED)
void
#else
char* arg
#endif
)
{
register int i;
i = fcntl(2, F_GETFL, 0);
if (i >= 0)
(void) fcntl(2, F_SETFL, i & ~FNDELAY);
}
static char** GetDeviceList (argc, argv)
int argc;
char **argv;
{
int i;
char *envList = NULL;
char *cmdList = NULL;
char **deviceList = (char **)NULL;
for (i = 1; i < argc; i++)
if (strcmp (argv[i], "-dev") == 0 && i+1 < argc) {
cmdList = argv[i + 1];
break;
}
if (!cmdList)
envList = getenv ("XDEVICE");
if (cmdList || envList) {
char *_tmpa;
char *_tmpb;
int _i1;
deviceList = (char **) xalloc ((MAXSCREENS + 1) * sizeof (char *));
_tmpa = (cmdList) ? cmdList : envList;
for (_i1 = 0; _i1 < MAXSCREENS; _i1++) {
_tmpb = strtok (_tmpa, ":");
if (_tmpb)
deviceList[_i1] = _tmpb;
else
deviceList[_i1] = NULL;
_tmpa = NULL;
}
deviceList[MAXSCREENS] = NULL;
}
if (!deviceList) {
deviceList =
(char **) xalloc ((FALLBACK_LIST_LEN + 1) * sizeof (char *));
for (i = 0; i < FALLBACK_LIST_LEN; i++)
deviceList[i] = fallbackList[i];
deviceList[FALLBACK_LIST_LEN] = NULL;
}
return deviceList;
}
static void getKbdType()
{
#if !defined(i386) && !defined(KIOCGKEY)
#define TYPE4KEYBOARDOVERRIDE
#endif
int ii;
for (ii = 0; ii < 3; ii++) {
sunKbdWait();
(void) ioctl (sunKbdPriv.fd, KIOCTYPE, &sunKbdPriv.type);
#ifdef TYPE4KEYBOARDOVERRIDE
if (sunKbdPriv.type == KB_SUN3) {
struct kiockeymap key;
key.kio_tablemask = 0;
key.kio_station = 118;
if (ioctl(sunKbdPriv.fd, KIOCGKEY, &key) == -1) {
Error( "ioctl KIOCGKEY" );
FatalError("Can't KIOCGKEY on fd %d\n", sunKbdPriv.fd);
}
if (key.kio_entry != HOLE)
sunKbdPriv.type = KB_SUN4;
}
#endif
switch (sunKbdPriv.type) {
case KB_SUN2:
case KB_SUN3:
case KB_SUN4: return;
default:
sunChangeKbdTranslation(sunKbdPriv.fd, FALSE);
continue;
}
}
FatalError ("Unsupported keyboard type %d\n", sunKbdPriv.type);
}
void OsVendorInit(
void
)
{
static int inited;
if (!inited) {
#ifndef i386
struct rlimit rl;
int maxfds = MAXCLIENTS + MAXSCREENS + 5;
if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
rl.rlim_cur = maxfds < rl.rlim_max ? maxfds : rl.rlim_max;
(void) setrlimit (RLIMIT_NOFILE, &rl);
}
#endif
sunKbdPriv.fd = open ("/dev/kbd", O_RDWR, 0);
if (sunKbdPriv.fd < 0)
FatalError ("Cannot open /dev/kbd, error %d\n", errno);
sunPtrPriv.fd = open ("/dev/mouse", O_RDWR, 0);
if (sunPtrPriv.fd < 0)
FatalError ("Cannot open /dev/mouse, error %d\n", errno);
getKbdType ();
if (sunKbdPriv.type == KB_SUN4) {
(void) ioctl (sunKbdPriv.fd, KIOCLAYOUT, &sunKbdPriv.layout);
if (sunKbdPriv.layout < 0 ||
sunKbdPriv.layout > sunMaxLayout ||
sunType4KeyMaps[sunKbdPriv.layout] == NULL)
FatalError ("Unsupported keyboard type 4 layout %d\n",
sunKbdPriv.layout);
sunKeySyms[KB_SUN4].map = sunType4KeyMaps[sunKbdPriv.layout];
sunModMaps[KB_SUN4] = sunType4ModMaps[sunKbdPriv.layout];
}
inited = 1;
}
}
#ifdef DDXOSFATALERROR
void OsVendorFatalError(void)
{
}
#endif
void InitOutput(pScreenInfo, argc, argv)
ScreenInfo *pScreenInfo;
int argc;
char **argv;
{
int i, scr;
int nonBlockConsole = 0;
char **devList;
static int setup_on_exit = 0;
extern Bool RunFromSmartParent;
if (!monitorResolution)
monitorResolution = 90;
if (RunFromSmartParent)
nonBlockConsole = 1;
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i],"-debug"))
nonBlockConsole = 0;
}
if (nonBlockConsole) {
if (!setup_on_exit) {
#if defined(SVR4) || defined(CSRG_BASED)
if (atexit(sunNonBlockConsoleOff))
#else
if (on_exit(sunNonBlockConsoleOff, (char *)0))
#endif
ErrorF("InitOutput: can't register NBIO exit handler\n");
setup_on_exit = 1;
}
i = fcntl(2, F_GETFL, 0);
if (i >= 0)
i = fcntl(2, F_SETFL, i | FNDELAY);
if (i < 0) {
Error("fcntl");
ErrorF("InitOutput: can't put stderr in non-block mode\n");
}
}
pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
pScreenInfo->numPixmapFormats = NUMFORMATS;
for (i=0; i< NUMFORMATS; i++)
pScreenInfo->formats[i] = formats[i];
#ifdef XKB
if (noXkbExtension)
#endif
sunAutoRepeatHandlersInstalled = FALSE;
if (!sunDevsInited) {
for (scr = 0; scr < MAXSCREENS; scr++)
sunFbs[scr].fd = -1;
devList = GetDeviceList (argc, argv);
for (i = 0, scr = 0; devList[i] != NULL && scr < MAXSCREENS; i++)
if (OpenFrameBuffer (devList[i], scr))
scr++;
sunDevsInited = TRUE;
xfree (devList);
}
for (scr = 0; scr < MAXSCREENS; scr++)
if (sunFbs[scr].fd != -1)
(void) AddScreen (sunFbData[sunFbs[scr].info.fb_type].init,
argc, argv);
(void) OsSignal(SIGWINCH, SIG_IGN);
}
void InitInput(argc, argv)
int argc;
char **argv;
{
pointer p, k;
extern Bool mieqInit();
p = AddInputDevice(sunMouseProc, TRUE);
k = AddInputDevice(sunKbdProc, TRUE);
if (!p || !k)
FatalError("failed to create input devices in InitInput");
RegisterPointerDevice(p);
RegisterKeyboardDevice(k);
miRegisterPointerDevice(screenInfo.screens[0], p);
(void) mieqInit (k, p);
#define SET_FLOW(fd) fcntl(fd, F_SETFL, FNDELAY | FASYNC)
#ifdef SVR4
(void) OsSignal(SIGPOLL, SigIOHandler);
#define WANT_SIGNALS(fd) ioctl(fd, I_SETSIG, S_INPUT | S_HIPRI)
#else
(void) OsSignal(SIGIO, SigIOHandler);
#define WANT_SIGNALS(fd) fcntl(fd, F_SETOWN, getpid())
#endif
if (sunKbdPriv.fd >= 0) {
if (SET_FLOW(sunKbdPriv.fd) == -1 || WANT_SIGNALS(sunKbdPriv.fd) == -1) {
(void) close (sunKbdPriv.fd);
sunKbdPriv.fd = -1;
FatalError("Async kbd I/O failed in InitInput");
}
}
if (sunPtrPriv.fd >= 0) {
if (SET_FLOW(sunPtrPriv.fd) == -1 || WANT_SIGNALS(sunPtrPriv.fd) == -1) {
(void) close (sunPtrPriv.fd);
sunPtrPriv.fd = -1;
FatalError("Async mouse I/O failed in InitInput");
}
}
}
#if SUNMAXDEPTH == 8
Bool
sunCfbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)
register ScreenPtr pScreen;
pointer pbits;
int xsize, ysize;
int dpix, dpiy;
int width;
int bpp;
{
return cfbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy,
width);
}
Bool
sunCfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)
register ScreenPtr pScreen;
pointer pbits;
int xsize, ysize;
int dpix, dpiy;
int width;
int bpp;
{
return cfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
width);
}
Bool
sunCfbScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)
register ScreenPtr pScreen;
pointer pbits;
int xsize, ysize;
int dpix, dpiy;
int width;
int bpp;
{
return cfbScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width);
}
#else
#if SUNMAXDEPTH == 32
static Bool
sunCfbCreateGC(pGC)
GCPtr pGC;
{
if (pGC->depth == 1)
{
return mfbCreateGC (pGC);
}
else if (pGC->depth <= 8)
{
return cfbCreateGC (pGC);
}
else if (pGC->depth <= 16)
{
return cfb16CreateGC (pGC);
}
else if (pGC->depth <= 32)
{
return cfb32CreateGC (pGC);
}
return FALSE;
}
static void
sunCfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
DrawablePtr pDrawable;
int wMax;
register DDXPointPtr ppt;
int *pwidth;
int nspans;
char *pdstStart;
{
switch (pDrawable->bitsPerPixel) {
case 1:
mfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
break;
case 8:
cfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
break;
case 16:
cfb16GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
break;
case 32:
cfb32GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
break;
}
return;
}
static void
sunCfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine)
DrawablePtr pDrawable;
int sx, sy, w, h;
unsigned int format;
unsigned long planeMask;
char *pdstLine;
{
switch (pDrawable->bitsPerPixel)
{
case 1:
mfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
break;
case 8:
cfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
break;
case 16:
cfb16GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
break;
case 32:
cfb32GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
break;
}
}
Bool
sunCfbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)
register ScreenPtr pScreen;
pointer pbits;
int xsize, ysize;
int dpix, dpiy;
int width;
int bpp;
{
int ret;
switch (bpp) {
case 8:
ret = cfbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width);
break;
case 16:
ret = cfb16SetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width);
break;
case 32:
ret = cfb32SetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width);
break;
default:
return FALSE;
}
pScreen->CreateGC = sunCfbCreateGC;
pScreen->GetImage = sunCfbGetImage;
pScreen->GetSpans = sunCfbGetSpans;
return ret;
}
#undef CFB_NEED_SCREEN_PRIVATE
#if !defined(SINGLEDEPTH) || defined(FORDE_SEPARATE_PRIVATE)
#define CFB_NEED_SCREEN_PRIVATE
#endif
extern BSFuncRec cfbBSFuncRec, cfb16BSFuncRec, cfb32BSFuncRec;
extern Bool cfbCloseScreen(), cfb16CloseScreen(), cfb32CloseScreen();
#ifdef CFB_NEED_SCREEN_PRIVATE
extern int cfb16ScreenPrivateIndex, cfb32ScreenPrivateIndex;
#endif
Bool
sunCfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)
register ScreenPtr pScreen;
pointer pbits;
int xsize, ysize;
int dpix, dpiy;
int width;
int bpp;
{
#ifdef CFB_NEED_SCREEN_PRIVATE
pointer oldDevPrivate;
#endif
VisualPtr visuals;
int nvisuals;
DepthPtr depths;
int ndepths;
VisualID defaultVisual;
int rootdepth = 0;
if (!cfbInitVisuals(&visuals, &depths, &nvisuals, &ndepths,
&rootdepth, &defaultVisual, 1 << (bpp - 1), 8))
return FALSE;
#ifdef CFB_NEED_SCREEN_PRIVATE
oldDevPrivate = pScreen->devPrivate;
#endif
if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
rootdepth, ndepths, depths,
defaultVisual, nvisuals, visuals))
return FALSE;
switch (bpp)
{
case 8:
pScreen->CloseScreen = cfbCloseScreen;
pScreen->BackingStoreFuncs = cfbBSFuncRec;
break;
case 16:
pScreen->CloseScreen = cfb16CloseScreen;
pScreen->BackingStoreFuncs = cfb16BSFuncRec;
#ifdef CFB_NEED_SCREEN_PRIVATE
pScreen->devPrivates[cfb16ScreenPrivateIndex].ptr =
pScreen->devPrivate;
pScreen->devPrivate = oldDevPrivate;
#endif
break;
case 32:
pScreen->CloseScreen = cfb32CloseScreen;
pScreen->BackingStoreFuncs = cfb32BSFuncRec;
#ifdef CFB_NEED_SCREEN_PRIVATE
pScreen->devPrivates[cfb32ScreenPrivateIndex].ptr =
pScreen->devPrivate;
pScreen->devPrivate = oldDevPrivate;
#endif
break;
}
return TRUE;
}
Bool
sunCfbScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)
register ScreenPtr pScreen;
pointer pbits;
int xsize, ysize;
int dpix, dpiy;
int width;
int bpp;
{
if (!sunCfbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy,
width, bpp))
return FALSE;
return sunCfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix,
dpiy, width, bpp);
}
#endif
#endif
#ifdef DPMSExtension
void DPMSSet (level)
int level;
{
}
int DPMSGet (level)
int* level;
{
return -1;
}
Bool DPMSSupported ()
{
return FALSE;
}
#endif