ftp.nice.ch/pub/next/graphics/3d/geomview.1.4.1.s.tar.gz#/Geomview/src/bin/geomview/common/ui.c

This is ui.c in view mode; [Download] [Up]

/* Copyright (c) 1992 The Geometry Center; University of Minnesota
   1300 South Second Street;  Minneapolis, MN  55454, USA;
   
This file is part of geomview/OOGL. geomview/OOGL is free software;
you can redistribute it and/or modify it only under the terms given in
the file COPYING, which you should have received along with this file.
This and other related software may be obtained via anonymous ftp from
geom.umn.edu; email: software@geom.umn.edu. */

/* Authors: Stuart Levy, Tamara Munzner, Mark Phillips,
   Celeste Fowler */

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <stdlib.h>
#include "lisp.h"
#include "lang.h"
#include "drawer.h"
#include "ui.h"
#include "motion.h"
#include "event.h"
#include "comm.h"


char *shades[4] = {
	"[0as] Constant",	/* APF_CONSTANT */
	"[1as] Flat",		/* APF_FLAT */
	"[2as] Smooth",		/* APF_SMOOTH */
	"[3as] CSmooth",	/* APF_CONSMOOTH */
};

char *norm[4] = {
	"[0N] None",		/* NONE */
	"[1N] Individual",	/* EACH */
	"[2N] Sequence",	/* ALL  */
	"[3N] Keep",		/* KEEP */
};

char *proj[2] = {
	"[0vp]  Orthographic",	/* ORTHOGRAPHIC */
	"[1vp]  Perspective",	/* PERSPECTIVE */
};

char *spc[3] = {
	"[me] Euclidean",	/* EUCLIDEAN */
	"[mh] Hyperbolic",	/* HYPERBOLIC */
	"[ms] Spherical",	/* SPHERICAL */
};

char *mdl[3] = {
	"[mv] Virtual",		/* VIRTUAL */
	"[mp] Projective",	/* PROJECTIVE */
	"[mc] Conformal", 	/* CONFORMALBALL */
};


char OBJROTATE[]	=	"[r] Rotate";
char OBJTRANSLATE[]	=	"[t] Translate";
char OBJZOOM[]		=	"[z] Cam Zoom";
char OBJSCALE[]		=	"[s] Geom Scale";
char OBJFLY[]		=	"[f] Cam Fly";
char OBJORBIT[]		=	"[o] Cam Orbit";
char LIGHTEDIT[] 	=	"[le] Edit Lights";

/* in ui.c */

void cui_init()
{

  uistate.targetid = WORLDGEOM;
  uistate.centerid = TARGETID;
  uistate.targetgeom = 0; /* World geom is index 0 */
  uistate.targetcam = INDEXOF(FOCUSID);
  uistate.mode_count = 0;
  uistate.emod_dir = NULL;
  uistate.apoverride = ~0;	/* Enable override by default */
  uistate.inertia = 1;		/* Enable inertia by default */

  /*
   * The order of these calls must be the same as the declared integers
   * in ui.h!! 
   */
  ui_install_mode(OBJROTATE,	minterp_rotate,		T_NONE);
  ui_install_mode(OBJZOOM,	minterp_zoom, 		T_CAM);
  ui_install_mode(OBJTRANSLATE,	minterp_translate,	T_NONE);
  ui_install_mode(OBJFLY,	minterp_fly,		T_CAM);
  ui_install_mode(OBJORBIT,	minterp_orbit,		T_CAM);
  ui_install_mode(OBJSCALE,	minterp_scale, 		T_GEOM);
  VVINIT(uistate.emod, emodule, 10);
  vvzero(&uistate.emod);
  uistate.savewhat = NOID;
  uistate.cursor_still = UI_CURSOR_STILL; 
  uistate.cursor_twitch = UI_CURSOR_TWITCH;
  uistate.longwhile = 2.5;		/* Max credible inter-redraw interval */
  uistate.backface = 0;
  return;
}

void ui_reinstall_mode(char *name, PFI proc, int type, int index)
{
  uistate.modenames[index] = name;
  uistate.modes[index] = proc;
  uistate.modetype[index] = type;
}

void ui_install_mode(char *name, PFI proc, int type)
{
  if(uistate.mode_count >= MAXMODES) {
    OOGLError(1, "Motion-mode table full (max %d entries)", MAXMODES);
    uistate.mode_count = MAXMODES-1;
  }
  uistate.modenames[uistate.mode_count] = name;
  uistate.modes[uistate.mode_count] = proc;
  uistate.modetype[uistate.mode_count] = type;
  ++uistate.mode_count;
}

void ui_uninstall_mode(char *name)
{
  register int i = ui_mode_index(name);

  if (i<0) return;
  --uistate.mode_count;
  while (i<uistate.mode_count) {
    uistate.modenames[i] = uistate.modenames[i+1];
    uistate.modes[i] = uistate.modes[i+1];
    uistate.modetype[i] = uistate.modetype[i+1];
    i++;
  }
}

/* 
 * Match names
 */
int ui_mode_index(register char *name)
{
  register int i;

  for (i=0; i<uistate.mode_count; ++i) {
    if(!strcasecmp(name, uistate.modenames[i]))
	return i;
  }
  OOGLError(0, "ui_mode_index: unknown mode \"%s\"", name);
  return 0;
}

void ui_emodule_uninstall(int k)
{
  emodule *em;
  if(k < 0 || k >= VVCOUNT(uistate.emod))
    return;
  em = &VVEC(uistate.emod, emodule)[k];
  bcopy(em+1, em, (VVCOUNT(uistate.emod) - k - 1)*sizeof(emodule));
  VVCOUNT(uistate.emod)--;
  uistate.emod_changed = k+1;
}

