2
/******************************************************************************
3
* MODULE : tm_server.cpp
4
* DESCRIPTION: The TeXmacs server
5
* COPYRIGHT : (C) 1999 Joris van der Hoeven
6
*******************************************************************************
7
* This software falls under the GNU general public license and comes WITHOUT
8
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
9
* If you don't have this file, write to the Free Software Foundation, Inc.,
10
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
11
******************************************************************************/
13
#include "tm_server.hpp"
14
#include "convert.hpp"
15
#include "connect.hpp"
16
#include "sys_utils.hpp"
18
#include "pipe_link.hpp"
19
#include "socket_link.hpp"
21
server* the_server= NULL;
22
url tm_init_file= url_none ();
23
url my_init_file= url_none ();
24
string my_init_cmds= "";
26
void reset_inclusions ();
27
extern string printing_dpi;
28
extern string printing_cmd;
29
extern string printing_on;
30
extern int nr_windows;
31
extern window (*get_current_window) (void);
33
/******************************************************************************
34
* Creation of TeXmacs window
35
******************************************************************************/
37
int geometry_w= 800, geometry_h= 600;
38
int geometry_x= 0 , geometry_y= 0;
41
texmacs_window (widget wid) {
43
int w= geometry_w, h= geometry_h;
44
int x= geometry_x, y= geometry_y;
45
wid->dis->get_extents (W, H); W /= PIXEL; H /= PIXEL;
46
if (x < 0) x= W + x + 1 - w;
47
if (y < 0) y= H + y + 1 - h;
48
return plain_window (wid, "TeXmacs", w*PIXEL, h*PIXEL, x*PIXEL, (-y)*PIXEL);
51
/******************************************************************************
52
* Texmacs server constructor and destructor
53
******************************************************************************/
56
texmacs_interpose_handler () {
57
if (the_server != NULL)
58
(*the_server)->interpose_handler ();
62
texmacs_wait_handler (string message, string arg, int level) {
64
if (the_server != NULL)
65
(*the_server)->wait_handler (message, arg);
69
texmacs_current_window () {
70
if (the_server == NULL)
71
fatal_error ("No server", "texmacs_current_window", "tm_server.cpp");
72
return (*the_server)->get_window()->win;
77
if (the_server == NULL)
78
fatal_error ("TeXmacs server not yet started", "get_server");
82
server_rep::server_rep () {}
83
server_rep::~server_rep () {}
85
tm_server_rep::tm_server_rep (display dis2):
86
dis (dis2), vw (NULL), banner_nr (-1), full_screen (false), def_sfactor (5),
87
style_cache (hashmap<string,tree> (UNINIT)),
88
style_drd (tree (COLLECTION))
90
the_server= new server (this);
92
set_interpose_handler (texmacs_interpose_handler);
93
set_wait_handler (texmacs_wait_handler);
94
get_current_window= texmacs_current_window;
95
out_lan= dis->get_output_language ();
96
if (is_none (tm_init_file))
97
tm_init_file= "$TEXMACS_PATH/progs/init-texmacs.scm";
98
if (is_none (my_init_file))
99
my_init_file= "$TEXMACS_HOME_PATH/progs/my-init-texmacs.scm";
100
if (exists (tm_init_file)) exec_file (tm_init_file);
101
if (exists (my_init_file)) exec_file (my_init_file);
102
if (my_init_cmds != "") {
103
my_init_cmds= "(begin" * my_init_cmds * ")";
104
exec_delayed (my_init_cmds);
106
style_update_menu ();
108
return; // in order to avoid segmentation faults
109
#elif defined OS_POWERPC_GNU_LINUX
110
return; // in order to avoid segmentation faults
115
tm_server_rep::advance_banner () {
117
if (get_editor()->et != tree (DOCUMENT, "")) banner_nr=5;
119
static string banner[4]= {
120
"Welcome to GNU TeXmacs",
121
"GNU TeXmacs falls under the GNU general public license",
122
"GNU TeXmacs comes without any form of legal warranty",
123
"More information about GNU TeXmacs can be found in the Help->About menu"
125
set_message (banner[banner_nr], "GNU TeXmacs " TEXMACS_VERSION);
126
dis->delayed_message (get_meta(), "banner", 2500);
129
else if (banner_nr == 4) set_message ("", "");
132
tm_server_rep::~tm_server_rep () {}
133
server::server (display dis): rep (new tm_server_rep (dis)) {}
135
/******************************************************************************
136
* Get and set objects associated to server
137
******************************************************************************/
140
tm_server_rep::get_server () {
145
tm_server_rep::get_display () {
150
tm_server_rep::has_view () {
155
tm_server_rep::get_view (bool must_be_valid) {
156
if (must_be_valid && (vw==NULL))
157
fatal_error ("No active view", "tm_server_rep::get_meta");
162
tm_server_rep::set_view (tm_view vw2) {
167
tm_server_rep::get_buffer () {
168
tm_view vw= get_view ();
173
tm_server_rep::get_editor () {
174
tm_view vw= get_view ();
175
// cout << "Get editor" << vw->ed << "\n";
180
tm_server_rep::get_window () {
181
tm_view vw= get_view ();
183
fatal_error ("No window attached to view", "tm_server_rep::get_meta");
188
tm_server_rep::get_meta () {
189
tm_window win= get_window ();
194
tm_server_rep::get_color (string s) {
195
return get_display () -> get_color (s);
199
tm_server_rep::get_nr_windows () {
203
/******************************************************************************
204
* The style and package menus
205
******************************************************************************/
208
compute_style_menu (url u, bool package) {
211
if (is_atomic (u[1]) &&
212
((is_concat (u[2]) && (u[2][1] != "CVS")) ||
213
(is_or (u[2]) && is_concat (u[2][1]))))
216
compute_style_menu (u[1], package) * sep *
217
compute_style_menu (u[2], package);
220
string dir= upcase_first (as_string (u[1]));
221
string sub= compute_style_menu (u[2], package);
222
if ((dir == "Test") || (dir == "Obsolete") || (dir == "CVS")) return "";
223
return "(-> \"" * dir * "\" " * sub * ")";
226
string l = as_string (u);
227
if (!ends (l, ".ts")) return "";
229
string cmd= package? string ("init-extra-style"): string ("init-style");
230
return "(\"" * l * "\" (" * cmd * " \"" * l * "\"))";
236
tm_server_rep::style_update_menu () {
237
string sty= compute_style_menu (descendance ("$TEXMACS_STYLE_ROOT"), false);
238
string pck= compute_style_menu (descendance ("$TEXMACS_PACKAGE_ROOT"), true);
239
(void) eval ("(menu-bind style-menu " * sty * ")");
240
(void) eval ("(menu-bind use-package-menu " * pck * ")");
243
/******************************************************************************
244
* Caching style files
245
******************************************************************************/
248
cache_file_name (tree t) {
249
if (is_atomic (t)) return t->label;
254
s << "__" << cache_file_name (t[i]);
260
tm_server_rep::style_clear_cache () {
262
hashmap<tree,hashmap<string,tree> > (hashmap<string,tree> (UNINIT));
263
remove ("$TEXMACS_HOME_PATH/system/cache" * url_wildcard ("*"));
265
int i, j, n= N(bufs);
266
for (i=0; i<n; i++) {
267
tm_buffer buf= ((tm_buffer) bufs[i]);
268
for (j=0; j<N(buf->vws); j++)
269
((tm_view) (buf->vws[j]))->ed->init_style ();
272
style_update_menu ();
276
tm_server_rep::style_set_cache (tree style, hashmap<string,tree> H, tree t) {
277
// cout << "set cache " << style << LF;
278
style_cache (copy (style))= H;
279
style_drd (copy (style))= t;
280
url name ("$TEXMACS_HOME_PATH/system/cache", cache_file_name (style));
281
if (!exists (name)) {
282
save_string (name, tree_to_scheme (tuple ((tree) H, t)));
283
// cout << "saved " << name << LF;
288
tm_server_rep::style_get_cache (
289
tree style, hashmap<string,tree>& H, tree& t, bool& f)
291
// cout << "get cache " << style << LF;
292
if ((style == "") || (style == tree (TUPLE))) { f= false; return; }
293
f= style_cache->contains (style);
295
H= style_cache [style];
296
t= style_drd [style];
300
url name ("$TEXMACS_HOME_PATH/system/cache", cache_file_name (style));
301
if (exists (name) && (!load_string (name, s))) {
302
// cout << "loaded " << name << LF;
303
tree pair= scheme_to_tree (s);
304
H= hashmap<string,tree> (UNINIT, pair[0]);
306
style_cache (copy (style))= H;
307
style_drd (copy (style))= t;
313
/******************************************************************************
314
* Routines concerning the widget
315
******************************************************************************/
318
tm_server_rep::get_visible (SI& x1, SI& y1, SI& x2, SI& y2) {
319
widget meta= (widget) get_meta ();
320
meta["canvas"] << ::get_visible (x1, y1, x2, y2);
324
tm_server_rep::scroll_where (SI& x, SI& y) {
325
widget meta= (widget) get_meta ();
326
meta["canvas"] << get_coord2 ("scroll position", x, y);
330
tm_server_rep::scroll_to (SI x, SI y) {
331
widget meta= (widget) get_meta ();
332
meta["canvas"] << set_scroll_pos (x, y);
336
tm_server_rep::set_extents (SI x1, SI y1, SI x2, SI y2) {
337
widget meta= (widget) get_meta ();
338
meta["canvas"] << ::set_extents (x1, y1, x2, y2);
342
tm_server_rep::set_left_footer (string s) {
343
if ((vw == NULL) || (vw->win == NULL)) return;
344
get_meta()->set_left_footer (s);
348
tm_server_rep::set_right_footer (string s) {
349
if ((vw == NULL) || (vw->win == NULL)) return;
350
get_meta()->set_right_footer (s);
354
tm_server_rep::set_message (string left, string right) {
355
get_editor()->set_message (left, right);
359
tm_server_rep::interactive (string name, string& s, command call_back) {
360
get_meta()->interactive (name, s, call_back);
364
tm_server_rep::full_screen_mode (bool on) {
365
widget meta= (widget) get_meta ();
369
meta ["canvas"] << set_integer ("scrollbars", false);
374
meta ["canvas"] << set_integer ("scrollbars", true);
376
meta->win->full_screen (on);
377
get_editor()->full_screen_mode (on);
382
tm_server_rep::in_full_screen_mode () {
386
/******************************************************************************
387
* Miscellaneous routines
388
******************************************************************************/
391
tm_server_rep::interpose_handler () {
393
listen_to_sockets ();
394
listen_to_connections ();
395
exec_pending_commands ();
398
for (i=0; i<N(bufs); i++) {
399
tm_buffer buf= (tm_buffer) bufs[i];
400
for (j=0; j<N(buf->vws); j++) {
401
tm_view vw= (tm_view) buf->vws[j];
402
if (vw->win != NULL) vw->ed->process_extern_input ();
404
for (j=0; j<N(buf->vws); j++) {
405
tm_view vw= (tm_view) buf->vws[j];
406
if (vw->win != NULL) vw->ed->apply_changes ();
412
tm_server_rep::wait_handler (string message, string arg) {
413
dis->set_wait_indicator (message, arg);
417
tm_server_rep::set_script_status (int i) {
422
tm_server_rep::focus_on_editor (editor ed) {
424
for (i=0; i<N(bufs); i++) {
425
tm_buffer buf= (tm_buffer) bufs[i];
426
for (j=0; j<N(buf->vws); j++) {
427
tm_view vw= (tm_view) buf->vws[j];
434
fatal_error ("Invalid situation", "tm_server_rep::focus_on_editor");
438
tm_server_rep::set_printing_command (string cmd) {
443
tm_server_rep::set_printer_page_type (string type) {
448
tm_server_rep::set_printer_dpi (string dpi) {
453
tm_server_rep::set_default_shrinking_factor (int sf) {
458
tm_server_rep::get_default_shrinking_factor () {
463
tm_server_rep::postscript_gc (string which) {
464
dis->postscript_gc (which);
466
for (i=0; i<N(bufs); i++) {
467
tm_buffer buf= (tm_buffer) bufs[i];
468
for (j=0; j<N(buf->vws); j++) {
469
tm_view vw= (tm_view) buf->vws[j];
470
vw->ed->typeset_invalidate_all ();
476
tm_server_rep::inclusions_gc (string which) {
480
for (i=0; i<N(bufs); i++) {
481
tm_buffer buf= (tm_buffer) bufs[i];
482
for (j=0; j<N(buf->vws); j++) {
483
tm_view vw= (tm_view) buf->vws[j];
484
vw->ed->typeset_invalidate_all ();
490
tm_server_rep::translate (string which, string from, string to) {
491
display dis= get_display ();
492
return dis->translate (which, from, to);
496
tm_server_rep::is_yes (string s) {
499
(s == "ano") || (s == "a") ||
500
(s == "yes") || (s == "y") ||
501
(s == "oui") || (s == "o") ||
502
(s == "ja") || (s == "j") ||
503
(s == "si") || (s == "s") ||
504
(s == "sim") || (s == "s") ||
505
(s == "tak") || (s == "t");
509
tm_server_rep::quit () {
514
/******************************************************************************
516
******************************************************************************/
519
tm_server_rep::evaluate (string name, string session, tree expr) {
520
if (name == "scheme") {
521
string s= tree_to_verbatim (expr);
522
string r= object_to_string (::eval (s));
523
if (r == "#<unspecified>") r= "";
524
return verbatim_to_tree (r);
526
if (!connection_declared (name)) {
527
set_message ("Package#'" * name * "'#not declared",
528
"Evaluate#'" * name * "'#expression");
531
if (connection_status (name, session) == CONNECTION_DEAD) {
532
string r= connection_start (name, session);
533
set_message (r, "Started#'" * name * "'");
534
if (connection_status (name, session) == CONNECTION_DEAD) return "";
536
return connection_eval (name, session, expr);
539
/******************************************************************************
541
******************************************************************************/
544
tm_server_rep::shell (string s) {