/*
$Id: xdriv.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: xdriv.c,v $
Revision 1.1.1.1 1996/11/04 12:05:46 roitzsch
minigraph module
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <limits.h>
#include "minigraph.h"
#define K180PI 57.29578
static real real_min = SHRT_MIN, real_max = SHRT_MAX;
#define TRANSX(X) ((X)*(graph->xScal)+(graph->xTrans))
#define TRANSY(Y) ((graph->wdHght)-(Y)*(graph->yScal)-(graph->yTrans))
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#define MAX_WINDOWS 16
#define STDCOLORS 32
#define COLORS 64
#define GRAYS 24
#define ALLCOL 96
#define not_nil 1L
static unsigned short red [ALLCOL] = {
0, 65535, 65535, 0,
0, 0, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
0, 0, 0, 0, 0, 0,
0, 4352, 8704, 13056, 17408, 21760,
26112, 30464, 34816, 39168, 43520, 47872,
52224, 56576, 60928, 65280, 65280, 65280,
65280, 65280, 65280, 65280, 65280, 65280,
65280, 65280, 65280, 65280, 65280, 65280,
65280, 65280, 65280, 65280, 65280, 65280,
65280, 65280, 65280, 65280, 65280, 65280,
65280, 65280, 65280, 65280, 65280, 65280,
65280, 65280, 65280, 65280, 65280, 65280,
65280, 65280, 65280, 65280
};
static unsigned short green[ALLCOL] = {
0, 65535, 0, 65535,
0, 65535, 0, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
0, 0, 0, 0, 0, 0,
0, 4352, 8704, 13056, 17408, 21760,
26112, 30464, 34816, 34816, 34816, 34816,
34816, 34816, 34816, 34816, 34816, 34816,
34816, 34816, 34816, 34816, 34816, 30464,
26112, 21760, 17408, 13056, 8704, 4352,
0, 4352, 8704, 13056, 17408, 21760,
26112, 30464, 34816, 39168, 43520, 47872,
52224, 56576, 60928, 65280, 65280, 65280,
65280, 65280, 65280, 65280, 65280, 65280,
65280, 65280, 65280, 65280
};
static unsigned short blue [ALLCOL] = {
0, 65535, 0, 0,
65535, 65535, 65535, 0,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535,
39168, 43520, 47872, 52224, 56576, 60928,
65280, 65280, 65280, 65280, 65280, 65280,
65280, 65280, 65280, 65280, 65280, 65280,
65280, 65280, 65280, 65280, 60928, 56576,
52224, 47872, 43520, 39168, 34816, 30464,
26112, 21760, 17408, 13056, 8704, 4352,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 17664, 22016,
26368, 30720, 35072, 39168, 43520, 47872,
52224, 56576, 60928, 65280
};
static unsigned long pixels[ALLCOL];
static unsigned lineWidth[3] = { 1, 2, 4 };
static int length[] = { 2, 2, 2, 2, 4, 6 };
static char pattern[6][7] = {
{ 1, 2 },
{ 1, 4 },
{ 3, 3 },
{ 6, 3 },
{ 5, 3, 1, 3 },
{ 5, 3, 1, 3, 1, 3 }
};
static char *mrkfontName[2] = {
"-adobe-symbol-medium-r-normal--14-140-75-75-p-85-adobe-fontspecific",
"8x13"
};
static int fonttyp=0;
static char *fontName[2][3] =
{ {
"-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1",
"-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1",
"-adobe-helvetica-medium-r-normal--14-140-75-75-p-77-iso8859-1"
},
{
"6x10", "8x13", "9x15"
}
};
static char *captionName = "MiniGraphic";
#define MAXXMARKERS 7
static int mrk_fonttyp=0;
static char XMarkers[2][MAXXMARKERS] = {
{ ' ', '*', '\xb4', '+', '\xb7', '\xc4', '\xb5' },
{ ' ', '*', 'x', '+', 'o', ' ', ' ' }
};
static int dxMarker[MAXXMARKERS] = { 0, -3, -3, -3, -3, -5, -5 };
static int dyMarker[2][MAXXMARKERS] = {
{ 0, 5, 4, 4, 4, 5, 5 },
{ 0, 4, 3, 4, 2, 0, 0 }
};
static Display *display;
static int screen;
static Window window[MAX_WINDOWS];
static GC gc[MAX_WINDOWS];
static Font font[MAX_WINDOWS], mrkFont;
static Colormap colormap;
static char input_queue[MAX_WINDOWS][MAX_STRING];
static int queue_pointer[MAX_WINDOWS];
static int SelFont(GRAPHIC *graph);
static int XOpenPort(GRAPHIC *graph)
{
int no = graph->wdNo;
XWMHints wmhints;
XSizeHints hint;
XEvent event;
XSetWindowAttributes attribute;
if (graph->ready) return false;
/* graph->wdWdth -= 8;
graph->wdHght -= 36;
*/ hint.height = graph->wdHght;
hint.width = graph->wdWdth;
hint.x = graph->wdOrgX;
hint.y = graph->wdOrgY - hint.height - 31;
hint.flags = PPosition | PSize;
window[no] = XCreateSimpleWindow(display, DefaultRootWindow(display),
hint.x, hint.y, hint.width, hint.height, 0,
BlackPixel(display, screen),
pixels[graph->backgrCol]);
gc[no] = XCreateGC(display, window[no], (unsigned long)0, NULL);
wmhints.flags = InputHint;
wmhints.input = True;
XSetWMHints(display, window[no], &wmhints);
XSetBackground(display, gc[no], BlackPixel(display, screen));
XSetForeground(display, gc[no], WhitePixel(display, screen));
if (graph->linestyle != SOLID)
{
XSetDashes(display, gc[no], 0, pattern[graph->linestyle],
length[graph->linestyle]);
XSetLineAttributes(display, gc[no],
lineWidth[graph->drPenSz],
LineOnOffDash, CapButt, 0);
}
else
XSetLineAttributes(display, gc[no],
lineWidth[graph->drPenSz], LineSolid,
CapButt, 0);
XSetFillRule(display, gc[no], WindingRule);
XSetStandardProperties(display, window[no], graph->caption, graph->caption,
None, nil, 0, &hint);
XSelectInput(display, window[no], ExposureMask);
XMapRaised(display, window[no]);
do
XWindowEvent(display, window[no], ExposureMask, &event);
while (event.xexpose.count != 0);
attribute.backing_store = Always;
XChangeWindowAttributes(display, window[no], CWBackingStore, &attribute);
XSelectInput(display, window[no], ButtonPressMask | KeyPressMask);
graph->ready = true;
if (fonttyp != -1)
SelFont(graph);
return true;
}
static int XNewPict(GRAPHIC *graph)
{
int no = graph->wdNo;
if (no < 0) return false;
if (graph->ready) XClearWindow(display, window[no]);
return true;
}
static int XClose(GRAPHIC *graph)
{
int no = graph->wdNo;
if (no < 0) return false;
free(graph->caption);
if (graph->ready) XDestroyWindow(display, window[no]);
window[no] = nil;
return true;
}
static int X_Color(int col_no, int rVal, int gVal, int bVal)
{
XColor color;
XFreeColors(display, colormap, &pixels[col_no], 1, 0);
color.red = rVal * 257;
color.green = gVal * 257;
color.blue = bVal * 257;
color.flags = DoRed | DoGreen | DoBlue;
if (!XAllocColor(display, colormap, &color))
{
printf("MiniGraphic - zibcol : failure to allocate color !\n");
return false;
}
pixels[col_no] = color.pixel;
return true;
}
static XPoint *pt = 0;
static int ptLng = 0;
static int XPLine(GRAPHIC *graph, void *xAdr, void *yAdr, int n)
{
int ind = graph->wdNo, k;
real x, y, a, b;
if (ptLng<n)
{
if (pt) free(pt);
pt = (XPoint*)malloc(n*sizeof(XPoint));
ptLng = n;
}
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];
}
a = TRANSX(x);
b = TRANSY(y);
if ((a<real_min)||(a>real_max)||(b<real_min)||(b>real_max))
return true;
pt[k].x = a;
pt[k].y = b;
}
XSetForeground(display, gc[ind], pixels[graph->penCol]);
XDrawLines(display, window[ind], gc[ind], pt, n, 0);
return true;
}
static int XPMarker(GRAPHIC *graph, void *xAdr, void *yAdr, int n)
{
int no = graph->wdNo, k, px, py;
real x, y, xt, yt;
char s[2];
if (mrkFont == 0)
{
printf("MiniGraphic - zibpm : no markers on screen !\n");
return false;
}
XSetFont(display, gc[no], mrkFont);
XSetForeground(display, gc[no], pixels[graph->mrkCol]);
s[0] = XMarkers[mrk_fonttyp][graph->mark]; s[1] = '\0';
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)+dxMarker[graph->mark];
yt = TRANSY(y)+dyMarker[mrk_fonttyp][graph->mark];
if ((xt<real_min)||(xt>real_max)||
(yt<real_min)||(yt>real_max)) return true;
px = xt; py = yt;
XDrawString(display, window[no], gc[no], px, py, s, 1);
}
if (fonttyp != -1)
XSetFont(display, gc[no], font[no]);
return true;
}
#ifdef __cplusplus
static int XText(GRAPHIC *graph, real x, real y, const char *s)
#else
static int XText(GRAPHIC *graph, real x, real y, char *s)
#endif
{
int no = graph->wdNo;
real xt = TRANSX(x), yt = TRANSY(y);
int px, py;
if (fonttyp == -1)
return false;
if ((xt<real_min)||(xt>real_max)||
(yt<real_min)||(yt>real_max)) return true;
px = xt; py = yt;
XSetForeground(display, gc[no], pixels[graph->fntCol]);
if (graph->FntProp == TRANSPARENT)
XDrawString(display, window[no], gc[no], px, py, s, strlen(s));
else
XDrawImageString(display, window[no], gc[no], px, py, s, strlen(s));
return true;
}
static int XFill(GRAPHIC *graph, void *xAdr, void *yAdr, int n)
{
int no = graph->wdNo, k;
real x, y, xt, yt;
if (ptLng<n)
{
if (pt) free(pt);
pt = (XPoint*)malloc(n*sizeof(XPoint));
ptLng = n;
}
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;
pt[k].x = xt;
pt[k].y = yt;
}
XSetForeground(display, gc[no], pixels[graph->fllCol]);
XFillPolygon(display, window[no], gc[no], pt, n, Complex, CoordModeOrigin);
return true;
}
static int XSettings(GRAPHIC *graph, int type, void *valAdr)
{
int iVal, n, no = graph->wdNo;
switch (type)
{
case WDORGX :
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal <= graph->right))
graph->wdOrgX = iVal;
else
{
printf("MiniGraphic - zibset : wrong value for WDORGX %d !\n", iVal);
return false;
}
return true;
case WDORGY :
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal <= graph->bottom))
graph->wdOrgY = iVal;
else
{
printf("MiniGraphic - zibset : wrong value for WDORGY %d !\n", iVal);
return false;
}
return true;
case WDWDTH :
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal + graph->wdOrgX <= graph->right))
graph->wdWdth = iVal;
else
{
printf("MiniGraphic - zibset : wrong value for WDWDTH %d !\n", iVal);
return false;
}
return true;
case WDHGHT :
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal <= graph->wdOrgY))
graph->wdHght = iVal;
else
{
printf("MiniGraphic - zibset : wrong value for WDHGHT %d !\n", iVal);
return false;
}
return true;
case PENSIZE:
iVal = *((int*)valAdr);
if ((iVal >= SMALL) && (iVal <= BIG))
graph->drPenSz = iVal;
else
{
printf("MiniGraphic - zibset : wrong value for PENSIZE %d !\n",
iVal);
return false;
}
if (graph->ready)
XSetLineAttributes(display, gc[no],
lineWidth[graph->drPenSz],
graph->linestyle == SOLID ? LineSolid :
LineOnOffDash,
CapButt, 0);
return true;
case LINESTYLE :
iVal = *((int*)valAdr);
if ((iVal >= DOTTED) && (iVal <= SOLID))
graph->linestyle = iVal;
else
{
printf("MiniGraphic - zibset : wrong value for LINESTYLE %d !\n",
iVal);
return false;
}
if (graph->ready)
if (iVal != SOLID)
{
XSetDashes(display, gc[no], 0, pattern[iVal],
length[graph->linestyle]);
XSetLineAttributes(display, gc[no],
lineWidth[graph->drPenSz],
LineOnOffDash, CapButt, 0);
}
else
XSetLineAttributes(display, gc[no],
lineWidth[graph->drPenSz], LineSolid,
CapButt, 0);
return true;
case COPYMODE:
iVal = *((int*)valAdr);
if ((iVal == GXOR) || (iVal == GCOPY))
graph->copyMode = iVal;
else
{
printf("MiniGraphic - zibset : wrong value for COPYMODE %d !\n",
iVal);
return false;
}
if (graph->ready)
XSetFunction(display, gc[no], ((graph->copyMode)==GXOR)?GXxor:GXcopy);
return true;
case FONTSIZE :
if (fonttyp == -1)
return false;
iVal = *((int*)valAdr);
if ((iVal >= SMALL) && (iVal <= BIG))
graph->drFntSz = iVal;
else
{
printf("MiniGraphic - zibset : wrong value for FONTSIZE %d !\n",
iVal);
return false;
}
SelFont(graph);
return true;
case FONTPROP : iVal = *((int*)valAdr);
if ((iVal == TRANSPARENT) || (iVal == OPAQUE))
graph->FntProp = iVal;
else
{
printf("MiniGraphik - zibset : wrong value for FNTPROP %d !\n", iVal);
return false;
}
return true;
case MARKER:
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal < MAXXMARKERS))
graph->mark = iVal;
else
{
printf("MiniGraphic - zibset : unkown marker %d !\n", iVal);
return false;
}
return true;
case FILLCOL:
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal < ALLCOL))
graph->fllCol = iVal;
else
{
printf("MiniGraphic - zibset : unkown fill-color %d !\n", iVal);
return false;
}
return true;
case MARKCOL:
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal < ALLCOL))
graph->mrkCol = iVal;
else
{
printf("MiniGraphic - zibset : unkown marker-color %d !\n", iVal);
return false;
}
return true;
case FONTCOL:
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal < ALLCOL))
graph->fntCol = iVal;
else
{
printf("MiniGraphic - zibset : unkown font-color %d !\n", iVal);
return false;
}
return true;
case PENCOL:
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal < ALLCOL))
graph->penCol = iVal;
else
{
printf("MiniGraphic - zibset : unkown pen-color %d !\n", iVal);
return false;
}
return true;
case BACKGRCOL:
iVal = *((int*)valAdr);
if ((iVal >= 0) && (iVal < ALLCOL))
graph->backgrCol = iVal;
else
{
printf("MiniGraphic - zibset : unkown background-color %d !\n",
iVal);
return false;
}
return true;
case CAPTION:
free(graph->caption);
n = strlen((char*)valAdr);
graph->caption = (char*)malloc(n+1);
strncpy(graph->caption, (char*)valAdr, n);
(graph->caption)[n] = '\0';
return true;
case BUFFER :
iVal = *((int*)valAdr);
if ((iVal == ON) || (iVal == OFF))
{
graph->buffer = iVal;
XSynchronize(display, !iVal);
}
else if (iVal == FLUSH)
XFlush(display);
else
{
printf("MiniGraphic - zibset : unkown buffer status %d !\n",
iVal);
return false;
}
return true;
default:
printf("MiniGraphic - zibset: unkown type %d !\n", type);
}
return false;
}
struct coor
{
int x,y;
};
typedef struct coor COOR;
static void geometric(GRAPHIC *graph, int geo, COOR org, COOR vec)
{
int ind = graph->wdNo, radius;
XPoint points[5];
XSegment segments[2];
switch (geo)
{
case LINE : XDrawLine(display, window[ind], gc[ind],
org.x, org.y, vec.x, vec.y);
break;
case RECTANGLE : points[0].x = org.x;
points[0].y = org.y;
points[1].x = vec.x;
points[1].y = org.y;
points[2].x = vec.x;
points[2].y = vec.y;
points[3].x = org.x;
points[3].y = vec.y;
points[4].x = org.x;
points[4].y = org.y;
XDrawLines(display, window[ind], gc[ind], points,
5, CoordModeOrigin);
/*XDrawRectangle(display, window[ind], gc[ind],
org.x, org.y,
(unsigned)(vec.x-org.x),
(unsigned)(vec.y-org.y) );*/
break;
case CIRCLE : radius = sqrt(pow((double)(vec.x-org.x),
2.0)+pow((double)(vec.y-org.y), 2.0));
segments[0].x1 = org.x-radius;
segments[0].y1 = org.y;
segments[0].x2 = org.x+radius;
segments[0].y2 = org.y;
segments[1].x1 = org.x;
segments[1].y1 = org.y+radius;
segments[1].x2 = org.x;
segments[1].y2 = org.y-radius;
XDrawArc(display, window[ind], gc[ind],
org.x-radius, org.y-radius,
2*radius, 2*radius, 0, 23040);
XDrawSegments(display, window[ind], gc[ind],
segments, 2);
break;
}
return;
}
static int XGin (GRAPHIC *graph, int geo, void *x1koordAdr, void *y1koordAdr, void *x2koordAdr, void *y2koordAdr)
{
Cursor cursor;
XEvent event;
float Org_x, Org_y;
double x1koord, y1koord, x2koord, y2koord;
int no = graph->wdNo;
COOR org, vec;
XFlush(display);
cursor = XCreateFontCursor(display, XC_tcross);
XDefineCursor(display, window[no], cursor);
XSetLineAttributes(display, gc[no], 0, 0, 0, 0);
XSetFunction(display, gc[no], GXxor);
XSetForeground(display, gc[no], pixels[0]);
XSelectInput(display, window[no], ButtonPressMask | Button1MotionMask |
ButtonReleaseMask | KeyPressMask );
while (XCheckWindowEvent(display, window[no], ButtonPressMask |
Button1MotionMask | ButtonReleaseMask, &event));
XWindowEvent(display, window[no], ButtonPressMask | Button1MotionMask,
&event);
org.x = vec.x = Org_x = event.xbutton.x;
org.y = vec.y = Org_y = event.xbutton.y;
geometric(graph, geo, org, vec);
do
{
XWindowEvent(display, window[no], Button1MotionMask |ButtonReleaseMask,
&event);
if ((vec.x != event.xmotion.x) || (vec.y != event.xmotion.y))
{
geometric(graph, geo, org, vec);
vec.x = event.xmotion.x;
vec.y = event.xmotion.y;
geometric(graph, geo, org, vec);
}
}
while (event.type != ButtonRelease);
geometric(graph, geo, org, vec);
XUndefineCursor(display, window[no]);
XSetLineAttributes(display, gc[no], lineWidth[graph->drPenSz],
graph->linestyle == SOLID ? LineSolid : LineOnOffDash,
CapButt, 0);
XSetFunction(display, gc[no], ((graph->copyMode)==GXOR)?GXxor:GXcopy);
XSelectInput(display, window[no], ButtonPressMask | KeyPressMask);
x1koord = (Org_x - graph->xTrans) / graph->xScal;
y1koord = (graph->wdHght - Org_y - graph->yTrans) / graph->yScal;
x2koord = (event.xmotion.x - graph->xTrans) / graph->xScal;
y2koord = (graph->wdHght - event.xmotion.y - graph->yTrans) / graph->yScal;
if (graph->prec == SINGLE)
{
*((float*)x1koordAdr) = x1koord;
*((float*)y1koordAdr) = y1koord;
*((float*)x2koordAdr) = x2koord;
*((float*)y2koordAdr) = y2koord;
}
else
{
*((double*)x1koordAdr) = x1koord;
*((double*)y1koordAdr) = y1koord;
*((double*)x2koordAdr) = x2koord;
*((double*)y2koordAdr) = y2koord;
}
return true;
}
static int X_Event (GRAPHIC *graph, int *typAdr, int *buttonAdr, void *xkoordAdr, void *ykoordAdr, int *chAdr)
{
char ch;
int no = graph->wdNo;
XEvent event, last_event;
double xkoord = 0, ykoord = 0;
*typAdr = *buttonAdr = *chAdr = 0;
last_event.type = -1;
while (XCheckWindowEvent(display, window[no],
ButtonPressMask | KeyPressMask, &event))
{
if (event.type == KeyPress)
if (XLookupString(&(event.xkey), &ch, 1, NULL, NULL))
if (ch > 31)
input_queue[no][queue_pointer[no]++] = ch;
last_event = event;
}
if (last_event.type != -1)
{
switch (last_event.type)
{
case KeyPress : *typAdr |= 4;
if (XLookupString(&(last_event.xkey), &ch, 1, NULL, NULL))
*chAdr = ch;
else
{
switch (XLookupKeysym(&(last_event.xkey), 0))
{
case XK_Shift_L :
case XK_Shift_R : *typAdr |= 1;
break;
case XK_Control_L :
case XK_Control_R : *typAdr |= 2;
break;
default : ;
}
}
break;
case ButtonPress : switch (last_event.xbutton.button)
{
case 1 : *buttonAdr |= 4; break;
case 2 : *buttonAdr |= 2; break;
case 3 : *buttonAdr |= 1; break;
default : *buttonAdr |= 4;
}
*typAdr |= 8;
break;
default : ;
}
if (last_event.xkey.state & ShiftMask) *typAdr |= 1;
if (last_event.xkey.state & ControlMask) *typAdr |= 2;
xkoord = (last_event.xbutton.x - graph->xTrans) / graph->xScal;
ykoord = (graph->wdHght - last_event.xbutton.y - graph->yTrans)
/ graph->yScal;
}
if (graph->prec == SINGLE)
{
*((float*)xkoordAdr) = xkoord;
*((float*)ykoordAdr) = ykoord;
}
else
{
*((double*)xkoordAdr) = xkoord;
*((double*)ykoordAdr) = ykoord;
}
if (last_event.type == -1)
return false;
return true;
}
static int XWait (GRAPHIC *graph, int *typAdr, int *buttonAdr, void *xkoordAdr, void *ykoordAdr, int *chAdr)
{
int no = graph->wdNo;
XEvent event;
double xkoord, ykoord;
char ch = 0;
*typAdr = *buttonAdr = *chAdr = 0;
XSetInputFocus(display, window[no], RevertToPointerRoot, CurrentTime);
XFlush(display);
while (XCheckWindowEvent(display, window[no],
ButtonPressMask | KeyPressMask, &event))
if (event.type == KeyPress)
if (XLookupString(&(event.xkey), &ch, 1, NULL, NULL))
if (ch > 31)
input_queue[no][queue_pointer[no]++] = ch;
XWindowEvent(display, window[no], ButtonPressMask | KeyPressMask, &event);
switch (event.type)
{
case KeyPress : *typAdr |= 4;
if (XLookupString(&(event.xkey), &ch, 1, NULL, NULL))
{
*chAdr = ch;
if (ch > 31)
input_queue[no][queue_pointer[no]++] = ch;
}
else
{
switch (XLookupKeysym(&(event.xkey), 0))
{
case XK_Shift_L :
case XK_Shift_R : *typAdr |= 1;
break;
case XK_Control_L :
case XK_Control_R : *typAdr |= 2;
break;
default : ;
}
}
break;
case ButtonPress : switch (event.xbutton.button)
{
case 1 : *buttonAdr |= 4; break;
case 2 : *buttonAdr |= 2; break;
case 3 : *buttonAdr |= 1; break;
default : *buttonAdr |= 4;
}
*typAdr |= 8;
break;
default : ;
}
if (event.xkey.state & ShiftMask) *typAdr |= 1;
if (event.xkey.state & ControlMask) *typAdr |= 2;
xkoord = (event.xbutton.x - graph->xTrans) / graph->xScal;
ykoord = (graph->wdHght - event.xbutton.y - graph->yTrans) / graph->yScal;
if (graph->prec == SINGLE)
{
*((float*)xkoordAdr) = xkoord;
*((float*)ykoordAdr) = ykoord;
}
else
{
*((double*)xkoordAdr) = xkoord;
*((double*)ykoordAdr) = ykoord;
}
/*XPutBackEvent(display, &event);*/
return true;
}
static int XString(GRAPHIC *graph, char *string, int *length)
{
int no = graph->wdNo, i;
XEvent event;
XKeyEvent key_event;
char ch;
while (XCheckWindowEvent(display, window[no], KeyPressMask, &event))
if (event.type == KeyPress)
if (XLookupString(&key_event, &ch, 1, NULL, NULL))
if (ch > 31)
input_queue[no][queue_pointer[no]++] = ch;
for(i = 0; i < queue_pointer[no]; i++)
*string++ = input_queue[no][i];
for(i = queue_pointer[no]; i < MAX_STRING; i++)
*string++ = '\0';
*length = queue_pointer[no];
queue_pointer[no] = 0;
return true;
}
/*int stop_event(display, event, args)
Display display;
XKeyEvent event;
char *args;
{
if (XLookupKeysym(&event, 0) == XK_Pause)
return true;
return false;
}
void stop()
{
XKeyEvent event;
if (XCheckIfEvent(display, &event, stop_event, NULL))
{
printf("MiniGraphik : Stop execution !\n");
printf("Press any key or button to continue.\n");
}
return;
}
*/
int XInit(GRAPHIC *graph)
{
static int first = true;
int k, i, free, size,
low = BLACK, high = WHITE;
real dRed, dGreen, dBlue, dk;
XColor color;
char **fontList;
if (first)
{
/*struct itimerval value;
signal(SIGALRM, stop);
value.it_value.tv_sec = 0;
value.it_value.tv_usec = 500000;
value.it_interval.tv_sec = 0;
value.it_interval.tv_usec = 500000;
setitimer(ITIMER_REAL, &value, NULL);
*/
int count = 0;
for (k = 0; k < MAX_WINDOWS; k++)
{
window[k] = font[k] = nil;
queue_pointer[k] = 0;
}
if ((display = XOpenDisplay(NULL)) == nil)
{
printf("MiniGraphic - zibwop : Failure to open display !\n");
return false;
}
screen = DefaultScreen(display);
for (size = SMALL; size <= BIG; size++)
{
fontList = XListFonts(display, fontName[0][size], 1, &count);
if (count == 0)
{
printf("MiniGraphic - zibwop : Failure to open font %s !\n",
fontName[0][size]);
fonttyp = 1;
}
XFreeFontNames(fontList);
}
if (fonttyp == 1)
for (size = SMALL; size <= BIG; size++)
{
fontList = XListFonts(display, fontName[1][size], 1, &count);
if (count == 0)
{
printf("MiniGraphic - zibwop : Failure to open font %s !\n",
fontName[1][size]);
fonttyp = -1;
}
XFreeFontNames(fontList);
}
fontList = XListFonts(display, mrkfontName[0], 1, &count);
if (count != 0)
{
XFreeFontNames(fontList);
mrkFont = XLoadFont(display, mrkfontName[0]);
}
else
{
printf("MiniGraphic - zibwop : Failure to open marker-font ");
printf("%s !\n", mrkfontName[0]);
fontList = XListFonts(display, mrkfontName[1], 1, &count);
if (count != 0)
{
mrkFont = XLoadFont(display, mrkfontName[1]);
XFreeFontNames(fontList);
mrk_fonttyp = 1;
}
else
{
printf("MiniGraphic - zibwop : Failure to open marker-font ");
printf("%s !\n", mrkfontName[1]);
}
}
colormap = XDefaultColormap(display, screen);
dRed = (red[high] - red[low]) / (GRAYS-1);
dGreen = (green[high] - green[low]) / (GRAYS-1);
dBlue = (blue[high] - blue[low]) / (GRAYS-1);
for (k = 0, dk = GRAYS-1; k < GRAYS; k++, dk--)
{
red [STDCOLORS-GRAYS+k] = red [high]-dk*dRed;
green[STDCOLORS-GRAYS+k] = green[high]-dk*dGreen;
blue [STDCOLORS-GRAYS+k] = blue [high]-dk*dBlue;
}
for (i = 0; i < ALLCOL; i++)
{
color.red = red[i];
color.green = green[i];
color.blue = blue[i];
color.flags = DoRed | DoGreen | DoBlue;
if (!XAllocColor(display, colormap, &color))
{
printf("MiniGraphic - zibwop : failure to allocate color ! \n");
break;
}
pixels[i] = color.pixel;
}
first = false;
}
for (free = 0; free < MAX_WINDOWS; free++)
if (window[free] == nil) break;
if (free == MAX_WINDOWS)
{
printf("MiniGraphic - zibwop : More than %d windows !\n", MAX_WINDOWS);
return false;
}
window[free] = not_nil;
graph->PLine = XPLine;
graph->PMarker = XPMarker;
graph->Text = XText;
graph->Fill = XFill;
graph->Color = X_Color;
graph->Settings = XSettings;
graph->NewPict = XNewPict;
graph->OpenPort = XOpenPort;
graph->Close = XClose;
graph->Gin = XGin;
graph->Wait = XWait;
graph->Event = X_Event;
graph->String = XString;
graph->bottom = DisplayHeight(display, screen);
graph->left = 0.0;
graph->top = 0.0;
graph->right = DisplayWidth(display, screen);
graph->wdWdth =
graph->wdHght = (graph->bottom-graph->top)*0.5 - 31.0;
switch (free % 4)
{
case 0 : graph->wdOrgX = graph->right - graph->wdWdth - 10;
graph->wdOrgY = (graph->bottom - graph->top) * 0.5;
break;
case 1 : graph->wdOrgX = graph->right - 2*graph->wdWdth - 20;
graph->wdOrgY = (graph->bottom - graph->top) * 0.5;
break;
case 2 : graph->wdOrgX = graph->right - 2*graph->wdWdth - 20;
graph->wdOrgY = graph->bottom;
break;
case 3 : graph->wdOrgX = graph->right - graph->wdWdth - 10;
graph->wdOrgY = graph->bottom;
break;
}
graph->wdWdth =
graph->wdHght -= 16.0;
graph->drRes = 1.0;
graph->drPenSz = SMALL;
graph->linestyle = SOLID;
graph->drFntSz = MEDIUM;
graph->FntProp = TRANSPARENT;
graph->drXcm = (double)DisplayWidthMM(display, screen) /
(double)(10*DisplayWidth(display, screen));
graph->drYcm = (double)DisplayHeightMM(display, screen) /
(double)(10*DisplayHeight(display, screen));
graph->penCol =
graph->fllCol =
graph->fntCol =
graph->mrkCol = WHITE;
graph->backgrCol = BLACK;
graph->maxCol = COLORS;
graph->maxGry = GRAYS;
graph->maxWd = MAX_WINDOWS;
graph->mark = STAR;
graph->prec = SINGLE;
graph->id = X11;
graph->wdNo = free;
graph->fontName = fontName[fonttyp][MEDIUM];
graph->fileName = nil;
i = strlen(captionName);
graph->caption = (char*)malloc(i+1);
strcpy(graph->caption, captionName);
graph->file = nil;
graph->buffer = ON;
for (i = 0; i < MAX_WINDOWS; i++)
graph->Ass[i] = nil;
/* XSynchronize(display, 1); */
return true;
}
static int SelFont(GRAPHIC *graph)
{
int no = graph->wdNo;
if (font[no] != 0)
XUnloadFont(display, font[no]);
graph->fontName = fontName[fonttyp][graph->drFntSz];
font[no] = XLoadFont(display, graph->fontName);
if (graph->ready)
XSetFont(display, gc[no], font[no]);
return true;
}
syntax highlighted by Code2HTML, v. 0.9.1