- Optification is done by auto builder now
[gnuplot] / term / pc.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: pc.trm,v 1.23 2006/07/21 02:35:47 sfeam Exp $
3  *
4  */
5
6 /* GNUPLOT - pc.trm */
7
8 /*[
9  * Copyright 1990 - 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  *  Under Microsoft C
43  *      cga, egabios, egalib, vgabios, hercules, corona325, att
44  *  Under Turboc C
45  *      cga, ega/vga, vgamono, svga, mcga, hercules, att
46  *  Under Watcom C
47  *      cga, ega/vga, vgamono, svga, mcga, hercules, ???
48  *
49  * AUTHORS
50  *  Colin Kelley, Thomas Williams, William Wilson, Russell Lang
51  *  modified by David J. Liu (liu@csb.yale.edu) for version 3.6
52  *
53  * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
54  *
55  * Because only one compiler is used to generate gnuplot.exe
56  * and the type of the single graphics board is auto-detected,
57  * we can combine all these parts into one terminal type: PC
58  * and let the computer take care of the rest.  -- DJL
59  *
60  * Since I don't have MicroSoft C, I assume it would define MSC.
61  * Please correct it if you are using MS C.  Thank you.  -- DJL
62  *
63  */
64
65 /*
66  * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
67  */
68
69 #include "driver.h"
70
71 #ifdef TERM_REGISTER
72 register_term(dospc)
73 #endif
74
75 #ifdef TERM_PROTO
76 TERM_PUBLIC void PC_text __PROTO((void));
77 TERM_PUBLIC void PC_reset __PROTO((void));
78 TERM_PUBLIC void PC_init __PROTO((void));
79 TERM_PUBLIC void PC_graphics __PROTO((void));
80 TERM_PUBLIC void PC_linetype __PROTO((int linetype));
81 TERM_PUBLIC void PC_move __PROTO((unsigned int x, unsigned int y));
82 TERM_PUBLIC void PC_vector __PROTO((unsigned int x, unsigned int y));
83 TERM_PUBLIC void PC_put_text __PROTO((unsigned int x, unsigned int y, const char *str));
84 TERM_PUBLIC int PC_text_angle __PROTO((int ang));
85 TERM_PUBLIC int PC_justify_text __PROTO((enum JUSTIFY ang));
86
87 #define PC_HCHAR FNT5X9_HCHAR
88 #define PC_VCHAR FNT5X9_VCHAR
89 #define PC_HTIC 5
90 #define PC_VTIC 4
91 #define PC_XMAX 100             /* These two entries are just place holders. */
92 #define PC_YMAX 100             /* The actual values will be found in init.  */
93 #endif /* TERM_PROTO */
94
95 #ifndef TERM_PROTO_ONLY
96 #ifdef TERM_BODY
97
98 #ifdef __TURBOC__
99 static int huge detect_svga __PROTO((void));
100 #endif /* __TURBOC__ */
101
102 #include <string.h>
103 #include <stdlib.h>
104 #ifdef __TURBOC__
105 #include <graphics.h>
106 #include <conio.h>
107 #include <dos.h>
108 #endif /* __TURBOC__ */
109 #ifdef __WATCOMC__
110 # include <conio.h>             /* for getch() */
111 # include <graph.h>
112 #endif /* WATCOMC */
113 #ifdef MSC
114 #include "mcega.h"
115 #endif /* MSC */
116
117 static unsigned int pattern[] ={ 0xffff, 0x0f0f, 0xffff, 0xaaaa, 0x3333, 0x3f3f, 0x0f0f };
118 static int vga_color[] ={ 7, 8, 2, 3, 4, 5, 9, 14, 12, 15, 13, 10, 11, 1, 6 };
119
120 static int pc_driver, pc_mode;
121 static int graphics_on = FALSE, pc_graphics = FALSE;
122 static int startx, starty, pc_lastx, pc_lasty, pc_colors;
123 static int pc_angle, pc_hjustify, pc_vjustify, pc_text_size, pc_text_dir, pc_corscreen = -1;
124
125
126 #ifdef __TURBOC__
127 extern int far _Cdecl SVGA_driver_far[];
128 #endif /* __TURBOC__ */
129
130 #ifdef __WATCOMC__
131 enum {
132     HORIZ_DIR, VERT_DIR
133 };
134 static void
135 _settextang(int ang)
136 {
137     if (ang == HORIZ_DIR) {
138         _settextorient(1, 0);
139     } else {
140         _settextorient(0, 1);
141     }
142 }
143 #endif /* WATCOMC */
144
145 static int huge
146 detect_svga()
147 {
148     return 0;                   /* the default mode, just a place holder */
149 }
150
151 void
152 PC_setup()
153 {                               /* called from the beginning of main() */
154     int i, t, x, y;
155     char pc_modename[9];
156 #ifdef __WATCOMC__
157     struct videoconfig VC;
158 #endif /* WATCOMC */
159
160     /* First link all BRI dribers, then detect the display card. */
161     /* If environment PCTRM is set, try initiate the card/mode.  */
162
163     /* special instruction on mode */
164     safe_strncpy(pc_modename, getenv("PCTRM"), 8);
165
166 #ifdef __TURBOC__
167     /* Some of this code including BGI drivers are copyright Borland Intl. */
168     registerfarbgidriver(EGAVGA_driver_far);
169     registerfarbgidriver(CGA_driver_far);
170     registerfarbgidriver(Herc_driver_far);
171     registerfarbgidriver(ATT_driver_far);
172     registerfarbgidriver(PC3270_driver_far);
173     pc_driver = DETECT;
174     detectgraph(&pc_driver, &pc_mode);
175     if (graphresult()) {
176         fputs("Unable to initialize graphics.\n", stderr);
177         return;
178     }
179 #ifdef BGI_NAME
180 /* the highest standard pc_driver value, see graphics.h */
181 #define LAST_BGI 10
182 /* the last mode of the SVGA.BGI */
183 #define LAST_SVGA_MODE 6
184     /* test SVGA if we have VGA */
185     if ((pc_driver == VGA) && (pc_modename[0] == 'S')) {
186         installuserdriver(BGI_NAME, &detect_svga);
187         registerfarbgidriver(SVGA_driver_far);
188         pc_driver = DETECT;
189         initgraph(&pc_driver, &pc_mode, "");
190         /* The following code, which is independent of the actual SVGA.BGI
191          * used, tries to find a mode of width defined in the environment
192          * variable PCTRM */
193         if (pc_driver > LAST_BGI) {     /* success */
194             sscanf(pc_modename, "S%d", &t);
195             switch (t) {
196             case 800:
197                 break;          /* S800  */
198             case 1024:
199                 break;          /* S1024 */
200             case 1280:
201                 break;          /* S1280 */
202             default:
203                 t = 640;        /* 640x480 */
204             }
205             for (i = 0; i <= LAST_SVGA_MODE; i++) {
206                 setgraphmode(i);
207                 if ((getmaxx() + 1 == t) && (getmaxcolor() > 14))
208                     pc_mode = i;
209             }
210             setgraphmode(pc_mode);
211             if (graphresult()) {        /* error, go back to VGA */
212                 pc_driver = VGA;
213                 pc_mode = 4;
214             }
215         }
216     }                           /* SVGA tested */
217     if (pc_driver <= LAST_BGI)
218 #endif /* BGI_NAME */
219         initgraph(&pc_driver, &pc_mode, "");
220     pc_colors = getmaxcolor() + 1;
221     pc_lastx = getmaxx();
222     pc_lasty = getmaxy();
223     restorecrtmode();
224     clrscr();
225 #endif /* __TURBOC__ */
226 #ifdef __WATCOMC__
227     _getvideoconfig(&VC);
228     if ((pc_driver = VC.adapter) == 0) {
229         fprintf(stderr, "Unable to initialize graphics.\n");
230         return;
231     }
232     switch (pc_driver = VC.adapter) {
233     case _HERCULES:
234         pc_mode = _HERCMONO;
235         break;
236     case _CGA:
237         pc_mode = _HRESBW;
238         break;
239     case _MCGA:
240         pc_mode = _MRES256COLOR;
241         break;
242     case _EGA:
243         pc_mode = (VC.monitor == _MONO ? _ERESCOLOR : _ERESNOCOLOR);
244         break;
245     case _VGA:
246         pc_mode = _VRES16COLOR;
247         break;
248     case _SVGA:
249         if (pc_modename[0] == 'S') {    /* test SVGA resolution */
250             sscanf(pc_modename, "S%d", &t);
251             switch (t) {
252             case 800:
253                 pc_mode = _SVRES256COLOR;
254                 break;          /* S800  */
255             case 1024:
256                 pc_mode = _XRES256COLOR;
257                 break;          /* S1024 */
258             case 1280:
259                 pc_mode = _XRES256COLOR + 2;
260                 break;          /* S1280 */
261                 /* Someone help me, who knows, how a newer Watcom calls that */
262             default:
263                 t = 640;
264                 pc_mode = _VRES256COLOR;        /* 640x480 */
265             }
266             while (_setvideomode(pc_mode) == 0)
267                 pc_mode--;
268         }
269         break;
270     default:
271         fputs("Unable to initialize graphics.\n", stderr);
272         return;
273     }
274     _setvideomode(pc_mode);
275     _getvideoconfig(&VC);
276     pc_lastx = VC.numxpixels - 1;
277     pc_lasty = VC.numypixels - 1;
278     pc_colors = VC.numcolors;
279     _setvideomode(_DEFAULTMODE);
280 #endif /* WATCOMC */
281     x = pc_lastx + 1;
282     y = pc_lasty + 1;
283     fprintf(stderr, "\tScreen of %d x %d pixels and %d colors.\n",
284             x, y, pc_colors);
285     pc_graphics = TRUE;
286 }
287
288 TERM_PUBLIC void
289 PC_init()
290 {
291     char *pathp;
292 #ifdef __WATCOMC__
293     struct _fontinfo fi;
294 #endif
295
296     if (!pc_graphics) {
297         fputs("Unable to initialize graphics.\n", stderr);
298         term = 0;
299         return;
300     }
301     /* Double the tic/font sizes. */
302     pc_text_size = (pc_lasty > 590) ? 2 : 1;
303     term->h_char = PC_HCHAR;
304     term->v_char = PC_VCHAR;
305     term->h_tic = PC_HTIC * pc_text_size;
306     term->v_tic = PC_VTIC * pc_text_size;
307     term->xmax = pc_lastx + 1;
308     term->ymax = pc_lasty + 1;
309 #ifdef __TURBOC__
310     setgraphmode(pc_mode);
311     settextstyle(DEFAULT_FONT, HORIZ_DIR, pc_text_size);
312     settextjustify(pc_hjustify, pc_vjustify);
313     term->h_char = textheight("X");     /* overriding the default */
314     term->v_char = textwidth("X");      /* overriding the default */
315 #endif /* __TURBOC__ */
316 #ifdef __WATCOMC__
317     _setvideomode(pc_mode);
318     _settextang(HORIZ_DIR);
319     _settextalign(pc_hjustify, pc_vjustify);
320     _setcharsize(pc_text_size * PC_HCHAR, pc_text_size * PC_VCHAR);
321     _getfontinfo(&fi);
322     term->h_char = fi.avgwidth;
323     term->v_char = fi.pixheight * 1.5;
324 #endif /* WATCOMC */
325 #ifdef MSC
326 #endif /* MSC */
327 }
328
329 TERM_PUBLIC void
330 PC_graphics()
331 {
332     graphics_on = TRUE;
333 #ifdef __TURBOC__
334     setgraphmode(pc_mode);
335 #endif /* __TURBOC__ */
336 #ifdef __WATCOMC__
337     _setvideomode(pc_mode);
338 #endif /* WATCOMC */
339 #ifdef MSC
340     if (pc_corscreen == -1)
341         Vmode(18);              /* VGA */
342     else {
343         grinit(corscreen);
344         grandtx();
345     }                           /* corolla */
346 #endif /* MSC */
347 }
348
349 TERM_PUBLIC void
350 PC_linetype(int linetype)
351 {
352     if (linetype < -2)
353         linetype = LT_BLACK;
354
355     if (pc_colors > 14) {       /* 16 or more colors */
356         if (linetype >= 13)
357             linetype %= 13;
358 #ifdef __TURBOC__
359         setcolor(vga_color[linetype + 2]);
360 #endif /* __TURBOC__ */
361 #ifdef __WATCOMC__
362         _setcolor(vga_color[linetype + 2]);
363 #endif /* WATCOMC */
364 #ifdef MSC
365 #endif /* MSC */
366     } else {                    /* MONO */
367         if (linetype >= 5)
368             linetype %= 5;
369 #ifdef __TURBOC__
370         setlinestyle(4, pattern[linetype + 2], 1);
371 #endif /* __TURBOC__ */
372 #ifdef __WATCOMC__
373         _setlinestyle(pattern[linetype + 2]);
374 #endif /* WATCOMC */
375 #ifdef MSC
376         if (pc_corscreen != -1)
377             Cor_mask(pattern[linetype + 2]);
378 #endif /* MSC */
379     }
380 }
381
382 TERM_PUBLIC void
383 PC_move(unsigned int x, unsigned int y)
384 {
385 #ifdef __TURBOC__
386     moveto(x, pc_lasty - y);
387 #endif /* __TURBOC__ */
388 #ifdef __WATCOMC__
389     _moveto(x, pc_lasty - y);
390 #endif /* WATCOMC */
391 #ifdef MSC
392 #endif /* MSC */
393     startx = x;
394     starty = y;
395 }
396
397 TERM_PUBLIC void
398 PC_vector(unsigned int x, unsigned int y)
399 {
400 #ifdef __TURBOC__
401     lineto(x, pc_lasty - y);
402 #endif /* __TURBOC__ */
403 #ifdef __WATCOMC__
404     _lineto(x, pc_lasty - y);
405 #endif /* WATCOMC */
406 #ifdef MSC
407     if (pc_corscreen != -1)
408         Cor_line(startx, COR_YLAST - starty, x, COR_YLAST - y);
409 #endif /* MSC */
410     startx = x;
411     starty = y;
412 }
413
414 TERM_PUBLIC void
415 PC_reset()
416 {
417     graphics_on = FALSE;
418 #ifdef __TURBOC__
419     restorecrtmode();
420     clrscr();
421 #endif /* __TURBOC__ */
422 #ifdef __WATCOMC__
423     _setvideomode(_DEFAULTMODE);
424 #endif /* WATCOMC */
425 #ifdef MSC
426     Vmode(3);
427 #endif /* MSC */
428 }
429
430 TERM_PUBLIC void
431 PC_text()
432 {
433     if (graphics_on) {
434         graphics_on = FALSE;
435         (void) getch();
436 #ifdef __TURBOC__
437         restorecrtmode();
438         clrscr();
439 #endif /* __TURBOC__ */
440 #ifdef __WATCOMC__
441         _setvideomode(_DEFAULTMODE);
442 #endif /* WATCOMC */
443 #ifdef MSC
444         if (pc_corscreen != -1) {
445             grreset();
446             txonly();
447         }
448         Vmode(3);
449 #endif /* MSC */
450     }
451 }
452
453 TERM_PUBLIC int
454 PC_text_angle(int ang)
455 {
456     switch (ang) {
457     case 0:
458         pc_text_dir = HORIZ_DIR;
459         break;
460     default:
461     case 1:
462         pc_text_dir = VERT_DIR;
463         break;
464     }
465     return TRUE;
466 }
467
468 TERM_PUBLIC int
469 PC_justify_text(enum JUSTIFY just)
470 {
471 #if defined(__TURBOC__)
472     switch (just) {
473     case LEFT:
474         pc_hjustify = LEFT_TEXT;
475         pc_vjustify = CENTER_TEXT;
476         break;
477     case CENTRE:
478         pc_hjustify = CENTER_TEXT;
479         pc_vjustify = CENTER_TEXT;
480         break;
481     case RIGHT:
482         pc_hjustify = RIGHT_TEXT;
483         pc_vjustify = CENTER_TEXT;
484         break;
485     }
486     settextjustify(pc_hjustify, pc_vjustify);
487     return 1;
488 #elif defined(__WATCOMC__)
489     switch (just) {
490     case LEFT:
491         pc_hjustify = _LEFT;
492         pc_vjustify = _HALF;
493         break;
494     case CENTRE:
495         pc_hjustify = _CENTER;
496         pc_vjustify = _HALF;
497         break;
498     case RIGHT:
499         pc_hjustify = _RIGHT;
500         pc_vjustify = _HALF;
501         break;
502     }
503     _settextalign(pc_hjustify, pc_vjustify);
504     return 1;
505 #else
506     return (just == LEFT);
507 #endif
508 }
509
510 TERM_PUBLIC void
511 PC_put_text(unsigned int x, unsigned int y, const char *str)
512 {
513 #ifdef __TURBOC__
514     settextstyle(DEFAULT_FONT, pc_text_dir, pc_text_size);
515     settextjustify(pc_hjustify, pc_vjustify);
516     outtextxy(x, pc_lasty - y, str);
517 #endif /* __TURBOC__ */
518 #ifdef __WATCOMC__
519     _setcharsize(pc_text_size * PC_VCHAR, pc_text_size * PC_HCHAR);
520     _settextang(pc_text_dir);
521     _settextalign(pc_hjustify, pc_vjustify);
522     _grtext(x, pc_lasty - y, str);
523 #endif /* WATCOMC */
524 #ifdef MSC
525 #endif /* MSC */
526 }
527
528 #endif /* TERM_BODY */
529
530 #ifdef TERM_TABLE
531
532 TERM_TABLE_START(dospc_driver)
533     "dospc", "IBM PC/Clone running DOS",
534     PC_XMAX, PC_YMAX, PC_VCHAR, PC_HCHAR,
535     PC_VTIC, PC_HTIC, options_null, PC_init, PC_reset,
536     PC_text, null_scale, PC_graphics, PC_move, PC_vector,
537     PC_linetype, PC_put_text, PC_text_angle,
538     PC_justify_text, line_and_point, do_arrow, set_font_null
539 TERM_TABLE_END(dospc_driver)
540
541 #undef LAST_TERM
542 #define LAST_TERM dospc_driver
543
544 #endif /* TERM_TABLE */
545 #endif /* TERM_PROTO_ONLY */
546
547 #ifdef TERM_HELP
548 START_HELP(dospc)
549 "1 dospc",
550 "?commands set terminal dospc",
551 "?set terminal dospc",
552 "?set term dospc",
553 "?terminal dospc",
554 "?term dospc",
555 "?dospc",
556 " The `dospc` terminal driver supports PCs with arbitrary graphics boards,",
557 " which will be automatically detected.  It should be used only if you are",
558 " not using the gcc or Zortec C/C++ compilers."
559 END_HELP(dospc)
560 #endif /* TERM_HELP */