emodule *
ui_emodule_install(int before, char *ename, PFI func)
{
  int i,k;
  emodule *em;

  if((k = ui_emodule_index(ename,NULL)) >= 0)
    ui_emodule_uninstall(k);
  k = VVCOUNT(uistate.emod)++;
  vvneeds(&uistate.emod, VVCOUNT(uistate.emod));
  if(before > k) before = k; else if(before < 0) before = 0;

  /* Shift the part of emodule table below the insertion point down
     one unit.  Don't use bcopy() for this because it does not
     correctly handle overlapping src and dst.
     mbp Wed Sep  9 19:07:39 1992 */
  em = VVEC(uistate.emod, emodule);
  for (i=VVCOUNT(uistate.emod)-1; i>before; --i)
    em[i] = em[i-1];

  em = &VVEC(uistate.emod, emodule)[before];
  em->name = strdup(ename);
  em->func = (PFV)func;
  em->dir =  uistate.emod_dir;
  /* Other emodule fields zeroed */
  uistate.emod_changed = before+1;
  return em;
}

LDEFINE(emodule_clear, LVOID,
	"(emodule-clear)\n\
	Clears the geomview application (external module) browser.")
{
  LDECLARE(("emodule-clear", LBEGIN,
	    LEND));

  while (VVCOUNT(uistate.emod))
    ui_emodule_uninstall(0);
  return Lt;
}

int
ui_emodule_index(char *ename, emodule **emp)
{
  int i;
  emodule *em;
  if(!emp) emp = &em;
  for (i=0, em=VVEC(uistate.emod, emodule); i<VVCOUNT(uistate.emod); i++, em++)
	if (strcasecmp(em->name, ename)==0) {
	    *emp = em;
	    return i;
	}
  *emp = NULL;
  return -1;
}

/*-----------------------------------------------------------------------
 * Function:	set_ui_target
 * Description:	set the target of user actions
 * Args:	type: T_GEOM or T_CAM
 *		index: index of current geom or current cam
 * Returns:	
 * Author:	mbp
 * Date:	Thu Nov 21 14:04:28 1991
 * Notes:	equivalent to set_ui_target_id( ID(type, index) )
 */
void
set_ui_target(int type, int index)
{
  
  switch (uistate.targettype = type) {
  case T_GEOM:  uistate.targetgeom = index; break;
  case T_CAM:	uistate.targetcam  = index; break;
  }
  uistate.targetid = ID(type, index);
}

void
set_ui_center(int id)
{
  uistate.centerid = id;
}

/*-----------------------------------------------------------------------
 * Function:	set_ui_target_id
 * Description:	set the target id of user actions
 * Args:	id: id to target
 * Returns:	
 * Author:	mbp
 * Date:	Thu Nov 21 14:05:33 1991
 * Notes:	equivalent to set_ui_target( TYPEOF(id), INDEXOF(id) )
 */
void
set_ui_target_id(int id)
{
  set_ui_target( TYPEOF(id), INDEXOF(id) );
}


void ui_cleanup()
{
  int i;
  for(i = 0; i < VVCOUNT(uistate.emod); ) {
    if(VVEC(uistate.emod, emodule)[i].pid > 0) {
	emodule_kill(&VVEC(uistate.emod, emodule)[i]);
    } else {
	i++;
    }
  }
}

/* maybe replace this later with something more useful: */
void ui_targeting()
{}


/**********************************************************************/

/* for debugging */
void print_emodtable()
{
  emodule *em;
  int i;

  for(i=0, em=VVEC(uistate.emod,emodule); i<VVCOUNT(uistate.emod); i++, em++) {
    fprintf(stderr, "em[%2d] = %s\n", i, em->name);
  }
  return;
}

LDEFINE(cursor_still, LVOID,
	"(cursor-still [INT])\n\
	Sets the number of microseconds for which the cursor must not\n\
	move to register as holding still.  If INT is not specified,\n\
	the value will be reset to the default.")
{
  uistate.cursor_still = UI_CURSOR_STILL;
  LDECLARE(("cursor-still", LBEGIN,
	    LOPTIONAL,
	    LINT, &uistate.cursor_still,
	    LEND));
  return Lt;
}

LDEFINE(cursor_twitch, LVOID,
	"(cursor-twitch	[INT])\n\
	Sets the distance which the cursor must not move (in x or\n\
	y) to register as holding still.  If INT is not specified,\n\
	the value will be reset to the default.")
{
  uistate.cursor_twitch = UI_CURSOR_TWITCH;
  LDECLARE(("cursor-twitch", LBEGIN,
	    LOPTIONAL,
	    LINT, &uistate.cursor_twitch,
	    LEND));
  return Lt;
}

LDEFINE(ap_override, LVOID,
	"(ap-override [on|off])\n\
	Selects whether appearance controls should override objects' own\n\
	settings.  On by default.  With no arguments, returns current setting.")
{
  int kw = -1;
  LDECLARE(("ap-override", LBEGIN,
	LOPTIONAL,
	LID, &kw,
	LEND));
  if(kw < 0) {
    int on = uistate.apoverride ? ON_KEYWORD : OFF_KEYWORD;
    return LNew(LKEYWORD, &on);
  }
  drawer_int(WORLDGEOM, DRAWER_APOVERRIDE, boolval("ap-override", kw));
  return Lt;
}


int
uispace(int space)
{
  switch (space) {
  case TM_EUCLIDEAN:  return EUCLIDEAN;
  case TM_HYPERBOLIC: return HYPERBOLIC;
  case TM_SPHERICAL: return SPHERICAL;
  }
  return -1;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.