#include #ifdef HAVE_SOCKET #include #include #include #include #include #include #include #include #include #include #include "transport.h" #include "open.h" #define BUFFERSIZ 2048 int _rfd, _wfd; int _quiet; extern int unlock_driver(int); int sync_driver(char *); static unsigned char outbuf[BUFFERSIZ]; static int cursiz; static volatile int no_mon; static RETSIGTYPE dead(int); static int _get(char *buf, int n) { int x; while (n > 0) { x = read(_rfd, buf, n); if (x <= 0) { fprintf(stderr, _("ERROR %s from graphics driver.\n"), x ? "reading" : "eof"); exit(1); } n -= x; buf += x; } return 0; } static int flushout(void) { if (cursiz) { write(_wfd, outbuf, (size_t) cursiz); cursiz = 0 ; } return 0; } int _send_ident(int anint) { unsigned char achar ; achar = anint; if ((cursiz+2) >= BUFFERSIZ) flushout() ; outbuf[cursiz++] = COMMAND_ESC ; outbuf[cursiz++] = achar ; return 0; } int _send_char(const unsigned char *achar) { if ((cursiz+2) >= BUFFERSIZ) flushout() ; outbuf[cursiz++] = *achar ; if (*achar == COMMAND_ESC) outbuf[cursiz++] = 0 ; return 0; } int _send_char_array(int num, const unsigned char *achar) { while (num-- > 0) _send_char(achar++); return 0; } int _send_int_array(int num, const int *anint) { return _send_char_array(num * sizeof(int), (const unsigned char *) anint); } int _send_float_array(int num, const float *afloat) { return _send_char_array(num * sizeof(float), (const unsigned char *) afloat); } int _send_int(const int *anint) { return _send_char_array(sizeof(int), (const unsigned char *) anint); } int _send_float(const float *afloat) { return _send_char_array(sizeof(float), (const unsigned char *) afloat); } int _send_text(const char *text) { return _send_char_array(1 + strlen(text), (const unsigned char *) text); } int _get_char(char *achar) { flushout() ; _get(achar, 1); return 0; } int _get_int(int *anint) { flushout() ; _get((char *)anint, sizeof(int)); return 0; } int _get_float(float *afloat) { flushout() ; _get((char *)afloat, sizeof(float)); return 0; } int _get_text(char *buf) { char *b; b = buf; do _get_char(b); while (*b++ != 0); return 0; } char *_get_text_2(void) { static char *buf; static int len; int i; for (i = 0; ; i++) { if (i >= len) { len += 1000; buf = G_realloc(buf, len); if (!buf) { fprintf(stderr, _("Unable to allocate memory\n")); exit(1); } } _get_char(&buf[i]); if (!buf[i]) break; } return buf; } int REM__open_quiet(void) { _quiet = 1; return 0; } int sync_driver(char *name) { RETSIGTYPE (*sigalarm)(int); int try; int count; unsigned char c; _send_ident(BEGIN); flushout(); /* * look for at least BEGIN_SYNC_COUNT zero bytes * then look for COMMAND_ESC * * try twice. first timeout is warning, second is fatal */ count = 0; sigalarm = signal(SIGALRM, dead); for (try = 0; try < 2; try++) { no_mon = 0; alarm(try?10:5); while(no_mon == 0) { if (read(_rfd, &c, (size_t) 1) != 1) { if (no_mon) break; /* from while */ fprintf(stderr, _("ERROR - eof from graphics monitor.\n")); exit(-1); } if (c == 0) count++; else if (c == COMMAND_ESC && count >= BEGIN_SYNC_COUNT) break; else count = 0; /* start over */ } alarm(0); signal(SIGALRM, sigalarm); if (no_mon == 0) return 1; /* ok! */ if (try) break; fprintf(stderr, _("Warning - no response from graphics monitor <%s>.\n"), name); fprintf(stderr, _("Check to see if the mouse is still active.\n")); signal(SIGALRM, dead); } fprintf(stderr, _("ERROR - no response from graphics monitor <%s>.\n"), name); exit(-1); } static RETSIGTYPE dead(int sig) { no_mon = 1 ; } int _hold_signals(int hold) { static RETSIGTYPE (*sigint)(int); static RETSIGTYPE (*sigquit)(int); if (hold) { sigint = signal(SIGINT, SIG_IGN); sigquit = signal(SIGQUIT, SIG_IGN); } else { signal(SIGINT, sigint); signal(SIGQUIT, sigquit); } return 0; } /*! * \brief synchronize graphics * * Send all pending graphics commands to the graphics driver and cause * all pending graphics to be drawn (provided the driver is written to * comply). This function is called automatically when the graphics driver * closes (R_close_driver()). Otherwise it only needs to be used * within a module for flushing interactive graphics. * * \param void * \return int */ int REM_stabilize(void) { char c; flushout(); _send_ident(RESPOND); _get_char(&c); return 0; } int REM_kill_driver(void) { char dummy; _send_ident(GRAPH_CLOSE); flushout(); read(_rfd, &dummy, 1); R_release_driver(); return 0; } /*! * \brief terminate graphics * * This routine breaks the connection with the graphics driver opened by R_open_driver(). * * \param void * \return int */ int REM_close_driver(void) { R_stabilize(); close(_rfd); close(_wfd); _wfd = _rfd = -1; unlock_driver(0); return 0; } int REM_release_driver(void) { close(_rfd); close(_wfd); _wfd = _rfd = -1; unlock_driver(1); return 0; } #endif /* HAVE_SOCKET */