prove@batcomputer.tn.cornell.edu (Roger Ove) (10/24/89)
Could someone please post an example using a socket connection between 2 NeWS processes? I have a pixrect image stored in a string and want to display it with readcanvas imagecanvas, without going to disk. An example receiving the data via separate socket from the C client would also be useful (to avoid NeWS string length restrictions). thanks, Roger Ove ove@ncsa.uiuc.edu
andrew@isgtec.UUCP (Andrew) (10/26/89)
Roger, This sounds very interesting. Could you please post any responses you receive. (Post to the net, becuase my mailer is down.) Thanks in advance. >Could someone please post an example using a socket connection >between 2 NeWS processes? I have a pixrect image stored in a string >and want to display it with readcanvas imagecanvas, without going to >disk. An example receiving the data via separate socket from the C >client would also be useful (to avoid NeWS string length restrictions). -- Andrew MacLean ...uunet!mnetor!lsuc!isgtec!andrew Success is a journey, not an adventure! ...utzoo!lsuc!isgtec!andrew ISG Technologies Inc. 3030 Orlando Dr. Mississauga. Ont. Can. L4V 1S8
prove@batcomputer.tn.cornell.edu (Roger Ove) (10/26/89)
In response to my own query: > Could someone please post an example using a socket connection > between 2 NeWS processes? I have a pixrect image stored in a string > and want to display it with readcanvas imagecanvas, without going to > disk. An example receiving the data via separate socket from the C > client would also be useful (to avoid NeWS string length restrictions). There is no difficulty in passing data between the C Client and NeWS process via a secondary socket connection, the most obvious thing works (I'll mail the example if anyone is interested). Help with the first question would still be appreciated. thanks, Roger Ove ove@ncsa.uiuc.edu
sjs@spectral.ctt.bellcore.com (Stan Switzer) (10/27/89)
In article <9150@batcomputer.tn.cornell.edu> prove@batcomputer.tn.cornell.edu (Roger Ove) writes: > In response to my own query: > > > Could someone please post an example using a socket connection > > between 2 NeWS processes? I have a pixrect image stored in a string > > and want to display it with readcanvas imagecanvas, without going to > > disk. An example receiving the data via separate socket from the C > > client would also be useful (to avoid NeWS string length restrictions). > > There is no difficulty in passing data between the C Client and > NeWS process via a secondary socket connection, the most obvious > thing works (I'll mail the example if anyone is interested). > Help with the first question would still be appreciated. > > thanks, > Roger Ove ove@ncsa.uiuc.edu OK, here's an example. The trick is that file names of the form (%socket[cl]nnn[.nnnnn]) are special. "c" means connect. "l" means listen. The first number is the socket number. The second number, if present, is the internet address (in decimal!). If the address is left off, localhost is the default. I have the opposite problem. I want to send a rasterfile via writecanvas to a C client from NeWS. I basically know how to do it, but I haven't done much socket hacking (in C) so an example would be greatly appreciated. I don't think you can do UDP sockets though, which is too bad since I am sorely tempted to write a SunRPC handler in NeWS so that I can write a yellow-pages client. Example follows. I haven't the foggiest idea why normal EOF detection on "currentfile" doesn't work. Stan Switzer sjs@bellcore.com ---------- #!/usr/NeWS/bin/psh % simple socket I/O example /buff1 100 string def /buff2 100 string def /receiver { /insocket (%socketl2345) (r) file acceptconnection def { % loop... insocket buff1 readline not { exit } if % read a line from socket == % print a line } loop (End of Input) == } fork def pause pause % give the process a chance to get launched { % sender: /outsocket (%socketc2345) (w) file def { % loop... currentfile buff2 readline not { exit } if % read a line from stdin dup (EOF) eq { exit } if outsocket exch writestring outsocket (\n) writestring outsocket flushfile } loop /outsocket null def % close output socket receiver waitprocess } exec line 1 another line line 3 last line EOF
prove@batcomputer.tn.cornell.edu (Roger Ove) (10/27/89)
Here is a demo with the C client sending data to the NeWS process by an independent socket. The file show.c isn't used by the demo, it is an interface to fortran on a Cray. I thinkg the Makefile will have to be modified to compile the demo on anything but a Cray. Roger Ove # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by tralfaz!ove on Fri Oct 27 10:09:09 EST 1989 # Contents: Makefile README opensock.c replay.c show.c show.cps echo x - Makefile sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//' # C/NeWS pixrect image displayed over network OBJ = replay.o opensock.o LIBS = $(NEWSHOME)/clientsrc/lib/NeWS/libcps.a /usr/lib/libnet.a @.SUFFIXES : @.SUFFIXES : .o .c replay : $(OBJ) cc -o replay $(OBJ) $(LIBS) replay.o : show.h show.o : show.h show.h : show.cps cps show.cps @.c.o : cc -O -c -I$(NEWSHOME)/clientsrc/include $*.c @//E*O*F Makefile// chmod u=rw,g=rw,o=rw Makefile echo x - README sed 's/^@//' > "README" <<'@//E*O*F README//' This is an example of sending data from the C client to a NeWS process by a secondary socket connection. It displays a sequence of pixrect image files (names read from the command line). The Makefile is for a Cray, some changes will be necessary to compile it on a Sun (source should require no changes). This example sets up a new socket connection for each image, which probably isn't such a great idea. @//E*O*F README// chmod u=rw,g=,o= README echo x - opensock.c sed 's/^@//' > "opensock.c" <<'@//E*O*F opensock.c//' #include <stdio.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <net/if.h> /* Open a socket to NeWS_addr.(port+1), for writing. Return the * stream. */ FILE *open_socket_handle() { FILE *handle ; char *server ; int fd ; char *semi, *dot ; struct sockaddr_in sin ; server = (char *) getenv("NEWSSERVER") ; fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ; if (server && fd >= 0) { extern char *rindex() ; register char *t ; if (semi = rindex(server, ';')) *semi = 0 ; if (dot = rindex(server, '.')) { /* 1 plus NeWS port */ *dot = 0 ; sin.sin_port = htons(atoi(dot + 1)+1); } sin.sin_addr.s_addr = htonl(inet_addr(server)) ; if (dot) *dot = '.' ; if (semi) *semi = ';' ; } else return(0) ; sin.sin_family = AF_INET ; if (connect(fd, &sin, sizeof(sin)) < 0) { close(fd) ; return(0) ; } handle = fdopen(fd, "w") ; return (handle) ; } @//E*O*F opensock.c// chmod u=rw,g=rw,o=rw opensock.c echo x - replay.c sed 's/^@//' > "replay.c" <<'@//E*O*F replay.c//' /* Replay * * Simple NeWS display of pixrect files across a network. * Invoke as * replay file1 file2 .... filen * where the files are pixrect image files */ #include <stdio.h> #include "show.h" #define MAXLENGTH (512*1024) main(argc, argv) int argc ; char *argv[] ; { int i, j, len ; char s[MAXLENGTH] ; char filename[100] ; FILE *in, *sock, *open_socket_handle() ; for (i=1; i<argc; i++) { sprintf(filename, "%s", argv[i]) ; fprintf(stderr, "filename %s\n", filename) ; if ( (in = fopen(filename, "r")) == 0 ) break ; if ( (len = fread(s, 1, MAXLENGTH, in)) <= 0 ) break ; /* initialize PS on 1st entry */ if (i == 1) { ps_open_PostScript() ; ps_initialize("Pixrect Image Demo") ; ps_flush_PostScript() ; } /* open socket connection */ for (j=0; j<10; j++) { sock = open_socket_handle() ; if (sock != 0) break ; sleep(2) ; } if (sock==0) { fprintf(stderr, "Connection timeout\n") ; exit() ; } /* write pixrect data */ fwrite(s, 1, len, sock) ; fflush(sock) ; } sleep(10) ; ps_close_PostScript() ; } @//E*O*F replay.c// chmod u=rw,g=rw,o=rw replay.c echo x - show.c sed 's/^@//' > "show.c" <<'@//E*O*F show.c//' /* Show * simple NeWS display of an array */ #include <stdio.h> #include <malloc.h> #include <math.h> #include "show.h" #include <fortran.h> #define max(a,b) (a>=b ? a : b) NEWSSTOP() { ps_close_PostScript() ; } /* Display a field using NeWS. Creates a string representation of a * Pixrect file and uses the NeWS readimage facility. */ #define RAS_MAGIC 0x59a66a95 struct rasterfile { long ras_magic ; long ras_width ; long ras_height ; long ras_depth ; long ras_length ; long ras_type ; long ras_maptype ; long ras_maplength ; } ; NEWSSHOW(mxp, myp, array_fcd) int *mxp, *myp ; _fcd array_fcd ; /* fortran character descriptor */ { static int entered = 0 ; FILE *mapfile, *sock, *open_socket_handle() ; int mx = *mxp, my = *myp ; int i ; int len = mx*my + 4*8 + 3*256 ; unsigned char *array = (unsigned char*)_fcdtocp(array_fcd); unsigned char *s = malloc(len + 1) ; unsigned char *data = &s[4*8 + 3*256] ; unsigned char *red = &(s[4*8]) ; unsigned char *green = &(s[4*8+256]) ; unsigned char *blue = &(s[4*8+2*256]) ; struct rasterfile pixrect ; /* set up the pixrect header */ pixrect.ras_magic = RAS_MAGIC ; pixrect.ras_width = mx ; pixrect.ras_height = my ; pixrect.ras_depth = 8 ; pixrect.ras_length = mx*my ; pixrect.ras_type = 1 ; pixrect.ras_maptype = 1 ; pixrect.ras_maplength = 3*256 ; /* copy the header into s, can't just memcpy, struct on 64bit boundaries */ ((long*)s)[0] = (pixrect.ras_magic << 32) + pixrect.ras_width ; ((long*)s)[1] = (pixrect.ras_height << 32) + pixrect.ras_depth ; ((long*)s)[2] = (pixrect.ras_length << 32) + pixrect.ras_type ; ((long*)s)[3] = (pixrect.ras_maptype << 32) + pixrect.ras_maplength ; /* add the rgb color map */ if ( NULL == (mapfile = fopen( "color.map", "rb" )) ) abort( "shit, where did the color.map file go?" ) ; for ( i=0; i<256; i++ ) red[i] = (unsigned char)fgetc(mapfile) ; for ( i=0; i<256; i++ ) green[i] = (unsigned char)fgetc(mapfile) ; for ( i=0; i<256; i++ ) blue[i] = (unsigned char)fgetc(mapfile) ; fclose( mapfile ) ; /* copy the data, reversing rows to undo pixrect convention */ for (i=0; i<my; i++) memcpy(&data[mx*(my-1-i)], &array[mx*i], mx) ; /* initialize PS end on 1st entry */ if (!entered) { entered = 1 ; ps_open_PostScript() ; ps_initialize("Electron Density") ; ps_flush_PostScript() ; } /* open socket connection */ for (i=0; i<10; i++) { if (sock = open_socket_handle()) break ; sleep(2) ; } if (!sock) { fprintf(stderr, "Connection timeout\n") ; exit() ; } /* write pixrect data */ fwrite(s, 1, len, sock) ; fflush(sock) ; savepix(s, len) ; /* dump numbered file to disk */ free(s) ; } /* SAVEPIX * * Dump a numbered file to disk, containing the pixrect image */ savepix(s, len) unsigned char *s ; int len ; { static int count = 0 ; FILE *o ; char filename[16] ; sprintf(filename, "%04d.img", count++) ; o = fopen(filename, "w") ; fwrite(s, 1, len, o) ; fclose(o) ; } /* COMPACT * * Reduce an array so that it will fit in a box (done in place). A * no-op if the box is already bigger. This is written for speed, * no averaging over nearby values is done (or should be). */ #define x_dim (*x_dimp) /* we want to update xy_dim in caller */ #define y_dim (*y_dimp) compact( data, x_dimp, y_dimp, x_size, y_size ) unsigned char *data ; int *x_dimp, *y_dimp ; /* original dimensions (could change) */ int x_size, y_size ; /* requested dimensions */ { register int x ; register int y ; int xindex, xslope, xinter, xfact ; int yindex, yslope, yinter, yfact ; /* calculate the linear coefficients */ if ( x_size > 1 ) { xslope = x_dim - 1 ; xinter = x_dim - 1 ; xfact = x_size ; } else { xslope = 1 ; xinter = 0 ; xfact = 1 ; } if ( y_size > 1 ) { yslope = y_dim - 1 ; yinter = y_dim - 1 ; yfact = y_size ; } else { yslope = 1 ; yinter = 0 ; yfact = 1 ; } /* compress the data to fit the window */ if ( x_dim > x_size & y_dim > y_size ) { for ( y = 0; y < y_size; y++ ) { yindex = ( yslope*y + yinter )/yfact ; for ( x = 0; x < x_size; x++ ) { xindex = ( xslope*x + xinter )/xfact ; data[x + y*x_size] = data[xindex + yindex*x_dim] ; }} x_dim = x_size ; y_dim = y_size ; } else { if ( x_dim > x_size ) { for ( y = 0; y < y_dim; y++ ) { for ( x = 0; x < x_size; x++ ) { xindex = ( xslope*x + xinter )/xfact ; data[x + y*x_size] = data[xindex + y*x_dim] ; }} x_dim = x_size ; } else { if ( y_dim > y_size ) { for ( y = 0; y < y_size; y++ ) { yindex = ( yslope*y + yinter )/yfact ; for ( x = 0; x < x_dim; x++ ) { data[x + y*x_dim] = data[x + yindex*x_dim] ; }} y_dim = y_size ; } }} } @//E*O*F show.c// chmod u=rw,g=rw,o=rw show.c echo x - show.cps sed 's/^@//' > "show.cps" <<'@//E*O*F show.cps//' %! show.cps % % Definitions for simple array display program % Initialize pixrect viewer. Data received via socket on port 2001 cdef ps_initialize(string flabel) /painter { % Paint routine for client or icon canvas setcanvas clippath pathbbox scale pop pop Pixcanvas imagecanvas pause } def /win framebuffer /new DefaultWindow send def % Create a window { % Install display src /Pixcanvas currentcanvas newcanvas def /FrameLabel flabel def /PaintClient { ClientCanvas painter } def /PaintIcon { IconCanvas painter } def } win send /reshapefromuser win send % Shape it. % define routine to get the data via socket /getimage { clear (%socketl2001) (r) file acceptconnection % should be waiting here a lot dup readcanvas /Pixcanvas exch store PaintClient closefile % close socket } def % fork a process to receive data /listener_pid { {{getimage} win send} loop } fork def % Activate window (Damage causes PaintClient to be called) /map win send @//E*O*F show.cps// chmod u=rw,g=rw,o=rw show.cps exit 0