1/* 2 * Copyright 2000 by Rainer Keller, <Rainer.Keller@studmail.uni-stuttgart.de>. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Alan Hourihane not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Alan Hourihane makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Authors: Adapted from: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23 * by: Rainer Keller, <Rainer.Keller@studmail.uni-stuttgart.de> 24 */ 25 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include "tseng.h" 31#include "dgaproc.h" 32 33static Bool Tseng_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 34 int *, int *, int *); 35static Bool Tseng_SetMode(ScrnInfoPtr, DGAModePtr); 36static void Tseng_Sync(ScrnInfoPtr); 37static int Tseng_GetViewport(ScrnInfoPtr); 38static void Tseng_SetViewport(ScrnInfoPtr, int, int, int); 39#ifdef HAVE_XAA_H 40static void Tseng_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 41static void Tseng_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 42/* 43static void Tseng_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 44 unsigned long); 45*/ 46#endif 47 48static 49DGAFunctionRec TsengDGAFuncs = { 50 Tseng_OpenFramebuffer, 51 NULL, /* Tseng_CloseFramebuffer */ 52 Tseng_SetMode, 53 Tseng_SetViewport, 54 Tseng_GetViewport, 55 Tseng_Sync, 56#ifdef HAVE_XAA_H 57 Tseng_FillRect, 58 Tseng_BlitRect, 59 NULL /* Tseng_BlitTransRect */ 60#else 61 NULL, NULL, NULL 62#endif 63}; 64 65 66 67 68Bool 69TsengDGAInit(ScreenPtr pScreen) 70{ 71 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 72 TsengPtr pTseng = TsengPTR(pScrn); 73 DGAModePtr modes = NULL, newmodes = NULL, currentMode; 74 DisplayModePtr pMode, firstMode; 75 int Bpp = pScrn->bitsPerPixel >> 3; 76 int num = 0; 77 int imlines = (pScrn->videoRam * 1024) / 78 (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 79 80 if (!pTseng->DGAnumModes) { 81 pMode = firstMode = pScrn->modes; 82 while (pMode) { 83 newmodes = realloc(modes, (num + 1) * sizeof (DGAModeRec)); 84 if (!newmodes) { 85 free(modes); 86 return FALSE; 87 } 88 modes = newmodes; 89 currentMode = modes + num; 90 num++; 91 (void)memset(currentMode, 1, sizeof(DGAModeRec)); 92 currentMode->mode = pMode; 93 currentMode->flags = DGA_PIXMAP_AVAILABLE; 94#ifdef HAVE_XAA_H 95 currentMode->flags |= ((pTseng->UseAccel) ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0); 96#endif 97 if (pMode->Flags & V_DBLSCAN) 98 currentMode->flags |= DGA_DOUBLESCAN; 99 if(pMode->Flags & V_INTERLACE) 100 currentMode->flags |= DGA_INTERLACED; 101 currentMode->byteOrder = pScrn->imageByteOrder; 102 currentMode->depth = pScrn->depth; 103 currentMode->bitsPerPixel = pScrn->bitsPerPixel; 104 currentMode->red_mask = pScrn->mask.red; 105 currentMode->green_mask = pScrn->mask.green; 106 currentMode->blue_mask = pScrn->mask.blue; 107 currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 108 currentMode->viewportWidth = pMode->HDisplay; 109 currentMode->viewportHeight = pMode->VDisplay; 110 currentMode->xViewportStep = 1; /* The granularity of x and y pos. */ 111 currentMode->yViewportStep = 1; 112 currentMode->viewportFlags = 0 /*DGA_FLIP_RETRACE*/; 113 currentMode->offset = 0; 114 currentMode->address = pTseng->FbBase; 115 currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; 116 currentMode->pixmapWidth = currentMode->imageWidth = pScrn->displayWidth; 117 currentMode->pixmapHeight = currentMode->imageHeight = imlines; 118 currentMode->maxViewportX = currentMode->imageWidth - 119 currentMode->viewportWidth; 120 /* this might need to get clamped to some maximum */ 121 currentMode->maxViewportY = currentMode->imageHeight - 122 currentMode->viewportHeight; 123 124 pMode = pMode->next; 125 if(pMode == firstMode) 126 break; 127 } 128 pTseng->DGAnumModes = num; 129 pTseng->DGAModes = modes; 130 } 131 return DGAInit(pScreen, &TsengDGAFuncs, pTseng->DGAModes, pTseng->DGAnumModes); 132} 133 134static Bool 135Tseng_OpenFramebuffer( 136 ScrnInfoPtr pScrn, 137 char **name, 138 unsigned char **mem, 139 int *size, 140 int *offset, 141 int *flags 142){ 143 TsengPtr pTseng = TsengPTR(pScrn); 144 145 *name = NULL; /* no special device */ 146 *mem = (unsigned char*)(uintptr_t)pTseng->FbAddress; 147 *size = pTseng->FbMapSize; 148 *offset = 0; /* Always */ 149 *flags = 0; /* Root permissions OS-dependent */ 150 151 return TRUE; 152} 153 154 155static Bool 156Tseng_SetMode( 157 ScrnInfoPtr pScrn, 158 DGAModePtr pMode 159){ 160 TsengPtr pTseng = TsengPTR(pScrn); 161 static int OldDisplayWidth[MAXSCREENS]; 162 int index = pScrn->pScreen->myNum; 163 Bool ret; 164 165 if(!pMode) { /* restore the original mode */ 166 /* put the ScreenParameters back */ 167 pScrn->displayWidth = OldDisplayWidth[index]; 168 ret = TsengModeInit(xf86Screens[index], pScrn->currentMode); 169 pTseng->DGAactive = FALSE; 170 } else { 171 if(!pTseng->DGAactive) { /* save the old parameters */ 172 OldDisplayWidth[index] = pScrn->displayWidth; 173 174 pTseng->DGAactive = TRUE; 175 } 176 pScrn->displayWidth = pMode->bytesPerScanline / 177 (pMode->bitsPerPixel >> 3); 178 179 ret = TsengModeInit(xf86Screens[index], pMode->mode); 180 } 181 return ret; 182} 183 184static void 185Tseng_SetViewport( 186 ScrnInfoPtr pScrn, 187 int x, int y, 188 int flags 189){ 190 TsengPtr pTseng = TsengPTR(pScrn); 191 vgaHWPtr hwp = VGAHWPTR(pScrn); 192 193 TsengAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 194 while((hwp->readST01(hwp) & 0x08)); 195 while(!(hwp->readST01(hwp) & 0x08)); 196 197 pTseng->DGAViewportStatus = 0; /* TsengAdjustFrame loops until finished */ 198} 199 200static int 201Tseng_GetViewport( 202 ScrnInfoPtr pScrn 203){ 204 TsengPtr pTseng = TsengPTR(pScrn); 205 206 return pTseng->DGAViewportStatus; 207} 208 209 210 211static void 212Tseng_Sync( 213 ScrnInfoPtr pScrn 214){ 215 TsengPtr pTseng = TsengPTR(pScrn); 216#ifdef HAVE_XAA_H 217 if(pTseng->AccelInfoRec) { 218 (*pTseng->AccelInfoRec->Sync)(pScrn); 219 } 220#endif 221} 222 223#ifdef HAVE_XAA_H 224static void 225Tseng_FillRect ( 226 ScrnInfoPtr pScrn, 227 int x, int y, int w, int h, 228 unsigned long color 229){ 230 TsengPtr pTseng = TsengPTR(pScrn); 231 232 if(pTseng->AccelInfoRec) { 233 (*pTseng->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 234 (*pTseng->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 235 SET_SYNC_FLAG(pTseng->AccelInfoRec); 236 } 237} 238 239static void 240Tseng_BlitRect( 241 ScrnInfoPtr pScrn, 242 int srcx, int srcy, 243 int w, int h, 244 int dstx, int dsty 245){ 246 TsengPtr pTseng = TsengPTR(pScrn); 247 248 if(pTseng->AccelInfoRec) { 249 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 250 int ydir = (srcy < dsty) ? -1 : 1; 251 252 (*pTseng->AccelInfoRec->SetupForScreenToScreenCopy)( 253 pScrn, xdir, ydir, GXcopy, ~0, -1); 254 (*pTseng->AccelInfoRec->SubsequentScreenToScreenCopy)( 255 pScrn, srcx, srcy, dstx, dsty, w, h); 256 SET_SYNC_FLAG(pTseng->AccelInfoRec); 257 } 258} 259#endif 260