The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
/*
 * $Id: gpr.trm,v 1.9 2002/07/26 16:42:29 mikulik Exp $
 *
 */

/* GNUPLOT - gpr.trm */

/*[
 * Copyright 1990 - 1993, 1998
 *
 * Permission to use, copy, and distribute this software and its
 * documentation for any purpose with or without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.
 *
 * Permission to modify the software is granted, but not the right to
 * distribute the complete modified source code.  Modifications are to
 * be distributed as patches to the released version.  Permission to
 * distribute binaries produced by compiling modified sources is granted,
 * provided you
 *   1. distribute the corresponding source modifications from the
 *    released version in the form of a patch file along with the binaries,
 *   2. add special version identification to distinguish your version
 *    in addition to the base release version number,
 *   3. provide your name and address as the primary contact for the
 *    support of your modified version, and
 *   4. retain our contact information in regard to use of the base
 *    software.
 * Permission to distribute the released version of the source code along
 * with corresponding source modifications in the form of a patch file is
 * granted with same provisions 2 through 4 for binary distributions.
 *
 * This software is provided "as is" without express or implied warranty
 * to the extent permitted by applicable law.
]*/

/*
 * This file is included by ../term.c.
 *
 * This terminal driver supports:
 *   APOLLO's GPR windowing system
 *
 * AUTHORS
 *  Michael Aramini
 *  Roque D Oliveira , oliveria@caen.engin.umich.edu
 * 
 * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
 * 
 */

/*
 * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
 */

#include "driver.h"

#ifdef TERM_REGISTER
register_term(gpr)
#endif

#ifdef TERM_PROTO
TERM_PUBLIC void GPR_init __PROTO((void));
TERM_PUBLIC void GPR_graphics __PROTO((void));
TERM_PUBLIC void GPR_text __PROTO((void));
TERM_PUBLIC void GPR_linetype __PROTO((int linetype));
TERM_PUBLIC void GPR_move __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void GPR_vector __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void GPR_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
TERM_PUBLIC int GPR_text_angle __PROTO((int ang));
TERM_PUBLIC int GPR_justify_text __PROTO((enum JUSTIFY mode));
TERM_PUBLIC void GPR_reset __PROTO((void));
/* landscape window */
/*
#define GPR_XMAX 720
#define GPR_YMAX 450
*/
/* portrait window */
#define GPR_XMAX 585
#define GPR_YMAX 735
#define GPR_VCHAR 19
#define GPR_HCHAR 10
#define GPR_VTIC (GPR_YMAX/80)
#define GPR_HTIC (GPR_XMAX/80)
#endif /* TERM_PROTO */

#ifndef TERM_PROTO_ONLY
#ifdef TERM_BODY
void GPRold_linetype __PROTO((int linetype));
static void check __PROTO((char *messagex));
int gpr_isa_pad __PROTO((void));
#include <apollo/base.h>
#include <apollo/error.h>
#include <apollo/gpr.h>
#include <apollo/pad.h>

#define GPR_XLAST (GPR_XMAX - 1)
#define GPR_YLAST (GPR_YMAX - 1)


gpr_$direction_t gpr_path = gpr_$right;
/* text angle, 0=horizontal, 1=vertical */
int gpr_ang = 0;
/* text is flush left */
enum JUSTIFY gpr_justify = LEFT;

static status_$t status;
/* set it to 1 when debugging program */
unsigned int Debug = 0;


static void
check(messagex)
char *messagex;
{
    if (status.all = status_$ok) {
	error_$print(status);
	printf("Error occurred while %s.\n", messagex);
    }
}

/* return whether stdout is a DM pad . Called by term.c */
int
gpr_isa_pad()
{
    pad_$isa(1, &status);
    return (status.all == status_$ok);
}


