Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / atarivdi.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: atarivdi.trm,v 1.19 2006/07/21 02:35:45 sfeam Exp $
3  *
4  */
5
6 /* GNUPLOT - atari.trm */
7
8 /*[
9  * Copyright 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  *   Atari Screens working with the normal VDI
43  *     (this should include TT and big screens)
44  *
45  * AUTHORS
46  *  Alexander Lehmann
47  *  HE Koechling
48  *
49  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
50  *
51  * ATARI-related comments please to alexlehm@iti.informatik.th-darmstadt.de
52  *
53  */
54
55 #include "driver.h"
56
57 #ifdef TERM_REGISTER
58 register_term(vdi)
59 #endif
60
61 #ifdef TERM_PROTO
62
63 /* function-prototypes */
64 TERM_PUBLIC void VDI_options(void);
65 TERM_PUBLIC void VDI_init(void);
66 TERM_PUBLIC void VDI_reset(void);
67 TERM_PUBLIC void VDI_graphics(void);
68 TERM_PUBLIC void VDI_text(void);
69 TERM_PUBLIC void VDI_move(unsigned int x, unsigned int y);
70 TERM_PUBLIC void VDI_vector(unsigned int x, unsigned int y);
71 TERM_PUBLIC void VDI_linetype(int lt);
72 TERM_PUBLIC int VDI_text_angle(int ang);
73 TERM_PUBLIC void VDI_put_text(unsigned int x, unsigned int y, const char *str);
74 TERM_PUBLIC int VDI_justify_text(enum JUSTIFY mode);
75 TERM_PUBLIC void VDI_point(unsigned int x, unsigned int y, int number);
76
77 /* default to hi-res */
78 #define VDI_XMAX 640
79 #define VDI_YMAX 400
80 #define VDI_VCHAR 16
81 #define VDI_HCHAR 8
82 #define VDI_HTIC (VDI_XMAX/100)
83 #define VDI_VTIC VDI_HTIC
84
85 #endif /* TERM_PROTO */
86
87 #ifndef TERM_PROTO_ONLY
88 #ifdef TERM_BODY
89
90 #ifdef __PUREC__
91 /* why did they have to change these names ??? */
92 # include <aes.h>
93 # include <vdi.h>
94 # include <tos.h>
95 #else /* !__PUREC__ i.e. __GNUC__, maybe others */
96 # include <aesbind.h>
97 # include <vdibind.h>
98 # include <osbind.h>
99 #endif
100
101 #define VDI_yc(y) (VDI_maxycoord-(y))
102 #define VDI_LINETYPES_MAX       11
103
104 static int VDI_linetypes[VDI_LINETYPES_MAX] =
105 {
106     0xffff, 0x1111,
107     0xffff, 0x5555, 0x3333, 0x7777,
108     0x3f3f, 0x0f0f, 0x5f5f, 0xe4e4, 0x55f5
109 };
110
111 static int VDI_lt;
112 static int vdi_vdi_handle = -1;
113 static int VDI_maxycoord;
114 static int VDI_rotation;
115 static int VDI_numcolors;
116 static int pxy[128];            /* Maximum of 64 pixels per v_pline */
117 static int pxy_index;
118 static int VDI_colors[16];
119 static int VDI_savecolors[16][3];
120 static int VDI_numpalette;
121
122 #define VDI_c_height_default 6  /* well, well ...               */
123
124 static int VDI_c_height = VDI_c_height_default;
125
126 static void vdi_flush_line(void);
127
128 TERM_PUBLIC void
129 VDI_options()
130 {
131 #define VDIHEXERROR "palette values 3 hex digits, please"
132 #define VDIHEIGHTERROR "expecting a character height"
133     char opt[4];
134     int i;
135     char *tok_end;
136
137     term_options[0] = NUL;
138     VDI_c_height = VDI_c_height_default;
139
140     for (i = 0; i < 17; i++) {
141         if (END_OF_COMMAND)
142             break;
143         if (token[c_token].length > 3) {
144             VDI_numpalette = 0;
145             VDI_c_height = VDI_c_height_default;
146             term_options[0] = NUL;
147             int_error(c_token, VDIHEXERROR);
148         }
149         capture(opt, c_token, c_token, 6);
150         if (!i) {
151             VDI_c_height = strtoul(opt, &tok_end, 10);
152             if (*tok_end != NUL) {
153                 VDI_numpalette = 0;
154                 VDI_c_height = VDI_c_height_default;
155                 term_options[0] = NUL;
156                 int_error(c_token, VDIHEIGHTERROR);
157             }
158             if (VDI_c_height > 999)
159                 VDI_c_height = 999;     /* avoid opt length overflow */
160             sprintf(opt, "%d ", VDI_c_height);
161         } else {
162             VDI_colors[i - 1] = strtoul(opt, &tok_end, 16);
163             if (*tok_end != NUL) {
164                 VDI_numpalette = 0;
165                 VDI_c_height = VDI_c_height_default;
166                 term_options[0] = NUL;
167                 int_error(c_token, VDIHEXERROR);
168             }
169             sprintf(opt, "%03X ", VDI_colors[i - 1]);
170         }
171         strcat(term_options, opt);
172         c_token++;
173     }
174     VDI_numpalette = (i == 0 ? 0 : i - 1);
175 }
176
177 TERM_PUBLIC void
178 VDI_init()
179 {
180     int work_in[11];
181     int work_out[57];
182     int i;
183     int hchar, wchar, dummy;
184     int rgb[3];
185     int num_save;
186     char *colors, *tok_end;
187
188     if (VDI_numpalette == 0 && (colors = getenv("GNUCOLORS")) && *colors) {
189         for (i = 0; i < 17; i++) {
190             if (!i) {
191                 VDI_c_height = strtoul(colors, &tok_end, 10);
192                 if (colors == tok_end) {
193                     i = 0;
194                     VDI_c_height = VDI_c_height_default;
195                     break;
196                 }
197             } else {
198                 if (*colors == NUL)
199                     break;
200                 VDI_colors[i] = strtoul(colors, &tok_end, 16);
201                 if (colors == tok_end || (unsigned) VDI_colors[i] > 0xfff) {
202                     i = 0;
203                     break;
204                 }
205             }
206             colors = tok_end;
207
208             while (*colors == ' ')
209                 colors++;
210         }
211         VDI_numpalette = (i == 0 ? 0 : i - 1);
212     }
213     vdi_vdi_handle = graf_handle(&wchar, &hchar, &dummy, &dummy);
214     if (!vdi_vdi_handle)
215         int_error(NO_CARET, "Fatal error opening virtual workstation");
216
217     for (i = 0; i < 10; work_in[i++] = 1);
218     work_in[10] = 2;            /* use raster coordinates */
219     v_opnvwk(work_in, &vdi_vdi_handle, work_out);
220     if (!vdi_vdi_handle)
221         int_error(NO_CARET, "Fatal error opening virtual workstation");
222
223     vst_height(vdi_vdi_handle, VDI_c_height, &dummy, &dummy, &wchar, &hchar);
224
225     vs_clip(vdi_vdi_handle, 0, work_in);        /* turn clipping off */
226
227     term->xmax = work_out[0] + 1;
228     term->ymax = work_out[1] + 1;
229     term->h_char = wchar;
230     term->v_char = hchar;       /* hchar stands for height this time */
231     term->h_tic = (work_out[0] + 1) / 100;
232     term->v_tic = term->h_tic;
233
234     VDI_maxycoord = work_out[1];
235     VDI_numcolors = work_out[13];
236     pxy_index = 0;
237
238     for (i = 0; i < VDI_numpalette; i++) {
239         vq_color(vdi_vdi_handle, i, 1, VDI_savecolors[i]);
240
241         rgb[0] = 1000 * (VDI_colors[i] >> 8);
242         rgb[0] /= 15;
243         rgb[1] = 1000 * ((VDI_colors[i] >> 4) & 15);
244         rgb[1] /= 15;
245         rgb[2] = 1000 * (VDI_colors[i] & 15);
246         rgb[2] /= 15;
247         vs_color(vdi_vdi_handle, i, rgb);
248     }
249 #ifdef __PUREC__
250 /* currently the PureC version runs as .prg and the GCC version runs as .ttp.
251    Let's hope that we soon figure out which way is the best */
252     v_hide_c(vdi_vdi_handle);
253 #endif
254 }
255
256 TERM_PUBLIC void
257 VDI_reset()
258 {
259     int i;
260
261     if (vdi_vdi_handle != -1) {
262         for (i = 0; i < VDI_numpalette; i++) {
263             vs_color(vdi_vdi_handle, i, VDI_savecolors[i]);
264         }
265 #ifdef __PUREC__
266 /* see above */
267         v_show_c(vdi_vdi_handle, 0);
268 #endif
269         v_clsvwk(vdi_vdi_handle);
270         vdi_vdi_handle = -1;
271     }
272 }
273
274 TERM_PUBLIC void
275 VDI_graphics()
276 {
277     int pxy[8];
278     MFDB mfdb;
279
280     fflush(stdout);
281     fflush(stderr);
282     Cconws("\033f");            /* turn cursor off */
283 /*  apparently v_clrwk doesn't work with overscan. We'll blit the screen clear.
284     v_clrwk( vdi_vdi_handle );
285 */
286     mfdb.fd_addr = NULL;        /* NULL means actual screen. So we don't need size etc. */
287
288     pxy[0] = pxy[4] = 0;
289     pxy[1] = pxy[5] = 0;
290     pxy[2] = pxy[6] = term->xmax - 1;
291     pxy[3] = pxy[7] = term->ymax - 1;
292
293     vro_cpyfm(vdi_vdi_handle, ALL_WHITE /*0 */ ,
294               pxy, &mfdb, &mfdb);
295
296     pxy_index = 0;
297 }
298
299 TERM_PUBLIC void
300 VDI_text()
301 {
302     vdi_flush_line();
303     Cnecin();                   /* wait for any char --> enable screen dump */
304     Cconws("\033e");            /* turn cursor on again */
305 }
306
307 TERM_PUBLIC void
308 VDI_move(unsigned int x, unsigned int y)
309 {
310     vdi_flush_line();
311
312     pxy_index = 1;
313     pxy[0] = x;
314     pxy[1] = VDI_yc(y);
315 }
316
317 TERM_PUBLIC void
318 VDI_vector(unsigned int x, unsigned int y)
319 {
320     pxy[2 * pxy_index] = x;
321     pxy[2 * pxy_index + 1] = VDI_yc(y);
322     pxy_index++;
323
324     if (pxy_index == 64) {      /* we're all full */
325         vdi_flush_line();
326     }
327 }
328
329 TERM_PUBLIC void
330 VDI_linetype(int lt)
331 {
332     vdi_flush_line();
333
334     VDI_lt = lt;
335 }
336
337 TERM_PUBLIC void
338 VDI_put_text(unsigned int x, unsigned int y, const char *str)
339 {
340     int vchar = term->v_char;
341     int dummy;
342
343     if (!strlen(str))
344         return;
345
346     if (x < 0)
347         x = 0;
348     if (y < 0)
349         y = 0;
350
351     /* align text left and to middle of char height */
352     vst_alignment(vdi_vdi_handle, 0, 5, &dummy, &dummy);
353     vst_rotation(vdi_vdi_handle, (VDI_rotation ? 900 : 0));
354     if (VDI_rotation)
355         v_gtext(vdi_vdi_handle, x - vchar / 2 + 1, VDI_yc(y) - 1, str);
356     else
357         v_gtext(vdi_vdi_handle, x + 1, VDI_yc(y) - vchar / 2 + 1, str);
358 }
359
360 TERM_PUBLIC int
361 VDI_text_angle(int ang)
362 {
363     VDI_rotation = ang;
364
365     return TRUE;
366 }
367
368 TERM_PUBLIC int
369 VDI_justify_text(enum JUSTIFY mode)
370 {
371     return FALSE;
372 }
373
374 TERM_PUBLIC void
375 VDI_point(unsigned int x, unsigned int y, int number)
376 {
377     int old_linetype;
378
379     if (VDI_numcolors == 2) {
380         line_and_point(x, y, number);   /* monochrome */
381     } else {
382         /* we map colors that exceed our limit to dotted lines, but we can't do
383            that with the markers (sortof a generalized line_and_point) */
384         old_linetype = VDI_lt;
385         if (VDI_lt > VDI_numcolors - 2) {
386             /* same color, but no dots */
387             VDI_linetype(VDI_lt % (VDI_numcolors - 2));
388         }
389         do_point(x, y, number);
390         VDI_linetype(old_linetype);
391     }
392 }
393
394 static void
395 vdi_flush_line()
396 {
397     int line_type;
398     int color_index;
399     int i;
400
401     if (pxy_index >= 2) {
402         if (VDI_numcolors == 2) {       /* Monochrome */
403             color_index = 1;
404             line_type = VDI_lt;
405             if (line_type >= 0)
406                 line_type %= (VDI_LINETYPES_MAX - 2);
407         } else {                /* Color */
408             if (VDI_lt < 0) {
409                 color_index = 1;
410                 line_type = VDI_lt;
411             } else {
412                 color_index = 2 + VDI_lt % (VDI_numcolors - 2);
413                 line_type = (VDI_lt / (VDI_numcolors - 2)) % (VDI_LINETYPES_MAX - 2);
414             }
415         }
416
417         vswr_mode(vdi_vdi_handle, MD_TRANS);
418         vsl_color(vdi_vdi_handle, color_index);
419
420         vsl_type(vdi_vdi_handle, 7);
421         vsl_udsty(vdi_vdi_handle, VDI_linetypes[line_type + 2]);
422
423         v_pline(vdi_vdi_handle, pxy_index, pxy);
424     }
425     if (pxy_index >= 1) {
426         pxy[0] = pxy[2 * (pxy_index - 1)];
427         pxy[1] = pxy[2 * (pxy_index - 1) + 1];
428         pxy_index = 1;
429     }
430 }
431
432 #endif /* TERM_BODY */
433
434 #ifdef TERM_TABLE
435
436 TERM_TABLE_START(vdi_driver)
437     "vdi", "Atari VDI-Terminal",
438     VDI_XMAX, VDI_YMAX, VDI_VCHAR, VDI_HCHAR,
439     VDI_VTIC, VDI_HTIC, VDI_options, VDI_init, VDI_reset,
440     VDI_text, null_scale, VDI_graphics, VDI_move, VDI_vector,
441     VDI_linetype, VDI_put_text, VDI_text_angle,
442     VDI_justify_text, VDI_point, do_arrow, set_font_null,
443     0, TERM_CAN_MULTIPLOT, 0, 0
444 TERM_TABLE_END(vdi_driver)
445
446 #undef LAST_TERM
447 #define LAST_TERM vdi_driver
448
449 #endif /* TERM_TABLE */
450
451 #endif /* TERM_PROTO_ONLY */
452
453 #ifdef TERM_HELP
454 START_HELP(vdi)
455 "1 atari ST (via VDI)",
456 "?commands set terminal vdi",
457 "?set terminal vdi",
458 "?set term vdi",
459 "?terminal vdi",
460 "?term vdi",
461 "?vdi",
462 " The `vdi` terminal is the same as the `atari` terminal, except that it sends",
463 " output to the screen via the VDI and not into AES-Windows.",
464 "",
465 " The `vdi` terminal has options to set the character size and the screen",
466 " colors.",
467 "",
468 " Syntax:",
469 "       set terminal vdi {<fontsize>} {<col0> <col1> ... <col15>}",
470 "",
471 " The character size must appear if any colors are to be specified.  Each of",
472 " the (up to 16) colors is given as a three-digit hex number, where the digits",
473 " represent RED, GREEN and BLUE (in that order).  The range of 0--15 is scaled",
474 " to whatever color range the screen actually has.  On a normal ST screen, odd",
475 " and even intensities are the same.",
476 "",
477 " Examples:",
478 "       set terminal vdi 4    # use small (6x6) font",
479 "       set terminal vdi 6 0  # set monochrome screen to white on black",
480 "       set terminal vdi 13 0 fff f00 f0 f ff f0f",
481 "                  # set first seven colors to black, white, red, green,",
482 "                  # blue, cyan, and purple and use large font (8x16).",
483 "",
484 " Additionally, if an environment variable GNUCOLORS exists, its contents are",
485 " interpreted as an options string, but an explicit terminal option takes",
486 " precedence."
487 END_HELP(vdi)
488 #endif /* TERM_HELP */