Changed russian description a little bit
[gnuplot] / term / amiga.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: amiga.trm,v 1.20 2006/07/21 02:35:45 sfeam Exp $
3  *
4  */
5
6 /* GNUPLOT - amiga.trm */
7
8 /*[
9  * Copyright 1991, 1992, 1993, 1998, 2004
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.
40  *
41  * This terminal driver supports:
42  *   Amiga Custom Screen
43  *
44  * AUTHORS
45  *   Carsten Steger
46  *
47  *   Pat R. Empleo      Slightly modified for Aztec C v5.2a (beta); sort of
48  *   08/27/91           supports overscan; for large WB 2.0 virtual screens,
49  *                      we limit the plot size so we don't have to scroll
50  *                      around (not fun).
51  *
52  *   Carsten Steger     Modified to support Kickstart 2.0.
53  *   09/11/91           Opens a text overscan screen when used with WB 2.0.
54  *                      Discerns between NTSC and PAL Amigas when used with
55  *                      WB 1.3 and lower.
56  *
57  *   Pat R. Empleo      Defined some 2.0 stuff in order to get Aztec C to
58  *   09/20/91           work with Carsten's new code (see above).  When
59  *                      KS/WB 2.0 support gets implemented in Aztec C, this
60  *                      kludge will get deleted!
61  *                      (Aztec C release 5.2 beta)
62  *
63  *   Carsten Steger     Converted to new terminal layout.
64  *   10/01/95
65  *
66  *   Lars Hecking       Add code from George Coulouris <glc5@cornell.edu> to
67  *   06/20/97           implement window option, requires AmigaOS 3.0+.
68  *                      General cleanup, better readability.
69  *
70  *   Lars Hecking       Replace static arrays for AMIGA_FontName and temporary
71  *   06/21/97           arrays with AllocMem()'d memory.
72  *
73  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
74  *
75  */
76
77 #include "driver.h"
78
79 #ifdef TERM_REGISTER
80 register_term(amiga)
81 #endif
82
83 #ifdef TERM_PROTO
84
85 #define AMIGA_XMAX 640
86 #define AMIGA_YMAX 512
87
88 #define AMIGA_VCHAR 12
89 #define AMIGA_HCHAR 8
90 #define AMIGA_VTIC  5
91 #define AMIGA_HTIC  5
92
93 TERM_PUBLIC void AMIGA_reset __PROTO((void));
94 TERM_PUBLIC void AMIGA_init __PROTO((void));
95 TERM_PUBLIC void AMIGA_options __PROTO((void));
96 TERM_PUBLIC void AMIGA_text __PROTO((void));
97 TERM_PUBLIC void AMIGA_graphics __PROTO((void));
98 TERM_PUBLIC void AMIGA_move __PROTO((unsigned int x, unsigned int y));
99 TERM_PUBLIC void AMIGA_vector __PROTO((unsigned int x, unsigned int y));
100 TERM_PUBLIC void AMIGA_linetype __PROTO((int linetype));
101 TERM_PUBLIC void AMIGA_put_text __PROTO((unsigned int x, unsigned int y, const char *str));
102 TERM_PUBLIC int AMIGA_justify_text __PROTO((enum JUSTIFY mode));
103 TERM_PUBLIC int AMIGA_set_font __PROTO((const char *font));
104 TERM_PUBLIC void AMIGA_suspend __PROTO((void));
105 TERM_PUBLIC void AMIGA_resume __PROTO((void));
106
107 #define GOT_AMIGA_PROTO
108
109 #endif /* TERM_PROTO */
110
111
112 #ifndef TERM_PROTO_ONLY
113 #ifdef TERM_BODY
114
115 #ifdef AMIGA_AC_5
116 #include <intuition/intuitionbase.h>
117 #include <intuition/screens.h>
118 #include <graphics/text.h>
119 #include <graphics/gfxbase.h>
120 #else
121 /* You will have to use the Kickstart 2.0 header files for this to compile */
122 #include <exec/types.h>
123 #include <dos/dos.h>
124 #include <intuition/intuitionbase.h>
125 #include <graphics/gfxbase.h>
126 #include <proto/intuition.h>
127 #include <proto/graphics.h>
128 #include <proto/exec.h>
129 #include <proto/diskfont.h>
130 #endif /* !AMIGA_AC_5 */
131
132 #ifdef HAVE_ATEXIT
133 void AMIGA_exit(void);
134 # define ATEXIT(x) (atexit(x) != 0)
135 # ifdef AMIGA_SC_6_1
136 /* #  define ATEXIT(x) (onexit(x) == 0) */
137 #  define RAWCON(x) rawcon(x)
138 # else
139 #  define RAWCON(x)             /* nought */
140 # endif                         /* SAS */
141 #else
142 # define ATEXIT(x) 0
143 #endif /* HAVE_ATEXIT */
144
145 #ifndef RETURN_FAIL
146 # define RETURN_FAIL 20
147 #endif
148
149 #define LIB_VERSION(LibBase)    ((LibBase)->LibNode.lib_Version)
150
151 #define AMIGA_ERROR(string,rc)  {fprintf (stderr,"%s\n",string);\
152                                  AMIGA_reset (); exit (rc);}
153
154 /* from plot.c */
155 extern TBOOLEAN interactive;
156
157 /* The origin is in the upper left hand corner, so we have to translate */
158 /* and flip the coordinates: */
159 #define AMIGA_VTF(y) (AMIGA_ymax-1-(y))
160
161
162 /* Libraries */
163 struct IntuitionBase *IntuitionBase;
164 struct GfxBase *GfxBase;
165 struct Library *DiskfontBase;
166
167
168 /* Name of font, size in pts */
169 static char *AMIGA_FontName = NULL;
170 static int AMIGA_FontNameLen = 0;
171 static int AMIGA_FontSize = 8;
172 static char AMIGA_default_font[MAX_ID_LEN+1] = {'\0'};
173 #define AMIGA_DEFAULTFONT "topaz"
174
175 /* Font stuff */
176 static struct TextAttr AMIGA_Font =
177 {
178     "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT
179 };
180 static struct TextFont *AMIGA_TextFont;
181
182
183 /* Screen stuff */
184 static struct NewScreen AMIGA_NewScreen =
185 {
186     0, 0, AMIGA_XMAX, AMIGA_YMAX, 4, 15, 0, HIRES | LACE,
187     CUSTOMSCREEN | SCREENBEHIND | SCREENQUIET, NULL, NULL, NULL, NULL
188 };
189 static struct Screen *AMIGA_Screen;
190 static struct TagItem AMIGA_ScrTagList[] =
191 {
192     { SA_Overscan, OSCAN_TEXT },
193     { TAG_DONE, 0 }
194 };
195
196
197 /* Window stuff */
198 /* FALSE: plot to screen; TRUE: plot to window */
199 static TBOOLEAN AMIGA_window_mode = FALSE;
200
201 #define AMIGA_WIN_XMAX 512
202 #define AMIGA_WIN_YMAX 320
203
204 static struct Window *AMIGA_Window;
205 static struct TagItem AMIGA_WinTagList[] =
206 {
207     { WA_InnerWidth, AMIGA_WIN_XMAX },
208     { WA_InnerHeight, AMIGA_WIN_YMAX },
209     { WA_Title, (ULONG) "gnuplot" },
210     { WA_DragBar, TRUE },
211     { WA_DepthGadget, TRUE },
212     { WA_WBenchWindow, TRUE },
213     { WA_SmartRefresh, TRUE },
214     { WA_GimmeZeroZero, TRUE },
215     { WA_AutoAdjust, TRUE },
216     { TAG_DONE, 0 }
217 };
218
219 /*
220  * This  is the palette.  Values are stored as 0xrrggbb, where rr, gg, and, bb
221  * are big-endian 8-bit intensities for red, green, and blue, respectively.
222  */
223 static unsigned int palette[] =
224 {
225     0xffffff,                   /* white */
226     0x000000,                   /* black */
227     0xff0000,                   /* red */
228     0x00ff00,                   /* green */
229     0x0000ff,                   /* blue */
230     0x00ffff,                   /* cyan */
231     0xff00ff,                   /* magenta */
232     0xffff00,                   /* yellow */
233     0x7f007f,                   /* purple */
234     0xff7f00,                   /* orange */
235 };
236
237 #define PALETTE_SIZE (sizeof (palette) / sizeof (unsigned int))
238
239 /* This is the color look-up table, indexed in the same order as
240  * the above palette. The values stored in this table are pen numbers;
241  * e.g clut[2] is the pen which represents the color "red".
242  */
243 static unsigned int clut[PALETTE_SIZE];
244
245
246 /* Colors */
247 static UWORD AMIGA_Colors[] =
248 {
249     0x000, 0xfff, 0xbbb, 0x0f0, 0xf00, 0x00f, 0x3ca, 0xf0f,
250     0x94d, 0x0ff, 0x82f, 0xff0, 0x0af, 0xc5e, 0xfa2, 0xf44
251 };
252
253
254 /* Misc */
255 static int AMIGA_slinetype;
256 static enum JUSTIFY AMIGA_justify = LEFT;
257 static unsigned int AMIGA_ymax, AMIGA_xmax;
258 static WORD AMIGA_cwd, AMIGA_cht, AMIGA_bsl, AMIGA_vadj;
259 /* Common RastPort */
260 static struct RastPort *AMIGA_RastPort;
261
262
263 enum AMIGA_id { AMI_SCREEN, AMI_WINDOW, AMI_OTHER };
264
265 static struct gen_table AMIGA_opts[] =
266 {
267     {"scr$een", AMI_SCREEN },
268     {"win$dow", AMI_WINDOW },
269     { NULL, AMI_OTHER }
270 };
271
272
273 /*
274  * Scan terminal options
275  */
276 TERM_PUBLIC void
277 AMIGA_options()
278 {
279
280     while (!END_OF_COMMAND) {
281         switch(lookup_table(&AMIGA_opts[0],c_token)) {
282         case AMI_SCREEN:
283             AMIGA_window_mode = FALSE;
284             c_token++;
285             break;
286         case AMI_WINDOW:
287             AMIGA_window_mode = TRUE;
288             c_token++;
289             break;
290         case AMI_OTHER:
291         default:
292             /* Font name */
293             if (isstring(c_token)) {
294                 if (AMIGA_FontName != NULL) {
295                     FreeMem(AMIGA_FontName,AMIGA_FontNameLen);
296                     AMIGA_FontName = NULL;
297                     AMIGA_FontNameLen = 0;
298                 }
299
300                 AMIGA_FontNameLen = token_len(c_token);
301
302                 AMIGA_FontName = AllocMem(AMIGA_FontNameLen,0);
303                 if (AMIGA_FontName == NULL)
304                     AMIGA_ERROR("No memory for font name", RETURN_FAIL);
305                 quote_str(AMIGA_FontName, c_token, AMIGA_FontNameLen);
306                 c_token++;
307             } else {
308                 /* Font size */
309                 struct value a;
310                 AMIGA_FontSize = (int) real(const_express(&a));
311             }
312
313             break;
314         }
315     }
316
317     if (AMIGA_FontName == NULL && AMIGA_FontSize != 0) {
318         AMIGA_FontNameLen = strlen(AMIGA_DEFAULTFONT) + 1;
319         AMIGA_FontName = AllocMem(AMIGA_FontNameLen,0);
320         if (AMIGA_FontName == NULL)
321             AMIGA_ERROR("No memory for font name", RETURN_FAIL);
322         strcpy(AMIGA_FontName, AMIGA_DEFAULTFONT);
323     }
324     if (AMIGA_FontName != NULL && AMIGA_FontSize == 0)
325         AMIGA_FontSize = 8;
326
327     if (AMIGA_FontName != NULL && AMIGA_FontSize != 0) {
328         sprintf(AMIGA_default_font, "%s,%d", AMIGA_FontName, AMIGA_FontSize);
329         sprintf(term_options, "%s \"%s\" %d", \
330                 (AMIGA_window_mode != TRUE ? "screen" : "window"), \
331                 AMIGA_FontName, AMIGA_FontSize);
332     } else
333         sprintf(term_options, "%s", (AMIGA_window_mode != TRUE ? "screen" : "window"));
334 }
335
336
337 /*
338  * Close open font, screen and libraries.
339  */
340 TERM_PUBLIC void
341 AMIGA_reset()
342 {
343     if (AMIGA_window_mode == TRUE) {
344         int i = 0;
345
346         /* Free the pens */
347         while (i < PALETTE_SIZE) {
348             if (clut[i] != -1)
349                 ReleasePen(AMIGA_Window->WScreen->ViewPort.ColorMap, clut[i]);
350
351             i++;
352         }
353
354         /* Close the window */
355         if (AMIGA_Window != NULL)
356             CloseWindow(AMIGA_Window);
357
358         AMIGA_Window = NULL;
359         AMIGA_window_mode = FALSE;
360     }
361     if (AMIGA_TextFont != NULL)
362         CloseFont(AMIGA_TextFont);
363
364     if (DiskfontBase != NULL)
365         CloseLibrary(DiskfontBase);
366
367     if (AMIGA_Screen != NULL)
368         CloseScreen(AMIGA_Screen);
369
370     if (IntuitionBase != NULL)
371         CloseLibrary((struct Library *) IntuitionBase);
372
373     if (GfxBase != NULL)
374         CloseLibrary((struct Library *) GfxBase);
375
376     if (AMIGA_FontName != NULL)
377         FreeMem(AMIGA_FontName,AMIGA_FontNameLen);
378
379     AMIGA_FontName = NULL;
380     AMIGA_FontNameLen = 0;
381     AMIGA_TextFont = NULL;
382     DiskfontBase = NULL;
383     AMIGA_Screen = NULL;
384     IntuitionBase = NULL;
385     GfxBase = NULL;
386
387     AMIGA_RastPort = NULL;
388 }
389
390
391 /*
392  * Init terminal.
393  */
394 TERM_PUBLIC void
395 AMIGA_init()
396 {
397
398     /* Install exit trap in case of abnormal termination (see below). */
399     if (ATEXIT(AMIGA_exit))
400         AMIGA_ERROR("Couldn't set exit trap", RETURN_FAIL);
401
402     /* Open needed libraries */
403     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
404     if (GfxBase == NULL)
405         AMIGA_ERROR("No Graphics-Library", RETURN_FAIL);
406
407     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
408     if (IntuitionBase == NULL)
409         AMIGA_ERROR("No Intuition-Library", RETURN_FAIL);
410
411     if (AMIGA_window_mode == TRUE) {
412         int i = 0;
413
414         /* Initialize the clut */
415         while (i < PALETTE_SIZE)
416             clut[i++] = -1;
417     }
418     if (LIB_VERSION(IntuitionBase) <= 34) {
419         /* We compute the vertical resolution for those poor NTSC-souls   :-)   */
420         if (GfxBase->DisplayFlags & PAL)
421             AMIGA_ymax = 512;
422         else
423             AMIGA_ymax = 400;
424
425         AMIGA_xmax = 640;
426         AMIGA_NewScreen.Width = AMIGA_xmax;
427         AMIGA_NewScreen.Height = AMIGA_ymax;
428
429         AMIGA_Screen = OpenScreen(&AMIGA_NewScreen);
430
431         if (AMIGA_Screen == NULL)
432             AMIGA_ERROR("No Screen", RETURN_FAIL);
433
434         AMIGA_RastPort = &AMIGA_Screen->RastPort;
435
436     } else {                    /* Intuition version > 34 */
437         /* Kickstart 2.0 support */
438         AMIGA_NewScreen.Width = STDSCREENWIDTH;
439         AMIGA_NewScreen.Height = STDSCREENHEIGHT;
440
441         if (AMIGA_window_mode != TRUE) {
442
443             AMIGA_Screen = OpenScreenTagList(&AMIGA_NewScreen, AMIGA_ScrTagList);
444
445             if (AMIGA_Screen == NULL)
446                 AMIGA_ERROR("No Screen", RETURN_FAIL);
447
448             AMIGA_RastPort = &AMIGA_Screen->RastPort;
449
450             AMIGA_xmax = AMIGA_Screen->Width;
451             AMIGA_ymax = AMIGA_Screen->Height;
452         } else if (LIB_VERSION(GfxBase) >= 39) { /* AMIGA_window_mode == TRUE */
453             /* Open the plot window */
454
455             AMIGA_Window = (struct Window *)OpenWindowTagList(NULL, AMIGA_WinTagList);
456
457             /* Don't do this: fall back to screen */
458             if (AMIGA_Window == NULL)
459                 AMIGA_ERROR("Could not open plot window", RETURN_FAIL);
460
461             AMIGA_RastPort = AMIGA_Window->RPort;
462
463             AMIGA_xmax = AMIGA_WIN_XMAX;
464             AMIGA_ymax = AMIGA_WIN_YMAX;
465
466         }                       /* Gfx version >= 39 */
467     }                           /* Intuition version <= 34 */
468
469     term->xmax = AMIGA_xmax;
470     term->ymax = AMIGA_ymax;
471
472     if (AMIGA_window_mode != TRUE) {
473         char *name =  NULL;
474 /*      assert(AMIGA_FontName != NULL); */
475         /* should even do for ridiculously large FontSize :) */
476         name = AllocMem(AMIGA_FontNameLen + 1 + INT_STR_LEN + 1,0);
477         if (name == NULL)
478             AMIGA_ERROR("No memory for font name", RETURN_FAIL);
479         sprintf(name, "%s,%d", AMIGA_FontName, AMIGA_FontSize);
480         AMIGA_set_font(name);
481         FreeMem(name,AMIGA_FontNameLen + INT_STR_LEN + 2);
482
483         LoadRGB4(&AMIGA_Screen->ViewPort, AMIGA_Colors, 16);
484         RemakeDisplay();
485         AMIGA_slinetype = 1;
486         SetAPen(&AMIGA_Screen->RastPort, AMIGA_slinetype);
487     } else {
488         int i, r, g, b;
489
490         AMIGA_bsl = AMIGA_Window->RPort->TxBaseline;    /* Reference line */
491         AMIGA_cht = AMIGA_Window->RPort->TxHeight;      /* Height of characters */
492
493         /* Allocate pens */
494         for (i = 0; i < PALETTE_SIZE; i++) {
495             r = (palette[i] << 8) & 0xFF000000;
496             g = (palette[i] << 16) & 0xFF000000;
497             b = (palette[i] << 24) & 0xFF000000;
498             clut[i] = ObtainBestPenA(AMIGA_Window->WScreen->ViewPort.ColorMap, r, g, b, NULL);
499         }
500
501     }
502
503     SetDrMd(AMIGA_RastPort, JAM1);
504
505 }
506
507
508 /*
509  *
510  */
511 TERM_PUBLIC void
512 AMIGA_text()
513 {
514     if (AMIGA_window_mode != TRUE) {
515         if (interactive == TRUE) {
516             FILE *fp;
517
518             if ((fp = fopen("*", "r")) != NULL) {
519                 int c = getc(fp);
520
521                 ungetc(c, stdin);
522                 fclose(fp);
523             }
524             ScreenToBack(AMIGA_Screen);
525         }
526     }
527 }
528
529
530 /*
531  *
532  */
533 TERM_PUBLIC void
534 AMIGA_graphics()
535 {
536
537     SetRast(AMIGA_RastPort, 0);
538
539     if (AMIGA_window_mode == TRUE) {
540         /* clear the window */
541         SetAPen(AMIGA_Window->RPort, clut[0]);
542         RectFill(AMIGA_Window->RPort, 0, 0, 640, 400);
543         AMIGA_slinetype = clut[1];
544     }
545     SetAPen(AMIGA_RastPort, AMIGA_slinetype);
546     AMIGA_resume();
547 }
548
549
550 /*
551  *
552  */
553 TERM_PUBLIC void
554 AMIGA_move(unsigned int x, unsigned int y)
555 {
556     if ((x >= AMIGA_xmax) || (y >= AMIGA_ymax))
557         return;
558
559     Move(AMIGA_RastPort, x, AMIGA_VTF(y));
560 }
561
562
563 /*
564  *
565  */
566 TERM_PUBLIC void
567 AMIGA_vector(unsigned int x, unsigned int y)
568 {
569     if ((x >= AMIGA_xmax) || (y >= AMIGA_ymax))
570         return;
571
572     Draw(AMIGA_RastPort, x, AMIGA_VTF(y));
573 }
574
575
576 /*
577  *
578  */
579 TERM_PUBLIC void
580 AMIGA_linetype(int linetype)
581 {
582     if (AMIGA_window_mode != TRUE) {
583         if (linetype >= 13)
584             linetype %= 13;
585
586         if (linetype < -3)
587             linetype = LT_BLACK;
588
589         AMIGA_slinetype = linetype + 3;
590     } else {
591         if (linetype >= 0)
592             linetype = (linetype % 9) + 1;
593
594         if (linetype < 0)
595             linetype = 1;
596
597         AMIGA_slinetype = clut[linetype];
598     }
599     SetAPen(AMIGA_RastPort, AMIGA_slinetype);
600 }
601
602
603 /*
604  *
605  */
606 TERM_PUBLIC void
607 AMIGA_put_text(unsigned int x, unsigned int y, const char *str)
608 {
609     LONG len, tx_len;
610     WORD x_min, x_max, y_min, y_max;
611
612     len = strlen(str);
613
614     tx_len = TextLength(AMIGA_RastPort, str, len);
615
616     switch (AMIGA_justify) {
617     case LEFT:
618         x_min = x;
619         x_max = x + tx_len;
620         break;
621     case CENTRE:
622         x_min = x - tx_len / 2;
623         x_max = x + tx_len - tx_len / 2;        /* avoid roundoff errors ! */
624         break;
625     default:                    /* does this make sense ?? */
626     case RIGHT:
627         x_min = x - tx_len;
628         x_max = x;
629         break;
630     }
631
632     y_min = AMIGA_VTF(y) - AMIGA_vadj;
633     y_max = y_min + AMIGA_cht;
634
635     /* Check if character-string lies completely within the screen: */
636     /* What about clipping? */
637     if ((x_max >= AMIGA_xmax) || (y_min < 0) || (y_max >= AMIGA_ymax))
638         return;
639
640     Move(AMIGA_RastPort, x_min, y_min + AMIGA_bsl);
641     Text(AMIGA_RastPort, str, len);
642 }
643
644
645 /*
646  *
647  */
648 TERM_PUBLIC int
649 AMIGA_justify_text(enum JUSTIFY mode)
650 {
651     AMIGA_justify = mode;
652     return TRUE;
653 }
654
655
656 /*
657  *
658  */
659 TERM_PUBLIC int
660 AMIGA_set_font(const char *font)
661 {
662     static char test_str[] =
663     " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
664     static WORD test_len, test_pxl;
665
666     /* Disable for window mode */
667     if (AMIGA_window_mode != TRUE) {
668         char *name = NULL;
669         int size, sep, namelen;
670
671         /* Allow caller to pass "" to indicate default font */
672         if (!font || !(*font))
673             font = AMIGA_default_font;
674
675         sep = strcspn(font, ",");
676         namelen = strlen(font) + strlen(".font") + 1;
677         name = AllocMem(namelen,0);
678         if (name == NULL)
679             AMIGA_ERROR("No memory for font name", RETURN_FAIL);
680         strcpy(name,font);
681         name[sep] = NUL;
682         size = AMIGA_FontSize;
683         if (font[sep] == ',')
684             sscanf(&(font[sep + 1]), "%d", &size);
685
686         if (name != NULL && strcmp(name, "") != 0) {
687             strcat(name, ".font");
688
689             /* Avoid opening "diskfont.library" if a built-in font is desired */
690             if ((strcmp("topaz.font", name) == 0) &&
691                 ((size == TOPAZ_EIGHTY) || (size == TOPAZ_SIXTY))) {
692                 AMIGA_Font.ta_Name = name;
693                 AMIGA_Font.ta_YSize = size;
694                 AMIGA_Font.ta_Style = FS_NORMAL;
695                 AMIGA_Font.ta_Flags = FPF_ROMFONT;
696                 AMIGA_TextFont = OpenFont(&AMIGA_Font);
697
698                 if (AMIGA_TextFont != NULL)
699                     SetFont(&AMIGA_Screen->RastPort, AMIGA_TextFont);
700
701             } else {
702                 DiskfontBase = OpenLibrary("diskfont.library", 0);
703
704                 if (DiskfontBase != NULL) {
705                     AMIGA_Font.ta_Name = name;
706                     AMIGA_Font.ta_YSize = size;
707                     AMIGA_Font.ta_Style = FS_NORMAL;
708                     AMIGA_Font.ta_Flags = FPF_ROMFONT | FPF_DISKFONT;
709                     AMIGA_TextFont = OpenDiskFont(&AMIGA_Font);
710
711                     if (AMIGA_TextFont != NULL)
712                         SetFont(&AMIGA_Screen->RastPort, AMIGA_TextFont);
713                 }
714             }
715         }
716         /* Width of characters: This works better for proportional fonts than */
717         /* AMIGA_Screen->RastPort.TxWidth + AMIGA_Screen->RastPort.TxSpacing */
718         test_len = strlen(test_str);
719         test_pxl = TextLength(&AMIGA_Screen->RastPort, test_str, test_len);
720
721         AMIGA_cwd = test_pxl / test_len;
722         AMIGA_cht = AMIGA_Screen->RastPort.TxHeight;    /* Height of characters */
723         AMIGA_bsl = AMIGA_Screen->RastPort.TxBaseline;  /* Reference line */
724
725         /* Amount by which characters have to be shifted upwards to be */
726         /* vertically justified: */
727         AMIGA_vadj = AMIGA_bsl / 2;
728         term->v_char = AMIGA_cht + 4;   /* So lines won't be too close */
729         term->h_char = AMIGA_cwd;
730
731         FreeMem(name,namelen);
732     }                           /* !window_mode */
733     return TRUE;
734 }
735
736
737 /*
738  *
739  */
740 TERM_PUBLIC void
741 AMIGA_suspend()
742 {
743     if (AMIGA_window_mode != TRUE) {
744         if (interactive == TRUE) {
745             FILE *fp;
746
747             if ((fp = fopen("*", "r")) != NULL) {
748                 int c = getc(fp);
749
750                 ungetc(c, stdin);
751                 fclose(fp);
752             }
753             ScreenToBack(AMIGA_Screen);
754         }
755     }
756 }
757
758
759 /*
760  *
761  */
762 TERM_PUBLIC void
763 AMIGA_resume()
764 {
765     if (AMIGA_window_mode != TRUE)
766         ScreenToFront(AMIGA_Screen);
767     else
768         WindowToFront(AMIGA_Window);
769 }
770
771
772 #ifdef HAVE_ATEXIT
773 /* This function is mainly included if the program terminates abnormally
774  * and the screen and libraries are still open. It closes down all opened
775  * libraries and screens. This happens e.g. when loading "bivariat.demo"
776  * and the stack is smaller than 120000 bytes.
777  */
778 void
779 AMIGA_exit()
780 {
781     AMIGA_reset();
782     RAWCON(0);
783 }
784
785 #endif /* HAVE_ATEXIT */
786
787
788 #endif /* TERM_BODY */
789
790 #ifdef TERM_TABLE
791
792 TERM_TABLE_START(amiga_driver)
793     "amiga", "Amiga Custom Screen/Window [screen window]",
794     AMIGA_XMAX, AMIGA_YMAX, AMIGA_VCHAR, AMIGA_HCHAR,
795     AMIGA_VTIC, AMIGA_HTIC, AMIGA_options, AMIGA_init, AMIGA_reset,
796     AMIGA_text, null_scale, AMIGA_graphics, AMIGA_move, AMIGA_vector,
797     AMIGA_linetype, AMIGA_put_text, null_text_angle,
798     AMIGA_justify_text, do_point, do_arrow, AMIGA_set_font,
799     0,                          /* pointsize */
800     TERM_CAN_MULTIPLOT, AMIGA_suspend, AMIGA_resume
801 TERM_TABLE_END(amiga_driver)
802
803 #undef LAST_TERM
804 #define LAST_TERM amiga_driver
805
806 #endif /* TERM_TABLE */
807 #endif /* TERM_PROTO_ONLY */
808
809
810 #ifdef TERM_HELP
811 START_HELP(amiga)
812 "1 amiga",
813 "?commands set terminal amiga",
814 "?set terminal amiga",
815 "?set term amiga",
816 "?terminal amiga",
817 "?term amiga",
818 "?amiga",
819 " The `amiga` terminal, for Commodore Amiga computers, allows the user to",
820 " plot either to a screen (default), or, if Kickstart 3.0 or higher is",
821 " installed, to a window on the current public screen. The font and its size",
822 " can also be selected.",
823 "",
824 " Syntax:",
825 "       set terminal amiga {screen | window} {\"<fontname>\"} {<fontsize>}",
826 "",
827 " The default font is 8-point \"topaz\".",
828 "",
829 " The screen option uses a virtual screen, so it is possible that the graph",
830 " will be larger than the screen."
831 END_HELP(amiga)
832 #endif /* TERM_HELP */