TERM_PUBLIC void
GPR_init()
{
    gpr_$offset_t dm_bitmap_size;
    gpr_$bitmap_desc_t dm_bitmap_desc;
    pad_$window_desc_t window;
    short font_id;
    stream_$id_t stream_id;
    static gpr_$rgb_plane_t hi_plane;
    static gpr_$disp_char_t display_characteristics;
    static float screen_size_r_width, screen_size_r_height;
    static short int disp_len = sizeof(gpr_$disp_char_t);
    static short int disp_len_returned;


    /* open a pad to do graphics in */
    window.top = 0;
    window.left = 0;
    /* 10 accounts for width of window border */
    window.width = GPR_XMAX + 10;
    /* 35 accounts for height of window border */
    window.height = GPR_YMAX + 35;
    pad_$create_window("", (short) 0, pad_$transcript, (short) 1, window, &stream_id, &status);
    check("pad_$create_window");

/*  pad_$set_full_window(stream_id,(short) 1,&window, &status); */
/*  pad_$set_border (stream_id,(short) 1, true, &status); */
    pad_$set_scale(stream_id, (short) 1, (short) 1, &status);
    pad_$set_auto_close(stream_id, (short) 1, true, &status);

    gpr_$inq_disp_characteristics(gpr_$direct, stream_id, disp_len, &display_characteristics, &disp_len_returned, &status);
    check("in gpr_$inq_display_characteristics");
    /*x_window_size in pixels */
    screen_size_r_width = (float) display_characteristics.x_window_size;
    /*y_window_size in pixels */
    screen_size_r_height = (float) display_characteristics.y_window_size;
    hi_plane = display_characteristics.n_planes - 1;
    if (Debug)
	printf("width=%f height=%f \n", screen_size_r_width, screen_size_r_height);

    dm_bitmap_size.x_size = 1280;
    dm_bitmap_size.y_size = 1024;
    gpr_$init(gpr_$direct, stream_id, dm_bitmap_size, hi_plane, &dm_bitmap_desc, &status);
    check("in gpr_$init");
/*
  gpr_$set_obscured_opt(gpr_$pop_if_obs, &status); 
  check("in gpr_$set_obscured_opt");
*/
    gpr_$set_auto_refresh(true, &status);
    check("in gpr_$set_auto_refresh");

    /* load a font and make it current */
    gpr_$load_font_file("f7x13", 5, &font_id, &status);
    check("in gpr_$load_font_file");
    gpr_$set_text_font(font_id, &status);
    check("in gpr_$set_text_font");

    /* set up color values */
    gpr_$set_draw_value((gpr_$pixel_value_t) 7, &status);	/* white */
    check("in gpr_set_draw_value");
    gpr_$set_text_background_value((gpr_$pixel_value_t) (-1), &status);	/* trans */
    check("in gpr_$set_text_background_value");
    gpr_$set_text_value((gpr_$pixel_value_t) 7, &status);	/* white */
    check("in gpr_$set_text_value");
}


TERM_PUBLIC void
GPR_graphics()
{
    gpr_$coordinate_t locx, locy, marker_size;

    (void) gpr_$acquire_display(&status);
    check("in gpr_$acquire display");
    gpr_$clear((gpr_$pixel_value_t) 0, &status);	/* black */
    check("in gpr_$clear");

    if (Debug) {
	marker_size = (short) 10;

	locx = (short) 5;
	locy = (short) 5;
	gpr_$set_draw_value((gpr_$pixel_value_t) 2, &status);	/* white */
	gpr_$move((locx - marker_size / 2), locy, &status);
	gpr_$line((locx + marker_size / 2), locy, &status);
	gpr_$move(locx, (locy + marker_size / 2), &status);
	gpr_$line(locx, (locy - marker_size / 2), &status);

	locx = (short) (GPR_XMAX - 1 - 5);
	locy = (short) 5;
	gpr_$set_draw_value((gpr_$pixel_value_t) 3, &status);	/* white */
	gpr_$move((locx - marker_size / 2), locy, &status);
	gpr_$line((locx + marker_size / 2), locy, &status);
	gpr_$move(locx, (locy + marker_size / 2), &status);
	gpr_$line(locx, (locy - marker_size / 2), &status);

	locx = (short) 5;
	locy = (short) (GPR_YMAX - 1 - 5);
	gpr_$set_draw_value((gpr_$pixel_value_t) 4, &status);	/* white */
	gpr_$move((locx - marker_size / 2), locy, &status);
	gpr_$line((locx + marker_size / 2), locy, &status);
	gpr_$move(locx, (locy + marker_size / 2), &status);
	gpr_$line(locx, (locy - marker_size / 2), &status);

	locx = (short) (GPR_XMAX - 1 - 5);
	locy = (short) (GPR_YMAX - 1 - 5);
	gpr_$set_draw_value((gpr_$pixel_value_t) 5, &status);	/* white */
	gpr_$move((locx - marker_size / 2), locy, &status);
	gpr_$line((locx + marker_size / 2), locy, &status);
	gpr_$move(locx, (locy + marker_size / 2), &status);
	gpr_$line(locx, (locy - marker_size / 2), &status);

	gpr_$set_draw_value((gpr_$pixel_value_t) 7, &status);	/* white */
	check("in gpr_$set_draw_value");
    }				/* end if(Debug) */
}


