void mk_ramp(FBIO *fb, int r, int g, int b, int n) { /* grey ramp */ for (x=0; x < scr_width; ++x) { if (r) line[x*3] = rampval[x / patch_width + 1]; else line[x*3] = 0; if (g) line[x*3+1] = rampval[x / patch_width + 1]; else line[x*3+1] = 0; if (b) line[x*3+2] = rampval[x / patch_width + 1]; else line[x*3+2] = 0; } for (y=patch_height*n; y < patch_height*(n+1) && y < scr_height; ++y) { fb_write(fb, 0, y, line, scr_width); } for (x=0; x < scr_width; ++x) { if (r) line[x*3] = rampval[x / patch_width]; else line[x*3] = 0; if (g) line[x*3+1] = rampval[x / patch_width]; else line[x*3+1] = 0; if (b) line[x*3+2] = rampval[x / patch_width]; else line[x*3+2] = 0; } for (y=patch_height*(n+1); y < patch_height*(n+2) && y < scr_height; y += 2) { fb_write(fb, 0, y, altline, scr_width); fb_write(fb, 0, y+1, line, scr_width); } }
/* * OutBuild - rasterize all strokes into raster frame image */ static bool OutBuild(void) /* returns true if successful */ { register struct band *hp; /* *hp -> head of descr list */ register struct band *np; /* `hp' for next band */ register stroke *vp; /* -> rasterization descr */ if ( single_banded ) { if ( debug ) fprintf(stderr, "OutBuild: band y=%d\n", ystart); if ( fb_write( fbp, 0, ystart, buffer, buffersize/sizeof(RGBpixel) ) <= 0 ) return false; /* can't write image file */ if ( over ) { /* Read back the composite image */ if ( fb_read( fbp, 0, ystart, buffer, buffersize/sizeof(RGBpixel) ) <= 0 ) fprintf(stderr, "pl-fb: band read error\n"); } return true; } for ( hp = &band[0]; hp < bandEnd; ++hp ) if ( hp->first != NULL ) break; if ( hp == bandEnd ) return true; /* nothing to do */ for ( hp = &band[0], np = &band[1], ystart = 0; hp < bandEnd; hp = np++, ystart += lines_per_band ) { if (debug) fprintf(stderr, "OutBuild: band y=%d\n", ystart); if ( over ) { /* Read in current band */ if ( fb_read( fbp, 0, ystart, buffer, buffersize/sizeof(RGBpixel) ) <= 0 ) fprintf(stderr, "pl-fb: band read error\n"); } else { /* clear pixels in the band */ memset((char *)buffer, 0, buffersize); } while ( (vp = Dequeue( hp, &hp->first )) != NULL ) Raster( vp, np ); /* rasterize stroke */ /* Raster() either re-queued the descriptor onto the next band list or else it freed the descriptor */ if (debug) fprintf(stderr, "OutBuild: fbwrite y=%d\n", ystart); if ( fb_write( fbp, 0, ystart, buffer, buffersize/sizeof(RGBpixel) ) <= 0 ) return false; /* can't write image file */ } return true; /* success */ }
/** repeatText: * Just prints a string of chars to the fb repeatedly, * with a time waster to ensure all text doesn't immediately * appear (for testing scrolling). * Prints newlines first, then no newlines. */ void repeatText() { char test[] = "CirnOS is the strongest OS. \n"; unsigned int i = 0; for(;i < 40; i++) { fb_write(test, 29); //waste time loop(1233356); } i = 0; for(;i < 40; i++) { fb_write(test, 28); //waste time loop(1233356); } }
/* * Display the array v[Y][X] at screen location xoff, yoff. */ void disp_array(long int (*v)[256], int xoff, int yoff) { register int x, y; static long max; static double scale; unsigned char obuf[256*3]; /* Find max value */ max = 0; for ( y = 0; y < 256; y++ ) { for ( x = 0; x < 256; x++ ) { if ( v[y][x] > max ) max = v[y][x]; } } scale = 255.0 / ((double)max); /* plot them */ for ( y = 0; y < 256; y++ ) { for ( x = 0; x < 256; x++ ) { register int value; value = v[y][x] * scale; if ( value < THRESH && v[y][x] != 0 ) value = THRESH; obuf[x*3+RED] = obuf[x*3+GRN] = obuf[x*3+BLU] = value; } fb_write( fbp, xoff, yoff+y, obuf, 256 ); } }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { unsigned char FB[]="MESSAGE WRITTEN THROUGH FRAMEBUFFER!!"; fb_init(); // initialize framebuffer device (2015.11.02) cprintf("\nUsing Framebuffer still presents some problems :(\n\n"); cprintf("\nSuggestion: review the way it is used in console.c\n\n"); fb_write(FB, sizeof(FB)); // Framebuffer maybe could be used before this moment (2015.11.02) see_mylock(MYLOCK); kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process // Finish setting up this processor in mpmain. mpmain(); }
static void PutPixel(register int value) { if ( pass == stop ) Fatal(fbp, "Too much raster data for image size" ); if ( value > entries ) Fatal(fbp, "Decoded color index %d exceeds color map size", value ); pixbuf[col*3+RED] = cmap[value][RED]; /* stuff pixel */ pixbuf[col*3+GRN] = cmap[value][GRN]; pixbuf[col*3+BLU] = cmap[value][BLU]; if ( ++col == right ) { /* Note that BRL-CAD frame buffers are upside-down. The following produces a right-side-up image at the bottom of the available frame buffer. */ if ( fb_write( fbp, 0, ht - row, pixbuf, write_width ) < 0 ) Message( "Error writing scan line to frame buffer" ); col = left; if ( (row += step[pass]) >= bottom && ++pass < stop ) row = start_row[pass]; } }
void display() { int image = 0; tty_printf(" !!! Processor %d running !!!\n", procid()); while(image < NIMAGES) { while( buf_out_empty == TRUE ) {} // synchro tty_printf("\n *** starting display for image %d at cycle %d\n", image, proctime()); if ( fb_write(0, buf_out, NLINES*NPIXELS) ) { tty_printf("echec fb_sync_write\n"); exit(); } else { tty_printf("*** success fb_write ***\n"); } if ( fb_completed() ) { tty_printf("echec fb_completed\n"); exit(); } buf_out_empty = TRUE; tty_printf(" *** completing display for image %d at cycle %d\n", image, proctime()); image++; } // end while image exit(); } // end display
//main entry point for the kernel int kmain() { setup_Com1(); char doneText[] = "Done.\n"; clearScreen(); //clear the screen of whatever was there //print welcome message char osVersion[] = "CirnOS v0.0.1\n"; fb_write(osVersion, 14); //set up the GDT table char gdtSetup[] = "Setting up GDT...\n"; fb_write(gdtSetup, 18); setupGDT(); fb_write(doneText, 6); //set up IDT table char idtSetup[] = "Setting up IDT...\n"; fb_write(idtSetup, 18); setupIDT(); fb_write(doneText, 6); //Program Pic char picSetup[] = "Programming PIC...\n"; fb_write(picSetup, 19); program_pic(); fb_write(doneText, 6); char pagingSetup[] = "Setup PDT (identity, 4MB pages) and enabling paging...\n"; fb_write(pagingSetup, 100); setup_pdt_enable_paging(); fb_write(doneText, 6); char testStart[] = "Begining print tests.\n"; fb_write(testStart, 22); //setup and write to Com1 serial port serial_write(osVersion, 14); serial_write(testStart, 21); char printfTest[] = "Printf test string: %c, %c, %d, %x.\n"; printf(SERIAL, printfTest, 'c', 'd', -30, 0xCAFEBABE); printf(FRAMEBUFFER, printfTest, 'c', 'd', -30, 0xCAFEBABE); //repeatText(); //repeat some dummy text return 0; //return value will be in EAX register, return 0 for now }
// Write a positive decimal integer to the screen. void fb_putui(unsigned int i) { if (i == 0) { fb_putc('0'); return; } char c[32]; itoa(i,c); fb_write(c); }
void paintCellFb(struct application *ap, unsigned char *pixpaint, unsigned char *pixexpendable) { int gx, gy; int gyfin, gxfin; int gxorg, gyorg; int x, y; int cnt; #if DEBUG_CELLFB brst_log("paintCellFb: expendable {%d, %d, %d}\n", pixexpendable[RED], pixexpendable[GRN], pixexpendable[BLU]); #endif gridToFb(ap->a_x, ap->a_y, &gx, &gy); gxorg = gx+1; gyorg = gy+1; gxfin = zoom == 1 ? gx+zoom+1 : gx+zoom; gyfin = zoom == 1 ? gy+zoom+1 : gy+zoom; cnt = gxfin - gxorg; for (y = gyorg; y < gyfin; y++) { if (zoom != 1 && (y - gy) % zoom == 0) continue; bu_semaphore_acquire(RT_SEM_STATS); (void) fb_read(fbiop, gxorg, y, (unsigned char *)pixbuf, cnt); bu_semaphore_release(RT_SEM_STATS); for (x = gxorg; x < gxfin; x++) { if (SAMERGB(&pixbuf[x-gxorg][0], pixexpendable) ) { #if DEBUG_CELLFB brst_log("Clobbering:<%d, %d>{%d, %d, %d}\n", x, y, pixbuf[x-gxorg][RED], pixbuf[x-gxorg][GRN], pixbuf[x-gxorg][BLU]); #endif COPYRGB(&pixbuf[x-gxorg][0], pixpaint); } #if DEBUG_CELLFB else brst_log("Preserving:<%d, %d>{%d, %d, %d}\n", x, y, pixbuf[x-gxorg][RED], pixbuf[x-gxorg][GRN], pixbuf[x-gxorg][BLU]); #endif } bu_semaphore_acquire(RT_SEM_STATS); (void) fb_write(fbiop, gxorg, y, (unsigned char *)pixbuf, cnt); bu_semaphore_release(RT_SEM_STATS); #if DEBUG_CELLFB brst_log("paintCellFb: fb_write(%d, %d)\n", x, y); #endif } return; }
void paintGridFb() { int fx, fy; int fxbeg, fybeg; int fxfin, fyfin; int fxorg, fyorg; int fgridwid; if (fb_clear(fbiop, pixbkgr) == -1) return; gridxmargin = (devwid - (gridwidth*zoom)) / 2.0; gridymargin = (devhgt - (gridheight*zoom)) / 2.0; gridToFb(gridxorg, gridyorg, &fxbeg, &fybeg); gridToFb(gridxfin+1, gridyfin+1, &fxfin, &fyfin); gridToFb(0, 0, &fxorg, &fyorg); CenterCell(fxorg); /* center of cell */ CenterCell(fyorg); if (zoom == 1) { fgridwid = gridwidth + 2; fxfin++; } else fgridwid = gridwidth * zoom + 1; /* draw vertical lines */ for (fx = 1; fx < fgridwid; fx++) COPYRGB(&pixbuf[fx][0], pixbkgr); for (fx = fxbeg; fx <= fxfin; fx += zoom) COPYRGB(&pixbuf[fx-fxbeg][0], &pixgrid[0]); for (fy = fybeg; fy <= fyfin; fy++) (void) fb_write(fbiop, fxbeg, fy, (unsigned char *)pixbuf, fgridwid); for (fy = 0; fy < devwid; fy++) (void) fb_write(fbiop, fxorg, fy, pixaxis, 1); /* draw horizontal lines */ if (zoom > 1) for (fy = fybeg; fy <= fyfin; fy += zoom) (void) fb_write(fbiop, fxbeg, fy, pixgrid, fgridwid); for (fx = 0; fx < devwid; fx++) COPYRGB(&pixbuf[fx][0], pixaxis); (void) fb_write(fbiop, 0, fyorg, (unsigned char *)pixbuf, devwid); return; }
/* * Set/get the pixel value at position (x, y). * * Usage: * procname pixel x y [rgb] */ HIDDEN int fbo_pixel_tcl(void *clientData, int argc, const char **argv) { struct fb_obj *fbop = (struct fb_obj *)clientData; struct bu_vls vls = BU_VLS_INIT_ZERO; int x, y; /* pixel position */ RGBpixel pixel; if (argc != 4 && argc != 5) { bu_log("ERROR: expecting five arguments\n"); return BRLCAD_ERROR; } /* get pixel position */ if (sscanf(argv[2], "%d", &x) != 1) { bu_log("fb_pixel: bad x value - %s", argv[2]); return BRLCAD_ERROR; } if (sscanf(argv[3], "%d", &y) != 1) { bu_log("fb_pixel: bad y value - %s", argv[3]); return BRLCAD_ERROR; } /* check pixel position */ if (!fbo_coords_ok(fbop->fbo_fbs.fbs_fbp, x, y)) { bu_log("fb_pixel: coordinates (%s, %s) are invalid.", argv[2], argv[3]); return BRLCAD_ERROR; } /* get pixel value */ if (argc == 4) { fb_rpixel(fbop->fbo_fbs.fbs_fbp, pixel); bu_vls_printf(&vls, "%d %d %d", pixel[RED], pixel[GRN], pixel[BLU]); Tcl_AppendResult(fbop->fbo_interp, bu_vls_addr(&vls), (char *)NULL); bu_vls_free(&vls); return BRLCAD_OK; } /* * Decompose the color list into its constituents. * For now must be in the form of rrr ggg bbb. */ /* set pixel value */ if (fbo_tcllist2color(argv[4], pixel) == BRLCAD_ERROR) { bu_log("fb_pixel: invalid color spec - %s", argv[4]); return BRLCAD_ERROR; } fb_write(fbop->fbo_fbs.fbs_fbp, x, y, pixel, 1); return BRLCAD_OK; }
static int fb_write_buffer(const uint8 *data, int len, int xlat) { int rv = len; (void)xlat; while(len--) { fb_write((int)(*data++)); } return rv; }
/* * V I E W _ E O L * * Called by worker() at the end of each line. Depricated. * Any end-of-line processing should be done in view_pixel(). */ void view_eol(register struct application *ap) { bu_semaphore_acquire( BU_SEM_SYSCALL ); if ( outfp != NULL ) fwrite( scanbuf, 1, width, outfp ); #if 0 else if ( fbp != FBIO_NULL ) fb_write( fbp, 0, ap->a_y, scanbuf, width ); #endif bu_semaphore_release( BU_SEM_SYSCALL ); }
void kmain() { char bing[34] = "wowowow"; char bong[50] = "JEJEJEJEJEJ"; gdttable.address = (unsigned int)gdt_entries; gdttable.size = 24; load_gdt_entries(); ggdt((unsigned int)&gdttable); serial_write(bong, SERIAL_COM1_BASE); fb_write(bing); }
__attribute__((constructor)) void display() { char byte; char buf[NB_LINES][NB_PIXELS]; int base = 0; int image = 0; int npixels; // number of pixels per processor int nblocks; // number of blocks per processor npixels = NB_PIXELS*NB_LINES; nblocks = npixels/BLOCK_SIZE; // main loop while(1) { tty_printf("\n *** image %d au cycle : %d *** \n", image, proctime()); /* Phase 1 : lecture image sur le disque et transfert vers buf */ if (ioc_read(base + nblocks, buf , nblocks)) { tty_printf("\n!!! echec ioc_read au cycle : %d !!!\n", proctime()); exit(); } if ( ioc_completed() ) { tty_printf("\n!!! echec ioc_completed au cycle : %d !!!\n", proctime()); exit(); } tty_printf("- image chargee au cycle = %d \n",proctime()); tty_printf("test\n"); /* Phase 3 : transfert de buf vers le frame buffer */ if (fb_write(0, buf, sizeof(buf))) { tty_printf("\n!!! echec fb_write au cycle : %d !!!\n", proctime()); exit(); } fb_completed(); tty_printf("- image affichee au cycle = %d \n",proctime()); base = base + nblocks; image = image + 1; tty_getc_irq(&byte); if (base == 640) base =0; } // end while exit(); } // end main
/* * Raster - rasterize stroke. * * If immediate mode, draw the individual pixel on the frame buffer. * If banded buffered mode, draw the portion in this band. If it * overflows into next band, requeue; else free the descriptor. * * Method: * Modified Bresenham algorithm. Guaranteed to mark a dot for * a zero-length stroke. Please do not try to "improve" this code * as it is extremely hard to get all aspects just right. */ static void Raster(register stroke *vp, register struct band *np) /* -> rasterization descr */ /* *np -> next band 1st descr */ { register short dy; /* raster within active band */ CK_STROKE(vp); /* * Draw the portion within this band. */ for ( dy = vp->pixel.y - ystart; dy < lines_per_band; ) { /* set the appropriate pixel in the buffer */ if ( immediate ) { fb_write( fbp, vp->pixel.x, dy, vp->col, 1 ); } else { register unsigned char *pp; pp = (unsigned char *)&buffer[((dy*Npixels) + vp->pixel.x)*sizeof(RGBpixel)]; COPYRGB( pp, vp->col ); } if ( vp->major-- == 0 ) { /* done! */ FREE_STROKE( vp ); /* return to "malloc" */ return; } if ( vp->e < 0 ) { /* advance major & minor */ dy += vp->ysign; vp->pixel.x += vp->xsign; vp->e += vp->de; } else { /* advance major only */ if ( vp->ymajor ) /* Y is major dir */ ++dy; else /* X is major dir */ vp->pixel.x += vp->xsign; vp->e -= vp->minor; } } /* overflow into next band; re-queue */ vp->pixel.y = ystart + lines_per_band; Requeue( np, vp ); /* DDA parameters already set */ }
/* * A routine to simulate the effect of fb_writerect() when a * particular display does not handle it. * * Returns number of pixels actually written. * Clipping to the screen may reduce the total if caller was sloppy. */ int fb_sim_writerect(FBIO *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp) { register int y; register int tot; int got; size_t xlen; xlen = width; if (xmin + width > fb_getwidth(ifp)) xlen = fb_getwidth(ifp) - xmin; tot = 0; for (y=ymin; y < ymin+height; y++) { got = fb_write(ifp, xmin, y, pp, xlen); tot += got; if (got != (int)xlen) break; pp += width * sizeof(RGBpixel); } return tot; }
HIDDEN ssize_t mem_write(FBIO *ifp, int x, int y, const unsigned char *pixelp, size_t count) { size_t pixels_to_end; if (x < 0 || x >= ifp->if_width || y < 0 || y >= ifp->if_height) return -1; /* make sure we don't run off the end of the buffer */ pixels_to_end = ifp->if_width*ifp->if_height - (y*ifp->if_width + x); if (pixels_to_end < count) count = pixels_to_end; memcpy(&(MI(ifp)->mem[(y*ifp->if_width + x)*3]), (char *)pixelp, count*3); if (MI(ifp)->write_thru) { return fb_write(MI(ifp)->fbp, x, y, pixelp, count); } else { MI(ifp)->mem_dirty = 1; } return count; }
void paintSpallFb(struct application *ap) { unsigned char pixel[3]; int x, y; int err; fastf_t celldist; #if DEBUG_SPALLFB brst_log("paintSpallFb: a_x=%d a_y=%d a_cumlen=%g cellsz=%g zoom=%d\n", ap->a_x, ap->a_y, ap->a_cumlen, cellsz, zoom); #endif pixel[RED] = ap->a_color[RED] * 255; pixel[GRN] = ap->a_color[GRN] * 255; pixel[BLU] = ap->a_color[BLU] * 255; gridToFb(ap->a_x, ap->a_y, &x, &y); CenterCell(x); /* center of cell */ CenterCell(y); celldist = ap->a_cumlen/cellsz * zoom; x = roundToInt(x + VDOT(ap->a_ray.r_dir, gridhor) * celldist); y = roundToInt(y + VDOT(ap->a_ray.r_dir, gridver) * celldist); bu_semaphore_acquire(RT_SEM_STATS); err = fb_write(fbiop, x, y, pixel, 1); bu_semaphore_release(RT_SEM_STATS); #if DEBUG_SPALLFB brst_log("paintSpallFb:gridhor=<%g, %g, %g> gridver=<%g, %g, %g>\n", gridhor[X], gridhor[Y], gridhor[Z], gridver[X], gridver[Y], gridver[Z]); brst_log("paintSpallFb:fb_write(x=%d, y=%d, pixel={%d, %d, %d})\n", x, y, (int) pixel[RED], (int) pixel[GRN], (int) pixel[BLU] ); #endif if (err == -1) brst_log("Write failed to pixel <%d, %d> from cell <%d, %d>.\n", x, y, ap->a_x, ap->a_y); return; }
int fb_sim_bwwriterect(FBIO *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp) { register int y; register int tot; int got; size_t xlen; unsigned char buf[SIMBUF_SIZE]; if (width > SIMBUF_SIZE) { fb_log("fb_sim_bwwriterect() width of %d exceeds internal buffer, aborting\n", width); return -SIMBUF_SIZE; /* FAIL */ } xlen = width; if (xmin + width > fb_getwidth(ifp)) xlen = fb_getwidth(ifp) - xmin; tot = 0; for (y=ymin; y < ymin+height; y++) { register int x; register unsigned char *bp; /* Copy monochrome (b&w) intensity into all three chans */ bp = buf; for (x=0; x < width; x++) { register unsigned char c = *pp++; bp[0] = c; bp[1] = c; bp[2] = c; bp += 3; } got = fb_write(ifp, xmin, y, buf, xlen); tot += got; if (got != (int)xlen) break; } return tot; }
int _fb_pgout(register FBIO *ifp) { int scans, first_scan; /*fb_log( "_fb_pgout(%d)\n", ifp->if_pno );*/ if ( ifp->if_pno < 0 ) /* Already paged out, return 1. */ return 1; first_scan = ifp->if_pno * PAGE_SCANS; if ( first_scan + PAGE_SCANS > ifp->if_height ) scans = ifp->if_height - first_scan; else scans = PAGE_SCANS; return fb_write( ifp, 0, first_scan, ifp->if_pbase, scans * ifp->if_width ); }
/* * * Usage: * procname cell xmin ymin width height color */ HIDDEN int fbo_rect_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 xmax, ymax; int width; int height; int i; RGBpixel pixel; if (argc != 7) { bu_vls_init(&vls); bu_vls_printf(&vls, "helplib fb_rect"); 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_rect: bad xmin value - ", argv[2], (char *)NULL); return TCL_ERROR; } if (sscanf(argv[3], "%d", &ymin) != 1) { Tcl_AppendResult(interp, "fb_rect: 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_rect: coordinates (", argv[2], ", ", argv[3], ") are invalid.", (char *)NULL); return TCL_ERROR; } if (sscanf(argv[4], "%d", &width) != 1) { Tcl_AppendResult(interp, "fb_rect: bad width - ", argv[4], (char *)NULL); return TCL_ERROR; } if (sscanf(argv[5], "%d", &height) != 1) { Tcl_AppendResult(interp, "fb_rect: bad height - ", argv[5], (char *)NULL); return TCL_ERROR; } /* check width and height */ if (width <=0 || height <=0) { Tcl_AppendResult(interp, "fb_rect: 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_rect: invalid color spec: ", argv[6], ".", (char *)NULL); return TCL_ERROR; } xmax = xmin + width; ymax = ymin + height; /* draw horizontal lines */ for (i = xmin; i <= xmax; ++i) { /* working on bottom line */ fb_write(fbop->fbo_fbs.fbs_fbp, i, ymin, pixel, 1); /* working on top line */ fb_write(fbop->fbo_fbs.fbs_fbp, i, ymax, pixel, 1); } /* draw vertical lines */ for (i = ymin; i <= ymax; ++i) { /* working on left line */ fb_write(fbop->fbo_fbs.fbs_fbp, xmin, i, pixel, 1); /* working on right line */ fb_write(fbop->fbo_fbs.fbs_fbp, xmax, i, pixel, 1); } return TCL_OK; }
/* * Set/get the pixel value at position (x, y). * * Usage: * procname pixel x y [rgb] */ HIDDEN int fbo_pixel_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { struct fb_obj *fbop = (struct fb_obj *)clientData; struct bu_vls vls; int x, y; /* pixel position */ RGBpixel pixel; if (argc < 4) goto error; /* get pixel position */ if (sscanf(argv[2], "%d", &x) != 1) { Tcl_AppendResult(interp, "fb_pixel: bad x value - ", argv[2], (char *)NULL); return TCL_ERROR; } if (sscanf(argv[3], "%d", &y) != 1) { Tcl_AppendResult(interp, "fb_pixel: bad y value - ", argv[3], (char *)NULL); return TCL_ERROR; } /* check pixel position */ if (!fbo_coords_ok(interp, fbop->fbo_fbs.fbs_fbp, x, y)) { Tcl_AppendResult(interp, "fb_pixel: coordinates (", argv[2], ", ", argv[3], ") are invalid.", (char *)NULL); return TCL_ERROR; } /* get pixel value */ if (argc == 4) { fb_rpixel(fbop->fbo_fbs.fbs_fbp, pixel); bu_vls_init(&vls); bu_vls_printf(&vls, "%d %d %d", pixel[RED], pixel[GRN], pixel[BLU]); Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL); bu_vls_free(&vls); return TCL_OK; } /* set pixel value */ if (argc == 5) { /* * Decompose the color list into its constituents. * For now must be in the form of rrr ggg bbb. */ if (fbo_tcllist2color(interp, argv[4], pixel) == TCL_ERROR) { Tcl_AppendResult(interp, "fb_pixel: invalid color spec - ", argv[4], ".", (char *)NULL); return TCL_ERROR; } fb_write(fbop->fbo_fbs.fbs_fbp, x, y, pixel, 1); return TCL_OK; } error: bu_vls_init(&vls); bu_vls_printf(&vls, "helplib fb_pixel"); Tcl_Eval(interp, bu_vls_addr(&vls)); bu_vls_free(&vls); return TCL_ERROR; }
static bool_t display_Cells(long int ncells) { Cell *gp, *ep = &grid[ncells]; static int zoom; unsigned char *buf; static RGBpixel pixel; double lasty = -INFINITY; double dx, dy; int y_0 = 0, y_1; if (compute_fb_height) { dy = ((ymax - ymin) / cell_size + 1.0) * (hgt + grid_flag); if (compute_fb_height == SNUG_FIT) fb_height = dy + (key_flag * 2 * hgt) + yorigin; else if (dy > LORES) /* LOOSE_FIT */ fb_height = HIRES; else fb_height = LORES; } if (compute_fb_width) { dx = ((xmax - xmin) / cell_size + 1.0) * (wid + grid_flag); if (compute_fb_width == SNUG_FIT) fb_width = dx + xorigin; else if (dx > LORES) /* LOOSE_FIT */ fb_width = HIRES; else fb_width = LORES; } zoom = 1; fbiop = fb_open((fbfile[0] != '\0') ? fbfile : NULL, fb_width, fb_height); if (fbiop == FB_NULL) return 0; if (compute_fb_height || compute_fb_width) { bu_log("fb_size requested: %d %d\n", fb_width, fb_height); fb_width = fb_getwidth(fbiop); fb_height = fb_getheight(fbiop); bu_log("fb_size obtained: %d %d\n", fb_width, fb_height); } if (fb_wmap(fbiop, COLORMAP_NULL) == -1) bu_log("Cannot initialize color map\n"); if (fb_zoom(fbiop, zoom, zoom) == -1) bu_log("Cannot set zoom <%d, %d>\n", zoom, zoom); if (erase_flag && fb_clear(fbiop, BACKGROUND) == -1) bu_log("Cannot clear frame buffer\n"); buf = (unsigned char *) bu_malloc(sizeof(RGBpixel) * fb_width, "line of frame buffer"); if (debug_flag & CFB_DBG_MEM) bu_log("buf = %p... %d pixels @ %lu bytes/pixel\n", (void *)buf, fb_width, sizeof(RGBpixel)); for (gp = grid; gp < ep; gp++) { int x0, x1; /* Whenever Y changes, write out row of cells. */ if (!ZERO(lasty - gp->c_y)) { /* If first time, nothing to write out. */ if (!ZERO(lasty - INFINITY)) { if (debug_flag & CFB_DBG_GRID) bu_log("%g = V2SCRY(%g)\n", V2SCRY(lasty), lasty); y_0 = V2SCRY(lasty); if (y_0 >= 0 && y_0 < fb_height) { for (y_1 = y_0 + hgt; y_0 < y_1; y_0++) if (fb_write(fbiop, 0, y_0, buf, fb_width) == -1) { bu_log("Couldn't write to <%d, %d>\n", 0, y_0); (void) fb_close(fbiop); return 0; } } } /* Clear buffer. */ for (x0 = 0; x0 < fb_width; x0++) { COPYRGB(&buf[3*x0], BACKGROUND); } /* Draw grid line between rows of cells. */ if (grid_flag && !ZERO(lasty - INFINITY)) { if (fb_write(fbiop, 0, y_0, buf, fb_width) == -1) { bu_log("Couldn't write to <%d, %d>\n", 0, y_0); (void) fb_close(fbiop); return 0; } if (debug_flag & CFB_DBG_GRID) bu_log("Writing grid row at %d\n", y_0); } lasty = gp->c_y; } val_To_RGB(gp->c_val, pixel); /* Be careful only to write color within bounds of the screen */ x0 = H2SCRX(gp->c_x); if (x0 >= 0 && x0 <= fb_width - wid) { for (x1 = x0 + wid; x0 < x1; x0++) { COPYRGB(&buf[3*x0], pixel); } } } /* Write out last row of cells. */ if (debug_flag & CFB_DBG_GRID) bu_log("%g = V2SCRY(%g)\n", V2SCRY(lasty), lasty); for (y_0 = V2SCRY(lasty), y_1 = y_0 + hgt; y_0 < y_1; y_0++) if (fb_write(fbiop, 0, y_0, buf, fb_width) == -1) { bu_log("Couldn't write to <%d, %d>\n", 0, y_0); (void) fb_close(fbiop); return 0; } /* Draw color key. */ if (key_flag && (fb_width < (10 + 1) * wid)) bu_log("Width of key (%d) would exceed frame-buffer width (%d)\n", (10 + 1) * wid, fb_width); else if (key_flag) { int i, j; double base; int scr_min, scr_max; int scr_center; /* screen coord of center of view */ int center_cell; /* cell # of center of view */ /* Clear buffer. */ for (i = 0; i < fb_width; i++) { COPYRGB(&buf[3*i], BACKGROUND); } /* Center the color key from side-to-side in the viewport. * Find screen coords of min and max vals, clip to (0, fb_width). * If there are fewer than 11 cells, the run the key * from the left edge to beyond the right edge. */ scr_min = H2SCRX(xmin); scr_max = H2SCRX(xmax); CLAMP(scr_min, 0, fb_width); CLAMP(scr_max, 0, fb_width); scr_center = (scr_max + scr_min)/2; if ((center_cell = VPX2CX(SCRX2VPX(scr_center))) < 5) center_cell = 5; /* Draw 10 cells for the color key */ dom_cvt = 10.0; for (i = 0; i <= 10; i++) { cell_val cv; /* * Determine where to start the key, * being careful not to back up beyond the beginning of buf. */ base = VPX2SCRX(CX2VPX(center_cell - 10/2 + i)); cv.v_scalar = i / 10.0; val_To_RGB(cv, pixel); for (j = 0; j < wid; j++) { int idx = base + j; COPYRGB(&buf[3*idx], pixel); } } dom_cvt = 10.0 / (dom_max - dom_min); for (i = yorigin; i < yorigin+hgt; i++) if (fb_write(fbiop, 0, i, buf, fb_width) == -1) { bu_log("Couldn't write to <%d, %d>\n", 0, i); (void) fb_close(fbiop); return 0; } } (void) fb_close(fbiop); bu_free((char *) buf, "line of frame buffer"); if (debug_flag & CFB_DBG_MEM) bu_log("freed buf, which is now %p\n", (void *)buf); return 1; }
/** * action performed at the end of each scanline */ void view_eol(struct application *ap) { int cpu = ap->a_resource->re_cpu; int i; if (overlay) { /* * Overlay mode. Check if the pixel is an edge. If so, write * it to the framebuffer. */ for (i = 0; i < per_processor_chunk; ++i) { if (writeable[cpu][i]) { /* * Write this pixel */ bu_semaphore_acquire(BU_SEM_SYSCALL); fb_write(fbp, i, ap->a_y, &scanline[cpu][i*3], 1); bu_semaphore_release(BU_SEM_SYSCALL); } } return; } else if (blend) { /* * Blend mode. * * Read a line from the existing framebuffer, convert to HSV, * manipulate, and put the results in the scanline as RGB. */ int replace_down = 0; /* flag that specifies if the pixel in the * scanline below must be replaced. */ RGBpixel rgb; fastf_t hsv[3]; bu_semaphore_acquire(BU_SEM_SYSCALL); if (fb_read(fbp, 0, ap->a_y, blendline[cpu], per_processor_chunk) < 0) bu_exit(EXIT_FAILURE, "rtedge: error reading from framebuffer.\n"); bu_semaphore_release(BU_SEM_SYSCALL); for (i = 0; i < per_processor_chunk; ++i) { /* * Is this pixel an edge? */ if (writeable[cpu][i]) { /* * The pixel is an edge, retrieve the appropriate * pixel from the line buffer and convert it to HSV. */ rgb[RED] = blendline[cpu][i*3+RED]; rgb[GRN] = blendline[cpu][i*3+GRN]; rgb[BLU] = blendline[cpu][i*3+BLU]; /* * Is the pixel in the blendline array the background * color? If so, look left and down to determine which * pixel is the "source" of the edge. Unless, of * course, we are on the bottom scanline or the * leftmost column (x=y=0) */ if (i != 0 && ap->a_y != 0 && !diffpixel(rgb, fb_bg_color)) { RGBpixel left; RGBpixel down; left[RED] = blendline[cpu][(i-1)*3+RED]; left[GRN] = blendline[cpu][(i-1)*3+GRN]; left[BLU] = blendline[cpu][(i-1)*3+BLU]; bu_semaphore_acquire(BU_SEM_SYSCALL); fb_read(fbp, i, ap->a_y - 1, down, 1); bu_semaphore_release(BU_SEM_SYSCALL); if (diffpixel(left, fb_bg_color)) { /* * Use this one. */ rgb[RED] = left[RED]; rgb[GRN] = left[GRN]; rgb[BLU] = left[BLU]; } else if (diffpixel(down, fb_bg_color)) { /* * Use the pixel from the scanline below */ replace_down = 1; rgb[RED] = down[RED]; rgb[GRN] = down[GRN]; rgb[BLU] = down[BLU]; } } /* * Convert to HSV */ bu_rgb_to_hsv(rgb, hsv); /* * Now perform the manipulations. */ hsv[VAL] *= 3.0; hsv[SAT] /= 3.0; if (hsv[VAL] > 1.0) { fastf_t d = hsv[VAL] - 1.0; hsv[VAL] = 1.0; hsv[SAT] -= d; hsv[SAT] = hsv[SAT] >= 0.0 ? hsv[SAT] : 0.0; } /* * Convert back to RGB. */ bu_hsv_to_rgb(hsv, rgb); if (replace_down) { /* * Write this pixel immediately, do not put it * into the blendline since it corresponds to the * wrong scanline. */ bu_semaphore_acquire(BU_SEM_SYSCALL); fb_write(fbp, i, ap->a_y, rgb, 1); bu_semaphore_release(BU_SEM_SYSCALL); replace_down = 0; } else { /* * Put this pixel back into the blendline array. * We'll push it to the buffer when the entire * scanline has been processed. */ blendline[cpu][i*3+RED] = rgb[RED]; blendline[cpu][i*3+GRN] = rgb[GRN]; blendline[cpu][i*3+BLU] = rgb[BLU]; } } /* end "if this pixel is an edge" */ } /* end pixel loop */ /* * Write the blendline to the framebuffer. */ bu_semaphore_acquire(BU_SEM_SYSCALL); fb_write(fbp, 0, ap->a_y, blendline[cpu], per_processor_chunk); bu_semaphore_release(BU_SEM_SYSCALL); return; } /* end blend */ if (fbp != FBIO_NULL) { /* * Simple whole scanline write to a framebuffer. */ bu_semaphore_acquire(BU_SEM_SYSCALL); fb_write(fbp, 0, ap->a_y, scanline[cpu], per_processor_chunk); bu_semaphore_release(BU_SEM_SYSCALL); } if (outputfile != NULL) { /* * Write to a file. */ bu_semaphore_acquire(BU_SEM_SYSCALL); /* TODO : Add double type data to maintain resolution */ icv_writeline(bif, ap->a_y, scanline[cpu], ICV_DATA_UCHAR); bu_semaphore_release(BU_SEM_SYSCALL); } if (fbp == FBIO_NULL && outputfile == NULL) bu_log("rtedge: strange, no end of line actions taken.\n"); return; }
HIDDEN void do_Char(int c, int xpos, int ypos, int odd) { register int i, j; int base; int totwid = font.width; int down; static float resbuf[FONTBUFSZ]; static RGBpixel fbline[FONTBUFSZ]; #if DEBUG_STRINGS fb_log( "do_Char: c='%c' xpos=%d ypos=%d odd=%d\n", c, xpos, ypos, odd ); #endif /* read in character bit map, with two blank lines on each end */ for (i = 0; i < 2; i++) clear_buf (totwid, filterbuf[i]); for (i = font.height + 1; i >= 2; i--) fill_buf (font.width, filterbuf[i]); for (i = font.height + 2; i < font.height + 4; i++) clear_buf (totwid, filterbuf[i]); (void)SignedChar( font.dir[c].up ); down = SignedChar( font.dir[c].down ); /* Initial base line for filtering depends on odd flag. */ base = (odd ? 1 : 2); /* Produce a RGBpixel buffer from a description of the character and the read back data from the frame buffer for anti-aliasing. */ for (i = font.height + base; i >= base; i--) { squash( filterbuf[i - 1], /* filter info */ filterbuf[i], filterbuf[i + 1], resbuf, totwid + 4 ); fb_read( fbp, xpos, ypos - down + i, (unsigned char *)fbline, totwid+3); for (j = 0; j < (totwid + 3) - 1; j++) { register int tmp; /* EDITOR'S NOTE : do not rearrange this code, the SUN compiler can't handle more complex expressions. */ tmp = fbline[j][RED] & 0377; fbline[j][RED] = (int)(paint[RED]*resbuf[j]+(1-resbuf[j])*tmp); fbline[j][RED] &= 0377; tmp = fbline[j][GRN] & 0377; fbline[j][GRN] = (int)(paint[GRN]*resbuf[j]+(1-resbuf[j])*tmp); fbline[j][GRN] &= 0377; tmp = fbline[j][BLU] & 0377; fbline[j][BLU] = (int)(paint[BLU]*resbuf[j]+(1-resbuf[j])*tmp); fbline[j][BLU] &= 0377; } fb_write( fbp, xpos, ypos - down + i, (unsigned char *)fbline, totwid+3 ); } return; }
void do_char(struct vfont *vfp, struct vfont_dispatch *vdp, int x, int y) { int i, j; int base; int totwid = width; int ln; static float resbuf[FONTBUFSZ]; static RGBpixel fbline[FONTBUFSZ]; int bytes_wide; /* # bytes/row in bitmap */ bytes_wide = (width+7)>>3; /* Read in the character bit map, with two blank lines on each end. */ for (i = 0; i < 2; i++) memset((char *)&filterbuf[i][0], 0, (totwid+4)*sizeof(int)); for (ln=0, i = height + 1; i >= 2; i--, ln++) fill_buf (width, &filterbuf[i][0], &vfp->vf_bits[vdp->vd_addr + bytes_wide*ln]); for (i = height + 2; i < height + 4; i++) memset((char *)&filterbuf[i][0], 0, (totwid+4)*sizeof(int)); /* Initial base line for filtering depends on odd flag. */ if (vdp->vd_down % 2) base = 1; else base = 2; /* Produce a RGBpixel buffer from a description of the character * and the read back data from the frame buffer for anti-aliasing. */ for (i = height + base; i >= base; i--) { squash(filterbuf[i - 1], /* filter info */ filterbuf[i], filterbuf[i + 1], resbuf, totwid + 4 ); fb_read(fbp, x, y - vdp->vd_down + i, (unsigned char *)fbline, totwid+3); for (j = 0; j < (totwid + 3) - 1; j++) { int tmp; /* EDITOR'S NOTE : do not rearrange this code, the SUN * compiler can't handle more complex expressions. */ tmp = fbline[j][RED] & 0377; fbline[j][RED] = (int)(pixcolor[RED]*resbuf[j]+(1-resbuf[j])*tmp); fbline[j][RED] &= 0377; tmp = fbline[j][GRN] & 0377; fbline[j][GRN] = (int)(pixcolor[GRN]*resbuf[j]+(1-resbuf[j])*tmp); fbline[j][GRN] &= 0377; tmp = fbline[j][BLU] & 0377; fbline[j][BLU] = (int)(pixcolor[BLU]*resbuf[j]+(1-resbuf[j])*tmp); fbline[j][BLU] &= 0377; } if (fb_write(fbp, x, y-vdp->vd_down+i, (unsigned char *)fbline, totwid+3) < totwid+3) { fprintf(stderr, "fblabel: pixel write error\n"); bu_exit(1, NULL); } } }
int main(int argc, char **argv) { FBIO *fbp; int i; int file_width; /* unclipped width of rectangle */ int file_skiplen; /* # of pixels to skip on l.h.s. */ int screen_xbase; /* screen X of l.h.s. of rectangle */ int screen_xlen; /* clipped len of rectangle */ int ncolors; infp = stdin; if (!get_args(argc, argv)) { (void)fputs(usage, stderr); bu_exit(1, NULL); } rle_dflt_hdr.rle_file = infp; if (rle_get_setup(&rle_dflt_hdr) < 0) { fprintf(stderr, "rle-fb: Error reading setup information\n"); bu_exit(1, NULL); } if (r_debug) { fprintf(stderr, "Image bounds\n\tmin %d %d\n\tmax %d %d\n", rle_dflt_hdr.xmin, rle_dflt_hdr.ymin, rle_dflt_hdr.xmax, rle_dflt_hdr.ymax); fprintf(stderr, "%d color channels\n", rle_dflt_hdr.ncolors); fprintf(stderr, "%d color map channels\n", rle_dflt_hdr.ncmap); if (rle_dflt_hdr.alpha) fprintf(stderr, "Alpha Channel present in input, ignored.\n"); for (i=0; i < rle_dflt_hdr.ncolors; i++) fprintf(stderr, "Background channel %d = %d\n", i, rle_dflt_hdr.bg_color[i]); rle_debug(1); } if (rle_dflt_hdr.ncmap == 0) crunch = 0; /* Only interested in R, G, & B */ RLE_CLR_BIT(rle_dflt_hdr, RLE_ALPHA); for (i = 3; i < rle_dflt_hdr.ncolors; i++) RLE_CLR_BIT(rle_dflt_hdr, i); ncolors = rle_dflt_hdr.ncolors > 3 ? 3 : rle_dflt_hdr.ncolors; /* Optional switch of library to overlay mode */ if (overlay) { rle_dflt_hdr.background = 1; /* overlay */ override_background = 0; } /* Optional background color override */ if (override_background) { for (i=0; i<ncolors; i++) rle_dflt_hdr.bg_color[i] = background[i]; } file_width = rle_dflt_hdr.xmax - rle_dflt_hdr.xmin + 1; /* If screen sizes not specified, try to display rectangle part > 0 */ if (screen_width == 0) { screen_width = rle_dflt_hdr.xmax + 1; if (scr_xoff > 0) screen_width += scr_xoff; } if (screen_height == 0) { screen_height = rle_dflt_hdr.ymax + 1; if (scr_yoff > 0) screen_height += scr_yoff; } /* Incorporate command-line rectangle repositioning */ rle_dflt_hdr.xmin += scr_xoff; rle_dflt_hdr.xmax += scr_xoff; rle_dflt_hdr.ymin += scr_yoff; /* Pretend saved image origin is at 0, clip & position in fb_write call */ screen_xbase = rle_dflt_hdr.xmin; rle_dflt_hdr.xmax -= screen_xbase; rle_dflt_hdr.xmin = 0; if ((fbp = fb_open(framebuffer, screen_width, screen_height)) == FBIO_NULL) bu_exit(12, NULL); /* Honor original screen size desires, if set, unless they shrank */ if (screen_width > 0 && fb_getwidth(fbp) < screen_width) screen_width = fb_getwidth(fbp); if (screen_height > 0 && fb_getheight(fbp) < screen_height) screen_height = fb_getheight(fbp); /* Discard any scanlines which exceed screen height */ if (rle_dflt_hdr.ymax > screen_height-1) rle_dflt_hdr.ymax = screen_height-1; /* Clip left edge */ screen_xlen = rle_dflt_hdr.xmax + 1; file_skiplen = 0; if (screen_xbase < 0) { file_skiplen = -screen_xbase; screen_xbase = 0; screen_xlen -= file_skiplen; } /* Clip right edge */ if (screen_xbase + screen_xlen > screen_width) screen_xlen = screen_width - screen_xbase; if (screen_xlen <= 0 || rle_dflt_hdr.ymin > screen_height || rle_dflt_hdr.ymax < 0) { fprintf(stderr, "rle-fb: Warning: RLE image rectangle entirely off screen\n"); goto done; } scan_buf = (unsigned char *)malloc(sizeof(RGBpixel) * screen_width); for (i=0; i < ncolors; i++) rows[i] = (unsigned char *)malloc((size_t)file_width); for (; i < 3; i++) rows[i] = rows[0]; /* handle monochrome images */ /* * Import Utah color map, converting to libfb format. * Check for old format color maps, where high 8 bits * were zero, and correct them. * XXX need to handle < 3 channels of color map, by replication. */ if (rle_dflt_hdr.ncmap > 0) { int maplen = (1 << rle_dflt_hdr.cmaplen); int all = 0; for (i=0; i<256; i++) { cmap.cm_red[i] = rle_dflt_hdr.cmap[i]; cmap.cm_green[i] = rle_dflt_hdr.cmap[i+maplen]; cmap.cm_blue[i] = rle_dflt_hdr.cmap[i+2*maplen]; all |= cmap.cm_red[i] | cmap.cm_green[i] | cmap.cm_blue[i]; } if ((all & 0xFF00) == 0 && (all & 0x00FF) != 0) { /* This is an old (Edition 2) color map. * Correct by shifting it left 8 bits. */ for (i=0; i<256; i++) { cmap.cm_red[i] <<= 8; cmap.cm_green[i] <<= 8; cmap.cm_blue[i] <<= 8; } fprintf(stderr, "rle-fb: correcting for old style colormap\n"); } } if (rle_dflt_hdr.ncmap > 0 && !crunch) (void)fb_wmap(fbp, &cmap); else (void)fb_wmap(fbp, COLORMAP_NULL); /* Handle any lines below zero in y. Decode and discard. */ for (i = rle_dflt_hdr.ymin; i < 0; i++) rle_getrow(&rle_dflt_hdr, rows); for (; i <= rle_dflt_hdr.ymax; i++) { unsigned char *pp = (unsigned char *)scan_buf; rle_pixel *rp = &(rows[0][file_skiplen]); rle_pixel *gp = &(rows[1][file_skiplen]); rle_pixel *bp = &(rows[2][file_skiplen]); int j; if (overlay) { fb_read(fbp, screen_xbase, i, scan_buf, screen_xlen); for (j = 0; j < screen_xlen; j++) { *rp++ = *pp++; *gp++ = *pp++; *bp++ = *pp++; } pp = (unsigned char *)scan_buf; rp = &(rows[0][file_skiplen]); gp = &(rows[1][file_skiplen]); bp = &(rows[2][file_skiplen]); } rle_getrow(&rle_dflt_hdr, rows); /* Grumble, convert from Utah layout */ if (!crunch) { for (j = 0; j < screen_xlen; j++) { *pp++ = *rp++; *pp++ = *gp++; *pp++ = *bp++; } } else { for (j = 0; j < screen_xlen; j++) { *pp++ = cmap.cm_red[*rp++]>>8; *pp++ = cmap.cm_green[*gp++]>>8; *pp++ = cmap.cm_blue[*bp++]>>8; } } if (fb_write(fbp, screen_xbase, i, scan_buf, screen_xlen) != screen_xlen) break; } done: fb_close(fbp); return 0; }
/* * * Usage: * procname cell xmin ymin width height color */ HIDDEN int fbo_rect_tcl(void *clientData, int argc, const char **argv) { struct fb_obj *fbop = (struct fb_obj *)clientData; int xmin, ymin; int xmax, ymax; int width; int height; int i; RGBpixel pixel; if (argc != 7) { bu_log("ERROR: expecting seven arguments\n"); return BRLCAD_ERROR; } if (sscanf(argv[2], "%d", &xmin) != 1) { bu_log("fb_rect: bad xmin value - %s", argv[2]); return BRLCAD_ERROR; } if (sscanf(argv[3], "%d", &ymin) != 1) { bu_log("fb_rect: 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_rect: coordinates (%s, %s) are invalid.", argv[2], argv[3]); return BRLCAD_ERROR; } if (sscanf(argv[4], "%d", &width) != 1) { bu_log("fb_rect: bad width - %s", argv[4]); return BRLCAD_ERROR; } if (sscanf(argv[5], "%d", &height) != 1) { bu_log("fb_rect: bad height - %s", argv[5]); return BRLCAD_ERROR; } /* check width and height */ if (width <=0 || height <=0) { bu_log("fb_rect: 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_rect: invalid color spec: %s", argv[6]); return BRLCAD_ERROR; } xmax = xmin + width; ymax = ymin + height; /* draw horizontal lines */ for (i = xmin; i <= xmax; ++i) { /* working on bottom line */ fb_write(fbop->fbo_fbs.fbs_fbp, i, ymin, pixel, 1); /* working on top line */ fb_write(fbop->fbo_fbs.fbs_fbp, i, ymax, pixel, 1); } /* draw vertical lines */ for (i = ymin; i <= ymax; ++i) { /* working on left line */ fb_write(fbop->fbo_fbs.fbs_fbp, xmin, i, pixel, 1); /* working on right line */ fb_write(fbop->fbo_fbs.fbs_fbp, xmax, i, pixel, 1); } return BRLCAD_OK; }