📄 gv_utils.c
字号:
/* ***************************************************** * * SaVi by Robert Thurman (thurman@geom.umn.edu) and * Patrick Worfolk (worfolk@alum.mit.edu). * * Copyright (c) 1997 by The Geometry Center. * This file is part of SaVi. SaVi is free software; * you can redistribute it and/or modify it only under * the terms given in the file COPYRIGHT which you should * have received along with this file. SaVi may be * obtained from: * http://savi.sourceforge.net/ * http://www.geom.uiuc.edu/locate/SaVi * ***************************************************** * * gv_utils.c * * $Id: gv_utils.c,v 1.15 2005/02/12 15:52:33 lloydwood Exp $ */#include <stdio.h>#include <math.h>#include <string.h>/* #include <bstring.h> *//* for select */#include <unistd.h>#include <sys/time.h>#include <sys/types.h>#include <netinet/in.h>/* #include <sys/select.h> *//* WARNING - not strictly correct !!! *//* extern int select(int, int *, int *, int *, struct timeval *); */#include "utils.h"#include "gv_file.h"#include "gv_utils.h"#include "constants.h"#include "globals.h"extern void gv_delayed_view_update(void);static unsigned char GV_LITTLE_ENDIAN = 1;static unsigned char GV_BIG_ENDIAN = 2;/* * variable to see if an acknowledgement request has been sent * accessed by gv_set_ready and gv_ready */static unsigned int gv_ack = FALSE;/* * if depth nesting ever goes negative, it's a bug. */static int progn_depth = 0;/* * get information on floating point storage type. * Suggested by Stuart Levy on geomview-users, November 2000 */unsigned chartest_ieee_float(){ static float testfloat = 40970.25; static unsigned char testle[] = { 0x40, 0x0a, 0x20, 0x47 }; static unsigned char testbe[] = { 0x47, 0x20, 0x0a, 0x40 }; if(sizeof(testfloat) != 4) return 0; /* wrong float size */ if(memcmp( &testfloat, testle, 4 ) == 0) return GV_LITTLE_ENDIAN; /* OK, little-endian */ if(memcmp( &testfloat, testbe, 4 ) == 0) return GV_BIG_ENDIAN; /* OK, big-endian */ return 0; /* non-IEEE, or something */}unsigned chargv_stream_init_proc(){ /* * Redirect stdout to stderr and close stdin */ int fdout, fdin, fderr; fdout = dup(fileno(stdout)); if (fdout == NOT_OK) { error("failure to set up output pipe to control Geomview."); return FALSE; } fdin = dup(fileno(stdin)); if (fdin == NOT_OK) { error("a problem was encountered with input pipe handling under Geomview."); } else { gv_in = fdopen(fdin, "r"); if (gv_in) { fclose(stdin); stdin = fopen("/dev/null", "r"); } else { error("a problem was encountered in resetting the input pipe."); } } gv_out = fdopen(fdout, "a"); if (gv_out) { fderr = dup(fileno(stderr)); fclose(stdout); if (fderr == NOT_OK) { error("a problem was encountered with error pipe handling under Geomview."); } else { stdout = fdopen(fderr, "a"); } } else { error("failure to open output pipe to control Geomview."); return FALSE; } return TRUE;}/* * gv_init_proc * * Call to initialize any variables, if necessary. * */unsigned chargv_init_proc(){ unsigned char gv_binary_format_available; gv_binary_format_available = test_ieee_float();#ifndef TEST_FOR_GV_BINARY_FORMAT error("can't use Geomview binary format on this architecture."); gv_binary_format_available = 0;#endif return gv_binary_format_available;}/* * gv_send * * Sends a string to geomview */voidgv_send(const char *buf){ if (!geomview_module) return; fprintf(gv_out, "%s", buf);}/* * gv_version * * Returns a pointer to a string containing the version of geomview */char *gv_version(){ static char version_str[256]; unsigned int c; char *p; /* request version from geomview */ gv_wait(); gv_send("(echo (geomview-version))\n"); fflush(gv_out); /* get a double quote */ do { c = fgetc(gv_in); } while (c != '"'); /* read in characters until another double quote is found */ p = version_str; do { *p = (char) fgetc(gv_in); } while ((*(p++)) != '"'); /* overwrite final double quote with a string terminator */ *(--p) = '\0'; return version_str;}/* * gv_send_binary_ints * * Sends long ints in (big endian) binary format to geomview * To convert to big endian format, use htonl_buffer * */voidgv_send_binary_ints(const u_int32_t *buf, unsigned int n){ fwrite((const void *) buf, 4, n, gv_out);}/* * gv_send_binary_shorts * * Sends short ints in (big endian) binary format to geomview * To convert to big endian format, use htons_buffer * */voidgv_send_binary_shorts(const u_int16_t *buf, unsigned int n){ fwrite((const void *) buf, 2, n, gv_out);}/* * gv_send_binary_floats * * Sends floats in (big endian) binary format to geomview * To convert to big endian format, use htonl_buffer * Presumes that a float is a 32-bit (4-byte) word. * */voidgv_send_binary_floats(const float *buf, unsigned int n){ fwrite((const void *) buf, 4, n, gv_out);}/* * gv_sendfile * * Sends a file to geomview */unsigned intgv_sendfile(const char *filename){ return copyfile(gv_out, filename);}/* * gv_wait * * Waits until geomview is up to date */voidgv_wait(){ while (!gv_ready()); /* just in case something is waiting already */ gv_set_ready(); while (!gv_ready());}/* * gv_begin * * Sets up beginning of block of commands. * */voidgv_begin(){ if (!geomview_module) { error("gv_begin() called although not running as Geomview module."); return; } if (0 == progn_depth++) { fprintf(gv_out, "(progn\n"); }}voidgv_start(){ if (!geomview_module) { error("gv_start() called although not running as Geomview module."); return; } if (0 == progn_depth++) { fprintf(gv_out, "(progn\n"); }}/* * gv_end * * Ends block of commands and flushes buffer */voidgv_end(){ if (!geomview_module) { error("gv_end() called although not running as Geomview module."); return; } if (--progn_depth == 0) { gv_delayed_view_update(); fprintf(gv_out, ")\n"); fflush(gv_out); } else if (progn_depth < 0) { error("gv_end() called more than gv_begin()! Nesting symmetry broken."); }}/* * gv_stop * As gv_end(), but doesn't call gv_delayed_view_update() to update everything. */voidgv_stop(){ if (!geomview_module) { error("gv_stop() called although not running as Geomview module."); return; } if (--progn_depth == 0) { fprintf(gv_out, ")\n"); fflush(gv_out); } else if (progn_depth < 0) { error("gv_stop() called too often! Nesting symmetry broken."); }}/* * gv_transform * * Defines transform name using matrix m. */voidgv_transform(const char *name, double m[4][4]){ unsigned int i, j; fprintf(gv_out, "(read transform {transform define %s\n", name); for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) fprintf(gv_out, "%g ", m[i][j]); fprintf(gv_out, "})\n");}/* * gv_create_geom * * Create geomview object name as the transformation tname * applied to the object hname. */voidgv_create_geom(const char *name, const char *tname, const char *hname){ fprintf(gv_out, "(geometry %s { INST transform :%s geom :%s} )\n", name, tname, hname);}/* * gv_create_geomh * * Create geomview object name from handle hname. */voidgv_create_geomh(const char *name, const char *hname){ fprintf(gv_out, "(geometry %s { :%s } )\n", name, hname);}/* * gv_create_alienh * * Create geomview object name from handle hname. */voidgv_create_alienh(const char *name, const char *hname){ fprintf(gv_out, "(new-alien %s { :%s } )\n", name, hname);}/* * gv_delete_geom(char *name) * * Deletes geomview object name */voidgv_delete_geom(const char *name){ fprintf(gv_out, "(delete %s)\n", name);}/* * gv_delete_handle(char *name) * * Deletes geomview handle object */voidgv_delete_handle(const char *name){ fprintf(gv_out, "(read geometry {define %s {} })\n", name);}/* * gv_ui_freeze(int flag) * * If flag is TRUE then geomview interface is frozen * else if FALSE it is reactivated. Currently unused. */voidgv_ui_freeze(int flag){ if (!flag) { fprintf(gv_out, "(ui-freeze off)\n"); fflush(gv_out); } else { fprintf(gv_out, "(ui-freeze on)\n"); }}/* * send msg to gv so that we can later test if it is ready */voidgv_set_ready(){ if (gv_ack) return; fprintf(gv_out, "(echo \"\\n\")\n"); fflush(gv_out); gv_ack = TRUE;}/* * returns true if GV has returned the last acknowledgement * sent by gv_set_ready */unsigned intgv_ready(){ char c; static struct timeval poll = { 0, 100000 }; fd_set fds; FD_ZERO(&fds); FD_SET(fileno(gv_in), &fds); /* if nothing to wait for then ready */ if (!gv_ack) gv_set_ready(); if (select(fileno(gv_in) + 1, &fds, NULL, NULL, &poll) > 0) { c = getc(gv_in); if (c != '\n') fprintf(stderr, "gv_ready: error, got char: %c (%d)\n", c, c); gv_ack = FALSE; if (debug) { putc('|', stderr); putc('\n', stderr); } return TRUE; } if (debug) putc('.', stderr); return FALSE;}char *gv_begin_cmd(int argc, char *argv[]){ if (geomview_module) { gv_begin(); } return EMPTY_str;}char *gv_end_cmd(int argc, char *argv[]){ if (geomview_module) { gv_end(); } return EMPTY_str;}char *gv_wait_cmd(int argc, char *argv[]){ gv_wait(); return EMPTY_str;}char *gv_send_cmd(int argc, char *argv[]){ if (!geomview_module) return EMPTY_str; if (argc == 3) { gv_begin(); gv_send(argv[2]); gv_end(); } else { error_format("gv_send_cmd: savi %s needs 1 argument", argv[1]); } return EMPTY_str;}/* * htonl_buffer * * Converts an array of unsigned ints from host format * to native (big endian) format. * This is for writing in binary format to Geomview and * requires use of an unsigned 32-bit word. */voidhtonl_buffer(u_int32_t *buf, unsigned int n){ /* * if we are not little-endian, do nothing. */ if (GV_BINARY_FORMAT_AVAILABLE != GV_LITTLE_ENDIAN) return; while ((n--) > 0) { *buf = htonl(*buf); buf++; }}/* * htons_buffer * * Converts an array of unsigned shorts from host format * to native (big endian) format. * This is for writing in binary format to Geomview and * requires use of an unsigned 16-bit (two-byte) word. */voidhtons_buffer(u_int16_t *buf, unsigned int n){ /* * if we are not little-endian, do nothing. */ if (GV_BINARY_FORMAT_AVAILABLE != GV_LITTLE_ENDIAN) return; while ((n--) > 0) { *buf = htons(*buf); buf++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -