Add PCMCIA server for HP VGA Out PC Card and the Voyager VGA Card. Use on

the Compaq IPAQ. Use -listmodes to see supported modes. Hack the
    touchscreen driver to work as a mouse pad for the VGA screen. Fixup key
    bindings so xmodmap can remap IPAQ's buttons as mouse buttons.
This commit is contained in:
Alan Hourihane 2001-05-23 08:56:09 +00:00
parent f9104754cd
commit 85d827f532
14 changed files with 2044 additions and 16 deletions

View File

@ -1,5 +1,5 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Imakefile,v 1.5 2000/12/01 00:01:30 keithp Exp $
XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Imakefile,v 1.6 2001/03/30 02:15:19 keithp Exp $
KDRIVE=.
#include "Kdrive.tmpl"
@ -13,6 +13,10 @@ XVSRCS=kxv.c
XVOBJS=kxv.o
#endif
#if XipaqServer
DEFINES = -DXIPAQ
#endif
SRCS = kcmap.c kcolor.c kdrive.c kinfo.c kinput.c kmap.c knoop.c ktest.c \
vga.c kasync.c kmode.c kcurscol.c kshadow.c $(RENDERSRCS) $(XVSRCS)

View File

@ -1,8 +1,12 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/Imakefile,v 1.2 2000/09/03 05:11:17 keithp Exp $
XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/Imakefile,v 1.3 2000/12/01 00:01:31 keithp Exp $
KDRIVE=..
#include "../Kdrive.tmpl"
#ifdef XipaqServer
DEFINES = -DXIPAQ
#endif
SRCS = fbdev.c fbinit.c
OBJS = fbdev.o fbinit.o

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.10 2000/10/03 17:22:14 keithp Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.11 2001/03/30 02:15:20 keithp Exp $ */
#include "fbdev.h"
@ -295,6 +295,8 @@ fbdevUpdateFake24 (ScreenPtr pScreen,
}
#endif /* FAKE24_ON_16 */
int TsFbdev = -1;
Bool
fbdevInitScreen (ScreenPtr pScreen)
{
@ -304,6 +306,8 @@ fbdevInitScreen (ScreenPtr pScreen)
ShadowUpdateProc update;
ShadowWindowProc window;
TsFbdev = pScreen->myNum;
if (scrpriv->shadow)
{
window = fbdevWindowLinear;

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c,v 1.4 2000/09/22 06:25:08 keithp Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c,v 1.6 2000/09/28 20:58:21 keithp Exp $ */
#include <fbdev.h>
@ -53,6 +53,7 @@ KdCardFuncs fbdevFuncs = {
fbdevPutColors, /* putColors */
};
#ifndef XIPAQ
void
InitCard (char *name)
{
@ -85,3 +86,4 @@ ddxProcessArgument (int argc, char **argv, int i)
{
return KdProcessArgument (argc, argv, i);
}
#endif

View File

@ -1,5 +1,5 @@
/*
* $XFree86$
* $XFree86: xc/programs/Xserver/hw/kdrive/linux/ts.c,v 1.2 2000/09/26 15:57:04 tsi Exp $
*
* Derived from ps2.c by Jim Gettys
*
@ -35,6 +35,10 @@
#include <sys/ioctl.h>
#include <linux/h3600_ts.h> /* touch screen events */
static long lastx = 0, lasty = 0;
int TsScreen;
extern int TsFbdev;
void
TsRead (int tsPort)
{
@ -52,20 +56,39 @@ TsRead (int tsPort)
{
if (event.pressure)
{
flags = KD_BUTTON_1;
x = event.x;
y = event.y;
}
else {
/*
* HACK ATTACK. (static global variables used !)
* Here we test for the touch screen driver actually being on the
* touch screen, if it is we send absolute coordinates. If not,
* then we send delta's so that we can track the entire vga screen.
*/
if (TsScreen == TsFbdev) {
flags = KD_BUTTON_1;
x = event.x;
y = event.y;
} else {
flags = /* KD_BUTTON_1 |*/ KD_MOUSE_DELTA;
if ((lastx == 0) || (lasty == 0)) {
x = 0;
y = 0;
} else {
x = event.x - lastx;
y = event.y - lasty;
}
lastx = event.x;
lasty = event.y;
}
} else {
flags = KD_MOUSE_DELTA;
x = 0;
y = 0;
lastx = 0;
lasty = 0;
}
KdEnqueueMouseEvent (flags, x, y);
}
}
char *TsNames[] = {
"/dev/ts",
"/dev/h3600_ts" /* temporary name; note this code can try

View File

@ -0,0 +1,13 @@
XCOMM $XFree86$
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = pcmcia.c pcmciacurs.c pcmciastub.c pcmciashadow.c
OBJS = pcmcia.o pcmciacurs.o pcmciastub.o pcmciashadow.o
INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/fbdev
NormalLibraryObjectRule()
NormalLibraryTarget(pcmcia,$(OBJS))
DependTarget()

66
hw/kdrive/pcmcia/modes.h Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Alan Hourihane not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Alan Hourihane makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
*/
/* $XFree86$ */
#define V_NHSYNC 0x01
#define V_NVSYNC 0x02
#define V_PHSYNC 0x04
#define V_PVSYNC 0x08
#define V_INTERLACE 0x10
pcmciaDisplayModeRec pcmciaDefaultModes [] = {
/* 640x400 @ 70Hz (VGA) hsync: 37.9kHz */
{640, 400, 70 ,31500, 640,672,736,832,0, 400,401,404,445,0, V_NHSYNC | V_PVSYNC},
/* 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz */
{640, 480, 60 ,25200, 640,656,752,800,0, 480,490,492,525,0, V_NHSYNC | V_NVSYNC},
/* 640x480 @ 72Hz (VESA) hsync: 37.9kHz */
{640, 480, 72 ,31500, 640,664,704,832,0, 480,489,491,520,0, V_NHSYNC | V_NVSYNC},
/* 640x480 @ 75Hz (VESA) hsync: 37.5kHz */
{640, 480, 75 ,31500, 640,656,720,840,0, 480,481,484,500,0, V_NHSYNC | V_NVSYNC},
/* 640x480 @ 85Hz (VESA) hsync: 43.3kHz */
{640, 480, 85 ,36000, 640,696,752,832,0, 480,481,484,509,0, V_NHSYNC | V_NVSYNC},
/* 800x600 @ 56Hz (VESA) hsync: 35.2kHz */
{800, 600, 56 ,36000, 800,824,896,1024,0, 600,601,603,625,0, V_PHSYNC | V_PVSYNC},
/* 800x600 @ 60Hz (VESA) hsync: 37.9kHz */
{800, 600, 60 ,40000, 800,840,968,1056,0, 600,601,605,628,0, V_PHSYNC | V_PVSYNC},
/* 800x600 @ 72Hz (VESA) hsync: 48.1kHz */
{800, 600, 72 ,50000, 800,856,976,1040,0, 600,637,643,666,0, V_PHSYNC | V_PVSYNC},
/* 800x600 @ 75Hz (VESA) hsync: 46.9kHz */
{800, 600, 75 ,49500, 800,816,896,1056,0, 600,601,604,625,0, V_PHSYNC | V_PVSYNC},
/* 800x600 @ 85Hz (VESA) hsync: 53.7kHz */
{800, 600, 85 ,56300, 800,832,896,1048,0, 600,601,604,631,0, V_PHSYNC | V_PVSYNC},
/* 1024x768i @ 43Hz (industry standard) hsync: 35.5kHz */
{1024, 768, 43 ,44900, 1024,1032,1208,1264,0, 768,768,776,817,0, V_PHSYNC | V_PVSYNC | V_INTERLACE},
/* 1024x768 @ 60Hz (VESA) hsync: 48.4kHz */
{1024, 768, 60 ,65000, 1024,1048,1184,1344,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC},
/* 1024x768 @ 70Hz (VESA) hsync: 56.5kHz */
{1024, 768, 70 ,75000, 1024,1048,1184,1328,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC},
/* 1024x768 @ 75Hz (VESA) hsync: 60.0kHz */
{1024, 768, 75 ,78800, 1024,1040,1136,1312,0, 768,769,772,800,0, V_PHSYNC | V_PVSYNC},
/* 1024x768 @ 85Hz (VESA) hsync: 68.7kHz */
{1024, 768, 85 ,94500, 1024,1072,1168,1376,0, 768,769,772,808,0, V_PHSYNC | V_PVSYNC},
/* 1152x864 @ 75Hz (VESA) hsync: 67.5kHz */
{1152, 864, 75 ,108000, 1152,1216,1344,1600,0, 864,865,868,900,0, V_PHSYNC | V_PVSYNC},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};

929
hw/kdrive/pcmcia/pcmcia.c Normal file
View File

@ -0,0 +1,929 @@
/*
* Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Alan Hourihane not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Alan Hourihane makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
*
* A driver for the following PCMCIA cards...
* Hewlett Packards HP VGA Out (Model F1252A)
* Colorgraphics Voyager VGA
*
* Tested running under a Compaq IPAQ Pocket PC running Linux
*/
/* $XFree86$ */
#include "pcmcia.h"
#define extern
#include <asm/io.h>
#undef extern
#define CLOCK 14318 /* KHz */
#define CLK_N(a,b) (a & 0xff)
#define CLK_M(a,b) ((b) & 0x3f)
#define CLK_K(a,b) (((b) >> 6) & 3)
#define CLK_FREQ(a,b) (((CLK_N(a,b) + 8) * CLOCK) / ((CLK_M(a,b)+2) << CLK_K(a,b)))
#include "modes.h"
extern void
tridentUpdatePacked (ScreenPtr pScreen,
PixmapPtr pShadow,
RegionPtr damage);
extern void
cirrusUpdatePacked (ScreenPtr pScreen,
PixmapPtr pShadow,
RegionPtr damage);
Bool
pcmciaCardInit (KdCardInfo *card)
{
pcmciaCardInfo *pcmciac;
CARD8 r9;
pcmciac = (pcmciaCardInfo *) xalloc (sizeof (pcmciaCardInfo));
if (!pcmciac)
return FALSE;
pcmciac->cop_base = (CARD8 *) KdMapDevice (PCMCIA_COP_BASE(card),
PCMCIA_COP_SIZE(card));
r9 = pcmciaReadIndex (pcmciac, 0x3c4, 0x09);
/*
* Crude detection....
* The trident chip has a read only register at 0x09, which returns 0x4.
* If it's not that, we assume the cirrus chip.
* BREAKAGE.! If we have an anonymous PCMCIA card inserted, we could
* potentially smash something here. FIXME !
*/
if (r9 == 0x04) {
ErrorF("PCMCIA: Found HP VGA card\n");
pcmciac->HP = TRUE; /* Select HP VGA Out Card */
} else {
ErrorF("PCMCIA: Found Voyager VGA card\n");
pcmciac->HP = FALSE; /* Select Voyager VGA Card */
}
if (pcmciac->HP) {
/* needed by the accelerator - later */
pcmciac->cop = (Cop *) (pcmciac->cop_base + TRIDENT_COP_OFF(card));
}
/*
* Map frame buffer
*/
if (pcmciac->HP)
pcmciac->fb = KdMapDevice (0x2ce00000, 0x80000);
else
pcmciac->fb = KdMapDevice (0x2c0a0000, 0x10000); /*64K bank switched*/
if (!pcmciac->fb)
return FALSE;
pcmciac->window = 0;
card->driver = pcmciac;
return TRUE;
}
Bool
pcmciaScreenInit (KdScreenInfo *screen)
{
pcmciaCardInfo *pcmciac = screen->card->driver;
pcmciaScreenInfo *pcmcias;
int screen_size, memory;
int i;
pcmcias = (pcmciaScreenInfo *) xalloc (sizeof (pcmciaScreenInfo));
if (!pcmcias)
return FALSE;
memset (pcmcias, '\0', sizeof (pcmciaScreenInfo));
/* if (!pcmciac->cop) */
screen->dumb = TRUE;
/* default to 8bpp */
if (!screen->fb[0].depth)
screen->fb[0].depth = 8;
/* default to 60Hz refresh */
if (!screen->rate)
screen->rate = 60;
i = 0;
pcmcias->Mode = -1;
while (pcmciaDefaultModes[i].Width != 0) {
if ( (screen->width == pcmciaDefaultModes[i].Width) &&
(screen->height == pcmciaDefaultModes[i].Height) &&
(screen->rate == pcmciaDefaultModes[i].Refresh) ) {
pcmcias->Mode = i;
break;
}
i++;
}
if ( pcmcias->Mode == -1 ) {
ErrorF("PCMCIA: no matching vesa mode for screen selection, aborting.\n");
ErrorF("PCMCIA: use -listmodes to check for supported list of modes.\n");
return FALSE; /* end of list */
}
memory = 512 * 1024;
pcmcias->screen = pcmciac->fb;
if (pcmciac->HP && !screen->softCursor && screen->fb[0].depth == 8) {
/* Let's do hw cursor for the HP card, only in 8bit mode though */
pcmcias->cursor_base = pcmcias->screen + memory - 4096;
memory -= 4096;
}
if (screen->fb[0].depth == 4) {
ErrorF("PCMCIA: depth 4 isn't supported.\n");
return FALSE; /* screen->fb[0].bitsPerPixel = 4; need fb to support it*/
} else
if (screen->fb[0].depth == 8)
screen->fb[0].bitsPerPixel = 8;
else
if (screen->fb[0].depth == 15 ||
screen->fb[0].depth == 16)
screen->fb[0].bitsPerPixel = 16;
if ( (screen->width * screen->height *
(screen->fb[0].bitsPerPixel / 8)) > memory) {
ErrorF("PCMCIA: Not enough memory for resolution requested, aborting.\n");
return FALSE;
}
screen->fb[0].pixelStride = screen->width;
screen->fb[0].byteStride = screen->width * (screen->fb[0].bitsPerPixel >>3);
screen->fb[0].frameBuffer = pcmciac->fb;
switch (screen->fb[0].depth) {
case 4:
screen->fb[0].visuals = ((1 << StaticGray) |
(1 << GrayScale) |
(1 << StaticColor));
screen->fb[0].blueMask = 0x00;
screen->fb[0].greenMask = 0x00;
screen->fb[0].redMask = 0x00;
break;
case 8:
screen->fb[0].visuals = ((1 << StaticGray) |
(1 << GrayScale) |
(1 << StaticColor) |
(1 << PseudoColor) |
(1 << TrueColor) |
(1 << DirectColor));
screen->fb[0].blueMask = 0x00;
screen->fb[0].greenMask = 0x00;
screen->fb[0].redMask = 0x00;
break;
case 15:
screen->fb[0].visuals = (1 << TrueColor);
screen->fb[0].blueMask = 0x001f;
screen->fb[0].greenMask = 0x03e0;
screen->fb[0].redMask = 0x7c00;
break;
case 16:
screen->fb[0].visuals = (1 << TrueColor);
screen->fb[0].blueMask = 0x001f;
screen->fb[0].greenMask = 0x07e0;
screen->fb[0].redMask = 0xf800;
break;
}
screen_size = screen->fb[0].byteStride * screen->height;
screen->driver = pcmcias;
return KdShadowScreenInit(screen);
}
void *
tridentWindowLinear (ScreenPtr pScreen,
CARD32 row,
CARD32 offset,
int mode,
CARD32 *size)
{
KdScreenPriv(pScreen);
pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
if (!pScreenPriv->enabled)
return 0;
*size = pScreenPriv->screen->fb[0].byteStride;
return (CARD8 *) pcmciac->fb + row * pScreenPriv->screen->fb[0].byteStride + offset;
}
void *
cirrusWindowWindowed (ScreenPtr pScreen,
CARD32 row,
CARD32 offset,
int mode,
CARD32 *size)
{
KdScreenPriv(pScreen);
pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
int bank, boffset;
if (!pScreenPriv->enabled)
return 0;
bank = (row * pScreenPriv->screen->fb[0].byteStride) / 0x1000;
pcmciaWriteIndex(pcmciac, 0x3ce, 0x0B, 8);
pcmciaWriteIndex(pcmciac, 0x3ce, 0x09, bank);
pcmciaWriteIndex(pcmciac, 0x3ce, 0x0A, bank);
*size = pScreenPriv->screen->fb[0].byteStride;
return (CARD8 *) pcmciac->fb + (row * pScreenPriv->screen->fb[0].byteStride) - (bank * 0x1000) + offset;
}
Bool
pcmciaInitScreen (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
ShadowUpdateProc update;
ShadowWindowProc window;
if (pcmciac->HP) {
update = tridentUpdatePacked;
window = tridentWindowLinear;
} else {
update = cirrusUpdatePacked;
window = cirrusWindowWindowed;
}
return KdShadowInitScreen (pScreen, update, window);
}
CARD8
pcmciaReadIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index)
{
CARD8 value;
pcmciac->cop_base[port] = index;
value = pcmciac->cop_base[port+1];
return value;
}
void
pcmciaWriteIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index, CARD8 value)
{
pcmciac->cop_base[port] = index;
pcmciac->cop_base[port+1] = value;
}
CARD8
pcmciaReadReg (pcmciaCardInfo *pcmciac, CARD16 port)
{
CARD8 value;
value = pcmciac->cop_base[port];
return value;
}
void
pcmciaWriteReg (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 value)
{
pcmciac->cop_base[port] = value;
}
void
pcmciaPause ()
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 50 * 1000;
select (1, 0, 0, 0, &tv);
}
void
pcmciaPreserve (KdCardInfo *card)
{
}
/* CLOCK_FACTOR is double the osc freq in kHz (osc = 14.31818 MHz) */
#define CLOCK_FACTOR 28636
/* stability constraints for internal VCO -- MAX_VCO also determines the maximum Video pixel clock */
#define MIN_VCO CLOCK_FACTOR
#define MAX_VCO 111000
/* clock in kHz is (numer * CLOCK_FACTOR / (denom & 0x3E)) >> (denom & 1) */
#define VCOVAL(n, d) \
((((n) & 0x7F) * CLOCK_FACTOR / ((d) & 0x3E)) )
#define CLOCKVAL(n, d) \
(VCOVAL(n, d) >> ((d) & 1))
int CirrusFindClock(freq, max_clock, num_out, den_out)
int freq;
int max_clock;
int *num_out;
int *den_out;
{
int n;
int num = 0, den = 0;
int mindiff;
/*
* If max_clock is greater than the MAX_VCO default, ignore
* MAX_VCO. On the other hand, if MAX_VCO is higher than max_clock,
* make use of the higher MAX_VCO value.
*/
if (MAX_VCO > max_clock)
max_clock = MAX_VCO;
mindiff = freq;
for (n = 0x10; n < 0x7f; n++) {
int d;
for (d = 0x14; d < 0x3f; d++) {
int c, diff;
/* Avoid combinations that can be unstable. */
if ((VCOVAL(n, d) < MIN_VCO) || (VCOVAL(n, d) > max_clock))
continue;
c = CLOCKVAL(n, d);
diff = abs(c - freq);
if (diff < mindiff) {
mindiff = diff;
num = n;
den = d;
}
}
}
*num_out = num;
*den_out = den;
return 0;
}
void
tridentSetCLK(int clock, CARD8 *a, CARD8 *b)
{
int powerup[4] = { 1,2,4,8 };
int clock_diff = 750;
int freq, ffreq;
int m, n, k;
int p, q, r, s;
int startn, endn;
int endm, endk;
p = q = r = s = 0;
startn = 0;
endn = 121;
endm = 31;
endk = 1;
freq = clock;
for (k=0;k<=endk;k++)
for (n=startn;n<=endn;n++)
for (m=1;m<=endm;m++)
{
ffreq = ( ( ((n + 8) * CLOCK) / ((m + 2) * powerup[k]) ));
if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff))
{
clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
p = n; q = m; r = k; s = ffreq;
}
}
#if 0
ErrorF ("ffreq %d clock %d\n", s, clock);
#endif
if (s == 0)
{
FatalError("Unable to set programmable clock.\n"
"Frequency %d is not a valid clock.\n"
"Please modify XF86Config for a new clock.\n",
freq);
}
/* N is first 7bits, first M bit is 8th bit */
*a = ((1 & q) << 7) | p;
/* first 4bits are rest of M, 1bit for K value */
*b = (((q & 0xFE) >> 1) | (r << 4));
}
Bool
pcmciaEnable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
int i,j;
unsigned char Sequencer[6];
unsigned char CRTC[31];
unsigned char Graphics[9];
unsigned char Attribute[21];
unsigned char MiscOutReg;
pcmciaDisplayModeRec mode = pcmciaDefaultModes[pcmcias->Mode];
/*
* compute correct Hsync & Vsync polarity
*/
if ((mode.Flags & (V_PHSYNC | V_NHSYNC))
&& (mode.Flags & (V_PVSYNC | V_NVSYNC)))
{
MiscOutReg = 0x23;
if (mode.Flags & V_NHSYNC) MiscOutReg |= 0x40;
if (mode.Flags & V_NVSYNC) MiscOutReg |= 0x80;
}
else
{
int VDisplay = mode.VDisplay;
if (VDisplay < 400)
MiscOutReg = 0xA3; /* +hsync -vsync */
else if (VDisplay < 480)
MiscOutReg = 0x63; /* -hsync +vsync */
else if (VDisplay < 768)
MiscOutReg = 0xE3; /* -hsync -vsync */
else
MiscOutReg = 0x23; /* +hsync +vsync */
}
/*
* Time Sequencer
*/
if (pScreenPriv->screen->fb[0].depth == 4)
Sequencer[0] = 0x02;
else
Sequencer[0] = 0x00;
Sequencer[1] = 0x01;
Sequencer[2] = 0x0F;
Sequencer[3] = 0x00; /* Font select */
if (pScreenPriv->screen->fb[0].depth < 8)
Sequencer[4] = 0x06; /* Misc */
else
Sequencer[4] = 0x0E; /* Misc */
Sequencer[5] = 0x00;
/*
* CRTC Controller
*/
CRTC[0] = (mode.HTotal >> 3) - 5;
CRTC[1] = (mode.HDisplay >> 3) - 1;
CRTC[2] = ((min(mode.HSyncStart,mode.HDisplay)) >> 3) - 1;
CRTC[3] = ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x1F) | 0x80;
i = (((mode.HSkew << 2) + 0x10) & ~0x1F);
if (i < 0x80)
CRTC[3] |= i;
CRTC[4] = (mode.HSyncStart >> 3);
CRTC[5] = (((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x20) << 2)
| (((mode.HSyncEnd >> 3)) & 0x1F);
CRTC[6] = (mode.VTotal - 2) & 0xFF;
CRTC[7] = (((mode.VTotal - 2) & 0x100) >> 8)
| (((mode.VDisplay - 1) & 0x100) >> 7)
| ((mode.VSyncStart & 0x100) >> 6)
| ((((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0x100) >> 5)
| 0x10
| (((mode.VTotal - 2) & 0x200) >> 4)
| (((mode.VDisplay - 1) & 0x200) >> 3)
| ((mode.VSyncStart & 0x200) >> 2);
CRTC[8] = 0x00;
CRTC[9] = ((((min(mode.VSyncStart,mode.VDisplay))-1) & 0x200) >> 4) | 0x40;
CRTC[10] = 0x00;
CRTC[11] = 0x00;
CRTC[12] = 0x00;
CRTC[13] = 0x00;
CRTC[14] = 0x00;
CRTC[15] = 0x00;
CRTC[16] = mode.VSyncStart & 0xFF;
CRTC[17] = (mode.VSyncEnd & 0x0F) | 0x20;
CRTC[18] = (mode.VDisplay - 1) & 0xFF;
if (pScreenPriv->screen->fb[0].depth == 4)
CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 4;
else
if (pScreenPriv->screen->fb[0].depth == 8)
CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 3;
else
if (pScreenPriv->screen->fb[0].depth == 16 ||
pScreenPriv->screen->fb[0].depth == 15)
CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 2;
CRTC[20] = 0x00;
CRTC[21] = ((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0xFF;
CRTC[22] = ((min(mode.VSyncEnd,mode.VDisplay)) - 1) & 0xFF;
if (pScreenPriv->screen->fb[0].depth < 8)
CRTC[23] = 0xE3;
else
CRTC[23] = 0xC3;
CRTC[24] = 0xFF;
CRTC[25] = 0x00;
CRTC[26] = 0x00;
if (!pcmciac->HP)
if (mode.Flags & V_INTERLACE) CRTC[26] |= 0x01;
if (pcmciac->HP)
CRTC[27] = 0x00;
else
CRTC[27] = 0x22;
CRTC[28] = 0x00;
CRTC[29] = 0x00;
CRTC[30] = 0x80;
if (pcmciac->HP)
if (mode.Flags & V_INTERLACE) CRTC[30] |= 0x04;
{
int nExtBits = 0;
CARD32 ExtBits;
CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6;
CRTC[3] = (CRTC[3] & ~0x1F)
| ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x1F);
CRTC[5] = (CRTC[5] & ~0x80)
| (((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x20) << 2);
ExtBits = (((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & ExtBitMask;
/* First the horizontal case */
if ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) == (mode.HTotal >> 3)))
{
int i = (CRTC[3] & 0x1F)
| ((CRTC[5] & 0x80) >> 2)
| ExtBits;
if ((i-- > ((((min(mode.HSyncStart,mode.HDisplay)) >> 3) - 1)
& (0x3F | ExtBitMask)))
&& ((min(mode.HSyncEnd,mode.HTotal)) == mode.HTotal))
i = 0;
CRTC[3] = (CRTC[3] & ~0x1F) | (i & 0x1F);
CRTC[5] = (CRTC[5] & ~0x80) | ((i << 2) & 0x80);
ExtBits = i & ExtBitMask;
}
}
{
CARD32 ExtBits;
CARD32 ExtBitMask = 0;
/* If width is not known nBits should be 0. In this
* case BitMask is set to 0 so we can check for it. */
CARD32 BitMask = 0;
int VBlankStart = ((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0xFF;
CRTC[22] = ((min(mode.VSyncEnd,mode.VTotal)) - 1) & 0xFF;
ExtBits = ((min(mode.VSyncEnd,mode.VTotal)) - 1) & ExtBitMask;
if ((min(mode.VSyncEnd,mode.VTotal)) == mode.VTotal)
/* Null top overscan */
{
int i = CRTC[22] | ExtBits;
if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask)))
|| ((i > VBlankStart) && /* 8-bit case */
((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */
!(CRTC[9] & 0x9F)) /* 1 scanline/row */
i = 0;
else
i = (i - 1);
CRTC[22] = i & 0xFF;
ExtBits = i & 0xFF00;
}
}
/*
* Graphics Display Controller
*/
Graphics[0] = 0x00;
Graphics[1] = 0x00;
Graphics[2] = 0x00;
Graphics[3] = 0x00;
Graphics[4] = 0x00;
if (pScreenPriv->screen->fb[0].depth == 4)
Graphics[5] = 0x02;
else
Graphics[5] = 0x40;
Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
Graphics[7] = 0x0F;
Graphics[8] = 0xFF;
Attribute[0] = 0x00; /* standard colormap translation */
Attribute[1] = 0x01;
Attribute[2] = 0x02;
Attribute[3] = 0x03;
Attribute[4] = 0x04;
Attribute[5] = 0x05;
Attribute[6] = 0x06;
Attribute[7] = 0x07;
Attribute[8] = 0x08;
Attribute[9] = 0x09;
Attribute[10] = 0x0A;
Attribute[11] = 0x0B;
Attribute[12] = 0x0C;
Attribute[13] = 0x0D;
Attribute[14] = 0x0E;
Attribute[15] = 0x0F;
if (pScreenPriv->screen->fb[0].depth == 4)
Attribute[16] = 0x81;
else
Attribute[16] = 0x41;
if (pScreenPriv->screen->fb[0].bitsPerPixel == 16)
Attribute[17] = 0x00;
else
Attribute[17] = 0xFF;
Attribute[18] = 0x0F;
Attribute[19] = 0x00;
Attribute[20] = 0x00;
/* Wake up the card */
if (pcmciac->HP) {
pcmciaWriteReg(pcmciac, 0x3c3, 0x1);
pcmciaWriteReg(pcmciac, 0x46e8, 0x10);
} else {
pcmciaWriteReg(pcmciac, 0x105, 0x1);
pcmciaWriteReg(pcmciac, 0x46e8, 0x1f);
pcmciaWriteReg(pcmciac, 0x102, 0x1);
pcmciaWriteReg(pcmciac, 0x46e8, 0xf);
pcmciaWriteReg(pcmciac, 0x3c3, 0x1);
}
if (pcmciac->HP) {
/* unlock */
pcmciaWriteIndex(pcmciac, 0x3c4, 0x11, 0x92);
j = pcmciaReadIndex(pcmciac, 0x3c4, 0xb);
pcmciaWriteIndex(pcmciac, 0x3c4, 0xe, 0xc2);
/* switch on dac */
pcmciaWriteIndex(pcmciac, 0x3d4, 0x29, 0x24);
/* switch on the accelerator */
pcmciaWriteIndex(pcmciac, 0x3d4, 0x36, 0x80);
/* bump up memory clk */
pcmciaWriteReg(pcmciac, 0x43c6, 0x65);
pcmciaWriteReg(pcmciac, 0x43c7, 0x00);
} else {
/* unlock */
pcmciaWriteIndex(pcmciac, 0x3c4, 0x06, 0x12);
pcmciaWriteReg(pcmciac, 0x3c2, MiscOutReg);
}
/* synchronous reset */
pcmciaWriteIndex(pcmciac, 0x3c4, 0, 0);
pcmciaWriteReg(pcmciac, 0x3da, 0x10);
for (i=0;i<6;i++)
pcmciaWriteIndex(pcmciac, 0x3c4, i, Sequencer[i]);
if (pcmciac->HP) {
/* Stick chip into color mode */
pcmciaWriteIndex(pcmciac, 0x3ce, 0x2f, 0x06);
/* Switch on Linear addressing */
pcmciaWriteIndex(pcmciac, 0x3d4, 0x21, 0x2e);
} else {
/* Stick chip into 8bit access mode - ugh! */
pcmciaWriteIndex(pcmciac, 0x3c4, 0x0F, 0x20); /* 0x26 ? */
/* reset mclk */
pcmciaWriteIndex(pcmciac, 0x3c4, 0x1F, 0);
}
pcmciaWriteIndex(pcmciac, 0x3c4, 0, 0x3);
for (i=0;i<31;i++)
pcmciaWriteIndex(pcmciac, 0x3d4, i, CRTC[i]);
for (i=0;i<9;i++)
pcmciaWriteIndex(pcmciac, 0x3ce, i, Graphics[i]);
j = pcmciaReadReg(pcmciac, 0x3da);
for (i=0;i<21;i++) {
pcmciaWriteReg(pcmciac, 0x3c0, i);
pcmciaWriteReg(pcmciac, 0x3c0, Attribute[i]);
}
j = pcmciaReadReg(pcmciac, 0x3da);
pcmciaWriteReg(pcmciac, 0x3c0, 0x20);
j = pcmciaReadReg(pcmciac, 0x3c8);
j = pcmciaReadReg(pcmciac, 0x3c6);
j = pcmciaReadReg(pcmciac, 0x3c6);
j = pcmciaReadReg(pcmciac, 0x3c6);
j = pcmciaReadReg(pcmciac, 0x3c6);
switch (pScreenPriv->screen->fb[0].depth) {
/* This is here for completeness, when/if we ever do 4bpp */
case 4:
pcmciaWriteReg(pcmciac, 0x3c6, 0x0);
if (pcmciac->HP) {
pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x90);
pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x00);
} else
pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x00);
break;
case 8:
pcmciaWriteReg(pcmciac, 0x3c6, 0x0);
if (pcmciac->HP) {
pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x92);
pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x00);
} else
pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x01);
break;
case 15:
if (pcmciac->HP) {
pcmciaWriteReg(pcmciac, 0x3c6, 0x10);
pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x9a);
pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x04);
} else {
pcmciaWriteReg(pcmciac, 0x3c6, 0xC0);
pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x03);
}
break;
case 16:
if (pcmciac->HP) {
pcmciaWriteReg(pcmciac, 0x3c6, 0x30);
pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x9a);
pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x04);
} else {
pcmciaWriteReg(pcmciac, 0x3c6, 0xC1);
pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x03);
}
break;
}
j = pcmciaReadReg(pcmciac, 0x3c8);
pcmciaWriteReg(pcmciac, 0x3c6, 0xff);
for (i=0;i<256;i++) {
pcmciaWriteReg(pcmciac, 0x3c8, i);
pcmciaWriteReg(pcmciac, 0x3c9, i);
pcmciaWriteReg(pcmciac, 0x3c9, i);
pcmciaWriteReg(pcmciac, 0x3c9, i);
}
/* Set the Clock */
if (pcmciac->HP) {
CARD8 a,b;
int clock = mode.Clock;
if (pScreenPriv->screen->fb[0].bitsPerPixel == 16)
clock *= 2;
tridentSetCLK(clock, &a, &b);
pcmciaWriteReg(pcmciac, 0x43c8, a);
pcmciaWriteReg(pcmciac, 0x43c9, b);
} else {
int num, den;
unsigned char tmp;
int clock = mode.Clock;
if (pScreenPriv->screen->fb[0].bitsPerPixel == 16)
clock *= 2;
CirrusFindClock(clock, MAX_VCO, &num, &den);
tmp = pcmciaReadIndex(pcmciac, 0x3c4, 0x0d);
pcmciaWriteIndex(pcmciac, 0x3c4, 0x0d, (tmp & 0x80) | num);
tmp = pcmciaReadIndex(pcmciac, 0x3c4, 0x1d);
pcmciaWriteIndex(pcmciac, 0x3c4, 0x1d, (tmp & 0xc0) | den);
}
pcmciaWriteReg(pcmciac, 0x3c2, MiscOutReg | 0x08);
#if 0 /* for debugging */
for (i=1;i<0x3f;i++)
ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3c4, i));
ErrorF("\n");
for (i=0;i<0x3f;i++)
ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3ce, i));
ErrorF("\n");
for (i=0;i<0x3f;i++)
ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3d4, i));
#endif
return TRUE;
}
void
pcmciaDisable (ScreenPtr pScreen)
{
}
const CARD8 tridentDPMSModes[4] = {
0x00, /* KD_DPMS_NORMAL */
0x01, /* KD_DPMS_STANDBY */
0x02, /* KD_DPMS_SUSPEND */
0x03, /* KD_DPMS_POWERDOWN */
};
Bool
pcmciaDPMS (ScreenPtr pScreen, int mode)
{
KdScreenPriv(pScreen);
pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
if (pcmciac->HP) {
pcmciaWriteIndex (pcmciac, 0x3ce, 0x23, tridentDPMSModes[mode]);
pcmciaPause ();
} else {
/* Voyager */
}
return TRUE;
}
void
pcmciaRestore (KdCardInfo *card)
{
}
void
pcmciaScreenFini (KdScreenInfo *screen)
{
pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) screen->driver;
xfree (pcmcias);
screen->driver = 0;
}
void
pcmciaCardFini (KdCardInfo *card)
{
pcmciaCardInfo *pcmciac = card->driver;
if (pcmciac->cop_base)
KdUnmapDevice ((void *) pcmciac->cop_base, PCMCIA_COP_SIZE(card));
}
void
pcmciaGetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
while (ndef--)
{
pcmciaWriteReg (pcmciac, 0x3C7, pdefs->pixel);
pdefs->red = pcmciaReadReg (pcmciac, 0x3C9) << 10;
pdefs->green = pcmciaReadReg (pcmciac, 0x3C9) << 10;
pdefs->blue = pcmciaReadReg (pcmciac, 0x3C9) << 10;
pdefs++;
}
}
void
pcmciaPutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
while (ndef--)
{
pcmciaWriteReg (pcmciac, 0x3C8, pdefs->pixel);
pcmciaWriteReg (pcmciac, 0x3C9, pdefs->red >> 10);
pcmciaWriteReg (pcmciac, 0x3C9, pdefs->green >> 10);
pcmciaWriteReg (pcmciac, 0x3C9, pdefs->blue >> 10);
pdefs++;
}
}
KdCardFuncs pcmciaFuncs = {
pcmciaCardInit, /* cardinit */
pcmciaScreenInit, /* scrinit */
pcmciaInitScreen, /* initScreen */
pcmciaPreserve, /* preserve */
pcmciaEnable, /* enable */
pcmciaDPMS, /* dpms */
pcmciaDisable, /* disable */
pcmciaRestore, /* restore */
pcmciaScreenFini, /* scrfini */
pcmciaCardFini, /* cardfini */
pcmciaCursorInit, /* initCursor */
pcmciaCursorEnable, /* enableCursor */
pcmciaCursorDisable, /* disableCursor */
pcmciaCursorFini, /* finiCursor */
pcmciaRecolorCursor, /* recolorCursor */
#if 0 /* not yet */
pcmciaDrawInit, /* initAccel */
pcmciaDrawEnable, /* enableAccel */
pcmciaDrawSync, /* syncAccel */
pcmciaDrawDisable, /* disableAccel */
pcmciaDrawFini, /* finiAccel */
#else
0,
0,
0,
0,
0,
#endif
pcmciaGetColors, /* getColors */
pcmciaPutColors, /* putColors */
};

