chip@chinacat.Unicom.COM (Chip Rosenthal) (08/31/90)
In article <24246@uflorida.cis.ufl.EDU> srb@beach.cis.ufl.edu () writes: >I got information that SCO Xenix 2.2 do not allow screen dump capability. >Any pointers regarding this will be appreciated. If you are talking a DOSish "print screen" kind of thing, no it doesn't. There are a couple of alternatives. First, there is a "send screen to host" ANSI sequence which the console does interpret (rtfm screen(HW)). I've used this in programs to build in a "dump screen" feature. You could jump over to another screen, send the control code to the first screen, and read the output from it. Unfortunately, if something is running on that first screen which is reading the tty then stuff will get scrambled. (BTW, this is a wonderful hole which can be exploited to give yourself root access in 3 seconds or less.) A cleaner way of implementing this approach might be to run on a pty and stick something between you and the application which will handle the screen dumps - this would be pretty easy to do with the above ANSI sequence. The second approach is to grab the display directly and dump the contents. Below is a quick hack which runs *only* on mono displays in 80x25 text mode, and grabs the contents of a screen. For example, if you are running on /dev/tty01, you can jump over to /dev/tty02 and do something like: prtscrn 1 | lp There are several things which would need to be done to make this thing a useful program. First, some of the other display types and modes should be supported. The way it's written, that should be easy to do. Second, I'm not aware of any ioctl's which allow you to determine or set the current screen, so I use an ANSI escape sequence to switch to the desired screen and the program just leaves it there. Hmmm...maybe leaving it there is a feature not a bug. --- cut here ----------------------------------------------------------------- #include <stdio.h> #include <fcntl.h> #include <sys/machdep.h> #define USAGE "usage: %s screen_no\n" #define SCREENS 12 int char_16bit(ptr) char **ptr; { int i; i = **ptr; *ptr += 2; return i; } main(argc,argv) int argc; char *argv[]; { char *disp_mem, buf[64]; int screen_num, disp_type, disp_mode, disp_fd, i; int num_cols, num_lines, (*char_sel)(); int line, col; if ( argc != 2 ) { fprintf(stderr,USAGE,argv[0]); exit(1); } screen_num = atoi(argv[1]); if ( screen_num < 1 || screen_num > SCREENS ) { fprintf(stderr,"%s: bad screen number '%s'\n",argv[0],argv[1]); exit(1); } /* * Assuming only one adapter. */ if ( (disp_fd=open("/dev/tty",O_RDWR)) < 0 ) { fprintf(stderr,"%s: could not open tty\n",argv[0]); exit(1); } /* * Switch to selected screen. */ sprintf(buf,"\033[%dz",screen_num-1); write(disp_fd,buf,strlen(buf)); /* * Determine the display type and mode. Map the display memory. */ if ( (disp_type=ioctl(disp_fd,CONS_CURRENT,0)) < 0 ) { fprintf(stderr,"%s: could not get display type\n",argv[0]); exit(1); } if ( (disp_mode=ioctl(disp_fd,CONS_GET,0)) < 0 ) { fprintf(stderr,"%s: could not get display type\n",argv[0]); exit(1); } if ( (disp_mem=(char *)ioctl(disp_fd,MAPCONS,0)) == NULL ) { fprintf(stderr,"%s: could not map display memory\n",argv[0]); exit(1); } /* * This has only been run on a Herc adapter in text mode. */ if ( disp_type != MONO || disp_mode != M_B80x25 ) { fprintf(stderr, "%s: sorry...currently supports only mono 80x25 displays\n", argv[0]); exit(1); } num_cols = 80; num_lines = 25; char_sel = char_16bit; /* * Do the screen dump. */ for ( line = 0 ; line < num_lines ; ++line ) { for ( col = 0 ; col < num_cols ; ++col ) { i = (*char_sel)(&disp_mem); putchar(i); } putchar('\n'); } exit(0); } --- cut here ----------------------------------------------------------------- -- Chip Rosenthal <chip@chinacat.Unicom.COM> Unicom Systems Development, 512-482-8260 Our motto is: We never say, "But it works with DOS."