/*
 *	Vdi input funcs library interface
 *
 *		vsin_mode	set input mode
 *		vrq_locator	input locator blocking
 *		vsm_locator 	input locator non-blocking
 *		vrq_valuator	get vauator blocking
 *		vsm_valuator	sample valuator non-blocking
 *		vrq_choice	request choice blocking
 *		vsm_choice	request choice non-blocking
 *		vrq_string	get string blocking
 *		vsm_string	get string non block
 *		vsc_form	set mouse form
 *		vex_timv	exchange timer interrupt vector
 *		v_show_c	show cursor
 *		v_hide_c	show hide
 *		vex_butv	exchange button vector
 *		vex_motv	exchange mouse movement vector
 *		vex_curv	exchange cursor change vector
 *		vq_key_s	sample kbd state
 *
 *		    ++jrb	bammi@cadence.com
 *		    modified: mj -- ntomczak@vm.ucs.ualberta.ca
 *
 * whoever at atari/dri designed this part was
 * definitely *not* on over-the-counter drugs
 *
 */
#include "common.h"

#ifdef __DEF_ALL__

#define L_vsin_mod
#define L_vsm_loca		/* provides also vrq_locator */
#define L_vrq_valu
#define L_vsm_valu
#define L_vrq_choi
#define L_vsm_choi
#define L_vsm_stri		/* provides also vrq_string */
#define L_vsc_form
#define L_vex_timv
#define L_v_show_c
#define L_v_hide_c
#define L_vq_mouse
#define L_vex_butv
#define L_vex_motv
#define L_vex_curv
#define L_vq_key_s

#endif /* __DEF_ALL__ */


#ifdef L_vsin_mod

/* vsin_mode	set input mode
 * returns input mode
 */
int vsin_mode(int handle, int dev, int mode)
{
    _intin[0] = dev;
    _intin[1] = mode;
    
    __vdi__(VDI_CONTRL_ENCODE(33, 0, 2, 0), handle);

    return (int)_intout[0];
}
#endif /* L_vsin_mod */

/* vrq_locator	input locator (blocking)
 * returns void (results in args)
 */


#ifdef L_vsm_loca

#ifndef	PURE_C
__asm__(".stabs \"_vrq_locator\",5,0,0,_vsm_locator");
					/* dept of clean tricks */
#else	PURE_C
int vrq_locator(int handle, int x, int y,
		 int *xout, int *yout, int *term)
{
    _ptsin[0] = x;
    _ptsin[1] = y;
    
    __vdi__(VDI_CONTRL_ENCODE(28, 1, 0, 0), handle);
    
    *xout = _ptsout[0];
    *yout = _ptsout[1];
    *term = _intout[0];

    /* ignore return value for vrq_locator */
    return (int)((_contrl[4] << 1) | _contrl[2]);
}
#endif

/* vsm_locator input locator non-blocking
 * returns coded message
 *	1	coordinates changed
 *	2	key pressed coordinates not changed
 *	3	key pressed coordinates changed
 *	0	no input
 */
int vsm_locator(int handle, int x, int y,
		 int *xout, int *yout, int *term)
{
    _ptsin[0] = x;
    _ptsin[1] = y;
    
    __vdi__(VDI_CONTRL_ENCODE(28, 1, 0, 0), handle);
    
    *xout = _ptsout[0];
    *yout = _ptsout[1];
    *term = _intout[0];

    /* ignore return value for vrq_locator */
    return (int)((_contrl[4] << 1) | _contrl[2]);
}
#endif /* L_vsm_loca */

#ifdef L_vrq_valu

/* vrq_valuator	get valuator blocking
 * returns void (results in args)
 */
void vrq_valuator(int handle, int in,
		  int *out,   int *term)
{
    _intin[0] = in;

    __vdi__(VDI_CONTRL_ENCODE(29, 0, 1, 0), handle);
    
    *out = _intout[0];
    *term = _intout[1];
}
#endif /* L_vrq_valu */

#ifdef L_vsm_valu