262
hw/kdrive/pcmcia/pcmcia.h Normal file
View File

@ -0,0 +1,262 @@
/*
* Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Alan Hourihane not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Alan Hourihane makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
*/
/* $XFree86$ */
#ifndef _PCMCIA_H_
#define _PCMCIA_H_
#include <fbdev.h>
/*
* offset from ioport beginning
*/
#define PCMCIA_COP_BASE(c) 0x20000000
#define PCMCIA_COP_SIZE(c) 0x10000
#define TRIDENT_COP_OFF(c) 0x2100
typedef volatile CARD8 VOL8;
typedef volatile CARD16 VOL16;
typedef volatile CARD32 VOL32;
typedef struct _cop {
VOL32 src_start_xy; /* 0x00 */
VOL32 src_end_xy; /* 0x04 */
VOL32 dst_start_xy; /* 0x08 */
VOL32 dst_end_xy; /* 0x0c */
VOL32 alpha; /* 0x10 */
CARD8 pad14[0xc]; /* 0x14 */
VOL32 multi; /* 0x20 */
#define COP_MULTI_CLIP_TOP_LEFT 0x10000000
#define COP_MULTI_DEPTH 0x40000000
#define COP_MULTI_COLOR_KEY 0x70000000
#define COP_MULTI_STYLE 0x50000000
#define COP_MULTI_PATTERN 0x80000000
#define COP_MULTI_ROP 0x90000000
#define COP_MULTI_STRIDE 0x60000000
#define COP_MULTI_Z 0xa0000000
#define COP_MULTI_ALPHA 0xb0000000
#define COP_MULTI_TEXTURE 0xd0000000
#define COP_MULTI_TEXTURE_BOUND 0xe0000000
#define COP_MULTI_TEXTURE_ADVANCED 0x20000000
#define COP_MULTI_MASK 0xf0000000
#define COP_DEPTH_8 0x00000000
#define COP_DEPTH_16 0x00000001
#define COP_DEPTH_24_32 0x00000002
#define COP_DEPTH_15 0x00000005
#define COP_DEPTH_DITHER_DISABLE 0x00000008
#define COP_ALPHA_SRC_BLEND_0 0x00000000
#define COP_ALPHA_SRC_BLEND_1 0x00000001
#define COP_ALPHA_SRC_BLEND_SRC_C 0x00000002
#define COP_ALPHA_SRC_BLEND_1_SRC_C 0x00000003
#define COP_ALPHA_SRC_BLEND_SRC_A 0x00000004
#define COP_ALPHA_SRC_BLEND_1_SRC_A 0x00000005
#define COP_ALPHA_SRC_BLEND_DST_A 0x00000006
#define COP_ALPHA_SRC_BLEND_1_DST_A 0x00000007
#define COP_ALPHA_SRC_BLEND_DST_C 0x00000008
#define COP_ALPHA_SRC_BLEND_1_DST_C 0x00000009
#define COP_ALPHA_SRC_BLEND_SAT 0x0000000A
#define COP_ALPHA_SRC_BLEND_BG 0x0000000B
#define COP_ALPHA_DST_BLEND_0 0x00000000
#define COP_ALPHA_DST_BLEND_1 0x00000010
#define COP_ALPHA_DST_BLEND_SRC_C 0x00000020
#define COP_ALPHA_DST_BLEND_1_SRC_C 0x00000030
#define COP_ALPHA_DST_BLEND_SRC_A 0x00000040
#define COP_ALPHA_DST_BLEND_1_SRC_A 0x00000050
#define COP_ALPHA_DST_BLEND_DST_A 0x00000060
#define COP_ALPHA_DST_BLEND_1_DST_A 0x00000070
#define COP_ALPHA_DST_BLEND_DST_C 0x00000080
#define COP_ALPHA_DST_BLEND_1_DST_C 0x00000090
#define COP_ALPHA_DST_BLEND_OTHER 0x000000A0
#define COP_ALPHA_RESULT_ALPHA 0x00100000
#define COP_ALPHA_DEST_ALPHA 0x00200000
#define COP_ALPHA_SOURCE_ALPHA 0x00400000
#define COP_ALPHA_WRITE_ENABLE 0x00800000
#define COP_ALPHA_TEST_ENABLE 0x01000000
#define COP_ALPHA_BLEND_ENABLE 0x02000000
#define COP_ALPHA_DEST_VALUE 0x04000000
#define COP_ALPHA_SOURCE_VALUE 0x08000000
VOL32 command; /* 0x24 */
#define COP_OP_NULL 0x00000000
#define COP_OP_LINE 0x20000000
#define COP_OP_BLT 0x80000000
#define COP_OP_TEXT 0x90000000
#define COP_OP_POLY 0xb0000000
#define COP_OP_POLY2 0xe0000000
#define COP_SCL_EXPAND 0x00800000
#define COP_SCL_OPAQUE 0x00400000
#define COP_SCL_REVERSE 0x00200000
#define COP_SCL_MONO_OFF 0x001c0000
#define COP_LIT_TEXTURE 0x00004000
#define COP_BILINEAR 0x00002000
#define COP_OP_ZBUF 0x00000800
#define COP_OP_ROP 0x00000400
#define COP_OP_FG 0x00000200
#define COP_OP_FB 0x00000080
#define COP_X_REVERSE 0x00000004
#define COP_CLIP 0x00000001
VOL32 texture_format; /* 0x28 */
CARD8 pad2c[0x4]; /* 0x2c */
VOL32 clip_bottom_right; /* 0x30 */
VOL32 dataIII; /* 0x34 */
VOL32 dataIV; /* 0x38 */
CARD8 pad3c[0x8]; /* 0x3c */
VOL32 fg; /* 0x44 */
VOL32 bg; /* 0x48 */
CARD8 pad4c[0x4]; /* 0x4c */
VOL32 pattern_fg; /* 0x50 */
VOL32 pattern_bg; /* 0x54 */
CARD8 pad58[0xc]; /* 0x58 */
VOL32 status; /* 0x64 */
#define COP_STATUS_BE_BUSY 0x80000000
#define COP_STATUS_DPE_BUSY 0x20000000
#define COP_STATUS_MI_BUSY 0x10000000
#define COP_STATUS_FIFO_BUSY 0x08000000
#define COP_STATUS_WB_BUSY 0x00800000
#define COP_STATUS_Z_FAILED 0x00400000
#define COP_STATUS_EFFECTIVE 0x00200000
#define COP_STATUS_LEFT_VIEW 0x00080000
CARD8 pad68[0x4]; /* 0x68 */
VOL32 src_offset; /* 0x6c */
VOL32 z_offset; /* 0x70 */
CARD8 pad74[0x4]; /* 0x74 */
VOL32 display_offset; /* 0x78 */
VOL32 dst_offset; /* 0x7c */
CARD8 pad80[0x34]; /* 0x80 */
VOL32 semaphore; /* 0xb4 */
} Cop;
#define TRI_XY(x,y) ((y) << 16 | (x))
typedef struct _pcmciaCardInfo {
CARD8 *fb;
Bool HP;
CARD8 *cop_base;
Cop *cop;
CARD32 *window;
CARD32 cop_depth;
CARD32 cop_stride;
} pcmciaCardInfo;
#define getpcmciaCardInfo(kd) ((pcmciaCardInfo *) ((kd)->card->driver))
#define pcmciaCardInfo(kd) pcmciaCardInfo *pcmciac = getpcmciaCardInfo(kd)
typedef struct _pcmciaCursor {
int width, height;
int xhot, yhot;
Bool has_cursor;
CursorPtr pCursor;
Pixel source, mask;
} pcmciaCursor;
#define PCMCIA_CURSOR_WIDTH 64
#define PCMCIA_CURSOR_HEIGHT 64
typedef struct _pcmciaScreenInfo {
int Mode;
CARD8 *cursor_base;
CARD8 *screen;
CARD8 *off_screen;
int off_screen_size;
pcmciaCursor cursor;
} pcmciaScreenInfo;
#define getpcmciaScreenInfo(kd) ((pcmciaScreenInfo *) ((kd)->screen->driver))
#define pcmciaScreenInfo(kd) pcmciaScreenInfo *pcmcias = getpcmciaScreenInfo(kd)
Bool
pcmciaDrawInit (ScreenPtr pScreen);
void
pcmciaDrawEnable (ScreenPtr pScreen);
void
pcmciaDrawSync (ScreenPtr pScreen);
void
pcmciaDrawDisable (ScreenPtr pScreen);
void
pcmciaDrawFini (ScreenPtr pScreen);
CARD8
pcmciaReadIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index);
void
pcmciaWriteIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index, CARD8 value);
void
pcmciaWriteReg (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 value);
Bool
pcmciaCursorInit (ScreenPtr pScreen);
void
pcmciaCursorEnable (ScreenPtr pScreen);
void
pcmciaCursorDisable (ScreenPtr pScreen);
void
pcmciaCursorFini (ScreenPtr pScreen);
void
pcmciaRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef);
typedef struct _pcmciaDisplayModeRec {
int Width;
int Height;
int Refresh;
int Clock; /* pixel clock freq */
int HDisplay; /* horizontal timing */
int HSyncStart;
int HSyncEnd;
int HTotal;
int HSkew;
int VDisplay; /* vertical timing */
int VSyncStart;
int VSyncEnd;
int VTotal;
int VScan;
int Flags;
} pcmciaDisplayModeRec, *pcmciaDisplayModePtr;
extern KdCardFuncs pcmciaFuncs;
#endif /* _PCMCIA_H_ */

