|
|
1.1 ! root 1: /*- ! 2: * sunCG2M.c -- ! 3: * Functions to support the sun CG2 board when treated as a monochrome ! 4: * frame buffer. ! 5: * ! 6: * Copyright (c) 1987 by the Regents of the University of California ! 7: * Copyright (c) 1987 by Adam de Boor, UC Berkeley ! 8: * ! 9: * Permission to use, copy, modify, and distribute this ! 10: * software and its documentation for any purpose and without ! 11: * fee is hereby granted, provided that the above copyright ! 12: * notice appear in all copies. The University of California ! 13: * makes no representations about the suitability of this ! 14: * software for any purpose. It is provided "as is" without ! 15: * express or implied warranty. ! 16: * ! 17: * ! 18: */ ! 19: #ifndef lint ! 20: static char rcsid[] = ! 21: "$Header: sunCG2M.c,v 4.4 87/09/11 17:04:55 sun Exp $ SPRITE (Berkeley)"; ! 22: #endif lint ! 23: ! 24: #include "sun.h" ! 25: #include "resource.h" ! 26: ! 27: #include <sys/mman.h> ! 28: #include <pixrect/memreg.h> ! 29: #include <pixrect/cg2reg.h> ! 30: #include <struct.h> ! 31: ! 32: extern caddr_t mmap(); ! 33: #ifndef _MAP_NEW ! 34: extern caddr_t valloc(); ! 35: #endif _MAP_NEW ! 36: ! 37: /*- ! 38: * The cg2 frame buffer is divided into several pieces. ! 39: * 1) a stack of 8 monochrome bitplanes ! 40: * 2) an array of 8-bit pixels ! 41: * 3) a union of these two where modifications are done via RasterOp ! 42: * chips ! 43: * 4) various control registers ! 44: * 5) a shadow colormap. ! 45: * ! 46: * Each of these things is at a given offset from the base of the 4Mb devoted ! 47: * to each color board. In addition, the mmap() system call insists on the ! 48: * address and the length to be mapped being aligned on 8K boundaries. ! 49: */ ! 50: struct cg2m_reg { ! 51: char pad[4096]; /* The status register is at 0x309000 */ ! 52: /* which isn't on an 8K boundary, so we */ ! 53: /* have to pad this thing here to make */ ! 54: /* the mmaping work... */ ! 55: union { ! 56: struct cg2statusreg csr; /* Control/status register */ ! 57: char pad[4096]; /* This is the amount of room */ ! 58: /* dedicated to the status register */ ! 59: } u_csr; ! 60: }; ! 61: ! 62: struct cg2m_ppmask { ! 63: union { ! 64: unsigned short ppmask; /* Per-plane mask */ ! 65: char pad[8192]; /* Padding to keep the length of */ ! 66: /* these registers page-aligned... */ ! 67: ! 68: } u_ppmask; ! 69: }; ! 70: ! 71: struct cg2m_cmap { ! 72: union { ! 73: struct { /* Shouldn't these be u_char's??? */ ! 74: u_short redmap[256]; /* Red-component map */ ! 75: u_short greenmap[256]; /* Green-component map */ ! 76: u_short bluemap[256]; /* Blue-component map */ ! 77: } cmap; ! 78: char pad[8192]; ! 79: } u_cmap; ! 80: }; ! 81: ! 82: typedef struct cg2m { ! 83: union bitplane *image; /* The first bitplane -- treated as a */ ! 84: /* monochrome frame buffer. */ ! 85: struct cg2m_reg *u_csr; /* the status register */ ! 86: struct cg2m_ppmask *u_ppmask; /* the plane mask register */ ! 87: struct cg2m_cmap *u_cmap; /* the colormap */ ! 88: } CG2M, CG2MRec, *CG2MPtr; ! 89: ! 90: #define CG2M_IMAGE(fb) ((caddr_t)((fb).image)) ! 91: #define CG2M_IMAGEOFF ((off_t)0x00000000) ! 92: #define CG2M_IMAGELEN (sizeof(union bitplane)) ! 93: #define CG2M_REG(fb) ((caddr_t)((fb).u_csr)) ! 94: #define CG2M_REGOFF ((off_t)0x00308000) ! 95: #define CG2M_REGLEN (2*8192) ! 96: #define CG2M_MASK(fb) ((caddr_t)((fb).u_ppmask)) ! 97: #define CG2M_MASKOFF ((off_t)0x0030A000) ! 98: #define CG2M_MASKLEN (0x2000) ! 99: #define CG2M_CMAP(fb) ((caddr_t)((fb).u_cmap)) ! 100: #define CG2M_CMAPOFF ((off_t)0x00310000) ! 101: #define CG2M_CMAPLEN 8192 ! 102: ! 103: /*- ! 104: *----------------------------------------------------------------------- ! 105: * sunCG2MSaveScreen -- ! 106: * Preserve the color screen by turning on or off the video ! 107: * ! 108: * Results: ! 109: * None. ! 110: * ! 111: * Side Effects: ! 112: * Video state is switched ! 113: * ! 114: *----------------------------------------------------------------------- ! 115: */ ! 116: static Bool ! 117: sunCG2MSaveScreen (pScreen, on) ! 118: ScreenPtr pScreen; ! 119: Bool on; ! 120: { ! 121: int state = on; ! 122: ! 123: switch (on) { ! 124: case SCREEN_SAVER_FORCER: ! 125: SetTimeSinceLastInputEvent(); ! 126: screenSaved = FALSE; ! 127: state = 1; ! 128: break; ! 129: case SCREEN_SAVER_OFF: ! 130: screenSaved = FALSE; ! 131: state = 1; ! 132: break; ! 133: case SCREEN_SAVER_ON: ! 134: default: ! 135: screenSaved = TRUE; ! 136: state = 0; ! 137: break; ! 138: } ! 139: ((CG2MPtr)sunFbs[pScreen->myNum].fb)->u_csr->u_csr.csr.video_enab = state; ! 140: return( TRUE ); ! 141: } ! 142: ! 143: /*- ! 144: *----------------------------------------------------------------------- ! 145: * sunCG2MCloseScreen -- ! 146: * called to ensure video is enabled when server exits. ! 147: * ! 148: * Results: ! 149: * Screen is unsaved. ! 150: * ! 151: * Side Effects: ! 152: * None ! 153: * ! 154: *----------------------------------------------------------------------- ! 155: */ ! 156: /*ARGSUSED*/ ! 157: static Bool ! 158: sunCG2MCloseScreen(i, pScreen) ! 159: int i; ! 160: ScreenPtr pScreen; ! 161: { ! 162: return (pScreen->SaveScreen(pScreen, SCREEN_SAVER_OFF)); ! 163: } ! 164: ! 165: /*- ! 166: *----------------------------------------------------------------------- ! 167: * sunCG2MResolveColor -- ! 168: * Resolve an RGB value into some sort of thing we can handle. ! 169: * Just looks to see if the intensity of the color is greater than ! 170: * 1/2 and sets it to 'white' (all ones) if so and 'black' (all zeroes) ! 171: * if not. ! 172: * ! 173: * Results: ! 174: * *pred, *pgreen and *pblue are overwritten with the resolved color. ! 175: * ! 176: * Side Effects: ! 177: * see above. ! 178: * ! 179: *----------------------------------------------------------------------- ! 180: */ ! 181: /*ARGSUSED*/ ! 182: static void ! 183: sunCG2MResolveColor(pred, pgreen, pblue, pVisual) ! 184: unsigned short *pred; ! 185: unsigned short *pgreen; ! 186: unsigned short *pblue; ! 187: VisualPtr pVisual; ! 188: { ! 189: *pred = *pgreen = *pblue = ! 190: (((39L * *pred + ! 191: 50L * *pgreen + ! 192: 11L * *pblue) >> 8) >= (((1<<8)-1)*50)) ? ~0 : 0; ! 193: } ! 194: ! 195: /*- ! 196: *----------------------------------------------------------------------- ! 197: * sunCG2CreateColormap -- ! 198: * create a bw colormap ! 199: * ! 200: * Results: ! 201: * None ! 202: * ! 203: * Side Effects: ! 204: * allocate two pixels ! 205: * ! 206: *----------------------------------------------------------------------- ! 207: */ ! 208: void ! 209: sunCG2CreateColormap(pmap) ! 210: ColormapPtr pmap; ! 211: { ! 212: int red, green, blue, pix; ! 213: ! 214: /* this is a monochrome colormap, it only has two entries, just fill ! 215: * them in by hand. If it were a more complex static map, it would be ! 216: * worth writing a for loop or three to initialize it */ ! 217: ! 218: /* this will be pixel 0 */ ! 219: red = green = blue = ~0; ! 220: AllocColor(pmap, &red, &green, &blue, &pix, 0); ! 221: ! 222: /* this will be pixel 1 */ ! 223: red = green = blue = 0; ! 224: AllocColor(pmap, &red, &green, &blue, &pix, 0); ! 225: ! 226: } ! 227: ! 228: /*- ! 229: *----------------------------------------------------------------------- ! 230: * sunCG2DestroyColormap -- ! 231: * destroy a bw colormap ! 232: * ! 233: * Results: ! 234: * None ! 235: * ! 236: * Side Effects: ! 237: * None ! 238: * ! 239: *----------------------------------------------------------------------- ! 240: */ ! 241: /*ARGSUSED*/ ! 242: void ! 243: sunCG2DestroyColormap(pmap) ! 244: ColormapPtr pmap; ! 245: { ! 246: } ! 247: ! 248: ! 249: /*- ! 250: *----------------------------------------------------------------------- ! 251: * sunCG2MInit -- ! 252: * Attempt to find and initialize a cg2 framebuffer used as mono ! 253: * ! 254: * Results: ! 255: * TRUE if everything went ok. FALSE if not. ! 256: * ! 257: * Side Effects: ! 258: * Most of the elements of the ScreenRec are filled in. The ! 259: * video is enabled for the frame buffer... ! 260: * ! 261: *----------------------------------------------------------------------- ! 262: */ ! 263: /*ARGSUSED*/ ! 264: static Bool ! 265: sunCG2MInit (index, pScreen, argc, argv) ! 266: int index; /* The index of pScreen in the ScreenInfo */ ! 267: ScreenPtr pScreen; /* The Screen to initialize */ ! 268: int argc; /* The number of the Server's arguments. */ ! 269: char **argv; /* The arguments themselves. Don't change! */ ! 270: { ! 271: ColormapPtr pCmap; ! 272: ! 273: if (!mfbScreenInit (index, pScreen, ! 274: ((CG2MPtr)sunFbs[index].fb)->image, ! 275: sunFbs[index].info.fb_width, ! 276: sunFbs[index].info.fb_height, 90, 90)) ! 277: return (FALSE); ! 278: ! 279: pScreen->SaveScreen = sunCG2MSaveScreen; ! 280: pScreen->RealizeCursor = sunRealizeCursor; ! 281: pScreen->UnrealizeCursor = sunUnrealizeCursor; ! 282: pScreen->DisplayCursor = sunDisplayCursor; ! 283: pScreen->SetCursorPosition = sunSetCursorPosition; ! 284: pScreen->CursorLimits = sunCursorLimits; ! 285: pScreen->PointerNonInterestBox = sunPointerNonInterestBox; ! 286: pScreen->ConstrainCursor = sunConstrainCursor; ! 287: pScreen->RecolorCursor = sunRecolorCursor; ! 288: pScreen->ResolveColor = sunCG2MResolveColor; ! 289: pScreen->CreateColormap = sunCG2CreateColormap; ! 290: pScreen->DestroyColormap = sunCG2DestroyColormap; ! 291: pScreen->RegionCreate = miRegionCreate; ! 292: pScreen->RegionCopy = miRegionCopy; ! 293: pScreen->RegionDestroy = miRegionDestroy; ! 294: pScreen->Intersect = miIntersect; ! 295: pScreen->Inverse = miInverse; ! 296: pScreen->Union = miUnion; ! 297: pScreen->Subtract = miSubtract; ! 298: pScreen->RegionReset = miRegionReset; ! 299: pScreen->TranslateRegion = miTranslateRegion; ! 300: pScreen->RectIn = miRectIn; ! 301: pScreen->PointInRegion = miPointInRegion; ! 302: ! 303: pScreen->whitePixel = 0; ! 304: pScreen->blackPixel = 1; ! 305: ! 306: if (CreateColormap(pScreen->defColormap, pScreen, ! 307: LookupID(pScreen->rootVisual, RT_VISUALID, RC_CORE), ! 308: &pCmap, AllocNone, 0) != Success ! 309: || pCmap == NULL) ! 310: FatalError("Can't create colormap in sunCG2MInit()\n"); ! 311: mfbInstallColormap(pCmap); ! 312: ! 313: /* ! 314: * Enable video output... ! 315: */ ! 316: sunCG2MSaveScreen(pScreen, SCREEN_SAVER_FORCER); ! 317: ! 318: sunScreenInit (pScreen); ! 319: return (TRUE); ! 320: } ! 321: ! 322: /*- ! 323: *----------------------------------------------------------------------- ! 324: * sunCG2MProbe -- ! 325: * Attempt to find and initialize a cg2 framebuffer used as mono ! 326: * ! 327: * Results: ! 328: * TRUE if everything went ok. FALSE if not. ! 329: * ! 330: * Side Effects: ! 331: * Memory is allocated for the frame buffer and the buffer is mapped. ! 332: * ! 333: *----------------------------------------------------------------------- ! 334: */ ! 335: Bool ! 336: sunCG2MProbe (pScreenInfo, index, fbNum, argc, argv) ! 337: ScreenInfo *pScreenInfo; /* The screenInfo struct */ ! 338: int index; /* The index of pScreen in the ScreenInfo */ ! 339: int fbNum; /* Index into the sunFbData array */ ! 340: int argc; /* The number of the Server's arguments. */ ! 341: char **argv; /* The arguments themselves. Don't change! */ ! 342: { ! 343: int i; ! 344: int oldNumScreens; ! 345: ! 346: if (sunFbData[fbNum].probeStatus == probedAndFailed) { ! 347: return FALSE; ! 348: } ! 349: ! 350: if (sunFbData[fbNum].probeStatus == neverProbed) { ! 351: int fd; ! 352: struct fbtype fbType; ! 353: static CG2MRec CG2Mfb; ! 354: ! 355: if ((fd = sunOpenFrameBuffer(FBTYPE_SUN2COLOR, &fbType, index, fbNum, ! 356: argc, argv)) < 0) { ! 357: sunFbData[fbNum].probeStatus = probedAndFailed; ! 358: return FALSE; ! 359: } ! 360: ! 361: #ifdef _MAP_NEW ! 362: if ((int)(CG2Mfb.image = (union bitplane *) mmap ((caddr_t) 0, ! 363: CG2M_IMAGELEN, PROT_READ | PROT_WRITE, ! 364: MAP_SHARED | _MAP_NEW, fd, CG2M_IMAGEOFF)) == -1) { ! 365: Error ("Mapping cg2m.image"); ! 366: goto bad; ! 367: } ! 368: if ((int)(CG2Mfb.u_csr = (struct cg2m_reg *) mmap ((caddr_t) 0, ! 369: CG2M_REGLEN, PROT_READ | PROT_WRITE, ! 370: MAP_SHARED | _MAP_NEW, fd, CG2M_REGOFF)) == -1) { ! 371: Error ("Mapping cg2m.reg"); ! 372: goto bad; ! 373: } ! 374: if ((int)(CG2Mfb.u_ppmask = (struct cg2m_ppmask *) mmap ((caddr_t) 0, ! 375: CG2M_MASKLEN, PROT_READ | PROT_WRITE, ! 376: MAP_SHARED | _MAP_NEW, fd, CG2M_MASKOFF)) == -1) { ! 377: Error ("Mapping cg2m.reg"); ! 378: goto bad; ! 379: } ! 380: if ((int)(CG2Mfb.u_cmap = (struct cg2m_cmap *) mmap ((caddr_t) 0, ! 381: CG2M_CMAPLEN, PROT_READ | PROT_WRITE, ! 382: MAP_SHARED | _MAP_NEW, fd, CG2M_CMAPOFF)) != -1) { ! 383: goto ok; ! 384: } ! 385: Error ("Mapping cg2m.cmap"); ! 386: #else ! 387: CG2Mfb.image = (union bitplane *)valloc (CG2M_IMAGELEN + CG2M_REGLEN + ! 388: CG2M_MASKLEN + CG2M_CMAPLEN); ! 389: CG2Mfb.u_csr = (struct cg2m_reg *) ((char *)CG2Mfb.image + ! 390: CG2M_IMAGELEN); ! 391: CG2Mfb.u_ppmask = (struct cg2m_ppmask *) ((char *)CG2Mfb.u_csr + ! 392: CG2M_REGLEN); ! 393: CG2Mfb.u_cmap = (struct cg2m_cmap *) ((char *)CG2Mfb.u_ppmask + ! 394: CG2M_MASKLEN); ! 395: if (CG2Mfb.image == (union bitplane *) NULL) { ! 396: ErrorF ("Could not allocate room for frame buffer.\n"); ! 397: sunFbData[fbNum].probeStatus = probedAndFailed; ! 398: return FALSE; ! 399: } ! 400: ! 401: if (mmap (CG2M_IMAGE(CG2Mfb), CG2M_IMAGELEN, PROT_READ | PROT_WRITE, ! 402: MAP_SHARED, fd, CG2M_IMAGEOFF) < 0) { ! 403: Error ("Mapping cg2m.image"); ! 404: goto bad; ! 405: } ! 406: if (mmap (CG2M_REG(CG2Mfb), CG2M_REGLEN, PROT_READ | PROT_WRITE, ! 407: MAP_SHARED, fd, CG2M_REGOFF) < 0) { ! 408: Error ("Mapping cg2m.reg"); ! 409: goto bad; ! 410: } ! 411: if (mmap (CG2M_MASK(CG2Mfb), CG2M_MASKLEN, PROT_READ | PROT_WRITE, ! 412: MAP_SHARED, fd, CG2M_MASKOFF) < 0) { ! 413: Error ("Mapping cg2m.mask"); ! 414: goto bad; ! 415: } ! 416: if (mmap (CG2M_CMAP(CG2Mfb), CG2M_CMAPLEN, PROT_READ | PROT_WRITE, ! 417: MAP_SHARED, fd, CG2M_CMAPOFF) >= 0) { ! 418: goto ok; ! 419: } ! 420: Error ("Mapping cg2m.cmap"); ! 421: #endif _MAP_NEW ! 422: bad: ! 423: sunFbData[fbNum].probeStatus = probedAndFailed; ! 424: (void) close (fd); ! 425: return FALSE; ! 426: ! 427: ok: ! 428: /* ! 429: * Enable only the first plane and make all even pixels be white, ! 430: * while all odd pixels are black. ! 431: */ ! 432: CG2Mfb.u_ppmask->u_ppmask.ppmask = 1; ! 433: CG2Mfb.u_csr->u_csr.csr.update_cmap = 0; ! 434: for ( i=0; i<256; i+=2 ) { ! 435: CG2Mfb.u_cmap->u_cmap.cmap.redmap[i] = ! 436: CG2Mfb.u_cmap->u_cmap.cmap.greenmap[i] = ! 437: CG2Mfb.u_cmap->u_cmap.cmap.bluemap[i] = 255; ! 438: CG2Mfb.u_cmap->u_cmap.cmap.redmap[i+1] = ! 439: CG2Mfb.u_cmap->u_cmap.cmap.greenmap[i+1] = ! 440: CG2Mfb.u_cmap->u_cmap.cmap.bluemap[i+1] = 0; ! 441: } ! 442: CG2Mfb.u_csr->u_csr.csr.update_cmap = 1; ! 443: ! 444: sunFbs[index].fd = fd; ! 445: sunFbs[index].info = fbType; ! 446: sunFbs[index].fb = (pointer) &CG2Mfb; ! 447: sunFbs[index].EnterLeave = NoopDDA; ! 448: sunFbData[fbNum].probeStatus = probedAndSucceeded; ! 449: } ! 450: ! 451: oldNumScreens = pScreenInfo->numScreens; ! 452: i = AddScreen(sunCG2MInit, argc, argv); ! 453: pScreenInfo->screen[index].CloseScreen = sunCG2MCloseScreen; ! 454: return (i > oldNumScreens); ! 455: } ! 456: ! 457:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.