home *** CD-ROM | disk | FTP | other *** search
- /*****
- *
- * File: cm_cell.c
- * By: Dave Hiebeler
- * June 1989
- *
- * Basic routines for the CM side of Cellsim...
- */
-
- #include "cm_cell.h"
- #include <sys/time.h>
-
-
- /*
- *
- * Cellsim copyright 1989, 1990 by Chris Langton and Dave Hiebeler
- * (cgl@lanl.gov, hiebeler@heretic.lanl.gov)
- *
- * This package may be freely distributed, as long as you don't:
- * - remove this notice
- * - try to make money by doing so
- * - prevent others from copying it freely
- * - distribute modified versions without clearly documenting your changes
- * and notifying us
- *
- * Please contact either of the authors listed above if you have questions
- * or feel an exception to any of the above restrictions is in order.
- *
- * If you make changes to the code, or have suggestions for changes,
- * let us know! If we use your suggestion, you will receive full credit
- * of course.
- */
-
- /*****
- * Cellsim history:
- *
- * Cellsim was originally written on Apollo workstations by Chris Langton.
- *
- * Sun versions:
- *
- * - version 1.0
- * by C. Ferenbaugh and C. Langton
- * released 09/02/88
- *
- * - version 1.5
- * by Dave Hiebeler and C. Langton May - June 1989
- * released 07/03/89
- *
- * - version 2.0
- * by Dave Hiebeler and C. Langton July - August 1989
- * never officially released (unofficially released 09/08/89)
- *
- * - version 2.5
- * by Dave Hiebeler and C. Langton September '89 - February 1990
- * released 02/26/90
- *****/
-
-
- #define CELLSIM_PORT 12700
-
-
- /* Functions callable by Sun-side of Cellsim */
- void
- send_LT(), send_image(), run(), display_image(), change_stuff(),
- set_displays(), get_LT(), cm_probe(), enable_socket(), disable_socket(),
- send_cmap(), change_delay(), run_forever(), set_disp_interval(),
- load_image(), quick_random(), general_random(),
- CM_clear_array(), CM_get_image(), CM_set_image_dir(), CM_set_fcn_dir(),
- CM_set_LT_dir(), load_rule(), set_zoom(), set_pan(), change_image_size(),
- CM_get_image_dir(), CM_get_fcn_dir(), CM_get_LT_dir();
-
- /* Dummy routine to hold a place in the array of routines */
- void null_proc();
-
- /* Various internal functions */
- void
- set_params(), init_cmfb(), set_states(), load_fcn(), load_LT(),
- CM_init_stuff(), get_client(), CM_uninit_stuff(), load_function_file(),
- CMFB_display_image(), load_image_compressed(), load_LT_compressed();
- int
- read_image_from_fp(), read_LT_from_fp();
-
- static struct stat statbuf;
-
- /* struct holding function callable by Cellsim */
- typedef struct {
- void_func_ptr fcn; /* ptr to function */
- char *fcn_name; /* name or description of fcn */
- int debug_lvl; /* debug-level at which to print out fcn-call */
- } CM_cellsim_func;
-
-
- /* Array of functions */
- CM_cellsim_func CM_cellsim_func_array[] = {
- {null_proc, "zero-entry", 0},
- {null_proc, "quit", 0}, {send_LT, "send_LT", 1},
- {send_image, "send_image", 1}, {run, "run", 1},
- {display_image, "display_image", 1}, {change_stuff, "change_stuff", 1},
- {set_displays, "set_displays", 1}, {get_LT, "get_LT", 1},
- {cm_probe, "probe", 1}, {enable_socket, "enable_socket", 1},
- {disable_socket, "disable_socket", 1}, {send_cmap, "send_cmap", 1},
- {change_delay, "change_delay", 1}, {run_forever, "run_forever", 1},
- {null_proc, "stop_run", 1}, {null_proc, "run2", 1},
- {set_disp_interval, "set_disp_interval", 1}, {null_proc, "done", 1},
- {null_proc, "error", 1}, {load_image, "load_image", 1},
- {quick_random, "quick_random", 1}, {general_random, "general_random", 1},
- {CM_clear_array, "clear", 1}, {CM_get_image, "get_image", 1},
- {CM_set_image_dir, "set image_dir", 1}, {CM_set_fcn_dir, "set_fcn_dir", 1},
- {CM_set_LT_dir, "set_LT_DIR", 1}, {load_rule, "load_rule", 1},
- {set_zoom, "set_zoom", 1}, {set_pan, "set_pan", 1},
- {change_image_size, "change_image_size", 1},
- {CM_get_image_dir, "get image-dir", 1}, {CM_get_fcn_dir, "get fcn-dir", 1},
- {CM_get_LT_dir, "get LT-dir", 1}
- };
- CM_cellsim_func_max = 34; /* max possible index into array */
-
-
- extern char *getenv();
- void which();
-
- char argv0[256];
- unsigned char buf[256];
- unsigned int
- start_vector[2], end_vector[2], axis_vector[2],
- dimension_vector[2];
- int offset_vector[2];
- unsigned int saved_x=0, saved_y=0, state_count[16];
- char CM_image_dir[128], CM_fcn_dir[128], CM_LT_dir[128], saved_fcn_name[256];
- int zoom_fac, pan_x, pan_y;
-
- int port_num, sock_fd, daemon;
-
-
- void
- printusage(s)
- char *s;
- {
- fprintf(stderr, "Usage: %s [-p port#] [-d debug-level]\n",s);
- exit(1);
- }
-
-
- void
- quit(s)
- char *s;
- {
- fprintf(stderr,"%s\n",s);
- exit(1);
- }
-
-
-
- void
- pquit(s)
- char *s;
- {
- fprintf(stderr,"%s\n",s);
- perror("cm_cell");
- exit(1);
- }
-
-
- void
- quit2(s1,s2)
- char *s1,*s2;
- {
- fprintf(stderr,s1,s2);
- fprintf(stderr,"\n");
- exit(1);
- }
-
-
- void
- Log(s,d)
- char *s;
- int d;
- {
- fprintf(logfile, "%s\n",s);
- if (debug >= d)
- fprintf(stderr, "%s\n",s);
- fflush(logfile);
- }
-
- void
- Log2(s1,s2,d)
- char *s1, *s2;
- int d;
- {
- fprintf(logfile, s1, s2);
- fprintf(logfile, "\n");
- if (debug >= d) {
- fprintf(stderr, s1, s2);
- fprintf(stderr, "\n");
- }
- fflush(logfile);
- }
-
-
-
- void
- Logd(s,n,d)
- char *s;
- int n, d;
- {
- fprintf(logfile, s, n);
- fprintf(logfile, "\n");
- if (debug >= d) {
- fprintf(stderr, s, n);
- fprintf(stderr, "\n");
- }
- fflush(logfile);
- }
-
-
-
- /* Main control loop to read commands from the socket and execute them */
- void
- main(argc,argv)
- int argc;
- char **argv;
- {
- u_short port;
- int addrs;
- int done, logfd, ret_val, err, tmp, i;
- char tmp_str[80];
-
- printf("Please wait.. initializing...\n");
- /* strcpy(argv0, argv[0]); */
- which(argv[0], argv0);
- daemon = 0;
- if (argc == 1) /* user, not the daemon, is invoking the program.
- * that means we have to act as a daemon & wait for
- * a client */
- daemon = 1;
- else { /* check to see if user or daemon is invoking us */
- err = sscanf(argv[1], "%d", &tmp);
- if ((err != 1) || (tmp == 0))
- daemon = 1;
- }
- /* set up some variables & stuff */
- debug = 0;
- debug2 = 0;
- exit_function = NULL;
- strcpy(CM_image_dir, CM_IMAGE_DIR);
- strcpy(CM_fcn_dir, CM_FCN_DIR);
- strcpy(CM_LT_dir, CM_LT_DIR);
- unlink("/tmp/cm_cell.log"); /* remove logfile */
- if ((logfile = fopen("/tmp/cm_cell.log", "w"))==NULL) {
- logfile = stderr;
- fprintf("Logging to stderr, couldn't open /tmp/cm_cell.log\n");
- }
- setbuf(logfile, NULL); /* turn off buffering in case someone is
- * watching (e.g. "tail -f") the logfile */
- CM_init();
- if (daemon) {
- port_num = CELLSIM_PORT;
- for (i=1; i<argc; i++) {
- if (strcmp(argv[i], "-p") && strncmp(argv[i], "-d", 2)) {
- printf("bad arg is '%s'\n",argv[i]);
- printusage(argv[0]);
- }
- switch (argv[i][1]) {
- case 'p': /* port number */
- if (i == (argc-1))
- quit("No port # given");
- sscanf(argv[++i], "%d", &port_num);
- printf("port # is %d\n",port_num);
- break;
- case 'd':
- if ((argv[i][2] > '0') && (argv[i][2] <= '9'))
- debug = argv[i][2] - '0';
- else {
- if (i == (argc-1))
- quit("No debug-value given");
- err = sscanf(argv[++i], "%d", &debug);
- if (err == 0)
- quit("No debug-value given");
- }
- break;
- }
- }
- port = htons(port_num);
- if ((sock_fd = open_host_socket(&addrs, &port, debug2)) == -1)
- pquit("Couldn't open socket");
- }
- else { /* if running under daemon, it's opened socket for us */
- sscanf(argv[1], "%d", &ns);
- sscanf(argv[2], "%d", &logfd); /* not used (leftover from old code) */
- set_params(argv[3]);
- }
- Log("***entering command loop***",0);
- Logd("debug = %d", debug, 0);
- forever_flag = 0;
- while (1) {
- if (daemon)
- get_client();
- while (!done) {
- Log("***waiting for command***",1);
- if ((ret_val = read_from_sock(ns, buf, 1, OFF, debug2)) == -1) {
- Log("read_from_sock returned -1 looking for cmd",0);
- quit("read_from_sock error");
- }
- if (!ret_val) {
- Log("Socket closed by client", 0);
- Log("Waiting for new client", 0);
- done = 1;
- break;
- }
- if (buf[0] == QUIT) {
- if (!daemon)
- exit(0);
- else {
- Log("Got quit command from client...", 0);
- done = 1;
- break;
- }
- }
- else if (buf[0] > CM_cellsim_func_max) {
- Logd("Got bogus command from Cellsim! (%d)", buf[0], 0);
- Log("Shutting down... waiting for new client", 0);
- done = 1;
- break;
- }
- else { /* call the function requested by Sun-Cellsim */
- Log2("Got %s request",CM_cellsim_func_array[buf[0]].fcn_name,
- CM_cellsim_func_array[buf[0]].debug_lvl);
- (CM_cellsim_func_array[buf[0]].fcn)();
- Log2("Done with %s", CM_cellsim_func_array[buf[0]].fcn_name,
- CM_cellsim_func_array[buf[0]].debug_lvl);
- }
- }
- close(ns);
- CM_uninit_stuff();
- done = 0;
- strcpy(CM_image_dir, CM_IMAGE_DIR);
- strcpy(CM_fcn_dir, CM_FCN_DIR);
- strcpy(CM_LT_dir, CM_LT_DIR);
- }
- }
-
-
- /*
- * Send acknowledgement to client; this is used to synchronize the CMFE
- * with the client
- */
- void
- CM_send_ack()
- {
- unsigned char buf[1];
-
- buf[0] = DONE;
- write_to_sock(ns, buf, 1, OFF, debug2);
- }
-
-
- /*
- * Read an integer from client. Since the byte-order of an integer on a
- * Vax is reverse from that on a Sun, we need this portable way to
- * transfer integers between CMFE and client.
- */
- int
- CM_read_int()
- {
- unsigned char buf[4];
- int n;
-
- read_from_sock(ns, buf, 4, OFF, 0);
- n = buf[0] + buf[1]*256;
- n += buf[2]*256*256 + buf[3]*256*256*256;
- return n;
- }
-
-
- /*
- * Send an integer to client
- */
- void
- CM_send_int(n)
- int n;
- {
- unsigned char buf[4];
-
- buf[0] = n%256;
- buf[1] = n/256;
- buf[2] = n/(256*256);
- buf[3] = n/(256*256*256);
- write_to_sock(ns, buf, 4, OFF, 0);
- }
-
-
- /*
- * If some kind of error occurs, tell client about it and send a brief
- * error message.
- */
- void
- CM_send_error(str)
- char str[80];
- {
- unsigned char buf[1];
- char local_copy[80];
-
- strcpy(local_copy, str);
- Log(str, 0);
- buf[0] = ERROR;
- write_to_sock(ns, buf, 1, OFF, debug2);
- write_to_sock(ns, local_copy, 80, OFF, debug2);
- }
-
-
- /*
- * Send the lookup-table (LT) to shared-array on CM
- */
- void
- send_table_to_CM()
- {
- unsigned int *iptr, i, j;
- unsigned char word[4];
-
- j = 0;
- iptr = (unsigned int *)word;
- for (i=0; i<TSIZE/4; i++) {
- if (!SUN) { /* have to worry about Sun vs. Vax byte-order again */
- word[0] = table[j++];
- word[1] = table[j++];
- word[2] = table[j++];
- word[3] = table[j++];
- }
- else {
- word[3] = table[j++];
- word[2] = table[j++];
- word[1] = table[j++];
- word[0] = table[j++];
- }
- CM_u_move_constant_1L(temp_value, *iptr, 32);
- CM_u_move_constant_1L(table_index, i, 13);
- CM_aset32_shared_2L(temp_value, trans, table_index, 32, 13, max_index);
- }
- }
-
-
- /*
- * Set up neighborhood & array-size characteristics, based on arguments
- */
- void
- set_params(args)
- char *args;
- {
- int i, err, n, tmp;
- char arg[80];
- double f1, f2, f3;
-
- B = 256;
- S = 8;
- L = 3;
- R = 1;
- function = 0;
- nhood = NH_VONN;
- while (sscanf(args, "%s", arg) == 1) {
- args += strlen(arg);
- while (*args == ' ')
- args++;
- switch (arg[0]) {
- case 'd': /* debug mode */
- debug = arg[1]-'0';
- break;
- case 'b': /* array size */
- err = sscanf(&arg[1],"%d",&n);
- if ((err != 1) || ((n != 128) && (n != 256) && (n != 512)))
- quit2("Illegal value %s for B",&arg[1]);
- B = n;
- break;
- case 'm':
- nhood = NH_MOORE;
- set_states(&arg[1]);
- break;
- case 'M':
- nhood = NH_MARG;
- set_states(&arg[1]);
- break;
- case 'v':
- nhood = NH_VONN;
- set_states(&arg[1]);
- break;
- case 'l':
- nhood = NH_LIN;
- set_states(&arg[1]);
- break;
- case 'r':
- err = sscanf(&arg[1], "%d", &R);
- if ((err != 1) || (R <= 0) || (R >3))
- quit("Illegal value for R");
- break;
- default:
- Log2("bad argument '%s'", arg, 0);
- quit("Bad arguments");
- break;
- }
- }
- if ((grid = (unsigned char *)malloc(B*B)) == NULL)
- quit("Could not allocate grid");
- if (S == 256)
- function = 1;
- L = 0;
- tmp = S;
- while (!(tmp & 0x01)) {
- tmp >>= 1;
- L++;
- }
-
- switch (nhood) {
- case NH_VONN:
- set_params_v();
- break;
- case NH_MOORE:
- set_params_m();
- break;
- case NH_MARG:
- set_params_marg();
- break;
- case NH_LIN:
- set_params_l();
- break;
- }
- Logd("L = %d", L, 1);
- Logd("N = %d", N, 1);
- Logd("S = %d", S, 1);
- if (nhood == NH_LIN)
- Logd("R = %d", R, 1);
- AMASK = S - 1;
- if (!function) {
- TSIZE = 1 << (L * N);
- Logd("tsize = %d\n",TSIZE, 1);
- if ((table = (unsigned char *)malloc(TSIZE)) == NULL)
- quit("Could not allocate table");
- max_index = TSIZE/4;
- }
-
-
- CM_init_stuff();
-
- init_cmfb();
- }
-
-
-
- /*
- * Initialize the frame-buffer, if there is one
- */
- void
- init_cmfb()
- {
- if (CMFB_EXISTS) {
- FB_attach_ret_val = CMFB_attach_display(NULL, &disp_id);
- if (FB_attach_ret_val)
- Logd("CMFB_attach_display returned %d (successfully attached)", FB_attach_ret_val, 0);
- if (FB_attach_ret_val) {
- CMFB_initialize_display(&disp_id, 8, 1);
- CMFB_initialize_color_table(&disp_id);
- CMFB_switch_buffer(&disp_id, CMFB_green);
- }
- else {
- Log("\n\n=======Could not attach to the CM frame-buffer!======", 0);
- Log("=======Execution will continue, but you won't see anything on the CM FB====\n\n", 0);
- }
- }
- else
- FB_attach_ret_val = 0;
- }
-
-
- /*
- * Set # of states
- */
- void
- set_states(str)
- char *str;
- {
- int n, err;
- if (str[0] == 0)
- return;
- err = sscanf(str,"%d",&n);
- if ((err != 1) || ((n != 2) && (n != 4) && (n != 8) && (n != 16) &&
- (n != 256)))
- quit2("Illegal value %s for S",str);
- else
- S = n;
- }
-
-
- /*
- * Send lookup table to CM, after reading it from client
- */
- void
- send_LT()
- {
- unsigned int *iptr, i, j, k, t1, t2, comsize, newlen;
- unsigned char word[4], buf[8], *table2;
- FILE *dumpfile;
-
- read_from_sock(ns, buf, 1, OFF, debug2);
- if (buf[0] == COMPRESSED) {
- Log("compressed\n", 1);
- }
- else {
- Log("uncompressed\n", 1);
- read_from_sock(ns, table, TSIZE, OFF, debug2);
- send_table_to_CM();
- CM_send_ack();
- }
- }
-
-
- /*
- * This is left over from debugging the code, it should never be called.
- */
- void
- get_LT()
- {
- }
-
-
- /*
- * Client is sending us an image; transfer it to the CM
- */
- void
- send_image()
- {
- unsigned char buf[8], *grid2;
- unsigned int t1, t2, comsize, newlen, ret_val;
-
- read_from_sock(ns, buf, 1, OFF, debug2);
- if (buf[0] == COMPRESSED) {
- Log("compressed\n", 1);
- }
- else {
- Log("uncompressed\n", 1);
- read_from_sock(ns, grid, B*B, OFF, debug2);
- }
- CM_u_write_to_news_array_1L(grid,
- offset_vector,
- start_vector,
- end_vector,
- axis_vector,
- cell,
- L,
- 2,
- dimension_vector,
- 1);
- if (use_FB && FB_attach_ret_val)
- CMFB_display_image();
- CM_send_ack();
- }
-
-
- /*
- * Probe the lookup table to find the result of the transition from
- * the neighborhood the client is sending us.
- */
- void
- cm_probe()
- {
- int x;
- unsigned char buf2[4];
-
- saved_x = CM_read_int();
- saved_y = CM_read_int();
- read_from_sock(ns, buf, 4, OFF, debug2);
- bcopy(buf, &x, 4);
- if (nhood == NH_MARG) {
- phase = CM_read_int();
- phase = phase%S;
- }
- probe_func(buf);
- Logd("probing nhood #%d\n", x, 1);
- Logd("probe returning %d\n", buf[0], 1);
- write_to_sock(ns, buf, 1, OFF, debug2
- );
- }
-
-
- /*
- * Run for a given number of steps (read the interval from client)
- */
- void
- run()
- {
- int num_steps, nthframes, i;
- unsigned char parm[4];
- struct timeval tp;
- struct timezone *tzp;
- long usec, sec;
- CM_timeval_t *cmtime;
-
- tzp = NULL;
- num_steps = CM_read_int();
- CM_disp_interval = CM_read_int();
- if (function) {
- parm1 = CM_read_int();
- parm2 = CM_read_int();
- }
- Logd("running for %d steps",num_steps, 1);
- if (nhood == NH_MARG) {
- phase = CM_read_int();
- phase = phase%S;
- }
- /* start timer */
- /*
- gettimeofday(&tp, tzp);
- sec = tp.tv_sec;
- usec = tp.tv_usec;
- */
-
- CM_set_context();
- /*
- CM_reset_timer();
- CM_start_timer();
- */
- auto_step(num_steps);
- /*
- cmtime = (CM_timeval_t *) CM_stop_timer();
- printf("timings:\n real = %f, cm = %f\n",
- cmtime->cmtv_real, cmtime->cmtv_cm);
- */
- CM_set_context();
-
- /* stop timer */
- /*
- gettimeofday(&tp, tzp);
- printf("%d seconds, %d useconds\n", tp.tv_sec-sec, tp.tv_usec-usec);
- */
-
- if (FB_attach_ret_val && use_FB)
- CMFB_display_image();
- CM_send_ack();
- }
-
-
-
- /*
- * Run until the client tells us to stop
- */
- void
- run_forever()
- {
- unsigned char buf[4];
- int num_steps;
- struct timeval tp;
- struct timezone *tzp;
- long usec, sec;
-
- tzp = NULL;
- if (function) {
- parm1 = CM_read_int();
- parm2 = CM_read_int();
- }
- if (nhood == NH_MARG) {
- phase = CM_read_int();
- phase = phase%S;
- Log("done reading phase from Sun\n",1);
- }
- CM_disp_interval = CM_read_int();
- Logd("display interval is %d", CM_disp_interval, 1);
- forever_flag = 1;
- CM_set_context();
- /* start timer */
- /*
- gettimeofday(&tp, tzp);
- sec = tp.tv_sec;
- usec = tp.tv_usec;
- */
-
- num_steps = auto_step(-1);
-
- /* stop timer */
- /*
- gettimeofday(&tp, tzp);
- printf("%d seconds, %d useconds\n", tp.tv_sec-sec, tp.tv_usec-usec);
- */
-
- CM_set_context();
- if (use_FB && FB_attach_ret_val)
- CMFB_display_image();
- Logd("num_steps = %d\n",num_steps, 1);
- forever_flag = 0;
- CM_send_int(num_steps); /* tell client how long we ran */
- }
-
-
- /*
- * Display the current image, on the CM frame-buffer (CMFB) and/or the
- * client's display (by sending the image through the socket to the client)
- */
- void
- display_image()
- {
- unsigned int newlen, se;
- unsigned char *grid2, buf[8];
- int ret_val;
-
- if (use_FB) {
- if (FB_attach_ret_val)
- CMFB_display_image();
- else
- Log("Remember, CMFB could not be initialized...", 0);
- }
- if (use_Sun_disp) {
- Log("sending image to sun...", 1);
- CM_u_read_from_news_array_1L(grid,
- offset_vector,
- start_vector,
- end_vector,
- axis_vector,
- cell,
- L,
- 2,
- dimension_vector,
- 1);
- read_from_sock(ns, buf, 1, OFF, debug2);
- if (buf[0] == COMPRESSED) {
- }
- else {
- write_to_sock(ns, grid, B*B, OFF, debug2);
- Logd("%d bytes written", B*B, 1);
- }
- Log("Done.", 1);
- }
- }
-
-
- /*
- * Change the current neighborhood configuration
- */
- void
- change_stuff()
- {
- char buf[80], arg[80];
- int i, j, tmp, oldnhood, oldS, oldL, oldN, oldR, oldfunction, err;
-
- read_from_sock(ns, buf, 80, OFF, debug2);
- Log2("Change-string is '%s'\n",buf, 1);
- i = 0;
- oldnhood = nhood;
- oldL = L;
- oldS = S;
- oldN = N;
- oldR = R;
- oldfunction = function;
- while (sscanf(&buf[i], "%s", arg) == 1) {
- i += strlen(arg);
- while (buf[i] == ' ')
- i++;
- switch (arg[0]) {
- case 'm':
- nhood = NH_MOORE;
- set_states(&arg[1]);
- break;
- case 'M':
- nhood = NH_MARG;
- set_states(&arg[1]);
- break;
- case 'v':
- nhood = NH_VONN;
- set_states(&arg[1]);
- break;
- case 'l':
- nhood = NH_LIN;
- set_states(&arg[1]);
- for (j=2; j<strlen(arg); j++) {
- if (arg[j] == 'r') {
- err = sscanf(&arg[j+1], "%d", &R);
- if ((err != 1) || (R <= 0) || (R > 3))
- quit("Illegal value for R");
- j = strlen(arg);
- }
- }
- break;
- case 'r':
- err = sscanf(&arg[1], "%d", &R);
- if ((err != 1) || (R <= 0) || (R > 3)) {
- R = 1;
- Logd("Illegal value for R (%d)", R, 0);
- }
- break;
- default:
- quit("Bad arguments to change_stuff() routine");
- break;
- }
- switch (nhood) {
- case NH_VONN:
- set_params_v();
- break;
- case NH_MOORE:
- set_params_m();
- break;
- case NH_MARG:
- set_params_marg();
- break;
- case NH_LIN:
- set_params_l();
- break;
- }
- tmp = S;
- L = 0;
- while (!(tmp & 0x01)) {
- tmp >>= 1;
- L++;
- }
- Logd("L = %d", L, 1);
- Logd("N = %d", N, 1);
- Logd("S = %d", S, 1);
- if (S == 256)
- function = 1;
- else
- function = 0;
- if ((nhood == oldnhood) && (S == oldS) && (R == oldR)) {
- Log("nhood didn't change", 0);
- CM_send_ack();
- return;
- }
- if (!oldfunction) {
- free(table);
- CM_deallocate_heap_field(trans);
- }
- else {
- if (exit_function) {
- exit_function();
- exit_function = NULL;
- initialization_function = NULL;
- }
- }
- if (!function) {
- TSIZE = 1 << (L * N);
- Logd("tsize = %d\n",TSIZE, 1);
- if ((table = (unsigned char *)malloc(TSIZE)) == NULL)
- quit("Could not allocate table");
- max_index = TSIZE/4;
- array_size = (TSIZE/CM_geometry_total_vp_ratio(geo))/4;
- trans = CM_allocate_heap_field(array_size);
- }
- CM_deallocate_heap_field(nbor_values);
- CM_logand_constant_2_1L(cell, S-1, 8);
- if (use_FB && FB_attach_ret_val)
- CMFB_display_image();
- nbor_values = CM_allocate_heap_field(L * N);
- VNorth = nbor_values + L * V_N_OFF;
- VSouth = nbor_values + L * V_S_OFF;
- VEast = nbor_values + L * V_E_OFF;
- VWest = nbor_values + L * V_W_OFF;
- VCenter = nbor_values + L * V_C_OFF;
- MNorth = nbor_values + L * M_N_OFF;
- MSouth = nbor_values + L * M_S_OFF;
- MEast = nbor_values + L * M_E_OFF;
- MWest = nbor_values + L * M_W_OFF;
- MNW = nbor_values + L * M_NW_OFF;
- MSW = nbor_values + L * M_SW_OFF;
- MNE = nbor_values + L * M_NE_OFF;
- MSE = nbor_values + L * M_SE_OFF;
- MCenter = nbor_values + L * M_C_OFF;
- MargCenter = nbor_values + L * MARG_C_OFF;
- MargCcw = nbor_values + L * MARG_CCW_OFF;
- MargOpp = nbor_values + L * MARG_OPP_OFF;
- MargCw = nbor_values + L * MARG_CW_OFF;
- MargPhase = nbor_values + L * MARG_PHASE_OFF;
- if (nhood == NH_LIN) {
- switch (R) {
- case 1:
- LR1_L = nbor_values + L * LR1_L_OFF;
- LR1_C = nbor_values + L * LR1_C_OFF;
- LR1_R = nbor_values + L * LR1_R_OFF;
- break;
- case 2:
- LR2_LL = nbor_values + L * LR2_LL_OFF;
- LR2_L = nbor_values + L * LR2_L_OFF;
- LR2_C = nbor_values + L * LR2_C_OFF;
- LR2_R = nbor_values + L * LR2_R_OFF;
- LR2_RR = nbor_values + L * LR2_RR_OFF;
- break;
- case 3:
- LR3_LLL = nbor_values + L * LR3_LLL_OFF;
- LR3_LL = nbor_values + L * LR3_LL_OFF;
- LR3_L = nbor_values + L * LR3_L_OFF;
- LR3_C = nbor_values + L * LR3_C_OFF;
- LR3_R = nbor_values + L * LR3_R_OFF;
- LR3_RR = nbor_values + L * LR3_RR_OFF;
- LR3_RRR = nbor_values + L * LR3_RRR_OFF;
- break;
- }
- }
- CM_set_context();
- CM_logand_constant_2_1L(cell, AMASK, 8);
- }
- CM_send_ack();
- }
-
-
-
- /*
- * Change image-size. This means we have to deallocate the current
- * VP-set and geometry (after deallocating all the fields), and recreate
- * a new one with the new geometry.
- */
- void
- change_image_size()
- {
- char buf[80], arg[80];
- int i, tmp, oldB, saved_parm1, saved_parm2;
-
- oldB = B;
- B = CM_read_int();
- if (B == oldB)
- return;
- CM_set_context();
- if (!function)
- CM_deallocate_heap_field(trans);
- CM_u_move_zero_1L(cell, 8);
- if (use_FB && FB_attach_ret_val)
- CMFB_display_image();
- CM_deallocate_heap_field(cell);
- CM_deallocate_heap_field(temp_value);
- CM_deallocate_heap_field(one);
- CM_deallocate_heap_field(table_index);
- CM_deallocate_heap_field(bottom);
- CM_deallocate_heap_field(not_bottom);
- CM_deallocate_heap_field(nbor_values);
- CM_deallocate_heap_field(UL);
- CM_deallocate_heap_field(UR);
- CM_deallocate_heap_field(LL);
- CM_deallocate_heap_field(LR);
- if (function) {
- if (exit_function) /* deallocate user-function stuff */
- exit_function();
- }
- CM_deallocate_vp_set(vp_set);
- CM_deallocate_geometry(geo);
- free(grid);
- if ((grid = (unsigned char *)malloc(B*B))==NULL)
- quit("Couldn't allocate memory for array on CMFE");
-
- CM_init_stuff();
- if (!function)
- send_table_to_CM();
- else {
- saved_parm1 = parm1;
- saved_parm2 = parm2;
- if (initialization_function) /* re-invoke user-fcn init-fcn, so it
- * can re-create any fields it needs */
- initialization_function();
- parm1 = saved_parm1;
- parm2 = saved_parm2;
- }
- CM_send_ack();
- }
-
-
- /*
- * Clear out the fields on the CM
- */
- void
- CM_uninit_stuff()
- {
- if (!function) {
- CM_deallocate_heap_field(trans);
- free(table);
- }
- CM_deallocate_heap_field(cell);
- CM_deallocate_heap_field(temp_value);
- CM_deallocate_heap_field(one);
- CM_deallocate_heap_field(table_index);
- CM_deallocate_heap_field(bottom);
- CM_deallocate_heap_field(not_bottom);
- CM_deallocate_heap_field(nbor_values);
- CM_deallocate_heap_field(UL);
- CM_deallocate_heap_field(UR);
- CM_deallocate_heap_field(LL);
- CM_deallocate_heap_field(LR);
- CM_deallocate_vp_set(vp_set);
- CM_deallocate_geometry(geo);
- free(grid);
- }
-
-
- /*
- * Allocate fields and stuff for the CM
- */
- void
- CM_init_stuff()
- {
- offset_vector[0] = 0;
- offset_vector[1] = 0;
- start_vector[0] = 0;
- start_vector[1] = 0;
- end_vector[0] = B;
- end_vector[1] = B;
- dimension_vector[0] = B;
- dimension_vector[1] = B;
- axis_vector[0] = 1;
- axis_vector[1] = 0;
- CM_set_context();
- geo_array[0] = B;
- geo_array[1] = B;
- geo = CM_create_geometry(geo_array, 2);
- vp_set = CM_allocate_vp_set(geo);
- CM_set_vp_set(vp_set);
-
- cell = CM_allocate_heap_field(8);
- temp_value = CM_allocate_heap_field(32);
- one = CM_allocate_heap_field(1);
- table_index = CM_allocate_heap_field(13);
- /* bottom & not_bottom used for 1-D rules */
- bottom = CM_allocate_heap_field(1);
- not_bottom = CM_allocate_heap_field(1);
- /* the next 4 are used to implement margolus neighborhood */
- UL = CM_allocate_heap_field(1);
- UR = CM_allocate_heap_field(1);
- LR = CM_allocate_heap_field(1);
- LL = CM_allocate_heap_field(1);
- if (!function) {
- array_size = (TSIZE/CM_geometry_total_vp_ratio(geo))/4;
- trans = CM_allocate_heap_field(array_size);
- }
- nbor_values = CM_allocate_heap_field(L * N);
- CM_set_context();
- CM_u_move_zero_1L(cell, 8);
- CM_u_move_zero_1L(bottom, 1);
- CM_my_news_coordinate_1L(temp_value, VERTICAL, 9);
- CM_u_eq_constant_1L(temp_value, B-1, 9);
- CM_logand_context_with_test();
- CM_u_move_constant_1L(bottom, 1, 1);
- CM_set_context();
- CM_lognot_2_1L(not_bottom, bottom, 1);
- CM_u_move_zero_1L(UL, 1);
- CM_u_move_zero_1L(UR, 1);
- CM_u_move_zero_1L(LR, 1);
- CM_u_move_zero_1L(LL, 1);
- CM_my_news_coordinate_1L(temp_value, HORIZONTAL, 9);
- CM_my_news_coordinate_1L(temp_value+1, VERTICAL, 9);
- CM_lognot_2_1L(temp_value+2, temp_value, 1);
- CM_lognot_2_1L(temp_value+3, temp_value+1, 1);
- CM_load_context(temp_value+2);
- CM_logand_context(temp_value+3);
- CM_u_move_constant_1L(UL, 1, 1);
- CM_load_context(temp_value+2);
- CM_logand_context(temp_value+1);
- CM_u_move_constant_1L(LL, 1, 1);
- CM_load_context(temp_value);
- CM_logand_context(temp_value+3);
- CM_u_move_constant_1L(UR, 1, 1);
- CM_load_context(temp_value);
- CM_logand_context(temp_value+1);
- CM_u_move_constant_1L(LR, 1, 1);
- CM_set_context();
- CM_u_move_constant_1L(one, 1, 1);
- VNorth = nbor_values + L * V_N_OFF;
- VSouth = nbor_values + L * V_S_OFF;
- VEast = nbor_values + L * V_E_OFF;
- VWest = nbor_values + L * V_W_OFF;
- VCenter = nbor_values + L * V_C_OFF;
- MNorth = nbor_values + L * M_N_OFF;
- MSouth = nbor_values + L * M_S_OFF;
- MEast = nbor_values + L * M_E_OFF;
- MWest = nbor_values + L * M_W_OFF;
- MNW = nbor_values + L * M_NW_OFF;
- MSW = nbor_values + L * M_SW_OFF;
- MNE = nbor_values + L * M_NE_OFF;
- MSE = nbor_values + L * M_SE_OFF;
- MCenter = nbor_values + L * M_C_OFF;
- MargCenter = nbor_values + L * MARG_C_OFF;
- MargCcw = nbor_values + L * MARG_CCW_OFF;
- MargOpp = nbor_values + L * MARG_OPP_OFF;
- MargCw = nbor_values + L * MARG_CW_OFF;
- MargPhase = nbor_values + L * MARG_PHASE_OFF;
- if (nhood == NH_LIN) {
- switch (R) {
- case 1:
- LR1_L = nbor_values + L * LR1_L_OFF;
- LR1_C = nbor_values + L * LR1_C_OFF;
- LR1_R = nbor_values + L * LR1_R_OFF;
- break;
- case 2:
- LR2_LL = nbor_values + L * LR2_LL_OFF;
- LR2_L = nbor_values + L * LR2_L_OFF;
- LR2_C = nbor_values + L * LR2_C_OFF;
- LR2_R = nbor_values + L * LR2_R_OFF;
- LR2_RR = nbor_values + L * LR2_RR_OFF;
- break;
- case 3:
- LR3_LLL = nbor_values + L * LR3_LLL_OFF;
- LR3_LL = nbor_values + L * LR3_LL_OFF;
- LR3_L = nbor_values + L * LR3_L_OFF;
- LR3_C = nbor_values + L * LR3_C_OFF;
- LR3_R = nbor_values + L * LR3_R_OFF;
- LR3_RR = nbor_values + L * LR3_RR_OFF;
- LR3_RRR = nbor_values + L * LR3_RRR_OFF;
- break;
- }
- }
- }
-
-
- /*
- * Read colormap from client, and send to FB
- */
- void
- send_cmap()
- {
- unsigned char buf[256];
- int i, clen;
-
- clen = 256;
- read_from_sock(ns, red, clen, OFF, debug2);
- read_from_sock(ns, green, clen, OFF, debug2);
- read_from_sock(ns, blue, clen, OFF, debug2);
- if (FB_attach_ret_val) {
- CMFB_write_color_table(&disp_id, CMFB_red, red);
- CMFB_write_color_table(&disp_id, CMFB_green, green);
- CMFB_write_color_table(&disp_id, CMFB_blue, blue);
- }
- CM_send_ack();
- }
-
-
- /*
- * Change the delay we pause between updates (sometimes necessary in order
- * to slow down the CM enough to watch stuff on the FB :-)
- */
- void
- change_delay()
- {
- unsigned char buf[4];
-
- CM_delay = CM_read_int();
- CM_send_ack();
- }
-
-
- /*
- * Client is telling us which display(s) to use, CMFB and/or client display
- */
- void
- set_displays()
- {
- unsigned char buf[4];
-
- read_from_sock(ns, buf, 1, OFF, debug2);
- Logd("set_displays parm = %d", buf[0], 1);
- use_FB = (buf[0] & 0x01);
- use_Sun_disp = (buf[0] & 0x02) >> 1;
- CM_send_ack();
- }
-
-
- /*
- * How often to display an image, when running
- */
- void
- set_disp_interval()
- {
- unsigned char buf[4];
-
- CM_disp_interval = CM_read_int();
- Logd("set disp interval to %d", CM_disp_interval, 1);
- CM_send_ack();
- }
-
-
- /*
- * Load an image from the CMFE disk
- */
- void
- load_image()
- {
- char fname[128], fname2[256];
- FILE *fp;
-
- read_from_sock(ns, fname, 128, OFF, debug2);
- if (expand_fname(fname,fname)) {
- CM_send_error(fname);
- return;
- }
- if (!strcmp(&fname[strlen(fname)-2], ".Z")) {
- load_image_compressed(fname);
- return;
- }
- Log2("fname is '%s'",fname, 1);
- if ((fp=fopen(fname, "r"))==NULL) {
- sprintf(fname2, "%s/%s", CM_image_dir, fname);
- if ((fp=fopen(fname, "r"))==NULL) {
- load_image_compressed(fname);
- return;
- }
- }
- if (read_image_from_fp(fp)) {
- fclose(fp);
- return;
- }
- fclose(fp);
- CM_send_ack();
- }
-
-
- /*
- * Load a compressed image from the CMFE disk
- */
- void
- load_image_compressed(fname)
- char *fname;
- {
- char fname2[256], cmdstr[256];
- FILE *fp;
- int err;
-
- if (strcmp(&fname[strlen(fname)-2], ".Z"))
- strcat(fname, ".Z");
- if (!stat(fname, &statbuf)) {
- sprintf(cmdstr, "uncompress -c %s", fname);
- if (!(fp = popen(cmdstr, "r"))) {
- Log("Error trying to open pipe to uncompress image", 0);
- CM_send_error("Error opening pipe");
- return;
- }
- }
- else {
- sprintf(fname2, "%s/%s", CM_image_dir, fname);
- if (stat(fname2, &statbuf)) {
- Log("No such image file", 0);
- CM_send_error("No such image file");
- return;
- }
- sprintf(cmdstr, "uncompress -c %s/%s", CM_image_dir, fname);
- if (!(fp = popen(cmdstr, "r"))) {
- Log("Error trying to open pipe to uncompress image", 0);
- CM_send_error("Error opening pipe");
- return;
- }
- }
- if (read_image_from_fp(fp)) {
- pclose(fp);
- return;
- }
- err = pclose(fp);
- if (err) {
- Logd("pclose returned %d", err, 0);
- CM_send_error("pclose() failed");
- return;
- }
- CM_send_ack();
- }
-
-
- int
- read_image_from_fp(fp)
- FILE *fp;
- {
- int bytes_left, count, ret_val;
-
- if (nhood == NH_LIN) {
- bytes_left = B;
- count = B*B-B;
- CM_u_read_from_news_array_1L(grid,
- offset_vector,
- start_vector,
- end_vector,
- axis_vector,
- cell,
- L,
- 2,
- dimension_vector,
- 1);
- }
- else {
- bytes_left = B*B;
- count = 0;
- }
- while (bytes_left) {
- if (!(ret_val = fread(grid+count, 1, bytes_left, fp))) {
- CM_send_error("Error reading file");
- return 1;
- }
- bytes_left -= ret_val;
- count += ret_val;
- }
- Log("done reading file... sending to CM", 1);
- CM_u_write_to_news_array_1L(grid,
- offset_vector,
- start_vector,
- end_vector,
- axis_vector,
- cell,
- L,
- 2,
- dimension_vector,
- 1);
- if (use_FB && FB_attach_ret_val)
- CMFB_display_image();
- return 0;
- }
-
-
-
- /*
- * Count the number of cells in each possible state, and tell client
- */
- void
- count_states()
- {
- int i;
- unsigned int x;
-
- /* count all the states, put into the state_count[] array,
- * then send to Sun */
- for (i=0; i < S; i++) {
- if (nhood == NH_LIN)
- CM_load_context(bottom);
- else
- CM_set_context();
- CM_u_eq_constant_1L(cell, i, L);
- CM_logand_context_with_test();
- x = CM_global_u_add_1L(one, 1);
- buf[i*4] = x%256;
- buf[i*4+1] = x/256;
- buf[i*4+2] = x/(256*256);
- buf[i*4+3] = x/(256*256*256);
- }
- write_to_sock(ns, buf, S*4, OFF, debug2);
- }
-
-
- /*
- * Generate quick (distributed evenly across all values, including 0)
- * random image
- */
- void
- quick_random()
- {
- CM_set_context();
- CM_u_random_1L(cell, 8, S);
- if (use_FB && FB_attach_ret_val)
- CMFB_display_image();
- CM_send_ack();
- }
-
-
- /*
- * More general random image routine
- */
- void
- general_random()
- {
- int ox, oy, sx, sy, density, min_val, max_val;
-
- CM_set_context();
- ox = CM_read_int();
- oy = CM_read_int();
- sx = CM_read_int();
- sy = CM_read_int();
- density = CM_read_int();
- min_val = CM_read_int();
- max_val = CM_read_int();
- CM_my_news_coordinate_1L(temp_value, HORIZONTAL, 10);
- CM_my_news_coordinate_1L(temp_value+10, VERTICAL, 10);
- /* make sure x-coord is > ox but < (ox+sx) (or ">=" and "<="?)
- * and similarly for oy
- * use that to set context-flag, then have active processors
- * generate a number in the appropriate range
- */
- CM_u_ge_constant_1L(temp_value, ox, 10);
- CM_logand_context_with_test();
- CM_u_lt_constant_1L(temp_value, ox+sx, 10);
- CM_logand_context_with_test();
- CM_u_ge_constant_1L(temp_value+10, oy, 10);
- CM_logand_context_with_test();
- CM_u_lt_constant_1L(temp_value+10, oy+sy, 10);
- CM_logand_context_with_test();
- CM_u_random_1L(temp_value, 7, 100);
- CM_u_lt_constant_1L(temp_value, density, 7);
- CM_logand_context_with_test();
- CM_u_random_1L(cell, 8, max_val - min_val + 1);
- CM_u_add_constant_2_1L(cell, min_val, 8);
- if (use_FB && FB_attach_ret_val)
- CMFB_display_image();
- CM_send_ack();
- CM_set_context();
- }
-
-
- /*
- * Clear out the current array on the CM
- */
- void
- CM_clear_array()
- {
- CM_u_move_zero_1L(cell,8);
- if (use_FB && FB_attach_ret_val)
- CMFB_display_image();
- CM_send_ack();
- }
-
-
- /*
- * Client wants to get image, so we send it
- */
- void
- CM_get_image()
- {
- Log("sending image to sun...", 1);
- CM_u_read_from_news_array_1L(grid,
- offset_vector,
- start_vector,
- end_vector,
- axis_vector,
- cell,
- L,
- 2,
- dimension_vector,
- 1);
- write_to_sock(ns, grid, B*B, OFF, debug2);
- Logd("%d bytes written", B*B, 1);
- Log("Done.", 1);
- }
-
-
-
- /*
- * Load a rule (LT or computed-fcn) from CMFE disk
- */
- void
- load_rule()
- {
- if (function)
- load_fcn();
- else
- load_LT();
- }
-
-
- /*
- * Load a computed-function rule (written in Paris)
- */
- void
- load_fcn()
- {
- char fname[128], fname2[256];
- struct stat statbuf;
-
- read_from_sock(ns, fname, 128, OFF, debug2);
- if (expand_fname(fname,fname)) {
- CM_send_error(fname);
- return;
- }
- strcpy(fname2, fname);
- Log2("fname is '%s'", fname, 1);
- if (stat(fname, &statbuf)) {
- sprintf(fname2, "%s/%s", CM_fcn_dir, fname);
- if (stat(fname2, &statbuf)) {
- CM_send_error("No such file");
- return;
- }
- }
- Log2("full filename is '%s'", fname2, 1);
- strcpy(saved_fcn_name, fname2);
- /* call previous function's exit-function, if it has one, to deallocate
- * any extra CM fields the rule was using */
- if (exit_function)
- exit_function();
- load_function_file(fname2);
- CM_send_ack();
- CM_send_int(parm1);
- CM_send_int(parm2);
- }
-
- /*
- * Actually load in the computed-function
- */
- void
- load_function_file(fname)
- char *fname;
- {
- Log("linking file...", 1);
- update_function = NULL;
- exit_function = NULL;
- initialization_function = (void_func_ptr) dynamic_load(argv0, fname);
- Logd("done linking, init_fcn = %d.", initialization_function, 1);
- initialization_function();
- Log("done initializing", 1);
- }
-
-
- /*
- * Load lookup table (LT) from CMFE disk
- */
- void
- load_LT()
- {
- char fname[128], fname2[256];
- FILE *fp;
- unsigned char word[4], buf[8];
- unsigned int *iptr, j, i;
-
- read_from_sock(ns, fname, 128, OFF, debug2);
- if (expand_fname(fname,fname)) {
- CM_send_error(fname);
- return;
- }
- if (!strcmp(&fname[strlen(fname)-2], ".Z")) {
- load_LT_compressed(fname);
- return;
- }
- Log2("fname is '%s'", fname, 1);
- if ((fp = fopen(fname, "r")) == NULL) {
- sprintf(fname2, "%s/%s", CM_LT_dir, fname);
- if ((fp=fopen(fname2, "r")) == NULL) {
- load_LT_compressed(fname);
- return;
- }
- }
- if (read_LT_from_fp(fp)) {
- fclose(fp);
- return;
- }
- fclose(fp);
- CM_send_ack();
- }
-
-
- void
- load_LT_compressed(fname)
- char *fname;
- {
- char fname2[256], cmdstr[256];
- FILE *fp;
- int err;
-
- if (strcmp(&fname[strlen(fname)-2], ".Z"))
- strcat(fname, ".Z");
- if (!stat(fname, &statbuf)) {
- sprintf(cmdstr, "uncompress -c %s", fname);
- if (!(fp = popen(cmdstr, "r"))) {
- Log("Error trying to open pipe to uncompress LT", 0);
- CM_send_error("Error opening pipe");
- return;
- }
- }
- else {
- sprintf(fname2, "%s/%s", CM_LT_dir, fname);
- if (stat(fname2, &statbuf)) {
- Log("No such LT file", 0);
- CM_send_error("No such LT file");
- return;
- }
- sprintf(cmdstr, "uncompress -c %s/%s", CM_LT_dir, fname);
- if (!(fp = popen(cmdstr, "r"))) {
- Log("Error trying to open pipe to uncompress LT", 0);
- CM_send_error("Error opening pipe");
- return;
- }
- }
- if (read_LT_from_fp(fp)) {
- pclose(fp);
- return;
- }
- err = pclose(fp);
- if (err) {
- Logd("pclose returned %d", err, 0);
- CM_send_error("pclose() failed");
- return;
- }
- CM_send_ack();
- }
-
-
-
- int
- read_LT_from_fp(fp)
- FILE *fp;
- {
- int bytes_left, count, ret_val;
-
- bytes_left = TSIZE;
- count = 0;
- while (bytes_left) {
- if (!(ret_val = fread(table+count, 1, bytes_left, fp))) {
- CM_send_error("Error reading file");
- return 1;
- }
- bytes_left -= ret_val;
- count += ret_val;
- }
- send_table_to_CM();
- return 0;
- }
-
-
- /*
- * Set directory to look for images in, when they can't be found in
- * current directory
- */
- void
- CM_set_image_dir()
- {
- read_from_sock(ns, CM_image_dir, 128, OFF, debug2);
- }
-
-
- /*
- * Get image-dir from CMFE to Sun
- */
- void
- CM_get_image_dir()
- {
- write_to_sock(ns, CM_image_dir, 128, OFF, debug2);
- }
-
-
-
- /*
- * Set default function dir
- */
- void
- CM_set_fcn_dir()
- {
- read_from_sock(ns, CM_fcn_dir, 128, OFF, debug2);
- }
-
-
- /*
- * Get fcn-dir from CMFE to Sun
- */
- void
- CM_get_fcn_dir()
- {
- write_to_sock(ns, CM_fcn_dir, 128, OFF, debug2);
- }
-
-
-
- /*
- * Set lookup-table dir
- */
- void
- CM_set_LT_dir()
- {
- read_from_sock(ns, CM_LT_dir, 128, OFF, debug2);
- }
-
-
- /*
- * Get LT dir from CMFE to Sun
- */
- void
- CM_get_LT_dir()
- {
- write_to_sock(ns, CM_LT_dir, 128, OFF, debug2);
- }
-
-
- /*
- * Find the full pathname of the program that is being executed,
- * so we can do dynamic linking if we need to.
- */
- void
- which(a0, result)
- char *a0, *result;
- {
- char *path, directory[256];
- int i, j;
- struct stat statbuf;
-
- if ((!strncmp(a0, "./", 2)) || (!strncmp(a0, "../", 3)) ||
- (a0[0] == '/')) {
- strcpy(result, a0);
- return;
- }
- if ((path = getenv("PATH")) == NULL)
- quit("Couldn't look up PATH from the environment!");
- i = 0;
- while (i < strlen(path)) {
- j = 0;
- while ((path[i] != ':') && (path[i] != '\0'))
- directory[j++] = path[i++];
- i++;
- directory[j++] = '/';
- directory[j++] = '\0';
- strcat(directory, a0);
- /* Now "directory" contains the next try */
- if (!stat(directory, &statbuf)) {
- strcpy(result, directory);
- return;
- }
- }
- }
-
-
- /*
- * Set zoom-factor (magnification level) for the CMFB
- */
- void
- set_zoom()
- {
- zoom_fac = CM_read_int();
- if (FB_attach_ret_val)
- /* CMFB_set_pan_and_zoom(&disp_id, pan_x, pan_y, zoom_fac, zoom_fac, 1); */
- CMFB_set_zoom(&disp_id, zoom_fac, zoom_fac, 0);
- /* CM_send_ack(); */
- }
-
-
- /*
- * Set pan (translational offsets) for CMFB
- */
- void
- set_pan()
- {
- pan_x = CM_read_int()-B/2;
- pan_y = CM_read_int()-B/2;
- if (FB_attach_ret_val)
- /* CMFB_set_pan_and_zoom(&disp_id, pan_x, pan_y, zoom_fac, zoom_fac,1); */
- CMFB_set_pan(&disp_id, pan_x, pan_y);
- /* CM_send_ack(); */
- }
-
-
- /*
- * Client wants state-count info when running
- */
- void
- enable_socket()
- {
- SOCKET_INUSE = 1;
- }
-
-
- /*
- * Client doesn't want state-count info when running
- */
- void
- disable_socket()
- {
- SOCKET_INUSE = 0;
- }
-
-
- /*
- * If cm_cell wasn't invoked by the cm_celld daemon, then we have to
- * wait for a client ourselves..
- */
- void
- get_client()
- {
- int addrlen;
- struct sockaddr addr;
- unsigned char buf[80];
-
- Log("waiting to accept client...", 0);
- addrlen = sizeof(struct sockaddr);
- if ((ns=wait_to_accept_socket(sock_fd, &addr, &addrlen, OFF, debug2))==-1)
- pquit("Couldn't wait for client");
- write_to_sock(ns, buf, 1, OFF, 0);
- Log("client accepted", 0);
- read_from_sock(ns, buf, 80, OFF, debug2);
- set_params(buf);
- }
-
-
- /*
- * Display image, using double-buffering
- */
- void
- CMFB_display_image()
- {
- static CMFB_buffer_id_t cmfb_buf=CMFB_green;
-
- if (cmfb_buf == CMFB_green) {
- CMFB_write_always(&disp_id, CMFB_blue, cell, 0, 0);
- CMFB_switch_buffer(&disp_id, CMFB_blue);
- }
- else {
- CMFB_write_always(&disp_id, CMFB_green, cell, 0, 0);
- CMFB_switch_buffer(&disp_id, CMFB_green);
- }
- }
-
-
-
- /*
- * Expand a "tilde" filename or filename with wildcards in it.
- */
- int
- expand_fname(src, dest)
- char *src, *dest;
- {
- FILE *fp;
- char command_str[256];
- int err, i;
-
- if (!strlen(src))
- return;
- sprintf(command_str, "/bin/sh -c \"/bin/csh -f -c '/bin/echo %s' 2>&1\"",src);
- if ((fp = popen(command_str, "r")) == NULL) {
- Log("Error trying to expand filename", 0);
- return 1;
- }
- fgets(dest, 128, fp);
- if ((dest[strlen(dest)-1] == '\n') || (dest[strlen(dest)-1] == '\r'))
- dest[strlen(dest)-1] = '\0';
- if ((!strncmp(dest,"Unknown user",12))||(!strncmp(dest,"No match.",9))) {
- Log(dest, 0);
- pclose(fp);
- return 1;
- }
- for (i=0; i<strlen(dest); i++)
- if (dest[i] == ' ') { /* multiple matches */
- Log("Multiple filenames matched.", 0);
- return 1;
- }
- if (strlen(dest) == 0) {
- Log("error trying to expand filename", 0);
- return 1;
- }
- err = pclose(fp);
- if (err) {
- Log("Error trying to expand filename", 0);
- return 1;
- }
- return 0;
- }
-
-
-
-
- /*
- * Null procedure, to hold a place in the array of routines
- */
- void
- null_proc()
- {
- }
-
-
-
- /*
- * There doesn't seem to be a usleep (microsecond sleep) routine in
- * the Vax C library, so we have to define one.
- * Yes, I know, this isn't really microseconds, it's just a counter;
- * I'll make this do real microseconds one of these days.
- */
- #if (SUN==0)
- usleep(delay)
- int delay;
- {
- int i, j;
-
- for (i=0; i<delay; i++)
- j = i; /* make sure the compiler doesn't optimize out this loop */
- }
- #endif
-
-