Annotation of OpenXM_contrib/gnuplot/term/openstep.trm, Revision 1.1.1.1
1.1 maekawa 1: /* -*- objc -*-
2: * $Id: openstep.trm,v 1.5.2.1 1999/08/20 12:09:47 lhecking Exp $
3: *
4: */
5:
6: /* GNUPLOT - openstep.trm */
7:
8: /*[
9: * Copyright 1991 - 1993, 1998
10: *
11: * Permission to use, copy, and distribute this software and its
12: * documentation for any purpose with or without fee is hereby granted,
13: * provided that the above copyright notice appear in all copies and
14: * that both that copyright notice and this permission notice appear
15: * in supporting documentation.
16: *
17: * Permission to modify the software is granted, but not the right to
18: * distribute the complete modified source code. Modifications are to
19: * be distributed as patches to the released version. Permission to
20: * distribute binaries produced by compiling modified sources is granted,
21: * provided you
22: * 1. distribute the corresponding source modifications from the
23: * released version in the form of a patch file along with the binaries,
24: * 2. add special version identification to distinguish your version
25: * in addition to the base release version number,
26: * 3. provide your name and address as the primary contact for the
27: * support of your modified version, and
28: * 4. retain our contact information in regard to use of the base
29: * software.
30: * Permission to distribute the released version of the source code along
31: * with corresponding source modifications in the form of a patch file is
32: * granted with same provisions 2 through 4 for binary distributions.
33: *
34: * This software is provided "as is" without express or implied warranty
35: * to the extent permitted by applicable law.
36: ]*/
37:
38: /*
39: * This file is included by ../term.c via ../term.h.
40: *
41: * This terminal driver supports:
42: * next
43: *
44: * AUTHORS
45: * Robert Lutwak from Russell Lang's post.trm
46: * 'old' option invokes Nick Strobel's original, single viewport terminal
47: *
48: * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
49: *
50: * This terminal attempts to connect, via the NeXTstep Distributed
51: * Objects system, to the "gnuplotServer." If there is no such
52: * service registered with the OS, the terminal attempts to fire
53: * up GnuTerm.app. If the user has not set the environment variable
54: * GNUTERMPATH, the terminal uses the users ApplicationPaths Workspace
55: * dwrite to search for GnuTerm.app (Note: this is usually something
56: * like ~/Apps, ~/LocalApps, ~/NextApps, etc.).
57: * In order to use this filter, you MUST have GnuTerm.app installed
58: * on your system.
59: *
60: * Once connected to the server, this filter is basically Russell Lang's
61: * Postscript filter, except that the resultant postscript code
62: * is sent, via the D.O. system, to GnuTerm.app, which manages
63: * the windows which produce the postscript output on the screen.
64: *
65: *
66: * Defaults are
67: * 'set term next new dashed auto "Helvetica" 14'
68: *
69: * To change font to Times-Roman and font size to 20pts use
70: * 'set term next "Times-Roman" 20'.
71: *
72: * to choose window by title
73: * 'set term next title "Window title"
74: *
75: * Monitor Options:
76: * monochrome, color
77: *
78: * To invoke Nick Strobel's old terminal
79: * 'set term next old'
80: */
81:
82: #include "driver.h"
83:
84: #ifdef TERM_REGISTER
85: register_term(next)
86: #endif
87:
88: #ifdef TERM_PROTO
89:
90: #import <Foundation/Foundation.h>
91: #import <AppKit/AppKit.h>
92: #import <stdarg.h>
93:
94:
95: TERM_PUBLIC void NEXT_options __PROTO((void));
96: TERM_PUBLIC void NEXT_common_init __PROTO((int uses_fonts, unsigned int xoff, unsigned int yoff, unsigned int xsize, unsigned int ysize, char **dict));
97: TERM_PUBLIC void NEXT_init __PROTO((void));
98: TERM_PUBLIC void NEXT_graphics __PROTO((void));
99: TERM_PUBLIC void NEXT_text __PROTO((void));
100: TERM_PUBLIC void NEXT_reset __PROTO((void));
101: TERM_PUBLIC void NEXT_linetype __PROTO((int linetype));
102: TERM_PUBLIC void NEXT_move __PROTO((unsigned int x, unsigned int y));
103: TERM_PUBLIC void NEXT_vector __PROTO((unsigned int x, unsigned int y));
104: TERM_PUBLIC void NEXT_put_text __PROTO((unsigned int x, unsigned int y, const char *str));
105: TERM_PUBLIC int NEXT_text_angle __PROTO((int ang));
106: TERM_PUBLIC int NEXT_justify_text __PROTO((enum JUSTIFY mode));
107: TERM_PUBLIC void NEXT_point __PROTO((unsigned int x, unsigned int y, int number));
108: TERM_PUBLIC int NEXT_set_font __PROTO((const char *font));
109: TERM_PUBLIC char *NEXT_RememberFont __PROTO((char *fname));
110: TERM_PUBLIC void NEXT_set_pointsize __PROTO((double size));
111:
112:
113: #define NEXT_POINT_TYPES 8 /* div */
114: #define NEXT_XOFF 1 /* page offset in pts */
115: #define NEXT_YOFF 1
116: #define NEXT_XMAX 6400
117: #define NEXT_YMAX 4800
118: #define NEXT_XLAST (NEXT_XMAX - 1)
119: #define NEXT_YLAST (NEXT_YMAX - 1)
120: #define NEXT_VTIC (NEXT_YMAX/80)
121: #define NEXT_HTIC (NEXT_YMAX/80)
122: #define NEXT_SC (10) /* scale is 1pt = 10 units */
123: #define NEXT_LW (0.5*NEXT_SC) /* linewidth = 0.5 pts */
124: #define NEXT_VCHAR (14*NEXT_SC) /* default is 14 point characters */
125: #define NEXT_HCHAR (14*NEXT_SC*6/10)
126:
127: #define GOT_NEXT_PROTO
128: #endif
129:
130:
131: #ifndef TERM_PROTO_ONLY
132:
133: #ifdef TERM_BODY
134:
135: @interface GnuTermDriver:NSObject
136: {
137: id server;
138: }
139:
140: - (void)senderIsInvalid:(NSNotification *)sender;
141: - (void)plot:(char *)PSstr;
142: -init;
143: @end
144:
145:
146: #define DEFAULTNEXTSIZE 10000
147:
148: static NSAutoreleasePool *arpool; // our autorelease pool
149: static id gnuTermAccess; /* local object manages the D.O. connection */
150:
151: static char *NEXTBuffer, *NEXTBufAt, *NEXTBufEnd;
152: static int NEXTsize;
153: static char NEXTTmpBuf[1000];
154: static void NEXTPrintf(char *,...);
155: static TBOOLEAN NEXT_oldterminal = FALSE;
156: /*static TBOOLEAN NEXT_colordetect();*/
157:
158: static char NEXT_title[MAX_LINE_LEN + 1]; /* name of font */
159:
160: static char NEXT_font[MAX_LINE_LEN + 1] = "Helvetica"; /* name of font */
161: static int NEXT_fontsize = 14; /* size of font in pts */
162: static TBOOLEAN NEXT_color = FALSE;
163: static TBOOLEAN NEXT_solid = FALSE; /* use dashed lines */
164: static int NEXT_path_count = 0; /* count of lines in path */
165: static int NEXT_ang = 0; /* text angle */
166: static enum JUSTIFY NEXT_justify = LEFT; /* text is flush left */
167:
168: static TBOOLEAN NEXT_duplex_state = FALSE;
169: static TBOOLEAN NEXT_duplex_option = FALSE;
170:
171: static char GPFAR *GPFAR NEXT_header[] =
172: {
173: "/M {moveto} bind def\n",
174: "/L {lineto} bind def\n",
175: "/R {rmoveto} bind def\n",
176: "/V {rlineto} bind def\n",
177: "/vpt2 vpt 2 mul def\n",
178: "/hpt2 hpt 2 mul def\n",
179: /* flush left show */
180: "/Lshow { currentpoint stroke M\n",
181: " 0 vshift R show } def\n",
182: /* flush right show */
183: "/Rshow { currentpoint stroke M\n",
184: " dup stringwidth pop neg vshift R show } def\n",
185: /* centred show */
186: "/Cshow { currentpoint stroke M\n",
187: " dup stringwidth pop -2 div vshift R show } def\n",
188: /* Dash or Color Line */
189: "/DL { Color {setrgbcolor Solid {pop []} if 0 setdash }\n",
190: " {pop pop pop Solid {pop []} if 0 setdash} ifelse } def\n",
191: /* Border Lines */
192: "/BL { stroke gnulinewidth 2 mul setlinewidth } def\n",
193: /* Axes Lines */
194: "/AL { stroke gnulinewidth 2 div setlinewidth } def\n",
195: /* Plot Lines */
196: "/PL { stroke gnulinewidth setlinewidth } def\n",
197: /* Line Types */
198: "/LTb { BL [] 0 0 0 DL } def\n", /* border */
199: "/LTa { AL [1 dl 2 dl] 0 setdash 0 0 0 setrgbcolor } def\n", /* axes */
200: "/LT0 { PL [] 0 1 0 DL } def\n",
201: "/LT1 { PL [4 dl 2 dl] 0 0 1 DL } def\n",
202: "/LT2 { PL [2 dl 3 dl] 1 0 0 DL } def\n",
203: "/LT3 { PL [1 dl 1.5 dl] 1 0 1 DL } def\n",
204: "/LT4 { PL [5 dl 2 dl 1 dl 2 dl] 0 1 1 DL } def\n",
205: "/LT5 { PL [4 dl 3 dl 1 dl 3 dl] 1 1 0 DL } def\n",
206: "/LT6 { PL [2 dl 2 dl 2 dl 4 dl] 0 0 0 DL } def\n",
207: "/LT7 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 1 0.3 0 DL } def\n",
208: "/LT8 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 0.5 0.5 0.5 DL } def\n",
209: /* Point (Round) *//* Matt Heffron make it round */
210: "/Pnt { stroke [] 0 setdash\n",
211: " gsave 1 setlinecap M 0 0 V stroke grestore } def\n",
212:
213: /* Diamond */
214: "/Dia { stroke [] 0 setdash 2 copy vpt add M\n",
215: " hpt neg vpt neg V hpt vpt neg V\n",
216: " hpt vpt V hpt neg vpt V closepath stroke\n",
217: " Pnt } def\n",
218:
219: /* Plus */
220: "/Pls { stroke [] 0 setdash vpt sub M 0 vpt2 V\n",
221: " currentpoint stroke M\n",
222: " hpt neg vpt neg R hpt2 0 V stroke\n",
223: " } def\n",
224:
225: /* Box */
226: "/Box { stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M\n",
227: " 0 vpt2 neg V hpt2 0 V 0 vpt2 V\n",
228: " hpt2 neg 0 V closepath stroke\n",
229: " Pnt } def\n",
230:
231: /* Cross (X) */
232: "/Crs { stroke [] 0 setdash exch hpt sub exch vpt add M\n",
233: " hpt2 vpt2 neg V currentpoint stroke M\n",
234: " hpt2 neg 0 R hpt2 vpt2 V stroke } def\n",
235:
236: /* Triangle Up*/
237: "/TriU { stroke [] 0 setdash 2 copy vpt 1.12 mul add M\n",
238: " hpt neg vpt -1.62 mul V\n",
239: " hpt 2 mul 0 V\n",
240: " hpt neg vpt 1.62 mul V closepath stroke\n",
241: " Pnt } def\n",
242:
243: /* Star */
244: "/Star { 2 copy Pls Crs } def\n",
245:
246: /* div added filed box */
247: /* Filled Box */
248: "/BoxF { stroke [] 0 setdash exch hpt sub exch vpt add M\n",
249: " 0 vpt2 neg V hpt2 0 V 0 vpt2 V\n",
250: " hpt2 neg 0 V closepath fill } def\n",
251:
252: /* div added filled triangle */
253: /* Triangle Up, Filled */
254: "/TriUF { stroke [] 0 setdash vpt 1.12 mul add M\n",
255: " hpt neg vpt -1.62 mul V\n",
256: " hpt 2 mul 0 V\n",
257: " hpt neg vpt 1.62 mul V closepath fill } def\n",
258:
259: /* Matt Heffron: added a few more types */
260: /* Triangle Down */
261: "/TriD { stroke [] 0 setdash 2 copy vpt 1.12 mul sub M\n",
262: " hpt neg vpt 1.62 mul V\n",
263: " hpt 2 mul 0 V\n",
264: " hpt neg vpt -1.62 mul V closepath stroke\n",
265: " Pnt } def\n",
266:
267: /* Triangle Down, Filled*/
268: "/TriDF { stroke [] 0 setdash vpt 1.12 mul sub M\n",
269: " hpt neg vpt 1.62 mul V\n",
270: " hpt 2 mul 0 V\n",
271: " hpt neg vpt -1.62 mul V closepath fill} def\n",
272:
273: /* Diamond, Filled */
274: "/DiaF { stroke [] 0 setdash vpt add M\n",
275: " hpt neg vpt neg V hpt vpt neg V\n",
276: " hpt vpt V hpt neg vpt V closepath fill } def\n",
277:
278: /* Pentagon */
279: "/Pent { stroke [] 0 setdash 2 copy gsave\n",
280: " translate 0 hpt M 4 {72 rotate 0 hpt L} repeat\n",
281: " closepath stroke grestore Pnt } def\n",
282:
283: /* Pentagon, Filled */
284: "/PentF { stroke [] 0 setdash gsave\n",
285: " translate 0 hpt M 4 {72 rotate 0 hpt L} repeat\n",
286: " closepath fill grestore } def\n",
287:
288: /* Circle */
289: "/Circle { stroke [] 0 setdash 2 copy\n",
290: " hpt 0 360 arc stroke Pnt } def\n",
291:
292: /* Circle,Filled */
293: "/CircleF { stroke [] 0 setdash hpt 0 360 arc fill } def\n",
294: /* 16 differently filled circles */
295: "/C0 { BL [] 0 setdash 2 copy moveto vpt 90 450 arc } bind def\n",
296: "/C1 { BL [] 0 setdash 2 copy moveto\n",
297: " 2 copy vpt 0 90 arc closepath fill\n",
298: " vpt 0 360 arc closepath } bind def\n",
299: "/C2 { BL [] 0 setdash 2 copy moveto\n",
300: " 2 copy vpt 90 180 arc closepath fill\n",
301: " vpt 0 360 arc closepath } bind def\n",
302: "/C3 { BL [] 0 setdash 2 copy moveto\n",
303: " 2 copy vpt 0 180 arc closepath fill\n",
304: " vpt 0 360 arc closepath } bind def\n",
305: "/C4 { BL [] 0 setdash 2 copy moveto\n",
306: " 2 copy vpt 180 270 arc closepath fill\n",
307: " vpt 0 360 arc closepath } bind def\n",
308: "/C5 { BL [] 0 setdash 2 copy moveto\n",
309: " 2 copy vpt 0 90 arc\n",
310: " 2 copy moveto\n",
311: " 2 copy vpt 180 270 arc closepath fill\n",
312: " vpt 0 360 arc } bind def\n",
313: "/C6 { BL [] 0 setdash 2 copy moveto\n",
314: " 2 copy vpt 90 270 arc closepath fill\n",
315: " vpt 0 360 arc closepath } bind def\n",
316: "/C7 { BL [] 0 setdash 2 copy moveto\n",
317: " 2 copy vpt 0 270 arc closepath fill\n",
318: " vpt 0 360 arc closepath } bind def\n",
319: "/C8 { BL [] 0 setdash 2 copy moveto\n",
320: " 2 copy vpt 270 360 arc closepath fill\n",
321: " vpt 0 360 arc closepath } bind def\n",
322: "/C9 { BL [] 0 setdash 2 copy moveto\n",
323: " 2 copy vpt 270 450 arc closepath fill\n",
324: " vpt 0 360 arc closepath } bind def\n",
325: "/C10 { BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill\n",
326: " 2 copy moveto\n",
327: " 2 copy vpt 90 180 arc closepath fill\n",
328: " vpt 0 360 arc closepath } bind def\n",
329: "/C11 { BL [] 0 setdash 2 copy moveto\n",
330: " 2 copy vpt 0 90 arc closepath fill\n",
331: " 2 copy moveto\n",
332: " 2 copy vpt 180 360 arc closepath fill\n",
333: " vpt 0 360 arc closepath } bind def\n",
334: "/C12 { BL [] 0 setdash 2 copy moveto\n",
335: " 2 copy vpt 180 360 arc closepath fill\n",
336: " vpt 0 360 arc closepath } bind def\n",
337: "/C13 { BL [] 0 setdash 2 copy moveto\n",
338: " 2 copy vpt 0 90 arc closepath fill\n",
339: " 2 copy moveto\n",
340: " 2 copy vpt 180 360 arc closepath fill\n",
341: " vpt 0 360 arc closepath } bind def\n",
342: "/C14 { BL [] 0 setdash 2 copy moveto\n",
343: " 2 copy vpt 90 360 arc closepath fill\n",
344: " vpt 0 360 arc } bind def\n",
345: "/C15 { BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill\n",
346: " vpt 0 360 arc closepath } bind def\n",
347:
348: /* Auxiliary definitions for rectangles */
349:
350: "/Rec { newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n",
351: " neg 0 rlineto closepath } bind def\n",
352: "/Square { dup Rec } bind def\n",
353: "/Bsquare { vpt sub exch vpt sub exch vpt2 Square } bind def\n",
354:
355: /* 16 differently filled squares */
356:
357: "/S0 { BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare } bind def\n",
358: "/S1 { BL [] 0 setdash 2 copy vpt Square fill Bsquare } bind def\n",
359: "/S2 { BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def\n",
360: "/S3 { BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare } bind def\n",
361: "/S4 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def\n",
362: "/S5 { BL [] 0 setdash 2 copy 2 copy vpt Square fill\n",
363: " exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def\n",
364: "/S6 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare } bind def\n",
365: "/S7 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill\n",
366: " 2 copy vpt Square fill\n",
367: " Bsquare } bind def\n",
368: "/S8 { BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare } bind def\n",
369: "/S9 { BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare } bind def\n",
370: "/S10 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill\n",
371: " Bsquare } bind def\n",
372: "/S11 { 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill\n",
373: " Bsquare } bind def\n",
374: "/S12 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare } bind def\n",
375: "/S13 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill\n",
376: " 2 copy vpt Square fill Bsquare } bind def\n",
377: "/S14 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill\n",
378: " 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def\n",
379: "/S15 { BL [] 0 setdash 2 copy Bsquare fill Bsquare } bind def\n",
380:
381: /* 16 different diamonds (actually just rotated squares) */
382:
383: "/D0 { gsave translate 45 rotate 0 0 Box stroke grestore } bind def\n",
384: "/D1 { gsave translate 45 rotate 0 0 S1 stroke grestore } bind def\n",
385: "/D2 { gsave translate 45 rotate 0 0 S2 stroke grestore } bind def\n",
386: "/D3 { gsave translate 45 rotate 0 0 S3 stroke grestore } bind def\n",
387: "/D4 { gsave translate 45 rotate 0 0 S4 stroke grestore } bind def\n",
388: "/D5 { gsave translate 45 rotate 0 0 S5 stroke grestore } bind def\n",
389: "/D6 { gsave translate 45 rotate 0 0 S6 stroke grestore } bind def\n",
390: "/D7 { gsave translate 45 rotate 0 0 S7 stroke grestore } bind def\n",
391: "/D8 { gsave translate 45 rotate 0 0 S8 stroke grestore } bind def\n",
392: "/D9 { gsave translate 45 rotate 0 0 S9 stroke grestore } bind def\n",
393: "/D10 { gsave translate 45 rotate 0 0 S10 stroke grestore } bind def\n",
394: "/D11 { gsave translate 45 rotate 0 0 S11 stroke grestore } bind def\n",
395: "/D12 { gsave translate 45 rotate 0 0 S12 stroke grestore } bind def\n",
396: "/D13 { gsave translate 45 rotate 0 0 S13 stroke grestore } bind def\n",
397: "/D14 { gsave translate 45 rotate 0 0 S14 stroke grestore } bind def\n",
398: "/D15 { gsave translate 45 rotate 0 0 S15 stroke grestore } bind def\n",
399:
400: NULL
401: };
402:
403: static char GPFAR *GPFAR ENHNEXT_header[] =
404: {
405: /* For MFshow and MFwidth the tos is an array with the string and font info: */
406: /* [<fontname (a string)> <fontsize> <vertical offset> <width significant?> <text string>] */
407:
408: "/MFshow {{dup dup 0 get findfont exch 1 get scalefont setfont\n",
409: " [ currentpoint ] exch dup 2 get 0 exch rmoveto dup 4 get show dup\n",
410: " 3 get {2 get neg 0 exch rmoveto pop} {pop aload pop moveto}ifelse} forall} bind def\n",
411: "/MFwidth {0 exch {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont\n",
412: " 4 get stringwidth pop add}\n",
413: " {pop} ifelse} forall} bind def\n",
414:
415: /* flush left show */
416: "/MLshow { currentpoint stroke M\n",
417: " 0 exch R MFshow } bind def\n",
418:
419: /* flush right show */
420: "/MRshow { currentpoint stroke M\n",
421: " exch dup MFwidth neg 3 -1 roll R MFshow } def\n",
422:
423: /* centred show */
424: "/MCshow { currentpoint stroke M\n",
425: " exch dup MFwidth -2 div 3 -1 roll R MFshow } def\n",
426: NULL
427: };
428:
429: /* added to post by Matt Heffron <heffron@falstaff.css.beckman.com> */
430: /* moved to post.trm by drd */
431:
432: struct NEXT_FontName {
433: char *name;
434: struct NEXT_FontName *next;
435: } *NEXT_DocFonts = NULL;
436:
437: TERM_PUBLIC char *
438: NEXT_RememberFont(fname)
439: char *fname;
440: {
441: struct NEXT_FontName *fnp;
442:
443: for (fnp = NEXT_DocFonts; fnp && strcmp(fnp->name, fname); fnp = fnp->next);
444: if (fnp)
445: return fnp->name; /* we must have found it in the list */
446:
447: if (encoding == ENCODING_ISO_8859_1) {
448: NEXTPrintf("/%s reencodeISO def\n", fname);
449: }
450: fnp = (struct NEXT_FontName *) gp_alloc(sizeof(struct NEXT_FontName), "PostScript Font record");
451: fnp->name = gp_alloc(1 + strlen(fname), "PostScript Font name");
452: strcpy(fnp->name, fname);
453: fnp->next = NEXT_DocFonts;
454: NEXT_DocFonts = fnp;
455: return fnp->name;
456: }
457:
458: int NEXT_pen_x, NEXT_pen_y;
459: int NEXT_taken;
460: int NEXT_linetype_last;
461: TBOOLEAN NEXT_relative_ok;
462:
463: TERM_PUBLIC void
464: NEXT_options()
465: {
466: char buf[40];
467: for (; !END_OF_COMMAND; ++c_token) {
468: if (almost_equals(c_token, "d$efault")) {
469: NEXT_oldterminal = FALSE;
470: /*NEXT_color=NEXT_colordetect(); */
471: NEXT_color = FALSE;
472: NEXT_solid = FALSE;
473: NEXT_duplex_option = FALSE;
474: strcpy(NEXT_font, "Helvetica");
475: NEXT_fontsize = 14;
476: term->v_char = (unsigned int) (NEXT_fontsize * NEXT_SC);
477: term->h_char = (unsigned int) (NEXT_fontsize * NEXT_SC * 6 / 10);
478: term->put_text = NEXT_put_text;
479: } else if (almost_equals(c_token, "mono$chrome")) {
480: NEXT_color = FALSE;
481: } else if (almost_equals(c_token, "col$or")
482: || almost_equals(c_token, "col$our")) {
483: NEXT_color = TRUE;
484: }
485: /*
486: else if (almost_equals(c_token,"auto$detect")) {
487: NEXT_color = NEXT_colordetect();
488: }
489: */
490:
491: else if (almost_equals(c_token, "so$lid")) {
492: NEXT_solid = TRUE;
493: } else if (almost_equals(c_token, "da$shed")) {
494: NEXT_solid = FALSE;
495: } else if (almost_equals(c_token, "si$mplex")) {
496: NEXT_duplex_state = FALSE;
497: NEXT_duplex_option = TRUE;
498: } else if (almost_equals(c_token, "du$plex")) {
499: NEXT_duplex_state = TRUE;
500: NEXT_duplex_option = TRUE;
501: } else if (almost_equals(c_token, "defaultp$lex")) {
502: NEXT_duplex_option = FALSE;
503: } else if (isstring(c_token)) {
504: quote_str(NEXT_font, c_token, MAX_LINE_LEN + 1);
505:
506: /* We must have font size specified */
507: copy_str(buf, ++c_token, 40);
508: NEXT_fontsize = atoi(buf);
509: term->v_char = (unsigned int) (NEXT_fontsize * NEXT_SC);
510: term->h_char = (unsigned int) (NEXT_fontsize * NEXT_SC * 6 / 10);
511: sprintf(default_font, "%s,%d", NEXT_font, NEXT_fontsize);
512: } else if (almost_equals(c_token, "ti$tle")) {
513: if (!isstring(++c_token)) {
514: fprintf(stderr, "usage: set term next title \"newtitle\"\n");
515: --c_token;
516: }
517: quote_str(NEXT_title, c_token, MAX_LINE_LEN + 1);
518: } else if (almost_equals(c_token, "old")) {
519: NEXT_oldterminal = TRUE;
520: } else if (almost_equals(c_token, "new")) {
521: NEXT_oldterminal = FALSE;
522: }
523: }
524:
525:
526:
527: sprintf(term_options, "%s %s %s %s \"%s\" %d title \"%s\"",
528: NEXT_oldterminal ? "old" : "new",
529: NEXT_color ? "color" : "monochrome",
530: NEXT_solid ? "solid" : "dashed",
531: NEXT_duplex_option ? (NEXT_duplex_state ? "duplex" : "simplex")
532: : "defaultplex",
533: NEXT_font,
534: NEXT_fontsize,
535: NEXT_title);
536: }
537:
538: /* store settings passed to common_init() for use in NEXT_graphics()
539: * are reserved for storing the term options
540: */
541: static int NEXT_common_uses_fonts;
542: static unsigned int NEXT_common_xoff, NEXT_common_yoff;
543:
544:
545: TERM_PUBLIC void
546: NEXT_common_init(uses_fonts, xoff, yoff, width, height, dict)
547: int uses_fonts; /* 0 for NEXT(la)tex */
548: unsigned int xoff, yoff; /* offset - 50 for /post, 0 for NEXT(la)tex */
549: unsigned int width, height; /* for bounding box */
550: char **dict; /* extra entries for the dictionary */
551: {
552: static char GPFAR NEXTi1[] = "%%%%Creator: gnuplot\n\
553: %%%%DocumentFonts: %s\n";
554: static char GPFAR NEXTi2[] = "%%%%EndComments\n\
555: /gnudict 120 dict def\ngnudict begin\n\
556: /Color %s def\n\
557: /Solid %s def\n\
558: /gnulinewidth %.3f def\n\
559: /vshift %d def\n\
560: /dl {%d mul} def\n\
561: /hpt %.1f def\n\
562: /vpt %.1f def\n";
563: static char GPFAR *NEXT_iso_8859_1_encoding[] =
564: {
565: "/reencodeISO {\n",
566: "dup dup findfont dup length dict begin\n",
567: "{ 1 index /FID ne { def }{ pop pop } ifelse } forall\n",
568: "/Encoding ISOLatin1Encoding def\n",
569: "currentdict end definefont\n",
570: "} def\n",
571: "/ISOLatin1Encoding [\n",
572: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
573: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
574: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
575: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
576: "/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright\n",
577: "/parenleft/parenright/asterisk/plus/comma/minus/period/slash\n",
578: "/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon\n",
579: "/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N\n",
580: "/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright\n",
581: "/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m\n",
582: "/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde\n",
583: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
584: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
585: "/.notdef/dotlessi/grave/acute/circumflex/tilde/macron/breve\n",
586: "/dotaccent/dieresis/.notdef/ring/cedilla/.notdef/hungarumlaut\n",
587: "/ogonek/caron/space/exclamdown/cent/sterling/currency/yen/brokenbar\n",
588: "/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot\n",
589: "/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior\n",
590: "/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine\n",
591: "/guillemotright/onequarter/onehalf/threequarters/questiondown\n",
592: "/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla\n",
593: "/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex\n",
594: "/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis\n",
595: "/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute\n",
596: "/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis\n",
597: "/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave\n",
598: "/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex\n",
599: "/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis\n",
600: "/yacute/thorn/ydieresis\n",
601: "] def\n",
602: NULL};
603:
604:
605: struct termentry *t = term;
606: int i;
607:
608: NEXT_common_uses_fonts = uses_fonts;
609: NEXT_common_xoff = xoff;
610: NEXT_common_yoff = yoff;
611:
612:
613: NEXTPrintf("%%!NEXT-Adobe-2.0\n");
614:
615: NEXTPrintf(NEXTi1, uses_fonts ? "(atend)" : "");
616:
617: NEXTPrintf("%%%%BoundingBox: %d %d %d %d\n", xoff, yoff,
618: (int) (xsize * width / NEXT_SC + 0.5 + xoff),
619: (int) (ysize * height / NEXT_SC + 0.5 + yoff));
620:
621: NEXTPrintf(NEXTi2,
622: NEXT_color ? "true" : "false",
623: NEXT_solid ? "true" : "false",
624: NEXT_LW, /* line width */
625: (int) (t->v_char) / (-3), /* shift for vertical centring */
626: NEXT_SC, /* dash length */
627: NEXT_HTIC / 2.0, /* half point width */
628: NEXT_VTIC / 2.0); /* half point height */
629:
630: if (uses_fonts && (encoding == ENCODING_ISO_8859_1)) {
631: for (i = 0; NEXT_iso_8859_1_encoding[i] != NULL; i++) {
632: NEXTPrintf("%s", NEXT_iso_8859_1_encoding[i]);
633: }
634: }
635: for (i = 0; NEXT_header[i] != NULL; i++)
636: NEXTPrintf("%s", NEXT_header[i]);
637: if (NEXT_duplex_option)
638: NEXTPrintf("statusdict begin %s setduplexmode end\n",
639: NEXT_duplex_state ? "true" : "false");
640: NEXT_RememberFont(NEXT_font);
641:
642: if (dict)
643: while (*dict)
644: NEXTPrintf("%s", *(dict++));
645:
646: NEXTPrintf("end\n%%%%EndProlog\n");
647: }
648:
649: /* the init fn for the NeXT Terminal driver */
650: TERM_PUBLIC void
651: NEXT_init()
652: {
653: // is this called more than once?
654: arpool = [[NSAutoreleasePool alloc] init];
655:
656: /* Initialize output string */
657: NEXTsize = DEFAULTNEXTSIZE;
658: if ((NEXTBuffer = malloc(NEXTsize)) == NULL) {
659: printf("Malloc error in next filter init\n");
660: exit(1);
661: }
662: NEXTBufEnd = NEXTBuffer + NEXTsize;
663: NEXTBufAt = NEXTBuffer;
664:
665:
666: term->xmax = NEXT_XMAX;
667: term->ymax = NEXT_YMAX;
668:
669: gnuTermAccess = [[GnuTermDriver alloc] init];
670: // [gnuTermAccess retain]; // since we hold it privately.
671: }
672:
673:
674: TERM_PUBLIC void
675: NEXT_graphics()
676: {
677: static char GPFAR NEXTg1[] = "0 setgray\nnewpath\n";
678: struct termentry *t = term;
679:
680: *NEXTBuffer = 0;
681: NEXTBufAt = NEXTBuffer;
682:
683: NEXT_common_init(1, NEXT_XOFF, NEXT_YOFF, term->xmax, term->ymax,
684: ENHNEXT_header);
685:
686: NEXTPrintf("gnudict begin\ngsave\n");
687: NEXTPrintf("%d %d translate\n", NEXT_common_xoff, NEXT_common_yoff);
688: NEXTPrintf("%.3f %.3f scale\n", 1.0 / NEXT_SC, 1.0 / NEXT_SC);
689:
690:
691: NEXTPrintf(NEXTg1);
692: if (NEXT_common_uses_fonts)
693: NEXTPrintf("(%s) findfont %d scalefont setfont\n", NEXT_font, (t->v_char));
694: NEXT_path_count = 0;
695: NEXT_relative_ok = FALSE;
696: NEXT_pen_x = NEXT_pen_y = -4000;
697: NEXT_taken = 0;
698: NEXT_linetype_last = -1;
699: }
700:
701:
702: TERM_PUBLIC voidNEXT_text()
703: {
704: static DPSContext d;
705:
706: NEXT_path_count = 0;
707: NEXTPrintf("stroke\ngrestore\nend\n");
708:
709: /* Terminate string */
710: *NEXTBufAt = 0;
711:
712: if (NEXT_oldterminal) {
713: d = DPSGetCurrentContext();
714: DPSPrintf(d, NEXTBuffer);
715: DPSFlushContext(d);
716: }
717: else {
718: /* Here's the call that dumps the string to the server */
719: [gnuTermAccess plot:NEXTBuffer];
720: }
721: }
722:
723:
724: TERM_PUBLIC void
725: NEXT_reset()
726: {
727: NEXTPrintf("%%%%Trailer\n");
728: if (!NEXT_common_uses_fonts) {
729: NEXTPrintf("%%%%DocumentFonts: ");
730: while (NEXT_DocFonts) {
731: struct NEXT_FontName *fnp;
732: fnp = NEXT_DocFonts->next;
733: NEXTPrintf("%s%s", NEXT_DocFonts->name, fnp ? ", " : "\n");
734: free(NEXT_DocFonts->name);
735: free(NEXT_DocFonts);
736: NEXT_DocFonts = fnp;
737: }
738: }
739: }
740:
741:
742: TERM_PUBLIC void
743: NEXT_linetype(linetype)
744: int linetype;
745: {
746: linetype = (linetype % 9) + 2;
747: if (linetype < 0)
748: linetype = 0;
749: NEXT_relative_ok = FALSE;
750: if (NEXT_linetype_last == linetype)
751: return;
752: NEXT_linetype_last = linetype;
753: NEXTPrintf("LT%c\n", "ba012345678"[linetype]);
754: NEXT_path_count = 0;
755: }
756:
757:
758: TERM_PUBLIC void
759: NEXT_move(x, y)
760: unsigned int x, y;
761: {
762: int dx, dy;
763: char abso[20], rel[20];
764: dx = x - NEXT_pen_x;
765: dy = y - NEXT_pen_y;
766: /* can't cancel all null moves--need a move after stroke'ing */
767: if (dx == 0 && dy == 0 && NEXT_relative_ok)
768: return;
769: sprintf(abso, "%d %d M\n", x, y);
770: sprintf(rel, "%d %d R\n", dx, dy);
771: if (strlen(rel) < strlen(abso) && NEXT_relative_ok) {
772: NEXTPrintf("%s", rel);
773: NEXT_taken++;
774: } else
775: NEXTPrintf("%s", abso);
776: NEXT_relative_ok = TRUE;
777: NEXT_path_count += 1;
778:
779: NEXT_pen_x = x;
780: NEXT_pen_y = y;
781: }
782:
783: TERM_PUBLIC void
784: NEXT_vector(x, y)
785: unsigned int x, y;
786: {
787: int dx, dy;
788: char abso[20], rel[20];
789: dx = x - NEXT_pen_x;
790: dy = y - NEXT_pen_y;
791: if (dx == 0 && dy == 0)
792: return;
793: sprintf(abso, "%d %d L\n", x, y);
794: sprintf(rel, "%d %d V\n", dx, dy);
795: if (strlen(rel) < strlen(abso) && NEXT_relative_ok) {
796: NEXTPrintf("%s", rel);
797: NEXT_taken++;
798: } else
799: NEXTPrintf("%s", abso);
800: NEXT_relative_ok = TRUE;
801: NEXT_path_count += 1;
802: NEXT_pen_x = x;
803: NEXT_pen_y = y;
804: if (NEXT_path_count >= 400) {
805: NEXTPrintf("currentpoint stroke M\n");
806: NEXT_path_count = 0;
807: }
808: }
809:
810:
811:
812:
813: TERM_PUBLIC int
814: NEXT_text_angle(ang)
815: int ang;
816: {
817: NEXT_ang = ang;
818: return TRUE;
819: }
820:
821:
822: TERM_PUBLIC int
823: NEXT_justify_text(mode)
824: enum JUSTIFY mode;
825: {
826: NEXT_justify = mode;
827: return TRUE;
828: }
829:
830:
831: TERM_PUBLIC int
832: NEXT_set_font(font) /* Entry font added by DJL */
833: const char *font;
834: {
835: char name[32];
836: int size, sep;
837:
838: sep = strcspn(font, ",");
839: strncpy(name, font, sep);
840: name[sep] = NUL;
841: size = NEXT_fontsize;
842: sscanf(&(font[sep + 1]), "%d", &size);
843: NEXTPrintf("/%s findfont %d scalefont setfont\n", name, size * NEXT_SC);
844: NEXT_RememberFont(name);
845: return TRUE;
846: }
847:
848:
849: /* postscript point routines */
850:
851: TERM_PUBLIC void
852: NEXT_set_pointsize(size)
853: double size;
854: {
855: NEXTPrintf("/vpt %.1f def /hpt %.1f def /vpt2 vpt 2 mul def /hpt2 hpt 2 mul def\n",
856: pointsize * NEXT_VTIC * 0.5, pointsize * NEXT_HTIC * 0.5);
857: }
858:
859: TERM_PUBLIC void
860: NEXT_point(x, y, number)
861: unsigned int x, y;
862: int number;
863: {
864: static char *pointFNS[] =
865: {"Pnt", "Pls", "Crs", "Star",
866: "Box", "BoxF", "Circle", "CircleF",
867: "TriU", "TriUF", "TriD", "TriDF",
868: "Dia", "DiaF", "Pent", "PentF",
869: "C0", "C1", "C2", "C3",
870: "C4", "C5", "C6", "C7",
871: "C8", "C9", "C10", "C11",
872: "C12", "C13", "C14", "C15",
873: "S0", "S1", "S2", "S3",
874: "S4", "S5", "S6", "S7",
875: "S8", "S9", "S10", "S11",
876: "S12", "S13", "S14", "S15",
877: "D0", "D1", "D2", "D3",
878: "D4", "D5", "D6", "D7",
879: "D8", "D9", "D10", "D11",
880: "D12", "D13", "D14", "D15"
881: };
882: if (number < 0)
883: number = -1; /* negative types are all 'dot' */
884: else
885: number %= sizeof(pointFNS) / sizeof(pointFNS[0]) - 1;
886: NEXTPrintf("%d %d %s\n", x, y, pointFNS[number + 1]);
887:
888: NEXT_relative_ok = 0;
889: NEXT_path_count = 0;
890: NEXT_linetype_last = -1; /* force next linetype change */
891: }
892:
893: /* All lifted from the enhanced postscript driver */
894:
895: static TBOOLEAN NEXT_opened_string; /* try to cut out empty ()'s */
896:
897: /* used in determining height of processed text */
898:
899: static float NEXT_max_height, NEXT_min_height;
900:
901:
902: /* process a bit of string, and return the last character used.
903: * p is start of string
904: * brace is TRUE to keep processing to }, FALSE for do one character
905: * fontname & fontsize are obvious
906: * base is the current baseline
907: * widthflag is TRUE if the width of this should count,
908: * FALSE for zero width boxes
909: */
910:
911: static char *
912: NEXT_recurse(p, brace, fontname, fontsize, base, widthflag)
913: char *p, *fontname;
914: TBOOLEAN brace, widthflag;
915: double fontsize, base;
916: {
917:
918: /* close a postscript string if it has been opened */
919: #define NEXT_FLUSH \
920: { if (NEXT_opened_string) \
921: { NEXTPrintf("%s", ")]\n"); \
922: NEXT_opened_string = FALSE; \
923: } \
924: }
925:
926: #define NEXT_OPEN \
927: { if (!NEXT_opened_string) \
928: { NEXTPrintf( "[(%s) %.1f %.1f %s (", \
929: fontname, fontsize, base, \
930: widthflag ? "true" : "false"); \
931: NEXT_opened_string = TRUE; \
932: } \
933: }
934:
935:
936: /* Start each recursion with a clean string */
937: NEXT_FLUSH
938:
939: if (base + fontsize > NEXT_max_height) {
940: NEXT_max_height = base + fontsize;
941: }
942: if (base < NEXT_min_height) {
943: NEXT_min_height = base;
944: }
945: for (; *p; ++p) {
946: float shift;
947: float f = 0; /* used for getting new font size */
948: char *localfontname, ch;
949:
950: switch (*p) {
951: case '}':
952: if (brace)
953: return (p);
954:
955: fprintf(stderr, "next driver - spurious }\n");
956: break;
957:
958: case '_':
959: case '^':
960: shift = (*p == '^') ? 0.5 : -0.3;
961:
962: NEXT_FLUSH
963:
964: p = NEXT_recurse(p + 1, FALSE, fontname, fontsize * 0.8, base + shift * fontsize, widthflag);
965:
966: break;
967:
968: case '{':
969: /*{{{ recurse (possibly with a new font) */
970:
971: if (*++p == '/') { /* then parse a fontname, optional fontsize */
972: while (*++p == ' ');
973: localfontname = p;
974: while ((ch = *p) > ' ' && ch != '=')
975: ++p;
976: if (ch == '=') {
977: *p++ = '\0';
978: /*{{{ get optional font size */
979: f = (float) strtod(p, &p);
980:
981: if (f)
982: f *= NEXT_SC; /* remember the scaling */
983: else
984: f = fontsize;
985:
986: /*}}} */
987: } else {
988: *p++ = '\0';
989: f = fontsize;
990: }
991:
992: while (*p == ' ')
993: ++p;
994: if (*localfontname)
995: localfontname = NEXT_RememberFont(localfontname);
996: else
997: localfontname = fontname;
998: } else {
999: localfontname = fontname;
1000: f = fontsize;
1001: }
1002: /*}}} */
1003:
1004:
1005: p = NEXT_recurse(p, TRUE, localfontname, f, base, widthflag);
1006:
1007:
1008: NEXT_FLUSH
1009:
1010: break;
1011:
1012: case '@':
1013: /*{{{ phantom box - prints next 'char', then restores currentpoint */
1014:
1015: NEXT_FLUSH
1016:
1017: p = NEXT_recurse(++p, FALSE, fontname, fontsize, base, FALSE);
1018:
1019: break;
1020: /*}}} */
1021:
1022: case '(':
1023: case ')':
1024: /* special cases */
1025: NEXT_OPEN
1026: NEXTPrintf("\\");
1027: NEXTPrintf("%c", *p);
1028: break;
1029: /*}}} */
1030:
1031: case '\\':
1032: /*{{{ is it an escape */
1033: /* special cases */
1034:
1035: if (p[1] == '\\' || p[1] == '(' || p[1] == ')') {
1036: NEXT_OPEN
1037: NEXTPrintf("%c", '\\');
1038: } else if ((ch = p[1]) >= '0' && ch <= '7') {
1039: /* up to 3 octal digits */
1040: NEXT_OPEN
1041: NEXTPrintf("%c", '\\');
1042: NEXTPrintf("%c", ch);
1043: ++p;
1044: if ((ch = p[1]) >= '0' && ch <= '7') {
1045: NEXTPrintf("%c", ch);
1046: ++p;
1047: if ((ch = p[1]) >= '0' && ch <= '7') {
1048: NEXTPrintf("%c", ch);
1049: ++p;
1050: }
1051: }
1052: break;
1053: }
1054: ++p;
1055: /* just go and print it (fall into the 'default' case) */
1056:
1057: /*}}} */
1058: default:
1059: NEXT_OPEN
1060:
1061: NEXTPrintf("%c", *p);
1062: }
1063:
1064: /* like TeX, we only do one character in a recursion, unless it's
1065: * in braces
1066: */
1067:
1068: if (!brace) {
1069: NEXT_FLUSH
1070: return (p); /* the ++p in the outer copy will increment us */
1071: }
1072: }
1073: NEXT_FLUSH
1074: return p;
1075: }
1076:
1077:
1078: TERM_PUBLIC void
1079: NEXT_put_text(x, y, str)
1080: unsigned int x, y;
1081: const char *str;
1082: {
1083: /* flush any pending graphics (all the XShow routines do this...) */
1084:
1085: if (!strlen(str))
1086: return;
1087:
1088: if (NEXT_path_count) {
1089: NEXTPrintf(" stroke\n");
1090: NEXT_path_count = 0;
1091: NEXT_relative_ok = FALSE;
1092: }
1093: NEXT_move(x, y);
1094:
1095: if (NEXT_ang != 0)
1096: NEXTPrintf("currentpoint gsave translate %d rotate 0 0 moveto\n",
1097: NEXT_ang * 90);
1098:
1099: NEXTPrintf("[ ");
1100:
1101: /* set up the globals */
1102:
1103: NEXT_opened_string = FALSE;
1104: NEXT_max_height = -1000;
1105: NEXT_min_height = 1000;
1106:
1107: while (*(str = NEXT_recurse(str, TRUE, NEXT_font,
1108: (double) term->v_char,
1109: 0.0, TRUE)));
1110:
1111: NEXT_max_height += NEXT_min_height;
1112:
1113: NEXTPrintf("] %.1f ", -NEXT_max_height / 3);
1114:
1115: switch (NEXT_justify) {
1116: case LEFT:
1117: NEXTPrintf("MLshow\n");
1118: break;
1119: case CENTRE:
1120: NEXTPrintf("MCshow\n");
1121: break;
1122: case RIGHT:
1123: NEXTPrintf("MRshow\n");
1124: break;
1125: }
1126:
1127: if (NEXT_ang != 0)
1128: NEXTPrintf("grestore\n");
1129: NEXT_path_count = 0;
1130: NEXT_relative_ok = FALSE;
1131: }
1132:
1133:
1134:
1135: /*
1136: static TBOOLEAN
1137: NEXT_colordetect()
1138: {
1139: NXScreen * mainscreen;
1140:
1141: mainscreen = [Application mainScreen];
1142: if (mainscreen->depth == NX_TwoBitGrayDepth) return(FALSE);
1143: return(TRUE);
1144: }
1145: */
1146:
1147: /* This just packs all the postscript into one (possibly huge) string
1148: * which will be passed (as a fake pointer) via D.O. to the server
1149: */
1150:
1151: void
1152: NEXTPrintf(char *fmt,...)
1153: {
1154: va_list ap;
1155: char *pb;
1156: int NEXToff;
1157:
1158: /* Process formatting instructions */
1159: va_start(ap, fmt);
1160: vsprintf(NEXTTmpBuf, fmt, ap);
1161: va_end(ap);
1162:
1163: /* Add to buffer */
1164: for (pb = NEXTTmpBuf; (*pb != 0); ++pb, ++NEXTBufAt) {
1165: /* reallocate if necessary */
1166: if (NEXTBufAt >= NEXTBufEnd) {
1167: NEXToff = NEXTBufAt - NEXTBuffer;
1168: NEXTsize *= 2;
1169: NEXTBuffer = realloc(NEXTBuffer, NEXTsize);
1170: NEXTBufEnd = NEXTBuffer + NEXTsize;
1171: NEXTBufAt = NEXTBuffer + NEXToff;
1172: }
1173: *NEXTBufAt = *pb;
1174: }
1175:
1176: return;
1177:
1178: }
1179:
1180: /* This next section implements the GnuTermDriver object which manages
1181: the D.O. connection and interface to Obj-C
1182: */
1183:
1184:
1185: @protocol GnuTermServerMethods
1186: /*- (oneway) executePScode:(in char *)PStext termTitle:(in char *)title;*/
1187: - (void) executePScode:(NSString *) PStext termTitle:(NSString *) title;
1188: @end
1189:
1190:
1191: @implementation GnuTermDriver
1192:
1193: - init
1194: {
1195: NSConnection *myConnection;
1196: char serverpath[100], *envstring;
1197: int GnuTermPathSet = 0;
1198:
1199:
1200: /* Ask OS for connection to server */
1201: server = [NSConnection rootProxyForConnectionWithRegisteredName: @"gnuplotServer" host:nil];
1202:
1203: [server retain];
1204:
1205: /* Server is running ready to go */
1206: if (server) printf("Connected to server\n")
1207: ;
1208:
1209: /* Server isn't running, we must fire it up */
1210: else {
1211: printf("Launching GnuTerm\n");
1212: *serverpath = 0;
1213:
1214: /* Check for path set in environment */
1215: if ((envstring = getenv("GNUTERMPATH")) != (char *) NULL) {
1216: sprintf(serverpath, "%s/GnuTerm.app/GnuTerm", envstring);
1217: GnuTermPathSet = 1;
1218: }
1219: /* Not in environment */
1220: else
1221: strcpy(serverpath, "GnuTerm");
1222:
1223: /* Try to launch application */
1224: if ([[NSWorkspace sharedWorkspace] launchApplication:[NSString stringWithCString:serverpath]] == NO) {
1225: printf("Failed to launch %s.\n", serverpath);
1226: /* Offer a little advice */
1227: if (GnuTermPathSet) {
1228: printf("You must have setenv GNUTERMPATH to something wrong\n");
1229: printf("I recommend you exit gnuplot and fix this.\n");
1230: } else {
1231: printf("It must be located in ~/Apps or /LocalApps\n");
1232: printf("I recommend that you either\n");
1233: printf("- move GnuTerm.app to one of these locations\n");
1234: printf("- set GNUTERMPATH with host%% setenv GNUTERMPATH /directory/containing_GnuTerm.app\n");
1235: printf("- start GnuTerm ahead of the first plot command\n");
1236: }
1237: }
1238: /* I wish the gnuplot terminal interface would
1239: let me return an error here.
1240: */
1241:
1242: /* Application is launching */
1243: else {
1244: /* Wait for it to register Server methods with OS */
1245: do {
1246: server =[[NSConnection
1247: rootProxyForConnectionWithRegisteredName: @"gnuplotServer" host:nil] retain];
1248: } while (!server); /* This could result in a hang,
1249: but I've never seen it fail */
1250: }
1251: }
1252:
1253:
1254: /* By limiting ourselves to known protocol
1255: * we speed up the messaging
1256: */
1257: [server setProtocolForProxy:@protocol(GnuTermServerMethods)];
1258:
1259: myConnection = [server connectionForProxy];
1260:
1261: /* If the server dies we want to know about it */
1262: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(senderIsInvalid:) name:NSConnectionDidDieNotification object:myConnection];
1263: /* In fact, we'll worry about it */
1264: ;
1265:
1266: return self;
1267: }
1268:
1269:
1270: - (void) plot:(char *)PSstr;
1271: {
1272: /* If server has become invalid, re-initialize */
1273: if (!server)
1274: [self init];
1275:
1276: /* This is where we send the huge postscript string to the server
1277: Note:
1278: The D.O. system doesn't actually give this pointer to the server.
1279: The pointer is dereferenced on the client side and the
1280: resulting data is sent to the server. On the server side,
1281: space for the data is automatically allocated, and a pointer to
1282: the local data is received.
1283: For details check out:
1284: /NextLibrary/Documentation/NextDev/GeneralRef/06_DistributedObjects/IntroDistObjects.rtf
1285: */
1286:
1287: printf("Calling server...");
1288: [server executePScode: [NSString stringWithCString: PSstr]
1289: termTitle: [NSString stringWithCString: NEXT_title]];
1290: printf("returned\n");
1291: *NEXT_title = 0;
1292: }
1293:
1294: /* This gets called by OS if server goes down */
1295: - (void) senderIsInvalid: (NSNotification *) sender
1296: {
1297: server = 0;
1298: }
1299:
1300: @end
1301:
1302:
1303:
1304: #endif /* TERM_BODY */
1305:
1306: #ifdef TERM_TABLE
1307:
1308:
1309: TERM_TABLE_START(next_driver)
1310: "next",
1311: "Interface to GnuTerm.app under NeXTstep",
1312: NEXT_XMAX, NEXT_YMAX, NEXT_VCHAR, NEXT_HCHAR,
1313: NEXT_VTIC, NEXT_HTIC, NEXT_options, NEXT_init, NEXT_reset,
1314: NEXT_text, null_scale, NEXT_graphics, NEXT_move, NEXT_vector,
1315: NEXT_linetype, NEXT_put_text, NEXT_text_angle,
1316: NEXT_justify_text, NEXT_point, do_arrow, NEXT_set_font,
1317: NEXT_set_pointsize
1318: TERM_TABLE_END(next_driver)
1319:
1320: #undef LAST_TERM
1321: #define LAST_TERM next_driver
1322:
1323: #endif /* TERM_TABLE */
1324: #endif /* TERM_PROTO_ONLY */
1325:
1326:
1327:
1328: #ifdef TERM_HELP
1329: START_HELP(next)
1330: "1 next",
1331: "?commands set terminal next",
1332: "?set terminal next",
1333: "?set term next",
1334: "?terminal next",
1335: "?term next",
1336: "?next",
1337: "?NeXT",
1338: " Several options may be set in the next driver.",
1339: "",
1340: " Syntax:",
1341: " set terminal next {<mode>} {<type> } {<color>} {<dashed>}",
1342: " {\"<fontname>\"} {<fontsize>} title {\"<newtitle>\"}",
1343: "",
1344: " where <mode> is `default`, which sets all options to their defaults;",
1345: " <type> is either `new` or `old`, where `old` invokes the old single window;",
1346: " <color> is either `color` or `monochrome`;",
1347: " <dashed> is either `solid` or `dashed`;",
1348: " \"<fontname>\" is the name of a valid PostScript font;",
1349: " <fontsize> is the size of the font in PostScript points; and",
1350: " <title> is the title for the GnuTerm window.",
1351: " Defaults are `new`, `monochrome`, `dashed`, \"Helvetica\", 14pt.",
1352: "",
1353: " Examples:",
1354: " set term next default",
1355: " set term next 22",
1356: " set term next color \"Times-Roman\" 14",
1357: " set term next color \"Helvetica\" 12 title \"MyPlot\"",
1358: " set term next old",
1359: "",
1360: " Pointsizes may be changed with `set linestyle`."
1361: END_HELP(next)
1362: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>