HIDDEN int mem_close(FBIO *ifp) { /* * Flush memory/cmap to attached frame buffer if any */ if (MI(ifp)->fbp != FBIO_NULL) { if (MI(ifp)->cmap_dirty) { fb_wmap(MI(ifp)->fbp, &(MI(ifp)->cmap)); } if (MI(ifp)->mem_dirty) { fb_writerect(MI(ifp)->fbp, 0, 0, ifp->if_width, ifp->if_height, (unsigned char *)MI(ifp)->mem); } fb_close(MI(ifp)->fbp); MI(ifp)->fbp = FBIO_NULL; } (void)free((char *)MI(ifp)->mem); (void)free((char *)MIL(ifp)); return 0; }
HIDDEN int mem_flush(FBIO *ifp) { /* * Flush memory/cmap to attached frame buffer if any */ if (MI(ifp)->fbp != FBIO_NULL) { if (MI(ifp)->cmap_dirty) { fb_wmap(MI(ifp)->fbp, &(MI(ifp)->cmap)); MI(ifp)->cmap_dirty = 0; } if (MI(ifp)->mem_dirty) { fb_writerect(MI(ifp)->fbp, 0, 0, ifp->if_width, ifp->if_height, (unsigned char *)MI(ifp)->mem); MI(ifp)->mem_dirty = 0; } return fb_flush(MI(ifp)->fbp); } MI(ifp)->cmap_dirty = 0; MI(ifp)->mem_dirty = 0; return 0; /* success */ }
/* * * Usage: * procname cell xmin ymin width height color */ HIDDEN int fbo_cell_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { struct fb_obj *fbop = (struct fb_obj *)clientData; struct bu_vls vls; int xmin, ymin; int width; int height; int i; RGBpixel pixel; unsigned char *pp; if (argc != 7) { bu_vls_init(&vls); bu_vls_printf(&vls, "helplib fb_cell"); Tcl_Eval(interp, bu_vls_addr(&vls)); bu_vls_free(&vls); return TCL_ERROR; } if (sscanf(argv[2], "%d", &xmin) != 1) { Tcl_AppendResult(interp, "fb_cell: bad xmin value - ", argv[2], (char *)NULL); return TCL_ERROR; } if (sscanf(argv[3], "%d", &ymin) != 1) { Tcl_AppendResult(interp, "fb_cell: bad ymin value - ", argv[3], (char *)NULL); return TCL_ERROR; } /* check coordinates */ if (!fbo_coords_ok(interp, fbop->fbo_fbs.fbs_fbp, xmin, ymin)) { Tcl_AppendResult(interp, "fb_cell: coordinates (", argv[2], ", ", argv[3], ") are invalid.", (char *)NULL); return TCL_ERROR; } if (sscanf(argv[4], "%d", &width) != 1) { Tcl_AppendResult(interp, "fb_cell: bad width - ", argv[4], (char *)NULL); return TCL_ERROR; } if (sscanf(argv[5], "%d", &height) != 1) { Tcl_AppendResult(interp, "fb_cell: bad height - ", argv[5], (char *)NULL); return TCL_ERROR; } /* check width and height */ if (width <=0 || height <=0) { Tcl_AppendResult(interp, "fb_cell: width and height must be > 0", (char *)NULL); return TCL_ERROR; } /* * Decompose the color list into its constituents. * For now must be in the form of rrr ggg bbb. */ if (fbo_tcllist2color(interp, argv[6], pixel) == TCL_ERROR) { Tcl_AppendResult(interp, "fb_cell: invalid color spec: ", argv[6], ".", (char *)NULL); return TCL_ERROR; } pp = (unsigned char *)calloc(width*height, sizeof(RGBpixel)); for (i = 0; i < width*height*sizeof(RGBpixel); i+=sizeof(RGBpixel)) { pp[i] = pixel[0]; pp[i+1] = pixel[1]; pp[i+2] = pixel[2]; } fb_writerect(fbop->fbo_fbs.fbs_fbp, xmin, ymin, width, height, pp); free((void *)pp); return TCL_OK; }
/* * * Usage: * procname cell xmin ymin width height color */ HIDDEN int fbo_cell_tcl(void *clientData, int argc, const char **argv) { struct fb_obj *fbop = (struct fb_obj *)clientData; int xmin, ymin; long width; long height; size_t i; RGBpixel pixel; unsigned char *pp; if (argc != 7) { bu_log("ERROR: expecting seven arguments\n"); return BRLCAD_ERROR; } if (sscanf(argv[2], "%d", &xmin) != 1) { bu_log("fb_cell: bad xmin value - %s", argv[2]); return BRLCAD_ERROR; } if (sscanf(argv[3], "%d", &ymin) != 1) { bu_log("fb_cell: bad ymin value - %s", argv[3]); return BRLCAD_ERROR; } /* check coordinates */ if (!fbo_coords_ok(fbop->fbo_fbs.fbs_fbp, xmin, ymin)) { bu_log("fb_cell: coordinates (%s, %s) are invalid.", argv[2], argv[3]); return BRLCAD_ERROR; } if (sscanf(argv[4], "%ld", &width) != 1) { bu_log("fb_cell: bad width - %s", argv[4]); return BRLCAD_ERROR; } if (sscanf(argv[5], "%ld", &height) != 1) { bu_log("fb_cell: bad height - %s", argv[5]); return BRLCAD_ERROR; } /* check width and height */ if (width <=0 || height <=0) { bu_log("fb_cell: width and height must be > 0"); return BRLCAD_ERROR; } /* * Decompose the color list into its constituents. * For now must be in the form of rrr ggg bbb. */ if (fbo_tcllist2color(argv[6], pixel) == BRLCAD_ERROR) { bu_log("fb_cell: invalid color spec: %s", argv[6]); return BRLCAD_ERROR; } pp = (unsigned char *)bu_calloc(width*height, sizeof(RGBpixel), "allocate pixel array"); for (i = 0; i < width*height*sizeof(RGBpixel); i+=sizeof(RGBpixel)) { pp[i] = pixel[0]; pp[i+1] = pixel[1]; pp[i+2] = pixel[2]; } fb_writerect(fbop->fbo_fbs.fbs_fbp, xmin, ymin, width, height, pp); bu_free((void *)pp, "free pixel array"); return BRLCAD_OK; }
int main(int argc, char **argv) { int y; FBIO *fbp; int xout, yout, n, m, xstart, xskip; if (!get_args(argc, argv)) { (void)fputs(usage, stderr); bu_exit(1, NULL); } /* autosize input? */ if (fileinput && autosize) { size_t w, h; if (fb_common_file_size(&w, &h, file_name, 3)) { file_width = w; file_height = h; } else { fprintf(stderr, "pix-fb: unable to autosize\n"); } } /* If screen size was not set, track the file size */ if (scr_width == 0) scr_width = file_width; if (scr_height == 0) scr_height = file_height; if ((fbp = fb_open(framebuffer, scr_width, scr_height)) == NULL) { bu_exit(12, NULL); } /* Get the screen size we were given */ scr_width = fb_getwidth(fbp); scr_height = fb_getheight(fbp); /* compute number of pixels to be output to screen */ if (scr_xoff < 0) { xout = scr_width + scr_xoff; xskip = (-scr_xoff); xstart = 0; } else { xout = scr_width - scr_xoff; xskip = 0; xstart = scr_xoff; } if (xout < 0) bu_exit(0, NULL); /* off screen */ if ((size_t)xout > (file_width-file_xoff)) xout = (file_width-file_xoff); scanpix = xout; /* # pixels on scanline */ if (inverse) scr_yoff = (-scr_yoff); yout = scr_height - scr_yoff; if (yout < 0) bu_exit(0, NULL); /* off screen */ if ((size_t)yout > (file_height-file_yoff)) yout = (file_height-file_yoff); /* Only in the simplest case use multi-line writes */ if (!one_line_only && multiple_lines > 0 && !inverse && !zoom && (size_t)xout == file_width && file_width <= (size_t)scr_width) { scanpix *= multiple_lines; } scanbytes = scanpix * sizeof(RGBpixel); if ((scanline = (unsigned char *)malloc(scanbytes)) == RGBPIXEL_NULL) { fprintf(stderr, "pix-fb: malloc(%d) failure for scanline buffer\n", scanbytes); bu_exit(2, NULL); } if (clear) { fb_clear(fbp, PIXEL_NULL); } if (zoom) { /* Zoom in, and center the display. Use square zoom. */ int zoomit; zoomit = scr_width/xout; if (scr_height/yout < zoomit) zoomit = scr_height/yout; if (inverse) { fb_view(fbp, scr_xoff+xout/2, scr_height-1-(scr_yoff+yout/2), zoomit, zoomit); } else { fb_view(fbp, scr_xoff+xout/2, scr_yoff+yout/2, zoomit, zoomit); } } if (file_yoff != 0) skipbytes(infd, (off_t)file_yoff*(off_t)file_width*sizeof(RGBpixel)); if (multiple_lines) { /* Bottom to top with multi-line reads & writes */ unsigned long height; for (y = scr_yoff; y < scr_yoff + yout; y += multiple_lines) { n = bu_mread(infd, (char *)scanline, scanbytes); if (n <= 0) break; height = multiple_lines; if (n != scanbytes) { height = (n/sizeof(RGBpixel)+xout-1)/xout; if (height <= 0) break; } /* Don't over-write */ if ((size_t)(y + height) > (size_t)(scr_yoff + yout)) height = scr_yoff + yout - y; if (height <= 0) break; m = fb_writerect(fbp, scr_xoff, y, file_width, height, scanline); if ((size_t)m != file_width*height) { fprintf(stderr, "pix-fb: fb_writerect(x=%d, y=%d, w=%lu, h=%lu) failure, ret=%d, s/b=%d\n", scr_xoff, y, (unsigned long)file_width, height, m, scanbytes); } } } else if (!inverse) { /* Normal way -- bottom to top */ for (y = scr_yoff; y < scr_yoff + yout; y++) { if (y < 0 || y > scr_height) { skipbytes(infd, (off_t)file_width*sizeof(RGBpixel)); continue; } if (file_xoff+xskip != 0) skipbytes(infd, (off_t)(file_xoff+xskip)*sizeof(RGBpixel)); n = bu_mread(infd, (char *)scanline, scanbytes); if (n <= 0) break; m = fb_write(fbp, xstart, y, scanline, xout); if (m != xout) { fprintf(stderr, "pix-fb: fb_write(x=%d, y=%d, npix=%d) ret=%d, s/b=%d\n", scr_xoff, y, xout, m, xout); } /* slop at the end of the line? */ if ((size_t)file_xoff+xskip+scanpix < file_width) skipbytes(infd, (off_t)(file_width-file_xoff-xskip-scanpix)*sizeof(RGBpixel)); } } else { /* Inverse -- top to bottom */ for (y = scr_height-1-scr_yoff; y >= scr_height-scr_yoff-yout; y--) { if (y < 0 || y >= scr_height) { skipbytes(infd, (off_t)file_width*sizeof(RGBpixel)); continue; } if (file_xoff+xskip != 0) skipbytes(infd, (off_t)(file_xoff+xskip)*sizeof(RGBpixel)); n = bu_mread(infd, (char *)scanline, scanbytes); if (n <= 0) break; m = fb_write(fbp, xstart, y, scanline, xout); if (m != xout) { fprintf(stderr, "pix-fb: fb_write(x=%d, y=%d, npix=%d) ret=%d, s/b=%d\n", scr_xoff, y, xout, m, xout); } /* slop at the end of the line? */ if ((size_t)file_xoff+xskip+scanpix < file_width) skipbytes(infd, (off_t)(file_width-file_xoff-xskip-scanpix)*sizeof(RGBpixel)); } } sleep(pause_sec); if (fb_close(fbp) < 0) { fprintf(stderr, "pix-fb: Warning: fb_close() error\n"); } return 0; }