/usr/bin/gnuplot symlinks packageing problems were fixed gor gnuplot-x11
[gnuplot] / term / djsvga.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: djsvga.trm,v 1.20.2.1 2007/06/04 21:02:36 mikulik Exp $
3  */
4
5 /* GNUPLOT - djsvga.trm */
6
7 /*[
8  * Copyright 1992 - 1993, 1998, 2004
9  *
10  * Permission to use, copy, and distribute this software and its
11  * documentation for any purpose with or without fee is hereby granted,
12  * provided that the above copyright notice appear in all copies and
13  * that both that copyright notice and this permission notice appear
14  * in supporting documentation.
15  *
16  * Permission to modify the software is granted, but not the right to
17  * distribute the complete modified source code.  Modifications are to
18  * be distributed as patches to the released version.  Permission to
19  * distribute binaries produced by compiling modified sources is granted,
20  * provided you
21  *   1. distribute the corresponding source modifications from the
22  *    released version in the form of a patch file along with the binaries,
23  *   2. add special version identification to distinguish your version
24  *    in addition to the base release version number,
25  *   3. provide your name and address as the primary contact for the
26  *    support of your modified version, and
27  *   4. retain our contact information in regard to use of the base
28  *    software.
29  * Permission to distribute the released version of the source code along
30  * with corresponding source modifications in the form of a patch file is
31  * granted with same provisions 2 through 4 for binary distributions.
32  *
33  * This software is provided "as is" without express or implied warranty
34  * to the extent permitted by applicable law.
35 ]*/
36
37 /*
38  * This file is included by ../term.c.
39  *
40  * This terminal driver supports:
41  *  svga
42  *
43  * AUTHORS
44  *  Russell Lang
45  *  Edzer Pebesma (gnuplot 3.6: new terminal layout, fonts, grx20)
46  *  Hans-Bernhard Broeker (several improvements)
47  *
48  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
49  *
50  */
51
52 /* HBB: A new version, called grx21a was released recently. To
53  * tell gnuplot you have it, add '-DGRX21' to your compilation flags.
54  * Currently, that only enables the drawing of wide lines. Maybe more
55  *  to come.
56  */
57
58 #include "driver.h"
59
60 #ifdef TERM_REGISTER
61 register_term(djsvga)           /* no ; */
62 #endif
63
64 #ifdef TERM_PROTO
65 #define DJSVGA_XMAX 640
66 #define DJSVGA_YMAX 480
67
68 #define DJSVGA_XLAST (DJSVGA_XMAX - 1)
69 #define DJSVGA_YLAST (DJSVGA_YMAX - 1)
70
71 #define DJSVGA_VCHAR 16
72 #define DJSVGA_HCHAR 8
73 #define DJSVGA_VTIC 4
74 #define DJSVGA_HTIC 4
75
76 TERM_PUBLIC void DJSVGA_init __PROTO((void));
77 TERM_PUBLIC void DJSVGA_graphics __PROTO((void));
78 TERM_PUBLIC void DJSVGA_text __PROTO((void));
79 TERM_PUBLIC void DJSVGA_reset __PROTO((void));
80 TERM_PUBLIC void DJSVGA_options __PROTO((void));
81 TERM_PUBLIC void DJSVGA_linetype __PROTO((int linetype));
82 TERM_PUBLIC void DJSVGA_move __PROTO((unsigned int x, unsigned int y));
83 TERM_PUBLIC void DJSVGA_vector __PROTO((unsigned int x, unsigned int y));
84 TERM_PUBLIC int DJSVGA_angle __PROTO((int ang));
85 TERM_PUBLIC int DJSVGA_justify_text __PROTO((enum JUSTIFY mode));
86 TERM_PUBLIC void DJSVGA_put_text __PROTO((unsigned int x, unsigned int y,
87                                           const char *str));
88 TERM_PUBLIC int DJSVGA_set_font __PROTO((const char *fontname));
89 TERM_PUBLIC void DJSVGA_suspend __PROTO((void));
90 TERM_PUBLIC void DJSVGA_resume __PROTO((void));
91 /* clear part of multiplot */
92 TERM_PUBLIC void DJSVGA_fillbox __PROTO((int style, unsigned int x1,
93                                          unsigned int y1, unsigned int width,
94                                          unsigned int height));
95 TERM_PUBLIC void DJSVGA_linewidth __PROTO((double linewidth));
96
97 #define GOT_DJSVGA_PROTO
98 #endif /* TERM_PROTO */
99
100 #ifndef TERM_PROTO_ONLY
101 #ifdef TERM_BODY
102
103 /* SVGA driver using DJGPP */
104 #if (DJGPP==2)
105 # define GRX20
106 #endif
107 #ifdef GRX20
108 /* use grx20.h for DJGPP V1 / GRX V2 combo as well */
109 # include <grx20.h>
110 #else
111 # include <grx.h>
112 #endif
113 #include <pc.h>
114
115 static int dj_startx, dj_starty;
116 static int dj_xlast, dj_ylast;
117 #define DJNUMCOLOR 15
118 /* HBB: Let's just use long for GRX1 as well */
119 static long dj_color;
120 static long svga256color[DJNUMCOLOR] =
121    /* old sequence: {7, 8, 2, 3, 4, 5, 9, 14, 12, 15, 13, 10, 11, 1, 6}; */
122 {
123    7 /*black*/, 8 /*grey*/, 
124 #if 0 /* prefer dark colors */
125    4 /*dark red*/, 2 /*dark green*/, 1 /*dark blue*/, 5 /*dark magenta*/, 3 /*dark cyan*/,
126    14 /*yellow*/, 15 /*white*/,
127    12 /*red*/, 9 /*blue*/, 13 /*magenta*/, 10 /*green*/, 11 /*cyan*/,
128    6 /*brown*/
129 #else /* prefer light colors */
130    12 /*red*/, 10 /*green*/, 9 /*blue*/, 13 /*magenta*/, 11 /*cyan*/,
131    14 /*yellow*/, 15 /*white*/,
132    4 /*dark red*/, 1 /*dark blue*/, 5 /*dark magenta*/, 2 /*dark green*/, 3 /*dark cyan*/,
133    6 /*brown*/
134 #endif
135 };
136 static long dj_colors[DJNUMCOLOR];
137 #ifdef GRX20
138 /* Save, Restore: for 16 color mode! */
139 static void *DJSVGA_colorbuf = NULL;
140 #endif
141 static GrTextOption DJSVGA_TextOption;
142 /* HBB: I think we should use GR_NAMEWIDTH (=16), instead of MAX_ID_LEN,
143  *   which has nothing to do with GRX at all */
144 #ifdef GRX20
145 char DJSVGA_fontname[MAX_ID_LEN + 1] = "";
146 #else
147 char DJSVGA_fontname[MAX_ID_LEN + 1] = "@:pc8x14.fnt";  /* EGA bios font */
148 #endif
149 static GrContext *DJSVGA_context = 0;   /* save screen for suspend/resume */
150 static char *dj_textsave = 0;   /* for text-screen-saving */
151 static int dj_cursorx, dj_cursory;
152 static int dj_width, dj_height;
153 #ifdef GRX21
154 static double dj_linewidth;     /* store linewidth assignments here */
155 #endif
156
157
158 TERM_PUBLIC void
159 DJSVGA_options()
160 {
161     if (!END_OF_COMMAND && isstring(c_token)) {
162         quote_str(DJSVGA_fontname, c_token, MAX_ID_LEN);
163         c_token++;
164     }
165     sprintf(term_options, "\"%s\"", DJSVGA_fontname);
166 }
167
168 TERM_PUBLIC void
169 DJSVGA_init()
170 {
171     int i, on, r, g, b, medium = 170, low = 85;
172     GrFont *font = NULL;
173
174 #ifdef GRX20
175     font = &GrDefaultFont;
176 #endif
177     /* HBB: save textscreen contents and cursor-position */
178     dj_textsave = gp_alloc(ScreenRows() * ScreenCols() * 2, "djsvga term scrbuf");
179     ScreenRetrieve(dj_textsave);
180     dj_width = ScreenCols();
181     dj_height = ScreenRows();
182     ScreenGetCursor(&dj_cursory, &dj_cursorx);
183     GrSetMode(GR_default_graphics);
184     GrSetRGBcolorMode();
185     GrResetColors();
186     /* Allocate colors */
187     for (i = 0; i < DJNUMCOLOR; i++) {
188         on = (svga256color[i] & 8) ? 255 : medium;
189         r = (svga256color[i] & 4) ? on : 0;
190         g = (svga256color[i] & 2) ? on : 0;
191         b = (svga256color[i] & 1) ? on : 0;
192         if (svga256color[i] == 8)
193             r = g = b = low;
194         dj_colors[i] = GrAllocColor(r, g, b);
195     }
196     /* Get the screen size: */
197     dj_xlast = GrMaxX();
198     term->xmax = dj_xlast + 1;
199     dj_ylast = GrMaxY();
200     term->ymax = dj_ylast + 1;
201     /* if GRX 1.x loads an GRX 2.x save'd file: */
202     if (font == NULL && DJSVGA_fontname[0] == '\0')
203         sprintf(DJSVGA_fontname, "@:pc8x14.fnt");
204
205     if (DJSVGA_fontname[0] != '\0')
206         font = GrLoadFont(DJSVGA_fontname);
207     if (font == NULL)
208         font = GrLoadFont("@:pc8x14.fnt");      /* try EGA bios font */
209     if (font == NULL)
210         font = GrLoadFont("@:pc8x16.fnt");      /* try VGA bios font */
211     /*
212      * HBB: There are cases when we reach this point with font still NULL,
213      *   eg. when the GRXFONT env.variable points to the GRX V1 fonts, but
214      *   GRX V2 is used for this program: some fonts will *fail* to load in
215      *   that setup (e.g. cour20b)! So IMHO, there should be some error
216      *   treatment here..., like int_error("Couldn't load font!");
217      */
218     DJSVGA_TextOption.txo_font = font;
219     DJSVGA_TextOption.txo_direct = GR_TEXT_RIGHT;
220     DJSVGA_TextOption.txo_xalign = GR_ALIGN_LEFT;
221     DJSVGA_TextOption.txo_yalign = GR_ALIGN_CENTER;
222     DJSVGA_TextOption.txo_chrtype = GR_BYTE_TEXT;
223     DJSVGA_TextOption.txo_bgcolor.v = GrNOCOLOR;
224 #ifndef GRX20
225     DJSVGA_TextOption.txo_xmag = 1;
226     DJSVGA_TextOption.txo_ymag = 1;
227 #endif
228     /* HBB: this version should work in all configurations */
229     term->v_char = font->h.height;
230     term->h_char = font->h.width;
231
232 #ifdef GRX20
233     if (DJSVGA_colorbuf == NULL)
234         DJSVGA_colorbuf = (void *) gp_alloc(GrColorSaveBufferSize(), "djsvga term colorbuf");
235     GrSaveColors(DJSVGA_colorbuf);
236 #endif
237     GrSetMode(GR_default_text);
238     ScreenUpdate(dj_textsave);
239     ScreenSetCursor(dj_cursory, dj_cursorx);
240 }
241
242 /*
243  * HBB: make these two inline, as they're called by other routines
244  * inside this module, and -finline-functions (normally switched
245  * on by 'gcc -O3') doesn't work for compiling term.c
246  */
247 __inline__
248 TERM_PUBLIC void
249 DJSVGA_graphics()
250 {
251     ScreenRetrieve(dj_textsave);        /* HBB: save text screen contents */
252     ScreenGetCursor(&dj_cursory, &dj_cursorx);
253     GrSetMode(GR_default_graphics);
254 #ifdef GRX20
255     GrRestoreColors(DJSVGA_colorbuf);
256 #endif
257 }
258
259 __inline__
260 TERM_PUBLIC void
261 DJSVGA_text()
262 {
263     (void) getkey();
264     GrSetMode(GR_width_height_text, dj_width, dj_height);
265     ScreenUpdate(dj_textsave);  /* HBB: restore text screen */
266     ScreenSetCursor(dj_cursory, dj_cursorx);
267 }
268
269 TERM_PUBLIC void
270 DJSVGA_reset()
271 {
272     GrResetColors();
273     free(dj_textsave);
274 }
275
276 TERM_PUBLIC void
277 DJSVGA_linetype(int linetype)
278 {
279     if (linetype < -2)
280         linetype = LT_BLACK;
281     if (linetype >= 13)
282         linetype %= 13;
283     /* HBB: set the TextOption color variable right here (faster) */
284     DJSVGA_TextOption.txo_fgcolor.v = dj_color = dj_colors[linetype + 2];
285 }
286
287 TERM_PUBLIC void
288 DJSVGA_move(unsigned int x, unsigned int y)
289 {
290     dj_startx = x;
291     dj_starty = y;
292 }
293
294
295 TERM_PUBLIC void
296 DJSVGA_vector(unsigned int x, unsigned int y)
297 {
298 #ifdef GRX21
299     GrLineOption dj_lineoption =
300     {dj_color, dj_linewidth, 0, ""};
301
302     GrCustomLine(dj_startx, dj_ylast - dj_starty, x, dj_ylast - y, &dj_lineoption);
303 #else
304     GrLine(dj_startx, dj_ylast - dj_starty, x, dj_ylast - y, dj_color);
305 #endif
306     dj_startx = x;
307     dj_starty = y;
308 }
309
310 /*
311  * HBB: IMHO, the previous version was seriously flawed. E.g.
312  *   in the termentry, _justify_text was pointing to the
313  *   null_justify_text dummy routine, so DJSVGA_justify wasn't
314  *   ever called at all. I copied the routines from my (now
315  *   otherwise pointless) own private driver, djgrx.trm, to
316  *   cure that.
317  */
318 TERM_PUBLIC int
319 DJSVGA_angle(int ang)
320 {
321     if (ang) {
322         DJSVGA_TextOption.txo_direct = GR_TEXT_UP;
323     } else {
324         DJSVGA_TextOption.txo_direct = GR_TEXT_RIGHT;
325     }
326     return TRUE;
327 }
328
329 TERM_PUBLIC int
330 DJSVGA_justify_text(enum JUSTIFY mode)
331 {
332     if (DJSVGA_TextOption.txo_direct == GR_TEXT_RIGHT) {
333         DJSVGA_TextOption.txo_yalign = GR_ALIGN_CENTER;
334         switch (mode) {
335         case LEFT:
336             DJSVGA_TextOption.txo_xalign = GR_ALIGN_LEFT;
337             break;
338         case CENTRE:
339             DJSVGA_TextOption.txo_xalign = GR_ALIGN_CENTER;
340             break;
341         case RIGHT:
342             DJSVGA_TextOption.txo_xalign = GR_ALIGN_RIGHT;
343             break;
344         }
345     } else {
346         DJSVGA_TextOption.txo_xalign = GR_ALIGN_CENTER;
347         switch (mode) {
348         case LEFT:
349             DJSVGA_TextOption.txo_yalign = GR_ALIGN_BOTTOM;
350             break;
351         case CENTRE:
352             DJSVGA_TextOption.txo_yalign = GR_ALIGN_CENTER;
353             break;
354         case RIGHT:
355             DJSVGA_TextOption.txo_yalign = GR_ALIGN_TOP;
356             break;
357         }
358     }
359     return TRUE;
360 }
361
362 TERM_PUBLIC int
363 DJSVGA_set_font(const char *fontname)
364 {
365     char *cp;
366     GrFont *font;
367     if (!fontname || !fontname[0])
368         return FALSE;
369     safe_strncpy(DJSVGA_fontname, fontname, sizeof(DJSVGA_fontname));
370     cp = strstr(DJSVGA_fontname, ",");
371     if (cp != NULL)
372         *cp = NUL;
373     font = GrLoadFont(DJSVGA_fontname);
374     /*HBB: if no font found, do *not* report success! */
375     if (font != NULL) {
376         GrUnloadFont(DJSVGA_TextOption.txo_font);
377         DJSVGA_TextOption.txo_font = font;
378         return TRUE;
379     } else {
380         graph_error("Font not found");
381         return FALSE;
382     }
383 }
384
385 TERM_PUBLIC void
386 DJSVGA_put_text(unsigned int x, unsigned int y, const char *str)
387 {
388     /* HBB: why isn't font!=NULL ensured elsewhere? Testing it at
389      * this point doesn't really make much sense (we're in graphics
390      * mode, so we can't even print out a useful error message!) */
391     /*if (DJSVGA_TextOption.txo_font != NULL) */
392     GrDrawString(str, strlen(str), x, dj_ylast - y, &DJSVGA_TextOption);
393 }
394
395 TERM_PUBLIC void
396 DJSVGA_suspend()
397 {
398     DJSVGA_context = GrCreateContext(GrSizeX(), GrSizeY(), 0, 0);
399     GrBitBltNC(DJSVGA_context, 0, 0, 0, 0, 0, GrMaxX(), GrMaxY(), GrWRITE);
400     DJSVGA_text();
401 }
402
403 TERM_PUBLIC void
404 DJSVGA_resume()
405 {
406     DJSVGA_graphics();
407     GrBitBltNC(0, 0, 0, DJSVGA_context, 0, 0, GrMaxX(), GrMaxY(), GrWRITE);
408     GrDestroyContext(DJSVGA_context);
409 }
410
411 TERM_PUBLIC void
412 DJSVGA_fillbox(
413     int style,
414     unsigned int left, unsigned int bottom,
415     unsigned int width, unsigned height)
416 {
417     if (style >= 13)
418         style %= 13;
419     /* HBB: prize question: should it be 'width-1' instead? */
420     /* HBB: fill with GRX Color '0', which *should* be black : */
421     /* ULIG: the style parameter is now used for the fillboxes style */
422     /* (not implemented here), see the documentation */
423
424     GrFilledBox(left, dj_ylast - bottom, left + width, dj_ylast - bottom - height, 0);
425 }
426
427 TERM_PUBLIC void
428 DJSVGA_linewidth(double linewidth)
429 {
430 #ifdef GRX21
431     dj_linewidth = linewidth;
432 #endif
433 }
434
435 #endif /* TERM_BODY */
436
437 #ifdef TERM_TABLE
438
439 /* HBB: I think \" is more readable than \042. BTW: why is this
440  *   option 'documented' here, but not in the Help node? */
441 TERM_TABLE_START(djsvga_driver)
442     "svga", "IBM PC/Clone with Super VGA graphics board [\"fontname\"]",
443     DJSVGA_XMAX, DJSVGA_YMAX, DJSVGA_VCHAR, DJSVGA_HCHAR,
444     DJSVGA_VTIC, DJSVGA_HTIC,
445     DJSVGA_options,
446     DJSVGA_init, DJSVGA_reset, DJSVGA_text,
447     null_scale, DJSVGA_graphics, DJSVGA_move, DJSVGA_vector,
448     DJSVGA_linetype, DJSVGA_put_text,
449     DJSVGA_angle, DJSVGA_justify_text,
450     do_point, do_arrow, DJSVGA_set_font,
451     0,                          /* no pointsize() */
452     TERM_CAN_MULTIPLOT,
453     DJSVGA_suspend, DJSVGA_resume,
454     DJSVGA_fillbox, DJSVGA_linewidth
455 TERM_TABLE_END(djsvga_driver)
456
457 #undef LAST_TERM
458 #define LAST_TERM djsvga_driver
459
460 #endif /* TERM_TABLE */
461 #endif /* TERM_PROTO_ONLY */
462
463 /*
464  * HBB: I think this documentation should be at least a *bit* longer
465  *   (E.g., the "fontname" parameter is claimed to be non-existent!)
466  */
467 /* RCC: Not any more...
468  *      If you have other ideas about what could be in the help section,
469  *      please let me know (rccrawford@lanl.gov) --- particularly info
470  *      about what fonts are permitted, if there is such a list.
471 */
472 #ifdef TERM_HELP
473 START_HELP(svga)
474 "1 svga",
475 "?commands set terminal svga",
476 "?set terminal svga",
477 "?set term svga",
478 "?terminal svga",
479 "?term svga",
480 "?svga",
481 " The `svga` terminal driver supports PCs with SVGA graphics.  It can only be",
482 " used if it is compiled with DJGPP.  Its only option is the font.",
483 "",
484 " Syntax:",
485 "       set terminal svga {\"<fontname>\"}"
486 END_HELP(svga)
487 #endif /* TERM_HELP */