|
|
1.1 root 1: /*-
2: * sunCG2C.c --
3: * Functions to support the sun CG2 board as a memory frame buffer.
4: */
5:
6: /************************************************************
7: Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
8:
9: All Rights Reserved
10:
11: Permission to use, copy, modify, and distribute this
12: software and its documentation for any purpose and without
13: fee is hereby granted, provided that the above copyright no-
14: tice appear in all copies and that both that copyright no-
15: tice and this permission notice appear in supporting docu-
16: mentation, and that the names of Sun or MIT not be used in
17: advertising or publicity pertaining to distribution of the
18: software without specific prior written permission. Sun and
19: M.I.T. make no representations about the suitability of this
20: software for any purpose. It is provided "as is" without any
21: express or implied warranty.
22:
23: SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
24: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
25: NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
26: ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
27: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
28: PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
29: OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
30: THE USE OR PERFORMANCE OF THIS SOFTWARE.
31:
32: ********************************************************/
33:
34: #ifndef lint
35: static char sccsid[] = "@(#)sunCG2C.c 2.8 87/06/05 Copyright 1987 Sun Micro";
36: #endif
37:
38: #include "sun.h"
39:
40: #include <sys/mman.h>
41: #include <struct.h>
42: #include <pixrect/memreg.h>
43: #include <pixrect/cg2reg.h>
44: #include "colormap.h"
45: #include "colormapst.h"
46: #include "resource.h"
47:
48: extern Bool sunCG2MProbe();
49: extern caddr_t mmap();
50: #ifndef _MAP_NEW
51: extern caddr_t valloc();
52: #endif _MAP_NEW
53:
54: /*-
55: * The cg2 frame buffer is divided into several pieces.
56: * 1) a stack of 8 monochrome bitplanes
57: * 2) an array of 8-bit pixels
58: * 3) a union of these two where modifications are done via RasterOp
59: * chips
60: * 4) various control registers
61: * 5) a shadow colormap.
62: *
63: * Each of these things is at a given offset from the base of the 4Mb devoted
64: * to each color board. In addition, the mmap() system call insists on the
65: * address and the length to be mapped being aligned on 8K boundaries.
66: *
67: * XXX This could be made a lot cleaner with proper use of structs and
68: * sizeof()'s.
69: */
70:
71: struct cg2c_reg {
72: /*
73: * The status register is at 0x309000. This isn't on an 8K
74: * boundary, so we have to put a 4K (0x1000) pad in front of it and
75: * map it here at 0x308000.
76: */
77: char csr_base[4096];
78: union {
79: struct cg2statusreg csr;
80: char csr_pad[4096];
81: } u_csr;
82: };
83:
84: struct cg2c_ppmask {
85: /* per-plane mask, offset = 0x30A000, size = 8K */
86: union {
87: unsigned short ppmask;
88: char ppm_pad[8192];
89: } u_ppmask;
90: };
91:
92: typedef struct cg2c_cmap {
93: /* colormap, offset = 0x310000, size = 8K */
94: union colormap_padded {
95: struct { /* Shouldn't these be u_char's??? */
96: u_short redmap[256]; /* Red-component map */
97: u_short greenmap[256]; /* Green-component map */
98: u_short bluemap[256]; /* Blue-component map */
99: } cmap;
100: char cmap_pad[8192];
101: } u_cmap;
102: };
103:
104: typedef struct cg2c {
105: union byteplane *image; /* the 8-bit memory */
106: struct cg2c_reg *u_csr; /* the status register */
107: struct cg2c_ppmask *u_ppmask; /* The plane mask register */
108: struct cg2c_cmap *u_cmap; /* the colormap */
109: } CG2C, CG2CRec, *CG2CPtr;
110:
111: #define CG2C_IMAGE(fb) ((caddr_t)((fb).image))
112: #define CG2C_IMAGEOFF ((off_t)0x00100000)
113: #define CG2C_IMAGELEN (sizeof(union byteplane))
114: #define CG2C_REG(fb) ((caddr_t)((fb).u_csr))
115: #define CG2C_REGOFF ((off_t)0x00308000)
116: #define CG2C_REGLEN (0x2000)
117: #define CG2C_MASK(fb) ((caddr_t)((fb).u_ppmask))
118: #define CG2C_MASKOFF ((off_t)0x0030A000)
119: #define CG2C_MASKLEN (0x2000)
120: #define CG2C_CMAP(fb) ((caddr_t)((fb).u_cmap))
121: #define CG2C_CMAPOFF ((off_t)0x00310000)
122: #define CG2C_CMAPLEN (0x2000)
123:
124:
125: extern int TellLostMap(), TellGainedMap();
126: #ifdef STATIC_COLOR
127: extern void cfbResolveStaticColor();
128: #endif STATIC_COLOR
129:
130: static void
131: sunCG2CUpdateColormap(fb, index, count, rmap, gmap,bmap)
132: CG2CPtr fb;
133: int index, count;
134: u_char *rmap, *gmap, *bmap;
135: {
136: #ifdef SUN_WINDOWS
137: if (sunUseSunWindows()) {
138: static Pixwin *pw = 0;
139:
140: if (! pw) {
141: if ( ! (pw = pw_open(windowFd)) )
142: FatalError( "sunCG2CUpdateColormap: pw_open failed\n" );
143: pw_setcmsname(pw, "X.V11");
144: }
145: pw_putcolormap(
146: pw, index, count, &rmap[index], &gmap[index], &bmap[index]
147: );
148: }
149: #endif SUN_WINDOWS
150:
151: fb->u_csr->u_csr.csr.update_cmap = 0;
152: while (count--) {
153: fb->u_cmap->u_cmap.cmap.redmap[index] = rmap[index];
154: fb->u_cmap->u_cmap.cmap.greenmap[index] = gmap[index];
155: fb->u_cmap->u_cmap.cmap.bluemap[index] = bmap[index];
156: index++;
157: }
158: fb->u_csr->u_csr.csr.update_cmap = 1;
159: }
160:
161: /*-
162: *-----------------------------------------------------------------------
163: * sunCG2CSaveScreen --
164: * Preserve the color screen by turning on or off the video
165: *
166: * Results:
167: * None.
168: *
169: * Side Effects:
170: * Video state is switched
171: *
172: *-----------------------------------------------------------------------
173: */
174: static Bool
175: sunCG2CSaveScreen (pScreen, on)
176: ScreenPtr pScreen;
177: Bool on;
178: {
179: int state = on;
180:
181: switch (on) {
182: case SCREEN_SAVER_FORCER:
183: SetTimeSinceLastInputEvent();
184: screenSaved = FALSE;
185: state = 1;
186: break;
187: case SCREEN_SAVER_OFF:
188: screenSaved = FALSE;
189: state = 1;
190: break;
191: case SCREEN_SAVER_ON:
192: default:
193: screenSaved = TRUE;
194: state = 0;
195: break;
196: }
197: ((CG2CPtr)sunFbs[pScreen->myNum].fb)->u_csr->u_csr.csr.video_enab = state;
198: return( TRUE );
199: }
200:
201: /*-
202: *-----------------------------------------------------------------------
203: * sunCG2CCloseScreen --
204: * called to ensure video is enabled when server exits.
205: *
206: * Results:
207: * Screen is unsaved.
208: *
209: * Side Effects:
210: * None
211: *
212: *-----------------------------------------------------------------------
213: */
214: /*ARGSUSED*/
215: static Bool
216: sunCG2CCloseScreen(i, pScreen)
217: int i;
218: ScreenPtr pScreen;
219: {
220: sunFbs[pScreen->myNum].fbPriv = NULL;
221: return (pScreen->SaveScreen(pScreen, SCREEN_SAVER_OFF));
222: }
223:
224: /*-
225: *-----------------------------------------------------------------------
226: * sunCG2CInstallColormap --
227: * Install given colormap.
228: *
229: * Results:
230: * None
231: *
232: * Side Effects:
233: * All clients requesting ColormapNotify are notified
234: *
235: *-----------------------------------------------------------------------
236: */
237: static void
238: sunCG2CInstallColormap(cmap)
239: ColormapPtr cmap;
240: {
241: register int i;
242: Entry *pent = cmap->red;
243: u_char rmap[256], gmap[256], bmap[256];
244: fbFd *fb = &sunFbs[cmap->pScreen->myNum];
245:
246: if (cmap == (ColormapPtr)fb->fbPriv)
247: return;
248: if (fb->fbPriv)
249: WalkTree(cmap->pScreen, TellLostMap,
250: (char *) &(((ColormapPtr)fb->fbPriv)->mid));
251: for (i = 0; i < cmap->pVisual->ColormapEntries; i++) {
252: if (pent->fShared) {
253: rmap[i] = pent->co.shco.red->color >> 8;
254: gmap[i] = pent->co.shco.green->color >> 8;
255: bmap[i] = pent->co.shco.blue->color >> 8;
256: }
257: else {
258: rmap[i] = pent->co.local.red >> 8;
259: gmap[i] = pent->co.local.green >> 8;
260: bmap[i] = pent->co.local.blue >> 8;
261: }
262: pent++;
263: }
264: fb->fbPriv = (pointer)cmap;
265: sunCG2CUpdateColormap((CG2CPtr)fb->fb, 0, 256, rmap, gmap, bmap);
266: WalkTree(cmap->pScreen, TellGainedMap, (char *) &(cmap->mid));
267: }
268:
269: /*-
270: *-----------------------------------------------------------------------
271: * sunCG2CUninstallColormap --
272: * Uninstall given colormap.
273: *
274: * Results:
275: * None
276: *
277: * Side Effects:
278: * All clients requesting ColormapNotify are notified
279: *
280: *-----------------------------------------------------------------------
281: */
282: static void
283: sunCG2CUninstallColormap(cmap)
284: ColormapPtr cmap;
285: {
286: if (cmap == (ColormapPtr)sunFbs[cmap->pScreen->myNum].fbPriv) {
287: Colormap defMapID = cmap->pScreen->defColormap;
288:
289: if (cmap->mid != defMapID) {
290: ColormapPtr defMap;
291:
292: defMap = (ColormapPtr) LookupID(defMapID, RT_COLORMAP, RC_CORE);
293: if (defMap)
294: sunCG2CInstallColormap(defMap);
295: else
296: ErrorF("sunCG2C: Can't find default colormap\n");
297: }
298: }
299: }
300:
301: /*-
302: *-----------------------------------------------------------------------
303: * sunCG2CListInstalledColormaps --
304: * Fills in the list with the IDs of the installed maps
305: *
306: * Results:
307: * Returns the number of IDs in the list
308: *
309: * Side Effects:
310: * None
311: *
312: *-----------------------------------------------------------------------
313: */
314: /*ARGSUSED*/
315: static int
316: sunCG2CListInstalledColormaps(pScreen, pCmapList)
317: ScreenPtr pScreen;
318: Colormap *pCmapList;
319: {
320: *pCmapList = ((ColormapPtr)sunFbs[pScreen->myNum].fbPriv)->mid;
321: return (1);
322: }
323:
324:
325: /*-
326: *-----------------------------------------------------------------------
327: * sunCG2CStoreColors --
328: * Sets the pixels in pdefs into the specified map.
329: *
330: * Results:
331: * None
332: *
333: * Side Effects:
334: * None
335: *
336: *-----------------------------------------------------------------------
337: */
338: static void
339: sunCG2CStoreColors(pmap, ndef, pdefs)
340: ColormapPtr pmap;
341: int ndef;
342: xColorItem *pdefs;
343: {
344: switch (pmap->class) {
345: case PseudoColor:
346: if (pmap == (ColormapPtr)sunFbs[pmap->pScreen->myNum].fbPriv) {
347: /* We only have a single colormap */
348: u_char rmap[256], gmap[256], bmap[256];
349: CG2CPtr fb = (CG2CPtr)sunFbs[pmap->pScreen->myNum].fb;
350:
351: while (ndef--) {
352: register int index = pdefs->pixel&0xff;
353:
354: rmap[index] = (pdefs->red) >> 8;
355: gmap[index] = (pdefs->green) >> 8;
356: bmap[index] = (pdefs->blue) >> 8;
357: sunCG2CUpdateColormap(fb, index, 1, rmap, gmap, bmap);
358: pdefs++;
359: }
360: }
361: break;
362: case DirectColor:
363: default:
364: ErrorF("sunCG2CStoreColors: bad class %d\n", pmap->class);
365: break;
366: }
367: }
368:
369: /*-
370: *-----------------------------------------------------------------------
371: * sunCG2CResolvePseudoColor --
372: * Adjust specified RGB values to closest values hardware can do.
373: *
374: * Results:
375: * Args are modified.
376: *
377: * Side Effects:
378: * None
379: *
380: *-----------------------------------------------------------------------
381: */
382: /*ARGSUSED*/
383: static void
384: sunCG2CResolvePseudoColor(pRed, pGreen, pBlue, pVisual)
385: CARD16 *pRed, *pGreen, *pBlue;
386: VisualPtr pVisual;
387: {
388: *pRed &= 0xff00;
389: *pGreen &= 0xff00;
390: *pBlue &= 0xff00;
391: }
392:
393: /*-
394: *-----------------------------------------------------------------------
395: * sunCG2CInit --
396: * Attempt to find and initialize a cg2 framebuffer used as mono
397: *
398: * Results:
399: * TRUE if everything went ok. FALSE if not.
400: *
401: * Side Effects:
402: * Most of the elements of the ScreenRec are filled in. Memory is
403: * allocated for the frame buffer and the buffer is mapped. The
404: * video is enabled for the frame buffer...
405: *
406: *-----------------------------------------------------------------------
407: */
408: /*ARGSUSED*/
409: static Bool
410: sunCG2CInit (index, pScreen, argc, argv)
411: int index; /* The index of pScreen in the ScreenInfo */
412: ScreenPtr pScreen; /* The Screen to initialize */
413: int argc; /* The number of the Server's arguments. */
414: char **argv; /* The arguments themselves. Don't change! */
415: {
416: CARD16 zero = 0, ones = ~0;
417: ColormapPtr cmap;
418:
419: if (!cfbScreenInit (index, pScreen,
420: ((CG2CPtr)sunFbs[index].fb)->image,
421: sunFbs[index].info.fb_width,
422: sunFbs[index].info.fb_height, 90))
423: return (FALSE);
424:
425: pScreen->SaveScreen = sunCG2CSaveScreen;
426:
427: #ifdef STATIC_COLOR
428: pScreen->InstallColormap = NoopDDA;
429: pScreen->UninstallColormap = NoopDDA;
430: pScreen->ListInstalledColormaps = (int (*)())NoopDDA;
431: pScreen->StoreColors = NoopDDA;
432: pScreen->ResolveColor = cfbResolveStaticColor;
433: #else STATIC_COLOR
434: pScreen->InstallColormap = sunCG2CInstallColormap;
435: pScreen->UninstallColormap = sunCG2CUninstallColormap;
436: pScreen->ListInstalledColormaps = sunCG2CListInstalledColormaps;
437: pScreen->StoreColors = sunCG2CStoreColors;
438: pScreen->ResolveColor = sunCG2CResolvePseudoColor;
439: #endif STATIC_COLOR
440:
441: cmap = (ColormapPtr)LookupID(pScreen->defColormap, RT_COLORMAP, RC_CORE);
442:
443: if (!cmap) {
444: FatalError("Can't find default colormap\n");
445: }
446: if (AllocColor(cmap, &ones, &ones, &ones, &(pScreen->whitePixel), 0) ||
447: AllocColor(cmap, &zero, &zero, &zero, &(pScreen->blackPixel), 0)){
448: FatalError("sunCG2CInit: Can't alloc black & white pixels\n" );
449: }
450: sunCG2CInstallColormap(cmap);
451:
452: sunCG2CSaveScreen( pScreen, SCREEN_SAVER_FORCER );
453: sunScreenInit (pScreen);
454:
455: return (TRUE);
456: }
457:
458:
459: /*-
460: *-----------------------------------------------------------------------
461: * sunCG2CProbe --
462: * Attempt to find and initialize a cg2 framebuffer used as mono
463: *
464: * Results:
465: * TRUE if everything went ok. FALSE if not.
466: *
467: * Side Effects:
468: * Memory is allocated for the frame buffer and the buffer is mapped.
469: *
470: *-----------------------------------------------------------------------
471: */
472: Bool
473: sunCG2CProbe (pScreenInfo, index, fbNum, argc, argv)
474: ScreenInfo *pScreenInfo; /* The screenInfo struct */
475: int index; /* The index of pScreen in the ScreenInfo */
476: int fbNum; /* Index into the sunFbData array */
477: int argc; /* The number of the Server's arguments. */
478: char **argv; /* The arguments themselves. Don't change! */
479: {
480: int i, oldNumScreens;
481:
482: /*
483: * See if the user wants this board to be treated as a monochrome
484: * display.
485: */
486: for (i = 0; i < argc; i++) {
487: if (strcmp (argv[i], "-mono") == 0) {
488: return sunCG2MProbe (pScreenInfo, index, fbNum, argc, argv);
489: }
490: }
491:
492: if (sunFbData[fbNum].probeStatus == probedAndFailed) {
493: return FALSE;
494: }
495:
496: if (sunFbData[fbNum].probeStatus == neverProbed) {
497: int fd;
498: struct fbtype fbType;
499: static CG2CRec CG2Cfb;
500:
501: if ((fd = sunOpenFrameBuffer(FBTYPE_SUN2COLOR, &fbType,
502: index, fbNum, argc, argv)) < 0) {
503: sunFbData[fbNum].probeStatus = probedAndFailed;
504: return FALSE;
505: }
506:
507: #ifdef _MAP_NEW
508: if ((int)(CG2Cfb.image = (union byteplane *) mmap ((caddr_t) 0, CG2C_IMAGELEN, PROT_READ | PROT_WRITE,
509: MAP_SHARED | _MAP_NEW, fd, CG2C_IMAGEOFF)) == -1) {
510: Error ("Mapping cg2c.image");
511: goto bad;
512: }
513: if ((int)(CG2Cfb.u_csr = (struct cg2c_reg *) mmap ((caddr_t) 0, CG2C_REGLEN, PROT_READ | PROT_WRITE,
514: MAP_SHARED | _MAP_NEW, fd, CG2C_REGOFF)) == -1) {
515: Error ("Mapping cg2c.reg");
516: goto bad;
517: }
518: if ((int)(CG2Cfb.u_ppmask = (struct cg2c_ppmask *) mmap ((caddr_t) 0, CG2C_MASKLEN, PROT_READ | PROT_WRITE,
519: MAP_SHARED | _MAP_NEW, fd, CG2C_MASKOFF)) == -1) {
520: Error ("Mapping cg2c.reg");
521: goto bad;
522: }
523: if ((int)(CG2Cfb.u_cmap = (struct cg2c_cmap *) mmap ((caddr_t) 0, CG2C_CMAPLEN, PROT_READ | PROT_WRITE,
524: MAP_SHARED | _MAP_NEW, fd, CG2C_CMAPOFF)) != -1) {
525: goto ok;
526: }
527: Error ("Mapping cg2c.cmap");
528: #else
529: CG2Cfb.image = (union byteplane *)valloc (CG2C_IMAGELEN + CG2C_REGLEN + CG2C_MASKLEN + CG2C_CMAPLEN);
530: CG2Cfb.u_csr = (struct cg2c_reg *) ((char *)CG2Cfb.image + CG2C_IMAGELEN);
531: CG2Cfb.u_ppmask = (struct cg2c_ppmask *) ((char *)CG2Cfb.u_csr + CG2C_REGLEN);
532: CG2Cfb.u_cmap = (struct cg2c_cmap *) ((char *)CG2Cfb.u_ppmask + CG2C_MASKLEN);
533: if (CG2Cfb.image == (union byteplane *) NULL) {
534: ErrorF ("Could not allocate room for frame buffer.\n");
535: sunFbData[fbNum].probeStatus = probedAndFailed;
536: return FALSE;
537: }
538:
539: if (mmap (CG2C_IMAGE(CG2Cfb), CG2C_IMAGELEN, PROT_READ | PROT_WRITE,
540: MAP_SHARED, fd, CG2C_IMAGEOFF) < 0) {
541: Error ("Mapping cg2c.image");
542: goto bad;
543: }
544: if (mmap (CG2C_REG(CG2Cfb), CG2C_REGLEN, PROT_READ | PROT_WRITE,
545: MAP_SHARED, fd, CG2C_REGOFF) < 0) {
546: Error ("Mapping cg2c.reg");
547: goto bad;
548: }
549: if (mmap (CG2C_MASK(CG2Cfb), CG2C_MASKLEN, PROT_READ | PROT_WRITE,
550: MAP_SHARED, fd, CG2C_MASKOFF) < 0) {
551: Error ("Mapping cg2c.reg");
552: goto bad;
553: }
554: if (mmap (CG2C_CMAP(CG2Cfb), CG2C_CMAPLEN, PROT_READ | PROT_WRITE,
555: MAP_SHARED, fd, CG2C_CMAPOFF) >= 0) {
556: goto ok;
557: }
558: Error ("Mapping cg2c.cmap");
559: #endif _MAP_NEW
560: bad:
561: sunFbData[fbNum].probeStatus = probedAndFailed;
562: (void) close (fd);
563: return FALSE;
564:
565: ok:
566: /*
567: * Enable all planes
568: */
569: CG2Cfb.u_ppmask->u_ppmask.ppmask = 0xFF;
570:
571: sunFbs[index].fd = fd;
572: sunFbs[index].info = fbType;
573: sunFbs[index].fb = (pointer) &CG2Cfb;
574: sunFbs[index].EnterLeave = NoopDDA;
575: sunFbData[fbNum].probeStatus = probedAndSucceeded;
576: }
577:
578: oldNumScreens = pScreenInfo->numScreens;
579: i = AddScreen(sunCG2CInit, argc, argv);
580: pScreenInfo->screen[index].CloseScreen = sunCG2CCloseScreen;
581: return (i > oldNumScreens);
582: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.