/********************************************************************
This file is part of the abs 0.907 distribution. abs is a spreadsheet
with graphical user interface.
Copyright (C) 1998-2001 André Bertin (Andre.Bertin@ping.be)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version if in the same spirit as version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Concact: abs@pi.be
http://home.pi.be/bertin/abs.shtml
*********************************************************************/
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Core.h>
#include <X11/Shell.h>
#include <stdio.h>
#include "memory.h"
#include "gr_interf.h"
#include "scale.h"
#include "fig.h"
#include "gr_interf_decl.h"
extern int BatchMode;
#define SCREEN 0
#define PRINTER 1
#define FIG 2
static int output = 0;
static int px0, py0;
static int pxscale, pyscale;
static Pixmap Pixmaps[50];
static int nPixmap = 0;
static int nfreepix = 0;
static int freepix[50];
static Display *Dpy;
static Window Win;
static int screen;
static Visual *Vis;
static int D;
static GC TheGc;
GC
getTheGc ()
{
return TheGc;
};
typedef struct
{
Pixel foreground;
Pixel background;
XFontStruct *font;
int ncol;
Boolean showsize;
}
res_data, *res_data_ptr;
static res_data res;
static XtResource application_resources[] =
{
{XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
XtOffset (res_data_ptr, foreground), XtRString, "Black"},
{XtNbackground, XtCBackground, XtRPixel, sizeof (Pixel),
XtOffset (res_data_ptr, background), XtRString, "#C000C000C000"},
{XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
XtOffset (res_data_ptr, font), XtRString, "Fixed"},
};
int
setzoom (z)
int z;
{
grz = z;
return 0;
}
int
getzoom ()
{
return grz;
}
static int grzbak;
int
desactivate_zoom ()
{
grzbak = grz;
grz = 100;
return 0;
}
int
reactivate_zoom ()
{
grz = grzbak;
return 0;
}
int
setXparam (dpy, win, toplevel)
Display *dpy;
Window win;
Widget toplevel;
{
XGCValues gcv;
XGCValues gcvr;
int i, j, k;
if (BatchMode)
return 0;
Dpy = dpy;
Win = win;
screen = DefaultScreen (Dpy);
Vis = DefaultVisual (Dpy, screen);
D = DefaultDepth (Dpy, screen);
parse_color (win);
XtGetApplicationResources (toplevel, &res, application_resources,
XtNumber (application_resources), NULL, 0);
gcv.foreground = res.foreground;
gcv.background = res.background;
gcv.font = res.font->fid;
gcvr.foreground = res.background;
gcvr.background = res.foreground;
gcvr.font = res.font->fid;
TheGc = XCreateGC (Dpy, Win, (GCFont | GCForeground | GCBackground), &gcv);
for (i = 0; i < 5; i++)
for (j = 0; j < 4; j++)
for (k = 0; k < 7; k++)
allfont[i][j][k] = 0;
return 0;
}
char *
parse_GetR (db, resource)
XrmDatabase db;
char *resource;
{
char name[16], class[128], *rc;
strcpy (name, Name);
strcat (name, resource);
strcpy (class, Class);
strcat (class, resource);
rc = XrmGetResource (db, name, class, type, &value)
? (char *) value.addr
: (char *) 0;
return (rc);
}
int
parse_color (Window win)
{
unsigned long black = BlackPixel (Dpy, screen) /* , white = WhitePixel(Dpy, screen) */ ;
char color[128], *v;
XColor xcolor;
Colormap cmap;
int depth;
double intensity = -1;
int i, n;
XColor *cols = NULL;
unsigned int ncols = 0;
depth = DefaultDepth (Dpy, screen);
cmap = DefaultColormap (Dpy, screen);
ncols = Vis->map_entries;
cols = (XColor *) absmalloc (ncols * sizeof (XColor), "cols");
for (i = 0; i < ncols; ++i)
cols[i].pixel = i;
XQueryColors (Dpy, cmap, cols, ncols);
for (n = 0; n < Ncolors; n++)
{
v = color_values[n];
if (sscanf (v, "%30[^,],%lf", color, &intensity) == 2)
{
if (intensity < 0 || intensity > 1)
{
fprintf (stderr, "\ninvalid color intensity in '%s'\n",
color);
intensity = 1;
}
}
else
{
strcpy (color, v);
intensity = 1;
}
if (!XParseColor (Dpy, cmap, color, &xcolor))
{
fprintf (stderr, "\nunable to parse '%s'. using black.\n",
color);
colors[n] = black;
}
else
{
xcolor.red *= intensity;
xcolor.green *= intensity;
xcolor.blue *= intensity;
if (XAllocColor (Dpy, cmap, &xcolor))
{
colors[n] = xcolor.pixel;
}
else
{
#define COLOR_FACTOR 3
#define BRIGHTNESS_FACTOR 1
int closeness = 1e9;
int alternative = 0;
int c;
for (i = 0; i < ncols; i++)
{
c =
COLOR_FACTOR * (abs ((long) xcolor.red - (long) cols[i].red)
+ abs ((long) xcolor.green - (long) cols[i].green)
+ abs ((long) xcolor.blue - (long) cols[i].blue))
+ BRIGHTNESS_FACTOR * abs (((long) xcolor.red +
(long) xcolor.green +
(long) xcolor.blue)
- ((long) cols[i].red +
(long) cols[i].green +
(long) cols[i].blue));
if (c < closeness)
{
closeness = c;
alternative = i;
}
}
colors[n] = cols[alternative].pixel;
}
}
}
absfree (cols, "cols");
return 0;
}
Pixmap
createpixmap (w, width, height)
Widget w;
int width, height;
{
int locpix;
if (nfreepix)
{
nfreepix--;
locpix = freepix[nfreepix];
}
else
{
locpix = nPixmap;
nPixmap++;
}
if (locpix == 49)
{
fprintf (stderr, "create pix: no more pixmaps");
return Pixmaps[49];
}
if (width <= 0 || width > 10000)
width = 1;
if (height <= 0 || height > 10000)
height = 1;
Pixmaps[locpix] = XCreatePixmap (XtDisplay (w), XtWindow (w), width, height, D);
return Pixmaps[locpix];
}
int
freepixmap (w, pixmap)
Widget w;
Pixmap pixmap;
{
int i = 0;
while (i < 50 && pixmap != Pixmaps[i])
i++;
if (i > 49)
return -1;
freepix[nfreepix] = i;
nfreepix++;
XFreePixmap (XtDisplay (w), pixmap);
return 0;
}
int
createpixgc (w, pixmap)
Widget w;
Pixmap pixmap;
{
return 0;
}
int
setbackpix (w, pixmap)
Widget w;
Pixmap pixmap;
{
XSetWindowBackgroundPixmap (XtDisplay (w), XtWindow (w), pixmap);
return 0;
}
int
copyarea (pix1, pix2, ngc, x1, y1, w, h, x2, y2)
Pixmap pix1, pix2;
int ngc, x1, y1, w, h, x2, y2;
{
if (BatchMode)
return 0;
XCopyArea (Dpy, pix1, pix2, TheGc, x1, y1, w, h, x2, y2);
return 0;
}
int
clearnflush ()
{
if (BatchMode)
return 0;
XClearWindow (Dpy, Win);
XFlush (Dpy);
return 0;
}
int
clearwin (w)
Widget w;
{
if (BatchMode)
return 0;
XClearWindow (XtDisplay (w), XtWindow (w));
return 0;
}
static Pixel fgpix, bgpix;
Pixel
getcolor (int col)
{
return colors[col];
}
int
setforeground (ngc, ncol)
int ngc;
int ncol;
{
if (!BatchMode)
XSetForeground (Dpy, TheGc, colors[ncol]);
fgpix = colors[ncol];
if (output)
{
FIG_setcol (ncol);
}
return 0;
}
int
setbackground (ngc, ncol)
int ngc;
int ncol;
{
if (!BatchMode)
XSetBackground (Dpy, TheGc, colors[ncol]);
bgpix = colors[ncol];
return 0;
}
Pixel
getforeground ()
{
return fgpix;
}
Pixel
getbackground ()
{
return bgpix;
}
int
setfont (ngc, fontname)
int ngc;
String fontname;
{
int num_fonts;
char **buf;
if (BatchMode)
return 0;
buf = XListFonts (Dpy, fontname, 1000, &num_fonts);
if (num_fonts)
XSetFont (Dpy, TheGc, XLoadFont (Dpy, buf[0]));
return 0;
}
int
parse_font (i, j, k)
int i, j, k;
{
char **buf;
char fontname[128];
int num_fonts;
char italic[2];
if (BatchMode)
return 0;
switch (i)
{
case 0:
{
sprintf (fontname, "-*-fixed-");
strcpy (italic, "i");
break;
};
case 1:
{
sprintf (fontname, "-*-courier-");
strcpy (italic, "o");
break;
};
case 2:
{
sprintf (fontname, "-*-helv*-");
strcpy (italic, "o");
break;
};
case 3:
{
sprintf (fontname, "-*-times-");
strcpy (italic, "i");
break;
};
case 4:
{
sprintf (fontname, "-*-symb*-");
strcpy (italic, "i");
break;
};
}
switch (j)
{
case 0:
{
sprintf (fontname, "%smedium-r-*-*-*-", fontname);
break;
};
case 1:
{
sprintf (fontname, "%sbold-r-*-*-*-", fontname);
break;
};
case 2:
{
sprintf (fontname, "%smedium-%1s-*-*-*-", fontname, italic);
break;
};
case 3:
{
sprintf (fontname, "%sbold-%1s-*-*-*-", fontname, italic);
break;
};
}
switch (k)
{
case 0:
{
sprintf (fontname, "%s60-*", fontname);
break;
};
case 1:
{
sprintf (fontname, "%s80-*", fontname);
break;
};
case 2:
{
sprintf (fontname, "%s100-*", fontname);
break;
};
case 3:
{
sprintf (fontname, "%s120-*", fontname);
break;
};
case 4:
{
sprintf (fontname, "%s140-*", fontname);
break;
};
case 5:
{
sprintf (fontname, "%s180-*", fontname);
break;
};
case 6:
{
sprintf (fontname, "%s240-*", fontname);
break;
};
}
buf = XListFonts (Dpy, fontname, 1, &num_fonts);
if (num_fonts < 1)
printf ("Warning! nomatch for fontname:%s \n", fontname);
if (num_fonts >= 1)
allfont[i][j][k] = XLoadFont (Dpy, buf[0]);
else
{
allfont[i][j][k] = res.font->fid;
if (j == 1 || j == 2)
allfont[i][j][k] = allfont[i][0][k];
if (j == 3 && allfont[i][1][k] != res.font->fid)
allfont[i][j][k] = allfont[i][1][k];
if (j == 3 && allfont[i][2][k] != res.font->fid)
allfont[i][j][k] = allfont[i][2][k];
}
allfontstr[i][j][k] = XQueryFont (Dpy, allfont[i][j][k]);
XFreeFontNames (buf);
return 0;
}
static int activefont = 2;
static int activefontw = 0;
static int activefonts = 3;
int
setfont2 (ngc, font, fontw, fonts)
int ngc;
int font, fontw, fonts;
{
if (font < 0 || fontw < 0 || fonts < 0 || font > 4 || fontw > 3 || fonts > 6)
return -1;
if (activefont == font && activefontw == fontw && activefonts == fonts)
return 0;
activefont = font;
activefontw = fontw;
activefonts = fonts;
if (allfont[font][fontw][fonts] == 0)
parse_font (font, fontw, fonts);
if (!BatchMode && allfont[font][fontw][fonts] != 0)
XSetFont (Dpy, TheGc, allfont[font][fontw][fonts]);
if (output)
{
FIG_setfont (font, fontw, fonts);
}
return 0;
}
XFontStruct *
font2fontstr (int font, int fontw, int fonts)
{
setfont2 (1, font, fontw, fonts);
return allfontstr[activefont][activefontw][activefonts];
}
int
setdashes (dpy, ngc, DashOffset, DashList, Number)
Display *dpy;
int ngc;
int DashOffset;
char DashList[];
int Number;
{
if (BatchMode)
return 0;
XSetDashes (dpy, TheGc, DashOffset, DashList, Number);
return 0;
}
int
setlineattributes (dpy, ngc, LineWidth, LineStyle, CapStyle, JoinStyle)
Display *dpy;
int ngc;
unsigned int LineWidth;
int LineStyle;
int CapStyle;
int JoinStyle;
{
if (BatchMode)
return 0;
XSetLineAttributes (dpy, TheGc, LineWidth, LineStyle, CapStyle, JoinStyle);
return 0;
}
int
setfillstyle (dpy, ngc, FillStyle)
Display *dpy;
int ngc;
int FillStyle;
{
if (BatchMode)
return 0;
XSetFillStyle (dpy, TheGc, FillStyle);
return 0;
}
int
setstipple (dpy, ngc, Stipple)
Display *dpy;
int ngc;
Pixmap Stipple;
{
if (BatchMode)
return 0;
XSetStipple (dpy, TheGc, Stipple);
return 0;
}
int
gettexth (name, nchar, font, fontw, fonts)
char *name;
int nchar, font, fontw, fonts;
{
XCharStruct overall;
int ascent, descent, direction;
if (BatchMode)
return 0;
if (allfont[font][fontw][fonts] == 0)
parse_font (font, fontw, fonts);
if (allfont[font][fontw][fonts] == 0)
return 10;
XTextExtents (allfontstr[font][fontw][fonts], name, nchar, &direction,
&ascent, &descent, &overall);
return overall.ascent + overall.descent;
}
int
gettextw (name, nchar, font, fontw, fonts)
char *name;
int nchar, font, fontw, fonts;
{
XCharStruct overall;
int ascent, descent, direction;
if (BatchMode)
return 0;
if (allfont[font][fontw][fonts] == 0)
parse_font (font, fontw, fonts);
if (allfont[font][fontw][fonts] == 0)
{
fprintf (stderr, "gettextw: problem with font allocation...");
return 10;
}
overall.width = 0;
XTextExtents (allfontstr[font][fontw][fonts], name, nchar, &direction,
&ascent, &descent, &overall);
return overall.width;
}
int
setout (ppstate, ppxscale, ppyscale, ppx0, ppy0)
int ppstate, ppxscale, ppyscale, ppx0, ppy0;
{
pxscale = ppxscale;
pyscale = ppyscale;
px0 = ppx0;
py0 = ppy0;
output = ppstate;
return 0;
}
int
drawline (dpy, pixmap, ngc, x1, y1, x2, y2, x0, y0)
Display *dpy;
Pixmap pixmap;
int ngc;
int x1, y1, x2, y2, x0, y0;
{
if (ngc < 0 || ngc > 45)
ngc = 1;
setforeground (0, ngc);
if (output)
{
x1 = (x1 + x0 - px0) * pxscale;
y1 = (y1 + y0 - py0) * pyscale;
x2 = (x2 + x0 - px0) * pxscale;
y2 = (y2 + y0 - py0) * pyscale;
if (output == 1)
{
}
else
{
FIG_setcol (ngc);
FIG_line (x1, y1, x2, y2);
}
}
else
{
if (BatchMode)
return 0;
if (grz != 100)
{
x1 = x1 * grz / 100;
y1 = y1 * grz / 100;
x2 = x2 * grz / 100;
y2 = y2 * grz / 100;
}
return XDrawLine (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, x2, y2);
}
return 0;
}
int
drawlines (dpy, pixmap, ngc, points, nb, mode, x0, y0)
Display *dpy;
Pixmap pixmap;
int ngc;
XPoint *points;
int nb, mode;
int x0, y0;
{
int x1, y1, x2, y2, i;
if (ngc < 0 || ngc > 45)
ngc = 1;
setforeground (0, ngc);
if (output && nb > 0)
{
FIG_setcol (ngc);
x1 = (points[0].x + x0 - px0) * pxscale;
y1 = (points[0].y + y0 - py0) * pyscale;
for (i = 1; i < nb; i++)
{
x2 = x1 + (points[i].x) * pxscale;
y2 = y1 + (points[i].y) * pyscale;
FIG_line (x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
}
else
{
if (BatchMode)
return 0;
if (grz != 100)
{
for (i = 0; i < nb; i++)
{
points[i].x = points[i].x * grz / 100;
points[i].y = points[i].y * grz / 100;
}
}
return XDrawLines (dpy, pixmap, TheGc /*[ngc] */ , points, nb, mode);
}
return 0;
}
int
drawimagestring (dpy, pixmap, ngc, x1, y1, name, nchar, x0, y0)
Display *dpy;
Pixmap pixmap;
int ngc;
int x1, y1;
char *name;
int nchar;
int x0, y0;
{
if (ngc < 0 || ngc > 45)
ngc = 1;
setforeground (0, ngc);
if (output)
{
x1 = (x1 + x0 - px0) * pxscale;
y1 = (y1 + y0 - py0) * pyscale;
if (output == 1)
{
}
else
{
FIG_setcol (ngc);
FIG_put_text (x1, y1, name);
}
}
else
{
if (BatchMode)
return 0;
if (grz != 100)
{
double scale = grz;
x1 = x1 * grz / 100;
y1 = y1 * grz / 100;
i18n_draw_string (dpy, pixmap, TheGc, x1, y1, name, nchar, 1, 1, scale);
return 0;
}
return XDrawImageString (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, name, nchar);
}
return 0;
}
int
drawstring (dpy, pixmap, ngc, x1, y1, name, nchar, x0, y0)
Display *dpy;
Pixmap pixmap;
int ngc;
char *name;
int nchar;
int x1, y1, x0, y0;
{
if (ngc < 0 || ngc > 45)
ngc = 1;
setforeground (0, ngc);
if (output)
{
x1 = (x1 + x0 - px0) * pxscale;
y1 = (y1 + y0 - py0) * pyscale;
if (output == 1)
{
}
else
{
FIG_setcol (ngc);
FIG_put_text (x1, y1, name);
}
}
else
{
if (BatchMode)
return 0;
if (grz != 100)
{
double scale = grz;
x1 = x1 * grz / 100;
y1 = y1 * grz / 100;
i18n_draw_string (dpy, pixmap, TheGc, x1, y1, name, nchar, 1, 1, scale);
return 0;
}
return XDrawString (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, name, nchar);
}
return 0;
}
int
drawrectangle (dpy, pixmap, ngc, x1, y1, w, h, x0, y0)
Display *dpy;
Pixmap pixmap;
int ngc;
int x1, y1, w, h, x0, y0;
{
if (ngc < 0 || ngc > 45)
ngc = 1;
setforeground (0, ngc);
if (output)
{
x1 = (x1 + x0 - px0) * pxscale;
y1 = (y1 + y0 - py0) * pyscale;
w = w * pxscale;
h = h * pyscale;
if (output == 1)
{
}
else
{
FIG_setcol (ngc);
FIG_rectangle (x1, y1, w, h);
}
}
else
{
if (BatchMode)
return 0;
if (grz != 100)
{
x1 = x1 * grz / 100;
y1 = y1 * grz / 100;
w = w * grz / 100;
h = h * grz / 100;
}
return XDrawRectangle (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, w, h);
}
return 0;
}
int
drawarc (dpy, pixmap, ngc, x1, y1, w, h, a1, a2, x0, y0)
Display *dpy;
Pixmap pixmap;
int ngc;
int x1, y1, w, h, x0, y0;
{
if (ngc < 0 || ngc > 45)
ngc = 1;
setforeground (0, ngc);
if (output)
{
x1 = (x1 + x0 - px0) * pxscale;
y1 = (y1 + y0 - py0) * pyscale;
w = w * pxscale;
h = h * pyscale;
FIG_setcol (ngc);
FIG_arc (x1, y1, w, h, a1, a2);
}
else
{
if (BatchMode)
return 0;
if (grz != 100)
{
x1 = x1 * grz / 100;
y1 = y1 * grz / 100;
w = w * grz / 100;
h = h * grz / 100;
}
return XDrawArc (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, w, h, a1, a2);
}
return 0;
}
int
fillarc (dpy, pixmap, ngc, x1, y1, w, h, a1, a2, x0, y0)
Display *dpy;
Pixmap pixmap;
int ngc;
int x1, y1, w, h, x0, y0;
{
if (ngc < 0 || ngc > 45)
ngc = 1;
setforeground (0, ngc);
if (output)
{
x1 = (x1 + x0 - px0) * pxscale;
y1 = (y1 + y0 - py0) * pyscale;
w = w * pxscale;
h = h * pyscale;
FIG_setcol (ngc);
FIG_fillarc (x1, y1, w, h, a1, a2);
}
else
{
if (BatchMode)
return 0;
if (grz != 100)
{
x1 = x1 * grz / 100;
y1 = y1 * grz / 100;
w = w * grz / 100;
h = h * grz / 100;
}
return XFillArc (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, w, h, a1, a2);
}
return 0;
}
int
fillrectangle (dpy, pixmap, ngc, x1, y1, w, h, x0, y0, doprint)
Display *dpy;
Pixmap pixmap;
int ngc;
int x1, y1, w, h, x0, y0;
int doprint;
{
if (ngc < 0 || ngc > 45)
ngc = 1;
setforeground (0, ngc);
if (output && doprint)
{
if (doprint > 0)
{
x1 = (x1 + x0 - px0) * pxscale;
y1 = (y1 + y0 - py0) * pyscale;
w = w * pxscale;
h = h * pyscale;
FIG_setcol (ngc);
FIG_fillrectangle (x1, y1, w, h, doprint);
}
}
else
{
if (BatchMode)
return 0;
if (grz != 100)
{
x1 = x1 * grz / 100;
y1 = y1 * grz / 100;
w = w * grz / 100;
h = h * grz / 100;
}
return XFillRectangle (dpy, pixmap, TheGc /*[ngc] */ , x1, y1, w, h);
}
return 0;
}
int
cleararea (Display * dpy, Pixmap pixmap, int x, int y, int w, int h, Boolean yes)
{
if (BatchMode)
return 0;
if (grz != 100)
{
x = x * grz / 100;
y = y * grz / 100;
w = w * grz / 100;
h = h * grz / 100;
}
XClearArea (dpy, pixmap, x, y, w, h, yes);
return 0;
}
int
drawbuttonup (Display * dpy, Pixmap pixmap, int x1, int y1, int x2, int y2, char *label, int X0, int Y0)
{
drawline (dpy, pixmap, 2, x1, y1, x2 - 1, y1, X0, Y0);
drawline (dpy, pixmap, 2, x1, y1, x1, y2, X0, Y0);
drawline (dpy, pixmap, 0, x1 + 1, y1 + 1, x2 - 1, y1 + 1, X0, Y0);
drawline (dpy, pixmap, 0, x1 + 1, y1 + 2, x1 + 1, y2 - 1, X0, Y0);
drawline (dpy, pixmap, 1, x2, y1, x2, y2, X0, Y0);
drawline (dpy, pixmap, 1, x1, y2, x2, y2, X0, Y0);
drawline (dpy, pixmap, 3, x2 - 1, y1, x2 - 1, y2 - 1, X0, Y0);
drawline (dpy, pixmap, 3, x1 + 1, y2 - 1, x2 - 1, y2 - 1, X0, Y0);
fillrectangle (dpy, pixmap, 2, x1 + 2, y1 + 2, x2 - x1 - 3, y2 - y1 - 3, X0, Y0, 1);
if (label != NULL)
if (strlen (label) > 0)
drawstring (dpy, pixmap, 1, x1 + 10, (y1 + y2) / 2, label, strlen (label), X0, Y0);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1