123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <grass/gis.h>
- #include <grass/dbmi.h>
- #include <grass/form.h>
- #ifdef HAVE_SOCKET
- #include <sys/types.h>
- #ifdef __MINGW32__
- #include <winsock.h>
- #else /*__MINGW32__*/
- #include <sys/socket.h>
- #include <netinet/in.h>
- #endif /*__MINGW32__*/
- #endif /*HAVE_SOCKET */
- #ifdef HAVE_SOCKET
- static int make_socketpair(int *);
- #endif
- int first = 1;
- /* the pipe to send data to GUI */
- FILE *parent_send, *parent_recv;
- #ifdef HAVE_SOCKET
- int pipefd[2];
- #define pfd pipefd[1] /* parent's end */
- #define cfd pipefd[0] /* child's end */
- #endif /*HAVE_SOCKET */
- /* Open new form
- *
- * returns: 0 success
- */
- #ifdef __MINGW32__
- int F_open(char *title, char *html)
- {
- G_fatal_error("F_open is not supported on Windows");
- return 1;
- }
- #else
- int F_open(char *title, char *html)
- {
- /* parent */
- int c;
- /* common */
- static int pid;
- #ifndef HAVE_SOCKET
- static int p1[2], p2[2];
- #endif /*HAVE_SOCKET */
- int length;
- /* child */
- G_debug(2, "F_open(): title = %s", title);
- if (first) {
- #ifdef HAVE_SOCKET
- if (make_socketpair(pipefd) < 0)
- G_fatal_error("Cannot make socket pair");
- #else
- if (pipe(p1) < 0 || pipe(p2) < 0)
- G_fatal_error("Cannot open pipe");
- #endif /*HAVE_SOCKET */
- if ((pid = fork()) < 0)
- G_fatal_error("Cannot create fork");
- }
- if (pid == 0) { /* Child */
- char command[2000], script[2000];
- G_debug(2, "CHILD");
- /* Note: If you are forking in a Tk based apllication you
- * must execl before doing any window operations in the
- * child or you will receive an error from the X server */
- close(0);
- close(1);
- #ifndef HAVE_SOCKET
- close(p1[1]);
- close(p2[0]);
- if (dup(p1[0]) != 0)
- G_fatal_error("Form: cannot dup() input");
- if (dup(p2[1]) != 1)
- G_fatal_error("Form: cannot dup() output");
- #else
- close(pfd);
- if (dup(cfd) != 0)
- G_fatal_error("Form: cannot dup() input");
- if (dup(cfd) != 1)
- G_fatal_error("Form: cannot dup() output");
- #endif /*HAVE_SOCKET */
- sprintf(command, "%s/etc/form/form", G_gisbase());
- sprintf(script, "%s/etc/form/form.tcl", G_gisbase());
- execl(command, "form", "-f", script, NULL);
- G_debug(2, "CHILD END\n");
- exit(0);
- }
- else { /* Parent */
- G_debug(2, "PARENT");
- if (first) {
- #ifndef HAVE_SOCKET
- parent_send = fdopen(p1[1], "w");
- close(p1[0]);
- parent_recv = fdopen(p2[0], "r");
- close(p2[1]);
- #else
- close(cfd);
- parent_send = fdopen(pfd, "w");
- parent_recv = fdopen(pfd, "r");
- #endif /*HAVE_SOCKET */
- first = 0;
- }
- G_debug(2, "PARENT HTML:\n%s\n", html);
- fprintf(parent_send, "O");
- length = strlen(title);
- fprintf(parent_send, "%d\n", length);
- fprintf(parent_send, "%s", title);
- length = strlen(html);
- fprintf(parent_send, "%d\n", length);
- fprintf(parent_send, "%s", html);
- fflush(parent_send);
- G_debug(2, "PARENT: Request sent\n");
- /* Wait for response */
- c = fgetc(parent_recv);
- G_debug(2, "PARENT: received %c\n", c);
- }
- return 0;
- }
- #endif
- /* Clear old forms from window
- *
- */
- void F_clear(void)
- {
- char c;
- G_debug(2, "F_clear()");
- if (first)
- return;
- fprintf(parent_send, "C");
- fflush(parent_send);
- c = fgetc(parent_recv);
- G_debug(2, "PARENT: received %c\n", c);
- }
- void F_close(void)
- {
- char c;
- G_debug(2, "F_close()");
- if (first)
- return;
- fprintf(parent_send, "D");
- fflush(parent_send);
- c = fgetc(parent_recv);
- G_debug(2, "PARENT: received %c\n", c);
- first = 1;
- }
- #ifdef HAVE_SOCKET
- static int make_socketpair(int *fd)
- {
- int n;
- if ((n = socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, fd)) < 0)
- return -1;
- else
- return 0;
- }
- #endif
|