1/* Hello, Emacs, this is -*-C-*- */
2
3/* GNUPLOT - HP26.trm */
4
5/*[
6 * Copyright 1990 - 1993, 1998, 2004
7 *
8 * Permission to use, copy, and distribute this software and its
9 * documentation for any purpose with or without fee is hereby granted,
10 * provided that the above copyright notice appear in all copies and
11 * that both that copyright notice and this permission notice appear
12 * in supporting documentation.
13 *
14 * Permission to modify the software is granted, but not the right to
15 * distribute the complete modified source code.  Modifications are to
16 * be distributed as patches to the released version.  Permission to
17 * distribute binaries produced by compiling modified sources is granted,
18 * provided you
19 *   1. distribute the corresponding source modifications from the
20 *    released version in the form of a patch file along with the binaries,
21 *   2. add special version identification to distinguish your version
22 *    in addition to the base release version number,
23 *   3. provide your name and address as the primary contact for the
24 *    support of your modified version, and
25 *   4. retain our contact information in regard to use of the base
26 *    software.
27 * Permission to distribute the released version of the source code along
28 * with corresponding source modifications in the form of a patch file is
29 * granted with same provisions 2 through 4 for binary distributions.
30 *
31 * This software is provided "as is" without express or implied warranty
32 * to the extent permitted by applicable law.
33]*/
34
35/*
36 * This file is included by ../term.c.
37 *
38 * This terminal driver supports:
39 *  HP2623A
40 *
41 * AUTHORS
42 *   luecken@udel.edu (Bruce Lueckenhoff)
43 *   hplvlch!ch (Chuck Heller)
44 *
45 * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
46 *
47 */
48
49/*
50 * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
51 */
52
53#include "driver.h"
54
55#ifdef TERM_REGISTER
56register_term(hp2623a)
57#endif
58
59#ifdef TERM_PROTO
60TERM_PUBLIC void HP26_vector(unsigned int x, unsigned int y);
61TERM_PUBLIC void HP26_move(unsigned int x, unsigned int y);
62TERM_PUBLIC void HP26_init(void);
63TERM_PUBLIC void HP26_graphics(void);
64TERM_PUBLIC void HP26_text(void);
65TERM_PUBLIC void HP26_reset(void);
66TERM_PUBLIC int HP26_text_angle(int ang);
67TERM_PUBLIC void HP26_put_text(unsigned int x, unsigned int y, const char *str);
68TERM_PUBLIC void HP26_linetype(int linetype);
69TERM_PUBLIC void HP26_line_and_point(unsigned int x, unsigned int y, int number);
70
71#define HP26_XMAX 512
72#define HP26_YMAX 390
73
74/* Use a size 1 character, or a 7 x 10 grid. */
75#define HP26_VCHAR	10
76#define HP26_HCHAR	7
77#define HP26_VTIC	5
78#define HP26_HTIC	5
79#endif /* TERM_PROTO */
80
81#ifndef TERM_PROTO_ONLY
82#ifdef TERM_BODY
83
84#define HP26_XLAST (HP26_XMAX - 1)
85#define HP26_YLAST (HP26_XMAX - 1)
86
87static void HP26_do_point(unsigned int x, unsigned int y, int number);
88static struct _HP26_Buffer_Node *BN_create(int index, int size, int linetype);
89static void BN_delete(struct _HP26_Buffer_Node * the_node);
90static int HP26_flush(struct _HP26_Buffer_Node * the_buff);
91static void HP26_handle_overflow(void);
92
93typedef struct _HP26_Buffer_Node {
94    int index;
95    int size;
96    int next;
97    int linetype;
98    int *x;
99    int *y;
100    TBOOLEAN *isa_move;
101} HP26_Buffer_Node;
102
103/* constructor method */
104static HP26_Buffer_Node *
105BN_create(int index, int size, int linetype)
106{
107    HP26_Buffer_Node *the_node;
108    the_node = (HP26_Buffer_Node *) gp_alloc(sizeof(HP26_Buffer_Node), "HP26");
109    if (the_node) {
110	the_node->index = index;
111	the_node->linetype = linetype;
112	the_node->size = size;
113	the_node->next = 0;
114	the_node->x = (int *) gp_alloc(size*sizeof(int), "HP26");
115	the_node->y = (int *) gp_alloc(size*sizeof(int), "HP26");
116	the_node->isa_move = (TBOOLEAN *) gp_alloc(size*sizeof(TBOOLEAN), "HP26");
117	if (the_node->x == NULL || the_node->y == NULL || the_node->isa_move == NULL)
118	    return (NULL);
119    }
120    memset(the_node->isa_move, 0, size*sizeof(TBOOLEAN));
121    return (the_node);
122}
123
124/* destructor method */
125static void
126BN_delete(HP26_Buffer_Node *the_node)
127{
128    free(the_node->x);
129    free(the_node->y);
130    free(the_node->isa_move);
131    free(the_node);
132}
133
134/* 2 for border and axes + 9 for plots + 1 for dots */
135#define HP26_gnu_map_size 12
136static HP26_Buffer_Node *HP26_gnu_map[HP26_gnu_map_size];
137static HP26_Buffer_Node *HP26_buff;
138static int HP26_pen_x;
139static int HP26_pen_y;
140static int HP26_angle;
141static int HP26_cursor_x;
142static int HP26_cursor_y;
143static TBOOLEAN HP26_in_text;
144static int HP26_linetype_current;
145static int HP26_reduction_int;
146static int HP26_reduction_slope;
147static int HP26_overflows;
148static int HP26_nop_move;
149static int HP26_nop_vect;
150static int HP26_nop_line;
151
152/* linetype stuff */
153#define	SOLID	1
154#define	USER	2
155#define LINE3	3
156#define LINE4	4
157#define LINE5	5
158#define LINE6	6
159#define	DOTS	7
160#define LINE8	8
161#define LINE9	9
162#define LINE10	10
163#define POINT	11
164
165
166
167#define swap(a, b) a ^= b; b ^= a; a ^= b;
168
169static char HP26_bin_short_table[32] =
170{
171    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>',
172    '?', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-',
173    '.', '/'
174};
175/* encodes an integer (assumed to be in range) into
176   binary short incremental format (j)*/
177#define short_encode(n) (HP26_bin_short_table[n+16])
178
179/* tells whether a given delta_x,delta_y pair can be expressed in
180   binary short incremental format */
181#define qualified(dx,dy) ((dx>-17)&&(dy>-17)&&(dx<16)&&(dy<16))
182
183
184static char HP26_bin_table[32] =
185{
186    ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-',
187    '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<',
188    '=', '>', '?'
189};
190/* returns the high byte of integer n in binary absolute format (i) */
191#define bin_encode_hi(n) (HP26_bin_table[n>>5])
192/* returns the low byte of integer n in binary absolute format (i) */
193#define bin_encode_lo(n) (HP26_bin_table[n & 31])
194
195
196
197/* the guts of the program
198-- first checks if any work need be done and, failing that, returns
199	immediately
200-- tries to compress the vector stream
201-- goes through the buffer, using binary short incremental (2 bytes/point)
202	as much as possible, even if must output two pairs to express one vector
203	(it's no more expensive, and will hopefully damp any excessive switching
204	back and forth between the two formats)
205	if can't use binary short incremental, use binary
206	absolute(4 bytes/point)
207-- finally, resets the HP26_next pointer to zero    */
208static int
209HP26_flush(HP26_Buffer_Node *the_buff)
210{
211    int i, delta_x, delta_y, half_dx, half_dy;
212    int *buff_x, *buff_y;
213    TBOOLEAN *isa_move;
214    TBOOLEAN bin_short;
215
216    if (the_buff->next == 0)
217	return (FALSE);
218    /* init pointers for easy access */
219    buff_x = the_buff->x;
220    buff_y = the_buff->y;
221    isa_move = the_buff->isa_move;
222    if (HP26_in_text) {
223	fputs("\033*dT", gpoutfile);
224	HP26_in_text = FALSE;
225    }
226    if (HP26_linetype_current != the_buff->linetype
227	&& (the_buff->next > 1 || !isa_move[0])) {
228	fprintf(gpoutfile, "\033*m%dB", the_buff->linetype);
229	HP26_linetype_current = the_buff->linetype;
230    }
231
232    /* start escape sequence */
233    fputs("\033*p", gpoutfile);
234    /* initialize the state:  binary short incremental or binary absolute */
235    delta_x = buff_x[0] - HP26_pen_x;
236    delta_y = buff_y[0] - HP26_pen_y;
237    if (qualified(delta_x, delta_y)) {
238	fputc('j', gpoutfile);
239	bin_short = TRUE;
240    } else {
241	fputc('i', gpoutfile);
242	bin_short = FALSE;
243    }
244    /* now work through the list */
245    for (i = 0; i < the_buff->next; i++) {
246	if (i > 0) {
247	    delta_x = buff_x[i] - buff_x[i - 1];
248	    delta_y = buff_y[i] - buff_y[i - 1];
249	}
250	if ((delta_x == 0) && (delta_y == 0)) {
251	    if (i > 0 && !isa_move[i - 1] && !isa_move[i]) {
252		/* allow null vectors only when drawing dots */
253		HP26_nop_vect++;
254		continue;
255	    } else if (isa_move[i]) {
256		/* a null move */
257		HP26_nop_move++;
258		continue;
259	    }
260	} else if (i > 0
261		   && i + 1 < the_buff->next
262		   && isa_move[i]
263		   && isa_move[i + 1]) {
264	    /* consecutive moves are condensed into one */
265	    HP26_nop_move++;
266	    continue;
267	} else if (!qualified(delta_x, delta_y)
268		   && i > 0
269		   && i + 2 < the_buff->next
270		   && isa_move[i]
271		   && !isa_move[i + 1]
272		   && isa_move[i + 2]
273		   && qualified(buff_x[i + 1] - buff_x[i - 1], buff_y[i + 1] - buff_y[i - 1])) {
274	    swap(buff_x[i], buff_x[i + 1]);
275	    swap(buff_y[i], buff_y[i + 1]);
276	    /* set up new delta_x & delta_y */
277	    delta_x = buff_x[i] - buff_x[i - 1];
278	    delta_y = buff_y[i] - buff_y[i - 1];
279	}
280	if (qualified(delta_x, delta_y)) {
281	    if (!bin_short) {
282		fputc('j', gpoutfile);
283		bin_short = TRUE;
284	    }
285	    if (isa_move[i])
286		fputc('a', gpoutfile);
287	    fputc(short_encode(delta_x), gpoutfile);
288	    fputc(short_encode(delta_y), gpoutfile);
289	} else {
290	    half_dx = (delta_x + (delta_x > 0 ? 1 : -1)) / 2;
291	    half_dy = (delta_y + (delta_y > 0 ? 1 : -1)) / 2;
292	    if (bin_short && qualified(half_dx, half_dy)) {
293		if (isa_move[i])
294		    fputc('a', gpoutfile);
295		fputc(short_encode(half_dx), gpoutfile);
296		fputc(short_encode(half_dy), gpoutfile);
297		if (isa_move[i])
298		    fputc('a', gpoutfile);
299		fputc(short_encode(delta_x - half_dx), gpoutfile);
300		fputc(short_encode(delta_y - half_dy), gpoutfile);
301	    } else {
302		if (bin_short) {
303		    bin_short = FALSE;
304		    fputc('i', gpoutfile);
305		}
306		if (isa_move[i])
307		    fputc('a', gpoutfile);
308		fputc(bin_encode_hi(buff_x[i]), gpoutfile);
309		fputc(bin_encode_lo(buff_x[i]), gpoutfile);
310		fputc(bin_encode_hi(buff_y[i]), gpoutfile);
311		fputc(bin_encode_lo(buff_y[i]), gpoutfile);
312	    }
313	}
314    }				/* end for.. */
315    /* the term doesn't seem to mind leaving this out */
316    /* finish the escape sequence */
317    fputc('Z', gpoutfile);
318    /* set these for next time */
319    HP26_pen_x = buff_x[the_buff->next - 1];
320    HP26_pen_y = buff_y[the_buff->next - 1];
321    the_buff->next = 0;
322    return (TRUE);
323}
324
325static void
326HP26_handle_overflow()
327{
328    HP26_Buffer_Node *bigger, *old;
329    int x, y;
330    x = (HP26_buff->x)[HP26_buff->next - 1];
331    y = (HP26_buff->y)[HP26_buff->next - 1];
332    HP26_flush(HP26_buff);
333    bigger = BN_create(HP26_buff->index, HP26_buff->size * 2,
334		       HP26_buff->linetype);
335    if (bigger != NULL) {
336	old = HP26_buff;
337	HP26_gnu_map[bigger->index] = bigger;
338	/* special case since DOTS entry is shared 3 ways */
339	if (bigger->index == 0) {
340	    HP26_gnu_map[1] = bigger;
341	    HP26_gnu_map[3] = bigger;
342	}
343	HP26_buff = bigger;
344	BN_delete(old);
345    }
346    (HP26_buff->x)[0] = x;
347    (HP26_buff->y)[0] = y;
348    (HP26_buff->isa_move)[0] = TRUE;
349    HP26_buff->next = 1;
350    HP26_overflows++;
351}
352
353/* checks for NOP, overcapacity condition, and then adds vector to the list */
354TERM_PUBLIC void
355HP26_vector(unsigned int x, unsigned int y)
356{
357    if (HP26_buff->next > 2
358	&& x == (HP26_buff->x)[HP26_buff->next - 1]
359	&& y == (HP26_buff->y)[HP26_buff->next - 1]
360	&& !(HP26_buff->isa_move)[HP26_buff->next - 1]) {
361	HP26_nop_vect++;
362	return;
363    }
364    if (HP26_buff->next == HP26_buff->size)
365	HP26_handle_overflow();
366    /* otherwise add to the list */
367    (HP26_buff->x)[HP26_buff->next] = x;
368    (HP26_buff->y)[HP26_buff->next] = y;
369    (HP26_buff->isa_move)[HP26_buff->next] = FALSE;
370    HP26_buff->next++;
371}
372
373/* checks for NOP, checks for overcapacity, puts self on list */
374TERM_PUBLIC void
375HP26_move(unsigned int x, unsigned int y)
376{
377    if (HP26_buff->next > 0) {
378	if (((HP26_buff->x)[HP26_buff->next - 1] == x)
379	    && ((HP26_buff->y)[HP26_buff->next - 1] == y)) {
380	    /* null moves are NOP's */
381	    HP26_nop_move++;
382	    return;
383	} else if ((HP26_buff->isa_move)[HP26_buff->next - 1]) {
384	    /* consecutive moves are NOP's */
385	    (HP26_buff->x)[HP26_buff->next - 1] = x;
386	    (HP26_buff->y)[HP26_buff->next - 1] = y;
387	    HP26_nop_move++;
388	    return;
389	}
390    }
391    if (HP26_buff->next == HP26_buff->size)
392	HP26_handle_overflow();
393    (HP26_buff->x)[HP26_buff->next] = x;
394    (HP26_buff->y)[HP26_buff->next] = y;
395    (HP26_buff->isa_move)[HP26_buff->next] = TRUE;
396    HP26_buff->next++;
397    return;
398}
399
400TERM_PUBLIC void
401HP26_init()
402{
403    HP26_gnu_map[-2 + 2] = BN_create(0, 2048, DOTS);	/* border */
404    HP26_gnu_map[-1 + 2] = HP26_gnu_map[-2 + 2];	/* axes */
405    HP26_gnu_map[0 + 2] = BN_create(2, 3072, SOLID);	/* plot 0 */
406    HP26_gnu_map[1 + 2] = HP26_gnu_map[-2 + 2];		/* plot 1 */
407    HP26_gnu_map[2 + 2] = BN_create(4, 1024, LINE5);	/* plot 2 */
408    HP26_gnu_map[3 + 2] = BN_create(5, 256, LINE6);	/* plot 3 */
409    HP26_gnu_map[4 + 2] = BN_create(6, 256, LINE8);	/* plot 4 */
410    HP26_gnu_map[5 + 2] = BN_create(7, 128, LINE9);	/* plot 5 */
411    HP26_gnu_map[6 + 2] = BN_create(8, 128, LINE10);	/* plot 6 */
412    HP26_gnu_map[7 + 2] = BN_create(9, 64, LINE6);	/* plot 7 */
413    HP26_gnu_map[8 + 2] = BN_create(10, 64, LINE4);	/* plot 8 */
414    HP26_gnu_map[9 + 2] = BN_create(11, 512, POINT);	/* point plot */
415    HP26_buff = HP26_gnu_map[10];	/* set to an unlikely linetype */
416    HP26_linetype_current = 0;	/* set to force a linetype change */
417    HP26_angle = 1;		/* left to right, default */
418    fputs("\033*mp1m2a2Q", gpoutfile);
419    /*           1 2 3 4
420       1.  make text upright
421       2.  select text size 1
422       3.  make SET the default drawing op
423       4.  left justify text */
424    fflush(gpoutfile);
425}
426
427
428TERM_PUBLIC void
429HP26_graphics()
430{
431    fputs("\033*daflsC", gpoutfile);
432    /*           12345
433       1.  clear graphics display
434       2.  shut off the alphanumeric display
435       3.  graphics cursor off
436       4.  into graphics text mode
437       5.  enable graphics display */
438    /* set the pen & cursor positions to force an initial absolute move */
439    HP26_pen_x = HP26_pen_y = -200;
440    HP26_cursor_x = HP26_cursor_y = 800;
441    HP26_in_text = TRUE;
442    /* initialize statistics */
443    HP26_reduction_int = 0;
444    HP26_reduction_slope = 0;
445    HP26_nop_move = 0;
446    HP26_nop_vect = 0;
447    HP26_nop_line = 0;
448    HP26_overflows = 0;
449}
450
451
452TERM_PUBLIC void
453HP26_text()
454{
455    int i, j, curr;
456
457    /* always flush the current line first */
458    for (i = 0; i < HP26_gnu_map_size; i++)
459	if ((HP26_gnu_map[i])->linetype == HP26_linetype_current)
460	    HP26_flush(HP26_gnu_map[i]);
461    /* now flush the rest of the lines */
462    for (i = 0; i < HP26_gnu_map_size; i++) {
463	HP26_flush(HP26_gnu_map[i]);
464	curr = HP26_gnu_map[i]->linetype;
465	for (j = 0; j < HP26_gnu_map_size; j++)
466	    if ((HP26_gnu_map[j])->linetype == curr)
467		HP26_flush(HP26_gnu_map[j]);
468    }
469    fputs("\033*deT", gpoutfile);
470    /*           12
471       1. turn on the alphanumeric display
472       2. back to text mode */
473    fflush(gpoutfile);
474    /* informational:  tells how many points compressed, how
475       many NOP's of each type, and how many times a buffer
476       overflowed during this plot */
477    /*
478       if(HP26_reduction_int
479       + HP26_reduction_slope
480       + HP26_nop_move
481       + HP26_nop_vect
482       + HP26_overflows
483       + HP26_nop_line > 0){
484       if (HP26_reduction_int>0)
485       printf("%d int-compress",HP26_reduction_int);
486       if (HP26_reduction_slope>0)
487       printf("%d slope-compress",HP26_reduction_slope);
488       if (HP26_nop_move>0)
489       printf("  %d nop_move",HP26_nop_move);
490       if (HP26_nop_vect>0)
491       printf("  %d nop_vect",HP26_nop_vect);
492       if (HP26_nop_line>0)
493       printf("  %d nop_line",HP26_nop_line);
494       if (HP26_overflows>0)
495       printf("  %d buffer overflows",HP26_overflows);
496       printf("\n");
497       }
498     */
499}
500
501TERM_PUBLIC void
502HP26_reset()
503{
504    int i;
505    for (i = 2; i < HP26_gnu_map_size; i++)
506	BN_delete(HP26_gnu_map[i]);
507}
508
509TERM_PUBLIC int
510HP26_text_angle(int ang)
511{
512    HP26_angle = (ang ? 2 : 1);
513    fprintf(gpoutfile, "\033*m%dN", HP26_angle);
514    return (TRUE);
515}
516
517
518TERM_PUBLIC void
519HP26_put_text(unsigned int x, unsigned int y, const char *str)
520{
521    char abs_str[10], rel_str[10];
522
523    if (!strlen(str))
524	return;
525    else {
526	fputs("\033*d", gpoutfile);
527	if (!HP26_in_text) {
528	    fputc('s', gpoutfile);
529	    HP26_in_text = TRUE;
530	}
531	sprintf(rel_str, "%d,%dP", x - HP26_cursor_x, y - HP26_cursor_y);
532	sprintf(abs_str, "%d,%dO", x, y);
533	if (strlen(rel_str) < strlen(abs_str))
534	    fputs(rel_str, gpoutfile);
535	else
536	    fputs(abs_str, gpoutfile);
537	fputs(str, gpoutfile);
538	HP26_pen_x = HP26_cursor_x = x;
539	HP26_pen_y = HP26_cursor_y = y;
540    }
541    /*
542       tmp = &(HP26_all_buffers[HP26_linetype_current]);
543       tmp->x[tmp->next] = x;
544       tmp->y[tmp->next] = y;
545       tmp->isa_move[tmp->next] = TRUE;
546       tmp->next++;
547       HP26_flush(tmp);
548       fprintf(gpoutfile,"\033*l%s\r",str);
549     */
550    return;
551}
552
553
554/* checks for NOP, sets HP26_buff to point to the right buffer */
555TERM_PUBLIC void
556HP26_linetype(int linetype)
557{
558    if (linetype < -2)
559	linetype = LT_BLACK;
560    if (linetype > 8)
561	linetype %= 9;
562    linetype += 2;
563    if (HP26_gnu_map[linetype] == HP26_buff) {
564	HP26_nop_line++;
565	return;			/* gnuplot just sent us another NOP */
566    }
567    HP26_buff = HP26_gnu_map[linetype];
568}
569
570
571
572/* switches to a solid linetype and calls do_point, then switches back */
573TERM_PUBLIC void
574HP26_line_and_point(unsigned int x, unsigned int y, int number)
575{
576    int line_save, not_solid;
577
578    /* shut up warnings with dummy initializer  -SB */
579    line_save = 0;
580    not_solid = (HP26_buff->linetype != SOLID);
581    if (not_solid) {
582	line_save = HP26_buff->linetype;
583	HP26_linetype(0);	/*switch to a solid line */
584    }
585    HP26_do_point(x, y, number);
586    if (not_solid)
587	HP26_linetype(line_save);
588}
589
590
591/* provides 9 point types so they stay in sync with the linetypes
592puts simpler point types first on the assumption they are more
593frequently used */
594static void
595HP26_do_point(unsigned int x, unsigned int y, int number)
596{
597    int htic, vtic;
598    HP26_Buffer_Node *tmp;
599
600    vtic = HP26_VTIC / 2;
601    htic = HP26_HTIC / 2;
602    if (number < 0) {
603	/* do a dot -- special case */
604	tmp = HP26_buff;
605	HP26_buff = HP26_gnu_map[11];	/* point plot */
606	HP26_vector(x, y);
607	HP26_buff = tmp;
608    }
609    switch (number % 9) {
610    case 0:
611	/* do triangle */
612	HP26_move(x - htic, y - vtic);
613	HP26_vector(x, y + vtic);
614	HP26_vector(x + htic, y - vtic);
615	HP26_vector(x - htic, y - vtic);
616	break;
617    case 1:
618	/* do nambla */
619	HP26_move(x - htic, y + vtic);
620	HP26_vector(x, y - vtic);
621	HP26_vector(x + htic, y + vtic);
622	HP26_vector(x - htic, y + vtic);
623	break;
624    case 2:
625	/* do left triangle */
626	HP26_move(x - htic, y);
627	HP26_vector(x + htic, y + vtic);
628	HP26_vector(x + htic, y - vtic);
629	HP26_vector(x - htic, y);
630	break;
631    case 3:
632	/* do right triangle */
633	HP26_move(x + htic, y);
634	HP26_vector(x - htic, y + vtic);
635	HP26_vector(x - htic, y - vtic);
636	HP26_vector(x + htic, y);
637	break;
638    case 4:
639	/* do box */
640	HP26_move(x - htic, y - vtic);
641	HP26_vector(x - htic, y + vtic);
642	HP26_vector(x + htic, y + vtic);
643	HP26_vector(x + htic, y - vtic);
644	HP26_vector(x - htic, y - vtic);
645	break;
646    case 5:
647	/* do plus */
648	HP26_move(x, y + vtic);
649	HP26_vector(x, y - vtic);
650	HP26_move(x - htic, y);
651	HP26_vector(x + htic, y);
652	break;
653    case 6:
654	/* do X */
655	HP26_move(x + htic, y + vtic);
656	HP26_vector(x - htic, y - vtic);
657	HP26_move(x - htic, y + vtic);
658	HP26_vector(x + htic, y - vtic);
659	break;
660    default:
661	/* do diamond */
662	HP26_move(x, y - vtic);
663	HP26_vector(x - htic, y);
664	HP26_vector(x, y + vtic);
665	HP26_vector(x + htic, y);
666	HP26_vector(x, y - vtic);
667	break;
668    }
669}
670
671#endif /* TERM_BODY */
672
673#ifdef TERM_TABLE
674
675TERM_TABLE_START(hp2623a_driver)
676    "hp2623A", "HP2623A and maybe others",
677    HP26_XMAX, HP26_YMAX, HP26_VCHAR, HP26_HCHAR,
678    HP26_VTIC, HP26_HTIC, options_null, HP26_init, HP26_reset,
679    HP26_text, null_scale, HP26_graphics, HP26_move, HP26_vector,
680    HP26_linetype, HP26_put_text, HP26_text_angle,
681    null_justify_text, HP26_line_and_point, do_arrow, set_font_null
682TERM_TABLE_END(hp2623a_driver)
683
684#undef LAST_TERM
685#define LAST_TERM hp2623a_driver
686
687#endif /* TERM_TABLE */
688#endif /* TERM_PROTO_ONLY */
689
690#ifdef TERM_HELP
691START_HELP(hp2623a)
692"1 hp2623a",
693"?commands set terminal hp2623a",
694"?set terminal hp2623a",
695"?set term hp2623a",
696"?terminal hp2623a",
697"?term hp2623a",
698"?hp2623a",
699" The `hp2623a` terminal driver supports the Hewlett Packard HP2623A.  It has",
700" no options."
701END_HELP(hp2623a)
702#endif
703