Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/*
2
Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.
3
All rights reserved.
4
Copyright (C) 2007-2010, Gabriel Dos Reis.
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
- Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
14
- Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the following disclaimer in
16
the documentation and/or other materials provided with the
17
distribution.
18
19
- Neither the name of The Numerical Algorithms Group Ltd. nor the
20
names of its contributors may be used to endorse or promote products
21
derived from this software without specific prior written permission.
22
23
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
/*
37
* This is the main module of the HyperDoc program. It contains the main
38
* routine which initializes all the X stuff, and the tables. Then it passes
39
* control over to the main event loop.
40
*/
41
42
/* #define DEBUG 1 */
43
44
/* Include all the needed include files */
45
46
#include <sys/types.h>
47
#include <sys/signal.h>
48
#include <sys/wait.h>
49
#include <setjmp.h>
50
#include <X11/cursorfont.h>
51
#include <stdlib.h>
52
#include <locale.h>
53
54
#include "debug.h"
55
#include "cfuns.h"
56
#include "sockio.h"
57
#include "hyper.h"
58
#include "lex.h"
59
#include "keyin.h"
60
#include "initx.h"
61
#include "event.h"
62
#include "hyper.h"
63
#include "bsdsignal.h"
64
#include "sockio.h"
65
#include "parse.h"
66
67
using namespace OpenAxiom;
68
69
static void init_hash();
70
static void make_server_connections();
71
static void check_arguments();
72
static void init_hash();
73
static void make_server_connections();
74
static void check_arguments();
75
76
/*
77
* Here is a flag used to tell me whether I made a good connection to the
78
* menu server. Needed so I don't send spad commands when I should not
79
*/
80
81
int MenuServerOpened = 1;
82
83
/* include icon bitmap data */
84
85
#define BITMAPDEPTH 1
86
87
/* X11 display and screen variables */
88
89
Display *gXDisplay;
90
int gXScreenNumber;
91
92
/*
93
* Information about the top level HyperDoc window
94
*/
95
96
HDWindow *gWindow = NULL; /* the current window */
97
HDWindow *gParentWindow =NULL; /* the parent window. The one that appears
98
* when you first start HyperDoc */
99
100
HashTable gSessionHashTable; /* hash table of HD windows */
101
HashTable init_page_hash; /* initial hash table of HD pages */
102
HashTable init_macro_hash; /* initial hash table of HD macros */
103
HashTable init_patch_hash; /* initial hash table of HD patches */
104
105
/* The various Cursors we use */
106
107
Cursor gNormalCursor; /* The normal mouse cursor */
108
Cursor gActiveCursor; /* The cursor in active regions */
109
Cursor gBusyCursor; /* The clock cursor for when I am busy */
110
111
112
HashTable gFileHashTable; /* hash table of HyperDoc files */
113
HashTable gImageHashTable; /* hash table for images */
114
115
116
/* Some things needed for Handling interupts properly */
117
118
int gIsEndOfOutput; /* set to true when spad has finished output */
119
int received_window_request = 0;/* true iff Spad wants a pop-up */
120
int in_next_event = 0; /* true when in XNextEvent */
121
int make_input_file = 0; /* true when making input files from ht */
122
int make_patch_files = 0; /* true when making patch files from ht */
123
int gmake_record_file= 0; /* true when making record files from ht */
124
int gverify_record_file = 0; /* true when verifying record files from ht */
125
int gverify_dates = 0; /* true when we want hypertex to verify ht.db dates */
126
127
openaxiom_sio *session_server; /* socket connecting to session manager */
128
129
int gIsAxiomServer = 0; /* true iff HyperDoc is acting as a */
130
/* an Axiom server */
131
132
int kill_spad = 0; /* kill spad when finished with paste file */
133
134
int gSwitch_to_mono=0; /* will be set to 1 if at any time we don't have
135
enough colours for the images. We will know this
136
when read_pixmap_file returns -1. We will use this
137
when deciding what to do in case of \inputimage */
138
139
int gTtFontIs850=0; /* a flag that tells us if the Tt font is a IBM pagecode 850
140
font and hence supports the graphics chars
141
set when the TtFont is opened*/
142
143
/*
144
* Global copies of the command line arguments, so they never have to be
145
* passed as parameters. This is also so any child process starting up also
146
* has the same values.
147
*/
148
149
int gArgc;
150
char **gArgv;
151
152
char **input_file_list;
153
int input_file_count;
154
155
/*
156
* SIGUSR2 is raised by the spadbuf program when it is done with the current
157
* command
158
*/
159
160
void
161
sigusr2_handler(int sig)
162
{
163
gIsEndOfOutput = 1;
164
return ;
165
}
166
167
void
168
sigcld_handler(int sig)
169
{
170
171
/* why were we waiting after the child had already died ??
172
because we don't want zombies */
173
174
int x;
175
wait(&x);
176
177
}
178
179
extern jmp_buf env;
180
181
182
/* Clean up spad sockets on exit */
183
void
184
clean_socket(void )
185
{
186
char name[256];
187
188
make_server_name(name, MenuServerName);
189
unlink(name);
190
}
191
192
/*
193
* initialize hash tables, signal handlers and windows, then call the main
194
* event handling loop
195
*/
196
197
int
198
main(int argc, char **argv)
199
{
200
using namespace OpenAxiom;
201
int ret_status;
202
203
/* Initialize some global values */
204
/* fprintf(stderr,"hyper:main:entered\n");*/
205
oa_setenv("LC_ALL", "C");
206
setlocale(LC_ALL, "");
207
gArgc = argc;
208
gArgv = argv;
209
gIsEndOfOutput = 1;
210
211
/* fprintf(stderr,"hyper:main:calling check_arguments\n");*/
212
check_arguments();
213
/* fprintf(stderr,"hyper:main:returned check_arguments\n");*/
214
215
/*
216
* initialize the hash tables for the files and the windows and images
217
*/
218
/* fprintf(stderr,"hyper:main:calling init_hash\n");*/
219
init_hash();
220
/* fprintf(stderr,"hyper:main:returned init_hash\n");*/
221
222
/*
223
* initialize the parser keyword hash table
224
*/
225
/* fprintf(stderr,"hyper:main:calling parser_init\n");*/
226
parser_init();
227
/* fprintf(stderr,"hyper:main:returned parser_init\n");*/
228
229
/* fprintf(stderr,"hyper:main:calling read_ht_db\n");*/
230
read_ht_db(&init_page_hash, &init_macro_hash, &init_patch_hash);
231
/* fprintf(stderr,"hyper:main:returned read_ht_db\n");*/
232
233
/*
234
* Now initialize x. This includes opening the display, setting the
235
* screen and display global values, and also gets all the fonts and
236
* colors we will need.
237
*/
238
239
if (!make_input_file && !gmake_record_file && !gverify_record_file) {
240
/* fprintf(stderr,"hyper:main:calling initializeWindowSystem\n");*/
241
initializeWindowSystem();
242
/* fprintf(stderr,"hyper:main:returned initializeWindowSystem\n");*/
243
244
/*
245
* Initialize some of the global values used by the input string
246
* routines
247
*/
248
/* fprintf(stderr,"hyper:main:calling init_keyin\n");*/
249
init_keyin();
250
/* fprintf(stderr,"hyper:main:returned init_keyin\n");*/
251
252
/*
253
* regardless of what else happened, we should always pop up an
254
* initial window.
255
*/
256
257
/* fprintf(stderr,"hyper:main:calling init_top_window\n");*/
258
ret_status = init_top_window("RootPage");
259
/* fprintf(stderr,"hyper:main:returned init_top_window\n");*/
260
gParentWindow = gWindow;
261
if (ret_status == -1) {
262
fprintf(stderr,
263
"(HyperDoc) Could not find RootPage for top-level window.\n");
264
exit(-1);
265
}
266
267
/*
268
* Tell it how to handle the user defined signals I may get
269
*/
270
bsdSignal(SIGUSR2, sigusr2_handler,RestartSystemCalls);
271
bsdSignal(SIGUSR1, SIG_IGN,RestartSystemCalls);
272
bsdSignal(OPENAXIOM_SIGCHLD, sigcld_handler,RestartSystemCalls);
273
bsdSignal(SIGINT, SIG_IGN,RestartSystemCalls);
274
275
/*
276
* Now go to the main event loop. I will never return, so just end
277
* the main routine after that
278
*/
279
280
/*
281
* make an input file if requested
282
*/
283
}
284
else {
285
286
/*
287
* Try to establish all the socket connections I need. If I am an
288
* gIsAxiomServer and the routine fails, it will exit for me
289
*/
290
/* fprintf(stderr,"hyper:main:in else case\n");*/
291
/* fprintf(stderr,"hyper:main:calling make_server_connections\n");*/
292
make_server_connections();
293
/* fprintf(stderr,"hyper:main:returned make_server_connections\n");*/
294
295
296
if (make_input_file) ht2_input();
297
if (gmake_record_file) make_record();
298
if (gverify_record_file) verify_record();
299
exit(0);
300
}
301
302
/*
303
* Try to establish all the socket connections I need. If I am an
304
* gIsAxiomServer and the routine fails, it will exit for me
305
*/
306
/* fprintf(stderr,"hyper:main:calling make_server_connections\n");*/
307
make_server_connections();
308
/* fprintf(stderr,"hyper:main:returned make_server_connections\n");*/
309
310
311
/* fprintf(stderr,"hyper:main:calling mainEventLoop\n");*/
312
mainEventLoop();
313
/* fprintf(stderr,"hyper:main:returned mainEventLoop\n");*/
314
315
return 0;
316
}
317
318
/*
319
* Initializes the hash table for Files, and Windows
320
*/
321
322
static void
323
init_hash()
324
{
325
hash_init(&gFileHashTable,
326
FileHashSize,
327
(EqualFunction)string_equal,
328
(HashcodeFunction) string_hash);
329
hash_init(&gSessionHashTable,
330
SessionHashSize,
331
(EqualFunction) window_equal,
332
(HashcodeFunction) window_code);
333
hash_init(&gImageHashTable,
334
ImageHashSize,
335
(EqualFunction) string_equal,
336
(HashcodeFunction) string_hash);
337
}
338
339
/* initialize the HyperDoc page hierarchy data structures */
340
341
void
342
init_page_structs(HDWindow *w)
343
{
344
int i;
345
346
w->fMemoStackIndex = 0;
347
for (i = 0; i < MaxMemoDepth; i++) {
348
w->fMemoStack[i] = NULL;
349
w->fDownLinkStackTop[i] = 0;
350
}
351
w->fDownLinkStackIndex = 0;
352
for (i = 0; i < MaxDownlinkDepth; i++)
353
w->fDownLinkStack[i] = NULL;
354
}
355
356
static void
357
check_arguments()
358
{
359
int i;
360
361
/*
362
* Now check the command line arguments, to see if I am supposed to be a
363
* server or not
364
*/
365
for (i = 1; i < gArgc; i++) {
366
if (gArgv[i][0] == '-')
367
switch (gArgv[i][1]) {
368
case 'p':
369
gverify_dates=1;
370
break;
371
case 's':
372
if (!MenuServerOpened) {
373
fprintf(stderr, "(HyperDoc) Server already in use.\n");
374
exit(-1);
375
}
376
gIsAxiomServer = 1;
377
break;
378
case 'i':
379
if (gArgv[i][2] == 'p')
380
make_patch_files = 1;
381
make_input_file = 1;
382
input_file_list = gArgv + i + 1;
383
input_file_count = gArgc - i - 1;
384
break;
385
case 'k':
386
kill_spad = 1;
387
break;
388
case 'r':
389
if (gArgv[i][2] == 'm')
390
gmake_record_file=1;
391
else if (gArgv[i][2] == 'v')
392
gverify_record_file=1;
393
else
394
fprintf(stderr, "(HyperDoc) v or m must follow -r\n");
395
input_file_list = gArgv + i + 1;
396
input_file_count = gArgc - i - 1;
397
break;
398
default:
399
fprintf(stderr, "(HyperDoc) Unexpected Command Line Argument %s\n", gArgv[i]);
400
fprintf(stderr, " Usage: hypertex [-s]\n");
401
break;
402
}
403
}
404
}
405
406
static void
407
make_server_connections()
408
{
409
int i, wait_time;
410
411
/*
412
* Try to open the menuserver socket, if I can not, then set a flag
413
*/
414
415
if (open_server(MenuServerName) == -2) {
416
fprintf(stderr, "(HyperDoc) Warning: Not connected to OpenAxiom Server!\n");
417
MenuServerOpened = 0;
418
} else {
419
atexit(&clean_socket);
420
MenuServerOpened = 1;
421
}
422
423
424
/*
425
* If I have opened the MenuServer socket, then I should also try to open
426
* the SpadServer socket, so I can send stuff right to SPAD.
427
*/
428
429
if (MenuServerOpened) {
430
431
/*
432
* If I am a ht server, then I should not continue on unless I
433
* establish some sort of connection
434
*/
435
436
/*
437
* Modified on 11/20 so that it prints an error message every ten for
438
* ten tries at opeing the socket. If it fails all ten times, it
439
* gives up and exits.
440
*/
441
442
if (!gIsAxiomServer)
443
wait_time = 2;
444
else
445
wait_time = 1000;
446
447
for (i = 0, spad_socket = NULL; i < 2 && spad_socket == NULL; i++) {
448
spad_socket = connect_to_local_server(SpadServer,
449
MenuServer, wait_time);
450
if (gIsAxiomServer && spad_socket == NULL)
451
fprintf(stderr, "(HyperDoc) Error opening OpenAxiom server. Retrying ...\n");
452
else
453
i = 11;
454
}
455
if (! spad_socket) {
456
fprintf(stderr, "(HyperDoc) Couldn't connect to OpenAxiom server!\n");
457
if (!gIsAxiomServer)
458
MenuServerOpened = 0;
459
else {
460
fprintf(stderr, "(HyperDoc) Couldn't connect to OpenAxiom server!\n");
461
exit(-1);
462
}
463
}
464
else {
465
466
/*
467
* Do the same thing for the SessionServer
468
*/
469
470
for (i = 0, session_server = NULL; i < 2 && session_server == NULL
471
; i++) {
472
session_server =
473
connect_to_local_server(SessionServer, MenuServer,
474
wait_time);
475
if (gIsAxiomServer && session_server == NULL) {
476
fprintf(stderr,
477
"(HyperDoc) Error opening SessionServer, Retrying ...\n");
478
}
479
else
480
i = 11;
481
}
482
if (session_server == NULL) {
483
fprintf(stderr, "(HyperDoc) Connection attempt to session manager timed out.\n");
484
if (gIsAxiomServer) {
485
fprintf(stderr,
486
"(HyperDoc) Server unable to connect to session server\n");
487
exit(-1);
488
}
489
else {
490
MenuServerOpened = 0;
491
}
492
}
493
}
494
}
495
}
496
497