rhc@nsscb.UUCP (Rick Calder) (11/20/89)
/* This is an example of how to program graphics on a console virtual terminal screen. It is written for an AT&T VDC600 VGA card, at 800x600, but can easily be modified for others supported by the compiler. See '/usr/include/sys/kd.h'. It will first open an available virtual terminal, set the graphic mode, and then display the graphic area ( 25 ints x 600 lines). Program the appropriate bytes of the graphic area to correspond to the screen pixels, one bit per pixel. You may put this program in the background to free up the console, and then use the <ALT-SysReq><Fx> to bounce back and forth. Use the <DEL> to close the graphic. After a bounce out and back, no input will be read until the <BEEP>. Why ? Let me know if you figure it out ! Really, I've no idea. See the manpage, display(7) Warnings: Although it is possible to write character sequences which set arbitrary bits on the screen in any of the three graphic modes, this mode of operation is not currently supported. Rick Calder, AT&T National Systems Support Center [att!]rick!rick rick@rick.att.com attmail!rcalder -------------------------------- cut here ------------------------------------ */ /* #disclaimer: per the manpage, display(7), this code is not supported by AT&T. Use at your own risk, distribute freely, please leave in my authorship info. Rick Calder [att!]rick!rick rick@rick.att.com attmail!rcalder programming help : research!debra research!shadow!dhn change the following for other video modes: VGASCREEN_SIZE (800 * 600) total pixels SCREEN ((800/8) * 600) bytes per line LINES 600 COLS ((800 / 8) / 4) ints per line in acquiredisplay(): ioctl(0, SW_VDC800x600E, 0); AT&T VDC600 video card in releasedisplay(): ioctl(0, SW_VGAC80x25, 0); any VGA card, text mode */ #include <fcntl.h> #include <memory.h> #include <stdio.h> #include <sys/signal.h> #include <sys/types.h> #include <sys/at_ansi.h> #include <sys/kd.h> #include <sys/vt.h> #define ALIGN_TO_4K(size) (((size) + 4095) & ~4095) #define VGAWINDOW_SIZE 0x10000 /* 65536, 64K */ #define VGASCREEN_ADDR 0xA0000 /* others at 0xB0000 */ #define VGASCREEN_SIZE (800 * 600) #define SCREEN ((800/8) * 600) /* bytes per line */ #define LINES 600 #define COLS ((800 / 8) / 4) /* ints per line */ struct kd_memloc memloc; char *dp; int *pad[LINES][COLS]; void scribble(), initmem(), acquiredisplay(), releasedisplay(); main(argc,argv) int argc; char **argv; { int a; long vt; char devname[15]; struct vt_mode vtmode; /* VT_OPENQRY on stderr allows prog to be put in background */ if ( ioctl(2,VT_OPENQRY,&vt) == -1 ) { perror("VT_OPENQRY failed"); exit(-1); } close(0); close(1); close(2); setpgrp(); sprintf(devname,"/dev/vt0%ld", vt); a = open(devname,O_RDWR,NULL); if ( a == -1 ) { perror("vtopen failed"); exit(-1); } dup(a); dup(a); if ( ioctl(0,VT_ACTIVATE,vt) == -1 ) { perror("VT_ACTIVATE failed"); exit(-1); } sigset(SIGINT,exit); vtmode.mode = VT_PROCESS; /* process controls console switching */ vtmode.waitv = 1; /* no writes on inactive consoles */ vtmode.relsig = SIGUSR1; /* received on hot-key for other console */ vtmode.acqsig = SIGUSR1; /* received on hot-key to this console */ vtmode.frsig = SIGUSR2; /* not used, for forced release of display */ sigset(SIGUSR2,SIG_IGN); /* prevents 'User signal 2' message */ ioctl(0,VT_SETMODE, &vtmode); **pad = (int *) malloc(SCREEN); memset(pad,'\0',SCREEN); initmem(); scribble(); acquiredisplay(); /* initial set up */ while ( 1 ); } void scribble() { int x, y; for ( y = 0; y < LINES; y++ ) for ( x = 0; x < COLS; x++ ) { pad[y][x] = (int *) 0xFF00FF00; x += 2; } } void acquiredisplay() { ioctl(0, SW_VDC800x600E, 0); /* AT&T VDC600 video card */ sleep(1); /* settling time */ ioctl(0, KDMAPDISP, &memloc); memcpy(dp, pad, SCREEN); /* need to refresh screen */ sigset(SIGUSR1, releasedisplay); /* set for next signal */ } void releasedisplay() { ioctl(0, KDUNMAPDISP, 0); /* unmap from user memory */ sleep(1); /* settling time */ ioctl(0, SW_VGAC80x25, 0); /* any VGA card, text mode */ ioctl(0, VT_RELDISP, 1); /* results in console switch */ sigset(SIGUSR1, acquiredisplay); /* set for next signal */ } void initmem() { /* get a virtual address that is page aligned */ dp = (char *) malloc(ALIGN_TO_4K(VGAWINDOW_SIZE + 4096)); dp = (char *) ALIGN_TO_4K ((unsigned long) dp); memloc.physaddr = (caddr_t) VGASCREEN_ADDR; memloc.vaddr = dp; memloc.length = ALIGN_TO_4K (VGAWINDOW_SIZE); memloc.ioflg = 1; } -- Rick Calder, AT&T National Systems Support Center [att!]rick!rick rick@rick.att.com attmail!rcalder
kdg@nirvo.uucp (Kurt Gollhardt) (12/06/89)
In article <1078@nsscb.UUCP> rhc@nsscb.UUCP (Rick Calder) writes a very nice sample SYSV/386 console graphics program, with the following plaint: > > You may put this program in the background to free up the > console, and then use the <ALT-SysReq><Fx> to bounce back and forth. > Use the <DEL> to close the graphic. After a bounce out and back, no > input will be read until the <BEEP>. Why ? Let me know if you > figure it out ! Really, I've no idea. > You need to add the following line to the end of your acquiredisplay() routine: ioctl(0, VT_RELDISP, VT_ACKACQ); This tells the driver that you've finished redrawing the screen and the acquire process is complete. -- Kurt Gollhardt \ Nirvonics, Inc. -- Plainfield, NJ Kurt.Gollhardt@nirvo.uucp /\ Software Design and Consulting ...!rutgers!nirvo!Kurt.Gollhardt / \ "It's all about people; not you and me or him and her, but *us*."