open-axiom repository from github
/*1Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.2All rights reserved.3Copyright (C) 2007-2011, Gabriel Dos Reis.4All rights reserved.56Redistribution and use in source and binary forms, with or without7modification, are permitted provided that the following conditions are8met:910- Redistributions of source code must retain the above copyright11notice, this list of conditions and the following disclaimer.1213- Redistributions in binary form must reproduce the above copyright14notice, this list of conditions and the following disclaimer in15the documentation and/or other materials provided with the16distribution.1718- Neither the name of The Numerical Algorithms Group Ltd. nor the19names of its contributors may be used to endorse or promote products20derived from this software without specific prior written permission.2122THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS23IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED24TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A25PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER26OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,27EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,28PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR29PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF30LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING31NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS32SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.33*/3435#define _PROCESS3D_C36#include "openaxiom-c-macros.h"3738#include <string.h>39#include <stdlib.h>40#include <unistd.h>41#include <stdio.h>42#include <sys/types.h>43#include <sys/time.h>444546#include "cfuns.h"47#include "header.h"48#include "cpanel.h"49#include "volume.h"50#include "mode.h"51#include "process.h"52#include "draw.h"53#include "sockio.h"54#include "com.h"55#include "util.H1"56#include "Gfun.H1"57#include "pixmap.h"58#include "XShade.h"59#include "XSpadFill.h"60#include "all_3d.H1"6162#define inside(A,B) (((XButtonEvent *)event)->x >= A && \63((XButtonEvent *)event)->x <= B)646566void67buttonAction (int bKey)68{6970const char* s1;71const char* s2;72int strL, strL1, strL2, offShade=14;7374/* Button colors which are offColor, RED, are turned off, and those which75are onColor, GREEN, indicate the mode is in effect. */7677switch (bKey) {7879case hideControl:80if (viewport->haveControl) {81viewport->haveControl = no;82XUnmapWindow(dsply,control->controlWindow);83}84break;8586case region3D:87clearControlMessage();88strcpy(control->message,viewport->title);89writeControlMessage();90if (viewport->regionOn) {91viewport->regionOn = no;92(control->buttonQueue[region3D]).textColor = offColor;93viewData.box = 0;94if (mono) {95XChangeShade(dsply,offShade);96XShadeRectangle(dsply,control->controlWindow,97(control->buttonQueue[region3D]).buttonX,98(control->buttonQueue[region3D]).buttonY,99(control->buttonQueue[region3D]).buttonWidth,100(control->buttonQueue[region3D]).buttonHeight);101GSetForeground(globalGC1,(float)foregroundColor,Xoption);102GDrawRectangle(globalGC1, control->controlWindow,103(control->buttonQueue[region3D]).buttonX,104(control->buttonQueue[region3D]).buttonY,105(control->buttonQueue[region3D]).buttonWidth,106(control->buttonQueue[region3D]).buttonHeight,Xoption);107}108} else { /* inverted color for region off */109viewport->regionOn = yes;110viewData.box = 1;111(control->buttonQueue[region3D]).textColor = onColor;112if (mono) {113GSetForeground(globalGC1,(float)backgroundColor,Xoption);114XFillRectangle(dsply, control->controlWindow, globalGC1,115(control->buttonQueue[region3D]).buttonX,116(control->buttonQueue[region3D]).buttonY,117(control->buttonQueue[region3D]).buttonWidth,118(control->buttonQueue[region3D]).buttonHeight);119GSetForeground(globalGC1,(float)foregroundColor,Xoption);120GDrawRectangle(globalGC1, control->controlWindow,121(control->buttonQueue[region3D]).buttonX,122(control->buttonQueue[region3D]).buttonY,123(control->buttonQueue[region3D]).buttonWidth,124(control->buttonQueue[region3D]).buttonHeight,Xoption);125}126}127128s = (control->buttonQueue[region3D]).text;129strL = strlen(s);130131GSetForeground(processGC,132(float)monoColor((control->buttonQueue[region3D]).textColor),Xoption);133GDrawImageString(processGC,control->controlWindow,134(control->buttonQueue[region3D]).buttonX +135centerX(processGC,s,strL,136(control->buttonQueue[region3D]).buttonWidth),137(control->buttonQueue[region3D]).buttonY +138centerY(processGC,139(control->buttonQueue[region3D]).buttonHeight),140s,strL,Xoption);141redoSmooth = yes;142drawViewport(Xoption);143break;144145146147case bwColor:148clearControlMessage();149strcpy(control->message,viewport->title);150writeControlMessage();151if (!mono) {152if (viewport->monoOn) {153viewport->monoOn = no;154if (viewport->hueTop == viewport->hueOffset) redoColor = yes;155else redoDither = yes;156(control->buttonQueue[bwColor]).textColor = offColor;157(control->buttonQueue[bwColor]).text = "BW";158} else {159viewport->monoOn = yes;160maxGreyShade = XInitShades(dsply,scrn);161if (viewport->hueTop == viewport->hueOffset) redoColor = yes;162else redoDither = yes;163(control->buttonQueue[bwColor]).textColor = onColor;164(control->buttonQueue[bwColor]).text = "BW";165GSetForeground(globalGC1,(float)backgroundColor,Xoption);166XFillRectangle(dsply, control->controlWindow, globalGC1,167(control->buttonQueue[bwColor]).buttonX,168(control->buttonQueue[bwColor]).buttonY,169(control->buttonQueue[bwColor]).buttonWidth,170(control->buttonQueue[bwColor]).buttonHeight);171GSetForeground(globalGC1,(float)monoColor(buttonColor),Xoption);172GDrawRectangle(globalGC1, control->controlWindow,173(control->buttonQueue[bwColor]).buttonX,174(control->buttonQueue[bwColor]).buttonY,175(control->buttonQueue[bwColor]).buttonWidth,176(control->buttonQueue[bwColor]).buttonHeight,Xoption);177}178179s = (control->buttonQueue[bwColor]).text;180strL = strlen(s);181182GSetForeground(processGC,183(float)monoColor((control->buttonQueue[bwColor]).textColor),Xoption);184GDrawImageString(processGC,control->controlWindow,185(control->buttonQueue[bwColor]).buttonX +186centerX(processGC,s,strL,187(control->buttonQueue[bwColor]).buttonWidth),188(control->buttonQueue[bwColor]).buttonY +189centerY(processGC,190(control->buttonQueue[bwColor]).buttonHeight),191s,strL,Xoption);192drawColorMap();193redoSmooth = yes;194writeTitle();195drawViewport(Xoption);196}197break;198199200201case outlineOnOff:202clearControlMessage();203strcpy(control->message,viewport->title);204writeControlMessage();205if (viewData.outlineRenderOn) {206viewData.outlineRenderOn = 0;207(control->buttonQueue[outlineOnOff]).textColor = offColor;208if (mono) {209XChangeShade(dsply,offShade);210XShadeRectangle(dsply,control->controlWindow,211(control->buttonQueue[outlineOnOff]).buttonX,212(control->buttonQueue[outlineOnOff]).buttonY,213(control->buttonQueue[outlineOnOff]).buttonWidth,214(control->buttonQueue[outlineOnOff]).buttonHeight);215GSetForeground(globalGC1,(float)foregroundColor,Xoption);216GDrawRectangle(globalGC1, control->controlWindow,217(control->buttonQueue[outlineOnOff]).buttonX,218(control->buttonQueue[outlineOnOff]).buttonY,219(control->buttonQueue[outlineOnOff]).buttonWidth,220(control->buttonQueue[outlineOnOff]).buttonHeight,Xoption);221}222} else {223viewData.outlineRenderOn = 1;224(control->buttonQueue[outlineOnOff]).textColor = onColor;225if (mono) {226GSetForeground(globalGC1,(float)backgroundColor,Xoption);227XFillRectangle(dsply, control->controlWindow, globalGC1,228(control->buttonQueue[outlineOnOff]).buttonX,229(control->buttonQueue[outlineOnOff]).buttonY,230(control->buttonQueue[outlineOnOff]).buttonWidth,231(control->buttonQueue[outlineOnOff]).buttonHeight);232GSetForeground(globalGC1,(float)foregroundColor,Xoption);233GDrawRectangle(globalGC1, control->controlWindow,234(control->buttonQueue[outlineOnOff]).buttonX,235(control->buttonQueue[outlineOnOff]).buttonY,236(control->buttonQueue[outlineOnOff]).buttonWidth,237(control->buttonQueue[outlineOnOff]).buttonHeight,Xoption);238}239}240s = (control->buttonQueue[outlineOnOff]).text;241strL = strlen(s);242243GSetForeground(processGC,244(float)monoColor((control->buttonQueue[outlineOnOff]).textColor),Xoption);245GDrawImageString(processGC,control->controlWindow,246(control->buttonQueue[outlineOnOff]).buttonX +247centerX(processGC,s,strL,248(control->buttonQueue[outlineOnOff]).buttonWidth),249(control->buttonQueue[outlineOnOff]).buttonY +250centerY(processGC,251(control->buttonQueue[outlineOnOff]).buttonHeight),252s,strL,Xoption);253if (viewData.style == render) {254drawViewport(Xoption);255}256break;257258259case lighting:260if (saveFlag) {261doingPanel = CONTROLpanel;262XUnmapWindow(dsply,saveWindow);263}264doingPanel = LIGHTpanel;265tempLightPointer[0] = viewport->lightVector[0];266tempLightPointer[1] = viewport->lightVector[1];267tempLightPointer[2] = viewport->lightVector[2];268tempLightIntensity = lightIntensity;269XMapWindow(dsply,lightingWindow);270break;271272273case viewVolume:274if (saveFlag) {275doingPanel = CONTROLpanel;276XUnmapWindow(dsply,saveWindow);277}278doingPanel = VOLUMEpanel;279XMapWindow(dsply,volumeWindow);280redrawView = yes;281drawViewport(Xoption); /* draw it with doingVolume set to yes */282break;283284285case volumeReturn:286doingPanel = CONTROLpanel;287redoSmooth = yes;288redrawView = yes;289XUnmapWindow(dsply,volumeWindow);290break;291292293case volumeAbort:294doingPanel = CONTROLpanel;295redrawView = yes;296XUnmapWindow(dsply,volumeWindow);297break;298299300case lightReturn:301doingPanel = CONTROLpanel;302viewport->lightVector[0] = lightPointer[0] = tempLightPointer[0];303viewport->lightVector[1] = lightPointer[1] = tempLightPointer[1];304viewport->lightVector[2] = lightPointer[2] = tempLightPointer[2];305lightIntensity = tempLightIntensity;306normalizeVector(viewport->lightVector);307redrawView = ((viewData.style == render) || (viewData.style == smooth));308if (movingLight || changedIntensity) redoSmooth = yes;309XUnmapWindow(dsply,lightingWindow);310break;311312313case lightAbort:314movingLight = no; changedIntensity = no;315doingPanel = CONTROLpanel;316XUnmapWindow(dsply,lightingWindow);317break;318319320case resetView:321clearControlMessage();322strcpy(control->message,viewport->title);323writeControlMessage();324viewport->axesOn = yes;325viewport->regionOn = no; viewData.box = 0;326viewData.outlineRenderOn = 0;327viewport->monoOn = no;328viewport->zoomXOn = viewport->zoomYOn = viewport->zoomZOn = yes;329viewport->originrOn = yes; viewport->objectrOn = no;330viewport->originFlag = no;331viewport->xyOn = viewport->xzOn = viewport->yzOn = no;332viewport->lightVector[0] = -0.5;333viewport->lightVector[1] = 0.5;334viewport->lightVector[2] = 0.5;335viewport->translucency = viewData.translucency;336viewport->deltaX = viewport->deltaX0;337viewport->deltaY = viewport->deltaY0;338viewport->deltaY = viewport->deltaZ0;339viewport->scale = viewport->scale0;340viewport->scaleX = viewport->scaleY = viewport->scaleZ = 1.0;341if (!equal(viewport->theta,viewport->theta0) || !equal(viewport->phi,viewport->phi0))342rotated = yes;343viewport->theta = viewport->axestheta = viewport->theta0 = viewData.theta;344viewport->phi = viewport->axesphi = viewport->phi0 = viewData.phi;345viewport->thetaObj = 0.0;346viewport->phiObj = 0.0;347redoSmooth = yes;348drawViewport(Xoption);349if (viewport->haveControl) drawControlPanel();350writeTitle();351break;352353354case axesOnOff:355clearControlMessage();356strcpy(control->message,viewport->title);357writeControlMessage();358if (viewport->axesOn) {359viewport->axesOn = no;360(control->buttonQueue[axesOnOff]).textColor = offColor;361if (mono) {362XChangeShade(dsply,offShade);363XShadeRectangle(dsply,control->controlWindow,364(control->buttonQueue[axesOnOff]).buttonX,365(control->buttonQueue[axesOnOff]).buttonY,366(control->buttonQueue[axesOnOff]).buttonWidth,367(control->buttonQueue[axesOnOff]).buttonHeight);368GSetForeground(globalGC1,(float)foregroundColor,Xoption);369GDrawRectangle(globalGC1, control->controlWindow,370(control->buttonQueue[axesOnOff]).buttonX,371(control->buttonQueue[axesOnOff]).buttonY,372(control->buttonQueue[axesOnOff]).buttonWidth,373(control->buttonQueue[axesOnOff]).buttonHeight,Xoption);374}375} else { /* draw invert-color button */376viewport->axesOn = yes;377(control->buttonQueue[axesOnOff]).textColor = onColor;378if (mono) {379GSetForeground(globalGC1,(float)backgroundColor,Xoption);380XFillRectangle(dsply, control->controlWindow, globalGC1,381(control->buttonQueue[axesOnOff]).buttonX,382(control->buttonQueue[axesOnOff]).buttonY,383(control->buttonQueue[axesOnOff]).buttonWidth,384(control->buttonQueue[axesOnOff]).buttonHeight);385GSetForeground(globalGC1,(float)foregroundColor,Xoption);386GDrawRectangle(globalGC1, control->controlWindow,387(control->buttonQueue[axesOnOff]).buttonX,388(control->buttonQueue[axesOnOff]).buttonY,389(control->buttonQueue[axesOnOff]).buttonWidth,390(control->buttonQueue[axesOnOff]).buttonHeight,Xoption);391}392}393394s = (control->buttonQueue[axesOnOff]).text;395strL = strlen(s);396397GSetForeground(processGC,398(float)monoColor((control->buttonQueue[axesOnOff]).textColor),Xoption);399GDrawImageString(processGC,control->controlWindow,400(control->buttonQueue[axesOnOff]).buttonX +401centerX(processGC,s,strL,402(control->buttonQueue[axesOnOff]).buttonWidth),403(control->buttonQueue[axesOnOff]).buttonY +404centerY(processGC,405(control->buttonQueue[axesOnOff]).buttonHeight),406s,strL,Xoption);407if (viewData.style == smooth) {408if (multiColorFlag) redoDither = yes;409else redoColor = yes;410}411drawViewport(Xoption);412break;413414415case zoomx:416if (viewport->zoomXOn) {417viewport->zoomXOn = no;418(control->buttonQueue[zoomx]).textColor = offColor;419if (mono) {420XChangeShade(dsply,offShade);421XShadeRectangle(dsply,control->controlWindow,422(control->buttonQueue[zoomx]).buttonX,423(control->buttonQueue[zoomx]).buttonY,424(control->buttonQueue[zoomx]).buttonWidth,425(control->buttonQueue[zoomx]).buttonHeight);426GSetForeground(globalGC1,(float)foregroundColor,Xoption);427GDrawRectangle(globalGC1, control->controlWindow,428(control->buttonQueue[zoomx]).buttonX,429(control->buttonQueue[zoomx]).buttonY,430(control->buttonQueue[zoomx]).buttonWidth,431(control->buttonQueue[zoomx]).buttonHeight,Xoption);432}433} else {434viewport->zoomXOn = yes;435(control->buttonQueue[zoomx]).textColor = onColor;436if (mono) {437GSetForeground(globalGC1,(float)backgroundColor,Xoption);438XFillRectangle(dsply, control->controlWindow, globalGC1,439(control->buttonQueue[zoomx]).buttonX,440(control->buttonQueue[zoomx]).buttonY,441(control->buttonQueue[zoomx]).buttonWidth,442(control->buttonQueue[zoomx]).buttonHeight);443GSetForeground(globalGC1,(float)foregroundColor,Xoption);444GDrawRectangle(globalGC1, control->controlWindow,445(control->buttonQueue[zoomx]).buttonX,446(control->buttonQueue[zoomx]).buttonY,447(control->buttonQueue[zoomx]).buttonWidth,448(control->buttonQueue[zoomx]).buttonHeight,Xoption);449}450}451452s = (control->buttonQueue[zoomx]).text;453strL = strlen(s);454455GSetForeground(processGC,456(float)monoColor((control->buttonQueue[zoomx]).textColor),Xoption);457GDrawImageString(processGC,control->controlWindow,458(control->buttonQueue[zoomx]).buttonX +459centerX(processGC,s,strL,460(control->buttonQueue[zoomx]).buttonWidth),461(control->buttonQueue[zoomx]).buttonY +462centerY(processGC,463(control->buttonQueue[zoomx]).buttonHeight),464s,strL,Xoption);465clearControlMessage();466strcpy(control->message,viewport->title);467writeControlMessage();468break;469470471case zoomy:472if (viewport->zoomYOn) {473viewport->zoomYOn = no;474(control->buttonQueue[zoomy]).textColor = offColor;475if (mono) {476XChangeShade(dsply,offShade);477XShadeRectangle(dsply,control->controlWindow,478(control->buttonQueue[zoomy]).buttonX,479(control->buttonQueue[zoomy]).buttonY,480(control->buttonQueue[zoomy]).buttonWidth,481(control->buttonQueue[zoomy]).buttonHeight);482GSetForeground(globalGC1,(float)foregroundColor,Xoption);483GDrawRectangle(globalGC1, control->controlWindow,484(control->buttonQueue[zoomy]).buttonX,485(control->buttonQueue[zoomy]).buttonY,486(control->buttonQueue[zoomy]).buttonWidth,487(control->buttonQueue[zoomy]).buttonHeight,Xoption);488}489} else {490viewport->zoomYOn = yes;491(control->buttonQueue[zoomy]).textColor = onColor;492if (mono) {493GSetForeground(globalGC1,(float)backgroundColor,Xoption);494XFillRectangle(dsply, control->controlWindow, globalGC1,495(control->buttonQueue[zoomy]).buttonX,496(control->buttonQueue[zoomy]).buttonY,497(control->buttonQueue[zoomy]).buttonWidth,498(control->buttonQueue[zoomy]).buttonHeight);499GSetForeground(globalGC1,(float)foregroundColor,Xoption);500GDrawRectangle(globalGC1, control->controlWindow,501(control->buttonQueue[zoomy]).buttonX,502(control->buttonQueue[zoomy]).buttonY,503(control->buttonQueue[zoomy]).buttonWidth,504(control->buttonQueue[zoomy]).buttonHeight,Xoption);505}506}507508s = (control->buttonQueue[zoomy]).text;509strL = strlen(s);510511GSetForeground(processGC,512(float)monoColor((control->buttonQueue[zoomy]).textColor),Xoption);513GDrawImageString(processGC,control->controlWindow,514(control->buttonQueue[zoomy]).buttonX +515centerX(processGC,s,strL,516(control->buttonQueue[zoomy]).buttonWidth),517(control->buttonQueue[zoomy]).buttonY +518centerY(processGC,519(control->buttonQueue[zoomy]).buttonHeight),520s,strL,Xoption);521clearControlMessage();522strcpy(control->message,viewport->title);523writeControlMessage();524break;525526527case zoomz:528if (viewport->zoomZOn) {529viewport->zoomZOn = no;530(control->buttonQueue[zoomz]).textColor = offColor;531if (mono) {532XChangeShade(dsply,offShade);533XShadeRectangle(dsply,control->controlWindow,534(control->buttonQueue[zoomz]).buttonX,535(control->buttonQueue[zoomz]).buttonY,536(control->buttonQueue[zoomz]).buttonWidth,537(control->buttonQueue[zoomz]).buttonHeight);538GSetForeground(globalGC1,(float)foregroundColor,Xoption);539GDrawRectangle(globalGC1, control->controlWindow,540(control->buttonQueue[zoomz]).buttonX,541(control->buttonQueue[zoomz]).buttonY,542(control->buttonQueue[zoomz]).buttonWidth,543(control->buttonQueue[zoomz]).buttonHeight,Xoption);544}545} else {546viewport->zoomZOn = yes;547(control->buttonQueue[zoomz]).textColor = onColor;548if (mono) {549GSetForeground(globalGC1,(float)backgroundColor,Xoption);550XFillRectangle(dsply, control->controlWindow, globalGC1,551(control->buttonQueue[zoomz]).buttonX,552(control->buttonQueue[zoomz]).buttonY,553(control->buttonQueue[zoomz]).buttonWidth,554(control->buttonQueue[zoomz]).buttonHeight);555GSetForeground(globalGC1,(float)foregroundColor,Xoption);556GDrawRectangle(globalGC1, control->controlWindow,557(control->buttonQueue[zoomz]).buttonX,558(control->buttonQueue[zoomz]).buttonY,559(control->buttonQueue[zoomz]).buttonWidth,560(control->buttonQueue[zoomz]).buttonHeight,Xoption);561}562}563564s = (control->buttonQueue[zoomz]).text;565strL = strlen(s);566567GSetForeground(processGC,568(float)monoColor((control->buttonQueue[zoomz]).textColor),Xoption);569GDrawImageString(processGC,control->controlWindow,570(control->buttonQueue[zoomz]).buttonX +571centerX(processGC,s,strL,572(control->buttonQueue[zoomz]).buttonWidth),573(control->buttonQueue[zoomz]).buttonY +574centerY(processGC,575(control->buttonQueue[zoomz]).buttonHeight),576s,strL,Xoption);577clearControlMessage();578strcpy(control->message,viewport->title);579writeControlMessage();580break;581582583case originr:584viewport->originrOn = yes;585(control->buttonQueue[originr]).textColor = onColor;586viewport->objectrOn = no;587(control->buttonQueue[objectr]).textColor = offColor;588viewport->originFlag = yes;589if (mono) {590XChangeShade(dsply,offShade);591XShadeRectangle(dsply,control->controlWindow,592(control->buttonQueue[objectr]).buttonX,593(control->buttonQueue[objectr]).buttonY,594(control->buttonQueue[objectr]).buttonWidth,595(control->buttonQueue[objectr]).buttonHeight);596GSetForeground(globalGC1,(float)foregroundColor,Xoption);597GDrawRectangle(globalGC1, control->controlWindow,598(control->buttonQueue[objectr]).buttonX,599(control->buttonQueue[objectr]).buttonY,600(control->buttonQueue[objectr]).buttonWidth,601(control->buttonQueue[objectr]).buttonHeight,Xoption);602GSetForeground(globalGC1,(float)backgroundColor,Xoption);603XFillRectangle(dsply, control->controlWindow, globalGC1,604(control->buttonQueue[originr]).buttonX,605(control->buttonQueue[originr]).buttonY,606(control->buttonQueue[originr]).buttonWidth,607(control->buttonQueue[originr]).buttonHeight);608GSetForeground(globalGC1,(float)foregroundColor,Xoption);609GDrawRectangle(globalGC1, control->controlWindow,610(control->buttonQueue[originr]).buttonX,611(control->buttonQueue[originr]).buttonY,612(control->buttonQueue[originr]).buttonWidth,613(control->buttonQueue[originr]).buttonHeight,Xoption);614}615s1 = (control->buttonQueue[objectr]).text;616strL1 = strlen(s1);617s2 = (control->buttonQueue[originr]).text;618strL2 = strlen(s2);619620GSetForeground(processGC,621(float)monoColor((control->buttonQueue[objectr]).textColor),Xoption);622GDrawImageString(processGC,control->controlWindow,623(control->buttonQueue[objectr]).buttonX +624centerX(processGC,s1,strL1,625(control->buttonQueue[objectr]).buttonWidth),626(control->buttonQueue[objectr]).buttonY +627centerY(processGC,628(control->buttonQueue[objectr]).buttonHeight),629s1,strL1,Xoption);630631GSetForeground(processGC,632(float)monoColor((control->buttonQueue[originr]).textColor),Xoption);633GDrawImageString(processGC,control->controlWindow,634(control->buttonQueue[originr]).buttonX +635centerX(processGC,s2,strL2,636(control->buttonQueue[originr]).buttonWidth),637(control->buttonQueue[originr]).buttonY +638centerY(processGC,639(control->buttonQueue[originr]).buttonHeight),640s2,strL2,Xoption);641clearControlMessage();642strcpy(control->message,viewport->title);643writeControlMessage();644break;645646647648case objectr:649viewport->objectrOn = yes;650(control->buttonQueue[objectr]).textColor = onColor;651viewport->originrOn = no;652(control->buttonQueue[originr]).textColor = offColor;653654viewport->originFlag = no;655if (mono) {656XChangeShade(dsply,offShade);657XShadeRectangle(dsply,control->controlWindow,658(control->buttonQueue[originr]).buttonX,659(control->buttonQueue[originr]).buttonY,660(control->buttonQueue[originr]).buttonWidth,661(control->buttonQueue[originr]).buttonHeight);662GSetForeground(globalGC1,(float)foregroundColor,Xoption);663GDrawRectangle(globalGC1, control->controlWindow,664(control->buttonQueue[originr]).buttonX,665(control->buttonQueue[originr]).buttonY,666(control->buttonQueue[originr]).buttonWidth,667(control->buttonQueue[originr]).buttonHeight,Xoption);668GSetForeground(globalGC1,(float)backgroundColor,Xoption);669XFillRectangle(dsply, control->controlWindow, globalGC1,670(control->buttonQueue[objectr]).buttonX,671(control->buttonQueue[objectr]).buttonY,672(control->buttonQueue[objectr]).buttonWidth,673(control->buttonQueue[objectr]).buttonHeight);674GSetForeground(globalGC1,(float)foregroundColor,Xoption);675GDrawRectangle(globalGC1, control->controlWindow,676(control->buttonQueue[objectr]).buttonX,677(control->buttonQueue[objectr]).buttonY,678(control->buttonQueue[objectr]).buttonWidth,679(control->buttonQueue[objectr]).buttonHeight,Xoption);680}681s1 = (control->buttonQueue[objectr]).text;682strL1 = strlen(s1);683s2 = (control->buttonQueue[originr]).text;684strL2 = strlen(s2);685686GSetForeground(processGC,687(float)monoColor((control->buttonQueue[objectr]).textColor),Xoption);688GDrawImageString(processGC,control->controlWindow,689(control->buttonQueue[objectr]).buttonX +690centerX(processGC,s1,strL1,691(control->buttonQueue[objectr]).buttonWidth),692(control->buttonQueue[objectr]).buttonY +693centerY(processGC,694(control->buttonQueue[objectr]).buttonHeight),695s1,strL1,Xoption);696697GSetForeground(processGC,698(float)monoColor((control->buttonQueue[originr]).textColor),Xoption);699GDrawImageString(processGC,control->controlWindow,700(control->buttonQueue[originr]).buttonX +701centerX(processGC,s2,strL2,702(control->buttonQueue[originr]).buttonWidth),703(control->buttonQueue[originr]).buttonY +704centerY(processGC,705(control->buttonQueue[originr]).buttonHeight),706s2,strL2,Xoption);707clearControlMessage();708strcpy(control->message,viewport->title);709writeControlMessage();710break;711712713714case ps:715strcpy(control->message," Creating postscript file ... ");716writeControlMessage();717if (PSInit(viewport->viewWindow, viewport->titleWindow) == psError) {718strcpy(control->message," Aborted: PSInit error. ");719writeControlMessage();720return; /* make new tmpnam for new file */721}722723redoSmooth = yes;724drawViewport(PSoption); /* draw picture in PS; create ps script file */725726if (PSCreateFile(viewBorderWidth, viewport->viewWindow,727viewport->titleWindow, viewport->title) == psError) {728strcpy(control->message," Aborted: PSCreateFile error. ");729writeControlMessage();730return;731}732733clearControlMessage();734strcpy(control->message,PSfilename);735strcat(control->message," in working dir ");736writeControlMessage();737break;738739740741case pixmap:742strcpy(control->message," Creating axiom3D.xpm now ... ");743writeControlMessage();744XGetWindowAttributes(dsply,viewport->viewWindow,&vwInfo);745write_pixmap_file(dsply,scrn,"axiom3D.xpm",746viewport->titleWindow,0,0,vwInfo.width,747vwInfo.height+titleHeight);748clearControlMessage();749strcpy(control->message," axiom3D.xpm in working dir ");750writeControlMessage();751break;752753754755case transparent:756case opaqueMesh:757case render:758case smooth:759clearControlMessage();760strcpy(control->message,viewport->title);761writeControlMessage();762viewData.style = bKey;763drawViewport(Xoption); /* draw picture in viewWindow with X routines */764break;765766767case closeAll:768clearControlMessage();769strcpy(control->message,viewport->title);770writeControlMessage();771doingPanel = QUITpanel;772viewport->closing = yes;773XMapWindow(dsply,quitWindow);774break;775776777case quitReturn:778XUnmapWindow(dsply,quitWindow);779break;780781782case quitAbort:783doingPanel = CONTROLpanel;784XUnmapWindow(dsply,quitWindow);785break;786787788case saveit:789clearControlMessage();790strcpy(control->message,viewport->title);791writeControlMessage();792saveFlag = yes;793doingPanel = SAVEpanel;794XMapWindow(dsply,saveWindow);795break;796797798case saveExit:799saveFlag = no;800doingPanel = CONTROLpanel;801XUnmapWindow(dsply,saveWindow);802break;803804805case xy:806viewport->theta = pi;807viewport->phi = 0.0;808viewport->axestheta = pi;809viewport->axesphi = 0.0;810rotated = yes;811viewport->yzOn = viewport->xzOn = no;812viewport->xyOn = yes;813drawViewport(Xoption);814break;815816817case xz:818viewport->theta = pi;819viewport->phi = -pi_half;820viewport->axestheta = pi;821viewport->axesphi = -pi_half;822rotated = yes;823viewport->yzOn = viewport->xyOn = no;824viewport->xzOn = yes;825drawViewport(Xoption);826break;827828829case yz:830viewport->theta = pi_half;831viewport->phi = -pi_half;832viewport->axestheta = pi_half;833viewport->axesphi = -pi_half;834rotated = yes;835viewport->xzOn = viewport->xyOn = no;836viewport->yzOn = yes;837drawViewport(Xoption);838break;839840841default:842fprintf(stderr,"Received a non-functioning button request: %d \n",bKey);843break;844} /* switch (action) */845846} /* processEvents() */847848849850/************************** X Event Processing *****************************/851void852processEvents(void)853{854855XEvent *event, tempEvent;856Window whichWindow;857buttonStruct *controlButton;858mouseCoord mouseXY, linearMouseXY;859int someInt, mouseW4, mouseH4;860int toggleReady =yes;861int checkButton = no;862int first_time = yes;863int changingColor = yes;864int gotEvent = 0, exposeView = no;865int tempTW, tempTH, tempVW, tempVH;866int buttonTablePtr;867float f1, f2;868int px, py, lx, ly;869unsigned int lbuttons;870Window dummy;871int Xcon,externalControl,len;872fd_set rd;873874externalControl = 0;875Xcon = ConnectionNumber(dsply);876877/** assign lightPointer for light panel **/878lightPointer[0] = tempLightPointer[0] = viewport->lightVector[0];879lightPointer[1] = tempLightPointer[1] = viewport->lightVector[1];880lightPointer[2] = tempLightPointer[2] = viewport->lightVector[2];881882if (!(event = (XEvent *)saymem("process.c",1,sizeof(XEvent)))) {883fprintf(stderr,"Ran out of memory initializing event processing.\n");884exitWithAck(RootWindow(dsply,scrn),Window,-1);885}886887controlButton = 0;888889while(1) {890891/* Store old viewport window size attributes for resizing comparison. */892XGetWindowAttributes(dsply,viewport->titleWindow,&graphWindowAttrib);893tempTW = graphWindowAttrib.width;894tempTH = graphWindowAttrib.height;895XGetWindowAttributes(dsply,viewport->viewWindow,&graphWindowAttrib);896tempVW = graphWindowAttrib.width;897tempVH = graphWindowAttrib.height;898899/* Get the next X event. The check for pending events is so that900a held down mouse button is interpreted as an event901even if nothing is pending. */902903len=0;904while(len<=0) {905FD_ZERO(&rd);906if (externalControl==0) FD_SET(0, &rd);907FD_SET(Xcon,&rd);908909if (XEventsQueued(dsply, QueuedAlready)) {910len=1;911break;912}913if (!followMouse)914len=select(FD_SETSIZE, &rd,0,0,0);915else916len=1;917}918919if (FD_ISSET(Xcon,&rd)||920XEventsQueued(dsply, QueuedAfterFlush) ||921followMouse) {922923if (followMouse) {924if (XPending(dsply))925XNextEvent(dsply,event);926gotEvent++;927} else {928XNextEvent(dsply,event);929gotEvent++;930}931932if (gotToggle || !followMouse)933checkButton = no;934935if (gotEvent) {936whichWindow = ((XButtonEvent *)event)->window;937first_time = no;938939switch(((XEvent *)event)->type) {940case ClientMessage:941if (event->xclient.data.l[0] == wm_delete_window) {942goodbye(-1);943}944else {945fprintf(stderr,"Unknown Client Message ...\n");946}947break;948case Expose:949if (whichWindow == viewport->titleWindow) {950exposeView = yes;951followMouse = no;952XSync(dsply,0);953/* get rid of redundant exposure events */954XCheckWindowEvent(dsply,viewport->titleWindow,955ExposureMask,&tempEvent);956writeTitle();957XGetWindowAttributes(dsply,viewport->titleWindow,958&graphWindowAttrib);959if ((graphWindowAttrib.width!=tempTW) ||960((graphWindowAttrib.height)!=tempTH)) {961XResizeWindow(dsply,viewport->viewWindow,962graphWindowAttrib.width, graphWindowAttrib.height);963redoSmooth = yes; /* recompute smooth image pixmap if resized */964}965} else if (whichWindow == viewport->viewWindow) {966exposeView = yes;967followMouse = no;968XSync(dsply,0);969XCheckWindowEvent(dsply,viewport->viewWindow,ExposureMask,970&tempEvent);971XGetWindowAttributes(dsply,viewport->viewWindow,&graphWindowAttrib);972if ((graphWindowAttrib.width!=tempVW) ||973((graphWindowAttrib.height)!=tempVH)) {974XResizeWindow(dsply,viewport->viewWindow,graphWindowAttrib.width,975graphWindowAttrib.height);976redoSmooth = yes; /* recompute smooth image pixmap if resized */977}978drawViewport(Xoption);979XMapWindow(dsply,whichWindow);980} else if (whichWindow == lightingWindow) {981XGetWindowAttributes(dsply,control->controlWindow,982&graphWindowAttrib);983/* do not allow resizing of control panel */984if ((graphWindowAttrib.width!=controlWidth) ||985(graphWindowAttrib.height!=controlHeight)) {986XResizeWindow(dsply,control->controlWindow,controlWidth,987controlHeight);988}989drawLightingPanel();990} else if (whichWindow == volumeWindow) {991XGetWindowAttributes(dsply,control->controlWindow,992&graphWindowAttrib);993/* do not allow resizing of control panel */994if ((graphWindowAttrib.width!=controlWidth) ||995(graphWindowAttrib.height!=controlHeight)) {996XResizeWindow(dsply,control->controlWindow,controlWidth,997controlHeight);998}999drawVolumePanel();1000if (redrawView) {1001redrawView = no;1002drawViewport(Xoption);1003}1004} else if (whichWindow == quitWindow) {1005XGetWindowAttributes(dsply,control->controlWindow,1006&graphWindowAttrib);1007/* do not allow resizing of control panel */1008if ((graphWindowAttrib.width!=controlWidth) ||1009(graphWindowAttrib.height!=controlHeight)) {1010XResizeWindow(dsply,control->controlWindow,controlWidth,1011controlHeight);1012}1013drawQuitPanel();1014} else if (whichWindow == saveWindow) {1015XGetWindowAttributes(dsply,control->controlWindow,1016&graphWindowAttrib);1017/* do not allow resizing of control panel */1018if ((graphWindowAttrib.width!=controlWidth) ||1019(graphWindowAttrib.height!=controlHeight)) {1020XResizeWindow(dsply,control->controlWindow,controlWidth,1021controlHeight);1022}1023drawSavePanel();1024} else if (whichWindow == control->controlWindow) {1025XGetWindowAttributes(dsply,control->controlWindow,1026&graphWindowAttrib);1027/* do not allow resizing of control panel */1028if ((graphWindowAttrib.width != controlWidth) ||1029(graphWindowAttrib.height != controlHeight)) {1030XResizeWindow(dsply,control->controlWindow,1031controlWidth,controlHeight);1032}1033if (viewport->haveControl) drawControlPanel();1034followMouse = no;1035if (redrawView || exposeView) {1036redrawView = no;1037drawViewport(Xoption);1038}1039exposeView = no;1040} else {1041fprintf(stderr,"Not a valid window.\n");1042}10431044XFlush(dsply);1045while(XCheckTypedWindowEvent(dsply, whichWindow, Expose, &tempEvent));1046break;104710481049case MotionNotify:1050exposeView = no;1051if (followMouse) {1052if (whichWindow == control->colormapWindow) {1053while (XCheckMaskEvent(dsply,ButtonMotionMask,event));1054first_time = checkButton = followMouse = changingColor = yes;1055gotToggle = no;1056} else if (whichWindow != control->controlWindow) {1057if (controlButton->pot) {1058while (XCheckMaskEvent(dsply,ButtonMotionMask,event));1059mouseXY = getPotValue(((XButtonEvent *)event)->x,1060((XButtonEvent *)event)->y,1061controlButton->xHalf,1062controlButton->yHalf);1063linearMouseXY = getLinearPotValue(((XButtonEvent *)event)->x,1064((XButtonEvent *)event)->y,1065controlButton->xHalf,1066controlButton->yHalf);1067first_time = checkButton = followMouse = yes;1068gotToggle = no;1069}1070}1071}1072break;10731074case ButtonRelease:1075exposeView = followMouse = no;1076toggleReady = yes; gotToggle = yes;1077break;10781079case LeaveNotify:1080XQueryPointer(dsply,rtWindow,&dummy,&dummy,&px,&py,&lx,&ly,&lbuttons);1081if ( (controlButton) &&1082((whichWindow == control->colormapWindow) ||1083(controlButton->pot)) &&1084(lbuttons & Button1Mask ||1085lbuttons & Button2Mask ||1086lbuttons & Button3Mask)) {1087followMouse = yes;1088if (whichWindow == control->colormapWindow)1089changingColor = yes;1090}1091else {1092followMouse = no;1093changingColor = no;1094}1095toggleReady = yes;1096checkButton = exposeView = no;1097break;10981099case ButtonPress:1100exposeView = no; changingColor = no;1101if (whichWindow == viewport->viewWindow) {1102/* find out where the mouse button is pressed on the viewport,1103this determines where to put the control panel */1104XGetWindowAttributes(dsply,whichWindow,&graphWindowAttrib);1105mouseW4 = graphWindowAttrib.width/4;1106if (((XButtonEvent *)event)->x > (graphWindowAttrib.width-mouseW4))1107someInt = 1;1108else {1109mouseH4 = graphWindowAttrib.height/4;1110if (((XButtonEvent *)event)->y >1111(graphWindowAttrib.height - mouseH4)) someInt = 2;1112else if (((XButtonEvent *)event)->x < mouseW4) someInt = 3;1113else if (((XButtonEvent *)event)->y < mouseH4) someInt = 4;1114else someInt = 0;1115}1116if (viewport->haveControl) {1117XUnmapWindow(dsply,control->controlWindow);1118}1119putControlPanelSomewhere(someInt);1120writeControlMessage();1121XSync(dsply,0);1122} else if (whichWindow == control->colormapWindow) {1123gotToggle = no;1124first_time = checkButton = followMouse = changingColor = yes;1125} else if (whichWindow != control->controlWindow) {1126/* mouse clicked on one of the buttons */1127if (!controlButton || (controlButton->self != whichWindow)) {1128buttonTablePtr = *((int *)XLookUpAssoc(dsply,table,whichWindow));1129/** lighting buttons have indices greater than 100 **/1130/** all buttons share the same array now **/1131controlButton = &(control->buttonQueue[buttonTablePtr]);1132}1133if (controlButton->pot) {1134/* figure out [x,y] for this button in the range [-1..1,-1..1] */1135mouseXY = getPotValue(((XButtonEvent *)event)->x,1136((XButtonEvent *)event)->y,1137controlButton->xHalf,controlButton->yHalf);1138linearMouseXY = getLinearPotValue(((XButtonEvent *)event)->x,1139((XButtonEvent *)event)->y,1140controlButton->xHalf,1141controlButton->yHalf);1142followMouse = yes;1143gotToggle = no;1144} else {1145followMouse = no;1146gotToggle = yes; /* auto-repeat of toggle buttons not allowed */1147if (toggleReady) toggleReady = no;1148}1149checkButton = yes;1150first_time = yes;1151}1152break;11531154default:1155toggleReady = gotToggle = yes;1156exposeView = changingColor = checkButton = followMouse = no;1157break;11581159} /* switch */1160gotEvent--;1161} /* if gotEvent */11621163/* Allow a pressed mouse button on a potentiometer to poll repeatedly. */1164if (followMouse && !first_time && (followMouse++ > mouseWait)) {1165/* reset for next timing loop */1166followMouse = yes;1167checkButton = yes;1168}1169if (checkButton) {1170if (viewport->closing && (controlButton->buttonKey == quitReturn)) {1171goodbye(-1);1172} else if (changingColor) {1173viewport->closing = no;1174/* moving top color map pointer */1175if (((XButtonEvent *)event)->y < colorOffsetY) {1176if (((XButtonEvent *)event)->x < (colorOffset+colorWidth)) {1177/* decreasing top hue number */1178if (viewport->hueTop > 0) viewport->hueTop--;1179} else if (((XButtonEvent *)event)->x >=1180(colorOffsetX + totalHues*colorWidth + colorWidth)) {1181if (viewport->hueTop < totalHues) viewport->hueTop++;1182} else {1183viewport->hueTop =1184(((XButtonEvent *)event)->x -1185colorOffsetX + colorWidth/2 - 13) / colorWidth;1186}1187} else if (((XButtonEvent *)event)->y >1188(colorOffsetY + colorHeight)) {1189/* moving bottom color map pointer */1190if (((XButtonEvent *)event)->x < (colorOffset+colorWidth)) {1191/* decreasing offset number */1192if (viewport->hueOffset > 0) viewport->hueOffset--;1193} else if (((XButtonEvent *)event)->x >=1194(colorOffsetX + totalHues*colorWidth + colorWidth)) {1195if (viewport->hueOffset < totalHues) viewport->hueOffset++;1196} else {1197viewport->hueOffset =1198(((XButtonEvent *)event)->x -1199colorOffsetX + colorWidth/2 - 13) / colorWidth;1200}1201}1202/* color map pointer does not wrap around */1203if (viewport->hueOffset < 0) viewport->hueOffset = 0;1204if (viewport->hueTop < 0) viewport->hueTop = 0;1205if (viewport->hueOffset >= totalHues)1206viewport->hueOffset = totalHues-1;1207if (viewport->hueTop >= totalHues) viewport->hueTop = totalHues-1;1208viewport->numberOfHues = viewport->hueTop - viewport->hueOffset;1209if ((viewport->hueTop == viewport->hueOffset) && !viewport->monoOn) {1210redoColor = yes;1211redoDither = no;1212} else {1213redoColor = no;1214redoDither = yes;1215}1216/* update color map changes on control panel */1217drawColorMap();1218} else {1219viewport->closing = no;1220clearControlMessage();1221/* reset all the things that might affect a recalculation for1222redrawing removing hidden surfaces */12231224/* determine what type of button has been pressed */1225switch(controlButton->buttonKey) {12261227/*** Potentiometers ***/1228case rotate:1229if (!((viewport->originrOn) && (viewport->objectrOn))) {1230/* update the amount of rotation around the object center1231of volume */1232if (viewport->objectrOn) {1233viewport->thetaObj += mouseXY.x * rotateFactor;1234viewport->phiObj -= mouseXY.y * rotateFactor;1235while (viewport->thetaObj >= two_pi) {1236viewport->thetaObj -= two_pi;1237}1238while (viewport->thetaObj < 0.0) {1239viewport->thetaObj += two_pi;1240}1241while (viewport->phiObj > pi) {1242viewport->phiObj -= two_pi;1243}1244while (viewport->phiObj <= -pi) {1245viewport->phiObj += two_pi;1246}1247}1248/* update amount of rotation around the world space origin */1249if (viewport->originrOn) {1250viewport->theta += mouseXY.x * rotateFactor;1251viewport->phi -= mouseXY.y * rotateFactor;1252while (viewport->theta >= two_pi) {1253viewport->theta -= two_pi;1254}1255while (viewport->theta < 0.0) {1256viewport->theta += two_pi;1257}1258while (viewport->phi > pi) {1259viewport->phi -= two_pi;1260}1261while (viewport->phi <= -pi) {1262viewport->phi += two_pi;1263}1264viewport->axestheta += mouseXY.x * rotateFactor;1265viewport->axesphi -= mouseXY.y * rotateFactor;1266while (viewport->axestheta >= two_pi) {1267viewport->axestheta -= two_pi;1268}1269while (viewport->axestheta < 0.0) {1270viewport->axestheta += two_pi;1271}1272while (viewport->axesphi > pi) {1273viewport->axesphi -= two_pi;1274}1275while (viewport->axesphi <= -pi) {1276viewport->axesphi += two_pi;1277}1278}1279rotated = yes;1280viewport->yzOn = viewport->xzOn = viewport->xyOn = no;1281clearControlMessage();1282strcpy(control->message,viewport->title);1283writeControlMessage();1284drawViewport(Xoption);1285}1286break;12871288case zoom:1289/* if uniform scaling */1290if ((viewport->zoomXOn) &&1291(viewport->zoomYOn) &&1292(viewport->zoomZOn)) {1293viewport->scale *= 1 - mouseXY.y * scaleFactor;1294} else { /* else scale axes independently */1295if (viewport->zoomXOn) viewport->scaleX *= (1 - mouseXY.y);1296if (viewport->zoomYOn) viewport->scaleY *= (1 - mouseXY.y);1297if (viewport->zoomZOn) viewport->scaleZ *= (1 - mouseXY.y);1298}1299if (viewport->scale > maxScale) viewport->scale = maxScale;1300else if (viewport->scale < minScale) viewport->scale = minScale;1301if (viewport->scaleX > maxScale) viewport->scaleX = maxScale;1302else if (viewport->scaleX < minScale) viewport->scaleX = minScale;1303if (viewport->scaleY > maxScale) viewport->scaleY = maxScale;1304else if (viewport->scaleY < minScale) viewport->scaleY = minScale;1305if (viewport->scaleZ > maxScale) viewport->scaleZ = maxScale;1306else if (viewport->scaleZ < minScale) viewport->scaleZ = minScale;1307zoomed = yes;1308clearControlMessage();1309strcpy(control->message,viewport->title);1310writeControlMessage();1311if ((viewport->zoomXOn) ||1312(viewport->zoomYOn) ||1313(viewport->zoomZOn))1314drawViewport(Xoption);1315break;13161317case translate:1318viewport->deltaX += mouseXY.x * translateFactor;1319viewport->deltaY += mouseXY.y * translateFactor;1320if (viewport->deltaX > maxDeltaX) viewport->deltaX = maxDeltaX;1321else if (viewport->deltaX < -maxDeltaX) viewport->deltaX = -maxDeltaX;13221323if (viewport->deltaY > maxDeltaY) viewport->deltaY = maxDeltaY;1324else if (viewport->deltaY < -maxDeltaY) viewport->deltaY = -maxDeltaY;1325translated = yes;1326clearControlMessage();1327strcpy(control->message,viewport->title);1328writeControlMessage();1329drawViewport(Xoption);1330break;13311332/*** Lighting panel ***/1333case lightMoveXY:1334tempLightPointer[0] = linearMouseXY.x;1335tempLightPointer[1] = linearMouseXY.y;1336if (tempLightPointer[0] > 1) tempLightPointer[0] = 1;1337else if (tempLightPointer[0] < -1) tempLightPointer[0] = -1;1338if (tempLightPointer[1] > 1) tempLightPointer[1] = 1;1339else if (tempLightPointer[1] < -1) tempLightPointer[1] = -1;1340movingLight = yes;1341drawLightingAxes();1342break;13431344case lightMoveZ:1345tempLightPointer[2] = linearMouseXY.y;1346/* linearMouse => no checking necessary */1347if (tempLightPointer[2] > 1) tempLightPointer[2] = 1;1348else if (tempLightPointer[2] < -1) tempLightPointer[2] = -1;1349movingLight = yes;1350drawLightingAxes();1351break;13521353/* changes the light intensity */1354case lightTranslucent:1355tempLightIntensity = (linearMouseXY.y+1)/2;1356if (tempLightIntensity > 1) tempLightIntensity = 1;1357else if (tempLightIntensity < 0) tempLightIntensity = 0;1358changedIntensity = yes;1359drawLightTransArrow();1360break;13611362/*** volume panel ***/1363case frustrumBut:1364screenX = ((XButtonEvent *)event)->x;1365if inside(eyeMinX,eyeMaxX) {1366/* object coordinate */1367f2 = mouseXY.x * (maxEyeDistance - minEyeDistance) +1368minEyeDistance;1369if (f2 != viewData.eyeDistance) {1370doingVolume = 2; /* flag for using screenX */1371changedEyeDistance = yes;1372viewData.eyeDistance = f2;1373drawFrustrum();1374drawViewport(Xoption);1375}1376}1377else if inside(hitherMinX,hitherMaxX) {1378f1 = ((float)hitherMaxX - ((XButtonEvent *)event)->x) /1379(hitherMaxX - hitherMinX);1380/* object coordinate */1381f2 = f1 * (clipPlaneMax - clipPlaneMin) + clipPlaneMin;1382if (f2 != viewData.clipPlane) {1383doingVolume = 3; /* flag for using screenX */1384viewData.clipPlane = f2;1385drawFrustrum();1386drawViewport(Xoption);1387}1388}1389else {1390doingVolume = 1; /* check out doingVolume */1391doingPanel = VOLUMEpanel;1392}1393break;13941395case clipXBut: /* this is a horizontal button */1396clipValue = linearMouseXY.x * 0.5 + 0.5; /* normalize to 0..1 */1397if (lessThan(clipValue,0.0)) clipValue = 0.0;1398if (greaterThan(clipValue,1.0)) clipValue = 1.0;1399if (lessThan(linearMouseXY.y,0.0)) {1400if (!equal(xClipMinN,clipValue)) {1401if (greaterThan(xClipMaxN-clipValue,minDistXY))1402xClipMinN = clipValue;1403else1404xClipMinN = xClipMaxN - minDistXY;1405viewData.clipXmin = xClipMinN *1406(viewData.xmax - viewData.xmin) +1407viewData.xmin;1408drawClipXBut();1409drawClipVolume();1410if (viewData.clipbox)1411drawViewport(Xoption);1412}1413} else {1414if (!equal(xClipMaxN,clipValue)) {1415if (greaterThan(clipValue-xClipMinN,minDistXY))1416xClipMaxN = clipValue;1417else1418xClipMaxN = xClipMinN + minDistXY;1419viewData.clipXmax = xClipMaxN *1420(viewData.xmax - viewData.xmin) +1421viewData.xmin;1422drawClipXBut();1423drawClipVolume();1424if (viewData.clipbox)1425drawViewport(Xoption);1426}1427}1428break;14291430case clipYBut: /* this is a vertical button */1431/* normalize to 0..1, bottom up */1432clipValue = 1 - (linearMouseXY.y * 0.5 + 0.5);1433if (lessThan(clipValue,0.0)) clipValue = 0.0;1434if (greaterThan(clipValue,1.0)) clipValue = 1.0;1435if (lessThan(linearMouseXY.x,0.0)) {1436if (!equal(yClipMinN,clipValue)) {1437if (greaterThan(yClipMaxN-clipValue,minDistXY))1438yClipMinN = clipValue;1439else1440yClipMinN = yClipMaxN - minDistXY;1441viewData.clipYmin = yClipMinN *1442(viewData.ymax - viewData.ymin) +1443viewData.ymin;1444drawClipYBut();1445drawClipVolume();1446if (viewData.clipbox)1447drawViewport(Xoption);1448}1449} else {1450if (!equal(yClipMaxN,clipValue)) {1451if (greaterThan(clipValue-yClipMinN,minDistXY))1452yClipMaxN = clipValue;1453else1454yClipMaxN = yClipMinN + minDistXY;1455viewData.clipYmax = yClipMaxN *1456(viewData.ymax - viewData.ymin) +1457viewData.ymin;1458drawClipYBut();1459drawClipVolume();1460if (viewData.clipbox)1461drawViewport(Xoption);1462}1463}1464break;14651466case clipZBut: /* this is a diagonally aligned button! */1467/* f1 is the distance from the center of the button along1468the diagonal line with a slope of -1. If f1 is negative,1469the direction is downward from the center, if f1 is1470positive, the direction is upward from the center.1471Note that there ought to be a constant factor, namely1472cos(45), multiplied by f1 for the correct normalized value;1473however, we exploit this by foreshortening the length of the1474diagonal by that same factor (so instead of normalizing the1475numbers to, the line we normalize the line to the numbers)1476since we need to shorten the line at some point anyway1477(both to match the length of the diagonal side of the box1478and to allow more area for mouse input. */14791480/* cos(45), etc => 0.4 */1481f1 = (linearMouseXY.x - linearMouseXY.y) * 0.4 + 0.5;1482if (lessThan(f1,0.0)) f1 = 0.0;1483if (greaterThan(f1,1.0)) f1 = 1.0;1484/* note that x<y => moving upward */1485if (lessThan(-linearMouseXY.x,linearMouseXY.y)) {1486if (!equal(zClipMaxN,f1)) {1487if (greaterThan(f1-zClipMinN,minDistZ))1488zClipMaxN = f1;1489else1490zClipMaxN = zClipMinN + minDistZ;1491viewData.clipZmax = zClipMaxN *1492(viewData.zmax - viewData.zmin) +1493viewData.zmin;1494drawClipZBut();1495drawClipVolume();1496if (viewData.clipbox)1497drawViewport(Xoption);1498}1499} else {1500if (!equal(zClipMinN,f1)) {1501if (greaterThan(zClipMaxN-f1,minDistZ))1502zClipMinN = f1;1503else1504zClipMinN = zClipMaxN - minDistZ;1505viewData.clipZmin = zClipMinN *1506(viewData.zmax - viewData.zmin) +1507viewData.zmin;1508drawClipZBut();1509drawClipVolume();1510if (viewData.clipbox)1511drawViewport(Xoption);1512}1513} /* if lessThan(x,y) */1514break;15151516case perspectiveBut:1517if ((viewData.perspective = !viewData.perspective)) {1518switchedPerspective = yes;1519GSetForeground(volumeGC,1520(float)monoColor((control->buttonQueue[perspectiveBut]).textColor),Xoption);1521GDrawString(volumeGC,volumeWindow,1522controlButton->buttonX +1523centerX(volumeGC,"x",1,controlButton->buttonWidth),1524controlButton->buttonY +1525centerY(volumeGC,controlButton->buttonHeight),1526"x",1,Xoption);1527}1528else1529XClearArea(dsply,volumeWindow,1530controlButton->buttonX+1,1531controlButton->buttonY+1,1532controlButton->buttonHeight-2,1533controlButton->buttonWidth-2,1534False);1535drawViewport(Xoption);1536break;15371538case clipRegionBut:1539if ((viewData.clipbox = !viewData.clipbox)) {1540GSetForeground(volumeGC,1541(float)monoColor((control->buttonQueue[clipRegionBut]).textColor),Xoption);1542GDrawString(volumeGC,volumeWindow,1543controlButton->buttonX +1544centerX(volumeGC,"x",1,controlButton->buttonWidth),1545controlButton->buttonY +1546centerY(volumeGC,controlButton->buttonHeight),1547"x",1,Xoption);1548}1549else1550XClearArea(dsply,volumeWindow,1551controlButton->buttonX+1,1552controlButton->buttonY+1,1553controlButton->buttonWidth-2,1554controlButton->buttonHeight-2,1555False);15561557drawViewport(Xoption);1558break;15591560case clipSurfaceBut:1561if ((viewData.clipStuff = !viewData.clipStuff)) {1562GSetForeground(volumeGC,1563(float)monoColor((control->buttonQueue[clipSurfaceBut]).textColor),Xoption);1564GDrawString(volumeGC,volumeWindow,1565controlButton->buttonX +1566centerX(volumeGC,"x",1,controlButton->buttonWidth),1567controlButton->buttonY +1568centerY(volumeGC,controlButton->buttonHeight),1569"x",1,Xoption);1570}1571else1572XClearArea(dsply,volumeWindow,1573controlButton->buttonX+1,1574controlButton->buttonY+1,1575controlButton->buttonWidth-2,1576controlButton->buttonHeight-2,1577False);1578break;15791580default:1581buttonAction(controlButton->buttonKey);1582} /* switch on buttonKey */15831584} /* else - not closing */1585} /* if checkButton */1586} /* if FD_ISSET(Xcon,.. */1587else if (FD_ISSET(0,&rd)) {1588externalControl = spadAction();1589if (spadDraw && (externalControl==0)) drawViewport(Xoption);1590}1591} /* for (until closed) */1592} /* processEvents() */159315941595159615971598