start.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <libgen.h>
  5. #include <grass/gis.h>
  6. #include <grass/spawn.h>
  7. #include <grass/display.h>
  8. #include <grass/glocale.h>
  9. #include "proto.h"
  10. static char *start(const char *, const char *, int, int, int);
  11. static char *start_wx(const char *, const char *, int, int, int);
  12. static void error_handler(void *);
  13. /* start file-based monitor */
  14. char *start(const char *name, const char *output, int width, int height, int update)
  15. {
  16. char *output_path;
  17. const char *output_name;
  18. /* stop monitor on failure */
  19. G_add_error_handler(error_handler, (char *)name);
  20. /* full path for output file */
  21. output_path = (char *) G_malloc(GPATH_MAX);
  22. output_path[0] = '\0';
  23. if (!output) {
  24. char buff[512];
  25. sprintf(buff, "GRASS_RENDER_IMMEDIATE=%s", name);
  26. putenv(G_store(buff));
  27. sprintf(buff, "GRASS_RENDER_WIDTH=%d", width);
  28. putenv(G_store(buff));
  29. sprintf(buff, "GRASS_RENDER_HEIGHT=%d", height);
  30. putenv(G_store(buff));
  31. D_open_driver();
  32. output_name = D_get_file();
  33. if (!output_name)
  34. return NULL;
  35. if (!update && access(output_name, F_OK) == 0) {
  36. if (G_get_overwrite()) {
  37. G_warning(_("File <%s> already exists and will be overwritten"), output_name);
  38. D_setup_unity(0);
  39. D_erase("white");
  40. }
  41. else {
  42. D_close_driver();
  43. G_fatal_error(_("option <%s>: <%s> exists. To overwrite, use the --overwrite flag"),
  44. "output", output_name);
  45. }
  46. }
  47. D_close_driver(); /* must be called after check because this
  48. * function produces default map file */
  49. putenv("GRASS_RENDER_IMMEDIATE=");
  50. }
  51. else {
  52. char *dir_name;
  53. output_name = output;
  54. /* check write permission */
  55. dir_name = G_store(output_name);
  56. if (access(dirname(dir_name), W_OK) != 0)
  57. G_fatal_error(_("Unable to start monitor, don't have "
  58. "write permission for <%s>"), output_name);
  59. G_free(dir_name);
  60. /* check if file exists */
  61. if (!update && access(output_name, F_OK) == 0) {
  62. if (G_get_overwrite()) {
  63. G_warning(_("File <%s> already exists and will be overwritten"), output_name);
  64. if (0 != unlink(output_name))
  65. G_fatal_error(_("Unable to delete <%s>"), output_name);
  66. }
  67. }
  68. }
  69. if (!strchr(output_name, HOST_DIRSEP)) { /* relative path */
  70. char *ptr;
  71. if (!getcwd(output_path, GPATH_MAX))
  72. G_fatal_error(_("Unable to get current working directory"));
  73. ptr = output_path + strlen(output_path) - 1;
  74. if (*(ptr++) != HOST_DIRSEP) {
  75. *(ptr++) = HOST_DIRSEP;
  76. *(ptr) = '\0';
  77. }
  78. strcat(output_path, output_name);
  79. G_message(_("Output file: %s"), output_path);
  80. }
  81. else {
  82. strcpy(output_path, output_name); /* already full path */
  83. }
  84. return output_path;
  85. }
  86. /* start wxGUI display monitor */
  87. char *start_wx(const char *name, const char *element, int width, int height, int x_only)
  88. {
  89. char progname[GPATH_MAX], mon_path[GPATH_MAX];
  90. char str_width[1024], str_height[1024], *str_x_only;
  91. char *mapfile;
  92. /* full path */
  93. mapfile = (char *) G_malloc(GPATH_MAX);
  94. mapfile[0] = '\0';
  95. sprintf(progname, "%s/gui/wxpython/mapdisp/main.py", G_gisbase());
  96. sprintf(str_width, "%d", width);
  97. sprintf(str_height, "%d", height);
  98. if (x_only)
  99. str_x_only = "1";
  100. else
  101. str_x_only = "0";
  102. G_file_name(mon_path, element, NULL, G_mapset());
  103. G_spawn_ex(getenv("GRASS_PYTHON"), progname, progname,
  104. name, mon_path, str_width, str_height, str_x_only, SF_BACKGROUND, NULL);
  105. G_file_name(mapfile, element, "map.ppm", G_mapset());
  106. return mapfile;
  107. }
  108. int start_mon(const char *name, const char *output, int select,
  109. int width, int height, const char *bgcolor,
  110. int truecolor, int x_only, int update)
  111. {
  112. char *mon_path;
  113. char *out_file, *env_file, *cmd_file, *leg_file;
  114. char buf[1024];
  115. char file_path[GPATH_MAX], render_cmd_path[GPATH_MAX];
  116. int fd;
  117. if (check_mon(name)) {
  118. const char *curr_mon;
  119. curr_mon = G_getenv_nofatal("MONITOR");
  120. if (select && (!curr_mon || strcmp(curr_mon, name) != 0))
  121. G_setenv("MONITOR", name);
  122. G_fatal_error(_("Monitor <%s> already running"), name);
  123. }
  124. G_verbose_message(_("Starting monitor <%s>..."), name);
  125. /* create .tmp/HOSTNAME/u_name directory */
  126. mon_path = get_path(name, FALSE);
  127. G_make_mapset_element(mon_path);
  128. G_file_name(file_path, mon_path, "env", G_mapset());
  129. env_file = G_store(file_path);
  130. G_file_name(file_path, mon_path, "cmd", G_mapset());
  131. cmd_file = G_store(file_path);
  132. G_file_name(file_path, mon_path, "leg", G_mapset());
  133. leg_file = G_store(file_path);
  134. /* create py file (renderer) */
  135. sprintf(render_cmd_path, "%s/etc/d.mon/render_cmd.py", getenv("GISBASE"));
  136. G_file_name(file_path, mon_path, "render.py", G_mapset());
  137. G_debug(1, "Monitor name=%s, pyfile = %s", name, file_path);
  138. if (1 != G_copy_file(render_cmd_path, file_path))
  139. G_fatal_error(_("Unable to copy render command file"));
  140. /* start monitor */
  141. if (strncmp(name, "wx", 2) == 0)
  142. out_file = start_wx(name, mon_path, width, height, x_only);
  143. else
  144. out_file = start(name, output, width, height, update);
  145. /* create env file (environmental variables used for rendering) */
  146. G_debug(1, "Monitor name=%s, envfile=%s", name, env_file);
  147. fd = creat(env_file, 0666);
  148. if (fd < 0)
  149. G_fatal_error(_("Unable to create file <%s>"), env_file);
  150. if (G_strncasecmp(name, "wx", 2) == 0) {
  151. sprintf(buf, "GRASS_RENDER_IMMEDIATE=default\n"); /* TODO: read settings from wxGUI */
  152. write(fd, buf, strlen(buf));
  153. sprintf(buf, "GRASS_RENDER_FILE_READ=FALSE\n");
  154. write(fd, buf, strlen(buf));
  155. sprintf(buf, "GRASS_RENDER_TRANSPARENT=TRUE\n");
  156. write(fd, buf, strlen(buf));
  157. }
  158. else {
  159. sprintf(buf, "GRASS_RENDER_IMMEDIATE=%s\n", name);
  160. write(fd, buf, strlen(buf));
  161. sprintf(buf, "GRASS_RENDER_FILE_READ=TRUE\n");
  162. write(fd, buf, strlen(buf));
  163. }
  164. sprintf(buf, "GRASS_RENDER_FILE=%s\n", out_file);
  165. write(fd, buf, strlen(buf));
  166. sprintf(buf, "GRASS_RENDER_WIDTH=%d\n", width);
  167. write(fd, buf, strlen(buf));
  168. sprintf(buf, "GRASS_RENDER_HEIGHT=%d\n", height);
  169. write(fd, buf, strlen(buf));
  170. sprintf(buf, "GRASS_LEGEND_FILE=%s\n", leg_file);
  171. write(fd, buf, strlen(buf));
  172. if (bgcolor) {
  173. if (strcmp(bgcolor, "none") == 0)
  174. sprintf(buf, "GRASS_RENDER_TRANSPARENT=TRUE\n");
  175. else
  176. sprintf(buf, "GRASS_RENDER_BACKGROUNDCOLOR=%s\n", bgcolor);
  177. write(fd, buf, strlen(buf));
  178. }
  179. if (truecolor) {
  180. sprintf(buf, "GRASS_RENDER_TRUECOLOR=TRUE\n");
  181. write(fd, buf, strlen(buf));
  182. }
  183. close(fd);
  184. /* create cmd file (list of GRASS display commands to render) */
  185. G_debug(1, "Monitor name=%s, cmdfile = %s", name, cmd_file);
  186. if (0 > creat(cmd_file, 0666))
  187. G_fatal_error(_("Unable to create file <%s>"), cmd_file);
  188. /* select monitor if requested */
  189. if (select)
  190. G_setenv("MONITOR", name);
  191. G_free(mon_path);
  192. G_free(out_file);
  193. G_free(env_file);
  194. return 0;
  195. }
  196. void error_handler(void *p)
  197. {
  198. const char *name = (const char *) p;
  199. stop_mon(name);
  200. }