View File

@ -0,0 +1,449 @@
/*
* Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Alan Hourihane not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Alan Hourihane makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
*/
/* $XFree86$ */
#include "pcmcia.h"
#include "cursorstr.h"
#define SetupCursor(s) KdScreenPriv(s); \
pcmciaCardInfo(pScreenPriv); \
pcmciaScreenInfo(pScreenPriv); \
pcmciaCursor *pCurPriv = &pcmcias->cursor
static void
_pcmciaMoveCursor (ScreenPtr pScreen, int x, int y)
{
SetupCursor(pScreen);
CARD8 xlow, xhigh, ylow, yhigh;
CARD8 xoff, yoff;
x -= pCurPriv->xhot;
xoff = 0;
if (x < 0)
{
xoff = -x;
x = 0;
}
y -= pCurPriv->yhot;
yoff = 0;
if (y < 0)
{
yoff = -y;
y = 0;
}
/* This is the recommended order to move the cursor */
if (pcmciac->HP) {
xlow = (CARD8) x;
xhigh = (CARD8) (x >> 8);
ylow = (CARD8) y;
yhigh = (CARD8) (y >> 8);
pcmciaWriteIndex (pcmciac, 0x3d4, 0x40, xlow);
pcmciaWriteIndex (pcmciac, 0x3d4, 0x41, xhigh);
pcmciaWriteIndex (pcmciac, 0x3d4, 0x42, ylow);
pcmciaWriteIndex (pcmciac, 0x3d4, 0x43, yhigh);
pcmciaWriteIndex (pcmciac, 0x3d4, 0x46, xoff);
pcmciaWriteIndex (pcmciac, 0x3d4, 0x47, yoff);
} else {
x >>= 3;
y >>= 3;
xlow = (CARD8) x;
xhigh = (CARD8) (x >> 8);
ylow = (CARD8) y;
yhigh = (CARD8) (y >> 8);
/* Don't be alarmed, yes the upper 3bits of the index are correct */
pcmciaWriteIndex (pcmciac, 0x3c4, 0x10 | xhigh << 5, xlow);
pcmciaWriteIndex (pcmciac, 0x3c4, 0x11 | yhigh << 5, ylow);
}
}
static void
pcmciaMoveCursor (ScreenPtr pScreen, int x, int y)
{
SetupCursor (pScreen);
if (!pCurPriv->has_cursor)
return;
if (!pScreenPriv->enabled)
return;
_pcmciaMoveCursor (pScreen, x, y);
}
static void
pcmciaAllocCursorColors (ScreenPtr pScreen)
{
SetupCursor (pScreen);
CursorPtr pCursor = pCurPriv->pCursor;
KdAllocateCursorPixels (pScreen, 0, pCursor,
&pCurPriv->source, &pCurPriv->mask);
switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
case 4:
pCurPriv->source |= pCurPriv->source << 4;
pCurPriv->mask |= pCurPriv->mask << 4;
case 8:
pCurPriv->source |= pCurPriv->source << 8;
pCurPriv->mask |= pCurPriv->mask << 8;
case 16:
pCurPriv->source |= pCurPriv->source << 16;
pCurPriv->mask |= pCurPriv->mask << 16;
}
}
static void
pcmciaSetCursorColors (ScreenPtr pScreen)
{
SetupCursor (pScreen);
CursorPtr pCursor = pCurPriv->pCursor;
CARD32 fg, bg;
fg = pCurPriv->source;
bg = pCurPriv->mask;
if (pcmciac->HP) {
/*
* This trident chip uses the palette for it's cursor colors - ouch!
* We enforce it to always stay the black/white colors as we don't
* want it to muck with the overscan color. Tough. Use softCursor
* if you want to change cursor colors.
*/
pcmciaWriteReg (pcmciac, 0x3c8, 0xff); /* DAC 0 */
pcmciaWriteReg (pcmciac, 0x3c9, 0x00);
pcmciaWriteReg (pcmciac, 0x3c9, 0x00);
pcmciaWriteReg (pcmciac, 0x3c9, 0x00);
pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 255 */
pcmciaWriteReg (pcmciac, 0x3c9, 0x3f);
pcmciaWriteReg (pcmciac, 0x3c9, 0x3f);
pcmciaWriteReg (pcmciac, 0x3c9, 0x3f);
} else {
CARD8 temp;
temp = pcmciaReadIndex(pcmciac, 0x3c4, 0x12);
pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, (temp & 0xFE) | 0x02);
pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 256 */
pcmciaWriteReg (pcmciac, 0x3c9, fg);
pcmciaWriteReg (pcmciac, 0x3c9, fg >> 8);
pcmciaWriteReg (pcmciac, 0x3c9, fg >> 16);
pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 257 */
pcmciaWriteReg (pcmciac, 0x3c9, bg);
pcmciaWriteReg (pcmciac, 0x3c9, bg >> 8);
pcmciaWriteReg (pcmciac, 0x3c9, bg >> 16);
pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, temp);
}
}
void
pcmciaRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef)
{
SetupCursor (pScreen);
CursorPtr pCursor = pCurPriv->pCursor;
xColorItem sourceColor, maskColor;
if (!pCurPriv->has_cursor || !pCursor)
return;
if (!pScreenPriv->enabled)
return;
if (pdef)
{
while (ndef)
{
if (pdef->pixel == pCurPriv->source ||
pdef->pixel == pCurPriv->mask)
break;
ndef--;
}
if (!ndef)
return;
}
pcmciaAllocCursorColors (pScreen);
pcmciaSetCursorColors (pScreen);
}
#define InvertBits32(v) { \
v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
}
static void
pcmciaLoadCursor (ScreenPtr pScreen, int x, int y)
{
SetupCursor(pScreen);
CursorPtr pCursor = pCurPriv->pCursor;
CursorBitsPtr bits = pCursor->bits;
int w, h;
CARD8 *ram;
CARD32 *msk, *mskLine, *src, *srcLine;
int i, j;
int cursor_address;
int lwsrc;
unsigned char ramdac_control_;
CARD32 offset;
/*
* Allocate new colors
*/
pcmciaAllocCursorColors (pScreen);
pCurPriv->pCursor = pCursor;
pCurPriv->xhot = pCursor->bits->xhot;
pCurPriv->yhot = pCursor->bits->yhot;
/*
* Stick new image into cursor memory
*/
if (pcmciac->HP) {
ram = (CARD8 *) pcmcias->cursor_base;
} else {
/* The last bank */
ram = (CARD8 *) pcmciac->fb;
pcmciaWriteIndex (pcmciac, 0x3ce, 0x09, 0x7f);
pcmciaWriteIndex (pcmciac, 0x3ce, 0x0A, 0x7f);
}
mskLine = (CARD32 *) bits->mask;
srcLine = (CARD32 *) bits->source;
h = bits->height;
if (h > PCMCIA_CURSOR_HEIGHT)
h = PCMCIA_CURSOR_HEIGHT;
lwsrc = BitmapBytePad(bits->width) / 4;
for (i = 0; i < PCMCIA_CURSOR_HEIGHT; i++) {
msk = mskLine;
src = srcLine;
mskLine += lwsrc;
srcLine += lwsrc;
for (j = 0; j < PCMCIA_CURSOR_WIDTH / 32; j++) {
CARD32 m, s;
if (i < h && j < lwsrc)
{
m = *msk++;
s = *src++;
InvertBits32(m);
InvertBits32(s);
}
else
{
m = 0;
s = 0;
}
/* Do 8bit access */
*ram++ = (m & 0xff);
*ram++ = (m & 0xff00) >> 8;
*ram++ = (m & 0xff0000) >> 16;
*ram++ = (m & 0xff000000) >> 24;
*ram++ = (s & 0xff);
*ram++ = (s & 0xff00) >> 8;
*ram++ = (s & 0xff0000) >> 16;
*ram++ = (s & 0xff000000) >> 24;
}
}
/* Set address for cursor bits */
if (pcmciac->HP) {
offset = pcmcias->cursor_base - (CARD8 *) pcmcias->screen;
offset >>= 10;
pcmciaWriteIndex (pcmciac, 0x3d4, 0x44, (CARD8) (offset & 0xff));
pcmciaWriteIndex (pcmciac, 0x3d4, 0x45, (CARD8) (offset >> 8));
} else {
pcmciaWriteIndex (pcmciac, 0x3c4, 0x13, 15); /* ?? */
}
/* Set new color */
pcmciaSetCursorColors (pScreen);
/* Enable the cursor */
if (pcmciac->HP)
pcmciaWriteIndex (pcmciac, 0x3d4, 0x50, 0xc1);
else
pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, 0x05);
/* Move to new position */
pcmciaMoveCursor (pScreen, x, y);
}
static void
pcmciaUnloadCursor (ScreenPtr pScreen)
{
SetupCursor (pScreen);
/* Disable cursor */
if (pcmciac->HP)
pcmciaWriteIndex (pcmciac, 0x3d4, 0x50, 0);
else
pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, 0);
}
static Bool
pcmciaRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
{
SetupCursor(pScreen);
if (!pScreenPriv->enabled)
return TRUE;
/* miRecolorCursor does this */
if (pCurPriv->pCursor == pCursor)
{
if (pCursor)
{
int x, y;
miPointerPosition (&x, &y);
pcmciaLoadCursor (pScreen, x, y);
}
}
return TRUE;
}
static Bool
pcmciaUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
{
return TRUE;
}
static void
pcmciaSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
{
SetupCursor(pScreen);
pCurPriv->pCursor = pCursor;
if (!pScreenPriv->enabled)
return;
if (pCursor)
pcmciaLoadCursor (pScreen, x, y);
else
pcmciaUnloadCursor (pScreen);
}
miPointerSpriteFuncRec pcmciaPointerSpriteFuncs = {
pcmciaRealizeCursor,
pcmciaUnrealizeCursor,
pcmciaSetCursor,
pcmciaMoveCursor,
};
static void
pcmciaQueryBestSize (int class,
unsigned short *pwidth, unsigned short *pheight,
ScreenPtr pScreen)
{
SetupCursor (pScreen);
switch (class)
{
case CursorShape:
if (*pwidth > pCurPriv->width)
*pwidth = pCurPriv->width;
if (*pheight > pCurPriv->height)
*pheight = pCurPriv->height;
if (*pwidth > pScreen->width)
*pwidth = pScreen->width;
if (*pheight > pScreen->height)
*pheight = pScreen->height;
break;
default:
fbQueryBestSize (class, pwidth, pheight, pScreen);
break;
}
}
Bool
pcmciaCursorInit (ScreenPtr pScreen)
{
SetupCursor (pScreen);
if (!pcmcias->cursor_base)
{
pCurPriv->has_cursor = FALSE;
return FALSE;
}
pCurPriv->width = PCMCIA_CURSOR_WIDTH;
pCurPriv->height= PCMCIA_CURSOR_HEIGHT;
pScreen->QueryBestSize = pcmciaQueryBestSize;
miPointerInitialize (pScreen,
&pcmciaPointerSpriteFuncs,
&kdPointerScreenFuncs,
FALSE);
pCurPriv->has_cursor = TRUE;
pCurPriv->pCursor = NULL;
return TRUE;
}
void
pcmciaCursorEnable (ScreenPtr pScreen)
{
SetupCursor (pScreen);
if (pCurPriv->has_cursor)
{
if (pCurPriv->pCursor)
{
int x, y;
miPointerPosition (&x, &y);
pcmciaLoadCursor (pScreen, x, y);
}
else
pcmciaUnloadCursor (pScreen);
}
}
void
pcmciaCursorDisable (ScreenPtr pScreen)
{
SetupCursor (pScreen);
if (!pScreenPriv->enabled)
return;
if (pCurPriv->has_cursor)
{
if (pCurPriv->pCursor)
{
pcmciaUnloadCursor (pScreen);
}
}
}
void
pcmciaCursorFini (ScreenPtr pScreen)
{
SetupCursor (pScreen);
pCurPriv->pCursor = NULL;
}

