1/* 2 * Copyright 2000-2001 by Alan Hourihane, Sychdyn, North Wales, UK. 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: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29#include "xf86.h" 30#include "xf86_OSproc.h" 31#include "xf86Pci.h" 32#include "glint.h" 33#ifdef HAVE_XAA_H 34#include "xaalocal.h" 35#endif 36#include "glint_regs.h" 37#include "dgaproc.h" 38 39static Bool GLINT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 40 int *, int *, int *); 41static Bool GLINT_SetMode(ScrnInfoPtr, DGAModePtr); 42static void GLINT_Sync(ScrnInfoPtr); 43static int GLINT_GetViewport(ScrnInfoPtr); 44static void GLINT_SetViewport(ScrnInfoPtr, int, int, int); 45#ifdef HAVE_XAA_H 46static void GLINT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 47static void GLINT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 48#endif 49 50static 51DGAFunctionRec GLINTDGAFuncs = { 52 GLINT_OpenFramebuffer, 53 NULL, 54 GLINT_SetMode, 55 GLINT_SetViewport, 56 GLINT_GetViewport, 57 GLINT_Sync, 58#ifdef HAVE_XAA_H 59 GLINT_FillRect, 60 GLINT_BlitRect, 61#else 62 NULL, NULL, 63#endif 64 NULL 65}; 66 67Bool 68GLINTDGAInit(ScreenPtr pScreen) 69{ 70 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 71 GLINTPtr pGlint = GLINTPTR(pScrn); 72 DGAModePtr modes = NULL, newmodes = NULL, currentMode; 73 DisplayModePtr pMode, firstMode; 74 int Bpp = pScrn->bitsPerPixel >> 3; 75 int num = 0; 76 Bool oneMore; 77 78 pMode = firstMode = pScrn->modes; 79 80 while(pMode) { 81 82 if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { 83 newmodes = realloc(modes, (num + 2) * sizeof(DGAModeRec)); 84 oneMore = TRUE; 85 } else { 86 newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec)); 87 oneMore = FALSE; 88 } 89 90 if(!newmodes) { 91 free(modes); 92 return FALSE; 93 } 94 modes = newmodes; 95 96SECOND_PASS: 97 98 currentMode = modes + num; 99 num++; 100 101 currentMode->mode = pMode; 102 currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 103#ifdef HAVE_XAA_H 104 if(!pGlint->NoAccel) 105 currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 106#endif 107 if(pMode->Flags & V_DBLSCAN) 108 currentMode->flags |= DGA_DOUBLESCAN; 109 if(pMode->Flags & V_INTERLACE) 110 currentMode->flags |= DGA_INTERLACED; 111 currentMode->byteOrder = pScrn->imageByteOrder; 112 currentMode->depth = pScrn->depth; 113 currentMode->bitsPerPixel = pScrn->bitsPerPixel; 114 currentMode->red_mask = pScrn->mask.red; 115 currentMode->green_mask = pScrn->mask.green; 116 currentMode->blue_mask = pScrn->mask.blue; 117 currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 118 currentMode->viewportWidth = pMode->HDisplay; 119 currentMode->viewportHeight = pMode->VDisplay; 120 currentMode->xViewportStep = 1; 121 currentMode->yViewportStep = 1; 122 currentMode->viewportFlags = DGA_FLIP_RETRACE; 123 currentMode->offset = 0; 124 currentMode->address = pGlint->FbBase; 125 126 if(oneMore) { /* first one is narrow width */ 127 currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; 128 currentMode->imageWidth = pMode->HDisplay; 129 currentMode->imageHeight = pMode->VDisplay; 130 currentMode->pixmapWidth = currentMode->imageWidth; 131 currentMode->pixmapHeight = currentMode->imageHeight; 132 currentMode->maxViewportX = currentMode->imageWidth - 133 currentMode->viewportWidth; 134 /* this might need to get clamped to some maximum */ 135 currentMode->maxViewportY = currentMode->imageHeight - 136 currentMode->viewportHeight; 137 oneMore = FALSE; 138 goto SECOND_PASS; 139 } else { 140 currentMode->bytesPerScanline = 141 ((pScrn->displayWidth * Bpp) + 3) & ~3L; 142 currentMode->imageWidth = pScrn->displayWidth; 143 currentMode->imageHeight = pMode->VDisplay; 144 currentMode->pixmapWidth = currentMode->imageWidth; 145 currentMode->pixmapHeight = currentMode->imageHeight; 146 currentMode->maxViewportX = currentMode->imageWidth - 147 currentMode->viewportWidth; 148 /* this might need to get clamped to some maximum */ 149 currentMode->maxViewportY = currentMode->imageHeight - 150 currentMode->viewportHeight; 151 } 152 153 pMode = pMode->next; 154 if(pMode == firstMode) 155 break; 156 } 157 158 pGlint->numDGAModes = num; 159 pGlint->DGAModes = modes; 160 161 return DGAInit(pScreen, &GLINTDGAFuncs, modes, num); 162} 163 164 165static Bool 166GLINT_SetMode( 167 ScrnInfoPtr pScrn, 168 DGAModePtr pMode 169){ 170 static int OldDisplayWidth[MAXSCREENS]; 171 int index = pScrn->pScreen->myNum; 172 GLINTPtr pGlint = GLINTPTR(pScrn); 173 174 if(!pMode) { /* restore the original mode */ 175 /* put the ScreenParameters back */ 176 177 pScrn->displayWidth = OldDisplayWidth[index]; 178 179 GLINTSwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 180 pGlint->DGAactive = FALSE; 181 } else { 182 if(!pGlint->DGAactive) { /* save the old parameters */ 183 OldDisplayWidth[index] = pScrn->displayWidth; 184 185 pGlint->DGAactive = TRUE; 186 } 187 188 pScrn->displayWidth = pMode->bytesPerScanline / 189 (pMode->bitsPerPixel >> 3); 190 191 GLINTSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 192 } 193 194 return TRUE; 195} 196 197static int 198GLINT_GetViewport( 199 ScrnInfoPtr pScrn 200){ 201 GLINTPtr pGlint = GLINTPTR(pScrn); 202 203 return pGlint->DGAViewportStatus; 204} 205 206static void 207GLINT_SetViewport( 208 ScrnInfoPtr pScrn, 209 int x, int y, 210 int flags 211){ 212 GLINTPtr pGlint = GLINTPTR(pScrn); 213 214 GLINTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 215 pGlint->DGAViewportStatus = 0; /* GLINTAdjustFrame loops until finished */ 216} 217 218#ifdef HAVE_XAA_H 219static void 220GLINT_FillRect ( 221 ScrnInfoPtr pScrn, 222 int x, int y, int w, int h, 223 unsigned long color 224){ 225 GLINTPtr pGlint = GLINTPTR(pScrn); 226 227 if(pGlint->AccelInfoRec) { 228 (*pGlint->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 229 (*pGlint->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 230 SET_SYNC_FLAG(pGlint->AccelInfoRec); 231 } 232} 233#endif 234 235static void 236GLINT_Sync( 237 ScrnInfoPtr pScrn 238){ 239 GLINTPtr pGlint = GLINTPTR(pScrn); 240#ifdef HAVE_XAA_H 241 if(pGlint->AccelInfoRec) { 242 (*pGlint->AccelInfoRec->Sync)(pScrn); 243 } 244#endif 245} 246 247#ifdef HAVE_XAA_H 248static void 249GLINT_BlitRect( 250 ScrnInfoPtr pScrn, 251 int srcx, int srcy, 252 int w, int h, 253 int dstx, int dsty 254){ 255 GLINTPtr pGlint = GLINTPTR(pScrn); 256 257 if(pGlint->AccelInfoRec) { 258 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 259 int ydir = (srcy < dsty) ? -1 : 1; 260 261 (*pGlint->AccelInfoRec->SetupForScreenToScreenCopy)( 262 pScrn, xdir, ydir, GXcopy, ~0, -1); 263 (*pGlint->AccelInfoRec->SubsequentScreenToScreenCopy)( 264 pScrn, srcx, srcy, dstx, dsty, w, h); 265 SET_SYNC_FLAG(pGlint->AccelInfoRec); 266 } 267} 268#endif 269static Bool 270GLINT_OpenFramebuffer( 271 ScrnInfoPtr pScrn, 272 char **name, 273 unsigned char **mem, 274 int *size, 275 int *offset, 276 int *flags 277){ 278 GLINTPtr pGlint = GLINTPTR(pScrn); 279 280 *name = NULL; /* no special device */ 281 *mem = (unsigned char*)pGlint->FbAddress; 282 *size = pGlint->FbMapSize; 283 *offset = 0; 284 *flags = DGA_NEED_ROOT; 285 286 return TRUE; 287} 288