PageRenderTime 57ms CodeModel.GetById 16ms RepoModel.GetById 2ms app.codeStats 0ms

/source/src/Texmacs/Server/tm_server.cpp

http://itexmacs.googlecode.com/
C++ | 454 lines | 359 code | 58 blank | 37 comment | 93 complexity | 2658d32767ec485bafd7ff8740beca0d MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.0
  1. /******************************************************************************
  2. * MODULE : tm_server.cpp
  3. * DESCRIPTION: The TeXmacs server
  4. * COPYRIGHT : (C) 1999 Joris van der Hoeven
  5. *******************************************************************************
  6. * This software falls under the GNU general public license version 3 or later.
  7. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
  8. * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
  9. ******************************************************************************/
  10. #include "config.h"
  11. #include "tm_server.hpp"
  12. #include "drd_std.hpp"
  13. #include "convert.hpp"
  14. #include "connect.hpp"
  15. #include "sys_utils.hpp"
  16. #include "file.hpp"
  17. #include "dictionary.hpp"
  18. #include "tm_link.hpp"
  19. #include "socket_notifier.hpp"
  20. server* the_server= NULL;
  21. bool texmacs_started= false;
  22. url tm_init_file= url_none ();
  23. url my_init_file= url_none ();
  24. string my_init_cmds= "";
  25. /******************************************************************************
  26. * Execution of commands
  27. ******************************************************************************/
  28. void reset_inclusions ();
  29. extern string printing_dpi;
  30. extern string printing_cmd;
  31. extern string printing_on;
  32. extern int nr_windows;
  33. /******************************************************************************
  34. * Texmacs server constructor and destructor
  35. ******************************************************************************/
  36. void
  37. texmacs_interpose_handler () {
  38. if (the_server != NULL)
  39. (*the_server)->interpose_handler ();
  40. }
  41. void
  42. texmacs_wait_handler (string message, string arg, int level) {
  43. (void) level;
  44. if (texmacs_started && the_server != NULL)
  45. (*the_server)->wait_handler (message, arg);
  46. }
  47. server
  48. get_server () {
  49. ASSERT (the_server != NULL, "TeXmacs server not yet started");
  50. return *the_server;
  51. }
  52. bool
  53. in_presentation_mode () {
  54. return get_server () -> in_full_screen_mode ();
  55. }
  56. tree
  57. get_subtree (path p) {
  58. return get_server()->get_editor()->the_subtree (p);
  59. }
  60. void
  61. gui_set_output_language (string lan) {
  62. set_output_language (lan);
  63. get_server () -> refresh ();
  64. gui_refresh ();
  65. }
  66. server_rep::server_rep () {}
  67. server_rep::~server_rep () {}
  68. tm_server_rep::tm_server_rep ():
  69. vw (NULL), def_sfactor (5),
  70. style_cache (hashmap<string,tree> (UNINIT)),
  71. style_drd (tree (COLLECTION))
  72. {
  73. the_server= tm_new<server> (this);
  74. initialize_guile ();
  75. gui_interpose (texmacs_interpose_handler);
  76. set_wait_handler (texmacs_wait_handler);
  77. if (is_none (tm_init_file))
  78. tm_init_file= "$TEXMACS_PATH/progs/init-texmacs.scm";
  79. if (is_none (my_init_file))
  80. my_init_file= "$TEXMACS_HOME_PATH/progs/my-init-texmacs.scm";
  81. bench_start ("initialize scheme");
  82. if (exists (tm_init_file)) exec_file (tm_init_file);
  83. if (exists (my_init_file)) exec_file (my_init_file);
  84. bench_cumul ("initialize scheme");
  85. if (my_init_cmds != "") {
  86. my_init_cmds= "(dialogue" * my_init_cmds * ")";
  87. exec_delayed (scheme_cmd (my_init_cmds));
  88. }
  89. #ifdef OS_GNU_LINUX
  90. return; // in order to avoid segmentation faults
  91. #elif defined OS_POWERPC_GNU_LINUX
  92. return; // in order to avoid segmentation faults
  93. #endif
  94. }
  95. tm_server_rep::~tm_server_rep () {}
  96. server::server (): rep (tm_new<tm_server_rep> ()) {}
  97. /******************************************************************************
  98. * Get and set objects associated to server
  99. ******************************************************************************/
  100. server_rep*
  101. tm_server_rep::get_server () {
  102. return this;
  103. }
  104. bool
  105. tm_server_rep::has_view () {
  106. return vw != NULL;
  107. }
  108. bool
  109. tm_server_rep::has_window () {
  110. return vw != NULL && vw->win != NULL;
  111. }
  112. tm_view
  113. tm_server_rep::get_view (bool must_be_valid) {
  114. ASSERT (!must_be_valid || vw != NULL, "no active view");
  115. return vw;
  116. }
  117. void
  118. tm_server_rep::set_view (tm_view vw2) {
  119. vw= vw2;
  120. if (vw != NULL)
  121. the_drd= vw->ed->drd;
  122. }
  123. tm_buffer
  124. tm_server_rep::get_buffer () {
  125. tm_view vw= get_view ();
  126. return vw->buf;
  127. }
  128. editor
  129. tm_server_rep::get_editor () {
  130. tm_view vw= get_view ();
  131. // cout << "Get editor" << vw->ed << "\n";
  132. return vw->ed;
  133. }
  134. tm_window
  135. tm_server_rep::get_window () {
  136. tm_view vw= get_view ();
  137. ASSERT (vw->win != NULL, "no window attached to view");
  138. return vw->win;
  139. }
  140. int
  141. tm_server_rep::get_nr_windows () {
  142. return nr_windows;
  143. }
  144. /******************************************************************************
  145. * The style and package menus
  146. ******************************************************************************/
  147. static string
  148. compute_style_menu (url u, int kind) {
  149. if (is_or (u)) {
  150. string sep= "\n";
  151. if (is_atomic (u[1]) &&
  152. ((is_concat (u[2]) && (u[2][1] != "CVS") && (u[2][1] != ".svn")) ||
  153. (is_or (u[2]) && is_concat (u[2][1]))))
  154. sep= "\n---\n";
  155. return
  156. compute_style_menu (u[1], kind) * sep *
  157. compute_style_menu (u[2], kind);
  158. }
  159. if (is_concat (u)) {
  160. string dir= upcase_first (as_string (u[1]));
  161. string sub= compute_style_menu (u[2], kind);
  162. if ((dir == "Test") || (dir == "Obsolete") ||
  163. (dir == "CVS") || (dir == ".svn")) return "";
  164. return "(-> \"" * dir * "\" " * sub * ")";
  165. }
  166. if (is_atomic (u)) {
  167. string l = as_string (u);
  168. if (!ends (l, ".ts")) return "";
  169. l= l(0, N(l)-3);
  170. string cmd ("init-style");
  171. if (kind == 1) cmd= "init-add-package";
  172. if (kind == 2) cmd= "init-remove-package";
  173. return "((verbatim \"" * l * "\") (" * cmd * " \"" * l * "\"))";
  174. }
  175. return "";
  176. }
  177. object
  178. tm_server_rep::get_style_menu () {
  179. url sty_u= descendance ("$TEXMACS_STYLE_ROOT");
  180. string sty= compute_style_menu (sty_u, 0);
  181. return eval ("(menu-dynamic " * sty * ")");
  182. }
  183. object
  184. tm_server_rep::get_add_package_menu () {
  185. url pck_u= descendance ("$TEXMACS_PACKAGE_ROOT");
  186. string pck= compute_style_menu (pck_u, 1);
  187. return eval ("(menu-dynamic " * pck * ")");
  188. }
  189. object
  190. tm_server_rep::get_remove_package_menu () {
  191. url pck_u= descendance ("$TEXMACS_PACKAGE_ROOT");
  192. string pck= compute_style_menu (pck_u, 2);
  193. return eval ("(menu-dynamic " * pck * ")");
  194. }
  195. /******************************************************************************
  196. * Caching style files
  197. ******************************************************************************/
  198. static string
  199. cache_file_name (tree t) {
  200. if (is_atomic (t)) return t->label;
  201. else {
  202. string s;
  203. int i, n= N(t);
  204. for (i=0; i<n; i++)
  205. s << "__" << cache_file_name (t[i]);
  206. return s * "__";
  207. }
  208. }
  209. void
  210. tm_server_rep::style_clear_cache () {
  211. style_cache=
  212. hashmap<tree,hashmap<string,tree> > (hashmap<string,tree> (UNINIT));
  213. remove ("$TEXMACS_HOME_PATH/system/cache" * url_wildcard ("__*"));
  214. int i, j, n= N(bufs);
  215. for (i=0; i<n; i++) {
  216. tm_buffer buf= ((tm_buffer) bufs[i]);
  217. for (j=0; j<N(buf->vws); j++)
  218. ((tm_view) (buf->vws[j]))->ed->init_style ();
  219. }
  220. }
  221. void
  222. tm_server_rep::style_set_cache (tree style, hashmap<string,tree> H, tree t) {
  223. // cout << "set cache " << style << LF;
  224. style_cache (copy (style))= H;
  225. style_drd (copy (style))= t;
  226. url name ("$TEXMACS_HOME_PATH/system/cache", cache_file_name (style));
  227. if (!exists (name)) {
  228. save_string (name, tree_to_scheme (tuple ((tree) H, t)));
  229. // cout << "saved " << name << LF;
  230. }
  231. }
  232. void
  233. tm_server_rep::style_get_cache (
  234. tree style, hashmap<string,tree>& H, tree& t, bool& f)
  235. {
  236. //cout << "get cache " << style << LF;
  237. if ((style == "") || (style == tree (TUPLE))) { f= false; return; }
  238. f= style_cache->contains (style);
  239. if (f) {
  240. H= style_cache [style];
  241. t= style_drd [style];
  242. }
  243. else {
  244. string s;
  245. url name ("$TEXMACS_HOME_PATH/system/cache", cache_file_name (style));
  246. if (exists (name) && (!load_string (name, s, false))) {
  247. //cout << "loaded " << name << LF;
  248. tree p= scheme_to_tree (s);
  249. H= hashmap<string,tree> (UNINIT, p[0]);
  250. t= p[1];
  251. style_cache (copy (style))= H;
  252. style_drd (copy (style))= t;
  253. f= true;
  254. }
  255. }
  256. }
  257. /******************************************************************************
  258. * Miscellaneous routines
  259. ******************************************************************************/
  260. void
  261. tm_server_rep::refresh () {
  262. path p= windows_list ();
  263. while (!is_nil (p)) {
  264. tm_view vw= window_find_view (p->item);
  265. vw->win->refresh ();
  266. p= p->next;
  267. }
  268. }
  269. void
  270. tm_server_rep::interpose_handler () {
  271. #ifdef QTTEXMACS
  272. // TeXmacs/Qt handles delayed messages and socket notification
  273. // in its own runloop
  274. #ifndef QTPIPES
  275. perform_select ();
  276. #endif
  277. process_all_pipes ();
  278. #else
  279. perform_select ();
  280. exec_pending_commands ();
  281. #endif
  282. int i,j;
  283. for (i=0; i<N(bufs); i++) {
  284. tm_buffer buf= (tm_buffer) bufs[i];
  285. for (j=0; j<N(buf->vws); j++) {
  286. tm_view vw= (tm_view) buf->vws[j];
  287. if (vw->win != NULL) vw->ed->apply_changes ();
  288. }
  289. for (j=0; j<N(buf->vws); j++) {
  290. tm_view vw= (tm_view) buf->vws[j];
  291. if (vw->win != NULL) vw->ed->animate ();
  292. }
  293. }
  294. }
  295. void
  296. tm_server_rep::wait_handler (string message, string arg) {
  297. show_wait_indicator (get_window () -> win, translate (message), arg);
  298. }
  299. void
  300. tm_server_rep::set_script_status (int i) {
  301. script_status= i;
  302. }
  303. void
  304. tm_server_rep::focus_on_editor (editor ed) {
  305. int i,j;
  306. for (i=0; i<N(bufs); i++) {
  307. tm_buffer buf= (tm_buffer) bufs[i];
  308. for (j=0; j<N(buf->vws); j++) {
  309. tm_view vw= (tm_view) buf->vws[j];
  310. if (vw->ed == ed) {
  311. set_view (vw);
  312. return;
  313. }
  314. }
  315. }
  316. FAILED ("invalid situation");
  317. }
  318. void
  319. tm_server_rep::set_printing_command (string cmd) {
  320. printing_cmd= cmd;
  321. }
  322. void
  323. tm_server_rep::set_printer_page_type (string type) {
  324. printing_on= type;
  325. }
  326. string
  327. tm_server_rep::get_printer_page_type () {
  328. return printing_on;
  329. }
  330. void
  331. tm_server_rep::set_printer_dpi (string dpi) {
  332. printing_dpi= dpi;
  333. }
  334. void
  335. tm_server_rep::set_default_shrinking_factor (int sf) {
  336. def_sfactor= sf;
  337. }
  338. int
  339. tm_server_rep::get_default_shrinking_factor () {
  340. return def_sfactor;
  341. }
  342. void
  343. tm_server_rep::image_gc (string which) {
  344. ::image_gc (which);
  345. typeset_update_all ();
  346. }
  347. void
  348. tm_server_rep::inclusions_gc (string which) {
  349. (void) which;
  350. reset_inclusions ();
  351. typeset_update_all ();
  352. }
  353. void
  354. tm_server_rep::typeset_update (path p) {
  355. int i, j, n= N(bufs);
  356. for (i=0; i<n; i++) {
  357. tm_buffer buf= ((tm_buffer) bufs[i]);
  358. for (j=0; j<N(buf->vws); j++)
  359. ((tm_view) (buf->vws[j]))->ed->typeset_invalidate (p);
  360. }
  361. }
  362. void
  363. tm_server_rep::typeset_update_all () {
  364. int i, j, n= N(bufs);
  365. for (i=0; i<n; i++) {
  366. tm_buffer buf= ((tm_buffer) bufs[i]);
  367. for (j=0; j<N(buf->vws); j++)
  368. ((tm_view) (buf->vws[j]))->ed->typeset_invalidate_all ();
  369. }
  370. }
  371. bool
  372. tm_server_rep::is_yes (string s) {
  373. s= locase_all (s);
  374. return
  375. (s == "ano") || (s == "a") ||
  376. (s == "yes") || (s == "y") ||
  377. (s == "oui") || (s == "o") ||
  378. (s == "ja") || (s == "j") ||
  379. (s == "si") || (s == "s") ||
  380. (s == "sim") || (s == "s") ||
  381. (s == "tak") || (s == "t");
  382. }
  383. void
  384. tm_server_rep::quit () {
  385. close_all_pipes ();
  386. call ("quit-TeXmacs-scheme");
  387. clear_pending_commands ();
  388. exit (0);
  389. }
  390. /******************************************************************************
  391. * System commands
  392. ******************************************************************************/
  393. void
  394. tm_server_rep::shell (string s) {
  395. system (s);
  396. }