/* $Header: llx.c,v 4.11 88/11/24 18:07:18 samarcq Exp $ */
#include <X/Xlib.h>
#include <lelisp.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
extern char *malloc();
XAssocTable *XCreateAssocTable();
#define NULL 0
/* Les plans sur lesquels on travaille */
#define PLANES 1
/* Macro pour mettre un int dans la CVAL d'un symbole Lisp */
#define SETINTCVAL(symb,i) *symb = (i) & 0xffff
#define LLLOCATOR(x,y) ((((x) & 0xffff) << 16) | ((y) & 0xffff))
/* les curseurs e'dite's par bitmap */
#define lelisp←width 16
#define lelisp←height 16
#define lelisp←x←hot 1
#define lelisp←y←hot 1
static short lelisp←bits[] = {
0x0000, 0x0002, 0x0006, 0x000e,
0x001e, 0x003e, 0x007e, 0x00fe,
0x001e, 0x0036, 0x0032, 0x0060,
0x0060, 0x00c0, 0x00c0, 0x0000};
#define lelisp←mask←width 16
#define lelisp←mask←height 16
#define lelisp←mask←x←hot 1
#define lelisp←mask←y←hot 1
static short lelisp←mask←bits[] = {
0x0003, 0x0007, 0x000f, 0x001f,
0x003f, 0x007f, 0x00ff, 0x01ff,
0x01ff, 0x007f, 0x007f, 0x00f3,
0x00f0, 0x01e0, 0x01e0, 0x01c0};
#define nocursor←width 16
#define nocursor←height 16
#define nocursor←x←hot 1
#define nocursor←y←hot 1
static short nocursor←bits[] = {
0x0000, 0x0002, 0x0006, 0x000e,
0x001e, 0x003e, 0x007e, 0x00fe,
0x001e, 0x0036, 0x0032, 0x0060,
0x0060, 0x00c0, 0x00c0, 0x0000};
#define nocursor←mask←width 16
#define nocursor←mask←height 16
#define nocursor←mask←x←hot 1
#define nocursor←mask←y←hot 1
static short nocursor←mask←bits[] = {
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
};
/* Les environnements graphiques */
struct grenv {
FontInfo *font;
Pattern linestyle;
int mode;
Pixmap pattern;
int clipx;
int clipy;
int clipw;
int cliph;
int topwindowp;
};
#define FONTINFO(n) (grenvs[n]->font)
#define FONT(n) (grenvs[n]->font->id)
#define MODE(n) (grenvs[n]->mode)
#define LINE←STYLE(n) (grenvs[n]->linestyle)
#define PATTERN(n) (grenvs[n]->pattern)
#define CLIPX(n) (grenvs[n]->clipx)
#define CLIPY(n) (grenvs[n]->clipy)
#define CLIPW(n) (grenvs[n]->clipw)
#define CLIPH(n) (grenvs[n]->cliph)
#define TOPWINDOWP(n) (grenvs[n]->topwindowp)
#define BORDERWIDTH 2
FontInfo *normalfont, *attributefont;
Cursor cursor, nocursor;
#define MAX←WINDOW 5000 /* nombre maximal de fene↑tres */
int nwindow = 0; /* nombre de fene↑tres construites */
int event←mode; /* le mode de la souris */
Display *display; /* l'e'cran ouvert */
Window windows[MAX←WINDOW]; /* le vecteur des Fene↑tres */
Window clips[MAX←WINDOW]; /* les fene↑tres transparentes pour le
clip */
struct grenv *grenvs[MAX←WINDOW]; /* graphenvs */
Pixmap patterns[5];
Pattern line←style[4] = {0, DashedLine, DottedLine,
XMakePattern(0xf900, 10, 1)};
XAssocTable *assoctable;
Window keyboardgrabber = 0;
Window downgrabber = 0;
short down←dx, down←dy;
int reversevideo;
int ForePixel, BackPixel;
Pixmap ForePixmap, BackPixmap;
/* Les vertex pour les POLYxxx et le FILLAREA */
#define MAXVERTEX 1024
Vertex vertex[MAXVERTEX];
int * lispnil;
int * lispxerrorsymbol;
int * lisperrorsymbol;
FontInfo *
load←font (s) char *s; {
return XOpenFont(s);
}
FontInfo *
default←font1 () {
return normalfont;
}
FontInfo *
default←font2 () {
return attributefont;
}
struct grenv *ge←default (topp) int topp; {
struct grenv *ge;
ge = (struct grenv *) malloc(sizeof(struct grenv));
ge->font = default←font1();
ge->linestyle = 0;
ge->mode = GXcopy;
ge->pattern = ForePixmap;
ge->clipx = 0;
ge->clipy = 0;
ge->clipw = 0;
ge->cliph = 0;
ge->topwindowp = topp;
return(ge);
}
/*ARGSUSED*/
llxError (dpy, rep)
Display *dpy;
XErrorEvent *rep;
{
pusharg(LLT←T, lispxerrorsymbol);
pusharg(LLT←STRING, XErrDescrip(rep->error←code));
pusharg(LLT←T, (int *) XLookUpAssoc(assoctable, rep->window));
lispcall(LLT←T, 3, lisperrorsymbol);
return(0);
}
ll←io () {
printf("IT event\r\n");
/* appeler ensuite ll←mouse() dans llmachine.s */
}
/* Initialisations generales. */
Display *bitprologue(xmax, ymax, planes, lenil, llxerror, llerror)
int *xmax, *ymax, *lenil, *llxerror, *llerror, *planes; {
char *def;
display = XOpenDisplay (NULL);
if (display == NULL) {
perror ("bitprologue: can't open display");
return (0);
}
XSetDisplay (display);
XErrorHandler(llxError);
*xmax = (DisplayWidth () - 1) & 0xffff;
*ymax = (DisplayHeight () - 1) & 0xffff;
*planes = DisplayPlanes () & 0xffff;
lispnil = lenil;
lispxerrorsymbol = llxerror;
lisperrorsymbol = llerror;
/* reversevideo:on blanc sur fond noir. (reversevideo true)
reversevideo:off noir sur fond blanc. (reversevideo false)
default off, reversevideo false.
*/
def = XGetDefault("lelisp", "ReverseVideo");
if (!def) def = XGetDefault("xterm", "ReverseVideo");
if (!def) def = "off";
reversevideo = strcmp(def, "off"); /* vrai si def <> "off" */
ForePixel = reversevideo ? WhitePixel : BlackPixel ;
BackPixel = reversevideo ? BlackPixel : WhitePixel ;
ForePixmap = reversevideo ? WhitePixmap : BlackPixmap ;
BackPixmap = reversevideo ? BlackPixmap : WhitePixmap ;
def = XGetDefault("lelisp", "font");
if (!def) def = "vtsingle";
normalfont = load←font(def);
def = XGetDefault("lelisp", "attributefont");
if (!def) def = "vtbold";
attributefont = load←font(def);
cursor = XCreateCursor(lelisp←width, lelisp←height,
lelisp←bits, lelisp←mask←bits,
lelisp←x←hot, lelisp←y←hot,
ForePixel, BackPixel, GXcopy);
nocursor = XCreateCursor(nocursor←width, nocursor←height,
nocursor←bits, nocursor←mask←bits,
nocursor←x←hot, nocursor←y←hot,
ForePixel, BackPixel, GXcopy);
init←pattern();
assoctable = XCreateAssocTable(64);
set←event←mode(0);
return (display);
}
void
bitepilogue () {
XDestroyAssocTable(assoctable);
XFreePixmap(patterns[4]);
XFreePixmap(patterns[3]);
XFreePixmap(patterns[2]);
XFreePixmap(patterns[1]);
XFreePixmap(patterns[0]);
XFreeCursor(nocursor);
XFreeCursor(cursor);
XCloseFont(attributefont);
XCloseFont(normalfont);
XFlush();
XCloseDisplay(display);
}
/* Cre'ation d'une fene↑tre */
int
create←window(lisp, left, top, width, height, ti, hi, vi)
int * lisp;
int left, top, width, height;
char *ti; {
Window win, cli;
struct grenv *ge;
if (nwindow == MAX←WINDOW) return(-1); /* plus de fene↑tres! */
/* X ne veut pas de fene↑tres de taille 0 */
if (width == 0) width = 1;
if (height == 0) height = 1;
/* allocation du GRAPHENV */
ge = ge←default(1);
/* cre'ation et allocation du FRAME */
win = XCreateWindow(RootWindow,
left-BORDERWIDTH,
top-BORDERWIDTH,
width,
height,
BORDERWIDTH,
hi ? ForePixmap : patterns[2],
BackPixmap);
XTileAbsolute(win);
XStoreName(win, ti);
cli = XCreateTransparency(win, 0, 0, width, height);
XClipDrawThrough(cli);
XDefineCursor(win, cursor);
/* choix de l'input */
XSelectInput (win, 0); /* ne pas avoir le premier redisplay */
XMapWindow (cli);
if (vi) XMapWindow (win);
XSelectInput (win, 0x7fbd);
/* mise a jour des vecteurs */
windows[nwindow] = win;
clips[nwindow] = cli;
grenvs[nwindow] = ge;
XMakeAssoc(assoctable, win, lisp);
/* initialisation du ge */
set←cur←mode (nwindow, 3);
set←clip(nwindow, 0, 0, width, height);
return (nwindow++);
}
create←subwindow(lisp, father, left, top, width, height, vi) int * lisp;
int father, left, top, width, height, vi;{
Window win, cli;
struct grenv *ge;
if (nwindow == MAX←WINDOW) return(-1); /* plus de fene↑tres! */
if (width == 0) width = 1;
if (height == 0) height = 1;
/* allocation du GRAPHENV */
ge = ge←default(0);
/* cre'ation et alloc<ation du FRAME */
win = XCreateTransparency(windows[father],
left,
top,
width,
height);
cli = XCreateTransparency(win,
0,
0,
width,
height);
XTileAbsolute(win);
/* choix de l'input */
XSelectInput (win, 0x7fbd);
XMapWindow (cli);
if (vi) XMapWindow (win);
/* mise a jour des vecteurs */
windows[nwindow] = win;
clips[nwindow] = cli;
grenvs[nwindow] = ge;
XMakeAssoc(assoctable, win, lisp);
/* initialisation du ge */
set←cur←mode (nwindow, 3);
set←clip (nwindow, 0, 0, width, height);
return (nwindow++);
}
modify←window (win, xyp, x, y, whp, width, height, ti, hi, vi)
char *ti; {
if (width == 0) width = 1;
if (height == 0) height = 1;
if (TOPWINDOWP(win)){
y -= BORDERWIDTH;
x -= BORDERWIDTH;
}
XSelectInput (windows[win], 0);
if (xyp && whp)
XConfigureWindow (windows[win], x, y, width, height);
else if (xyp)
XMoveWindow (windows[win], x, y);
else if (whp)
XChangeWindow (windows[win], width, height);
XSelectInput (windows[win], 0x7fbd);
set←clip (win, CLIPX(win), CLIPY(win), width, height);
if (TOPWINDOWP(win)){
XStoreName (windows[win], ti);
if (hi)
XChangeBorder (windows[win], ForePixmap);
else
XChangeBorder (windows[win], patterns[2]);
}
if (vi)
XMapWindow (windows[win]);
else
XUnmapWindow (windows[win]);
}
kill←window (n) int n; {
if ((n < 0) || (n >= nwindow))
return (-1);
if (keyboardgrabber = windows[n]) keyboardgrabber = 0;
if (downgrabber = windows[n]) downgrabber = 0;
XDeleteAssoc(assoctable, windows[n]);
XDestroyWindow (windows[n]);
free (grenvs[n]);
if (n != nwindow - 1)
while (++n < nwindow) {
windows[n - 1] = windows[n];
grenvs[n - 1] = grenvs[n];
clips[n - 1] = clips[n];
}
nwindow--;
return (0);
}
pop←window (n) int n; {
XRaiseWindow (windows[n]);
}
/*ARGSUSED*/
move←behind←window (n1, n2) int n1,
n2; {
XLowerWindow (windows[n1]);
}
int *
find←window (x, y, lispnil) int * lispnil; int x, y;{
int lx,
ly,
loc = LLLOCATOR(x, y);
int *lispwin = NULL, *prevlispwin = NULL;
Window win = RootWindow;
do {
prevlispwin = lispwin;
XInterpretLocator (win, &lx, &ly, &win, loc);
lispwin = (int *) XLookUpAssoc(assoctable, win);
} while (lispwin);
return prevlispwin ? prevlispwin : lispnil;
}
map←window (win, x, y, lx, ly)
int win,
x,
y;
int *lx, *ly; {
Window pwin; int px, py;
XInterpretLocator (windows[win], &px, &py, &pwin, LLLOCATOR(x, y));
*lx = px & 0xffff;
*ly = py & 0xffff;
}
grab←keyboard (win, flag) int win, flag;{
if (flag)
keyboardgrabber = windows[win];
else
keyboardgrabber = 0;
}
/* grabbe uniquement le clavier, a` corriger */
grab←mouse (win, flag) int win, flag; {
if (flag){
keyboardgrabber = windows[win];
downgrabber = windows[win];
} else {
keyboardgrabber = 0;
downgrabber = 0;
}
}
draw←cn (win, x, y, cn) char cn; {
char cnstring[2];
cnstring[0] = cn;
XTextPad (clips[win], x-CLIPX(win), y-CLIPY(win),
cnstring, 1, FONT (win), 0, 0,
ForePixel, BackPixel, MODE (win), PLANES);
}
draw←substr (win, x, y, s, start, length) char *s; {
XTextPad (clips[win], x-CLIPX(win), y-CLIPY(win),
s + start, length, FONT (win), 0, 0,
ForePixel, BackPixel, MODE (win), PLANES);
}
fast←draw←substr (win, x, y, s, start, length)
struct LL←STRING *s;
short win, x, y, start, length; {
char *cs;
cs = (&((s->ll←strobj)->ll←strfil))+start;
XTextPad (clips[win], x-CLIPX(win), y-CLIPY(win),
cs, length, FONT (win), 0, 0,
ForePixel, BackPixel, MODE (win), PLANES);
}
width←substr (s, start, length, win) char *s; {
int plength;
char c = s[start + length];
s[start + length] = '\0';
plength = (win >= 0) ?
XStringWidth (s+start, FONTINFO (win), 0, 0) :
XStringWidth (s+start, default←font1(), 0, 0);
s[start + length] = c;
return (plength);
}
/*ARGSUSED*/
height←cn (cn, win) char cn; {
return (win >= 0) ? FONTINFO (win) -> height : default←font1() -> height;
}
xinc←substr (s, start, length, win) char *s; {
return (width←substr (s, start, length, win));
}
tycleol(win, x, y) {
x -= CLIPX(win);
y -= CLIPY(win);
XPixSet(clips[win], x, y, 2000, FONTINFO(win)->height, BackPixel);
}
draw←cursor (win, x, y, st) {
x -= CLIPX(win);
y -= CLIPY(win);
XLine (clips[win],
x, y,
x, y+(FONTINFO(win)->height)-1,
1, 1,
st ? ForePixel : BackPixel, GXcopy,
PLANES);
}
clear←ge (win) {
XClear (clips[win]);
}
/* Les environnements graphiques */
current←font (win, font) FontInfo * font; {
FONTINFO (win) = font;
}
/* la souris */
#define MAXEVENT 256
XEvent events[MAXEVENT];
int ievent = 0, mevent = 0;
fillevent(event) XEvent *event; {
int i, pending;
if (ievent == mevent) {
pending = XPending();
if (pending > MAXEVENT) pending = MAXEVENT;
if (pending == 0) pending = 1;
for (i = 0; i < pending; i++)
XNextEvent(&events[i]);
ievent = 0;
mevent = pending;
}
*event = events[ievent];
ievent++;
}
struct llevent {
int code;
int * window;
int detail;
int gx;
int gy;
int x;
int y;
int w;
int h;
};
i←peek←mouse (event) struct llevent *event; {
XEvent rep;
XPeekEvent (&rep);
parse←event (event, &rep, 0);
}
i←read←mouse (event) struct llevent *event; {
XEvent rep;
XNextEvent(&rep);
if (((rep.type) == EnterWindow) || ((rep.type) == LeaveWindow))
if (XPending())
XNextEvent(&rep);
parse←event (event, &rep, 1);
}
flush←event () {
XSync (1);
}
read←mouse (event) struct llevent *event; {
Window subw;
short state;
int x, y;
XQueryMouseButtons(RootWindow, &x, &y, &subw, &state);
event->gx = x & 0xffff;
event->gy = y & 0xffff;
event->detail = (state & 0x0700) ? (state & 0xffff) : 0;
}
set←event←mode (mode) int mode; {
if(mode & 0x2)
XCompressEvents ();
else
XExpandEvents();
event←mode = mode;
}
int *
eventp (lispnil) int * lispnil; {
return XPending() ? (int *) 1 : lispnil;
}
#define ASCII 256
#define MOVE 257
#define DRAG 258
#define DOWN 259
#define UP 260
#define MODIFY 264
#define KILL 265
#define REPAINT 266
#define RELEASE 267
#define ENTERWINDOW 268
#define LEAVEWINDOW 269
#define UNMAPWINDOW 270
#define FOCUSCHANGE 271
#define CODEBIDON 272
parse←event (event, rep, readp)
struct llevent *event;
XEvent * rep;
int readp; {
/* readp est vrai si on est dans un READ-EVENT, faux dans un PEEK-EVENT */
int nbytes;
char *bytes;
int detail;
/* L'e've'nement appartient a trois classes:
- clavier
- souris
- fene↑tre
*/
switch (rep -> type) {
case MouseMoved:
case ButtonPressed:
case ButtonReleased:
parse←mouse←event(event, rep, readp); break;
case KeyPressed:
case KeyReleased:
parse←keyboard←event(event, rep, readp); break;
default:
parse←window←event(event, rep, readp); break;
}
}
#define bit(i,mask) ((i & mask)? 1 : 0)
parse←mouse←event(event, rep, readp)
struct llevent *event;
XEvent * rep;
int readp; {
int detail;
/* recherche de la fene↑tre: downgrabber ou window de l'evt */
event->window =
(int *)XLookUpAssoc(assoctable,
downgrabber ?
downgrabber : rep->window);
/* calcul du code et du detail */
detail = ((XMouseMovedEvent *) rep) -> detail;
switch(rep -> type) {
case MouseMoved:
event -> detail = bit(detail, MiddleMask)
+ 2*bit(detail, RightMask);
event -> code =
detail & (LeftMask | MiddleMask | RightMask) ?
DRAG : MOVE;
break;
case ButtonPressed:
event->code = DOWN;
if (readp) downgrabber = rep->window;
event->detail = 2-(detail & 0xff);
down←dx = (((XMouseMovedEvent *) rep) -> location >> 16)
- ((XMouseMovedEvent *) rep) -> x;
down←dy = (((XMouseMovedEvent *) rep) -> location & 0xffff)
- ((XMouseMovedEvent *) rep) -> y;
break;
case ButtonReleased:
event->code = UP;
if (readp) downgrabber = 0;
event->detail = 2-(detail & 0xff);
break;
}
event->detail += 3*bit(detail, ShiftMask) + 6*bit(detail, ControlMask)
+ 9*bit(detail, MetaMask);
set←x←y←gx←gy(event, rep);
}
parse←keyboard←event(event, rep, readp)
struct llevent *event;
XEvent * rep;
int readp; {
int nbytes;
char *bytes;
/* recherche de la fene↑tre: keyboardgrabber ou window de l'evt */
event->window =
(int *)XLookUpAssoc(assoctable,
keyboardgrabber ?
keyboardgrabber : rep->window);
/* recheche du code et des caracteres */
switch (rep -> type) {
case KeyPressed:
bytes = XLookupMapping (rep, &nbytes);
if (nbytes == 1){
event->detail = *bytes;
event->code = ASCII;
}else{
event->code = CODEBIDON;
event->detail = '\33';
}
break;
case KeyReleased:
event->code = RELEASE;
break;
}
}
parse←window←event(event, rep, readp)
struct llevent *event;
XEvent * rep;
int readp; {
/* recherche de la fene↑tre: window de l'evt */
event->window = (int *)XLookUpAssoc(assoctable, rep -> window);
switch (rep -> type) {
case EnterWindow:
event->code = ENTERWINDOW;
break;
case LeaveWindow:
event->code = LEAVEWINDOW;
break;
case ExposeWindow:
/* d'abord un resize */
event->code = MODIFY;
event->x = (int) lispnil;
event->y = (int) lispnil;
event->w = ((XExposeEvent *) rep) -> width;
event->h = ((XExposeEvent *) rep) -> height;
/* qui sera suivi d'un repaint */
if (readp) {
rep -> type = ExposeRegion;
XPutBackEvent(rep);
}
break;
case ExposeRegion:
event->code = REPAINT;
event->x = ((XExposeEvent *) rep) -> x;
event->y = ((XExposeEvent *) rep) -> y;
event->w = ((XExposeEvent *) rep) -> width;
event->h = ((XExposeEvent *) rep) -> height;
break;
case UnmapWindow:
event->code = UNMAPWINDOW;
break;
case FocusChange:
event->code = FOCUSCHANGE;
if (event->detail == LeaveWindow)
event->window = lispnil;
break;
default:
event->code = CODEBIDON;
}
}
find←window←number (window) Window window; {
int i;
for (i = 0; (i<nwindow) && (windows[i]!=window); i++);
return i;
}
set←x←y←gx←gy(event, rep)
struct llevent *event;
XEvent * rep; {
Window subw;
event -> gx = ((XMouseMovedEvent *) rep) -> location >> 16;
event -> gy = ((XMouseMovedEvent *) rep) -> location & 0xffff;
event -> x = event -> gx - down←dx;
event -> y = event -> gy - down←dy;
event->x &= 0xffff;
event->y &= 0xffff;
}
/* le graphique */
int vecmode[16]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int vecmodei[16]={15, 7, 11, 3, 13, 5, 9, 1, 14, 6, 10, 2, 12, 4, 8, 0};
set←cur←mode (win, n) {
MODE (win) = reversevideo ? vecmode[n] : vecmodei[n];
}
set←clip (win, x, y, w, h) {
XConfigureWindow (clips[win], x, y, w, h);
XLowerWindow(clips[win]);
CLIPX(win) = x;
CLIPY(win) = y;
CLIPW(win) = w;
CLIPH(win) = h;
}
draw←polymarker (win, n, vx, vy)
int vx[],
vy[]; {
int next = 0;
while (n) {
vx = &vx[next];
vy = &vy[next];
next = fill←point (win, n, vx, vy);
vertex←draw(win, vertex, 2*next);
n -= next;
}
}
fill←point (win, n, vx, vy) int vx[], vy[];{
int i, j, fill;
fill = n*2 < MAXVERTEX ? n : MAXVERTEX/2;
for(i = 0; i < fill; i+=1){
j = i+i;
vertex[j].x = vx[i]-CLIPX(win);
vertex[j].y = vy[i]-CLIPY(win);
vertex[j].flags = VertexDontDraw;
vertex[j+1].x = vx[i]-CLIPX(win);
vertex[j+1].y = vy[i]-CLIPY(win);
vertex[j+1].flags = 0;
}
return fill;
}
draw←point (win, x, y)
int win,
x,
y; {
draw←line (win, x, y, x+1, y+1);
}
draw←line (win, x0, y0, x1, y1) {
Vertex line[2];
line[0].x = x0-CLIPX(win); line[0].y = y0-CLIPY(win); line[0].flags = 0;
line[1].x = x1-CLIPX(win); line[1].y = y1-CLIPY(win); line[1].flags = 0;
vertex←draw(win, line, 2);
}
draw←rectangle (win, x, y, w, h) {
Vertex rect[5];
x -= CLIPX(win);
y -= CLIPY(win);
rect[0].x = x; rect[0].y = y; rect[0].flags = 0;
rect[1].x = x; rect[1].y = y+h; rect[1].flags = 0;
rect[2].x = x+w; rect[2].y = y+h; rect[2].flags = 0;
rect[3].x = x+w; rect[3].y = y; rect[3].flags = 0;
rect[4].x = x; rect[4].y = y; rect[4].flags = 0;
vertex←draw(win, rect, 5);
}
draw←polyline (win, n, vx, vy)
int vx[],
vy[]; {
int next = 0;
while (n) {
vx = &vx[next];
vy = &vy[next];
next = fill←vertex (win, n, vx, vy, 0);
vertex←draw(win, vertex, next);
n -= next;
}
}
vertex←draw (win, vertex, n) Vertex *vertex; {
if (LINE←STYLE (win)){
XDrawDashed (clips[win], vertex, n,
1, 1, ForePixel, LINE←STYLE(win),
MODE(win), PLANES);
}
else
XDraw (clips[win], vertex, n,
1, 1, ForePixel, MODE (win), PLANES);
}
set←line←style (win, n) {
LINE←STYLE(win) = line←style[n];
}
Pixmap
make←pattern (l1, l2) int l1, l2; {
Bitmap b; Pixmap p; short vec[16]; int i;
for (i=0; i < 16; i+=2) {
vec[i]=l1; vec[i+1]=l2;
}
b = XStoreBitmap(16, 16, vec);
p = XMakePixmap(b, WhitePixel, BlackPixel);
XFreeBitmap(b);
return(p);
}
init←pattern () {
patterns[reversevideo ? 0 : 1] = make←pattern (0, 0);
patterns[reversevideo ? 1 : 0] = make←pattern(0xffff, 0xffff);
patterns[2] = reversevideo ?
make←pattern(0xaaaa, 0x5555) :
make←pattern(0x5555, 0xaaaa);
patterns[reversevideo ? 3 : 4] = make←pattern(0x8888, 0x2222);
patterns[reversevideo ? 4 : 3] = make←pattern(0x7777, 0xdddd);
}
set←cur←pattern(win, n) int win, n; {
PATTERN(win)=patterns[n];
}
fill←area (win, n, vx, vy) int vx[],
vy[]; {
int i;
for(i = 0; i < n; i++){
vertex[i].x = vx[i]-CLIPX(win);
vertex[i].y = vy[i]-CLIPY(win);
vertex[i].flags = 0;
}
vertex[i].x = vx[0]-CLIPX(win);
vertex[i].y = vy[0]-CLIPY(win);
vertex[i].flags = 0;
vertex[0].flags = VertexStartClosed | VertexDontDraw;
vertex[i].flags = VertexEndClosed;
#ifdef sun
no←cursor (win);
#endif sun
XDrawTiled (clips[win], vertex, i+1, PATTERN(win), MODE(win), PLANES);
#ifdef sun
std←cursor (win);
#endif sun
}
no←cursor (win) {
XDefineCursor (clips[win], nocursor);
}
std←cursor (win) {
XDefineCursor (clips[win], cursor);
}
fill←rectangle (win, x, y, w, h) {
XTileFill(clips[win], x-CLIPX(win),
y-CLIPY(win), w, h,
PATTERN(win), 0, MODE(win), PLANES);
}
fill←vertex (win, n, vx, vy, flags) int vx[], vy[];{
int i, fill;
fill = n < MAXVERTEX ? n : MAXVERTEX;
for(i = 0; i < fill; i++){
vertex[i].x = vx[i]-CLIPX(win);
vertex[i].y = vy[i]-CLIPY(win);
vertex[i].flags = flags;
}
return fill;
}
draw←ellipse(win, x, y, rx, ry) {
fil←ver←ell (win, x, y, rx, ry);
vertex←draw (win, vertex, 5);
}
fill←ellipse(win, x, y, rx, ry) {
fil←ver←ell (win, x, y, rx, ry);
XDrawTiled(clips[win], vertex, 5, PATTERN(win), MODE(win), PLANES);
}
fil←ver←ell (win, x, y, rx, ry) {
x -= CLIPX(win);
y -= CLIPY(win);
vertex[0].x = x+rx;
vertex[1].x = x;
vertex[2].x = x-rx;
vertex[3].x = x;
vertex[4].x = x+rx;
vertex[0].y = y;
vertex[1].y = y-ry;
vertex[2].y = y;
vertex[3].y = y+ry;
vertex[4].y = y;
vertex[0].flags = VertexCurved | VertexStartClosed;
vertex[1].flags = VertexCurved;
vertex[2].flags = VertexCurved;
vertex[3].flags = VertexCurved;
vertex[4].flags = VertexCurved | VertexEndClosed;
}
draw←vertex(win, n, vx, vy, vf) int vx[], vy[], vf[];{
int i;
for(i=0; i<n; i++){
vertex[i].x=CLIPX(win)+vx[i];
vertex[i].y=CLIPY(win)+vy[i];
vertex[i].flags=vf[i];
}
XDraw(clips[win], vertex, n, 1, 1, ForePixel, MODE(win), PLANES);
}
tile←vertex(win, n, vx, vy, vf) int vx[], vy[], vf[];{
int i;
for(i=0; i<n; i++){
vertex[i].x=CLIPX(win)+vx[i];
vertex[i].y=CLIPY(win)+vy[i];
vertex[i].flags=vf[i];
}
XDrawTiled(clips[win], vertex, n, PATTERN(win), MODE(win), PLANES);
}
/* Les ico↑nes */
getpixmap (win, x, y, w, h, data) char *data; {
x -= CLIPX(win);
y -= CLIPY(win);
XPixmapGetXY (clips[win], x, y, w, h, data);
}
putpixmap (win, xs, ys, xd, yd, w, h, pixmap) Pixmap *pixmap; {
xd -= CLIPX(win);
yd -= CLIPY(win);
XPixmapPut (clips[win], xs, ys, xd, yd, w, h, pixmap, MODE(win), PLANES);
}
copyarea (win, xd, yd, xs, ys, w, h) {
xd -= CLIPX(win);
yd -= CLIPY(win);
xs -= CLIPX(win);
ys -= CLIPY(win);
XCopyArea (clips[win], xd, yd, xs, ys, w, h, MODE(win), PLANES);
}
Window Xwindow (win) { return windows[win];}
int llreversevideo () { return reversevideo; }
bidon () {
XFreePixmap();
XFreeBitmap();
XStoreBitmap();
XLine();
XMakePixmap();
XStorePixmapXY();
XPixmapBitsPutXY();
XPixmapGetXY();
XPixmapSave();
}
Window rootwindow() { return(RootWindow); }
int make←color (r, g, b) int r, g, b; {
Color color;
color.red = r;
color.green = g;
color.blue = b;
return XGetHardwareColor(&color) ? color.pixel : 0;
}
set←foreground (pixel) {
ForePixel = pixel;
}
set←background (pixel) {
BackPixel = pixel;
}