/*
$Id: macdriv.c,v 1.1.1.1 1996/11/04 12:05:46 roitzsch Exp $
(C)opyright 1996 by Konrad-Zuse-Center, Berlin
All rights reserved.
Part of the common environment
$Log: macdriv.c,v $
Revision 1.1.1.1 1996/11/04 12:05:46 roitzsch
minigraph module
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#include <Quickdraw.h>
#include <ToolUtils.h>
#include <Fonts.h>
#include <Events.h>
#include <Events.h>
#include <Windows.h>
#include <Dialogs.h>
#include <Menus.h>
#include <TextEdit.h>
#include <Scrap.h>
#ifdef THINK_C
#include <Palettes.h>
#include <pascal.h>
#else
#include <Palettes.h>
/* #include <SysEqu.h> */
#endif
#include "minigraph.h"
#define K180PI 57.29578
#define CMTOPT 0.1
#define PTTOCM 10.0
/*
#define TRANSX(X) ((X)*(graph->xScal)+(graph->xTrans))
#define TRANSY(Y) (graph->wdHght-(Y)*(graph->yScal)-(graph->yTrans))
*/
#define TRANSX(X) ((X)*(graph->xScal)+(graph->xTrans))
#define TRANSY(Y) (-(Y)*(graph->yScal)-(graph->yTrans)+(graph->wdHght))
#define maxWindows 16
#define maxColors 64
static real real_min = SHRT_MIN, real_max = SHRT_MAX;
static char *fontName ="courier";
static char *captionName ="MiniGraphic";
static real fontSize[3] = {10.0, 12.0, 14.0};
static real lineWidth[3] = {1.0, 2.0, 3.0};
#define MAXMACMARKERS 7
static char macMarkers[MAXMACMARKERS] =
{ ' ', '*', 'x', '+', '¥', 'Æ', '×' };
static int dyMarker[MAXMACMARKERS] =
{ 0, 5, 3, 3, 3, 3, 4 };
static int *rVals=nil, *gVals=nil, *bVals=nil;
static WindowRecord wRecords[maxWindows];
static WindowPtr myWindows[maxWindows];
static Rect screenRect;
static int MacOpenPort(GRAPHIC *graph)
{
int no = graph->wdNo, size;
short font;
int top = graph->wdOrgY-graph->wdHght, left = graph->wdOrgX,
height = graph->wdHght, width = graph->wdWdth;
PaletteHandle ph;
RGBColor newColor;
int k;
if (graph->ready) return true;
if ((graph->wdOrgX)==-1.0)
{
graph->wdWdth = (graph->right-graph->left)*0.5;
graph->wdHght = (graph->bottom-graph->top)*0.5-16.0;
switch (no)
{
case 0:
graph->wdOrgX = (graph->right)*0.5;
graph->wdOrgY = (graph->bottom-graph->top)*0.5+20;
break;
case 1:
graph->wdOrgX = graph->left;
graph->wdOrgY = (graph->bottom-graph->top)*0.5+20;
break;
case 2:
graph->wdOrgX = graph->left;
graph->wdOrgY = graph->bottom;
break;
case 3:
graph->wdOrgX = (graph->right)*0.5;
graph->wdOrgY = graph->bottom;
break;
}
}
top = graph->wdOrgY-graph->wdHght;
left = graph->wdOrgX;
height = graph->wdHght;
width = graph->wdWdth;
myWindows[no] = GetNewCWindow(501, (Ptr)&wRecords[no],
(WindowPtr) -1);
if (myWindows[no]==nil)
{
fprintf(miniErrorFile,"MacOpenPort failed\n");
return false;
}
MoveWindow(myWindows[no], left, top, false);
SizeWindow(myWindows[no], width, height, false),
#ifdef THINK_C
SetWTitle(myWindows[no], CtoPstr(graph->caption));
PtoCstr((unsigned char*)graph->caption);
#else
setwtitle(myWindows[no], graph->caption);
#endif
SetPort(myWindows[no]);
ph = GetPalette(myWindows[no]);
for (k=0; k<maxColors; k++)
{
if (rVals[k]==-1) continue;
newColor.red = 256*rVals[k];
newColor.green = 256*gVals[k];
newColor.blue = 256*bVals[k];
SetEntryColor(ph, k+32, &newColor);
/* rVals[k] = gVals[k] = bVals[k] = -1; */
}
ShowWindow(myWindows[no]);
ClipRect(&(myWindows[no]->portRect));
PmBackColor(graph->backgrCol);
EraseRect(&(myWindows[no]->portRect));
#ifdef THINK_C
GetFNum(CtoPstr(graph->fontName), &font);
PtoCstr((unsigned char*)graph->fontName);
#else
getfnum(graph->fontName, &font);
#endif
TextFont(font);
size = graph->drFntSz;
TextSize(size);
size = graph->drPenSz;
PenSize(size, size);
graph->ready = true;
return true;
}
static int MacNewPict(GRAPHIC *graph)
{
int ind = graph->wdNo;
if (!(graph->ready)) return false;
SetPort(myWindows[ind]);
ClipRect(&(myWindows[ind]->portRect));
PmBackColor(graph->backgrCol);
EraseRect(&(myWindows[ind]->portRect));
return true;
}
/*
static int MacShow(graph)
GRAPHIC *graph;
{
int ind = graph->wdNo;
EventRecord myEvent;
if (!(graph->ready)) return false;
myEvent.what = 0;
SetPort(myWindows[ind]);
while (true)
{
GetNextEvent(everyEvent,&myEvent);
if (myEvent.what==mouseDown) break;
}
return true;
}
*/
static int MacClose(GRAPHIC *graph)
{
int ind = graph->wdNo;
if (!(graph->ready)) return false;
CloseWindow(myWindows[ind]);
myWindows[ind] = nil;
graph->wdNo = -1;
SetPort(FrontWindow());
SetCursor(&(qd.arrow));
return true;
}
static int MacPLine(GRAPHIC *graph, void *xAdr, void *yAdr, int n)
{
int k, px, py, size;
real x, y, xt, yt;
SetPort(myWindows[graph->wdNo]);
PmForeColor(graph->penCol);
size = graph->drPenSz;
PenSize(size, size);
if ((graph->prec)==SINGLE)
{ x = ((float*)xAdr)[0]; y = ((float*)yAdr)[0]; }
else
{ x = ((double*)xAdr)[0]; y = ((double*)yAdr)[0]; }
xt = TRANSX(x); yt = TRANSY(y);
if ((xt<real_min)||(xt>real_max)||
(yt<real_min)||(yt>real_max)) return true;
px = xt; py = yt;
MoveTo(px, py);
for (k=1; k<n; k++)
{
if ((graph->prec)==SINGLE)
{ x = ((float*)xAdr)[k]; y = ((float*)yAdr)[k]; }
else
{ x = ((double*)xAdr)[k]; y = ((double*)yAdr)[k]; }
xt = TRANSX(x); yt = TRANSY(y);
if ((xt<real_min)||(xt>real_max)||
(yt<real_min)||(yt>real_max)) return true;
px = xt; py = yt;
LineTo(px, py);
}
return true;
}
static int MacPMarker(GRAPHIC *graph, void *xAdr, void *yAdr, int n)
{
int k, px, py, size;
real x, y, xt, yt;
char s[2];
SetPort(myWindows[graph->wdNo]);
PmForeColor(graph->mrkCol);
size = fontSize[MEDIUM];
TextSize(size);
#ifdef THINK_C
s[0] = 1; s[1] = macMarkers[graph->mark];
#else
s[0] = macMarkers[graph->mark]; s[1] = '\0';
#endif
for (k=0; k<n; k++)
{
if ((graph->prec)==SINGLE)
{ x = ((float*)xAdr)[k]; y = ((float*)yAdr)[k]; }
else
{ x = ((double*)xAdr)[k]; y = ((double*)yAdr)[k]; }
xt = TRANSX(x); yt = TRANSY(y);
if ((xt<real_min)||(xt>real_max)||
(yt<real_min)||(yt>real_max)) return true;
px = xt-2; py = yt+dyMarker[graph->mark];
MoveTo(px, py);
#ifdef THINK_C
DrawString((unsigned char*)s);
#else
drawstring(s);
#endif
}
size = graph->drFntSz;
TextSize(size);
return true;
}
#ifdef __cplusplus
static int MacString(GRAPHIC *graph, real x,real y, const char *s)
#else
static int MacString(GRAPHIC *graph, real x,real y, char *s)
#endif
{
int px, py, size;
int xt = TRANSX(x), yt = TRANSY(y);
if ((xt<real_min)||(xt>real_max)||
(yt<real_min)||(yt>real_max)) return true;
SetPort(myWindows[graph->wdNo]);
PmForeColor(graph->fntCol);
size = graph->drFntSz;
TextSize(size);
px = xt; py = yt;
MoveTo(px, py);
#ifdef THINK_C
DrawString(CtoPstr(s));
PtoCstr((unsigned char*)s);
#else
drawstring(s);
#endif
return true;
}
static int MacFill(GRAPHIC *graph, void *xAdr, void *yAdr, int n)
{
int k, px, py, px0, py0;
real x, y, xt, yt;
PolyHandle Tr;
SetPort(myWindows[graph->wdNo]);
PmForeColor(graph->fllCol);
if ((graph->prec)==SINGLE)
{ x = ((float*)xAdr)[0]; y = ((float*)yAdr)[0]; }
else
{ x = ((double*)xAdr)[0]; y = ((double*)yAdr)[0]; }
xt = TRANSX(x); yt = TRANSY(y);
if ((xt<real_min)||(xt>real_max)||
(yt<real_min)||(yt>real_max)) return true;
px0 = xt; py0 = yt;
Tr = OpenPoly();
MoveTo(px0, py0);
for (k=1; k<n; k++)
{
if ((graph->prec)==SINGLE)
{ x = ((float*)xAdr)[k]; y = ((float*)yAdr)[k]; }
else
{ x = ((double*)xAdr)[k]; y = ((double*)yAdr)[k]; }
xt = TRANSX(x); yt = TRANSY(y);
if ((xt<real_min)||(xt>real_max)||
(yt<real_min)||(yt>real_max))
{ KillPoly(Tr); return true; }
px = xt; py = yt;
LineTo(px, py);
}
LineTo(px0, py0);
ClosePoly();
PaintPoly(Tr);
KillPoly(Tr);
return true;
}
static int MacSettings(GRAPHIC *graph, int type, void *valAdr)
{
int iVal, size;
switch (type)
{
case WDORGX :
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal <= graph->right))
graph->wdOrgX = iVal;
else
fprintf(miniErrorFile,"MacSettings : wrong value for WDORGX %d\n", iVal);
break;
case WDORGY :
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal <= graph->bottom))
graph->wdOrgY = iVal;
else
fprintf(miniErrorFile,"MacSettings : wrong value for WDORGY %d\n", iVal);
break;
case WDWDTH :
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal + graph->wdOrgX <= graph->right))
graph->wdWdth = iVal;
else
fprintf(miniErrorFile,"MacSettings : wrong value for WDWDTH %d\n", iVal);
break;
case WDHGHT :
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal <= graph->wdOrgY))
graph->wdHght = iVal;
else
fprintf(miniErrorFile,"MacSettings : wrong value for WDHGHT %d\n", iVal);
break;
case PENSIZE:
iVal = *((int*)valAdr);
switch (iVal)
{
case SMALL : graph->drPenSz = lineWidth[SMALL]; break;
case MEDIUM : graph->drPenSz = lineWidth[MEDIUM]; break;
case BIG : graph->drPenSz = lineWidth[BIG]; break;
default : graph->drPenSz = iVal*graph->xScal;
}
break;
case FONTSIZE:
iVal = *((int*)valAdr);
switch (iVal)
{
case SMALL : graph->drFntSz = fontSize[SMALL]; break;
case MEDIUM : graph->drFntSz = fontSize[MEDIUM]; break;
case BIG : graph->drFntSz = fontSize[BIG]; break;
default : graph->drFntSz = iVal*graph->xScal;
}
break;
case MARKER:
iVal = *((int*)valAdr);
if ((iVal>=0)&&(iVal<MAXMACMARKERS))
graph->mark = iVal;
else
fprintf(miniErrorFile,"MacSettings: unkown marker %d\n", iVal);
break;
case FILLCOL:
iVal = *((int*)valAdr);
graph->fllCol = iVal;
break;
case MARKCOL:
iVal = *((int*)valAdr);
graph->mrkCol = iVal;
break;
case FONTCOL:
iVal = *((int*)valAdr);
graph->fntCol = iVal;
break;
case PENCOL:
iVal = *((int*)valAdr);
graph->penCol = iVal;
break;
case BACKGRCOL:
iVal = *((int*)valAdr);
graph->backgrCol = iVal;
break;
case CAPTION:
size = strlen((char*)valAdr);
graph->caption = (char*)malloc(size+1);
strncpy(graph->caption, (char*)valAdr, size+1);
if (graph->ready)
{
SetPort(myWindows[graph->wdNo]);
#ifdef THINK_C
SetWTitle(myWindows[graph->wdNo], CtoPstr(graph->caption));
PtoCstr((unsigned char*)graph->caption);
#else
setwtitle(myWindows[graph->wdNo], graph->caption);
#endif
}
break;
default:
fprintf(miniErrorFile,"MacSettings: unkown type %d\n", type);
break;
}
return true;
}
static int MacWait(GRAPHIC *graph, int *typAdr, int *buttonAdr,
void *xkoordAdr, void *ykoordAdr, int *chAdr)
{
int ind = graph->wdNo, waitLoop = true, whichPart;
float x, y;
EventRecord myEvent;
WindowPtr clickedWindow;
if (!(graph->ready)) return false;
myEvent.what = 0;
*typAdr = *buttonAdr = *chAdr = 0;
if (graph->prec == SINGLE)
*((float*)xkoordAdr) = *((float*)ykoordAdr) = 0.0;
else
*((double*)xkoordAdr) = *((double*)ykoordAdr) = 0.0;
SetPort(myWindows[ind]);
while (waitLoop)
{
GetNextEvent(everyEvent,&myEvent);
switch (myEvent.what)
{
case mouseDown:
whichPart = FindWindow(myEvent.where,&clickedWindow);
if (clickedWindow!=myWindows[ind]) break;
GlobalToLocal(&(myEvent.where));
x = (myEvent.where).h;
y = (myEvent.where).v;
if (graph->prec == SINGLE)
{
*((float*)xkoordAdr) = (x-graph->xTrans)/graph->xScal;
*((float*)ykoordAdr) = (graph->wdHght-y-graph->yTrans)/graph->yScal;
}
else
{
*((double*)xkoordAdr) = (x-graph->xTrans)/graph->xScal;
*((double*)ykoordAdr) = (graph->wdHght-y-graph->yTrans)/graph->yScal;
}
*typAdr |= 8;
*buttonAdr = 1;
waitLoop=false;
break;
case keyDown:
*chAdr = BitAnd(myEvent.message,charCodeMask);
*typAdr |= 4;
if (BitAnd(myEvent.modifiers,shiftKey)) *typAdr |= 2;
if (BitAnd(myEvent.modifiers,controlKey)) *typAdr |= 1;
waitLoop=false;
break;
}
}
return true;
}
static int MacGin (GRAPHIC *graph, int geo, void *x1koordAdr, void *y1koordAdr,
void *x2koordAdr, void *y2koordAdr)
{
static int first = true;
if (first)
{
first = false;
fprintf(miniErrorFile,"zibevent not yet implemented\n");
}
switch (geo)
{
case LINE:
break;
case RECTANGLE:
break;
default:
fprintf(miniErrorFile,"%d as geo for zibgin not implemented\n",geo);
break;
}
return true;
}
static int MacEvent (GRAPHIC *graph, int *typAdr, int *buttonAdr,
void *xkoordAdr, void *ykoordAdr, int *charAdr)
{
static int first = true;
if (first)
{
first = false;
fprintf(miniErrorFile,"zibevent not yet implemented\n");
}
return true;
}
static int MacWindow(GRAPHIC *graph)
{
int no = graph->wdNo;
return true;
}
static int MacColor(int col_no, int rVal, int gVal, int bVal)
{
col_no -= 32;
if ((col_no<0)||(col_no>=maxColors)) return false;
rVals[col_no] = rVal;
gVals[col_no] = gVal;
bVals[col_no] = bVal;
return true;
}
int MacInit(GRAPHIC *graph)
{
int i, k, free;
static int first = true;
BitMap screenBits;
GrafPtr thePort;
if (first)
{
for (k=0; k<maxWindows; k++) myWindows[k]=nil;
InitGraf(&qd.thePort);
InitFonts();
FlushEvents(everyEvent, 0);
InitWindows();
screenRect = qd.screenBits.bounds;
first = false;
screenBits = qd.screenBits;
thePort = qd.thePort;
rVals = (int*)malloc(maxColors*sizeof(int));
gVals = (int*)malloc(maxColors*sizeof(int));
bVals = (int*)malloc(maxColors*sizeof(int));
if (bVals==nil) return false;
for (k=0; k<maxColors; k++)
rVals[k] = gVals[k] = bVals[k] = -1;
}
for (free=0; free<maxWindows; free++)
if (myWindows[free]==nil) break;
if (free==maxWindows)
{ fprintf(miniErrorFile,"More than %d windows\n",graph->maxWd); return false; }
myWindows[free] = (WindowPtr)(-1);
graph->PLine = MacPLine;
graph->PMarker = MacPMarker;
graph->Text = MacString;
graph->Fill = MacFill;
graph->Color = MacColor;
graph->Settings = MacSettings;
graph->NewPict = MacNewPict;
graph->OpenPort = MacOpenPort;
graph->Close = MacClose;
graph->Wait = MacWait;
graph->Gin = MacGin;
graph->Event = MacEvent;
/* graph->Window = MacWindow; */
graph->bottom = screenRect.bottom;
graph->left = screenRect.left;
graph->top = screenRect.top+20.0;
graph->right = screenRect.right;
graph->wdOrgX = -1.0;
graph->wdOrgY = -1.0;
graph->wdWdth = -1.0;
graph->wdHght = -1.0;
graph->drRes = 1.0;
graph->drPenSz = lineWidth[SMALL];
graph->drFntSz = fontSize[MEDIUM];
graph->drXcm = CMTOPT;
graph->drYcm = CMTOPT;
graph->penCol = WHITE;
graph->fntCol = WHITE;
graph->mrkCol = WHITE;
graph->backgrCol = BLACK;
/* graph->fillP = true; */
/* graph->clipP = true; */
graph->maxCol = maxColors;
graph->maxGry = 24;
graph->maxWd = 4;
graph->mark = STAR;
graph->prec = SINGLE;
graph->line_count = 0;
graph->id = MAC;
graph->wdNo = free;
graph->fontName = fontName;
graph->fileName = nil;
graph->caption = captionName;
graph->file = nil;
for (i = 0; i < 16; i++)
graph->Ass[i] = nil;
return true;
}
syntax highlighted by Code2HTML, v. 0.9.1