RasMol2
|
Announce,
ChangeLog,
ChangeLog.1,
ChangeLog.2,
ChangeLog.3,
ChangeLog.4,
ChangeLog.5,
ChangeLog.6,
INSTALL,
Imakefile,
Makefile,
Makefile.bak,
Makefile.in,
Makefile.nt,
Makefile.pc,
PROJECTS,
README,
TODO,
abstree.c,
abstree.h,
abstree.o,
applemac.c,
bitmaps.h,
cexio.c,
command.c,
command.h,
command.o,
data,
doc,
font.h,
graphics.h,
infile.c,
infile.h,
infile.o,
mac,
molecule.c,
molecule.h,
molecule.o,
mswin,
mswin31.c,
outfile.c,
outfile.h,
outfile.o,
pixutils.c,
pixutils.h,
pixutils.o,
rasmac.c,
rasmol.c,
rasmol.h,
rasmol.hlp,
rasmol.o,
rasmol.sh,
raswin.c,
render.c,
render.h,
render.o,
repres.c,
repres.h,
repres.o,
script.c,
script.h,
script.o,
tokens.h,
transfor.c,
transfor.h,
transfor.o,
vms,
x11win.c,
x11win.o,
|
|
|
/* x11win.c
* RasMol2 Molecular Graphics
* Roger Sayle, August 1995
* Version 2.6
*/
#ifndef sun386
#include
#endif
#include
#include
#include
#include
#ifdef VMS
#include
#endif
#include
#include
#include
#include
#include
#define GRAPHICS
#include "rasmol.h"
#include "graphics.h"
#include "bitmaps.h"
#include "command.h"
/* Menu Definitions */
#define mbEnable 0x01
#define mbOption 0x02
#define mbCheck 0x04
#define mbSepBar 0x08
#define mbAccel 0x10
typedef struct _MenuItem {
char *text;
int flags;
int pos;
int len;
} MenuItem;
static MenuItem FilMenu[5] = {
{ "Open...", 0x11, 0, 7 },
{ "Save As...", 0x11, 0, 10 },
{ "Close", 0x11, 0, 5 },
{ "", 0x08, 0, 0 },
{ "Exit", 0x11, 0, 4 } };
static MenuItem DisMenu[8] = {
{ "Wireframe", 0x11, 0, 9 },
{ "Backbone", 0x11, 0, 8 },
{ "Sticks", 0x11, 1, 6 },
{ "Spacefill", 0x11, 0, 9 },
{ "Ball & Stick", 0x11, 0, 12 },
{ "Ribbons", 0x11, 0, 7 },
{ "Strands", 0x01, 0, 7 },
{ "Cartoons", 0x11, 0, 8 } };
static MenuItem ColMenu[8] = {
{ "Monochrome", 0x11, 0, 10 },
{ "CPK", 0x11, 0, 3 },
{ "Shapely", 0x11, 0, 7 },
{ "Group", 0x11, 0, 5 },
{ "Chain", 0x11, 1, 5 },
{ "Temperature", 0x11, 0, 11 },
{ "Structure", 0x11, 2, 9 },
{ "User", 0x11, 0, 4 } };
static MenuItem OptMenu[7] = {
{ "Slab Mode", 0x13, 0, 9 },
{ "Hydrogens", 0x17, 1, 9 },
{ "Hetero Atoms", 0x17, 2, 12 },
{ "Specular", 0x13, 1, 8 },
{ "Shadows", 0x13, 1, 7 },
{ "Stereo", 0x13, 1, 6 },
{ "Labels", 0x13, 0, 6 } };
static MenuItem ExpMenu[7] = {
{ "GIF...", 0x11, 0, 6 },
{ "PostScript...", 0x11, 0, 13 },
{ "PPM...", 0x11, 2, 6 },
{ "IRIS RGB...", 0x11, 5, 11 },
{ "Sun Raster...", 0x11, 0, 13 },
{ "BMP...", 0x11, 0, 6 },
{ "PICT...", 0x11, 1, 7 } };
static MenuItem HelMenu[2] = {
{ "About RasMol...", 0x10, 0, 15 },
{ "User Manual...", 0x10, 0, 14 } };
typedef struct _BarItem {
MenuItem *menu;
char *text;
int count;
int flags;
int len;
} BarItem;
#define MenuBarMax 6
static BarItem MenuBar[MenuBarMax] = {
{ FilMenu, "File", 5, 0x01, 4 },
{ DisMenu, "Display", 8, 0x01, 7 },
{ ColMenu, "Colours", 8, 0x01, 7 },
{ OptMenu, "Options", 7, 0x01, 7 },
{ ExpMenu, "Export", 7, 0x01, 6 },
{ HelMenu, "Help", 2, 0x01, 4 } };
static int MenuFocus;
static int ItemFocus;
static int MenuItemSelect;
static int MenuBarSelect;
static int MenuBarCount;
static int PopUpWide;
static int PopUpHigh;
static int PopUpFlag;
static int ItemFlag;
#ifdef DIALBOX
#include
static char *DialLabel[] = { "ROTATE X", "ROTATE Y", "ROTATE Z", " ZOOM ",
"TRANS X ", "TRANS Y ", "TRANS Z ", " SLAB " };
static int *DialMap;
static int ESVDialMap[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
static int SGIDialMap[8] = { 3, 7, 2, 6, 1, 5, 0, 4 };
static Real DialRes[8];
static int DialPrev[8];
static int DialMode;
static int UseDialLEDs;
static XDevice *Dials;
static int DialEvent;
static int UseDials;
#endif
#ifdef MITSHM
#include
#include
#include
#include
XShmSegmentInfo xshminfo;
int SharedMemOption;
int SharedMemFlag;
#endif
#define XScrlDial 1 /*1*/
#define YScrlDial 0 /*0*/
#define XScrlSkip 8
#define YScrlSkip 8
typedef union {
Long longword;
Byte bytes[4];
} ByteTest;
/* Determine Mouse Sensitivity! */
#define IsClose(u,v) (((u)>=(v)-1) && ((u)<=(v)+1))
static int MenuHigh;
static int FontHigh;
static Cursor cross;
static Cursor arrow;
static Cursor hglass;
static Pixmap Scrl;
static Pixmap tilepix;
static Pixmap uppix, dnpix;
static Pixmap lfpix, rgpix;
static XFontStruct *MenuFont;
static XSetWindowAttributes attr;
static Window XScrlWin, YScrlWin;
static Window PopUpWin;
static Window MainWin;
static Window CanvWin;
static Window MenuWin;
static Window RootWin;
static XWMHints hints;
static Colormap cmap;
static Colormap lmap;
static XImage *image;
static Display *dpy;
static Visual *vis;
static GC gcon;
#ifdef EIGHTBIT
static unsigned long Ident[256];
static int IdentCount;
#endif
static int InitX, InitY;
static int HeldButton;
static int HeldStep;
static Byte Intensity[LutSize];
static Pixel WhiteCol;
static Pixel BlackCol;
static int Monochrome;
#ifndef EIGHTBIT
static int SwapBytes;
#endif
static int MinWidth,MaxWidth;
static int MinHeight,MaxHeight;
static int MainWide, MainHigh;
static int ScrlX,NewScrlX;
static int ScrlY,NewScrlY;
static int PixDepth;
static int LocalMap;
/* WM_PROTOCOLS */
static char TkInterp[10];
static Atom AppNameAtom;
static Atom DelWinXAtom;
static Atom ProtoXAtom;
static Atom InterpAtom;
static Atom CommAtom;
/* Routine in rasmol.c! */
extern int ProcessCommand();
/* Forward Declarations */
static int HandleMenuLoop();
static void FatalGraphicsError(ptr)
char *ptr;
{
char buffer[80];
sprintf(buffer,"Graphics Error: %s!",ptr);
RasMolFatalExit(buffer);
}
void AllocateColourMap()
{
#ifdef EIGHTBIT
static XColor Col;
register int i,j;
if( Monochrome )
{ for( i=0; i>6);
return;
}
if( LocalMap )
{ XSetWindowColormap(dpy,MainWin,cmap);
XSetWindowColormap(dpy,CanvWin,cmap);
XUninstallColormap(dpy,lmap);
XFreeColormap(dpy,lmap);
LocalMap = False;
} else if( IdentCount )
XFreeColors(dpy,cmap,Ident,IdentCount,(long)0);
IdentCount = 0;
for( i=0; i<256; i++ )
if( ULut[i] )
{ Col.red = RLut[i]<<8 | RLut[i];
Col.green = GLut[i]<<8 | GLut[i];
Col.blue = BLut[i]<<8 | BLut[i];
Col.flags = DoRed | DoGreen | DoBlue;
if( !XAllocColor(dpy,cmap,&Col) )
break;
Ident[IdentCount++] = Col.pixel;
Lut[i] = Col.pixel;
}
if( i<256 )
{ lmap = XCopyColormapAndFree(dpy,cmap);
LocalMap = True;
for( j=0; j<5; j++ )
{ Col.red = RLut[j]<<8 | RLut[j];
Col.green = GLut[j]<<8 | GLut[j];
Col.blue = BLut[j]<<8 | BLut[j];
XAllocColor(dpy,cmap,&Col);
Lut[i] = Col.pixel;
}
for( j=i; j<256; j++ )
if( ULut[j] )
{ Col.red = RLut[j]<<8 | RLut[j];
Col.green = GLut[j]<<8 | GLut[j];
Col.blue = BLut[j]<<8 | BLut[j];
XAllocColor(dpy,lmap,&Col);
Lut[j] = Col.pixel;
}
XSetWindowColormap(dpy,MainWin,lmap);
XSetWindowColormap(dpy,CanvWin,lmap);
XInstallColormap(dpy,lmap);
}
#else
static XColor Col;
static ByteTest buf;
register Byte temp;
register int i;
for( i=0; i<256; i++ )
if( ULut[i] )
{ Col.red = RLut[i]<<8 | RLut[i];
Col.green = GLut[i]<<8 | GLut[i];
Col.blue = BLut[i]<<8 | BLut[i];
XAllocColor(dpy,cmap,&Col);
if( SwapBytes )
{ buf.longword = (Long)Col.pixel;
temp = buf.bytes[0];
buf.bytes[0] = buf.bytes[3];
buf.bytes[3] = temp;
temp = buf.bytes[1];
buf.bytes[1] = buf.bytes[2];
buf.bytes[2] = temp;
Lut[i] = buf.longword;
} else Lut[i] = (Long)Col.pixel;
}
#endif
XSetWindowBackground(dpy,CanvWin,(unsigned long)Lut[5]);
}
static void OpenCanvas( x, y )
int x, y;
{
register unsigned long mask;
mask = CWEventMask;
attr.event_mask = ExposureMask | ButtonPressMask | ButtonMotionMask
| ButtonReleaseMask;
attr.cursor = cross; mask |= CWCursor;
attr.background_pixel = Lut[0]; mask |= CWBackPixel;
CanvWin = XCreateWindow(dpy, MainWin, 14, MenuHigh+14, x, y, 0,
CopyFromParent, InputOutput, vis, mask, &attr );
}
static void OpenFonts()
{
static char *fontname[] = { "-*-helvetica-bold-o-normal-*-14-*",
"-*-serf-bold-o-normal-*-14-*",
"-*-*-bold-o-normal-*-14-*" };
register int i;
cross = XCreateFontCursor(dpy,XC_tcross);
arrow = XCreateFontCursor(dpy,XC_top_left_arrow);
for( i=0; i<3; i++ )
if( (MenuFont=XLoadQueryFont(dpy,fontname[i])) )
break;
if( !MenuFont )
FatalGraphicsError("Unable to find suitable font");
FontHigh = MenuFont->max_bounds.descent +
MenuFont->max_bounds.ascent + 1;
MenuHigh = FontHigh+6;
}
static void OpenCursors()
{
Pixmap source,mask;
XColor black,white;
white.red = 65535; black.red = 0;
white.green = 65535; black.green = 0;
white.blue = 65535; black.blue = 0;
white.flags = DoRed | DoGreen | DoBlue;
black.flags = DoRed | DoGreen | DoBlue;
source = XCreateBitmapFromData(dpy,MainWin,(char*)HGlassData,16,16);
mask = XCreateBitmapFromData(dpy,MainWin,(char*)HGlassMask,16,16);
hglass = XCreatePixmapCursor(dpy,source,mask,&black,&white,7,7);
}
static void OpenColourMap()
{
#ifdef EIGHTBIT
static XColor Col;
register int i;
if( !Monochrome )
{ Col.flags = DoRed | DoGreen | DoBlue;
for( i=0; i<5; i++ )
{ Col.red = RLut[i]<<8 | RLut[i];
Col.green = GLut[i]<<8 | GLut[i];
Col.blue = BLut[i]<<8 | BLut[i];
if( !XAllocColor(dpy,cmap,&Col) )
{ cmap = XCopyColormapAndFree(dpy,cmap);
XAllocColor(dpy,cmap,&Col);
}
Lut[i] = Col.pixel;
}
} else /* Black & White */
{ Lut[0] = BlackCol;
Lut[1] = BlackCol;
Lut[2] = WhiteCol;
Lut[3] = BlackCol;
}
LocalMap = False;
IdentCount = 0;
Lut[5]=Lut[0];
#endif
}
static int RegisterInterpName( name )
char *name;
{
static unsigned char *registry;
static unsigned long len,left;
static char buffer[32];
static int format;
static Atom type;
register int result;
register char *ptr;
registry = NULL;
result = XGetWindowProperty(dpy, RootWindow(dpy,0), InterpAtom,
0, 100000, False, XA_STRING, &type,
&format, &len, &left, ®istry );
if( (result!=Success) || (format!=8) || (type!=XA_STRING) )
{ if( (type!=None) && registry ) XFree( (char*)registry );
sprintf(buffer,"%x %s",(int)MainWin,name);
XChangeProperty( dpy, RootWindow(dpy,0), InterpAtom, XA_STRING,
8, PropModeReplace, (unsigned char*)buffer,
strlen(buffer)+1 );
return( True );
}
ptr = (char*)registry;
while( *ptr )
{ /* Skip Window ID */
while( *ptr++ != ' ' )
if( !*ptr ) break;
/* Compare Interp Name */
if( !strcmp(ptr,name) )
{ XFree( (char*)registry );
return(False);
}
while( *ptr++ );
}
XFree( (char*)registry );
sprintf(buffer,"%x %s",(int)MainWin,name);
XChangeProperty( dpy, RootWindow(dpy,0), InterpAtom, XA_STRING,
8, PropModeAppend, (unsigned char*)buffer,
strlen(buffer)+1 );
return( True );
}
static void DeRegisterInterpName( name )
char *name;
{
static unsigned char *registry;
static unsigned long len,left;
static int format;
static Atom type;
register char *src, *dst;
register int result;
registry = NULL;
result = XGetWindowProperty(dpy, RootWindow(dpy,0), InterpAtom,
0, 100000, False, XA_STRING, &type,
&format, &len, &left, ®istry );
if( type==None )
return;
if( (result!=Success) || (format!=8) || (type!=XA_STRING) )
{ XDeleteProperty( dpy, RootWindow(dpy,0), InterpAtom );
if( registry ) XFree( (char*)registry );
return;
}
dst = (char*)registry;
while( *dst )
{ /* Skip Window ID */
src = dst;
while( *src++ != ' ' )
if( !*src ) break;
/* Compare Interp Name */
if( strcmp(src,name) )
{ while( *dst++ );
} else break;
}
if( *dst )
{ /* Skip Interp Name */
while( *src++ );
/* Shuffle Registry */
while( *src )
while( (*dst++ = *src++) );
*dst = 0;
XChangeProperty( dpy, RootWindow(dpy,0), InterpAtom, XA_STRING,
8, PropModeReplace, registry, dst-(char*)registry );
}
XFree( (char*)registry );
}
static void OpenIPCComms()
{
auto char buffer[16];
register int i;
CommAtom = XInternAtom( dpy, "Comm", False );
InterpAtom = XInternAtom( dpy, "InterpRegistry", False );
AppNameAtom = XInternAtom(dpy, "TK_APPLICATION", False );
DelWinXAtom = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
/* XSetWMProtocols(dpy,MainWin,&DelWinXAtom,True); */
if( (ProtoXAtom = XInternAtom(dpy,"WM_PROTOCOLS",False)) )
XChangeProperty( dpy, MainWin, ProtoXAtom, XA_ATOM, 32,
PropModeReplace, (Byte*)&DelWinXAtom, True );
i = 0;
XGrabServer( dpy );
if( !RegisterInterpName("rasmol") )
{ strcpy(TkInterp,"rasmol #0");
for( i=1; i<10; i++ )
{ TkInterp[8] = i+'0';
if( RegisterInterpName(TkInterp) )
break;
}
if( i < 10 )
{ /* Tk4.0 and later! */
strcpy(buffer,"{rasmol #0}"); buffer[9] = i+'0';
XChangeProperty( dpy, MainWin, AppNameAtom, XA_STRING,
8, PropModeReplace, buffer, 12 );
} else *TkInterp = 0;
} else
{ XChangeProperty( dpy, MainWin, AppNameAtom, XA_STRING,
8, PropModeReplace, "rasmol", 7 );
strcpy(TkInterp,"rasmol");
}
XUngrabServer( dpy );
}
static void DrawUpBox( wdw, x1, y1, x2, y2 )
Drawable wdw; int x1,y1,x2,y2;
{
register int lx,ly,ux,uy;
lx = x1+1; ly = y1+1;
ux = x2-1; uy = y2-1;
XSetForeground(dpy,gcon,(unsigned long)Lut[3]);
XDrawLine(dpy,wdw,gcon,x1,y1,x2,y1);
XDrawLine(dpy,wdw,gcon,x1,y1,x1,y2);
XDrawLine(dpy,wdw,gcon,lx,ly,ux,ly);
XDrawLine(dpy,wdw,gcon,lx,ly,lx,uy);
XSetForeground(dpy,gcon,(unsigned long)Lut[1]);
XDrawLine(dpy,wdw,gcon,x2,y1,x2,y2);
XDrawLine(dpy,wdw,gcon,x1,y2,x2,y2);
XDrawLine(dpy,wdw,gcon,ux,ly,ux,uy);
XDrawLine(dpy,wdw,gcon,lx,uy,ux,uy);
}
static void DrawDnBox( wdw, x1, y1, x2, y2 )
Drawable wdw; int x1,y1,x2,y2;
{
register int lx,ly,ux,uy;
lx = x1+1; ly = y1+1;
ux = x2-1; uy = y2-1;
XSetForeground(dpy,gcon,(unsigned long)Lut[1]);
XDrawLine(dpy,wdw,gcon,x1,y1,x2,y1);
XDrawLine(dpy,wdw,gcon,x1,y1,x1,y2);
XDrawLine(dpy,wdw,gcon,lx,ly,ux,ly);
XDrawLine(dpy,wdw,gcon,lx,ly,lx,uy);
XSetForeground(dpy,gcon,(unsigned long)Lut[3]);
XDrawLine(dpy,wdw,gcon,x2,y1,x2,y2);
XDrawLine(dpy,wdw,gcon,x1,y2,x2,y2);
XDrawLine(dpy,wdw,gcon,ux,ly,ux,uy);
XDrawLine(dpy,wdw,gcon,lx,uy,ux,uy);
}
static void DrawNoBox( wdw, x1, y1, x2, y2 )
Drawable wdw; int x1,y1,x2,y2;
{
register int lx,ly,ux,uy;
lx = x1+1; ly = y1+1;
ux = x2-1; uy = y2-1;
XSetForeground(dpy,gcon,(unsigned long)Lut[2]);
XDrawLine(dpy,wdw,gcon,x1,y1,x2,y1);
XDrawLine(dpy,wdw,gcon,x2,y1,x2,y2);
XDrawLine(dpy,wdw,gcon,x2,y2,x1,y2);
XDrawLine(dpy,wdw,gcon,x1,y2,x1,y1);
XDrawLine(dpy,wdw,gcon,lx,ly,ux,ly);
XDrawLine(dpy,wdw,gcon,ux,ly,ux,uy);
XDrawLine(dpy,wdw,gcon,ux,uy,lx,uy);
XDrawLine(dpy,wdw,gcon,lx,uy,lx,ly);
}
static void OpenMenuBar()
{
register unsigned long mask;
mask = CWEventMask;
attr.event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask;
MenuWin = XCreateWindow( dpy, MainWin, 2, 2, XRange+49, FontHigh+5, 0,
CopyFromParent, InputOnly, vis, mask, &attr );
/* Create Unmapped PopUp Window! */
mask = CWEventMask;
attr.event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask |
KeyPressMask;
attr.background_pixel = Lut[2]; mask |= CWBackPixel;
attr.border_pixel = Lut[2]; mask |= CWBorderPixel;
attr.override_redirect = True; mask |= CWOverrideRedirect;
attr.save_under = True; mask |= CWSaveUnder;
attr.colormap = cmap; mask |= CWColormap;
PopUpWin = XCreateWindow(dpy, RootWin, 0, 0, 100, 100, 0,
PixDepth, InputOutput, vis,
mask, &attr );
MenuFocus = False;
PopUpFlag = False;
}
static void OpenScrollBars()
{
register unsigned long mask;
Scrl = XCreatePixmap( dpy, MainWin, 16, 16, PixDepth );
XSetForeground(dpy,gcon,(unsigned long)Lut[2]);
XFillRectangle(dpy,Scrl,gcon,0,0,15,15);
XSetForeground(dpy,gcon,(unsigned long)Lut[0]);
XDrawRectangle(dpy,Scrl,gcon,0,0,15,15);
DrawUpBox( Scrl, 1, 1, 14, 14 );
tilepix = XCreatePixmapFromBitmapData( dpy, MainWin, (char*)ScrlTile, 8, 8,
(unsigned long)Lut[0],
(unsigned long)Lut[2], PixDepth );
mask = CWEventMask;
attr.event_mask = ExposureMask | ButtonPressMask | ButtonMotionMask
| ButtonReleaseMask;
attr.background_pixmap = tilepix; mask |= CWBackPixmap;
XScrlWin = XCreateWindow(dpy,MainWin,14,YRange+MenuHigh+24,XRange,16,
0,CopyFromParent,InputOutput,vis,mask,&attr);
lfpix = XCreatePixmapFromBitmapData( dpy, MainWin, (char*)LfArrow, 16, 16,
(unsigned long)Lut[0],
(unsigned long)Lut[2], PixDepth );
rgpix = XCreatePixmapFromBitmapData( dpy, MainWin, (char*)RgArrow, 16, 16,
(unsigned long)Lut[0],
(unsigned long)Lut[2], PixDepth );
YScrlWin = XCreateWindow(dpy,MainWin,XRange+24,MenuHigh+14,16,YRange,
0,CopyFromParent,InputOutput,vis,mask,&attr);
uppix = XCreatePixmapFromBitmapData( dpy, MainWin, (char*)UpArrow, 16, 16,
(unsigned long)Lut[0],
(unsigned long)Lut[2], PixDepth );
dnpix = XCreatePixmapFromBitmapData( dpy, MainWin, (char*)DnArrow, 16, 16,
(unsigned long)Lut[0],
(unsigned long)Lut[2], PixDepth );
ScrlX = (XRange/2)-8;
ScrlY = (YRange/2)-8;
}
static void DrawXScroll()
{
XCopyArea(dpy,rgpix,XScrlWin,gcon,0,0,16,16,XRange-16,0);
XCopyArea(dpy,Scrl ,XScrlWin,gcon,0,0,16,16,ScrlX,0);
XCopyArea(dpy,lfpix,XScrlWin,gcon,0,0,16,16,0,0);
}
static void DrawYScroll()
{
XCopyArea(dpy,dnpix,YScrlWin,gcon,0,0,16,16,0,YRange-16);
XCopyArea(dpy,Scrl ,YScrlWin,gcon,0,0,16,16,0,ScrlY);
XCopyArea(dpy,uppix,YScrlWin,gcon,0,0,16,16,0,0);
}
void UpdateScrollBars()
{
register int temp;
temp = (DialValue[YScrlDial]+1.0)*(YRange-48);
NewScrlY = (temp>>1)+16;
if( NewScrlY != ScrlY )
{ XClearArea(dpy,YScrlWin,0,ScrlY,16,16,False);
XCopyArea(dpy,Scrl,YScrlWin,gcon,0,0,16,16,0,NewScrlY);
ReDrawFlag |= (1<>1)+16;
if( NewScrlX != ScrlX )
{ XClearArea(dpy,XScrlWin,ScrlX,0,16,16,False);
XCopyArea(dpy,Scrl,XScrlWin,gcon,0,0,16,16,NewScrlX,0);
ReDrawFlag |= (1<data;
for( i=0; inum_classes; i++ )
{ if( ptr->class == ValuatorClass )
{ if( ptr->mode & 0x01 )
{ DialMode = Absolute;
max = MinFun(ptr->num_valuators,8);
for( j=0; jvaluators[j];
} else DialMode = Relative;
break;
} else ptr = (XValuatorState*)(((char*)ptr) +
ptr->length);
}
XFreeDeviceState(stat);
}
static void OpenDialsBox()
{
register XValuatorInfo *valptr;
register XFeedbackState *list;
register XFeedbackState *feed;
register XDeviceInfo *devlist;
register XDeviceInfo *ptr;
register Atom devtype;
register int i,j,max;
static XEventClass dclass;
static int count;
UseDials = False;
/* Avoid X Server's without the extension */
if( !XQueryExtension(dpy,"XInputExtension",
&count,&count,&count) )
return;
devlist = XListInputDevices(dpy,&count);
devtype = XInternAtom(dpy,XI_KNOB_BOX,True );
if( (devtype==None) || !devlist ) return;
ptr = devlist;
for( i=0; iuse==IsXExtensionDevice) && (ptr->type==devtype) )
{ valptr = (XValuatorInfo*)ptr->inputclassinfo;
for( j=0; jnum_classes; j++ )
{ if( valptr->class == ValuatorClass )
if( (Dials=XOpenDevice(dpy,ptr->id)) )
{ UseDials = True;
break;
}
valptr = (XValuatorInfo*)(((char*)valptr) +
valptr->length);
}
if( UseDials ) break;
} else ptr++;
/* XFreeDeviceList(devlist); */
if( UseDials )
{ /* Determine Dial Mapping! */
if( !strcmp(ServerVendor(dpy),"Silicon Graphics") )
{ DialMap = SGIDialMap;
} else DialMap = ESVDialMap;
DialMode = valptr->mode;
max = MinFun(valptr->num_axes,8);
for( i=0; iaxes[i].resolution;
GetDialState();
} else return;
UseDialLEDs = 0;
feed = list = XGetFeedbackControl( dpy, Dials, &count );
for( i=0; iclass == StringFeedbackClass ) UseDialLEDs++;
feed = (XFeedbackState*)(((char*)feed) + feed->length);
}
XFreeFeedbackList( list );
if( UseDialLEDs >= 8 )
{ for( i=0; i<8; i++ )
SetDialLabel(i,DialLabel[DialMap[i]]);
} else UseDialLEDs = False;
DeviceMotionNotify( Dials, DialEvent, dclass );
XSelectExtensionEvent( dpy, MainWin, &dclass, 1 );
XSelectExtensionEvent( dpy, MenuWin, &dclass, 1 );
XSelectExtensionEvent( dpy, CanvWin, &dclass, 1 );
XSelectExtensionEvent( dpy, XScrlWin, &dclass, 1 );
XSelectExtensionEvent( dpy, YScrlWin, &dclass, 1 );
}
static void HandleDialEvent( ptr )
XDeviceMotionEvent *ptr;
{
register double temp;
register int count;
register int value;
register int index;
register int num;
/* Limit Number of Dials */
count = 8 - ptr->first_axis;
if( count > (int)ptr->axes_count )
count = (int)ptr->axes_count;
for( index=0; indexfirst_axis+index;
if( DialMode == Absolute )
{ value = ptr->axis_data[index] - DialPrev[num];
DialPrev[num] = ptr->axis_data[index];
} else value = ptr->axis_data[index];
if( value )
{ temp = (Real)value/DialRes[num];
num = DialMap[num];
temp += DialValue[num];
ReDrawFlag |= (1<1.0 ) temp -= 2.0;
} else
{ if( temp<-1.0 ) temp = -1.0;
if( temp>1.0 ) temp = 1.0;
}
DialValue[num] = temp;
if( num==YScrlDial )
{ value = (temp+1.0)*(YRange-48);
NewScrlY = (value>>1)+16;
}
if( num==XScrlDial )
{ value = (temp+1.0)*(XRange-48);
NewScrlX = (value>>1)+16;
}
}
}
}
#endif
static void DrawMainWin()
{
register int temp;
DrawUpBox(MainWin,0,0,MainWide,MainHigh);
DrawUpBox(MainWin,0,0,MainWide-2,FontHigh+7);
temp = YRange+MenuHigh;
DrawDnBox(MainWin,12,MenuHigh+12,XRange+16,temp+16);
DrawDnBox(MainWin,XRange+22,MenuHigh+12,XRange+41,temp+16);
DrawDnBox(MainWin,12,temp+22,XRange+16,temp+41);
}
/********************/
/* Menu Bar Display */
/********************/
static void DisplayMenuBarText( ptr, x, y )
BarItem *ptr; int x, y;
{
register unsigned long col;
register int under,wide;
if( ptr->flags&mbEnable && !DisableMenu )
{ col = Lut[0];
} else col = Lut[1];
XSetForeground( dpy, gcon, col );
XDrawString( dpy, MainWin, gcon, x, y, ptr->text, ptr->len );
under = y + MenuFont->descent;
wide = XTextWidth( MenuFont, ptr->text, 1 );
XDrawLine( dpy, MainWin, gcon, x, under, x+wide, under );
}
static void DrawMenuBar()
{
register BarItem *ptr;
register int wide;
register int x,y;
register int i;
x = 6; y = MenuFont->ascent+4;
XSetFont( dpy, gcon, MenuFont->fid );
for( i=0; itext, ptr->len );
if( x+wide+24 > MainWide ) break;
/* Right Justify "Help" */
if( i == MenuBarMax-1 )
x = MainWide - (wide+24);
DisplayMenuBarText( ptr, x+8, y );
if( MenuFocus && (i==MenuBarSelect) )
{ DrawUpBox( MainWin, x, 2, x+wide+16, FontHigh+5 );
} else DrawNoBox( MainWin, x, 2, x+wide+16, FontHigh+5 );
x += wide+24;
}
MenuBarCount = i;
/* XSync(dpy,False); */
XFlush(dpy);
}
/***********************/
/* Pop-up Menu Display */
/***********************/
static void DisplayPopUpText( ptr, x, y )
MenuItem *ptr; int x, y;
{
register unsigned long col;
register int pos, wide;
register int i,under;
register int index;
col = (ptr->flags&mbEnable)? Lut[0] : Lut[1];
XSetForeground( dpy, gcon, col );
XDrawString( dpy, PopUpWin, gcon, x, y, ptr->text, ptr->len );
if( ptr->flags & mbAccel )
{ under = y + MenuFont->descent;
pos = x;
for( i=0; ipos; i++ )
{ index = ptr->text[i] - MenuFont->min_char_or_byte2;
pos += MenuFont->per_char[index].width;
}
index = ptr->text[ptr->pos] - MenuFont->min_char_or_byte2;
wide = pos+MenuFont->per_char[index].rbearing;
pos += MenuFont->per_char[index].lbearing;
XDrawLine( dpy, PopUpWin, gcon, pos, under, wide, under );
}
}
static void DrawPopUpMenu()
{
register MenuItem *ptr;
register int count;
register int x,y;
register int i;
DrawUpBox(PopUpWin,0,0,PopUpWide,PopUpHigh);
ptr = MenuBar[MenuBarSelect].menu;
count = MenuBar[MenuBarSelect].count;
y = 2; x = 2;
for( i=0; iflags&mbSepBar) )
{ DisplayPopUpText( ptr, x+8, y+MenuFont->ascent+2 );
if( ItemFlag && (i==MenuItemSelect) )
{ DrawUpBox(PopUpWin,2,y,PopUpWide-2,y+FontHigh+3);
} else DrawNoBox(PopUpWin,2,y,PopUpWide-2,y+FontHigh+3);
y += FontHigh+4;
} else
{ XSetForeground( dpy, gcon, (unsigned long)Lut[1] );
XDrawLine(dpy,PopUpWin,gcon,2,y,PopUpWide-2,y);
XSetForeground( dpy, gcon, (unsigned long)Lut[3] );
XDrawLine(dpy,PopUpWin,gcon,2,y+1,PopUpWide-2,y+1);
y += 2;
}
ptr++;
}
/* XSync(dpy,False); */
XFlush(dpy);
}
static void DisplayPopUpMenu( i, x )
int i, x;
{
register int wide, count;
register MenuItem *ptr;
register int flag;
static int xpos, ypos;
static Window win;
MenuBarSelect = i;
DrawMenuBar();
ptr = MenuBar[i].menu;
count = MenuBar[i].count;
flag = False;
PopUpHigh = 4;
PopUpWide = 4;
for( i=0; iflags&mbSepBar) )
{ if( ptr->flags & mbOption ) flag = True;
wide = XTextWidth(MenuFont,ptr->text,ptr->len);
if( wide+28 > PopUpWide ) PopUpWide = wide+28;
PopUpHigh += FontHigh+4;
} else PopUpHigh += 2;
ptr++;
}
/* Determine pop-up menu position! */
XTranslateCoordinates(dpy,MainWin,RootWin,x,FontHigh+6,
&xpos, &ypos, &win );
if( ypos+PopUpHigh > MaxHeight )
ypos -= (PopUpHigh+FontHigh+6);
if( xpos+PopUpWide > MaxWidth )
xpos = MaxWidth-PopUpWide;
if( xpos < 0 ) xpos = 0;
XUnmapWindow(dpy,PopUpWin);
XMoveResizeWindow(dpy,PopUpWin,xpos,ypos,PopUpWide+1,PopUpHigh+1);
XRaiseWindow(dpy,PopUpWin);
XMapWindow(dpy,PopUpWin);
PopUpFlag = True;
DrawPopUpMenu();
}
/******************************/
/* Pop-Up Menu Event Handling */
/******************************/
static void HandleItemClick( x, y )
int x, y;
{
register MenuItem *ptr;
register int count,i;
static int xpos, ypos;
static Window win;
XTranslateCoordinates(dpy,MenuWin,PopUpWin,x,y,
&xpos,&ypos,&win);
/* Ignore by not setting ItemFocus! */
if( (xpos<0) || (xpos>PopUpWide) ) return;
if( (ypos<0) || (ypos>PopUpHigh) ) return;
ItemFocus = True;
ptr = MenuBar[MenuBarSelect].menu;
count = MenuBar[MenuBarSelect].count;
y = 2;
for( i=0; iflags&mbSepBar) )
{ if( (ypos>=y) && (ypos<=y+FontHigh+3) )
{ if( ptr->flags & mbEnable )
{ if( !ItemFlag || (MenuItemSelect!=i) )
{ /* Avoid Flickering */
MenuItemSelect = i;
ItemFlag = True;
DrawPopUpMenu();
}
return;
} else break;
}
y += FontHigh+4;
} else y += 2;
ptr++;
}
if( ItemFlag )
{ ItemFlag = False;
DrawPopUpMenu();
}
}
static void HandleItemMove( x, y )
int x, y;
{
register MenuItem *ptr;
register int count,i;
static int xpos, ypos;
static Window win;
XTranslateCoordinates(dpy,MenuWin,PopUpWin,x,y,
&xpos,&ypos,&win);
if( (xpos>=0) && (xpos<=PopUpWide) )
{ ptr = MenuBar[MenuBarSelect].menu;
count = MenuBar[MenuBarSelect].count;
y = 2;
for( i=0; iflags&mbSepBar) )
{ if( (ypos>=y) && (ypos<=y+FontHigh+3) )
{ if( !ItemFlag || (MenuItemSelect!=i) )
{ /* Avoid Flicker! */
MenuItemSelect = i;
ItemFlag = True;
DrawPopUpMenu();
}
ItemFocus = True;
return;
}
y += FontHigh+4;
} else y += 2;
ptr++;
}
}
if( ItemFlag )
{ /* Avoid Flicker! */
ItemFlag = False;
DrawPopUpMenu();
}
}
static int HandleItemKey( key )
int key;
{
register MenuItem *ptr;
register int count;
register int item;
register int ch;
register int i;
key = ToUpper( key );
item = MenuItemSelect;
ptr = &MenuBar[MenuBarSelect].menu[item];
count = MenuBar[MenuBarSelect].count;
for( i=0; iflags&(mbEnable|mbAccel)) &&
!(ptr->flags&mbSepBar) )
{ ch = ptr->text[ptr->pos];
if( ToUpper(ch) == key )
return( (MenuBarSelect<<8)+item+1 );
}
/* Advance to next item! */
if( item == count-1 )
{ ptr = MenuBar[MenuBarSelect].menu;
item = 0;
} else
{ item++;
ptr++;
}
}
return( 0 );
}
static void SelectFirstItem( menu )
int menu;
{
register MenuItem *ptr;
register int count;
register int i;
count = MenuBar[menu].count;
ptr = MenuBar[menu].menu;
ItemFlag = False;
for( i=0; iflags&mbEnable) &&
!(ptr->flags&mbSepBar) )
{ MenuItemSelect = i;
ItemFlag = True;
break;
} else ptr++;
}
static void SelectPrevItem()
{
register BarItem *ptr;
register int flags;
register int item;
register int i;
if( !ItemFlag )
return;
item = MenuItemSelect;
ptr = MenuBar + MenuBarSelect;
for( i=0; icount; i++ )
{ if( !item )
{ item = ptr->count-1;
} else item--;
flags = ptr->menu[item].flags;
if( (flags&mbEnable) && !(flags&mbSepBar) )
break;
}
if( item != MenuItemSelect )
{ MenuItemSelect = item;
DrawPopUpMenu();
}
}
static void SelectNextItem()
{
register BarItem *ptr;
register int flags;
register int item;
register int i;
if( !ItemFlag )
return;
item = MenuItemSelect;
ptr = MenuBar + MenuBarSelect;
for( i=0; icount; i++ )
{ if( item == ptr->count-1 )
{ item = 0;
} else item++;
flags = ptr->menu[item].flags;
if( (flags&mbEnable) && !(flags&mbSepBar) )
break;
}
if( item != MenuItemSelect )
{ MenuItemSelect = item;
DrawPopUpMenu();
}
}
/***************************/
/* Menu Bar Event Handling */
/***************************/
static void SelectMenu( menu )
int menu;
{
register BarItem *ptr;
register int wide;
register int i,x;
if( !PopUpFlag )
{ MenuBarSelect = menu;
DrawMenuBar();
return;
}
if( menu != MenuBarMax-1 )
{ x = 6;
for( i=0; i
|