View File

@ -0,0 +1,191 @@
/*
* Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Alan Hourihane not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Alan Hourihane makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
*/
/* $XFree86$ */
#include "X.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "font.h"
#include "dixfontstr.h"
#include "fontstruct.h"
#include "mi.h"
#include "regionstr.h"
#include "globals.h"
#include "gcstruct.h"
#include "shadow.h"
#include "fb.h"
void
tridentUpdatePacked (ScreenPtr pScreen,
PixmapPtr pShadow,
RegionPtr damage)
{
shadowScrPriv(pScreen);
int nbox = REGION_NUM_RECTS (damage);
BoxPtr pbox = REGION_RECTS (damage);
FbBits *shaBase, *shaLine, *sha;
FbStride shaStride;
int scrBase, scrLine, scr;
int shaBpp;
int x, y, w, h, width;
int i;
FbBits *winBase, *win;
CARD32 winSize;
fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp);
while (nbox--)
{
x = pbox->x1 * shaBpp;
y = pbox->y1;
w = (pbox->x2 - pbox->x1) * shaBpp;
h = pbox->y2 - pbox->y1;
scrLine = (x >> FB_SHIFT);
shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
x &= FB_MASK;
w = (w + x + FB_MASK) >> FB_SHIFT;
while (h--)
{
winSize = 0;
scrBase = 0;
width = w;
scr = scrLine;
sha = shaLine;
while (width) {
/* how much remains in this window */
i = scrBase + winSize - scr;
if (i <= 0 || scr < scrBase)
{
winBase = (FbBits *) (*pScrPriv->window) (pScreen,
y,
scr * sizeof (FbBits),
SHADOW_WINDOW_WRITE,
&winSize);
if(!winBase)
return;
scrBase = scr;
winSize /= sizeof (FbBits);
i = winSize;
}
win = winBase + (scr - scrBase);
if (i > width)
i = width;
width -= i;
scr += i;
{
CARD16 *sha16 = (CARD16*)sha;
CARD16 *win16 = (CARD16*)win;
while (i--)
{
*win16++ = *sha16++;
*win16++ = *sha16++;
}
}
}
shaLine += shaStride;
y++;
}
pbox++;
}
}
void
cirrusUpdatePacked (ScreenPtr pScreen,
PixmapPtr pShadow,
RegionPtr damage)
{
shadowScrPriv(pScreen);
int nbox = REGION_NUM_RECTS (damage);
BoxPtr pbox = REGION_RECTS (damage);
FbBits *shaBase, *shaLine, *sha;
FbStride shaStride;
int scrBase, scrLine, scr;
int shaBpp;
int x, y, w, h, width;
int i;
FbBits *winBase, *win;
CARD32 winSize;
fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp);
while (nbox--)
{
x = pbox->x1 * shaBpp;
y = pbox->y1;
w = (pbox->x2 - pbox->x1) * shaBpp;
h = pbox->y2 - pbox->y1;
scrLine = (x >> FB_SHIFT);
shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
x &= FB_MASK;
w = (w + x + FB_MASK) >> FB_SHIFT;
while (h--)
{
winSize = 0;
scrBase = 0;
width = w;
scr = scrLine;
sha = shaLine;
while (width) {
/* how much remains in this window */
i = scrBase + winSize - scr;
if (i <= 0 || scr < scrBase)
{
winBase = (FbBits *) (*pScrPriv->window) (pScreen,
y,
scr * sizeof (FbBits),
SHADOW_WINDOW_WRITE,
&winSize);
if(!winBase)
return;
scrBase = scr;
winSize /= sizeof (FbBits);
i = winSize;
}
win = winBase + (scr - scrBase);
if (i > width)
i = width;
width -= i;
scr += i;
{
CARD8 *sha8 = (CARD8*)sha;
CARD8 *win8 = (CARD8*)win;
while (i--)
{
*win8++ = *sha8++;
*win8++ = *sha8++;
*win8++ = *sha8++;
*win8++ = *sha8++;
}
}
}
shaLine += shaStride;
y++;
}
pbox++;
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Alan Hourihane not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Alan Hourihane makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
*/
/* $XFree86$ */
#include "pcmcia.h"
void
InitCard (char *name)
{
KdCardAttr attr;
KdCardInfoAdd (&pcmciaFuncs, &attr, 0);
}
void
InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
{
KdInitOutput (pScreenInfo, argc, argv);
}
void
InitInput (int argc, char **argv)
{
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
}
extern pcmciaDisplayModeRec pcmciaDefaultModes[];
int
ddxProcessArgument (int argc, char **argv, int i)
{
return KdProcessArgument (argc, argv, i);
}

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.12 2001/01/23 06:25:05 keithp Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.13 2001/03/30 02:15:20 keithp Exp $ */
#include "kdrive.h"
#include "inputstr.h"
@ -992,7 +992,7 @@ extern int nClients;
void
KdCheckSpecialKeys(xEvent *xE)
{
KeySym sym;
KeySym sym = KEYCOL1(xE->u.u.detail);
if (!pKdKeyboard) return;
@ -1001,7 +1001,25 @@ KdCheckSpecialKeys(xEvent *xE)
*/
if (xE->u.u.type == KeyRelease) return;
#ifdef XIPAQ
/*
* Check for buttons 1, 2 and 3 on the iPAQ
*/
if (sym == XK_Pointer_Button1) {
KdEnqueueMouseEvent(KD_MOUSE_DELTA | KD_BUTTON_1, 0, 0);
return;
}
if (sym == XK_Pointer_Button2) {
KdEnqueueMouseEvent(KD_MOUSE_DELTA | KD_BUTTON_2, 0, 0);
return;
}
if (sym == XK_Pointer_Button3) {
KdEnqueueMouseEvent(KD_MOUSE_DELTA | KD_BUTTON_3, 0, 0);
return;
}
#endif
/*
* Check for control/alt pressed
*/
@ -1009,7 +1027,6 @@ KdCheckSpecialKeys(xEvent *xE)
(ControlMask|Mod1Mask))
return;
sym = KEYCOL1(xE->u.u.detail);
/*
* Let OS function see keysym first
@ -1428,16 +1445,22 @@ KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
static void
KdCrossScreen(ScreenPtr pScreen, Bool entering)
{
#ifndef XIPAQ
if (entering)
KdEnableScreen (pScreen);
else
KdDisableScreen (pScreen);
#endif
}
/* HACK! */
extern int TsScreen;
static void
KdWarpCursor (ScreenPtr pScreen, int x, int y)
{
KdBlockSigio ();
TsScreen = pScreen->myNum;
miPointerWarpCursor (pScreen, x, y);
KdUnblockSigio ();
}

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/kmap.c,v 1.6 2000/12/13 18:06:54 keithp Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/kmap.c,v 1.7 2001/03/30 02:15:20 keithp Exp $ */
#include "kdrive.h"
@ -67,7 +67,11 @@ KdMapDevice (CARD32 addr, CARD32 size)
void *a;
int fd;
#ifdef __arm__
fd = open ("/dev/mem", O_RDWR|O_SYNC);
#else
fd = open ("/dev/mem", O_RDWR);
#endif
if (fd < 0)
FatalError ("KdMapDevice: failed to open /dev/mem (%s)\n",
strerror (errno));