/* vsm_valuator	sample valuator (non-block)
 * returns void (results in args)
 */
void vsm_valuator(int handle, int in,
		  int *out,   int *term, int *status)
{
    _intin[0] = in;

    __vdi__(VDI_CONTRL_ENCODE(29, 0, 1, 0), handle);
    
    *out = _intout[0];
    *term = _intout[1];
    *status = _contrl[4];
}
#endif /* L_vsm_valu */

#ifdef L_vrq_choi

/* vrq_choice	request choice blocking
 * returns void (result in arg)
 */
void vrq_choice(int handle, int cin, int *cout)
{
    _intin[0] = cin;
    
    __vdi__(VDI_CONTRL_ENCODE(30, 0, 1, 0), handle);
    
    *cout = _intout[0];
}
#endif /* L_vrq_choi */

#ifdef L_vsm_choi

/* vsm_choice	request choice (non-block)
 * returns status and choice in arg
 */
int vsm_choice(int handle, int *choice)
{
    __vdi__(VDI_CONTRL_ENCODE(30, 0, 0, 0), handle);
    
    *choice = _intout[0];
    return (int)_contrl[4];
}
#endif /* L_vsm_choi */

#ifdef L_vsm_stri

/* vrq_string	get string blocking
 * returns void (string in arg)
 * void vrq_string(int handle, int len, int echo, int echoxy[], char *str)
 */
 
#ifndef	PURE_C
__asm__(".stabs \"_vrq_string\",5,0,0,_vsm_string"); /* dept of clean tricks */
#else	PURE_C
int vrq_string(int handle, int len, int echo, int echoxy[], char *str)
{
    short status;
    short *end, *wptr = _intout;

    /* Switch roles of _intin and _intout */
    _vdiparams[1] = (void *)wptr;
    _vdiparams[3] = (void *)&_intin[0];

    *wptr++ = len;
    *wptr++ = echo;

     wptr = (short *)_contrl;
    *wptr++  = 31;	/* 0  - opcode */
    *wptr++  = 1;	/* 1 */
     wptr++;		/* 2 */
    *wptr    = 2;	/* 3  - # of entries in _intout (this time) */
     wptr[3] = handle;	/* 6 - handle */
    vdi();		/* call vdi */

    status = _contrl[4];
    wptr = _intin;
    end = wptr + status;
    while (wptr < end)
	*str++ = *wptr++;
    *str = '\0';

    /* Restore usual meaning of _intin and _intout */
    _vdiparams[1] = (void *)&_intin[0];
    _vdiparams[3] = (void *)&_intout[0];

    return (int) status; /* not used by vrq_string */
}
#endif

/* vsm_string	get string non block
 * returns 0 no chars avail	>0 chars avail
 *
 * The code below does not use VDI_CONTRL_ENCODE macro since
 * len can be a negative number.
 */
/*
 * Both functions will handle strings up to INTINMAX characters in
 * length (currently 255). Note that if length is specified as
 * a negative number then scan codes are available after a call
 * in _intin[] array  (not _intout! - this binding temporarily
 * switches roles of _intin and _intout).
 */


int vsm_string(int handle, int len, int echo, int echoxy[], char *str)
{
    short status;
    short *end, *wptr = _intout;

    /* Switch roles of _intin and _intout */
    _vdiparams[1] = (void *)wptr;
    _vdiparams[3] = (void *)&_intin[0];

    *wptr++ = len;
    *wptr++ = echo;

     wptr = (short *)_contrl;
    *wptr++  = 31;	/* 0  - opcode */
    *wptr++  = 1;	/* 1 */
     wptr++;		/* 2 */
    *wptr    = 2;	/* 3  - # of entries in _intout (this time) */
     wptr[3] = handle;	/* 6 - handle */
    vdi();		/* call vdi */

    status = _contrl[4];
    wptr = _intin;
    end = wptr + status;
    while (wptr < end)
	*str++ = *wptr++;
    *str = '\0';

    /* Restore usual meaning of _intin and _intout */
    _vdiparams[1] = (void *)&_intin[0];
    _vdiparams[3] = (void *)&_intout[0];

    return (int) status; /* not used by vrq_string */
}
#endif /* L_vsm_stri */


