GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <grass/config.h> 00002 00003 #ifdef HAVE_SOCKET 00004 00005 #include <stdio.h> 00006 #include <stdlib.h> 00007 #include <signal.h> 00008 #include <string.h> 00009 #include <unistd.h> 00010 #include <errno.h> 00011 00012 #include <grass/gis.h> 00013 #include <grass/glocale.h> 00014 #include <grass/raster.h> 00015 #include <grass/graphics.h> 00016 00017 #include "transport.h" 00018 #include "open.h" 00019 00020 #define BUFFERSIZ 2048 00021 00022 int _rfd, _wfd; 00023 int _quiet; 00024 00025 int sync_driver(char *); 00026 00027 static unsigned char outbuf[BUFFERSIZ]; 00028 static int cursiz; 00029 static volatile int no_mon; 00030 00031 static RETSIGTYPE dead(int); 00032 00033 static int _get(char *buf, int n) 00034 { 00035 int x; 00036 00037 while (n > 0) { 00038 x = read(_rfd, buf, n); 00039 if (x <= 0) { 00040 fprintf(stderr, _("ERROR %s from graphics driver.\n"), 00041 x ? "reading" : "eof"); 00042 exit(1); 00043 } 00044 n -= x; 00045 buf += x; 00046 } 00047 00048 return 0; 00049 } 00050 00051 static int flushout(void) 00052 { 00053 if (cursiz) { 00054 write(_wfd, outbuf, (size_t) cursiz); 00055 cursiz = 0; 00056 } 00057 00058 return 0; 00059 } 00060 00061 int _send_ident(int anint) 00062 { 00063 unsigned char achar; 00064 00065 achar = anint; 00066 00067 if ((cursiz + 2) >= BUFFERSIZ) 00068 flushout(); 00069 outbuf[cursiz++] = COMMAND_ESC; 00070 outbuf[cursiz++] = achar; 00071 00072 return 0; 00073 } 00074 00075 int _send_char(const unsigned char *achar) 00076 { 00077 if ((cursiz + 2) >= BUFFERSIZ) 00078 flushout(); 00079 outbuf[cursiz++] = *achar; 00080 if (*achar == COMMAND_ESC) 00081 outbuf[cursiz++] = 0; 00082 00083 return 0; 00084 } 00085 00086 int _send_char_array(int num, const unsigned char *achar) 00087 { 00088 while (num-- > 0) 00089 _send_char(achar++); 00090 00091 return 0; 00092 } 00093 00094 int _send_int_array(int num, const int *anint) 00095 { 00096 return _send_char_array(num * sizeof(int), (const unsigned char *)anint); 00097 } 00098 00099 int _send_float_array(int num, const float *afloat) 00100 { 00101 return _send_char_array(num * sizeof(float), 00102 (const unsigned char *)afloat); 00103 } 00104 00105 int _send_int(const int *anint) 00106 { 00107 return _send_char_array(sizeof(int), (const unsigned char *)anint); 00108 } 00109 00110 int _send_float(const float *afloat) 00111 { 00112 return _send_char_array(sizeof(float), (const unsigned char *)afloat); 00113 } 00114 00115 int _send_text(const char *text) 00116 { 00117 return _send_char_array(1 + strlen(text), (const unsigned char *)text); 00118 } 00119 00120 int _get_char(char *achar) 00121 { 00122 flushout(); 00123 _get(achar, 1); 00124 00125 return 0; 00126 } 00127 00128 int _get_int(int *anint) 00129 { 00130 flushout(); 00131 _get((char *)anint, sizeof(int)); 00132 00133 return 0; 00134 } 00135 00136 int _get_float(float *afloat) 00137 { 00138 flushout(); 00139 _get((char *)afloat, sizeof(float)); 00140 00141 return 0; 00142 } 00143 00144 int _get_text(char *buf) 00145 { 00146 char *b; 00147 00148 b = buf; 00149 do 00150 _get_char(b); 00151 while (*b++ != 0); 00152 00153 return 0; 00154 } 00155 00156 char *_get_text_2(void) 00157 { 00158 static char *buf; 00159 static int len; 00160 int i; 00161 00162 for (i = 0;; i++) { 00163 if (i >= len) { 00164 len += 1000; 00165 buf = G_realloc(buf, len); 00166 if (!buf) { 00167 fprintf(stderr, _("Unable to allocate memory\n")); 00168 exit(1); 00169 } 00170 } 00171 _get_char(&buf[i]); 00172 if (!buf[i]) 00173 break; 00174 } 00175 00176 return buf; 00177 } 00178 00179 int REM__open_quiet(void) 00180 { 00181 _quiet = 1; 00182 00183 return 0; 00184 } 00185 00186 int sync_driver(char *name) 00187 { 00188 #ifndef __MINGW32__ 00189 RETSIGTYPE(*sigalarm) (int); 00190 #endif 00191 int try; 00192 int count; 00193 unsigned char c; 00194 00195 _send_ident(BEGIN); 00196 flushout(); 00197 00198 /* 00199 * look for at least BEGIN_SYNC_COUNT zero bytes 00200 * then look for COMMAND_ESC 00201 * 00202 * try twice. first timeout is warning, second is fatal 00203 */ 00204 count = 0; 00205 #ifndef __MINGW32__ 00206 sigalarm = signal(SIGALRM, dead); 00207 #endif 00208 for (try = 0; try < 2; try++) { 00209 no_mon = 0; 00210 #ifndef __MINGW32__ 00211 alarm(try ? 10 : 5); 00212 #endif 00213 while (no_mon == 0) { 00214 if (read(_rfd, &c, (size_t) 1) != 1) { 00215 if (no_mon) 00216 break; /* from while */ 00217 fprintf(stderr, _("ERROR - eof from graphics monitor.\n")); 00218 exit(-1); 00219 } 00220 if (c == 0) 00221 count++; 00222 else if (c == COMMAND_ESC && count >= BEGIN_SYNC_COUNT) 00223 break; 00224 else 00225 count = 0; /* start over */ 00226 } 00227 #ifndef __MINGW32__ 00228 alarm(0); 00229 signal(SIGALRM, sigalarm); 00230 #endif 00231 if (no_mon == 0) 00232 return 1; /* ok! */ 00233 if (try) 00234 break; 00235 00236 fprintf(stderr, 00237 _("Warning - no response from graphics monitor <%s>.\n"), 00238 name); 00239 fprintf(stderr, _("Check to see if the mouse is still active.\n")); 00240 #ifndef __MINGW32__ 00241 signal(SIGALRM, dead); 00242 #endif 00243 } 00244 fprintf(stderr, _("ERROR - no response from graphics monitor <%s>.\n"), 00245 name); 00246 exit(-1); 00247 } 00248 00249 static RETSIGTYPE dead(int sig) 00250 { 00251 no_mon = 1; 00252 } 00253 00254 void _hold_signals(int hold) 00255 { 00256 static RETSIGTYPE(*sigint) (int); 00257 00258 #ifdef SIGQUIT 00259 static RETSIGTYPE(*sigquit) (int); 00260 #endif 00261 00262 if (hold) { 00263 sigint = signal(SIGINT, SIG_IGN); 00264 #ifdef SIGQUIT 00265 sigquit = signal(SIGQUIT, SIG_IGN); 00266 #endif 00267 } 00268 else { 00269 signal(SIGINT, sigint); 00270 #ifdef SIGQUIT 00271 signal(SIGQUIT, sigquit); 00272 #endif 00273 } 00274 } 00275 00289 void REM_stabilize(void) 00290 { 00291 char c; 00292 00293 flushout(); 00294 _send_ident(RESPOND); 00295 _get_char(&c); 00296 } 00297 00298 void REM_kill_driver(void) 00299 { 00300 char dummy; 00301 00302 _send_ident(GRAPH_CLOSE); 00303 flushout(); 00304 read(_rfd, &dummy, 1); 00305 R_release_driver(); 00306 } 00307 00317 void REM_close_driver(void) 00318 { 00319 R_stabilize(); 00320 00321 close(_rfd); 00322 close(_wfd); 00323 _wfd = _rfd = -1; 00324 } 00325 00326 void REM_release_driver(void) 00327 { 00328 close(_rfd); 00329 close(_wfd); 00330 _wfd = _rfd = -1; 00331 } 00332 00333 #endif /* HAVE_SOCKET */