4
* $Id: browser.c 685 2003-03-08 15:26:51Z travo $
6
* Main for GIST CGM viewer
9
/* Copyright (c) 1994. The Regents of the University of California.
10
All rights reserved. */
19
/* OpenCGM, ReadCGM, CGMRelative, cgmLandscape, bg0fg1 in cgmin.h */
21
/* GpEPSEngine declared in eps.h */
24
extern long strtol(const char *, char **, int);
26
extern int cgmScaleToFit;
27
extern int gtDoEscapes;
29
/* List of commands in alphabetical order, 0 terminated */
30
static char *commandList[]= {
31
"cgm", "display", "draw", "eps", "free", "help", "info", "open",
32
"ps", "quit", "send", 0 };
34
/* Corresponding functions */
35
static int MakeCGM(int help);
36
static int MakeX(int help);
37
static int Draw(int help);
38
static int EPS(int help);
39
static int FreeAny(int help);
40
static int Help(int help);
41
static int Info(int help);
42
static int OpenIn(int help);
43
static int MakePS(int help);
44
static int Quit(int help);
45
static int Send(int help);
46
static int Special(int help); /* must correspond to 0 in commandList */
47
static int nPrefix, cSuffix; /* arguments for Special */
48
typedef int (*Command)(int help);
49
static Command CommandList[]= {
50
&MakeCGM, &MakeX, &Draw, &EPS, &FreeAny, &Help, &Info, &OpenIn,
51
&MakePS, &Quit, &Send, &Special };
52
static int GetCommand(char *token);
59
static int CreateCGM(int device, char *name);
60
static int CreatePS(int device, char *name);
61
static int CreateX(int device, char *name);
63
static int GetPageGroup(char *token);
64
static int CheckEOL(char *command);
65
static void DrawSend(int ds, char *token);
66
static int GetDeviceList(int ds, char *command);
67
static int FindDevice(void);
68
static int SaveName(int device, char *name);
69
static void DoSpecial(int nPrefix, int cSuffix);
71
static int xPrefix= 0;
72
static void HandleExpose(Engine *engine, Drauing *drauing, int xy[]);
73
static void HandleOther(Engine *engine, int k, int md);
74
static int HelpAndExit(void);
75
static int MessageAndExit(char *msg);
77
extern int on_idle(void);
78
extern int on_quit(void);
79
extern void on_stdin(char *line);
80
static int did_startup = 0;
81
extern int do_startup(void);
87
int outDraw[8], outSend[8], outMark[8];
90
int mPage[32], nPage[32], sPage[32];
91
int n_active_groups = 0;
93
static int nOut, noDisplay, x_only;
97
on_launch(int argc, char *argv[])
103
for (i=0 ; i<8 ; i++) {
106
outDraw[i]= outSend[i]= outLengths[i]= 0;
108
noDisplay= amBatch= x_only= 0;
114
p_stdinit(&on_stdin);
117
for (i=1 ; i<argc ; i++) {
123
if (strcmp(arg, "cgm")==0) {
126
if (i>=argc) return MessageAndExit("Missing file or display name");
128
} else if (strcmp(arg, "ps")==0) {
131
if (i>=argc) return MessageAndExit("Missing file or display name");
133
} else if (strcmp(arg, "in")==0) {
135
if (i>=argc) return MessageAndExit("Missing file or display name");
136
if (inName) return HelpAndExit();
137
else inName= argv[i];
138
} else if (strcmp(arg, "display")==0 || strcmp(arg, "d")==0) {
141
if (i>=argc) return MessageAndExit("Missing file or display name");
143
} else if (strcmp(arg, "f")==0) {
147
} else if (strcmp(arg, "nd")==0) noDisplay= 1;
148
else if (strcmp(arg, "b")==0) amBatch= 1;
149
else if (strcmp(arg, "nowarn")==0) no_warnings= 1;
150
else if (strcmp(arg, "geometry")==0) {
154
if (i>=argc) MessageAndExit("Missing geometry");
156
w = (int)strtol(arg, &suffix, 10);
157
if (suffix!=arg && *suffix=='x') {
159
h = (int)strtol(arg, &suffix, 10);
161
if (w < 10 || h < 10) MessageAndExit("Invalid geometry");
162
gx75width = gx100width = w;
163
gx75height = gx100height = h;
164
} else if (strcmp(arg, "75")==0) defaultDPI= 75;
165
else if (strcmp(arg, "100")==0) defaultDPI= 100;
166
else if (strcmp(arg, "gks")==0) {
167
gx75width= gx75height= 600; /* 8x8 X window size */
168
gx100width= gx100height= 800; /* 8x8 X window size */
169
cgmScaleToFit= 1; /* 8x8 PostScript plotting area */
171
} else if (strcmp(arg, "x")==0) x_only= 1;
172
else if (strcmp(arg, "gks")==0) {
176
else if (strcmp(arg, "fmbug")==0) epsFMbug= 1;
177
else if (strcmp(arg, "bg0fg1")==0) bg0fg1= 1;
178
else if (strcmp(arg, "esc0")==0) gtDoEscapes= 0;
179
else if (strcmp(arg, "esc1")==0) gtDoEscapes= 1;
180
else return HelpAndExit();
184
return MessageAndExit("At most 8 output files/displays allowed");
185
for (j=0 ; j<nOut ; j++) if (strcmp(outNames[j], arg)==0)
186
return MessageAndExit("Duplicate output filenames not allowed");
188
outTypes[nOut]= fileType;
192
} else if (arg[0]<='9' && arg[0]>='0') {
193
if (GetPageGroup(arg)) return MessageAndExit("Try again");
195
} else if (!inName) {
199
return HelpAndExit();
203
if (inName && OpenCGM(inName)) inName= 0;
207
return MessageAndExit("Must specify an input CGM file to use -b or -f");
209
return MessageAndExit("Must specify some output file to use -b");
213
/* Create CGM and PostScript engines */
214
for (i=0 ; i<nOut ; i++) {
215
if (outTypes[i]==0) CreateCGM(i, outNames[i]);
216
else if (outTypes[i]==1) CreatePS(i, outNames[i]);
219
/* If page list specified, do implied send command */
220
if (amBatch && nPageGroups<=0) {
227
for (i=0 ; i<8 ; i++) {
228
if (!outSend[i]) GpDeactivate(outEngines[i]);
229
if (outSend[i] && !GpActivate(outEngines[i])) n_active_groups++;
233
g_initializer(&argc, argv);
246
for (i=0 ; i<nOut ; i++) if (outTypes[i]==2) {
247
if (!CreateX(i, outNames[i])) noX= 0;
250
if (!CreateX(nOut, 0)) {
257
if (noDisplay && x_only)
258
return MessageAndExit("Must be an X display to use -x");
259
if (x_only && !inName)
260
return MessageAndExit("Must specify an input CGM file to use -x");
263
ReadCGM(mPage, nPage, sPage, nPageGroups);
267
static int need_prompt = 1;
273
if (!did_startup && do_startup()) return 0;
274
if (need_prompt && !x_only && !amBatch) p_stdout("gist> ");
277
if (!flag && amBatch) p_quit();
285
for (i=0 ; i<8 ; i++) {
287
GpDeactivate(outEngines[i]);
288
GpKillEngine(outEngines[i]);
295
/* ------------------------------------------------------------------------ */
297
static int HelpAndExit(void)
299
p_stderr("Usage: gist [cgminput] [options] [page list]\n\n");
300
p_stderr(" options: -in cgminput (open cgminput for input)\n");
301
p_stderr(" -cgm cgmout (open cgmout for output)\n");
302
p_stderr(" -ps psout (open psout for output)\n");
303
p_stderr(" -display host:n.m (connect to X server)\n");
304
p_stderr(" -75 (default to 75 dpi)\n");
305
p_stderr(" -100 (default to 100 dpi)\n");
306
p_stderr(" -gks (default to 8x8 inches)\n");
307
p_stderr(" -geometry WxH (initial window size in pixels)\n");
308
p_stderr(" -nd (not even default X server)\n");
309
p_stderr(" -b (batch mode, implies -nd)\n");
310
p_stderr(" -x (graphics window only, no keyboard)\n");
311
p_stderr(" -nowarn (only one warning message printed)\n");
312
p_stderr(" -f (PostScript to stdout, implies -b)\n");
313
p_stderr(" -fmbug (if EPS files are for FrameMaker)\n");
314
p_stderr(" -bg0fg1 (force color 0 to bg, 1 to fg)\n");
315
p_stderr(" -esc0 (skip ^_! escapes-assumed if -gks)\n");
316
p_stderr(" -esc1 (handle ^_! text escapes-default)\n");
317
p_stderr(" page list: [page group] [page group] ...\n");
318
p_stderr(" page group: n (output page n)\n");
319
p_stderr(" page group: n-m (output pages n->m inclusive)\n");
320
p_stderr(" page group: n-m-s (output every s-th page, n-m)\n");
325
static int MessageAndExit(char *msg)
329
p_stderr("\ngist: try gist -help for usage\n");
334
void Warning(char *general, char *particular)
336
if (++warningCount > 5) return;
339
p_stderr("gist: (WARNING) rerun without -nowarn to see warnings");
343
p_stderr("gist: (WARNING) ");
345
p_stderr(particular);
349
/* ------------------------------------------------------------------------ */
351
static int GetCommand(char *token)
353
char **command= commandList;
360
/* Quit has two synonyms, ? is a synonym for help, and f, b, and g
361
are special command forms. */
362
if (strcmp(token, "exit")==0 || strcmp(token, "end")==0 ||
363
strcmp(token, "quit")==0) {
364
/* Quit and its synonyms cannot be abbreviated */
367
} else if (strcmp(token, "?")==0) now= "help";
368
else if (strcmp(token, "f")==0) now= "1f";
369
else if (strcmp(token, "b")==0) now= "1b";
370
else if (strcmp(token, "g")==0) now= "1g";
371
else if (strcmp(token, "s")==0) now= "send";
373
/* Check for nf, nb, ng */
374
if (*now<='9' && *now>='0') {
376
nPrefix= (int)strtol(now, &suffix, 10);
378
if ((cSuffix=='f' || cSuffix=='b' || cSuffix=='g') &&
380
while (*command) command++;
381
return command-commandList;
386
while (cmd && *now>*cmd) cmd= *(++command);
387
while (cmd && *now==*cmd) {
388
while (*cmd && *now==*cmd) { now++; cmd++; }
389
if (!*now) break; /* token matches cmd */
394
p_stderr("gist: Unknown command: ");
396
p_stderr("\n Type help for help.\n");
403
if (cmd && *now++==*cmd++) {
404
while (*cmd && *now==*cmd) { now++; cmd++; }
406
p_stderr("gist: Ambiguous command: ");
408
p_stderr("\n Type help for help.\n");
414
if (strcmp(*command, "quit")==0 && !quitOK) {
415
p_stderr("gist: The quit command cannot be abbreviated.\n");
419
return command-commandList;
422
static int GetPageGroup(char *token)
428
n= m= (int)strtol(token, &suffix, 10);
429
if (suffix!=token && *suffix=='-') {
431
n= (int)strtol(tok, &suffix, 10);
432
if (suffix!=tok && *suffix=='-') {
434
s= (int)strtol(tok, &suffix, 10);
435
if (suffix==tok) suffix= tok-1; /* this is an error */
440
p_stderr("gist: (SYNTAX) ");
442
p_stderr(" is not a legal page number group\n");
446
if (nPageGroups>=32) {
447
p_stderr("gist: (SYNTAX) too many page number groups (32 max)\n");
451
mPage[nPageGroups]= m;
452
nPage[nPageGroups]= n;
453
sPage[nPageGroups]= s;
458
static int CheckEOL(char *command)
460
if (strtok(0, " \t\n")) {
461
p_stderr("gist: (SYNTAX) garbage after ");
463
p_stderr(" command\n");
470
static int Help(int help)
475
p_stderr("gist: help command syntax:\n help [command]\n");
476
p_stderr(" Print help message (for given command).\n");
480
cmd= GetCommand(strtok(0, " \t\n"));
484
char line[80], **command= commandList;
485
p_stderr("gist: Input Syntax:\n command [arg1] [arg2] ...\n");
486
strcpy(line, " Available commands are: ");
490
if (len+strlen(*command) > 72) {
491
strcpy(line+len, "\n");
495
strcpy(line+len, *command);
496
len+= strlen(*command++);
498
strcpy(line+len, "\n");
502
strcpy(line+len, ", ");
505
if (!*command) break;
509
p_stderr(" The quit command has two synonyms: exit, end\n");
510
p_stderr(" Any command except quit may be abbreviated by\n");
511
p_stderr(" omitting characters from the right.\n");
512
p_stderr(" The help command explains specific syntax, e.g.:\n");
513
p_stderr(" help cgm\n");
514
p_stderr(" describes the syntax of the cgm command.\n");
515
p_stderr(" Five commands can be typed to a gist X window:\n");
516
p_stderr(" nf - forward n pages and draw (default 1)\n");
517
p_stderr(" nb - backward n pages and draw (default 1)\n");
518
p_stderr(" ng - go to page n and draw (default 1)\n");
519
p_stderr(" s - send current page\n");
520
p_stderr(" q - quit\n");
529
static char line[256];
537
strncat(line, lin, 255);
538
cmd= GetCommand(strtok(line, " \t\n"));
540
warningCount= xPrefix= 0;
541
if (cmd>=0 && CommandList[cmd](0))
547
static int Quit(int help)
550
p_stderr("gist: quit command syntax:\n quit\n");
551
p_stderr(" Finish and close any output files, then exit.\n");
552
p_stderr(" Synonyms: exit, end (no abbreviations allowed)\n");
558
/* ------------------------------------------------------------------------ */
560
static int SaveName(int device, char *name)
564
if (name == outNames[device]) return 0;
566
len= name? (int)strlen(name) : 0;
567
if (len>outLengths[device]) {
568
if (outLengths[device]>0) p_free(outNames[device]);
569
outNames[device]= (char *)p_malloc(len+1);
570
if (!outNames[device]) {
571
p_stderr("gist: (SEVERE) memory manager failed in SaveName\n");
572
outLengths[device]= 0;
575
outLengths[device]= len;
578
if (name) strcpy(outNames[device], name);
579
else if (outLengths[device]>0) outNames[device][0]= '\0';
580
else outNames[device]= 0;
584
static int CreateCGM(int device, char *name)
586
if (SaveName(device, name)) return 1;
589
GpCGMEngine("CGM Viewer", cgmLandscape, 0, name);
590
if (!outEngines[device]) {
591
Warning(gistError, "");
592
Warning("Unable to create CGM engine ", name);
603
static int CreatePS(int device, char *name)
605
if (SaveName(device, name)) return 1;
608
GpPSEngine("CGM Viewer", cgmLandscape, 0, name);
609
if (!outEngines[device]) {
610
Warning(gistError, "");
611
Warning("Unable to create PostScript engine ", name);
623
static int CreateX(int device, char *name)
625
if (SaveName(device, name)) return 1;
629
GpBXEngine("CGM Viewer", cgmLandscape, defaultDPI, name);
630
if (!outEngines[device]) {
631
Warning(gistError, "");
632
Warning("Unable to open X server ", name? name : "(default)");
640
GxInput(outEngines[device], &HandleExpose, 0, 0, &HandleOther);
646
/* ------------------------------------------------------------------------ */
648
static int OpenIn(int help)
653
p_stderr("gist: open command syntax:\n open cgminput\n");
654
p_stderr(" Closes the current CGM input file, then opens cgminput.\n");
655
p_stderr(" Only a Gist-compliant binary CGM file is legal.\n");
656
p_stderr(" The cgminput may be the first file of a family.\n");
657
p_stderr(" Subsequent page numbers refer to this input file.\n");
661
token= strtok(0, " \t\n");
663
p_stderr("gist: (SYNTAX) cgminput name missing in open command\n");
666
if (CheckEOL("open")) return 0;
668
if (no_warnings) no_warnings= 1; /* one warning per file family */
673
static int FindDevice(void)
676
for (i=0 ; i<8 ; i++) if (!outEngines[i]) break;
678
Warning("8 devices already open for output, command ignored", "");
682
static int MakeCGM(int help)
684
char *token, *cgmout;
689
p_stderr("gist: cgm command syntax:\n cgm cgmout [size]\n");
690
p_stderr(" Opens a CGM file cgmout for output.\n");
691
p_stderr(" The size (default 1000000) is the maximum size of a\n");
692
p_stderr(" single file in the output family, in bytes.\n");
693
p_stderr(" Subsequent send commands will write to cgmout,\n");
694
p_stderr(" unless the send to list is modified (see send).\n");
698
token= strtok(0, " \t\n");
700
p_stderr("gist: (SYNTAX) cgmout name missing in cgm command\n");
704
token= strtok(0, " \t\n");
707
size= strtol(token, &suffix, 0);
709
p_stderr("gist: (SYNTAX) size unintelligble in cgm command\n");
712
if (CheckEOL("cgm")) return 0;
715
device= FindDevice();
716
if (device>=8) return 0;
718
if (!CreateCGM(device, cgmout) &&
719
size>0) ((CGMEngine *)outEngines[device])->fileSize= size;
724
static int MakePS(int help)
730
p_stderr("gist: ps command syntax:\n ps psout\n");
731
p_stderr(" Opens a PostScript file psout for output.\n");
732
p_stderr(" Subsequent send commands will write to psout,\n");
733
p_stderr(" unless the send to list is modified (see send).\n");
737
token= strtok(0, " \t\n");
739
p_stderr("gist: (SYNTAX) psout name missing in ps command\n");
742
if (CheckEOL("ps")) return 0;
744
device= FindDevice();
745
if (device>=8) return 0;
747
CreatePS(device, token);
752
static int MakeX(int help)
754
char *token, *server;
755
int dpi, device, defDPI;
758
p_stderr("gist: display command syntax:\n ");
759
p_stderr("display host:server.screen [dpi]\n");
760
p_stderr(" Connects to the specified X server.\n");
761
p_stderr(" Subsequent draw commands will write to server,\n");
762
p_stderr(" unless the draw to list is modified (see draw).\n");
763
p_stderr(" If specified, 40<=dpi<=200 (default 100).\n");
767
token= strtok(0, " \t\n");
769
p_stderr("gist: (SYNTAX) cgmoutput name missing in cgm command\n");
773
token= strtok(0, " \t\n");
776
dpi= (int)strtol(token, &suffix, 0);
778
p_stderr("gist: (SYNTAX) dpi unintelligble in display command\n");
781
if (dpi<40 && dpi>200) {
783
"gist: (SYNTAX) dpi not between 40 and 200 in display command\n");
786
if (CheckEOL("display")) return 0;
791
device= FindDevice();
792
if (device>=8) return 0;
796
CreateX(device, server);
802
static int EPS(int help)
808
p_stderr("gist: eps command syntax:\n eps epsout\n");
809
p_stderr(" Open an Encapsulated PostScript file epsout, write\n");
810
p_stderr(" the current page to it, then close epsout.\n");
811
p_stderr(" (Note that an EPS file can have only a single page.)\n");
815
token= strtok(0, " \t\n");
817
p_stderr("gist: (SYNTAX) epsout name missing in eps command\n");
820
if (CheckEOL("eps")) return 0;
822
device= FindDevice();
823
if (device>=8) return 0;
825
device= FindDevice();
826
if (device>=8) return 0;
829
GpPSEngine("CGM Viewer", cgmLandscape, 0, "_tmp.eps");
830
if (!outEngines[device]) {
831
Warning(gistError, "");
832
Warning("Unable to create PostScript engine ", token);
836
GpPreempt(outEngines[device]);
838
nPage[0]= mPage[0]= CGMRelative(0);
842
/* First read does PS part, second computes EPS preview */
843
if (!ReadCGM(mPage, nPage, sPage, nPageGroups)) {
845
outEngines[device]= EPSPreview(outEngines[device], token);
846
if (outEngines[device]) {
847
GpPreempt(outEngines[device]);
848
ReadCGM(mPage, nPage, sPage, nPageGroups);
850
Warning("memory manager failed creating EPS engine ", token);
855
if (outEngines[device]) {
858
GpKillEngine(outEngines[device]);
859
outEngines[device]= 0;
865
static int FreeAny(int help)
870
p_stderr("gist: free command syntax:\n free [device# ...]\n");
871
p_stderr(" Finish and close the device#(s). If none given,\n");
872
p_stderr(" frees all send devices,\n");
873
p_stderr(" (Use the info command to describe current device numbers.)\n");
877
if (GetDeviceList(1, "free")) return 0;
879
for (i=0 ; i<8 ; i++) {
881
GpKillEngine(outEngines[i]);
889
static char *yorn[2]= { "No ", "Yes " };
890
static char *tname[3]= { "CGM", "PS ", "X " };
892
extern void CGMinfo(void); /* cgmin.c */
894
static int Info(int help)
899
p_stderr("gist: info command syntax:\n info\n");
900
p_stderr(" Print descriptions of all current output files.\n");
906
p_stdout("Number Draw Send Type Name\n");
907
for (i=0 ; i<8 ; i++) {
910
sprintf(msg, "%3d %s %s %s ", i, yorn[outDraw[i]], yorn[outSend[i]],
913
p_stdout(outNames[i]? outNames[i] : "");
922
/* ------------------------------------------------------------------------ */
924
static int Draw(int help)
930
p_stderr("gist: draw command syntax:\n draw [page list]\n");
932
" Copy the page(s) (default current page) from the current CGM input\n");
933
p_stderr(" to all display output devices.\n");
934
p_stderr(" By default, these are all X windows.\n");
935
p_stderr(" Use alternate syntax:\n draw to [device#1 ...]\n");
936
p_stderr(" to specify a particular list of devices to be used\n");
937
p_stderr(" by the draw command. Without any device numbers,\n");
938
p_stderr(" draw to restores the default list of devices.\n");
939
p_stderr(" (Use the info command to describe current device numbers.)\n");
940
p_stderr(" Page list syntax: group1 [group2 ...]\n");
941
p_stderr(" Page group syntax: n - just page n\n");
942
p_stderr(" m-n - pages n thru m\n");
943
p_stderr(" m-n-s - pages n thru m, step s\n");
947
token= strtok(0, " \t\n");
948
if (token && strcmp(token, "to")==0) {
954
for (i=0 ; i<8 ; i++) {
955
if (!outDraw[i]) GpDeactivate(outEngines[i]);
956
if (outDraw[i] && !GpActivate(outEngines[i])) n++;
959
if (!n && (i= FindDevice())<8) {
960
if (!CreateX(i, 0) && !GpActivate(outEngines[i])) n++;
963
if (n) DrawSend(0, token);
964
else Warning("no devices active for draw command", "");
968
static int Send(int help)
974
p_stderr("gist: send command syntax:\n send [page list]\n");
976
" Copy the page(s) (default current page) from the current CGM input\n");
977
p_stderr(" to all display output devices.\n");
978
p_stderr(" By default, these are all X windows.\n");
979
p_stderr(" Use alternate syntax:\n send to [device#1] ...\n");
980
p_stderr(" to specify a particular list of devices to be used\n");
981
p_stderr(" by the send command. Without any device numbers,\n");
982
p_stderr(" send to restores the default list of devices.\n");
983
p_stderr(" (Use the info command to describe current device numbers.)\n");
984
p_stderr(" Page list syntax: group1 [group2 ...]\n");
985
p_stderr(" Page group syntax: n - just page n\n");
986
p_stderr(" m-n - pages n thru m\n");
987
p_stderr(" m-n-s - pages n thru m, step s\n");
991
token= strtok(0, " \t\n");
992
if (token && strcmp(token, "to")==0) {
998
for (i=0 ; i<8 ; i++) {
999
if (!outSend[i]) GpDeactivate(outEngines[i]);
1000
if (outSend[i] && !GpActivate(outEngines[i])) n++;
1003
if (n) DrawSend(1, token);
1004
else Warning("no devices active for send command", "");
1008
static int GetDeviceList(int ds, char *command)
1011
char *token= strtok(0, " \t\n");
1015
for (device=0 ; device<8 ; device++) outMark[device]= 0;
1017
device= (int)strtol(token, &suffix, 10);
1018
if (*suffix || device<0 || device>7) {
1019
p_stderr("gist: (SYNTAX) ");
1021
p_stderr(" not a legal device# in ");
1023
p_stderr(" command\n");
1026
if (!outEngines[device])
1027
Warning("ignoring non-existent device# ", token);
1030
} while ((token= strtok(0, " \t\n")));
1032
for (device=0 ; device<8 ; device++) if (outMark[device]) break;
1034
Warning(command, " command with no legal devices, no action taken");
1040
for (device=0 ; device<8 ; device++) outMark[device]= 0;
1042
for (device=0 ; device<8 ; device++) outMark[device]= outSend[device];
1048
static char *dsName[]= { "draw to", "send to" };
1050
static void DrawSend(int ds, char *token)
1054
if (token && strcmp(token, "to")==0) {
1055
/* draw to or send to merely resets outDraw or outSend list */
1057
int *outDS= ds? outSend : outDraw;
1058
if (GetDeviceList(0, dsName[ds])) return;
1059
for (i=0 ; i<8 ; i++) if ((outDS[i]= outMark[i])) n++;
1060
if (!n) for (i=0 ; i<8 ; i++)
1061
outDS[i]= outEngines[i]? (ds? outTypes[i]<2 : outTypes[i]==2) : 0;
1066
if (GetPageGroup(token)) return;
1067
} while ((token= strtok(0, " \t\n")));
1069
nPage[0]= mPage[0]= CGMRelative(0);
1074
ReadCGM(mPage, nPage, sPage, nPageGroups);
1077
static int Special(int help)
1081
sprintf(msg, "gist: n%c command syntax:\n n%c\n",
1085
p_stderr(" Forward n (default 1) pages, then draw\n");
1086
else if (cSuffix=='b')
1087
p_stderr(" Backward n (default 1) pages, then draw\n");
1089
p_stderr(" Go to page n (default 1), then draw\n");
1093
if (CheckEOL("nf, nb, or ng")) return 0;
1095
DoSpecial(nPrefix, cSuffix);
1099
static void DoSpecial(int nPrefix, int cSuffix)
1104
for (i=0 ; i<8 ; i++) {
1105
if (!outDraw[i]) GpDeactivate(outEngines[i]);
1106
if (outDraw[i] && !GpActivate(outEngines[i])) n++;
1109
if (cSuffix=='f') mPage[0]= CGMRelative(nPrefix);
1110
else if (cSuffix=='b') mPage[0]= CGMRelative(-nPrefix);
1111
else mPage[0]= nPrefix;
1116
if (n) ReadCGM(mPage, nPage, sPage, nPageGroups);
1117
else Warning("no devices active for nf, nb, or ng command", "");
1120
/* ------------------------------------------------------------------------ */
1123
static void HandleExpose(Engine *engine, Drauing *drauing, int xy[])
1125
XEngine *xEngine= GisXEngine(engine);
1127
if (!xEngine) return;
1129
/* Redraw current picture on this engine only */
1133
nPage[0]= mPage[0]= CGMRelative(0);
1137
ReadCGM(mPage, nPage, sPage, nPageGroups);
1140
GxExpose(engine, drauing, xy);
1143
static int cSuffices[]= { 'f', 'b', 'g' };
1146
static void HandleOther(Engine *engine, int k, int md)
1148
XEngine *xEngine= GisXEngine(engine);
1151
if (!xEngine) return;
1155
if (k == '0') xPrefix= 10*xPrefix;
1156
else if (k == '1') xPrefix= 10*xPrefix+1;
1157
else if (k == '2') xPrefix= 10*xPrefix+2;
1158
else if (k == '3') xPrefix= 10*xPrefix+3;
1159
else if (k == '4') xPrefix= 10*xPrefix+4;
1160
else if (k == '5') xPrefix= 10*xPrefix+5;
1161
else if (k == '6') xPrefix= 10*xPrefix+6;
1162
else if (k == '7') xPrefix= 10*xPrefix+7;
1163
else if (k == '8') xPrefix= 10*xPrefix+8;
1164
else if (k == '9') xPrefix= 10*xPrefix+9;
1165
else if (k=='f' || k=='F' || (k=='+' && (md&P_KEYPAD))) go= 1;
1166
else if (k=='b' || k=='B' || (k=='-' && (md&P_KEYPAD))) go= 2;
1167
else if (k=='g' || k=='G' || k=='\r') go= 3;
1168
else if (k=='s' || k=='S' || (k=='=' && (md&P_KEYPAD))) go= 4;
1169
else if (k=='q' || k=='Q') go= 5;
1172
if ((go==4||go==5) && xPrefix!=0) bad= 1;
1175
if (xPrefix==0) xPrefix= 1;
1176
DoSpecial(xPrefix, cSuffices[go-1]);
1179
for (i=0 ; i<8 ; i++) {
1180
if (!outSend[i]) GpDeactivate(outEngines[i]);
1181
if (outSend[i] && !GpActivate(outEngines[i])) n++;
1184
nPage[0]= mPage[0]= CGMRelative(0);
1188
if (n) ReadCGM(mPage, nPage, sPage, nPageGroups);
1189
else Warning("no devices active for send command", "");
1196
p_feep(xEngine->win);
1201
/* ------------------------------------------------------------------------ */