home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------*
- * *
- * Module: GetTouch.c *
- * Purpose: To provide an intelligent interface *
- * to the Elographics ELODEV TSR from an *
- * application that must distinguish *
- * between button and curve type touches.*
- * Author: W. Harvey Gray *
- * Compiler: Microsoft 5.0 *
- * *
- * External GetTouch *
- * Functions: InitializeTouch *
- * ReplayTouch *
- * SetButtonRadius *
- * TouchInfo *
- * *
- * Variables: There are no external variables used *
- * or defined by this module. *
- * *
- * Copyright 1992, W. Harvey Gray. May be used *
- * freely, if authorship and publication are *
- * acknowledged. *
- * *
- *--------------------------------------------------*/
-
- #include <math.h>
- #include <stdio.h>
-
- #include "dvrfunc.h"
- #include "GetTouch.h"
-
- /*--------------------------------------------------*
- * module defines *
- *--------------------------------------------------*/
-
- #define TOUCH_BUF_NUM 50 /* Internal buffer size. */
-
- /*--------------------------------------------------*
- * static variables *
- *--------------------------------------------------*/
-
- static boolean is_button; /* Is a button flag */
- static boolean from_tbuff; /* Touch in buffer flag */
- static boolean overflow; /* Buff storage exceeded */
-
- static int num_returned; /* Total touch points */
- static int num_touch; /* Count of touch points */
- static int ut; /* Touch point untouch flag */
- static int xt; /* Touch point x coordinate */
- static int yt; /* Touch point y coordinate */
-
- static long radius2; /* Square of button radius */
- static long dist2; /* Distance variable */
- static long xcen; /* X centroid of touch */
- static long xsum; /* X sum of touch points */
- static long ycen; /* Y centroid of touch */
- static long ysum; /* Y sum of touch points */
-
- /*--------------------------------------------------*
- * touch buffer and pointers *
- *--------------------------------------------------*/
-
- static struct touchit touch_information;
-
- static struct touchit *pti = &touch_information;
-
- static struct touchxy touch[TOUCH_BUF_NUM];
- static struct touchxy tub;
-
- static struct touchxy *ptouch = &touch[0];
- static struct touchxy *ptub = &tub;
-
- /*--------------------------------------------------*
- * static prototypes *
- *--------------------------------------------------*/
-
- static struct touchxy *buffered( boolean * );
- static struct touchxy *unbuffered( boolean * );
-
- static void buffer_touch( void );
- static void store_touch( struct touchxy * );
-
- /*--------------------------------------------------*
- * extern function GetTouch() *
- *--------------------------------------------------*/
-
- struct touchxy *GetTouch( boolean *button ) {
-
- /*--------------------------------------------------*
- * Purpose: *
- * *
- * Function GetTouch doesn't accept any inputs *
- * from the caller and returns two values. If *
- * there is a touch in progress, then GetTouch *
- * returns a pointer to a struct that contains the *
- * next touch point coordinate pair. If no touch *
- * is in progress, then GetTouch returns a NULL *
- * pointer to a touchxy struct. Also returned via *
- * a pointer to the boolean button variable is the *
- * logical value of the button flag. If TRUE, then *
- * the touch should be interpreted like the user *
- * touched a button. If FALSE, then the touch *
- * should be interpreted like the user is drawing *
- * a curve. *
- * *
- *--------------------------------------------------*/
-
- if ( from_tbuff )
- return buffered( button );
-
- /*----------------------------------------------*
- * If there is no touch, then return immedi- *
- * ately pointing to a null touch point. *
- *----------------------------------------------*/
-
- if ( ! gettouch( &xt, &yt, &ut ) )
- return (struct touchxy *) NULL;
-
- /*----------------------------------------------*
- * If the space in the touch buffer has been *
- * exceeded, then simply return the touch point.*
- *----------------------------------------------*/
-
- if ( overflow )
- return unbuffered( button );
-
- /*----------------------------------------------*
- * The last special case occurs when an *
- * untouch occurs on the first touch point. If *
- * this happens, simply return the untouch pt. *
- *----------------------------------------------*/
-
- else if ( ut ) {
-
- ptub->xt = xt;
- ptub->yt = yt;
- ptub->ut = ut;
- *button = TRUE;
-
- return ptub;
- }
-
- /*----------------------------------------------*
- * If here, then the touch point is the first *
- * touch point of a new touch. Begin by buffer-*
- * ing (at most) TOUCH_BUF_NUM touch points. *
- *----------------------------------------------*/
-
- is_button = TRUE; /* Assume it's a button. */
- num_touch = 1; /* Init. number of touch points */
-
- ptouch = &touch[0]; /* Init. touch buffer ptr. */
- ptouch->xt = xt; /* Store touch point */
- ptouch->yt = yt;
- ptouch->ut = ut;
-
- xcen = xsum = (long) xt; /* Init. touch pt cen. */
- ycen = ysum = (long) yt;
-
- buffer_touch(); /* Fill the touch buffer */
-
- /*----------------------------------------------*
- * Setup so that the touch can be extracted *
- * from its internal buffer and return the *
- * first touch point. *
- *----------------------------------------------*/
-
- from_tbuff = TRUE;
- num_returned = 1;
-
- ptouch = &touch[0];
- *button = is_button;
-
- return ptouch;
- }
-
- /*--------------------------------------------------*
- * extern function InitializeTouch() *
- *--------------------------------------------------*/
-
- void InitializeTouch( void ) {
-
- /*--------------------------------------------------*
- * Purpose: *
- * *
- * Initialize the internal variables of the *
- * GetTouch module. *
- * *
- *--------------------------------------------------*/
-
- is_button = FALSE;
- from_tbuff = FALSE;
- overflow = FALSE;
-
- num_returned = 0;
- num_touch = 0;
- ut = FALSE;
- xt = 0;
- yt = 0;
-
- radius2 = 0;
- dist2 = 0;
- xcen = 0;
- xsum = 0;
- ycen = 0;
- ysum = 0;
-
- return;
- }
-
- /*--------------------------------------------------*
- * extern function ReplayTouch() *
- *--------------------------------------------------*/
-
- void ReplayTouch( boolean set_button ) {
-
- /*--------------------------------------------------*
- * Purpose: *
- * *
- * Replays a touch, if there is one in the buffer.*
- * *
- *--------------------------------------------------*/
-
- if ( from_tbuff ) { /* Lose, if no buffer. */
-
- num_returned = 0;
- ptouch = &touch[-1]; /* It will be ++'ed. */
- is_button = set_button;
- }
- return;
- }
-
- /*--------------------------------------------------*
- * extern function SetButtonRadius() *
- *--------------------------------------------------*/
-
- void SetButtonRadius( int radius ) {
-
- /*--------------------------------------------------*
- * Purpose: *
- * *
- * Sends the button radius to this module. *
- * *
- *--------------------------------------------------*/
-
- radius2 = (long) radius * radius;
- }
-
- /*--------------------------------------------------*
- * extern function TouchInfo() *
- *--------------------------------------------------*/
-
- struct touchit *TouchInfo( void ) {
-
- /*--------------------------------------------------*
- * Purpose: *
- * *
- * Returns a pointer to a struct that contains *
- * touch information. *
- * *
- *--------------------------------------------------*/
-
- pti->xcen = (int) ( xsum / (long) num_touch );
- pti->ycen = (int) ( ysum / (long) num_touch );
- pti->n = num_touch;
- pti->button = is_button;
-
- return pti;
- }
-
- /*--------------------------------------------------*
- * static function buffer_touch() *
- *--------------------------------------------------*/
-
- static void buffer_touch( void ) {
-
- /*--------------------------------------------------*
- * Purpose: *
- * *
- * Fill up the touch buffer by reading and storing*
- * touch points. Several conditions stop filing *
- * the touch buffer: if there are too many touch *
- * points for the buffer, stop buffering; if the *
- * touch is determined to not be a button, then *
- * there is no need to continue buffering; or if *
- * an untouch is encountered, then quit buffering. *
- * *
- *--------------------------------------------------*/
-
- while ( num_touch < TOUCH_BUF_NUM ) {
-
- if ( gettouch( &xt, &yt, &ut ) ) {
-
- num_touch++;
- store_touch( ++ptouch );
-
- if ( dist2 > radius2 ) {
-
- /* If here, then not a button push. */
- /* Stop buffering. */
- is_button = FALSE;
- break;
- }
- if ( ut ) {
- /* Stop buffering. */
- overflow = FALSE;
- break;
- }
- }
- }
- return;
- }
-
- /*--------------------------------------------------*
- * static function buffered() *
- *--------------------------------------------------*/
-
- static struct touchxy *buffered( boolean *button ) {
-
- /*--------------------------------------------------*
- * Purpose: *
- * *
- * Returns a buffered touch checking for the end *
- * of the internal touch buffer. If the end of the *
- * buffer is encountered, then several conditional *
- * flags are set. *
- * *
- *--------------------------------------------------*/
-
- num_returned++;
- ptouch++;
- *button = is_button;
- /* Exhausted buffer? */
-
- if ( num_returned == num_touch ||
- num_returned > TOUCH_BUF_NUM ) {
-
- from_tbuff = FALSE;
- overflow = TRUE;
- }
- /* Untouch buffered? */
- if ( ptouch->ut ) {
-
- from_tbuff = FALSE;
- overflow = FALSE;
- }
- return ptouch;
- }
-
- /*--------------------------------------------------*
- * static function store_touch() *
- *--------------------------------------------------*/
-
- static void store_touch( struct touchxy *pt ) {
-
- /*--------------------------------------------------*
- * Purpose: *
- * *
- * Stores touch point into a touch point struct *
- * and calculates the instantaneous average touch *
- * coordinates and the distance between this touch *
- * point's coordinate and the touches average coor- *
- * dinate. *
- * *
- *--------------------------------------------------*/
-
- pt->xt = xt;
- pt->yt = yt;
- pt->ut = ut;
-
- xsum += xt;
- ysum += yt;
- xcen = xsum / (long) num_touch;
- ycen = ysum / (long) num_touch;
-
- dist2 = (xt - xcen) * (xt - xcen) +
- (yt - ycen) * (yt - ycen);
- return;
- }
-
- /*--------------------------------------------------*
- * static function unbuffered() *
- *--------------------------------------------------*/
-
- static struct touchxy *unbuffered( boolean *button ) {
-
- /*--------------------------------------------------*
- * Purpose: *
- * *
- * Returns an unbuffered touch point. *
- * Additionally, it sets the button *
- * flag if it is determined that the touch's *
- * distance exceeds the button's radius. *
- * *
- *--------------------------------------------------*/
-
- num_touch++;
- store_touch( ptub );
-
- if ( dist2 > radius2 ) {
-
- is_button = FALSE; /* Touch is a button. */
- }
- *button = is_button;
-
- if ( ut ) /* If untouch, reset function. */
- overflow = FALSE;
-
- return ptub;
- } /* End of file. */
-