TERM_PUBLIC void
GPR_text()
{
    gpr_$release_display(&status);
    check("gpr_$release_display");
}


void
GPRold_linetype(linetype)
int linetype;
{
    static gpr_$line_pattern_t patterns[2 + 5] =
    {
	{0xFFFF},		/* solid              1111111111111111 */
	{0x3FFF},		/* very long dashed   0011111111111111 */
	{0xFFFF},		/* solid              1111111111111111 */
	{0x5555},		/* dotted             0101010101010101 */
	{0x3333},		/* short dashed       0011001100110011 */
	{0xB5AD},		/* dot short-dashed   1011010110101101 */
	{0x3FFF}		/* very long dashed   0011111111111111 */
    };
    if (linetype >= 5)
	linetype %= 5;
    gpr_$set_line_pattern((short) 1, patterns[linetype + 2], (short) 16, &status);
    check("in gpr_$set_line_pattern");
}

TERM_PUBLIC void
GPR_linetype(linetype)
int linetype;
{
    static gpr_$line_pattern_t patterns[2 + 7] =
    {
	{0xFFFF},		/* solid              1111111111111111 */
	{0x1111},		/* long-spaced dotted 0001000100010001 */
	{0xFFFF},		/* solid              1111111111111111 */
	{0x5555},		/* dotted             0101010101010101 */
	{0x3333},		/* short  dashed      0011001100110011 */
	{0x7777},		/* medium dashed      0111011101110111 */
	{0x3F3F},		/* long   dashed      0011111100111111 */
	{0x0F0F},		/* long-spaced dashed 0000111100001111 */
	{0x5F5F}		/* dot dashed         0101111101011111 */
    };
    if (linetype >= 7)
	linetype %= 7;
    gpr_$set_line_pattern((short) 1, patterns[linetype + 2], (short) 16, &status);
    check("in gpr_$set_line_pattern");

/*
  gpr_$set_draw_value((gpr_$pixel_value_t)(linetype + 1), &status);
  check("in gpr_$set_draw_value");
*/
}


TERM_PUBLIC void
GPR_move(x, y)
unsigned int x, y;
{
    gpr_$move((short) x, (short) (GPR_YMAX - 1 - y), &status);
    check("in gpr_$move");
}


TERM_PUBLIC void
GPR_vector(x, y)
unsigned int x, y;
{
    gpr_$line((short) x, (short) (GPR_YMAX - 1 - y), &status);
    check("in gpr_$line");
}


