aboutsummaryrefslogtreecommitdiff
path: root/src/graph/view3D/process3d.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/graph/view3D/process3d.c')
-rw-r--r--src/graph/view3D/process3d.c1605
1 files changed, 1605 insertions, 0 deletions
diff --git a/src/graph/view3D/process3d.c b/src/graph/view3D/process3d.c
new file mode 100644
index 00000000..79c11b42
--- /dev/null
+++ b/src/graph/view3D/process3d.c
@@ -0,0 +1,1605 @@
+/*
+ Copyright (C) 1991-2002, The Numerical ALgorithms Group Ltd.
+ All rights reserved.
+ Copyright (C) 2007-2008, Gabriel Dos Reis.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _PROCESS3D_C
+#include "axiom-c-macros.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+
+#include "header.h"
+#include "cpanel.h"
+#include "volume.h"
+#include "mode.h"
+#include "process.h"
+#include "draw.h"
+#include "sockio.h"
+#include "com.h"
+
+
+#include "util.H1"
+#include "Gfun.H1"
+#include "pixmap.H1"
+#include "XShade.H1"
+#include "XSpadFill.H1"
+#include "all_3d.H1"
+
+#define inside(A,B) (((XButtonEvent *)event)->x >= A && \
+ ((XButtonEvent *)event)->x <= B)
+
+
+void
+#ifdef _NO_PROTO
+buttonAction (bKey)
+int bKey;
+#else
+buttonAction (int bKey)
+#endif
+{
+
+ char *s1, *s2;
+ int strL, strL1, strL2, offShade=14;
+
+ /* Button colors which are offColor, RED, are turned off, and those which
+ are onColor, GREEN, indicate the mode is in effect. */
+
+ switch (bKey) {
+
+ case hideControl:
+ if (viewport->haveControl) {
+ viewport->haveControl = no;
+ XUnmapWindow(dsply,control->controlWindow);
+ }
+ break;
+
+ case region3D:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if (viewport->regionOn) {
+ viewport->regionOn = no;
+ (control->buttonQueue[region3D]).textColor = offColor;
+ viewData.box = 0;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight,Xoption);
+ }
+ } else { /* inverted color for region off */
+ viewport->regionOn = yes;
+ viewData.box = 1;
+ (control->buttonQueue[region3D]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX,
+ (control->buttonQueue[region3D]).buttonY,
+ (control->buttonQueue[region3D]).buttonWidth,
+ (control->buttonQueue[region3D]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[region3D]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[region3D]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[region3D]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[region3D]).buttonWidth),
+ (control->buttonQueue[region3D]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[region3D]).buttonHeight),
+ s,strL,Xoption);
+ redoSmooth = yes;
+ drawViewport(Xoption);
+ break;
+
+
+
+ case bwColor:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if (!mono) {
+ if (viewport->monoOn) {
+ viewport->monoOn = no;
+ if (viewport->hueTop == viewport->hueOffset) redoColor = yes;
+ else redoDither = yes;
+ (control->buttonQueue[bwColor]).textColor = offColor;
+ (control->buttonQueue[bwColor]).text = "BW";
+ } else {
+ viewport->monoOn = yes;
+ maxGreyShade = XInitShades(dsply,scrn);
+ if (viewport->hueTop == viewport->hueOffset) redoColor = yes;
+ else redoDither = yes;
+ (control->buttonQueue[bwColor]).textColor = onColor;
+ (control->buttonQueue[bwColor]).text = "BW";
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[bwColor]).buttonX,
+ (control->buttonQueue[bwColor]).buttonY,
+ (control->buttonQueue[bwColor]).buttonWidth,
+ (control->buttonQueue[bwColor]).buttonHeight);
+ GSetForeground(globalGC1,(float)monoColor(buttonColor),Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[bwColor]).buttonX,
+ (control->buttonQueue[bwColor]).buttonY,
+ (control->buttonQueue[bwColor]).buttonWidth,
+ (control->buttonQueue[bwColor]).buttonHeight,Xoption);
+ }
+
+ s = (control->buttonQueue[bwColor]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[bwColor]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[bwColor]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[bwColor]).buttonWidth),
+ (control->buttonQueue[bwColor]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[bwColor]).buttonHeight),
+ s,strL,Xoption);
+ drawColorMap();
+ redoSmooth = yes;
+ writeTitle();
+ drawViewport(Xoption);
+ }
+ break;
+
+
+
+ case outlineOnOff:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if (viewData.outlineRenderOn) {
+ viewData.outlineRenderOn = 0;
+ (control->buttonQueue[outlineOnOff]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[outlineOnOff]).buttonX,
+ (control->buttonQueue[outlineOnOff]).buttonY,
+ (control->buttonQueue[outlineOnOff]).buttonWidth,
+ (control->buttonQueue[outlineOnOff]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[outlineOnOff]).buttonX,
+ (control->buttonQueue[outlineOnOff]).buttonY,
+ (control->buttonQueue[outlineOnOff]).buttonWidth,
+ (control->buttonQueue[outlineOnOff]).buttonHeight,Xoption);
+ }
+ } else {
+ viewData.outlineRenderOn = 1;
+ (control->buttonQueue[outlineOnOff]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[outlineOnOff]).buttonX,
+ (control->buttonQueue[outlineOnOff]).buttonY,
+ (control->buttonQueue[outlineOnOff]).buttonWidth,
+ (control->buttonQueue[outlineOnOff]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[outlineOnOff]).buttonX,
+ (control->buttonQueue[outlineOnOff]).buttonY,
+ (control->buttonQueue[outlineOnOff]).buttonWidth,
+ (control->buttonQueue[outlineOnOff]).buttonHeight,Xoption);
+ }
+ }
+ s = (control->buttonQueue[outlineOnOff]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[outlineOnOff]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[outlineOnOff]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[outlineOnOff]).buttonWidth),
+ (control->buttonQueue[outlineOnOff]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[outlineOnOff]).buttonHeight),
+ s,strL,Xoption);
+ if (viewData.style == render) {
+ drawViewport(Xoption);
+ }
+ break;
+
+
+ case lighting:
+ if (saveFlag) {
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,saveWindow);
+ }
+ doingPanel = LIGHTpanel;
+ tempLightPointer[0] = viewport->lightVector[0];
+ tempLightPointer[1] = viewport->lightVector[1];
+ tempLightPointer[2] = viewport->lightVector[2];
+ tempLightIntensity = lightIntensity;
+ XMapWindow(dsply,lightingWindow);
+ break;
+
+
+ case viewVolume:
+ if (saveFlag) {
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,saveWindow);
+ }
+ doingPanel = VOLUMEpanel;
+ XMapWindow(dsply,volumeWindow);
+ redrawView = yes;
+ drawViewport(Xoption); /* draw it with doingVolume set to yes */
+ break;
+
+
+ case volumeReturn:
+ doingPanel = CONTROLpanel;
+ redoSmooth = yes;
+ redrawView = yes;
+ XUnmapWindow(dsply,volumeWindow);
+ break;
+
+
+ case volumeAbort:
+ doingPanel = CONTROLpanel;
+ redrawView = yes;
+ XUnmapWindow(dsply,volumeWindow);
+ break;
+
+
+ case lightReturn:
+ doingPanel = CONTROLpanel;
+ viewport->lightVector[0] = lightPointer[0] = tempLightPointer[0];
+ viewport->lightVector[1] = lightPointer[1] = tempLightPointer[1];
+ viewport->lightVector[2] = lightPointer[2] = tempLightPointer[2];
+ lightIntensity = tempLightIntensity;
+ normalizeVector(viewport->lightVector);
+ redrawView = ((viewData.style == render) || (viewData.style == smooth));
+ if (movingLight || changedIntensity) redoSmooth = yes;
+ XUnmapWindow(dsply,lightingWindow);
+ break;
+
+
+ case lightAbort:
+ movingLight = no; changedIntensity = no;
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,lightingWindow);
+ break;
+
+
+ case resetView:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ viewport->axesOn = yes;
+ viewport->regionOn = no; viewData.box = 0;
+ viewData.outlineRenderOn = 0;
+ viewport->monoOn = no;
+ viewport->zoomXOn = viewport->zoomYOn = viewport->zoomZOn = yes;
+ viewport->originrOn = yes; viewport->objectrOn = no;
+ viewport->originFlag = no;
+ viewport->xyOn = viewport->xzOn = viewport->yzOn = no;
+ viewport->lightVector[0] = -0.5;
+ viewport->lightVector[1] = 0.5;
+ viewport->lightVector[2] = 0.5;
+ viewport->translucency = viewData.translucency;
+ viewport->deltaX = viewport->deltaX0;
+ viewport->deltaY = viewport->deltaY0;
+ viewport->deltaY = viewport->deltaZ0;
+ viewport->scale = viewport->scale0;
+ viewport->scaleX = viewport->scaleY = viewport->scaleZ = 1.0;
+ if (!equal(viewport->theta,viewport->theta0) || !equal(viewport->phi,viewport->phi0))
+ rotated = yes;
+ viewport->theta = viewport->axestheta = viewport->theta0 = viewData.theta;
+ viewport->phi = viewport->axesphi = viewport->phi0 = viewData.phi;
+ viewport->thetaObj = 0.0;
+ viewport->phiObj = 0.0;
+ redoSmooth = yes;
+ drawViewport(Xoption);
+ if (viewport->haveControl) drawControlPanel();
+ writeTitle();
+ break;
+
+
+ case axesOnOff:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if (viewport->axesOn) {
+ viewport->axesOn = no;
+ (control->buttonQueue[axesOnOff]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight,Xoption);
+ }
+ } else { /* draw invert-color button */
+ viewport->axesOn = yes;
+ (control->buttonQueue[axesOnOff]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX,
+ (control->buttonQueue[axesOnOff]).buttonY,
+ (control->buttonQueue[axesOnOff]).buttonWidth,
+ (control->buttonQueue[axesOnOff]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[axesOnOff]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[axesOnOff]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[axesOnOff]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[axesOnOff]).buttonWidth),
+ (control->buttonQueue[axesOnOff]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[axesOnOff]).buttonHeight),
+ s,strL,Xoption);
+ if (viewData.style == smooth) {
+ if (multiColorFlag) redoDither = yes;
+ else redoColor = yes;
+ }
+ drawViewport(Xoption);
+ break;
+
+
+ case zoomx:
+ if (viewport->zoomXOn) {
+ viewport->zoomXOn = no;
+ (control->buttonQueue[zoomx]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight,Xoption);
+ }
+ } else {
+ viewport->zoomXOn = yes;
+ (control->buttonQueue[zoomx]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX,
+ (control->buttonQueue[zoomx]).buttonY,
+ (control->buttonQueue[zoomx]).buttonWidth,
+ (control->buttonQueue[zoomx]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[zoomx]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[zoomx]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[zoomx]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[zoomx]).buttonWidth),
+ (control->buttonQueue[zoomx]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[zoomx]).buttonHeight),
+ s,strL,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+ case zoomy:
+ if (viewport->zoomYOn) {
+ viewport->zoomYOn = no;
+ (control->buttonQueue[zoomy]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight,Xoption);
+ }
+ } else {
+ viewport->zoomYOn = yes;
+ (control->buttonQueue[zoomy]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX,
+ (control->buttonQueue[zoomy]).buttonY,
+ (control->buttonQueue[zoomy]).buttonWidth,
+ (control->buttonQueue[zoomy]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[zoomy]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[zoomy]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[zoomy]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[zoomy]).buttonWidth),
+ (control->buttonQueue[zoomy]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[zoomy]).buttonHeight),
+ s,strL,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+ case zoomz:
+ if (viewport->zoomZOn) {
+ viewport->zoomZOn = no;
+ (control->buttonQueue[zoomz]).textColor = offColor;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight,Xoption);
+ }
+ } else {
+ viewport->zoomZOn = yes;
+ (control->buttonQueue[zoomz]).textColor = onColor;
+ if (mono) {
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX,
+ (control->buttonQueue[zoomz]).buttonY,
+ (control->buttonQueue[zoomz]).buttonWidth,
+ (control->buttonQueue[zoomz]).buttonHeight,Xoption);
+ }
+ }
+
+ s = (control->buttonQueue[zoomz]).text;
+ strL = strlen(s);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[zoomz]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[zoomz]).buttonX +
+ centerX(processGC,s,strL,
+ (control->buttonQueue[zoomz]).buttonWidth),
+ (control->buttonQueue[zoomz]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[zoomz]).buttonHeight),
+ s,strL,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+ case originr:
+ viewport->originrOn = yes;
+ (control->buttonQueue[originr]).textColor = onColor;
+ viewport->objectrOn = no;
+ (control->buttonQueue[objectr]).textColor = offColor;
+ viewport->originFlag = yes;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight,Xoption);
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight,Xoption);
+ }
+ s1 = (control->buttonQueue[objectr]).text;
+ strL1 = strlen(s1);
+ s2 = (control->buttonQueue[originr]).text;
+ strL2 = strlen(s2);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[objectr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX +
+ centerX(processGC,s1,strL1,
+ (control->buttonQueue[objectr]).buttonWidth),
+ (control->buttonQueue[objectr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[objectr]).buttonHeight),
+ s1,strL1,Xoption);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[originr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX +
+ centerX(processGC,s2,strL2,
+ (control->buttonQueue[originr]).buttonWidth),
+ (control->buttonQueue[originr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[originr]).buttonHeight),
+ s2,strL2,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+
+ case objectr:
+ viewport->objectrOn = yes;
+ (control->buttonQueue[objectr]).textColor = onColor;
+ viewport->originrOn = no;
+ (control->buttonQueue[originr]).textColor = offColor;
+
+ viewport->originFlag = no;
+ if (mono) {
+ XChangeShade(dsply,offShade);
+ XShadeRectangle(dsply,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[originr]).buttonX,
+ (control->buttonQueue[originr]).buttonY,
+ (control->buttonQueue[originr]).buttonWidth,
+ (control->buttonQueue[originr]).buttonHeight,Xoption);
+ GSetForeground(globalGC1,(float)backgroundColor,Xoption);
+ XFillRectangle(dsply, control->controlWindow, globalGC1,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight);
+ GSetForeground(globalGC1,(float)foregroundColor,Xoption);
+ GDrawRectangle(globalGC1, control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX,
+ (control->buttonQueue[objectr]).buttonY,
+ (control->buttonQueue[objectr]).buttonWidth,
+ (control->buttonQueue[objectr]).buttonHeight,Xoption);
+ }
+ s1 = (control->buttonQueue[objectr]).text;
+ strL1 = strlen(s1);
+ s2 = (control->buttonQueue[originr]).text;
+ strL2 = strlen(s2);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[objectr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[objectr]).buttonX +
+ centerX(processGC,s1,strL1,
+ (control->buttonQueue[objectr]).buttonWidth),
+ (control->buttonQueue[objectr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[objectr]).buttonHeight),
+ s1,strL1,Xoption);
+
+ GSetForeground(processGC,
+ (float)monoColor((control->buttonQueue[originr]).textColor),Xoption);
+ GDrawImageString(processGC,control->controlWindow,
+ (control->buttonQueue[originr]).buttonX +
+ centerX(processGC,s2,strL2,
+ (control->buttonQueue[originr]).buttonWidth),
+ (control->buttonQueue[originr]).buttonY +
+ centerY(processGC,
+ (control->buttonQueue[originr]).buttonHeight),
+ s2,strL2,Xoption);
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ break;
+
+
+
+ case ps:
+ strcpy(control->message," Creating postscript file ... ");
+ writeControlMessage();
+ if (PSInit(viewport->viewWindow, viewport->titleWindow) == psError) {
+ strcpy(control->message," Aborted: PSInit error. ");
+ writeControlMessage();
+ return; /* make new tmpnam for new file */
+ }
+
+ redoSmooth = yes;
+ drawViewport(PSoption); /* draw picture in PS; create ps script file */
+
+ if (PSCreateFile(viewBorderWidth, viewport->viewWindow,
+ viewport->titleWindow, viewport->title) == psError) {
+ strcpy(control->message," Aborted: PSCreateFile error. ");
+ writeControlMessage();
+ return;
+ }
+
+ clearControlMessage();
+ strcpy(control->message,PSfilename);
+ strcat(control->message," in working dir ");
+ writeControlMessage();
+ break;
+
+
+
+ case pixmap:
+ strcpy(control->message," Creating axiom3D.xpm now ... ");
+ writeControlMessage();
+ XGetWindowAttributes(dsply,viewport->viewWindow,&vwInfo);
+ write_pixmap_file(dsply,scrn,"axiom3D.xpm",
+ viewport->titleWindow,0,0,vwInfo.width,
+ vwInfo.height+titleHeight);
+ clearControlMessage();
+ strcpy(control->message," axiom3D.xpm in working dir ");
+ writeControlMessage();
+ break;
+
+
+
+ case transparent:
+ case opaqueMesh:
+ case render:
+ case smooth:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ viewData.style = bKey;
+ drawViewport(Xoption); /* draw picture in viewWindow with X routines */
+ break;
+
+
+ case closeAll:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ doingPanel = QUITpanel;
+ viewport->closing = yes;
+ XMapWindow(dsply,quitWindow);
+ break;
+
+
+ case quitReturn:
+ XUnmapWindow(dsply,quitWindow);
+ break;
+
+
+ case quitAbort:
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,quitWindow);
+ break;
+
+
+ case saveit:
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ saveFlag = yes;
+ doingPanel = SAVEpanel;
+ XMapWindow(dsply,saveWindow);
+ break;
+
+
+ case saveExit:
+ saveFlag = no;
+ doingPanel = CONTROLpanel;
+ XUnmapWindow(dsply,saveWindow);
+ break;
+
+
+ case xy:
+ viewport->theta = pi;
+ viewport->phi = 0.0;
+ viewport->axestheta = pi;
+ viewport->axesphi = 0.0;
+ rotated = yes;
+ viewport->yzOn = viewport->xzOn = no;
+ viewport->xyOn = yes;
+ drawViewport(Xoption);
+ break;
+
+
+ case xz:
+ viewport->theta = pi;
+ viewport->phi = -pi_half;
+ viewport->axestheta = pi;
+ viewport->axesphi = -pi_half;
+ rotated = yes;
+ viewport->yzOn = viewport->xyOn = no;
+ viewport->xzOn = yes;
+ drawViewport(Xoption);
+ break;
+
+
+ case yz:
+ viewport->theta = pi_half;
+ viewport->phi = -pi_half;
+ viewport->axestheta = pi_half;
+ viewport->axesphi = -pi_half;
+ rotated = yes;
+ viewport->xzOn = viewport->xyOn = no;
+ viewport->yzOn = yes;
+ drawViewport(Xoption);
+ break;
+
+
+ default:
+ fprintf(stderr,"Received a non-functioning button request: %d \n",bKey);
+ break;
+ } /* switch (action) */
+
+} /* processEvents() */
+
+
+
+/************************** X Event Processing *****************************/
+void
+#ifdef _NO_PROTO
+processEvents()
+#else
+processEvents(void)
+#endif
+{
+
+ XEvent *event, tempEvent;
+ Window whichWindow;
+ buttonStruct *controlButton;
+ mouseCoord mouseXY, linearMouseXY;
+ int someInt, mouseW4, mouseH4;
+ int toggleReady =yes;
+ int checkButton = no;
+ int first_time = yes;
+ int changingColor = yes;
+ int gotEvent = 0, exposeView = no;
+ int tempTW, tempTH, tempVW, tempVH;
+ int buttonTablePtr;
+ float f1, f2;
+ int px, py, lx, ly;
+ unsigned int lbuttons;
+ Window dummy;
+ int Xcon,externalControl,len;
+ fd_set rd;
+
+ externalControl = 0;
+ Xcon = ConnectionNumber(dsply);
+
+ /** assign lightPointer for light panel **/
+ lightPointer[0] = tempLightPointer[0] = viewport->lightVector[0];
+ lightPointer[1] = tempLightPointer[1] = viewport->lightVector[1];
+ lightPointer[2] = tempLightPointer[2] = viewport->lightVector[2];
+
+ if (!(event = (XEvent *)saymem("process.c",1,sizeof(XEvent)))) {
+ fprintf(stderr,"Ran out of memory initializing event processing.\n");
+ exitWithAck(RootWindow(dsply,scrn),Window,-1);
+ }
+
+ controlButton = 0;
+
+ while(1) {
+
+ /* Store old viewport window size attributes for resizing comparison. */
+ XGetWindowAttributes(dsply,viewport->titleWindow,&graphWindowAttrib);
+ tempTW = graphWindowAttrib.width;
+ tempTH = graphWindowAttrib.height;
+ XGetWindowAttributes(dsply,viewport->viewWindow,&graphWindowAttrib);
+ tempVW = graphWindowAttrib.width;
+ tempVH = graphWindowAttrib.height;
+
+ /* Get the next X event. The check for pending events is so that
+ a held down mouse button is interpreted as an event
+ even if nothing is pending. */
+
+ len=0;
+ while(len<=0) {
+ FD_ZERO(&rd);
+ if (externalControl==0) FD_SET(0, &rd);
+ FD_SET(Xcon,&rd);
+
+ if (XEventsQueued(dsply, QueuedAlready)) {
+ len=1;
+ break;
+ }
+ if (!followMouse)
+ len=select(FD_SETSIZE,(void *)&rd,0,0,0);
+ else
+ len=1;
+ }
+
+ if (FD_ISSET(Xcon,&rd)||
+ XEventsQueued(dsply, QueuedAfterFlush) ||
+ followMouse) {
+
+ if (followMouse) {
+ if (XPending(dsply))
+ XNextEvent(dsply,event);
+ gotEvent++;
+ } else {
+ XNextEvent(dsply,event);
+ gotEvent++;
+ }
+
+ if (gotToggle || !followMouse)
+ checkButton = no;
+
+ if (gotEvent) {
+ whichWindow = ((XButtonEvent *)event)->window;
+ first_time = no;
+
+ switch(((XEvent *)event)->type) {
+ case ClientMessage:
+ if (event->xclient.data.l[0] == wm_delete_window) {
+ goodbye(-1);
+ }
+ else {
+ fprintf(stderr,"Unknown Client Message ...\n");
+ }
+ break;
+ case Expose:
+ if (whichWindow == viewport->titleWindow) {
+ exposeView = yes;
+ followMouse = no;
+ XSync(dsply,0);
+ /* get rid of redundant exposure events */
+ XCheckWindowEvent(dsply,viewport->titleWindow,
+ ExposureMask,&tempEvent);
+ writeTitle();
+ XGetWindowAttributes(dsply,viewport->titleWindow,
+ &graphWindowAttrib);
+ if ((graphWindowAttrib.width!=tempTW) ||
+ ((graphWindowAttrib.height)!=tempTH)) {
+ XResizeWindow(dsply,viewport->viewWindow,
+ graphWindowAttrib.width, graphWindowAttrib.height);
+ redoSmooth = yes; /* recompute smooth image pixmap if resized */
+ }
+ } else if (whichWindow == viewport->viewWindow) {
+ exposeView = yes;
+ followMouse = no;
+ XSync(dsply,0);
+ XCheckWindowEvent(dsply,viewport->viewWindow,ExposureMask,
+ &tempEvent);
+ XGetWindowAttributes(dsply,viewport->viewWindow,&graphWindowAttrib);
+ if ((graphWindowAttrib.width!=tempVW) ||
+ ((graphWindowAttrib.height)!=tempVH)) {
+ XResizeWindow(dsply,viewport->viewWindow,graphWindowAttrib.width,
+ graphWindowAttrib.height);
+ redoSmooth = yes; /* recompute smooth image pixmap if resized */
+ }
+ drawViewport(Xoption);
+ XMapWindow(dsply,whichWindow);
+ } else if (whichWindow == lightingWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width!=controlWidth) ||
+ (graphWindowAttrib.height!=controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,controlWidth,
+ controlHeight);
+ }
+ drawLightingPanel();
+ } else if (whichWindow == volumeWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width!=controlWidth) ||
+ (graphWindowAttrib.height!=controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,controlWidth,
+ controlHeight);
+ }
+ drawVolumePanel();
+ if (redrawView) {
+ redrawView = no;
+ drawViewport(Xoption);
+ }
+ } else if (whichWindow == quitWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width!=controlWidth) ||
+ (graphWindowAttrib.height!=controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,controlWidth,
+ controlHeight);
+ }
+ drawQuitPanel();
+ } else if (whichWindow == saveWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width!=controlWidth) ||
+ (graphWindowAttrib.height!=controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,controlWidth,
+ controlHeight);
+ }
+ drawSavePanel();
+ } else if (whichWindow == control->controlWindow) {
+ XGetWindowAttributes(dsply,control->controlWindow,
+ &graphWindowAttrib);
+ /* do not allow resizing of control panel */
+ if ((graphWindowAttrib.width != controlWidth) ||
+ (graphWindowAttrib.height != controlHeight)) {
+ XResizeWindow(dsply,control->controlWindow,
+ controlWidth,controlHeight);
+ }
+ if (viewport->haveControl) drawControlPanel();
+ followMouse = no;
+ if (redrawView || exposeView) {
+ redrawView = no;
+ drawViewport(Xoption);
+ }
+ exposeView = no;
+ } else {
+ fprintf(stderr,"Not a valid window.\n");
+ }
+
+ XFlush(dsply);
+ while(XCheckTypedWindowEvent(dsply, whichWindow, Expose, &tempEvent));
+ break;
+
+
+ case MotionNotify:
+ exposeView = no;
+ if (followMouse) {
+ if (whichWindow == control->colormapWindow) {
+ while (XCheckMaskEvent(dsply,ButtonMotionMask,event));
+ first_time = checkButton = followMouse = changingColor = yes;
+ gotToggle = no;
+ } else if (whichWindow != control->controlWindow) {
+ if (controlButton->pot) {
+ while (XCheckMaskEvent(dsply,ButtonMotionMask,event));
+ mouseXY = getPotValue(((XButtonEvent *)event)->x,
+ ((XButtonEvent *)event)->y,
+ controlButton->xHalf,
+ controlButton->yHalf);
+ linearMouseXY = getLinearPotValue(((XButtonEvent *)event)->x,
+ ((XButtonEvent *)event)->y,
+ controlButton->xHalf,
+ controlButton->yHalf);
+ first_time = checkButton = followMouse = yes;
+ gotToggle = no;
+ }
+ }
+ }
+ break;
+
+ case ButtonRelease:
+ exposeView = followMouse = no;
+ toggleReady = yes; gotToggle = yes;
+ break;
+
+ case LeaveNotify:
+ XQueryPointer(dsply,rtWindow,&dummy,&dummy,&px,&py,&lx,&ly,&lbuttons);
+ if ( (controlButton) &&
+ ((whichWindow == control->colormapWindow) ||
+ (controlButton->pot)) &&
+ (lbuttons & Button1Mask ||
+ lbuttons & Button2Mask ||
+ lbuttons & Button3Mask)) {
+ followMouse = yes;
+ if (whichWindow == control->colormapWindow)
+ changingColor = yes;
+ }
+ else {
+ followMouse = no;
+ changingColor = no;
+ }
+ toggleReady = yes;
+ checkButton = exposeView = no;
+ break;
+
+ case ButtonPress:
+ exposeView = no; changingColor = no;
+ if (whichWindow == viewport->viewWindow) {
+ /* find out where the mouse button is pressed on the viewport,
+ this determines where to put the control panel */
+ XGetWindowAttributes(dsply,whichWindow,&graphWindowAttrib);
+ mouseW4 = graphWindowAttrib.width/4;
+ if (((XButtonEvent *)event)->x > (graphWindowAttrib.width-mouseW4))
+ someInt = 1;
+ else {
+ mouseH4 = graphWindowAttrib.height/4;
+ if (((XButtonEvent *)event)->y >
+ (graphWindowAttrib.height - mouseH4)) someInt = 2;
+ else if (((XButtonEvent *)event)->x < mouseW4) someInt = 3;
+ else if (((XButtonEvent *)event)->y < mouseH4) someInt = 4;
+ else someInt = 0;
+ }
+ if (viewport->haveControl) {
+ XUnmapWindow(dsply,control->controlWindow);
+ }
+ putControlPanelSomewhere(someInt);
+ writeControlMessage();
+ XSync(dsply,0);
+ } else if (whichWindow == control->colormapWindow) {
+ gotToggle = no;
+ first_time = checkButton = followMouse = changingColor = yes;
+ } else if (whichWindow != control->controlWindow) {
+ /* mouse clicked on one of the buttons */
+ if (!controlButton || (controlButton->self != whichWindow)) {
+ buttonTablePtr = *((int *)XLookUpAssoc(dsply,table,whichWindow));
+ /** lighting buttons have indices greater than 100 **/
+ /** all buttons share the same array now **/
+ controlButton = &(control->buttonQueue[buttonTablePtr]);
+ }
+ if (controlButton->pot) {
+ /* figure out [x,y] for this button in the range [-1..1,-1..1] */
+ mouseXY = getPotValue(((XButtonEvent *)event)->x,
+ ((XButtonEvent *)event)->y,
+ controlButton->xHalf,controlButton->yHalf);
+ linearMouseXY = getLinearPotValue(((XButtonEvent *)event)->x,
+ ((XButtonEvent *)event)->y,
+ controlButton->xHalf,
+ controlButton->yHalf);
+ followMouse = yes;
+ gotToggle = no;
+ } else {
+ followMouse = no;
+ gotToggle = yes; /* auto-repeat of toggle buttons not allowed */
+ if (toggleReady) toggleReady = no;
+ }
+ checkButton = yes;
+ first_time = yes;
+ }
+ break;
+
+ default:
+ toggleReady = gotToggle = yes;
+ exposeView = changingColor = checkButton = followMouse = no;
+ break;
+
+ } /* switch */
+ gotEvent--;
+ } /* if gotEvent */
+
+ /* Allow a pressed mouse button on a potentiometer to poll repeatedly. */
+ if (followMouse && !first_time && (followMouse++ > mouseWait)) {
+ /* reset for next timing loop */
+ followMouse = yes;
+ checkButton = yes;
+ }
+ if (checkButton) {
+ if (viewport->closing && (controlButton->buttonKey == quitReturn)) {
+ goodbye(-1);
+ } else if (changingColor) {
+ viewport->closing = no;
+ /* moving top color map pointer */
+ if (((XButtonEvent *)event)->y < colorOffsetY) {
+ if (((XButtonEvent *)event)->x < (colorOffset+colorWidth)) {
+ /* decreasing top hue number */
+ if (viewport->hueTop > 0) viewport->hueTop--;
+ } else if (((XButtonEvent *)event)->x >=
+ (colorOffsetX + totalHues*colorWidth + colorWidth)) {
+ if (viewport->hueTop < totalHues) viewport->hueTop++;
+ } else {
+ viewport->hueTop =
+ (((XButtonEvent *)event)->x -
+ colorOffsetX + colorWidth/2 - 13) / colorWidth;
+ }
+ } else if (((XButtonEvent *)event)->y >
+ (colorOffsetY + colorHeight)) {
+ /* moving bottom color map pointer */
+ if (((XButtonEvent *)event)->x < (colorOffset+colorWidth)) {
+ /* decreasing offset number */
+ if (viewport->hueOffset > 0) viewport->hueOffset--;
+ } else if (((XButtonEvent *)event)->x >=
+ (colorOffsetX + totalHues*colorWidth + colorWidth)) {
+ if (viewport->hueOffset < totalHues) viewport->hueOffset++;
+ } else {
+ viewport->hueOffset =
+ (((XButtonEvent *)event)->x -
+ colorOffsetX + colorWidth/2 - 13) / colorWidth;
+ }
+ }
+ /* color map pointer does not wrap around */
+ if (viewport->hueOffset < 0) viewport->hueOffset = 0;
+ if (viewport->hueTop < 0) viewport->hueTop = 0;
+ if (viewport->hueOffset >= totalHues)
+ viewport->hueOffset = totalHues-1;
+ if (viewport->hueTop >= totalHues) viewport->hueTop = totalHues-1;
+ viewport->numberOfHues = viewport->hueTop - viewport->hueOffset;
+ if ((viewport->hueTop == viewport->hueOffset) && !viewport->monoOn) {
+ redoColor = yes;
+ redoDither = no;
+ } else {
+ redoColor = no;
+ redoDither = yes;
+ }
+ /* update color map changes on control panel */
+ drawColorMap();
+ } else {
+ viewport->closing = no;
+ clearControlMessage();
+ /* reset all the things that might affect a recalculation for
+ redrawing removing hidden surfaces */
+
+ /* determine what type of button has been pressed */
+ switch(controlButton->buttonKey) {
+
+ /*** Potentiometers ***/
+ case rotate:
+ if (!((viewport->originrOn) && (viewport->objectrOn))) {
+ /* update the amount of rotation around the object center
+ of volume */
+ if (viewport->objectrOn) {
+ viewport->thetaObj += mouseXY.x * rotateFactor;
+ viewport->phiObj -= mouseXY.y * rotateFactor;
+ while (viewport->thetaObj >= two_pi) {
+ viewport->thetaObj -= two_pi;
+ }
+ while (viewport->thetaObj < 0.0) {
+ viewport->thetaObj += two_pi;
+ }
+ while (viewport->phiObj > pi) {
+ viewport->phiObj -= two_pi;
+ }
+ while (viewport->phiObj <= -pi) {
+ viewport->phiObj += two_pi;
+ }
+ }
+ /* update amount of rotation around the world space origin */
+ if (viewport->originrOn) {
+ viewport->theta += mouseXY.x * rotateFactor;
+ viewport->phi -= mouseXY.y * rotateFactor;
+ while (viewport->theta >= two_pi) {
+ viewport->theta -= two_pi;
+ }
+ while (viewport->theta < 0.0) {
+ viewport->theta += two_pi;
+ }
+ while (viewport->phi > pi) {
+ viewport->phi -= two_pi;
+ }
+ while (viewport->phi <= -pi) {
+ viewport->phi += two_pi;
+ }
+ viewport->axestheta += mouseXY.x * rotateFactor;
+ viewport->axesphi -= mouseXY.y * rotateFactor;
+ while (viewport->axestheta >= two_pi) {
+ viewport->axestheta -= two_pi;
+ }
+ while (viewport->axestheta < 0.0) {
+ viewport->axestheta += two_pi;
+ }
+ while (viewport->axesphi > pi) {
+ viewport->axesphi -= two_pi;
+ }
+ while (viewport->axesphi <= -pi) {
+ viewport->axesphi += two_pi;
+ }
+ }
+ rotated = yes;
+ viewport->yzOn = viewport->xzOn = viewport->xyOn = no;
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ drawViewport(Xoption);
+ }
+ break;
+
+ case zoom:
+ /* if uniform scaling */
+ if ((viewport->zoomXOn) &&
+ (viewport->zoomYOn) &&
+ (viewport->zoomZOn)) {
+ viewport->scale *= 1 - mouseXY.y * scaleFactor;
+ } else { /* else scale axes independently */
+ if (viewport->zoomXOn) viewport->scaleX *= (1 - mouseXY.y);
+ if (viewport->zoomYOn) viewport->scaleY *= (1 - mouseXY.y);
+ if (viewport->zoomZOn) viewport->scaleZ *= (1 - mouseXY.y);
+ }
+ if (viewport->scale > maxScale) viewport->scale = maxScale;
+ else if (viewport->scale < minScale) viewport->scale = minScale;
+ if (viewport->scaleX > maxScale) viewport->scaleX = maxScale;
+ else if (viewport->scaleX < minScale) viewport->scaleX = minScale;
+ if (viewport->scaleY > maxScale) viewport->scaleY = maxScale;
+ else if (viewport->scaleY < minScale) viewport->scaleY = minScale;
+ if (viewport->scaleZ > maxScale) viewport->scaleZ = maxScale;
+ else if (viewport->scaleZ < minScale) viewport->scaleZ = minScale;
+ zoomed = yes;
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ if ((viewport->zoomXOn) ||
+ (viewport->zoomYOn) ||
+ (viewport->zoomZOn))
+ drawViewport(Xoption);
+ break;
+
+ case translate:
+ viewport->deltaX += mouseXY.x * translateFactor;
+ viewport->deltaY += mouseXY.y * translateFactor;
+ if (viewport->deltaX > maxDeltaX) viewport->deltaX = maxDeltaX;
+ else if (viewport->deltaX < -maxDeltaX) viewport->deltaX = -maxDeltaX;
+
+ if (viewport->deltaY > maxDeltaY) viewport->deltaY = maxDeltaY;
+ else if (viewport->deltaY < -maxDeltaY) viewport->deltaY = -maxDeltaY;
+ translated = yes;
+ clearControlMessage();
+ strcpy(control->message,viewport->title);
+ writeControlMessage();
+ drawViewport(Xoption);
+ break;
+
+ /*** Lighting panel ***/
+ case lightMoveXY:
+ tempLightPointer[0] = linearMouseXY.x;
+ tempLightPointer[1] = linearMouseXY.y;
+ if (tempLightPointer[0] > 1) tempLightPointer[0] = 1;
+ else if (tempLightPointer[0] < -1) tempLightPointer[0] = -1;
+ if (tempLightPointer[1] > 1) tempLightPointer[1] = 1;
+ else if (tempLightPointer[1] < -1) tempLightPointer[1] = -1;
+ movingLight = yes;
+ drawLightingAxes();
+ break;
+
+ case lightMoveZ:
+ tempLightPointer[2] = linearMouseXY.y;
+ /* linearMouse => no checking necessary */
+ if (tempLightPointer[2] > 1) tempLightPointer[2] = 1;
+ else if (tempLightPointer[2] < -1) tempLightPointer[2] = -1;
+ movingLight = yes;
+ drawLightingAxes();
+ break;
+
+ /* changes the light intensity */
+ case lightTranslucent:
+ tempLightIntensity = (linearMouseXY.y+1)/2;
+ if (tempLightIntensity > 1) tempLightIntensity = 1;
+ else if (tempLightIntensity < 0) tempLightIntensity = 0;
+ changedIntensity = yes;
+ drawLightTransArrow();
+ break;
+
+ /*** volume panel ***/
+ case frustrumBut:
+ screenX = ((XButtonEvent *)event)->x;
+ if inside(eyeMinX,eyeMaxX) {
+ /* object coordinate */
+ f2 = mouseXY.x * (maxEyeDistance - minEyeDistance) +
+ minEyeDistance;
+ if (f2 != viewData.eyeDistance) {
+ doingVolume = 2; /* flag for using screenX */
+ changedEyeDistance = yes;
+ viewData.eyeDistance = f2;
+ drawFrustrum();
+ drawViewport(Xoption);
+ }
+ }
+ else if inside(hitherMinX,hitherMaxX) {
+ f1 = ((float)hitherMaxX - ((XButtonEvent *)event)->x) /
+ (hitherMaxX - hitherMinX);
+ /* object coordinate */
+ f2 = f1 * (clipPlaneMax - clipPlaneMin) + clipPlaneMin;
+ if (f2 != viewData.clipPlane) {
+ doingVolume = 3; /* flag for using screenX */
+ viewData.clipPlane = f2;
+ drawFrustrum();
+ drawViewport(Xoption);
+ }
+ }
+ else {
+ doingVolume = 1; /* check out doingVolume */
+ doingPanel = VOLUMEpanel;
+ }
+ break;
+
+ case clipXBut: /* this is a horizontal button */
+ clipValue = linearMouseXY.x * 0.5 + 0.5; /* normalize to 0..1 */
+ if (lessThan(clipValue,0.0)) clipValue = 0.0;
+ if (greaterThan(clipValue,1.0)) clipValue = 1.0;
+ if (lessThan(linearMouseXY.y,0.0)) {
+ if (!equal(xClipMinN,clipValue)) {
+ if (greaterThan(xClipMaxN-clipValue,minDistXY))
+ xClipMinN = clipValue;
+ else
+ xClipMinN = xClipMaxN - minDistXY;
+ viewData.clipXmin = xClipMinN *
+ (viewData.xmax - viewData.xmin) +
+ viewData.xmin;
+ drawClipXBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ } else {
+ if (!equal(xClipMaxN,clipValue)) {
+ if (greaterThan(clipValue-xClipMinN,minDistXY))
+ xClipMaxN = clipValue;
+ else
+ xClipMaxN = xClipMinN + minDistXY;
+ viewData.clipXmax = xClipMaxN *
+ (viewData.xmax - viewData.xmin) +
+ viewData.xmin;
+ drawClipXBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ }
+ break;
+
+ case clipYBut: /* this is a vertical button */
+ /* normalize to 0..1, bottom up */
+ clipValue = 1 - (linearMouseXY.y * 0.5 + 0.5);
+ if (lessThan(clipValue,0.0)) clipValue = 0.0;
+ if (greaterThan(clipValue,1.0)) clipValue = 1.0;
+ if (lessThan(linearMouseXY.x,0.0)) {
+ if (!equal(yClipMinN,clipValue)) {
+ if (greaterThan(yClipMaxN-clipValue,minDistXY))
+ yClipMinN = clipValue;
+ else
+ yClipMinN = yClipMaxN - minDistXY;
+ viewData.clipYmin = yClipMinN *
+ (viewData.ymax - viewData.ymin) +
+ viewData.ymin;
+ drawClipYBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ } else {
+ if (!equal(yClipMaxN,clipValue)) {
+ if (greaterThan(clipValue-yClipMinN,minDistXY))
+ yClipMaxN = clipValue;
+ else
+ yClipMaxN = yClipMinN + minDistXY;
+ viewData.clipYmax = yClipMaxN *
+ (viewData.ymax - viewData.ymin) +
+ viewData.ymin;
+ drawClipYBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ }
+ break;
+
+ case clipZBut: /* this is a diagonally aligned button! */
+ /* f1 is the distance from the center of the button along
+ the diagonal line with a slope of -1. If f1 is negative,
+ the direction is downward from the center, if f1 is
+ positive, the direction is upward from the center.
+ Note that there ought to be a constant factor, namely
+ cos(45), multiplied by f1 for the correct normalized value;
+ however, we exploit this by foreshortening the length of the
+ diagonal by that same factor (so instead of normalizing the
+ numbers to, the line we normalize the line to the numbers)
+ since we need to shorten the line at some point anyway
+ (both to match the length of the diagonal side of the box
+ and to allow more area for mouse input. */
+
+ /* cos(45), etc => 0.4 */
+ f1 = (linearMouseXY.x - linearMouseXY.y) * 0.4 + 0.5;
+ if (lessThan(f1,0.0)) f1 = 0.0;
+ if (greaterThan(f1,1.0)) f1 = 1.0;
+ /* note that x<y => moving upward */
+ if (lessThan(-linearMouseXY.x,linearMouseXY.y)) {
+ if (!equal(zClipMaxN,f1)) {
+ if (greaterThan(f1-zClipMinN,minDistZ))
+ zClipMaxN = f1;
+ else
+ zClipMaxN = zClipMinN + minDistZ;
+ viewData.clipZmax = zClipMaxN *
+ (viewData.zmax - viewData.zmin) +
+ viewData.zmin;
+ drawClipZBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ } else {
+ if (!equal(zClipMinN,f1)) {
+ if (greaterThan(zClipMaxN-f1,minDistZ))
+ zClipMinN = f1;
+ else
+ zClipMinN = zClipMaxN - minDistZ;
+ viewData.clipZmin = zClipMinN *
+ (viewData.zmax - viewData.zmin) +
+ viewData.zmin;
+ drawClipZBut();
+ drawClipVolume();
+ if (viewData.clipbox)
+ drawViewport(Xoption);
+ }
+ } /* if lessThan(x,y) */
+ break;
+
+ case perspectiveBut:
+ if ((viewData.perspective = !viewData.perspective)) {
+ switchedPerspective = yes;
+ GSetForeground(volumeGC,
+ (float)monoColor((control->buttonQueue[perspectiveBut]).textColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,
+ controlButton->buttonX +
+ centerX(volumeGC,"x",1,controlButton->buttonWidth),
+ controlButton->buttonY +
+ centerY(volumeGC,controlButton->buttonHeight),
+ "x",1,Xoption);
+ }
+ else
+ XClearArea(dsply,volumeWindow,
+ controlButton->buttonX+1,
+ controlButton->buttonY+1,
+ controlButton->buttonHeight-2,
+ controlButton->buttonWidth-2,
+ False);
+ drawViewport(Xoption);
+ break;
+
+ case clipRegionBut:
+ if ((viewData.clipbox = !viewData.clipbox)) {
+ GSetForeground(volumeGC,
+ (float)monoColor((control->buttonQueue[clipRegionBut]).textColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,
+ controlButton->buttonX +
+ centerX(volumeGC,"x",1,controlButton->buttonWidth),
+ controlButton->buttonY +
+ centerY(volumeGC,controlButton->buttonHeight),
+ "x",1,Xoption);
+ }
+ else
+ XClearArea(dsply,volumeWindow,
+ controlButton->buttonX+1,
+ controlButton->buttonY+1,
+ controlButton->buttonWidth-2,
+ controlButton->buttonHeight-2,
+ False);
+
+ drawViewport(Xoption);
+ break;
+
+ case clipSurfaceBut:
+ if ((viewData.clipStuff = !viewData.clipStuff)) {
+ GSetForeground(volumeGC,
+ (float)monoColor((control->buttonQueue[clipSurfaceBut]).textColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,
+ controlButton->buttonX +
+ centerX(volumeGC,"x",1,controlButton->buttonWidth),
+ controlButton->buttonY +
+ centerY(volumeGC,controlButton->buttonHeight),
+ "x",1,Xoption);
+ }
+ else
+ XClearArea(dsply,volumeWindow,
+ controlButton->buttonX+1,
+ controlButton->buttonY+1,
+ controlButton->buttonWidth-2,
+ controlButton->buttonHeight-2,
+ False);
+ break;
+
+ default:
+ buttonAction(controlButton->buttonKey);
+ } /* switch on buttonKey */
+
+ } /* else - not closing */
+ } /* if checkButton */
+ } /* if FD_ISSET(Xcon,.. */
+ else if FD_ISSET(0,&rd) {
+ externalControl = spadAction();
+ if (spadDraw && (externalControl==0)) drawViewport(Xoption);
+ }
+ } /* for (until closed) */
+} /* processEvents() */
+
+
+