/*************************************************************************** * RasMol 2.7.1 * * * * RasMol * * Molecular Graphics Visualisation Tool * * 22 June 1999 * * * * Based on RasMol 2.6 by Roger Sayle * * Biomolecular Structures Group, Glaxo Wellcome Research & Development, * * Stevenage, Hertfordshire, UK * * Version 2.6, August 1995, Version 2.6.4, December 1998 * * Copyright (C) Roger Sayle 1992-1999 * * * * and Based on Mods by Arne Mueller * * Version 2.6x1, May 1998 * * Copyright (C) Arne Mueller 1998 * * * * Version 2.7.0, 2.7.1 Mods by Herbert J. Bernstein * * Bernstein + Sons, P.O. Box 177, Bellport, NY, USA * * yaya@bernstein-plus-sons.com * * 2.7.0 March 1999, 2.7.1 June 1999 * * Copyright (C) Herbert J. Bernstein 1998-1999 * * * * Please read the file NOTICE for important notices which apply to this * * package. If you are not going to make changes to RasMol, you are not * * only permitted to freely make copies and distribute them, you are * * encouraged to do so, provided you do the following: * * * 1. Either include the complete documentation, especially the file * * NOTICE, with what you distribute or provide a clear indication * * where people can get a copy of the documentation; and * * * 2. Please give credit where credit is due citing the version and * * original authors properly; and * * * 3. Please do not give anyone the impression that the original * * authors are providing a warranty of any kind. * * * * If you would like to use major pieces of RasMol in some other program, * * make modifications to RasMol, or in some other way make what a lawyer * * would call a "derived work", you are not only permitted to do so, you * * are encouraged to do so. In addition to the things we discussed above, * * please do the following: * * * 4. Please explain in your documentation how what you did differs * * from this version of RasMol; and * * * 5. Please make your modified source code available. * * * * This version of RasMol is not in the public domain, but it is given * * freely to the community in the hopes of advancing science. If you make * * changes, please make them in a responsible manner, and please offer us * * the opportunity to include those changes in future versions of RasMol. * ***************************************************************************/ /* cmndline.c */ #include "rasmol.h" #ifdef IBMPC #include #include #endif #ifdef APPLEMAC #include #include #ifdef __CONDITIONALMACROS__ #include #else #include #endif #endif #ifndef sun386 #include #endif #include #include #include #define CMNDLINE #include "cmndline.h" #include "molecule.h" #include "command.h" #include "render.h" #include "graphics.h" /* Determine Mouse Sensitivity! */ #define IsClose(u,v) (((u)>=(v)-1) && ((u)<=(v)+1)) #define MM_NONE 0x00 #define MM_ROTX 0x01 #define MM_ROTY 0x02 #define MM_ROTZ 0x03 #define MM_TRNX 0x04 #define MM_TRNY 0x05 #define MM_ZOOM 0x06 #define MM_CLIP 0x07 #define MM_PICK 0x01 #define MM_NEXT 0x02 #define MM_LABL 0x03 #define MM_SELE 0x04 typedef struct { Byte dxfunc, dxinvrt; Byte dyfunc, dyinvrt; Byte click; } MouseMapping; /* RasMol Mouse Bindings: * XY Rotation: Left (and any other) Button * XY Translaion: Middle or Right Buttons * Scale: Shift (and Control) Left (and any other) Button * Z Rotation: Shift (and Control) Middle or Right Buttons * Clipping: Control Left (and any other) Button */ static MouseMapping MouseRasMol[32] = { { MM_NONE, 0, MM_NONE, 0, MM_PICK }, /* */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Lft */ { MM_TRNX, 0, MM_TRNY, 0, MM_PICK }, /* Mid */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Lft+Mid */ { MM_TRNX, 0, MM_TRNY, 0, MM_PICK }, /* Rgt */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Lft +Rgt */ { MM_TRNX, 0, MM_TRNY, 0, MM_PICK }, /* Mid+Rgt */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Lft+Mid+Rgt */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Sft */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft +Sft */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Mid +Sft */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft+Mid +Sft */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Rgt+Sft */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft +Rgt+Sft */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Mid+Rgt+Sft */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft+Mid+Rgt+Sft */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Ctl */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Mid +Ctl */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft+Mid +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Rgt +Ctl */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft +Rgt +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Mid+Rgt +Ctl */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft+Mid+Rgt +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Sft+Ctl */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft +Sft+Ctl */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Mid +Sft+Ctl */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft+Mid +Sft+Ctl */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Rgt+Sft+Ctl */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft +Rgt+Sft+Ctl */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Mid+Rgt+Sft+Ctl */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft+Mid+Rgt+Sft+Ctl */ }; /* MSI (Biosym) Insight Bindings: * Needs to be verified! */ static MouseMapping MouseInsight[32] = { { MM_NONE, 0, MM_NONE, 0, MM_PICK }, /* */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Lft */ { MM_TRNX, 0, MM_TRNY, 0, MM_PICK }, /* Mid */ { MM_ZOOM, 0, MM_ZOOM, 0, MM_PICK }, /* Lft+Mid */ { MM_NONE, 0, MM_NONE, 0, MM_PICK }, /* Rgt */ { MM_ROTZ, 0, MM_ROTZ, 0, MM_PICK }, /* Lft +Rgt */ { MM_NONE, 0, MM_NONE, 0, MM_PICK }, /* Mid+Rgt */ { MM_CLIP, 0, MM_CLIP, 0, MM_PICK }, /* Lft+Mid+Rgt */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Sft */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Lft +Sft */ { MM_TRNY, 0, MM_TRNY, 0, MM_NEXT }, /* Mid +Sft */ { MM_ZOOM, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft+Mid +Sft */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Rgt+Sft */ { MM_ROTZ, 0, MM_ROTZ, 0, MM_NEXT }, /* Lft +Rgt+Sft */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Mid+Rgt+Sft */ { MM_CLIP, 0, MM_CLIP, 0, MM_NEXT }, /* Lft+Mid+Rgt+Sft */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Lft +Ctl */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Mid +Ctl */ { MM_ZOOM, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft+Mid +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Rgt +Ctl */ { MM_ROTZ, 0, MM_ROTZ, 0, MM_NEXT }, /* Lft +Rgt +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Mid+Rgt +Ctl */ { MM_CLIP, 0, MM_CLIP, 0, MM_NEXT }, /* Lft+Mid+Rgt +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Sft+Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Lft +Sft+Ctl */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Mid +Sft+Ctl */ { MM_ZOOM, 0, MM_ZOOM, 0, MM_NEXT }, /* Lft+Mid +Sft+Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Rgt+Sft+Ctl */ { MM_ROTZ, 0, MM_ROTZ, 0, MM_NEXT }, /* Lft +Rgt+Sft+Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Mid+Rgt+Sft+Ctl */ { MM_CLIP, 0, MM_CLIP, 0, MM_NEXT }, /* Lft+Mid+Rgt+Sft+Ctl */ }; /* MSI Quanta Mouse Bindings: * Needs to be verified! */ static MouseMapping MouseQuanta[32] = { { MM_NONE, 0, MM_NONE, 0, MM_PICK }, /* */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Lft */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Mid */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Lft+Mid */ { MM_ROTZ, 0, MM_NONE, 0, MM_PICK }, /* Rgt */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Lft +Rgt */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Mid+Rgt */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Lft+Mid+Rgt */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Sft */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft +Sft */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Mid +Sft */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft+Mid +Sft */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Rgt+Sft */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft +Rgt+Sft */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Mid+Rgt+Sft */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft+Mid+Rgt+Sft */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Lft +Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Mid +Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Lft+Mid +Ctl */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Rgt +Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Lft +Rgt +Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Mid+Rgt +Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Lft+Mid+Rgt +Ctl */ { MM_NONE, 0, MM_ZOOM, 0, MM_NEXT }, /* Sft+Ctl */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft +Sft+Ctl */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Mid +Sft+Ctl */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft+Mid +Sft+Ctl */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Rgt+Sft+Ctl */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft +Rgt+Sft+Ctl */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Mid+Rgt+Sft+Ctl */ { MM_NONE, 0, MM_CLIP, 0, MM_NEXT }, /* Lft+Mid+Rgt+Sft+Ctl */ }; /* Tripos Sybyl 6.2 Mouse Bindings: * Tripos Graphics Manual, July 1995 * Selection: Left Button * Scale: Middle & Right Buttons * XY Rotation: Right Button * Z Rotation: Left & Right Buttons * XY Translation: Middle Button * Z Translation: Left & Middle Buttons */ static MouseMapping MouseSybyl[32] = { { MM_NONE, 0, MM_NONE, 0, MM_PICK }, /* */ { MM_NONE, 0, MM_NONE, 0, MM_PICK }, /* Lft */ { MM_TRNX, 0, MM_TRNY, 0, MM_PICK }, /* Mid */ { MM_NONE, 0, MM_NONE, 0, MM_PICK }, /* Lft+Mid */ { MM_ROTY, 0, MM_ROTX, 0, MM_PICK }, /* Rgt */ { MM_ROTZ, 0, MM_NONE, 0, MM_PICK }, /* Lft +Rgt */ { MM_ZOOM, 0, MM_ZOOM, 0, MM_PICK }, /* Mid+Rgt */ { MM_NONE, 0, MM_NONE, 0, MM_PICK }, /* Lft+Mid+Rgt */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Sft */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Lft +Sft */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Mid +Sft */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Lft+Mid +Sft */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Rgt+Sft */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Lft +Rgt+Sft */ { MM_ZOOM, 0, MM_ZOOM, 0, MM_NEXT }, /* Mid+Rgt+Sft */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Lft+Mid+Rgt+Sft */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Lft +Ctl */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Mid +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Lft+Mid +Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Rgt +Ctl */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Lft +Rgt +Ctl */ { MM_ZOOM, 0, MM_ZOOM, 0, MM_NEXT }, /* Mid+Rgt +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Lft+Mid+Rgt +Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Sft+Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Lft +Sft+Ctl */ { MM_TRNX, 0, MM_TRNY, 0, MM_NEXT }, /* Mid +Sft+Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Lft+Mid +Sft+Ctl */ { MM_ROTY, 0, MM_ROTX, 0, MM_NEXT }, /* Rgt+Sft+Ctl */ { MM_ROTZ, 0, MM_NONE, 0, MM_NEXT }, /* Lft +Rgt+Sft+Ctl */ { MM_ZOOM, 0, MM_ZOOM, 0, MM_NEXT }, /* Mid+Rgt+Sft+Ctl */ { MM_NONE, 0, MM_NONE, 0, MM_NEXT }, /* Lft+Mid+Rgt+Sft+Ctl */ }; #define HISTSIZE 4096 #define HISTMASK 4095 static char HistBuff[HISTSIZE]; static int MinHist,MaxHist; static int CurHist; static char *CurPrompt; static int CurPos,MaxPos; static MouseMapping *MouseBinding; static int PointX,PointY; static int InitX,InitY; static int HeldButton; static void UpdateLine( void ) { register int i; for( i=CurPos; iCurPos; i-- ) WriteChar(0x08); } static void CopyHistory( void ) { register int i; for( i=CurPos; i>0; i-- ) WriteChar(0x08); for( i=0; i=' ') && (ch<='~') ) { if( MaxPosCurPos; i-- ) CurLine[i] = CurLine[i-1]; CurLine[CurPos++] = ch; CurLine[++MaxPos] = 0; WriteChar(ch); if( CurPos0 ) { for( i=CurPos; i<=MaxPos; i++ ) CurLine[i-1] = CurLine[i]; CurPos--; MaxPos--; WriteChar(0x08); UpdateLine(); } break; case( 0x04 ): if( CurPos0 ) /* ^B */ { WriteChar(0x08); CurPos--; } break; case( 0x06 ): if( CurPos0 ) /* ^A */ { WriteChar(0x08); CurPos--; } break; case( 0x05 ): while( CurPos 1.0 ) { DialValue[dial] = 1.0; } else if( temp < -1.0 ) { DialValue[dial] = -1.0; } else DialValue[dial] = temp; } static void WrapDial( int dial, Real value ) { register Real temp; temp = DialValue[dial] + value; while( temp < -1.0 ) temp += 2.0; while( temp > 1.0 ) temp -= 2.0; DialValue[dial] = temp; } void ProcessMouseDown( int x, int y, int stat ) { register MouseMapping *map; map = &MouseBinding[stat]; if( map->dxfunc || map->dyfunc ) SetMouseCaptureStatus(True); InitX = PointX = x; InitY = PointY = y; HeldButton = True; } void ProcessMouseUp( int x, int y, int stat ) { register MouseMapping *map; map = &MouseBinding[stat]; if( map->dxfunc || map->dyfunc ) SetMouseCaptureStatus(False); if( !HeldButton ) return; HeldButton = False; if( Database && IsClose(x,InitX) && IsClose(y,InitY) ) { switch( map->click ) { case(MM_PICK): if( PickAtom(False,x,y) ) { AdviseUpdate(AdvPickNumber); AdviseUpdate(AdvPickAtom); AdviseUpdate(AdvPickCoord); } break; case(MM_NEXT): if( PickAtom(True,x,y) ) { AdviseUpdate(AdvPickNumber); AdviseUpdate(AdvPickAtom); AdviseUpdate(AdvPickCoord); } break; } } } static int BindingActive( int stat ) { return( MouseBinding[stat].dxfunc || MouseBinding[stat].dyfunc ); } void SetMouseMode( int mode ) { register int stat; switch( mode ) { case(MMRasMol): MouseBinding = MouseRasMol; break; case(MMInsight): MouseBinding = MouseInsight; break; case(MMQuanta): MouseBinding = MouseQuanta; break; case(MMSybyl): MouseBinding = MouseSybyl; break; } /* Should also test for BindingActive(MMSft|MMCtl)! */ stat = BindingActive(MMSft) || BindingActive(MMCtl); SetMouseUpdateStatus(stat); } static void PerformMouseFunc( int func, int delta, int max ) { switch( func ) { case(MM_ROTX): WrapDial( 0, (Real)(2*delta)/max ); ReDrawFlag |= RFRotateX; break; case(MM_ROTY): WrapDial( 1, (Real)(2*delta)/max ); ReDrawFlag |= RFRotateY; break; case(MM_ROTZ): WrapDial( 2, (Real)(2*delta)/max ); ReDrawFlag |= RFRotateZ; break; case(MM_ZOOM): ClampDial( 3, (Real)(2*delta)/max ); ReDrawFlag |= RFZoom; break; case(MM_TRNX): ClampDial( 4, (Real)delta/max ); ReDrawFlag |= RFTransX; break; case(MM_TRNY): ClampDial( 5, (Real)delta/max ); ReDrawFlag |= RFTransY; break; case(MM_CLIP): ClampDial( 7, (Real)delta/max ); ReDrawFlag |= RFSlab; break; } } void ProcessMouseMove( int x, int y, int stat ) { register MouseMapping *map; register int dx,dy; map = &MouseBinding[stat]; if( map->dxfunc || map->dyfunc ) { SetMouseCaptureStatus(True); if( !HeldButton ) { InitX = PointX = x; InitY = PointY = y; HeldButton = True; return; } if( IsClose(x,InitX) && IsClose(y,InitY) ) return; if( map->dxinvrt ) { dx = PointX - x; } else dx = x - PointX; if( map->dyinvrt ) { dy = PointY - y; } else dy = y - PointY; if( dx ) PerformMouseFunc(map->dxfunc,dx,XRange); if( dy ) PerformMouseFunc(map->dyfunc,dy,YRange); if( ReDrawFlag & (RFRotateX|RFRotateY) ) UpdateScrollBars(); PointX = x; PointY = y; } else { SetMouseCaptureStatus(False); HeldButton = False; } } void InitialiseCmndLine( void ) { MaxHist = MinHist = 1; HistBuff[0] = 0; CommandActive = False; SetMouseMode(MMRasMol); HeldButton = False; }