TERM_PUBLIC void
GPR_put_text(x, y, str)
unsigned int x, y;		/* reference point of string */
const char str[];		/* the text */
{
    gpr_$coordinate_t xgpr, ygpr;
    gpr_$offset_t str_size_in_pixels;
    short int str_len;

    gpr_$coordinate_t locx, locy, marker_size;

    if (Debug) {
	locx = (short) x;
	locy = (short) (GPR_YMAX - 1 - y);
	marker_size = (short) 20;
	gpr_$set_draw_value((gpr_$pixel_value_t) 1, &status);	/* white */
	gpr_$move((locx - marker_size / 2), locy, &status);
	gpr_$line((locx + marker_size / 2), locy, &status);
	gpr_$move(locx, (locy + marker_size / 2), &status);
	gpr_$line(locx, (locy - marker_size / 2), &status);
	gpr_$set_draw_value((gpr_$pixel_value_t) 7, &status);	/* white */
    }
    xgpr = (short) x;
    ygpr = (short) (GPR_YMAX - 1 - y);
    gpr_$set_text_path(gpr_path, &status);
    check("gpr_$set_text_path");

    str_len = (short) strlen(str);
    /* Calculate how much space (in pixels) the string requires */
    gpr_$inq_text_extent(str, str_len, &str_size_in_pixels, &status);
    check("in gpr_$inq_text_extent");

    switch (gpr_justify) {
    case LEFT:
	{
	    switch (gpr_path) {
	    case gpr_$up:	/* vertical */
		{
		    if (Debug)
			printf("LEFT and up , str=%s\n", str);
		    break;
		}
	    case gpr_$right:	/* horizontal */
		{
		    ygpr = ygpr + str_size_in_pixels.y_size / 2;
		    if (Debug)
			printf("LEFT and right, str=%s \n", str);
		    break;
		}
	    }
	    break;
	}

    case CENTRE:
	{
	    switch (gpr_path) {
	    case gpr_$up:	/* vertical */
		{
		    xgpr = xgpr + str_size_in_pixels.x_size / 2;
		    ygpr = ygpr + str_size_in_pixels.y_size / 2;
		    if (Debug)
			printf("CENTRE and up, str=%s \n", str);
		    break;
		}
	    case gpr_$right:	/* horizontal */
		{
		    xgpr = xgpr - str_size_in_pixels.x_size / 2;
		    ygpr = ygpr + str_size_in_pixels.y_size / 2;
		    if (Debug)
			printf("CENTRE and right, str=%s \n", str);
		    break;
		}
	    }
	    break;
	}
    case RIGHT:
	{
	    switch (gpr_path) {
	    case gpr_$up:	/* vertical */
		{
		    ygpr = ygpr + str_size_in_pixels.y_size;
		    if (Debug)
			printf("RIGHT and up, str=%s \n", str);
		    break;
		}
	    case gpr_$right:	/* horizontal */
		{
		    xgpr = xgpr - str_size_in_pixels.x_size;
		    ygpr = ygpr + str_size_in_pixels.y_size / 2;
		    if (Debug)
			printf("RIGHT and right, str=%s \n", str);
		    break;
		}
	    }
	    break;
	}
    }

    gpr_$move(xgpr, ygpr, &status);
    check("in gpr_$move");
    gpr_$text(str, str_len, &status);
    check("in gpr_$text");
}

TERM_PUBLIC int
GPR_text_angle(ang)
int ang;
{
    if (gpr_ang != ang) {
	gpr_ang = ang;
	gpr_path = (gpr_ang ? gpr_$up : gpr_$right);
    }
    return (TRUE);
}

TERM_PUBLIC int
GPR_justify_text(mode)
enum JUSTIFY mode;
{
    gpr_justify = mode;
    return (TRUE);
}

TERM_PUBLIC void
GPR_reset()
{
    gpr_$terminate(false, &status);
    check("in gpr_$terminate");
}

#endif /* TERM_BODY */

#ifdef TERM_TABLE

TERM_TABLE_START(gpr_driver)
    "gpr", "Apollo Graphics Primitive Resource, fixed-size window",
    GPR_XMAX, GPR_YMAX, GPR_VCHAR, GPR_HCHAR,
    GPR_VTIC, GPR_HTIC, options_null, GPR_init, GPR_reset,
    GPR_text, null_scale, GPR_graphics, GPR_move, GPR_vector,
    GPR_linetype, GPR_put_text, GPR_text_angle,
    GPR_justify_text, line_and_point, do_arrow, set_font_null
TERM_TABLE_END(gpr_driver)

#undef LAST_TERM
#define LAST_TERM gpr_driver

#endif /* TERM_TABLE */
#endif /* TERM_PROTO_ONLY */

#ifdef TERM_HELP
START_HELP(gpr)
"1 gpr",
"?commands set terminal gpr",
"?set terminal gpr",
"?set term gpr",
"?terminal gpr",
"?term gpr",
"?gpr",
" The `gpr` terminal driver supports the Apollo Graphics Primitive Resource",
" for a fixed-size window.  It has no options.",
"",
" If a variable window size is desired, use the `apollo` terminal instead."
END_HELP(gpr)
#endif /* TERM_HELP */