open-axiom repository from github
/*1Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.2All rights reserved.3Copyright (C) 2007-2010, 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 _CONTROL3D_C36#include "openaxiom-c-macros.h"3738#include <string.h>39#include <stdio.h>40#include <unistd.h>41#include <stdlib.h>4243#include "mouse11.bitmap"44#include "mouse11.mask"4546#include "header.h"47#include "cpanel.h"4849#include "util.H1"50#include "XShade.h"51#include "XSpadFill.h"52#include "Gfun.H1"53#include "all_3d.H1"5455/* Defines the pixmap for the arrow displayed in the scale window */56#define zoomArrowN 1157static XPoint zoomArrow[zoomArrowN] = {58{29,14},{38,23},{33,23},59{40,45},{53,45},60{29,69},61{5,45},{18,45},62{25,23},{20,23},{29,14} };6364/* Defines the pixmap for the arrows displayed in the translate window */65#define translateArrowN 2566static XPoint translateArrow[translateArrowN] = {67{55,2},{60,10},{58,10},{58,37},68{85,37},{85,35},{93,40},{85,45},{85,43},{58,43},69{58,70},{60,70},{55,78},{50,70},{52,70},{52,43},70{25,43},{25,45},{17,40},{25,35},{25,37},{52,37},71{52,10},{50,10},{55,2} };7273static int rotateX, rotateY, rotateR;7475/*76void drawColorMap ()77*/7879void80drawColorMap (void)81{8283controlPanelStruct *cp;84int i,shadeWidth;8586/* Draw the color map window */8788cp = viewport->controlPanel;8990XClearArea(dsply,cp->controlWindow,5,colormapY,colormapW,colormapH,False);9192/* if window is grayscale, show the grayscale colormap */93if (mono || (viewport->monoOn)) {94shadeWidth = 230/maxGreyShade;95for (i=0; i<maxGreyShade; i++) {96XChangeShade(dsply, i);97XShadeRectangle(dsply,cp->controlWindow,98colormapX + colorOffsetX + i*shadeWidth,99colormapY + colorOffsetY - 10, shadeWidth, 40);100}101} else {102GDrawString(globalGC2,cp->controlWindow,colorWidth,103colormapY + 13,"-",1,Xoption);104GDrawString(globalGC2,cp->controlWindow,30*colorWidth + 40,105colormapY + 13,"+",1,Xoption);106GDrawString(globalGC2,cp->controlWindow,colorWidth,107colormapY + 46,"-",1,Xoption);108GDrawString(globalGC2,cp->controlWindow,30*colorWidth + 40,109colormapY + 46,"+",1,Xoption);110for (i=0; i<totalHues; i++) {111GSetForeground(anotherGC, (float)XSolidColor(i,2), Xoption);112GDrawLine(anotherGC,cp->controlWindow,113colormapX + i*colorWidth + colorOffsetX,114colormapY + colorOffsetY,115colormapX + i*colorWidth + colorOffsetX,116colormapY + colorOffsetY + colorHeight,Xoption);117}118119if (viewport->hueTop > totalHues-1) viewport->hueTop = totalHues-1;120if (viewport->hueOffset > totalHues-1) viewport->hueOffset = totalHues-1;121122GSetForeground(globGC, (float)monoColor(7), Xoption);123/* Bottom (zmin) color indicator */124GDrawLine(globGC,cp->controlWindow,125colormapX + viewport->hueOffset * colorWidth + colorOffsetX,126colormapY + colorOffsetY+colorHeight,127colormapX + viewport->hueOffset * colorWidth + colorOffsetX,128colormapY + colorOffsetY+colorHeight+colorPointer,Xoption);129130/* Top (zmax) color indicator */131GDrawLine(globGC,cp->controlWindow,132colormapX + viewport->hueTop * colorWidth+colorOffsetX,133colormapY + colorOffsetY,134colormapX + viewport->hueTop * colorWidth+colorOffsetX,135colormapY + colorOffsetY-colorPointer,Xoption);136137/* Connect the bottom and top color indicator bars */138GSetForeground(globGC, (float)monoColor(0), Xoption);139GDrawLine(globGC,cp->controlWindow,140colormapX + viewport->hueOffset * colorWidth + colorOffsetX,141colormapY + colorOffsetY+colorHeight,142colormapX + viewport->hueTop * colorWidth+colorOffsetX,143colormapY + colorOffsetY,Xoption);144}145XSync(dsply,0);146147} /* drawColorMap() */148149150/*******************************151* void writeControlTitle(w) *152* *153* We need the window argument *154* here because there are *155* multiple control panels in *156* 3D. *157*******************************/158159void160writeControlTitle (Window w)161{162int strlength;163164s = viewport->title;165strlength = strlen(s);166XClearArea(dsply,w,0,0,controlWidth,potA,False);167168GSetForeground(anotherGC,(float)controlTitleColor,Xoption);169GDrawString(anotherGC,w,centerX(anotherGC,s,strlength,controlWidth),17015,s,strlength,Xoption);171172} /* writeControlTitle() */173174175/************************************/176/*** void clearControlMessage() ***/177/************************************/178179void180clearControlMessage (void)181{182int strlength;183184strcpy(viewport->controlPanel->message," ");185strlength = strlen(viewport->controlPanel->message);186GDrawImageString(globalGC1,viewport->controlPanel->controlWindow,187centerX(globalGC1,viewport->controlPanel->message,188strlength,controlWidth),189controlMessageY + globalFont->max_bounds.ascent + 8,190viewport->controlPanel->message,strlength,Xoption);191192}193194/************************************/195/*** void writeControlMessage() ***/196/************************************/197198void199writeControlMessage (void)200{201202int strlength;203controlPanelStruct *cp;204205cp = viewport->controlPanel;206strlength = strlen(cp->message);207XClearArea(dsply,cp->controlWindow,2080,controlMessageY+ globalFont->max_bounds.ascent + 8,2090,controlMessageHeight,False);210GSetForeground(globalGC1, (float)controlMessageColor, Xoption);211GDrawImageString(globalGC1,cp->controlWindow,212centerX(globalGC1,cp->message,strlength,controlWidth),213controlMessageY + globalFont->max_bounds.ascent + 8,214cp->message,strlength,Xoption);215216XFlush(dsply);217218}219220/*********************************/221/*** void drawControlPanel() ***/222/*********************************/223224void225drawControlPanel(void )226{227228int offShade=14;229controlPanelStruct *cp;230int i, strlength;231const char* s;232233cp = viewport->controlPanel;234235GSetForeground(trashGC, (float)foregroundColor, Xoption);236237/* Draw border lines to separate the potentiometer, message, colormap and238button regions of the control panel. */239GSetLineAttributes(trashGC, 2, LineSolid, CapButt, JoinMiter, Xoption);240241/* Draw a horizontal white line below the potentiometer area. */242GDrawLine(trashGC, cp->controlWindow, 0, potB-1, controlWidth, potB-1, Xoption);243244/* Draw a horizontal white line above the rendering mode buttons. */245GDrawLine(trashGC, cp->controlWindow, 0, butA, controlWidth, butA, Xoption);246247/* Draw a horizontal white line above the color mapping area. */248GDrawLine(trashGC, cp->controlWindow, 0, cmapA, controlWidth, cmapA, Xoption);249250GSetLineAttributes(trashGC, 3, LineSolid, CapButt, JoinMiter, Xoption);251/* Draw a horizontal white line above the potentiometer area. */252GDrawLine(trashGC, cp->controlWindow, 0, potA, controlWidth, potA, Xoption);253254/* Set the line width as 1 here because it is used below as well. */255GSetLineAttributes(trashGC, 1, LineSolid, CapButt, JoinMiter, Xoption);256257/* Draw inner white lines around quit, hide panel, and reset buttons. */258GDrawLine(trashGC, cp->controlWindow, closeL, butA, closeL, butA+110, Xoption);259260/* Write potentiometer titles on the control panel. */261262writeControlTitle(cp->controlWindow);263GSetForeground(globGC, (float)controlPotHeaderColor, Xoption);264265s = "Rotate";266GDrawString(globGC,cp->controlWindow,35,31+headerHeight,s,strlen(s),Xoption);267s = "Translate";268GDrawString(globGC,cp->controlWindow,202,31+headerHeight,s,strlen(s),Xoption);269s = "Scale";270GDrawString(globGC,cp->controlWindow,126,31+headerHeight,s,strlen(s),Xoption);271272GSetForeground(globGC, (float)controlColorColor, Xoption);273274/* Write labels on regular buttons, draw pixmaps on the potentiometers. */275276GSetForeground(globalGC1, (float)monoColor(buttonColor), Xoption);277278for (i=controlButtonsStart3D; i<(controlButtonsEnd3D); i++) {279/* special cases depending on initial conditions */280281/* check if axes are set on or off */282283if (((cp->buttonQueue[i]).buttonKey == axesOnOff) &&284(viewport->axesOn)) {285(cp->buttonQueue[i]).textColor = onColor;286if (mono) {287GSetForeground(globalGC1, (float)backgroundColor, Xoption);288XFillRectangle(dsply, control->controlWindow, globalGC1,289(control->buttonQueue[axesOnOff]).buttonX,290(control->buttonQueue[axesOnOff]).buttonY,291(control->buttonQueue[axesOnOff]).buttonWidth,292(control->buttonQueue[axesOnOff]).buttonHeight);293GSetForeground(globalGC1, (float)foregroundColor, Xoption);294GDrawRectangle(globalGC1,control->controlWindow,295(control->buttonQueue[axesOnOff]).buttonX,296(control->buttonQueue[axesOnOff]).buttonY,297(control->buttonQueue[axesOnOff]).buttonWidth,298(control->buttonQueue[axesOnOff]).buttonHeight,Xoption);299}300} else {301if (((cp->buttonQueue[i]).buttonKey == axesOnOff) &&302(!viewport->axesOn)) {303(cp->buttonQueue[i]).textColor = offColor;304if (mono) {305XChangeShade(dsply,offShade);306XShadeRectangle(dsply,cp->controlWindow,307(cp->buttonQueue[i]).buttonX,308(cp->buttonQueue[i]).buttonY,309(cp->buttonQueue[i]).buttonWidth,310(cp->buttonQueue[i]).buttonHeight);311s = (control->buttonQueue[axesOnOff]).text;312strlength = strlen(s);313GSetForeground(processGC,314(float)monoColor((control->buttonQueue[axesOnOff]).textColor),Xoption);315GDrawImageString(processGC,control->controlWindow,316(control->buttonQueue[axesOnOff]).buttonX +317centerX(processGC,s,strlength,318(control->buttonQueue[axesOnOff]).buttonWidth),319(control->buttonQueue[axesOnOff]).buttonY +320centerY(processGC,321(control->buttonQueue[axesOnOff]).buttonHeight),322s,strlength,Xoption);323} /* if mono */324}325} /* if axes */326327/* check if bounding region is set on or off */328329if (((cp->buttonQueue[i]).buttonKey == region3D) &&330(viewport->regionOn)) {331(cp->buttonQueue[i]).textColor = onColor;332if (mono) {333GSetForeground(globalGC1, (float)backgroundColor, Xoption);334XFillRectangle(dsply, control->controlWindow, globalGC1,335(control->buttonQueue[region3D]).buttonX,336(control->buttonQueue[region3D]).buttonY,337(control->buttonQueue[region3D]).buttonWidth,338(control->buttonQueue[region3D]).buttonHeight);339GSetForeground(globalGC1, (float)foregroundColor, Xoption);340GDrawRectangle(globalGC1,control->controlWindow,341(control->buttonQueue[region3D]).buttonX,342(control->buttonQueue[region3D]).buttonY,343(control->buttonQueue[region3D]).buttonWidth,344(control->buttonQueue[region3D]).buttonHeight,Xoption);345}346} else {347if (((cp->buttonQueue[i]).buttonKey == region3D) &&348(!viewport->regionOn)) {349(cp->buttonQueue[i]).textColor = offColor;350if (mono) {351XChangeShade(dsply,offShade);352XShadeRectangle(dsply,cp->controlWindow,353(cp->buttonQueue[i]).buttonX,354(cp->buttonQueue[i]).buttonY,355(cp->buttonQueue[i]).buttonWidth,356(cp->buttonQueue[i]).buttonHeight);357s = (control->buttonQueue[region3D]).text;358strlength = strlen(s);359GSetForeground(processGC,360(float)monoColor((control->buttonQueue[region3D]).textColor),Xoption);361GDrawImageString(processGC,control->controlWindow,362(control->buttonQueue[region3D]).buttonX +363centerX(processGC,s,strlength,364(control->buttonQueue[region3D]).buttonWidth),365(control->buttonQueue[region3D]).buttonY +366centerY(processGC,367(control->buttonQueue[region3D]).buttonHeight),368s,strlength,Xoption);369} /* if mono */370}371} /* if bounding region */372373/* check if black and white is set on or off */374375if (((cp->buttonQueue[i]).buttonKey == bwColor) && (mono)) {376(cp->buttonQueue[i]).text = " ";377XChangeShade(dsply,offShade);378XShadeRectangle(dsply,cp->controlWindow,379(cp->buttonQueue[i]).buttonX,380(cp->buttonQueue[i]).buttonY,381(cp->buttonQueue[i]).buttonWidth,382(cp->buttonQueue[i]).buttonHeight);383} else {384if (((cp->buttonQueue[i]).buttonKey == bwColor) && viewport->monoOn) {385(cp->buttonQueue[i]).textColor = onColor;386s = (control->buttonQueue[bwColor]).text;387strlength = strlen(s);388389GSetForeground(processGC,390(float)monoColor((control->buttonQueue[bwColor]).textColor),Xoption);391GDrawImageString(processGC,control->controlWindow,392(control->buttonQueue[bwColor]).buttonX +393centerX(processGC,s,strlength,394(control->buttonQueue[bwColor]).buttonWidth),395(control->buttonQueue[bwColor]).buttonY +396centerY(processGC,397(control->buttonQueue[bwColor]).buttonHeight),398s,strlength,Xoption);399} else {400if (((cp->buttonQueue[i]).buttonKey == bwColor) && (!viewport->monoOn)) {401(cp->buttonQueue[i]).textColor = offColor;402s = (control->buttonQueue[bwColor]).text;403strlength = strlen(s);404405GSetForeground(processGC,406(float)monoColor((control->buttonQueue[bwColor]).textColor),Xoption);407GDrawImageString(processGC,control->controlWindow,408(control->buttonQueue[bwColor]).buttonX +409centerX(processGC,s,strlength,410(control->buttonQueue[bwColor]).buttonWidth),411(control->buttonQueue[bwColor]).buttonY +412centerY(processGC,413(control->buttonQueue[bwColor]).buttonHeight),414s,strlength,Xoption);415}416}417} /* if black and white */418419/* check if object rotation is set on or off */420421if (((cp->buttonQueue[i]).buttonKey == objectr) &&422(viewport->objectrOn)) {423(control->buttonQueue[objectr]).textColor = onColor;424if (mono) {425GSetForeground(globalGC1, (float)backgroundColor, Xoption);426XFillRectangle(dsply, control->controlWindow, globalGC1,427(control->buttonQueue[objectr]).buttonX,428(control->buttonQueue[objectr]).buttonY,429(control->buttonQueue[objectr]).buttonWidth,430(control->buttonQueue[objectr]).buttonHeight);431GSetForeground(globalGC1, (float)foregroundColor, Xoption);432GDrawRectangle(globalGC1,control->controlWindow,433(control->buttonQueue[objectr]).buttonX,434(control->buttonQueue[objectr]).buttonY,435(control->buttonQueue[objectr]).buttonWidth,436(control->buttonQueue[objectr]).buttonHeight,Xoption);437}438} else {439if (((cp->buttonQueue[i]).buttonKey == objectr) &&440(!viewport->objectrOn)) {441(control->buttonQueue[objectr]).textColor = offColor;442if (mono) {443XChangeShade(dsply,offShade);444XShadeRectangle(dsply,control->controlWindow,445(control->buttonQueue[objectr]).buttonX,446(control->buttonQueue[objectr]).buttonY,447(control->buttonQueue[objectr]).buttonWidth,448(control->buttonQueue[objectr]).buttonHeight);449GSetForeground(globalGC1, (float)foregroundColor, Xoption);450GDrawRectangle(globalGC1,control->controlWindow,451(control->buttonQueue[objectr]).buttonX,452(control->buttonQueue[objectr]).buttonY,453(control->buttonQueue[objectr]).buttonWidth,454(control->buttonQueue[objectr]).buttonHeight,Xoption);455GSetForeground(processGC,456(float)monoColor((control->buttonQueue[objectr]).textColor),Xoption);457GDrawImageString(processGC,control->controlWindow,458(control->buttonQueue[objectr]).buttonX +459centerX(processGC,(control->buttonQueue[objectr]).text,460strlen((control->buttonQueue[objectr]).text),461(control->buttonQueue[objectr]).buttonWidth),462(control->buttonQueue[objectr]).buttonY +463centerY(processGC,464(control->buttonQueue[objectr]).buttonHeight),465(control->buttonQueue[objectr]).text,466strlen((control->buttonQueue[objectr]).text),Xoption);467}468} /* else not object rotation */469} /* if object rotation */470471/* check if origin rotation is set on or off */472473if (((cp->buttonQueue[i]).buttonKey == originr) &&474(viewport->originrOn)) {475(control->buttonQueue[originr]).textColor = onColor;476if (mono) {477GSetForeground(globalGC1, (float)backgroundColor, Xoption);478XFillRectangle(dsply, control->controlWindow, globalGC1,479(control->buttonQueue[originr]).buttonX,480(control->buttonQueue[originr]).buttonY,481(control->buttonQueue[originr]).buttonWidth,482(control->buttonQueue[originr]).buttonHeight);483GSetForeground(globalGC1, (float)foregroundColor, Xoption);484GDrawRectangle(globalGC1,control->controlWindow,485(control->buttonQueue[originr]).buttonX,486(control->buttonQueue[originr]).buttonY,487(control->buttonQueue[originr]).buttonWidth,488(control->buttonQueue[originr]).buttonHeight,Xoption);489}490} else {491if (((cp->buttonQueue[i]).buttonKey == originr) &&492(!viewport->originrOn)) {493(control->buttonQueue[originr]).textColor = offColor;494if (mono) {495XChangeShade(dsply,offShade);496XShadeRectangle(dsply,control->controlWindow,497(control->buttonQueue[originr]).buttonX,498(control->buttonQueue[originr]).buttonY,499(control->buttonQueue[originr]).buttonWidth,500(control->buttonQueue[originr]).buttonHeight);501GSetForeground(globalGC1, (float)foregroundColor, Xoption);502GDrawRectangle(globalGC1,control->controlWindow,503(control->buttonQueue[originr]).buttonX,504(control->buttonQueue[originr]).buttonY,505(control->buttonQueue[originr]).buttonWidth,506(control->buttonQueue[originr]).buttonHeight,Xoption);507508GSetForeground(processGC,509(float)monoColor((control->buttonQueue[originr]).textColor),Xoption);510GDrawImageString(processGC,control->controlWindow,511(control->buttonQueue[originr]).buttonX +512centerX(processGC,(control->buttonQueue[originr]).text,513strlen((control->buttonQueue[originr]).text),514(control->buttonQueue[originr]).buttonWidth),515(control->buttonQueue[originr]).buttonY +516centerY(processGC,517(control->buttonQueue[originr]).buttonHeight),518(control->buttonQueue[originr]).text,519strlen((control->buttonQueue[originr]).text),Xoption);520}521} /* else not origin rotation */522} /* if origin rotation */523524/* check if zoom X is set on or off */525526if (((cp->buttonQueue[i]).buttonKey == zoomx) &&527(viewport->zoomXOn)) {528(control->buttonQueue[zoomx]).textColor = onColor;529if (mono) {530GSetForeground(globalGC1, (float)backgroundColor, Xoption);531XFillRectangle(dsply, control->controlWindow, globalGC1,532(control->buttonQueue[zoomx]).buttonX,533(control->buttonQueue[zoomx]).buttonY,534(control->buttonQueue[zoomx]).buttonWidth,535(control->buttonQueue[zoomx]).buttonHeight);536GSetForeground(globalGC1, (float)foregroundColor, Xoption);537GDrawRectangle(globalGC1,control->controlWindow,538(control->buttonQueue[zoomx]).buttonX,539(control->buttonQueue[zoomx]).buttonY,540(control->buttonQueue[zoomx]).buttonWidth,541(control->buttonQueue[zoomx]).buttonHeight,Xoption);542}543} else {544if (((cp->buttonQueue[i]).buttonKey == zoomx) &&545(!viewport->zoomXOn)) {546(control->buttonQueue[zoomx]).textColor = offColor;547if (mono) {548XChangeShade(dsply,offShade);549XShadeRectangle(dsply,control->controlWindow,550(control->buttonQueue[zoomx]).buttonX,551(control->buttonQueue[zoomx]).buttonY,552(control->buttonQueue[zoomx]).buttonWidth,553(control->buttonQueue[zoomx]).buttonHeight);554GSetForeground(globalGC1, (float)foregroundColor, Xoption);555GDrawRectangle(globalGC1,control->controlWindow,556(control->buttonQueue[zoomx]).buttonX,557(control->buttonQueue[zoomx]).buttonY,558(control->buttonQueue[zoomx]).buttonWidth,559(control->buttonQueue[zoomx]).buttonHeight,Xoption);560561GSetForeground(processGC,562(float)monoColor((control->buttonQueue[zoomx]).textColor),Xoption);563GDrawImageString(processGC,control->controlWindow,564(control->buttonQueue[zoomx]).buttonX +565centerX(processGC,(control->buttonQueue[zoomx]).text,566strlen((control->buttonQueue[zoomx]).text),567(control->buttonQueue[zoomx]).buttonWidth),568(control->buttonQueue[zoomx]).buttonY +569centerY(processGC,570(control->buttonQueue[zoomx]).buttonHeight),571(control->buttonQueue[zoomx]).text,572strlen((control->buttonQueue[zoomx]).text),Xoption);573}574} /* else not zoom X */575} /* if zoom X */576577/* check if zoom Y is set on or off */578579if (((cp->buttonQueue[i]).buttonKey == zoomy) &&580(viewport->zoomYOn)) {581(control->buttonQueue[zoomy]).textColor = onColor;582if (mono) {583GSetForeground(globalGC1, (float)backgroundColor, Xoption);584XFillRectangle(dsply, control->controlWindow, globalGC1,585(control->buttonQueue[zoomy]).buttonX,586(control->buttonQueue[zoomy]).buttonY,587(control->buttonQueue[zoomy]).buttonWidth,588(control->buttonQueue[zoomy]).buttonHeight);589GSetForeground(globalGC1, (float)foregroundColor, Xoption);590GDrawRectangle(globalGC1, control->controlWindow,591(control->buttonQueue[zoomy]).buttonX,592(control->buttonQueue[zoomy]).buttonY,593(control->buttonQueue[zoomy]).buttonWidth,594(control->buttonQueue[zoomy]).buttonHeight,Xoption);595}596} else {597if (((cp->buttonQueue[i]).buttonKey == zoomy) &&598(!viewport->zoomYOn)) {599(control->buttonQueue[zoomy]).textColor = offColor;600if (mono) {601XChangeShade(dsply,offShade);602XShadeRectangle(dsply,control->controlWindow,603(control->buttonQueue[zoomy]).buttonX,604(control->buttonQueue[zoomy]).buttonY,605(control->buttonQueue[zoomy]).buttonWidth,606(control->buttonQueue[zoomy]).buttonHeight);607GSetForeground(globalGC1, (float)foregroundColor, Xoption);608GDrawRectangle(globalGC1,control->controlWindow,609(control->buttonQueue[zoomy]).buttonX,610(control->buttonQueue[zoomy]).buttonY,611(control->buttonQueue[zoomy]).buttonWidth,612(control->buttonQueue[zoomy]).buttonHeight,Xoption);613614GSetForeground(processGC,615(float)monoColor((control->buttonQueue[zoomy]).textColor),Xoption);616GDrawImageString(processGC,control->controlWindow,617(control->buttonQueue[zoomy]).buttonX +618centerX(processGC,(control->buttonQueue[zoomy]).text,619strlen((control->buttonQueue[zoomy]).text),620(control->buttonQueue[zoomy]).buttonWidth),621(control->buttonQueue[zoomy]).buttonY +622centerY(processGC,623(control->buttonQueue[zoomy]).buttonHeight),624(control->buttonQueue[zoomy]).text,625strlen((control->buttonQueue[zoomy]).text),Xoption);626}627} /* else not zoom Y */628} /* if zoom Y */629630/* check if zoom Z is set on or off */631632if (((cp->buttonQueue[i]).buttonKey == zoomz) &&633(viewport->zoomZOn)) {634(control->buttonQueue[zoomz]).textColor = onColor;635if (mono) {636GSetForeground(globalGC1, (float)backgroundColor, Xoption);637XFillRectangle(dsply, control->controlWindow, globalGC1,638(control->buttonQueue[zoomz]).buttonX,639(control->buttonQueue[zoomz]).buttonY,640(control->buttonQueue[zoomz]).buttonWidth,641(control->buttonQueue[zoomz]).buttonHeight);642GSetForeground(globalGC1, (float)foregroundColor, Xoption);643GDrawRectangle(globalGC1,control->controlWindow,644(control->buttonQueue[zoomz]).buttonX,645(control->buttonQueue[zoomz]).buttonY,646(control->buttonQueue[zoomz]).buttonWidth,647(control->buttonQueue[zoomz]).buttonHeight,Xoption);648}649} else {650if (((cp->buttonQueue[i]).buttonKey == zoomz) &&651(!viewport->zoomZOn)) {652(control->buttonQueue[zoomz]).textColor = offColor;653if (mono) {654XChangeShade(dsply,offShade);655XShadeRectangle(dsply,control->controlWindow,656(control->buttonQueue[zoomz]).buttonX,657(control->buttonQueue[zoomz]).buttonY,658(control->buttonQueue[zoomz]).buttonWidth,659(control->buttonQueue[zoomz]).buttonHeight);660GSetForeground(globalGC1, (float)foregroundColor, Xoption);661GDrawRectangle(globalGC1,control->controlWindow,662(control->buttonQueue[zoomz]).buttonX,663(control->buttonQueue[zoomz]).buttonY,664(control->buttonQueue[zoomz]).buttonWidth,665(control->buttonQueue[zoomz]).buttonHeight,Xoption);666667GSetForeground(processGC,668(float)monoColor((control->buttonQueue[zoomz]).textColor),Xoption);669GDrawImageString(processGC,control->controlWindow,670(control->buttonQueue[zoomz]).buttonX +671centerX(processGC,(control->buttonQueue[zoomz]).text,672strlen((control->buttonQueue[zoomz]).text),673(control->buttonQueue[zoomz]).buttonWidth),674(control->buttonQueue[zoomz]).buttonY +675centerY(processGC,676(control->buttonQueue[zoomz]).buttonHeight),677(control->buttonQueue[zoomz]).text,678strlen((control->buttonQueue[zoomz]).text),Xoption);679}680} /* else not zoom Y */681} /* if zoom Y */682683/* check if outline is set on or off */684685if (((cp->buttonQueue[i]).buttonKey == outlineOnOff) &&686(viewData.outlineRenderOn)) {687(cp->buttonQueue[i]).textColor = onColor;688} else {689if (((cp->buttonQueue[i]).buttonKey == outlineOnOff) &&690!(viewData.outlineRenderOn)) {691(cp->buttonQueue[i]).textColor = offColor;692if (mono) {693XChangeShade(dsply,offShade);694XShadeRectangle(dsply,cp->controlWindow,695(cp->buttonQueue[i]).buttonX,696(cp->buttonQueue[i]).buttonY,697(cp->buttonQueue[i]).buttonWidth,698(cp->buttonQueue[i]).buttonHeight);699s = (control->buttonQueue[outlineOnOff]).text;700strlength = strlen(s);701702GSetForeground(processGC,703(float)monoColor((control->buttonQueue[outlineOnOff]).textColor),Xoption);704GDrawImageString(processGC,control->controlWindow,705(control->buttonQueue[outlineOnOff]).buttonX +706centerX(processGC,s,strlength,707(control->buttonQueue[outlineOnOff]).buttonWidth),708(control->buttonQueue[outlineOnOff]).buttonY +709centerY(processGC,710(control->buttonQueue[outlineOnOff]).buttonHeight),711s,strlength,Xoption);712} /* if mono */713} /* outline off */714} /* outline on */715716/* Draw the button window border */717718GDraw3DButtonOut(globalGC1,cp->controlWindow,719(cp->buttonQueue[i]).buttonX, (cp->buttonQueue[i]).buttonY,720(cp->buttonQueue[i]).buttonWidth,721(cp->buttonQueue[i]).buttonHeight,Xoption);722723GSetForeground(trashGC,724(float)monoColor((cp->buttonQueue[i]).textColor), Xoption);725switch (i) {726case rotate:727GDrawArc(trashGC, cp->controlWindow,728rotateX, rotateY, rotateR, rotateR, 0, 360*64, Xoption);729break;730731case zoom:732GDrawLines(trashGC, cp->controlWindow, zoomArrow, zoomArrowN,733CoordModeOrigin, Xoption);734break;735736case translate:737GDrawLines(trashGC, cp->controlWindow, translateArrow,738translateArrowN, CoordModeOrigin, Xoption);739break;740741default:742s = (cp->buttonQueue[i]).text;743strlength = strlen(s);744GDrawString(trashGC, cp->controlWindow,745(cp->buttonQueue[i]).buttonX +746centerX(processGC,s,strlength,747(cp->buttonQueue[i]).buttonWidth),748(cp->buttonQueue[i]).buttonY +749centerY(processGC,750(cp->buttonQueue[i]).buttonHeight),s,strlen(s),Xoption);751break;752};753754if ((cp->buttonQueue[i]).pot) {755/* draw horizontal and vertical centerlines */756757GDrawLine(globalGC1,cp->controlWindow,758(cp->buttonQueue[i]).buttonX + (cp->buttonQueue[i]).xHalf,759(cp->buttonQueue[i]).buttonY,760(cp->buttonQueue[i]).buttonX + (cp->buttonQueue[i]).xHalf,761(cp->buttonQueue[i]).buttonY + 2*(cp->buttonQueue[i]).yHalf,Xoption);762763GDrawLine(globalGC1,cp->controlWindow,764(cp->buttonQueue[i]).buttonX,765(cp->buttonQueue[i]).buttonY + (cp->buttonQueue[i]).yHalf,766(cp->buttonQueue[i]).buttonX + 2*(cp->buttonQueue[i]).xHalf,767(cp->buttonQueue[i]).buttonY + (cp->buttonQueue[i]).yHalf,Xoption);768}769}770771/* refresh the latest message */772clearControlMessage();773strcpy(control->message,viewport->title);774writeControlMessage();775776/* Draw the color map window */777cp = viewport->controlPanel;778drawColorMap();779XFlush(dsply);780781} /* drawControlPanel() */782783784/*****************************785* void getControlXY() *786* *787* Determines the x and y *788* coordinate where the *789* control panel is to be *790* placed, based upon where *791* the mouse button was *792* pressed within the graph *793* viewport window. *794*****************************/795796controlXY797getControlXY (int whereDoYouWantPanel)798{799800XWindowAttributes wAttrib;801controlXY cXY;802int viewX, viewY, viewW, viewH, tmp=1;803Window rootW, parentW, *childrenWs, tmpW;804unsigned int nChildren;805806tmpW = viewport->titleWindow;807while(tmp) {808XQueryTree(dsply,tmpW,&rootW,&parentW,&childrenWs,&nChildren);809XFree(childrenWs);810if (parentW == rtWindow) {811tmp = 0;812} else {813tmpW = parentW;814}815}816XGetWindowAttributes(dsply,tmpW,&wAttrib);817818viewX = wAttrib.x;819viewY = wAttrib.y;820viewW = wAttrib.width;821viewH = wAttrib.height;822823if (whereDoYouWantPanel) {824switch (whereDoYouWantPanel) {825case 1: /* right */826cXY.putX = viewX + viewW;827cXY.putY = viewY;828break;829case 2: /* bottom */830cXY.putX = viewX + (viewW - controlWidth)/2; /* center it */831cXY.putY = viewY + viewH;832break;833case 3: /* left */834cXY.putX = viewX - controlWidth - borderWidth;835cXY.putY = viewY;836break;837case 4: /* top */838cXY.putX = viewX + (viewW - controlWidth)/2; /* center it */839cXY.putY = viewY - controlHeight - borderHeight;840}841} else {842if ((physicalWidth - (viewX + viewW)) >= controlWidth) {843cXY.putX = viewX + viewW;844cXY.putY = viewY;845} else if ((physicalHeight - (viewY + viewH)) >= controlHeight) {846cXY.putX = viewX + (viewW - controlWidth)/2; /* center it */847cXY.putY = viewY + viewH;848} else if (viewX >= controlWidth) {849cXY.putX = viewX - controlWidth - borderWidth;850cXY.putY = viewY;851} else if (viewY >= controlHeight) {852cXY.putX = viewX + (viewW - controlWidth)/2; /* center it */853cXY.putY = viewY - controlHeight - borderHeight;854} else { /* put inside of viewport */855cXY.putX = viewX + viewW - controlWidth;856cXY.putY = viewY + viewH - controlHeight;857}858}859if (cXY.putX < 0) cXY.putX = 0;860if (cXY.putY < 0) cXY.putY = 0;861return(cXY);862863}864865866867/************************************************/868/*** controlPanelStruct *makeControlPanel() ***/869/************************************************/870871controlPanelStruct *872makeControlPanel (void)873{874875Window cw;876int i;877controlPanelStruct *control;878buttonStruct *buttons;879controlXY cXY;880XSetWindowAttributes cwAttrib, controlAttrib;881XSizeHints sizehint;882Pixmap mousebits, mousemask;883XColor foreColor, backColor;884885if (!(control = (controlPanelStruct *)saymem("control.c",1,886sizeof(controlPanelStruct)))) {887fprintf(stderr,"Ran out of memory trying to create control panel.\n");888exitWithAck(RootWindow(dsply,scrn),Window,-1);889}890891cXY = getControlXY(0);892893mousebits = XCreateBitmapFromData(dsply,rtWindow,894(const char*) mouseBitmap_bits,895mouseBitmap_width, mouseBitmap_height);896mousemask = XCreateBitmapFromData(dsply,rtWindow,897(const char*) mouseMask_bits,898mouseMask_width, mouseMask_height);899cwAttrib.background_pixel = backgroundColor;900cwAttrib.border_pixel = foregroundColor;901cwAttrib.event_mask = controlMASK;902cwAttrib.colormap = colorMap;903cwAttrib.override_redirect = overrideManager;904foreColor.pixel = controlCursorForeground;905XQueryColor(dsply,colorMap,&foreColor);906backColor.pixel = controlCursorBackground;907XQueryColor(dsply,colorMap,&backColor);908cwAttrib.cursor = XCreatePixmapCursor(dsply,mousebits,909mousemask, &foreColor,&backColor,910mouseBitmap_x_hot,mouseBitmap_y_hot);911cw = XCreateWindow(dsply,rtWindow,912cXY.putX,cXY.putY,controlWidth,controlHeight,3,913CopyFromParent,InputOutput,CopyFromParent,914controlCreateMASK,&cwAttrib);915916sizehint.flags = PPosition | PSize;917sizehint.x = cXY.putX;918sizehint.y = cXY.putY;919sizehint.width = controlWidth;920sizehint.height = controlHeight;921/*** the None stands for icon pixmap ***/922XSetNormalHints(dsply,cw,&sizehint);923XSetStandardProperties(dsply,cw,"3D Control Panel","3D Control Panel",924None,NULL,0,&sizehint);925926/* Define and assign a mouse cursor */927control->controlWindow = cw;928929initButtons(control->buttonQueue);930buttons = control->buttonQueue;931for (i=controlButtonsStart3D; i<(controlButtonsEnd3D); i++) {932controlAttrib.event_mask = (control->buttonQueue[i]).mask;933(control->buttonQueue[i]).self = XCreateWindow(dsply,cw,934(control->buttonQueue[i]).buttonX,935(control->buttonQueue[i]).buttonY,936(control->buttonQueue[i]).buttonWidth,937(control->buttonQueue[i]).buttonHeight,9380,0,InputOnly,CopyFromParent,939buttonCreateMASK,&controlAttrib);940XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,941&((control->buttonQueue[i]).buttonKey));942/* use buttonKey and not i because buttonKey has a permanent address */943944XMapWindow(dsply,(control->buttonQueue[i]).self);945946} /* for each button */947948949/* Set up the potentiometer pixmaps. */950for (i=0; i<zoomArrowN; i++) {951zoomArrow[i].x += buttons[zoom].buttonX;952zoomArrow[i].y += buttons[zoom].buttonY;953}954for (i=0; i<translateArrowN; i++) {955translateArrow[i].x += buttons[translate].buttonX;956translateArrow[i].y += buttons[translate].buttonY;957}958959rotateX = control->buttonQueue[rotate].buttonX+17;960rotateY = control->buttonQueue[rotate].buttonY+2;961rotateR = control->buttonQueue[rotate].buttonHeight-4;962963strcpy(control->message," ");964965/* Create the color mapping window */966controlAttrib.event_mask = colorMASK;967control->colormapWindow = XCreateWindow(dsply,cw, colorWidth,colormapY,968colormapW,colormapH,0, 0,InputOnly,969CopyFromParent, colormapCreateMASK,970&controlAttrib);971XMapWindow(dsply,control->colormapWindow);972viewport->justMadeControl = yes;973974return(control);975976} /* makeControlPanel() */977978979980981/******************************************982* void putControlPanelSomewhere() *983* This routine puts up the control panel *984* associated with the viewport passed *985* in. It first tries to put it to the *986* right of the viewport. If there isn't *987* enough room, it tries the bottom and *988* so on going clockwise. If the viewport *989* is too big and there is no room to put *990* the control panel outside of it, the *991* control panel is placed on the bottom *992* right hand corner of the viewport. *993*****************************************/994995void996putControlPanelSomewhere (int whereDoesPanelGo)997{998controlPanelStruct *control;999controlXY whereControl;10001001control = viewport->controlPanel;1002whereControl = getControlXY(whereDoesPanelGo);10031004viewport->haveControl = yes;10051006XRaiseWindow(dsply,control->controlWindow);1007XMoveWindow(dsply, control->controlWindow,1008whereControl.putX, whereControl.putY);10091010drawControlPanel();1011XSync(dsply,0);1012if (viewport->justMadeControl) {1013XMapWindow(dsply,control->controlWindow);1014viewport->justMadeControl = no;1015}1016XMapWindow(dsply,control->controlWindow);1017XFlush(dsply);10181019}102010211022102310241025