#ifndef lint static char sccsid[] = "@(#)pixrectint.c 6.9 87/05/26 SMI"; #endif /* * pixrectint.c * * The pixrect create and destroy functions for supported Sun frame * buffers. File was created by concatenating pixrect files for each * frame buffer (bw1.c, bw2.c, etc.) */ #ifdef sparc #undef INCLGP1 #undef INCLBW1 #endif #include #include #include #include #include #include #include #include #include #ifdef INCLCG1 #include #include #endif #include #include #ifdef INCLCG4 #include #include #endif #include #ifdef INCLGP1 #include #include #include #endif #include #include #include #ifdef alloctype #undef alloctype #endif #define alloctype(datatype) (datatype *)softcalloc("pr_make.c", 1, sizeof(datatype)) extern char *calloc(), *valloc(), *snoopcalloc(), *softcalloc(); extern generic_shapetext(), mem_shapetext(), cg2_shapetext(), cg2_shapecurve(), generic_shaperop(), #ifdef INCLGP1 gp1_shapetext(), gp1_shaperop(), #endif generic_shapecurve(), mem_shapecurve(), generic_shapevector(); /* JAG */ static Missing() { return -1;} static struct pixrect *MissingP() {return 0;} /* * Copyright (c) 1983 by Sun Microsystems, Inc. */ /* * Sun1 Black-and-White pixrect create and destroy */ static struct pr_devdata *bw1devdata; struct pixrectops bw1_ops = { #ifdef INCLBW1 bw1_rop, #ifdef PREVIEW bw1_stencil, bw1_batchrop, #else Missing /*bw1_stencil*/, Missing /*bw1_batchrop*/, #endif 0, bw1_destroy, bw1_get, bw1_put, bw1_vector, bw1_region, bw1_putcolormap, bw1_getcolormap, bw1_putattributes, bw1_getattributes, generic_shapetext, generic_shaperop, generic_shapecurve, generic_shapevector, /* JAG */ generic_replrop, #else Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, MissingP, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, #endif }; struct pixrect * bw1_make(fd, size, depth) int fd; struct pr_size size; int depth; { #ifdef INCLBW1 struct pixrect *pr; register struct bw1pr *bwpr; struct pr_devdata *dd; if (depth != 1 || size.x != 1024 || size.y != 800) { fprintf(stderr,"bw1_make sizes wrong %D %D %D\n", depth, size.x, size.y); return (0); } /* * Allocate/initialize pixrect and get virtual address for it. */ if (!(pr = pr_makefromfd(fd, size, depth, &bw1devdata, &dd, sizeof (struct bw1fb), sizeof(struct bw1pr), 0))) return (0); pr->pr_ops = &bw1_ops; pr->pr_canvas = 0; /* * Initialize pixrect private data. */ bwpr = (struct bw1pr *)pr->pr_data; bwpr->bwpr_fd = dd->fd; bwpr->bwpr_va = (struct bw1fb *)dd->va; bwpr->bwpr_flags = BW_REVERSEVIDEO; bwpr->bwpr_offset.x = bwpr->bwpr_offset.y = 0; return (pr); #else return 0; #endif } bw1_destroy(pr) struct pixrect *pr; { #ifdef INCLBW1 register struct bw1pr *bwpr; if (pr == 0) return (0); if (bwpr = bw1_d(pr)) { if (bwpr->bwpr_fd != -1) { /* * Don't free this part if region */ pr_unmakefromfd(bwpr->bwpr_fd, &bw1devdata); } free(bwpr); } free(pr); return (0); #else return 0; #endif } /* * Copyright (c) 1983 by Sun Microsystems, Inc. */ /* * Sun2 Black-and-White pixrect create and destroy */ static struct pr_devdata *bw2devdata; struct pixrectops bw2_ops = { mem_rop, #ifdef PREVIEW mem_stencil, mem_batchrop, #else Missing /*mem_stencil*/, Missing /*mem_batchrop*/, #endif 0, bw2_destroy, mem_get, mem_put, mem_vector, mem_region, mem_putcolormap, mem_getcolormap, mem_putattributes, mem_getattributes, mem_shapetext, generic_shaperop, mem_shapecurve, generic_shapevector, /* JAG */ generic_replrop, }; struct pixrect * bw2_make(fd, size, depth) int fd; struct pr_size size; int depth; { register struct pixrect *pr; register struct mpr_data *md; struct pr_devdata *dd; register linebytes = mpr_linebytes(size.x, depth); pr = pr_makefromfd(fd, size, depth, &bw2devdata, &dd, linebytes * size.y, sizeof(struct mpr_data), 0); if (pr == 0) return 0; pr->pr_ops = &bw2_ops; pr->pr_canvas = 0; md = (struct mpr_data *) pr->pr_data; md->md_linebytes = linebytes; md->md_image = dd->va; md->md_offset.x = md->md_offset.y = 0; md->md_primary = -1 - dd->fd; md->md_flags = MP_DISPLAY; /* pr is display dev */ return (pr); } bw2_destroy(pr) struct pixrect *pr; { register struct mpr_data *md; if (pr == 0) return (0); if (md = mpr_d(pr)) { if (md->md_primary) { /* * Don't free this part if region */ pr_unmakefromfd(-1 - md->md_primary, &bw2devdata); } free(md); } free(pr); return (0); } /* * Copyright (c) 1983 by Sun Microsystems, Inc. */ /* * Sun1 color pixrect create and destroy */ static struct pr_devdata *cg1devdata; struct pixrectops cg1_ops = { #ifdef INCLCG1 cg1_rop, #ifdef PREVIEW cg1_stencil, cg1_batchrop, #else Missing /*cg1_stencil*/, Missing /*cg1_batchrop*/, #endif 0, cg1_destroy, cg1_get, cg1_put, cg1_vector, cg1_region, cg1_putcolormap, cg1_getcolormap, cg1_putattributes, cg1_getattributes, generic_shapetext, generic_shaperop, generic_shapecurve, generic_shapevector, /* JAG */ generic_replrop, #else Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, MissingP, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, #endif }; struct pixrect * cg1_make(fd, size, depth) int fd; struct pr_size size; int depth; { #ifdef INCLCG1 struct pixrect *pr; register struct cg1pr *cgpr; struct pr_devdata *dd; if (depth != CG1_DEPTH || size.x != CG1_WIDTH || size.y != CG1_HEIGHT) { fprintf(stderr, "cg1_make sizes wrong %D %D %D\n", depth, size.x, size.y); return (0); } /* * Allocate/initialize pixrect and get virtual address for it. */ if (!(pr = pr_makefromfd(fd, size, depth, &cg1devdata, &dd, sizeof(struct cg1fb), sizeof(struct cg1pr), 0))) return (0); pr->pr_ops = &cg1_ops; pr->pr_canvas = 0; /* * Initialize pixrect private data. */ cgpr = (struct cg1pr *)pr->pr_data; cgpr->cgpr_fd = dd->fd; cgpr->cgpr_va = (struct cg1fb *)dd->va; cgpr->cgpr_planes = 255; cgpr->cgpr_offset.x = cgpr->cgpr_offset.y = 0; cg1_setreg(cgpr->cgpr_va, CG_STATUS, CG_VIDEOENABLE); return (pr); #else return 0; #endif } /*---------------------------------------------------------------------------*/ cg1_destroy(pr) struct pixrect *pr; { #ifdef INCLCG1 register struct cg1pr *cgpr; if (pr == 0) return (0); if (cgpr = cg1_d(pr)) { if (cgpr->cgpr_fd != -1) { /* * Don't free this part if region */ pr_unmakefromfd(cgpr->cgpr_fd, &cg1devdata); } free(cgpr); } free(pr); return (0); #else return 0; #endif } /* * Copyright (c) 1983 by Sun Microsystems, Inc. */ /* * Sun2 color pixrect create and destroy */ static struct pr_devdata *cg2devdata; extern cg2_shaperop(); struct pixrectops cg2_ops = { #ifdef INCLCG2 cg2_rop, #ifdef PREVIEW cg2_stencil, cg2_batchrop, #else Missing /*cg2_stencil*/, Missing /*cg2_batchrop*/, #endif 0, cg2_destroy, cg2_get, cg2_put, cg2_vector, cg2_region, cg2_putcolormap, cg2_getcolormap, cg2_putattributes, cg2_getattributes, cg2_shapetext, cg2_shaperop, cg2_shapecurve, generic_shapevector, /* JAG */ generic_replrop, #else Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, MissingP, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, #endif }; struct pixrect * cg2_make(fd, size, depth) int fd; struct pr_size size; int depth; { #ifdef INCLCG2 struct pixrect *pr; register struct cg2pr *cgpr; struct pr_devdata *dd; struct fbtype fb; if (ioctl(fd, FBIOGTYPE, &fb) == -1) { fprintf(stderr, "FBIOGTYPE: problem determining fb type of cgtwo\n"); close(fd); return (0); } if (depth!=CG2_DEPTH || size.x!=fb.fb_width || size.y!=fb.fb_height) { fprintf(stderr, "cg2_make sizes wrong %D %D %D\n", depth, size.x, size.y); return (0); } /* * Allocate/initialize pixrect and get virtual address for it. */ if (!(pr = pr_makefromfd(fd, size, depth, &cg2devdata, &dd, sizeof (struct cg2fb), sizeof(struct cg2pr), sizeof(struct cg2memfb)))) return (0); pr->pr_ops = &cg2_ops; pr->pr_canvas = 0; /* * Initialize cg2 status register for video enable * and no pan or zoom. Must be careful not to mess with the * rop controls because another application may be in the middle * of a rop. It is debatable whether or not the pan and zoom * stuff should be initialized here in the case when another * application is doing something with them. */ #ifdef undef /* This stuff is never used, the fields are initialized outside * of NeWS, and graphics group has changed the h-files so that * these names no longer work. Let's put this code out of it's * (our) misery. */ ((struct cg2fb *)dd->va)->status.reg.video_enab = 1; /* video enable */ ((struct cg2fb *)dd->va)->wordpan.reg = 0; /* hi pixel adr = 0 */ ((struct cg2fb *)dd->va)->zoom.word = 0; /* zoom=0, yoff=0 */ ((struct cg2fb *)dd->va)->pixpan.word = 0; /* pix adr=0, xoff=0 */ ((struct cg2fb *)dd->va)->varzoom.reg = 0xff; /* unzoom at lin 4*ff */ #endif /* * Initialize pixrect private data. */ cgpr = (struct cg2pr *)pr->pr_data; cgpr->cgpr_fd = dd->fd; cgpr->cgpr_va = (struct cg2fb *)dd->va; cgpr->cgpr_planes = 255; cgpr->cgpr_offset.x = cgpr->cgpr_offset.y = 0; return (pr); #else return 0; #endif } /*---------------------------------------------------------------------------*/ cg2_destroy(pr) struct pixrect *pr; { #ifdef INCLCG2 register struct cg2pr *cgpr; if (pr == 0) return (0); if (cgpr = cg2_d(pr)) { if (cgpr->cgpr_fd != -1) { /* * Don't free this part if region */ pr_unmakefromfd(cgpr->cgpr_fd, &cg2devdata); } free(cgpr); } free(pr); #endif return (0); } /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ /* * Sun2 graphics processor create and destroy */ static struct pr_devdata *gp1devdata; struct pixrectops gp1_ops = { #ifdef INCLGP1 gp1_rop, #ifdef PREVIEW gp1_stencil, gp1_batchrop, #else Missing /*gp1_stencil*/, Missing /*gp1_batchrop*/, #endif 0, gp1_destroy, gp1_get, gp1_put, gp1_vector, gp1_region, gp1_putcolormap, gp1_getcolormap, gp1_putattributes, gp1_getattributes, gp1_shapetext, gp1_shaperop, generic_shapecurve, generic_shapevector, /* JAG */ generic_replrop, #else Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, MissingP, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, #endif }; struct pixrect *gp1_makefromfd(); struct pixrect * gp1_make(fd, size, depth) int fd; struct pr_size size; int depth; { #ifdef INCLGP1 struct pixrect *pr; register struct gp1pr *gppr; int gbufflag; char minordev; struct pr_devdata *dd; struct fbtype fb; struct fbinfo fbinfo; if (ioctl(fd, FBIOGTYPE, &fb) == -1) { fprintf(stderr, "FBIOGTYPE: problem determining fb type of gpone\n"); close(fd); return (0); } if (depth!=CG2_DEPTH || size.x!=fb.fb_width || size.y!=fb.fb_height) { fprintf(stderr, "gp1_make sizes wrong %D %D %D\n", depth, size.x, size.y); return (0); } if (ioctl(fd, FBIOGINFO, &fbinfo) == -1) { fprintf(stderr, "FBIOGINFO: problem getting info about device\n"); close(fd); return (0); } if (ioctl(fd, GP1IO_GET_GBUFFER_STATE, &gbufflag) == -1) { fprintf(stderr, "GP1IO_GET_GBUFFER_STATE: problem getting gbuffer state\n"); close(fd); return (0); } if (ioctl(fd, GP1IO_GET_TRUMINORDEV, &minordev) == -1) { fprintf(stderr, "GP1IO_GET_TRUMINORDEV: problem getting minor device number \n"); close(fd); return (0); } /* * Allocate/initialize pixrect and get virtual address for it. */ /* can't call pr_makefromfd due to dual memory mapping */ if (!(pr = gp1_makefromfd(fd, size, depth, &gp1devdata, &dd, sizeof(struct gp1pr), GP1_SHMEM_SIZE, GP1_SHMEM_OFFSET, sizeof(struct cg2fb), fbinfo.fb_addrdelta + sizeof(struct cg2memfb)))) return (0); pr->pr_ops = &gp1_ops; pr->pr_canvas = 0; /* * Initialize pixrect private data. */ gppr = (struct gp1pr *)pr->pr_data; gppr->cgpr_fd = dd->fd; gppr->gp_shmem = (caddr_t)dd->va; gppr->cgpr_va = (struct cg2fb *)((caddr_t)dd->va + GP1_SHMEM_SIZE); gppr->cgpr_planes = 255; gppr->cgpr_offset.x = gppr->cgpr_offset.y = 0; gppr->cg2_index = fbinfo.fb_unit; gppr->minordev = minordev; gppr->gbufflag = gbufflag; gppr->ioctl_fd = gppr->cgpr_fd; /* * Initialize cg2 status register for video enable * and no pan or zoom. Must be careful not to mess with the * rop controls because another application may be in the middle * of a rop. It is debatable whether or not the pan and zoom * stuff should be initialized here in the case when another * application is doing something with them. */ gppr->cgpr_va->status.reg.video_enab = 1; /* video enable */ gppr->cgpr_va->wordpan.reg = 0; /* hi pixel adr = 0 */ gppr->cgpr_va->zoom.word = 0; /* zoom=0, yoff=0 */ gppr->cgpr_va->pixpan.word = 0; /* pix adr=0, xoff=0 */ gppr->cgpr_va->varzoom.reg = 0xff; /* unzoom at lin 4*ff */ return (pr); #else return 0; #endif } /*---------------------------------------------------------------------------*/ gp1_destroy(pr) struct pixrect *pr; { #ifdef INCLGP1 register struct gp1pr *gppr; if (pr == 0) return (0); if (gppr = gp1_d(pr)) { if (gppr->cgpr_fd != -1) { /* * Don't free this part if region */ pr_unmakefromfd(gppr->cgpr_fd, &gp1devdata); } free(gppr); } free(pr); return (0); #else return 0; #endif } /* * graphics processor pixrect make/unmake utilities * (can't use pr_makefromfd due to dual memory mapping) */ struct pixrect * gp1_makefromfd(fd, size, depth, devdata, curdd, privdatabytes, gp1mmapbytes, gp1offsetbytes, cg2mmapbytes, cg2offsetbytes) int fd; struct pr_size size; int depth; struct pr_devdata **devdata; register struct pr_devdata **curdd; int privdatabytes; int gp1mmapbytes, gp1offsetbytes, cg2mmapbytes, cg2offsetbytes; { #ifdef INCLGP1 struct pixrect *pr = 0; dev_t devtype; char *errstr = ""; register struct pr_devdata *dd; /* * Check args */ if (fd < 0) { errstr = "invalid fd"; goto bad; } if (devdata == 0 || curdd == 0) { errstr = "no **pr_devdata"; goto bad; } /* * Allocate and initial struct pixrect. */ pr = (struct pixrect *)softcalloc("pixrectint.c", 1, sizeof(struct pixrect)); if (pr == 0) goto bad; pr->pr_size.x = size.x, pr->pr_size.y = size.y; pr->pr_depth = depth; /* * Allocate private data. */ pr->pr_data = (caddr_t)softcalloc("pixrectint.c", 1, privdatabytes); if (pr->pr_data == 0) goto bad; /* * Get pr_devdata that will use by finding node that matches fd's rdev. */ ioctl (fd, GP1IO_GET_REQDEV, &devtype); if (*devdata == 0) { /* * Allocate first node */ dd = *devdata = alloctype(struct pr_devdata); } else { for (dd = *devdata;dd; dd = dd->next) { if (devtype == dd->rdev) break; if (dd->next == 0) { /* * Add new node. */ dd->next = alloctype(struct pr_devdata); dd = dd->next; break; } } } dd->rdev = devtype; /* * Get virtual addresses for gp and color board if don't already * have it. This is the main reason for the pr_devdata, * i.e., reducing virtual address space usage. * Valloc enough space for both the gp and the cg2 boards with * with contiguous memory mappings. GP mmap should be first * since it is a multiple of the page size. */ if (dd->va == 0) { /* * Caller responsible for closing fd so dup here. */ dd->fd = dup(fd); /* * Round mmap args to page sizes because mmap wants it that way. */ gp1mmapbytes = gp1_rounduppage(gp1mmapbytes); cg2mmapbytes = gp1_rounduppage(cg2mmapbytes); if (gp1offsetbytes != gp1_rounduppage(gp1offsetbytes)) { errstr = "gp1offsetbytes not page size multiple"; goto bad; } if (cg2offsetbytes != gp1_rounduppage(cg2offsetbytes)) { errstr = "cg2offsetbytes not page size multiple"; goto bad; } /* * Allocate virtual memory. */ dd->bytes = gp1mmapbytes + cg2mmapbytes; dd->va = (short *)valloc(dd->bytes); if (dd->va == 0) { errstr = "valloc failed"; goto bad; } /* first map the GP board */ if (mmap(dd->va, gp1mmapbytes, PROT_READ|PROT_WRITE, MAP_SHARED, dd->fd, gp1offsetbytes) < 0) { extern errno; fprintf(stderr, "errno=%D, va=%X, fd=%D, size=%X, off=%X\n", errno, dd->va, dd->fd, gp1mmapbytes, gp1offsetbytes); errstr = "gp mmap failed"; goto bad; } /* next map the CG2 board */ if (mmap((caddr_t)dd->va + gp1mmapbytes, cg2mmapbytes, PROT_READ|PROT_WRITE, MAP_SHARED, dd->fd, cg2offsetbytes) < 0) { extern errno; fprintf(stderr, "errno=%D, va=%X, fd=%D, size=%X, off=%X\n", errno, (caddr_t)dd->va + gp1mmapbytes, dd->fd, cg2mmapbytes, cg2offsetbytes); errstr = "cg2 mmap failed"; goto bad; } } dd->count++; *curdd = dd; return(pr); bad: /* * All the errors in this routine are essentially fatal. * Thus, we don't bother to release allocated resources. */ fprintf(stderr, "gp1_makefromfd error: %s\n", errstr); *curdd = 0; return (0); #else return 0; #endif } static gp1_rounduppage(bytes) register int bytes; { #ifdef INCLGP1 register int pagesize = getpagesize(); register int roundup = pagesize-(bytes%pagesize); if (roundup != pagesize) bytes += roundup; return(bytes); #else return 0; #endif } /* * Copyright (c) 1983 by Sun Microsystems, Inc. */ /* * Memory pixrect creation */ struct pixrectops mem_ops = { mem_rop, #ifdef PREVIEW mem_stencil, mem_batchrop, #else Missing /*mem_stencil*/, Missing /*mem_batchrop*/, #endif 0, mem_destroy, mem_get, mem_put, mem_vector, mem_region, mem_putcolormap, mem_getcolormap, mem_putattributes, mem_getattributes, mem_shapetext, generic_shaperop, generic_shapecurve, generic_shapevector, /* JAG */ generic_replrop, }; struct memropc *mem_ropc; /* Pointer to ROP chip, or zero */ /* * Create a memory pixrect that points to an existing (non-pixrect) image. */ struct pixrect * mem_point(x, y, depth, data) int x, y, depth; short *data; { register struct pixrect *pr; register struct mpr_data *md; pr = alloctype(struct pixrect); if (pr == 0) return (0); md = alloctype(struct mpr_data); if (md == 0) { free(pr); return (0); } pr->pr_ops = &mem_ops; pr->pr_canvas = 0; pr->pr_size.x = x; pr->pr_size.y = y; pr->pr_depth = depth; pr->pr_data = (caddr_t)md; md->md_linebytes = mpr_linebytes(x, depth); md->md_offset.x = 0; md->md_offset.y = 0; md->md_primary = 0; md->md_flags = 0; md->md_image = data; return (pr); } /* * Create a memory pixrect, allocate space, and clear it. */ struct pixrect * mem_create(x, y, depth) int x, y, depth; { struct pixrect *pr; register struct mpr_data *md; short *zero = 0; pr = mem_point(x, y, depth, zero); if (pr == 0) return 0; md = mpr_d(pr); md->md_image = (short *)softcalloc("pixrectint.c", 1,pr_product(md->md_linebytes, y)); if (md->md_image == 0) { /* No room at the inn */ mem_destroy(pr); return (0); } md->md_primary = 1; /* cfree when mem_destroy */ return (pr); } mem_destroy(pr) struct pixrect *pr; { register struct mpr_data *md; if (pr == 0) return; md = mpr_d(pr); if (md) { if (md->md_primary && md->md_image) free(md->md_image); free(md); } free(pr); } #ifdef undef int mem_needinit = 1; mem_init() { int mf; struct memropc *mrc; mem_needinit = 0; mf = open("/dev/ropc", 2); if (mf < 0) return; mrc = (struct memropc *)valloc(sizeof (*mrc)); if (mrc == 0 || mmap(mrc, sizeof (*mrc), PROT_READ|PROT_WRITE, MAP_SHARED, mf, 0) < 0) { close(mf); return; } mem_ropc = mrc; } #endif /* * Copyright 1986 by Sun Microsystems, Inc. * (from cg4.c 1.2 86/07/31 on pest--3.2FCS) */ /* * Color memory frame buffer (cg4) create and destroy */ /* initial active frame buffer */ #ifndef CG4_INITFB #define CG4_INITFB 2 #endif /* round value up to specified granularity -- gran must be a power of two */ #define ROUNDUP(val, gran) (((val) - 1 | (gran) - 1) + 1) /* device data list head */ static struct pr_devdata *cg4devdata; /* pixrect ops vector */ struct pixrectops cg4_ops = { #ifdef INCLCG4 mem_rop, #ifdef PREVIEW mem_stencil, mem_batchrop, #else Missing /*mem_stencil*/, Missing /*mem_batchrop*/, #endif 0, cg4_destroy, mem_get, mem_put, mem_vector, cg4_region, cg4_putcolormap, cg4_getcolormap, cg4_putattributes, cg4_getattributes, mem_shapetext, generic_shaperop, mem_shapecurve, generic_shapevector, /* JAG */ generic_replrop, #else Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, MissingP, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, #endif }; /* pixrect create function */ Pixrect * cg4_make(fd, size, depth) int fd; struct pr_size size; int depth; { #ifdef INCLCG4 register int w, h; register Pixrect *pr; register struct cg4_data *cgd; struct pr_devdata *curdd; int pagesize, mmapbytes; caddr_t fb_addr; register struct cg4fb *fbp; static struct fbdesc { short group; short depth; int allplanes; } fbdesc[CG4_NFBS] = { { PIXPG_OVERLAY, 1, 0 }, { PIXPG_OVERLAY_ENABLE, 1, 0 }, { PIXPG_8BIT_COLOR, 8, 255 } }; register struct fbdesc *descp; /* * compute total space to be mmaped */ w = size.x; h = size.y; pagesize = getpagesize(); mmapbytes = 0; for (descp = fbdesc; descp < &fbdesc[CG4_NFBS]; descp++) mmapbytes += ROUNDUP(mpr_linebytes(w, descp->depth) * h, pagesize); /* allocate pixrect and map frame buffer */ if ((pr = pr_makefromfd(fd, size, depth, &cg4devdata, &curdd, mmapbytes, sizeof(struct cg4_data), 0)) == 0) return 0; /* initialize pixrect data */ pr->pr_ops = &cg4_ops; cgd = cg4_d(pr); cgd->flags = CG4_PRIMARY | CG4_OVERLAY_CMAP; cgd->planes = 0; cgd->fd = curdd->fd; fb_addr = (caddr_t) curdd->va; for (fbp = cgd->fb, descp = fbdesc; descp < &fbdesc[CG4_NFBS]; fbp++, descp++) { fbp->group = descp->group; fbp->depth = descp->depth; fbp->mprp.mpr.md_linebytes = mpr_linebytes(w, descp->depth); fbp->mprp.mpr.md_image = (short *) fb_addr; fbp->mprp.mpr.md_offset.x = 0; fbp->mprp.mpr.md_offset.y = 0; fbp->mprp.mpr.md_primary = 0; fbp->mprp.mpr.md_flags = descp->allplanes != 0 ? MP_DISPLAY | MP_PLANEMASK : MP_DISPLAY; fbp->mprp.planes = descp->allplanes; fb_addr += ROUNDUP(fbp->mprp.mpr.md_linebytes * h, pagesize); } /* see if the frame buffer really has an overlay plane color map */ { static int overlayplanes = PIX_GROUP(PIXPG_OVERLAY); u_char rgb[1]; (void) cg4_putattributes(pr, &overlayplanes); if (cg4_getcolormap(pr, overlayplanes, 1, rgb, rgb, rgb) != 0) cgd->flags &= ~(CG4_OVERLAY_CMAP); } /* set up pixrect initial state */ { #ifdef CG4_ENABLE_HACK int initplanes, initfb = CG4_INITFB; extern char *sun_fb_name; char *index(); int len = strlen (sun_fb_name); /* Special file names get overlay and enable planes */ if (index(sun_fb_name, '_') != NULL) { if (sun_fb_name[len-1] == 'l') /* cgfour0_ovl */ initfb = 0; /* overlay plane */ else if (sun_fb_name[len-1] == 'e') /* cgfour0_ove */ initfb = 1; /* enable plane */ else initfb = 2; /* color plane */ } initplanes = PIX_GROUP(fbdesc[initfb].group) | fbdesc[initfb].allplanes; #else !CG4_ENABLE_HACK int initplanes = PIX_GROUP(fbdesc[CG4_INITFB].group) | fbdesc[CG4_INITFB].allplanes; #endif !CG4_ENABLE_HACK (void) cg4_putattributes(pr, &initplanes); } return pr; #else return 0; #endif } cg4_destroy(pr) Pixrect *pr; { #ifdef INCLCG4 if (pr != 0) { register struct cg4_data *cgd; if ((cgd = cg4_d(pr)) != 0) { if (cgd->flags & CG4_PRIMARY) pr_unmakefromfd(cgd->fd, &cg4devdata); free(cgd); } free(pr); } #endif return 0; }