#ifdef L_vsc_form

/* vsc_form	set mouse form
 * returns void
 */
void vsc_form(int handle, int form[])
{
  
#ifdef __MSHORT__
    _vdiparams[1] = &form[0];
#else
    int   *end = form + 37;
    short *wptr = _intin;

    do {
	*wptr++ = *form++;
    } while (form < end);
#endif
    
    __vdi__(VDI_CONTRL_ENCODE(111, 0, 37, 0), handle);
#ifdef __MSHORT__
    _vdiparams[1] = (void *)&_intin[0];
#endif
}
#endif /* L_vsc_form */

#ifdef L_vex_timv

/* vex_timv	exchange timer interrupt vector
 * returns void (results in args)
 */
void vex_timv(int handle, void *time_addr,
	      void **otime_addr, int *time_conv)
{
    *((void **)(&_contrl[7])) = time_addr;
    
    __vdi__(VDI_CONTRL_ENCODE(118, 0, 0, 0), handle);
    
    *otime_addr = *((void **)(&_contrl[9]));
    *time_conv  = _intout[0];
}
#endif /* L_vex_timv */

#ifdef L_v_show_c

/* v_show_c	show cursor
 * returns void
 */
void v_show_c(int handle, int reset)
{
    _intin[0] = reset;
    
    __vdi__(VDI_CONTRL_ENCODE(122, 0, 1, 0), handle);
}
#endif /* L_v_show_c */

#ifdef L_v_hide_c

/* v_hide_c	show hide
 * returns void
 */
void v_hide_c(int handle)
{
    __vdi__(VDI_CONTRL_ENCODE(123, 0, 0, 0), handle);
}
#endif /* L_v_hide_c */

#ifdef L_vq_mouse

/* vq_mouse	sample mouse button state
 * returns void (results in args
 */
void vq_mouse(int handle, int *pstatus, int *x, int *y)
{
    __vdi__(VDI_CONTRL_ENCODE(124, 0, 0, 0), handle);
    
    *pstatus = _intout[0];
    *x = _ptsout[0];
    *y = _ptsout[1];
}
#endif /* L_vq_mouse */

#ifdef L_vex_butv

/* vex_butv	exchange button vector
 * returns void (results in args)
 */
void vex_butv(int handle, void *new, void **old)
{
    *((void **)(&_contrl[7])) = new;
    
    __vdi__(VDI_CONTRL_ENCODE(125, 0, 0, 0), handle);
    
    *old = *((void **)(&_contrl[9]));
}
#endif /* L_vex_butv */

#ifdef L_vex_motv

/* vex_motv	exchange mouse movement vector
 * returns void (result in arg)
 */
void vex_motv(int handle, void *new, void **old)
{
    *((void **)(&_contrl[7])) = new;
    
    __vdi__(VDI_CONTRL_ENCODE(126, 0, 0, 0), handle);
    
    *old = *((void **)(&_contrl[9]));
}
#endif /* L_vex_motv */

#ifdef L_vex_curv

/* vex_curv	exchange cursor change vector
 * returns void (result in arg)
 */
void vex_curv(int handle, void *new, void **old)
{
    *((void **)(&_contrl[7])) = new;
    
    __vdi__(VDI_CONTRL_ENCODE(127, 0, 0, 0), handle);
    
    *old = *((void **)(&_contrl[9]));
}
#endif /* L_vex_curv */

#ifdef L_vq_key_s

/* vq_key_s	sample kbd state
 * returns void (result in arg)
 */
void vq_key_s(int handle, int *state)
{
    __vdi__(VDI_CONTRL_ENCODE(128, 0, 0, 0), handle);
    
    *state = _intout[0];
}
#endif /* L_vq_key_s */

/* -eof- */
