#include #include #include #include #include #include #include extern const char *__progname; #include "gl-int.h" #include "gl-md-asm.h" static const char *defpath = "/dev/cgthree0"; static int fd; static struct gl_fb8 fb; static struct gl_fb1 shadow; static struct fbcmap oldcm; static unsigned char oldcm_r[256]; static unsigned char oldcm_g[256]; static unsigned char oldcm_b[256]; #define NOMINAL_AR (NOMINAL_XSIZE/(double)NOMINAL_YSIZE) static void setcmap(void) { struct fbcmap cm; unsigned char v; cm.index = 0; cm.count = 1; cm.red = &v; cm.green = &v; cm.blue = &v; v = 0; ioctl(fd,FBIOPUTCMAP,&cm); cm.index = 255; cm.count = 1; cm.red = &v; cm.green = &v; cm.blue = &v; v = 255; ioctl(fd,FBIOPUTCMAP,&cm); } static void savecmap(void) { oldcm.index = 0; oldcm.count = 256; oldcm.red = &oldcm_r[0]; oldcm.green = &oldcm_g[0]; oldcm.blue = &oldcm_b[0]; if (ioctl(fd,FBIOGETCMAP,&oldcm) < 0) { fprintf(stderr,"%s: FBIOGETCMAP: %s\n",__progname,strerror(errno)); exit(1); } } static void restorecmap(void) { oldcm.index = 0; oldcm.count = 256; oldcm.red = &oldcm_r[0]; oldcm.green = &oldcm_g[0]; oldcm.blue = &oldcm_b[0]; ioctl(fd,FBIOPUTCMAP,&oldcm); } static int x_probe(const char *path) { caddr_t mm; struct fbtype fbtype; double ar; if (! path) path = defpath; fd = open(path,O_RDWR,0); if (fd < 0) return(0); if ( (ioctl(fd,FBIOGTYPE,&fbtype) < 0) || (fbtype.fb_depth != 8) ) { close(fd); return(0); } savecmap(); mm = mmap(0,fbtype.fb_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0x04000000); if (mm == (caddr_t)-1) { fprintf(stderr,"%s: mmap %s: %s\n",__progname,path,strerror(errno)); exit(1); } fb.vram = (void *) mm; ar = fbtype.fb_width / (double)fbtype.fb_height; fb.stride = fbtype.fb_width; fb.xsize = fbtype.fb_width; fb.ysize = fbtype.fb_height; if (ar < (NOMINAL_AR*.9)) { fb.ysize = fb.xsize / NOMINAL_AR; fb.vram += fb.stride * ((fbtype.fb_height-fb.ysize)/2); } else if (ar > (NOMINAL_AR/.9)) { fb.xsize = fb.ysize * NOMINAL_AR; fb.vram += (fbtype.fb_width - fb.xsize) / 2; } fb.size = fb.stride * fb.ysize; shadow.stride = (fb.xsize + 7) / 8; shadow.xsize = fb.xsize; shadow.ysize = fb.ysize; shadow.size = shadow.stride * shadow.ysize; #ifdef MAP_ANON mm = mmap(0,shadow.size,PROT_READ|PROT_WRITE,MAP_ANON,-1,0); if (mm == (caddr_t)-1) { fprintf(stderr,"%s: mmap scratch space: %s\n",__progname,strerror(errno)); exit(1); } #else fd = open("/dev/zero",O_RDWR,0); if (fd < 0) { fprintf(stderr,"%s: can't open /dev/zero: %s\n",__progname,strerror(errno)); exit(1); } mm = mmap(0,shadow.size,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0); if (mm == (caddr_t)-1) { fprintf(stderr,"%s: mmap scratch space: %s\n",__progname,strerror(errno)); exit(1); } close(fd); #endif shadow.vram = (void *) mm; bzero(fb.vram,fb.size); XMAXSCREEN = shadow.xsize; YMAXSCREEN = shadow.ysize; PIXELSCALE = shadow.xsize / (double)NOMINAL_XSIZE; setcmap(); return(1); } static void x_shutdown(void) { restorecmap(); } static void x_clear(void) { gl_clear_fb1(&shadow); } static void x_swap(void) { gl_copy_fb1_fb8(&shadow,&fb); } static void x_line(int a, int b, int c, int d) { gl_line_fb1(&shadow,a,b,c,d); } static void x_point(int x, int y) { gl_point_fb1(&shadow,x,y); } ODEV odev_cgthree = { "cgthree", "cg3 color display", x_probe, x_probe, x_shutdown, x_clear, x_swap, x_line, x_point };