|
|
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.