Initial import for the first release. init
authorshort <>
Fri, 9 Jun 2000 20:52:15 +0000 (20:52 +0000)
committershort <>
Fri, 9 Jun 2000 20:52:15 +0000 (20:52 +0000)
17 files changed:
GNUmakefile [new file with mode: 0644]
README [new file with mode: 0644]
dyna-add.c [new file with mode: 0644]
gmk2mk.c [new file with mode: 0644]
mkmk [new file with mode: 0755]
mop451.c [new file with mode: 0644]
mop451.in [new file with mode: 0644]
mop451.xpm [new file with mode: 0644]
mop453.c [new file with mode: 0644]
mop453.in [new file with mode: 0644]
mop453.xpm [new file with mode: 0644]
scoptions [new file with mode: 0644]
wllib-Amiga.c [new file with mode: 0644]
wllib-SVGA.c [new file with mode: 0644]
wllib-X11.c [new file with mode: 0644]
wllib-none.c [new file with mode: 0644]
wllib.h [new file with mode: 0644]

diff --git a/GNUmakefile b/GNUmakefile
new file mode 100644 (file)
index 0000000..76f76a2
--- /dev/null
@@ -0,0 +1,127 @@
+empty=
+space=$(empty) $(empty)
+
+## Operating system specification:
+# linux - Linux (1.3.37)
+# amiga - Amiga (customized 40.62)
+OS_NAME=linux
+
+## C compiler specification:
+# gcc  - GCC (2.7.0)
+# sasc - SAS/C (6.55)
+CC_NAME=gcc
+
+## Windowing system specification:
+# x11   - X Window System, Version 11(tm) (Release 6, Implementation: XFree 3.1.2)
+# amiga - Amiga native windowing system (customized 40.62)
+# svga  - svgalib - low level gfx (1.2.8) - only for Linux, as far as I know
+# none  - Without any graphics support
+WS_NAME=x11
+
+###
+
+ifndef WS_NAME
+WS_NAME=none
+endif
+
+###
+
+ifeq "$(CC_NAME)" "gcc" # C compiler: GCC
+CC_CFLAGS=-Wall -O6 -fomit-frame-pointer -finline-functions -fexpensive-optimizations #-ansi -pedantic
+CC_LDFLAGS=-lm -s
+DEFKWD=-D
+LDTO=-o
+LDTOO=-c -o
+endif
+
+ifeq "$(CC_NAME)" "sasc" # C compiler: SAS/C
+CC_CFLAGS=
+CC_LDFLAGS=LINK
+DEFKWD=DEF$(space)
+LDTO=PNAME
+LDTOO=OBJNAME
+endif
+
+###
+
+ifeq "$(OS_NAME)" "linux" # Operating system: Linux
+OS_CFLAGS=$(DEFKWD)_BSD_SOURCE $(DEFKWD)HAVE_RINT
+OS_LDFLAGS=
+CP=cp
+RM=rm -f
+endif
+
+ifeq "$(OS_NAME)" "amiga" # Operating system: Amiga
+OS_CFLAGS=
+OS_LDFLAGS=
+CP=copy
+RM=delete >NIL:
+endif
+
+###
+
+ifeq "$(WS_NAME)" "x11" # Windowing system: X Window System, Version 11(tm)
+WS_CFLAGS=$(DEFKWD)FOR_X11
+WS_LDFLAGS=-L/usr/X11/lib -lX11 -lXext -lXpm
+WS_LIBSUFF=X11
+endif
+
+ifeq "$(WS_NAME)" "amiga" # Windowing system: Amiga native windowing system
+WS_CFLAGS=$(DEFKWD)FOR_AMIGA
+WS_LDFLAGS=
+WS_LIBSUFF=Amiga
+endif
+
+ifeq "$(WS_NAME)" "svga" # Windowing system: svgalib - low level gfx
+WS_CFLAGS=$(DEFKWD)FOR_SVGA
+WS_LDFLAGS=-lvga
+WS_LIBSUFF=SVGA
+endif
+
+ifeq "$(WS_NAME)" "none" # Windowing system: Without any graphics support
+WS_CFLAGS=$(DEFKWD)FOR_NONE
+WS_LDFLAGS=
+WS_LIBSUFF=none
+endif
+
+###
+
+CFLAGS=$(OS_CFLAGS) $(CC_CFLAGS) $(WS_CFLAGS)
+LDFLAGS=$(OS_LDFLAGS) $(CC_LDFLAGS) $(WS_LDFLAGS)
+WLLIB=wllib-$(WS_LIBSUFF).c
+
+TARGETS=mop451 mop453  ## Examples-related
+
+.PHONY: all clean
+all: Makefile $(TARGETS)
+
+clean: 
+       -$(RM) $(TARGETS) *.o *.lnk *.npg gmk2mk
+
+distclean: clean
+       -$(RM) Makefile
+
+# Compatibility-related
+#######################
+gmk2mk: gmk2mk.c
+       $(CC) $(CFLAGS) $(LDFLAGS) $(LDTO) $@ $<
+
+Makefile: GNUmakefile gmk2mk
+       gmk2mk <GNUmakefile >Makefile
+
+# Examples-related
+##################
+mop451: mop451.o wllib.o
+       $(CC) $(LDFLAGS) $(LDTO) $@ $< wllib.o
+
+mop451.o: mop451.c mop451.xpm dyna-add.c wllib.h
+       $(CC) $(CFLAGS) $(LDTOO) $@ $<
+
+mop453: mop453.o wllib.o
+       $(CC) $(LDFLAGS) $(LDTO) $@ $< wllib.o
+
+mop453.o: mop453.c mop453.xpm dyna-add.c wllib.h
+       $(CC) $(CFLAGS) $(LDTOO) $@ $<
+
+wllib.o: $(WLLIB) wllib.h
+       $(CC) $(CFLAGS) $(LDTOO) $@ $<
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..8ade577
--- /dev/null
+++ b/README
@@ -0,0 +1,59 @@
+This library should make you generically use line drawing on the following
+platforms:
+
+Amiga computers (with native AmigaOS)
+Any UNIX station running X Window System (X11)
+Any UNIX (although probably only Linux) station running SVGA library
+
+Please set your platform in GNUmakefile (UNIX/X11 is default) and run 'make',
+then you can run './mop451 <mop451.in' or './mop453 <mop453.in' as example.  If
+you don't have GNU make installed (and 'make' command fails due to it), try
+using the provided './mkmk' script.
+
+The scale of drawing area is detected automatically, just use wl_line()
+function to draw lines.
+
+Please note that all these sources were written sometimes in 1995 or even
+sooner, I don't remember.
+
+
+WL library related file:
+------------------------
+README          This file you are reading
+GNUmakefile     Rules for 'make' to build this package
+wllib.h         Include file for WL library
+wllib-Amiga.c   Amiga native windowing system (customized 40.62)
+wllib-SVGA.c    Low level gfx (1.2.8) - only for Linux, as far as I know
+wllib-X11.c     X Window System, Version 11(tm) (Release 6, Implementation: XFree 3.1.2)
+wllib-none.c    Without any graphics support
+
+Files for some demonstration of WL library:
+-------------------------------------------
+mop451.c        First demonstration example source (its comments are in Czech language!)
+mop451.xpm      Icon for first demonstration example
+mop451.in       Some input, use following command to show it: ./mop451 <mop451.in
+
+mop453.c        Second demonstration example source (its comments are in Czech language!)
+dyna-add.c      Some functions needed by mop453
+mop453.xpm      Icon for second demonstration example
+mop453.in       Some input, use following command to show it: ./mop453 <mop453.in
+
+gmk2mk.c        Converter from GNUmakefile to the generally compatible Makefile
+mkmk            Builds Makefile from GNUmakefile if you have dumb 'make' (no GNU make)
+scoptions       Options file needed for SAS/C Amiga C compiler
+
+Contact to author:
+==================
+
+Name:       Jan Kratochvil
+
+e-Mail:     short@ucw.cz
+
+Phone: +420602431329 or
+       +420603431329
+
+Homepage:   http://atrey.karlin.mff.cuni.cz/~short/
+
+Snail-mail: K ovcinu 44
+            182 00, Praha 8
+            Czech Republic
diff --git a/dyna-add.c b/dyna-add.c
new file mode 100644 (file)
index 0000000..64f96c8
--- /dev/null
@@ -0,0 +1,68 @@
+#include <stdlib.h>
+#include <assert.h>
+#include "wllib.h"
+
+#define DA_QUANTUM (1024)
+
+struct da_list {
+       struct da_list *succ;
+       unsigned used;
+       da_num a[DA_QUANTUM];
+       } *da_head,*da_putp,*da_read;
+
+unsigned da_readn;
+unsigned long da_total;
+
+#ifdef NEED_DA_POS
+struct da_pos {
+       struct da_list *read;
+       unsigned readn;
+       };
+
+void da_putpos(struct da_pos *p)
+{
+       p->read=da_read;
+       p->readn=da_readn;
+}
+
+void da_getpos(struct da_pos *p)
+{
+       da_read=p->read;
+       da_readn=p->readn;
+}
+#endif
+
+#define da_init
+
+void da_put(long n)
+{
+struct da_list **lpp=NULL;
+       if (!da_head) lpp=&da_head;
+       else if (da_putp->used==DA_QUANTUM) lpp=&da_putp->succ;
+       if (lpp) {
+               if (!(da_putp=malloc(sizeof(*da_putp)))) iofail();
+               (*lpp=da_putp)->succ=NULL;
+               da_putp->used=0;
+               }
+       da_putp->a[da_putp->used++]=n;
+       da_total++;
+}
+
+void da_reset(void)
+{
+       da_read=da_head;
+       da_readn=0;
+}
+
+int da_get(long *n)
+{
+       if (da_read) {
+               *n=da_read->a[da_readn++];
+               if (da_readn==da_read->used) {
+                       da_read=da_read->succ;
+                       da_readn=0;
+                       }
+               return(1);
+               }
+       return(0);
+}
diff --git a/gmk2mk.c b/gmk2mk.c
new file mode 100644 (file)
index 0000000..26eebb1
--- /dev/null
+++ b/gmk2mk.c
@@ -0,0 +1,182 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#undef DEBUG
+
+#define iofail() do { perror(pname); exit(EXIT_FAILURE); } while (0)
+#define iofailn(e) do { errno=(e); perror(pname); exit(EXIT_FAILURE); } while (0)
+
+struct sym {
+       struct sym *succ;
+       char *sym,*val;
+       } *symt;
+char *pname;
+
+#define WHITE(c) ((c)==' '||(c)=='\t')
+
+static char *getsym(char *s)
+{
+struct sym *sm=symt;
+#ifdef DEBUG
+       fprintf(stderr,"getsym(\"%s\")\n",s);
+#endif
+       while (sm) {
+               if (!strcmp(sm->sym,s)) {
+#ifdef DEBUG
+                       fputs("getsym() - OK",stderr);
+#endif
+                       return(sm->val);
+                       }
+               sm=sm->succ;
+               }
+#ifdef DEBUG
+       fputs("getsym() - NOT FOUND",stderr);
+#endif
+       return(NULL);
+}
+
+static void addsym(char *sym,char *val)
+{
+size_t syml;
+struct sym *sm=malloc(sizeof(*sm)+(syml=strlen(sym)+1)+strlen(val)+1);
+#ifdef DEBUG
+       fprintf(stderr,"addsym(\"%s\",\"%s\")\n",sym,val);
+#endif
+       if (!sm) iofail();
+       sm->succ=symt;
+       symt=sm;
+       strcpy(symt->val=strcpy(symt->sym=(char *)sm+sizeof(*sm),sym)+syml,val);
+#ifdef DEBUG
+       fputs("addsym() end\n",stderr);
+#endif
+}
+
+static char *strip(char *s)
+{
+char *s2;
+#ifdef DEBUG
+       fprintf(stderr,"strip(\"%s\")\n",s);
+#endif
+       while (WHITE(*s)) s++;
+       for (s2=s;*s2;s2++); s2--;
+       while (s2>=s&&WHITE(*s2)) s2--;
+       *(s2+1)='\0';
+#ifdef DEBUG
+       fprintf(stderr,"strip()==\"%s\"\n",s);
+#endif
+       return(s);
+}
+
+static char *quote(char **sp)
+{
+char *s=*sp,*s2;
+       while (WHITE(*s)) s++;
+       if (*s++!='"') return(NULL);
+       s2=s;
+       while (*s&&*s!='"') s++;
+       if (!*s) return(NULL);
+       *s++='\0'; *sp=s;
+       return(s2);
+}
+
+int eval(char *s,char *buf,int bs)
+{
+#ifdef DEBUG
+       fprintf(stderr,"eval(\"%s\")\n",s);
+#endif
+       for (;;) {
+               while (*s&&*s!='$'&&bs) bs--,*buf++=*s++;
+               if (!bs) return(0);
+               if (!*s) {
+                       *buf++='\0';
+#ifdef DEBUG
+                       fputs("eval() end\n",stderr);
+#endif
+                       return(1);
+                       }
+               if (*++s=='(') {
+char *smn=++s,*sym;
+                       while (*s&&*s!=')') s++;
+                       if (!*s) return(0);
+                       *s++='\0';
+                       if ((sym=getsym(smn))) {
+                               while (*sym&&bs) bs--,*buf++=*sym++;
+                               if (!bs) return(0);
+                               }
+                       }
+               else *buf++='$';
+               }
+}
+
+int main(int argc,char **argv)
+{
+char line[512],outt[sizeof(line)],*s;
+char *c1,*c2,cn1[512],cn2[sizeof(cn1)];
+int lins,run=1,cdpos,proc,i;
+       if ((pname=rindex(*argv,'/'))) pname++;
+       else pname=*argv;
+       puts("\
+##############################################################\n\
+### This file was created automatically by gmk2mk utility. ###\n\
+### PLEASE DON'T EDIT THIS FILE, edit GNUmakefile instead. ###\n\
+##############################################################\n");
+       while (fgets(line,sizeof(line),stdin)) {
+               if (line[(lins=strlen(line))-1]=='\n') line[--lins]='\0';
+               strcpy(outt,line);
+               cdpos=1;
+               for (i=0;i<lins;i++)
+                       if (line[i]=='"') cdpos=!cdpos;
+                       else if (cdpos&&line[i]=='#') {
+                               line[lins=i]='\0';
+                               break;
+                               }
+               proc=1;
+               if (!strncmp(line,"ifeq ",5)) {
+                       cdpos=5;
+valcond:
+                       proc=0; s=&line[cdpos];
+                       if ((c1=quote(&s))) if ((c2=quote(&s))) {
+                               while (WHITE(*s)) s++;
+                               if (!*s&&eval(c1,cn1,sizeof(cn1))&&eval(c2,cn2,sizeof(cn2))) {
+                                       i=strcmp(cn1,cn2);
+                                       run=(!i&&cdpos==5)||(!!i&&cdpos==6);
+                                       }
+                               }
+                       }
+               else if (!strncmp(line,"ifneq ",6)) {
+                       cdpos=6;
+                       goto valcond;
+                       }
+               else if (!strncmp(line,"ifdef ",6)) {
+                       run=!!getsym(strip(&line[6]));
+                       proc=0;
+                       }
+               else if (!strncmp(line,"ifndef ",7)) {
+                       run=!getsym(strip(&line[7]));
+                       proc=0;
+                       }
+               else if (!strncmp(line,"else",4)) {
+                       run=!run;
+                       proc=0;
+                       }
+               else if (!strncmp(line,"endif",5)) {
+                       run=1;
+                       proc=0;
+                       }
+               if (!run||!proc) putchar('#');
+               else {
+                       for (i=0;i<lins;i++)
+                               if (line[i]=='=') {
+                                       line[i++]='\0';
+                                       if (eval(strip(&line[i]),cn1,sizeof(cn1))) {
+                                               addsym(strip(line),cn1);
+                                               }
+                                       break;
+                                       }
+                       }
+               puts(outt);
+               }
+       return(EXIT_SUCCESS);
+}
diff --git a/mkmk b/mkmk
new file mode 100755 (executable)
index 0000000..2c95693
--- /dev/null
+++ b/mkmk
@@ -0,0 +1,5 @@
+#!/bin/sh
+echo "cc -o gmk2mk gmk2mk.c"
+cc -o gmk2mk gmk2mk.c
+echo "./gmk2mk <GNUmakefile >Makefile"
+./gmk2mk <GNUmakefile >Makefile
diff --git a/mop451.c b/mop451.c
new file mode 100644 (file)
index 0000000..12153db
--- /dev/null
+++ b/mop451.c
@@ -0,0 +1,50 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+#include "wllib.h"
+
+#ifdef FOR_X11
+#include "mop451.xpm" /* Ikona pro X Window System$^{\def\fntmag{\magstep.2}\rm TM}$ */
+#endif
+
+struct {
+       long x,y; /* Souêadnice v~gfx */
+       } *ar; /* Pole vîech bodû */
+unsigned N,p; /* $N$, souçasný bod pêi kreslení */
+
+void drawgfx(void)
+{ /* vykresli gfx */
+       for (p=0;p<=N;p++) /* pro vîechny body dokola (první 2-krát) */
+               wl_line(ar[p==N?0:p].x,ar[p==N?0:p].y); /* spoj çáru */
+}
+
+int main(int argc,char **argv)
+{
+int i,j,rot=0,nkvx=0; /* pomocné, pomocné, smër uhýbání, není konvexní */
+long x,y; /* pro naçítání (zdrojové souê.) */
+float k=sin((float)60);
+       wl_init(&argc,argv,"MOP451"); /* inicializuj gfx */
+       if (scanf("%u",&N)!=1) iofailn(EINVAL); /* naçti $N$ */
+       if (N<3) iofailn(EINVAL); /* chceme mnohoúhelník */
+       if (!(ar=malloc(N*sizeof(*ar)))) iofail(); /* pole bodû */
+       for (i=0;i<N+1;i++) { /* na konci otestujeme jeîtë první body */
+               if (i<N) { /* jsme-li jeîtë v~naçítání */
+                       if (scanf("%ld %ld",&x,&y)!=2) iofailn(EINVAL);
+                       x<<=4; y<<=4; /* pro zvëtîení pêesnosti vykreslování */
+                       ar[i].x=x+y/2; ar[i].y=rint(k*y); /* pêeveð na pravoúhlé souê. */
+                       }
+#define A(q) ar[(q)>=N?(q)-N:(q)] /* pole se zrcadlem */
+               if (i>=2&&!nkvx) if ((j=(A(i-1).x-A(i-2).x)*(A(i).y-A(i-2).y)
+                               -(A(i-1).y-A(i-2).y)*(A(i).x-A(i-2).x))) { /* do \var j dej zatoçení souç. bodu */
+#undef A
+                       if (rot) nkvx|=j!=rot; /* víme-li jiù, kam zatáçíme, otestuj konvexnost */
+                       else rot=j; /* nyní jiù víme, kam zatáçíme */
+                       }
+               }
+       if (!rot) iofailn(EINVAL); /* vîechny body náleùely pêímce */
+       printf("Zadaný %u-úhelník %s konvexní.\n",N,nkvx?"není":"je");
+       wl_done(); /* gfx okno */
+       return(nkvx); /* hotovo */
+}
diff --git a/mop451.in b/mop451.in
new file mode 100644 (file)
index 0000000..18c47c7
--- /dev/null
+++ b/mop451.in
@@ -0,0 +1,4 @@
+3
+0 0
+1 0
+0 1
diff --git a/mop451.xpm b/mop451.xpm
new file mode 100644 (file)
index 0000000..b966cb6
--- /dev/null
@@ -0,0 +1,43 @@
+/* XPM */
+char *icon_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"    44    32        4            1",
+/* colors */
+". c gray67",     /* #aaaaaa */
+"# c black",      /* #000000 */
+"a c white",      /* #ffffff */
+"b c steel blue", /* #6688bb */
+/* pixels */
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+"a###########################################",
+"a#........................................a#",
+"a#........................................a#",
+"a#........................................a#",
+"a#........................................a#",
+"a#.............##.......a.................a#",
+"a#............#..##.....a.................a#",
+"a#...........#.....##....a................a#",
+"a#..........#........##..a................a#",
+"a#.........#...........##.a...............a#",
+"a#........#..........aaaaaa...............a#",
+"a#.......#.................b..............a#",
+"a#......#....................b............a#",
+"a#.....#.......................b..........a#",
+"a#....#..........................b........a#",
+"a#...#.............................b......a#",
+"a#....#............................b.b....a#",
+"a#.....#.......................b.b........a#",
+"a#......#..................b.b............a#",
+"a#.......#................................a#",
+"a#........#...............................a#",
+"a#.........#..............................a#",
+"a#..........#.............................a#",
+"a#...........#............................a#",
+"a#............#...........................a#",
+"a#........................................a#",
+"a#........................................a#",
+"a#........................................a#",
+"a#........................................a#",
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#",
+"a###########################################"
+};
diff --git a/mop453.c b/mop453.c
new file mode 100644 (file)
index 0000000..d3aaa8d
--- /dev/null
+++ b/mop453.c
@@ -0,0 +1,122 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <limits.h>
+#include <errno.h>
+#include "wllib.h"
+
+#ifdef FOR_X11
+#include "mop453.xpm" /* Ikona pro X Window System$^{\def\fntmag{\magstep.2}\rm TM}$ */
+#endif
+
+#ifndef PI
+#ifdef M_PI
+#define PI M_PI
+#else
+#define PI 3.14159265358979323846
+#endif
+#endif
+
+typedef long da_num; /* budeme {\I dyna-add}it \type{long}y */
+#define NEED_DA_POS /* potêebujeme \func{da_putpos}() a \func{da_getpos}() */
+#include "dyna-add.c" /* modul dynamického pêidávání */
+
+float curX,curY; /* souêadnice pera */
+int curA; /* úhel natoçení pera */
+
+static void draw_seq(void)
+{ /* vykresli posloupnost z~dyna-struktury */
+long st1; /* první parametr dyna-struktury */
+int i; /* pomocné */
+       for (;;) { /* pro neomezený poçet dvojic */
+               i=da_get(&st1); assert(!!i); /* poslední prvek bude 0 */
+               if (!st1) return; /* ukonçení posloupnosti */
+               if (st1<0) { /* prvek$<0$ $\Longrightarrow$ dvë çísla */
+long p1; /* vzdálenost */
+float k=0/*fake for GCC*/; /* úhel v~radiánech */
+                       i=da_get(&p1); assert(!!i); /* tento parametr také musí existovat */
+                       curX+=p1*sin(k=(float)curA*PI/180); /* îoupni pérem */
+                       wl_line((long)rint(curX*16),(long)rint((curY+=p1*cos(k))*16)); /* táhni! (\dots çáru) */
+                       if ((curA+=st1)<0) curA+=360; /* natoç pero a moùná pêeteç */
+                       }
+               else { /* opakuj posloupnost */
+struct da_pos pos; /* zapamatování pozice pro opakování */
+                       da_putpos(&pos); /* pamatuj! */
+                       while (st1--) { /* \var{st1}-krát */
+                               da_getpos(&pos); /* pro velký ohlas repríza */
+                               draw_seq(); /* jedem znova posloupnost */
+                               }
+                       }
+               }
+}
+
+void drawgfx(void)
+{ /* vykresli gfx */
+long n;
+       da_reset(); /* nainicializuj dyna-struktury na zaçátek */
+       wl_line((long)(curX=0),(long)(curY=0)); /* první bod je z~$(0,0)$ */
+       curA=0; /* natoçení ªna severº */
+       draw_seq(); /* zpracuj top-level posloupnost */
+       assert(!da_get(&n)); /* ujisti se, ùe to bylo vîe */
+}
+
+static long get_lex(void)
+{ /* naçti lexikální element a vraï çíslo,
+çi LONG_MIN pro \sign[ nebo LONG_MAX pro \sign] */
+int c,isn=0,neg=0; /* naçtený znak, kousek çísla?, záporné? */
+long n=0; /* sestavované çíslo */
+       for (;;) { /* \dots a v~ùivotë to nikdo nezastaví */
+               if ((c=getchar())==EOF) iofail(); /* EOF má pêijít v~\func{main}()u */
+               if (c=='\n'||c=='\t') c=' '; /* white-space */
+               if (c==' ') {
+                       if (isn) break; /* je-li kousek çísla, potom oddëlovaç */
+                       else continue; /* jinak ignoruj */
+                       }
+               if (c=='['||c==']') break; /* terminují vùdy */
+               if (!neg&&c=='-') { neg=1; continue; } /* záporné çíslo? */
+               if (c<'0'||c>'9') iofailn(EINVAL); /* tady by to jiù mëla být cifra */
+               isn=1; /* jiù máme kousek çísla */
+               if (n>LONG_MAX/10) iofailn(ERANGE); /* nevyteçeme? */
+               n=n*10+c-'0'; /* pêedpoklady: desítková soustava a souvislé kódy cifer */
+               }
+       if (isn) { /* terminace uprostêed çísla */
+               if (neg) n=-n; /* negativní numero */
+               if (n==LONG_MIN||n==LONG_MAX) iofailn(ERANGE); /* check kolize návratových hodnot */
+               ungetc(c,stdin); /* byla-li to hranatka, bude jeîtë potêeba, white-space se sveze */
+               }
+       return(isn?n:(c=='['?LONG_MIN:LONG_MAX)); /* çíslo, çi typ hranatky */
+}
+
+long p1,p2; /* pro chroustání posloupnosti jsou jako auto-variábly zbyteçnë expensive */
+
+static void do_seq(void)
+{ /* nachroustej jednu úroveñ posloupnosti */
+       while ((p1=get_lex())!=LONG_MAX) { /* dokud nenarazíî na \sign] */
+               if (p1==LONG_MIN) iofailn(EINVAL); /* $P_1$ musí být çíslo */
+               if ((p2=get_lex())==LONG_MAX) iofailn(EINVAL); /* $P_2$ nesmí být \sign] */
+               if (p2==LONG_MIN) { /* bylo-li $P_2$ \sign[ */
+                       if (p1<=0) iofailn(EINVAL); /* $P_1$ musí být kladné */
+                       da_put(p1); /* uloù kladné çíslo jako opakovaní */
+                       do_seq(); /* rekurzivnë zpracuj opakovanou posloupnost */
+                       }
+               else { /* budeme kreslit */
+                       p2%=360; if (p2>=0) p2-=360; /* znormalizuj úhel do záporna */
+                       da_put(p2); da_put(p1); /* nejdêív úhel ($P_2$ -- odliîení od opakování),
+potom délka ($P_1$) */
+                       }
+               }
+       da_put(0); /* terminátor posloupnosti */
+}
+
+int main(int argc,char **argv)
+{
+int i;
+       wl_init(&argc,argv,"MOP453"); /* inicializuj gfx */
+       if (get_lex()!=LONG_MIN) iofailn(EINVAL); /* první element musí být \sign[ */
+       do_seq(); /* zpracuj top-level posloupnost */
+       do i=getchar(); while (i==' '||i=='\n'||i=='\t'); /* seùer white-spacy */
+       if (i!=EOF) iofailn(EINVAL); /* musí být EOF, jinak ERROR */
+       wl_done(); /* gfx okno */
+       return(0); /* hotovo */
+}
diff --git a/mop453.in b/mop453.in
new file mode 100644 (file)
index 0000000..44b83c4
--- /dev/null
+++ b/mop453.in
@@ -0,0 +1 @@
+[4[100 90]]
diff --git a/mop453.xpm b/mop453.xpm
new file mode 100644 (file)
index 0000000..1a3fabb
--- /dev/null
@@ -0,0 +1,42 @@
+/* XPM */
+char *icon_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"    44    32        3            1",
+/* colors */
+". c gray67",     /* #aaaaaa */
+"# c black",      /* #000000 */
+"a c white",      /* #ffffff */
+/* pixels */
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+"a###########################################",
+"a#........................................a#",
+"a#........................................a#",
+"a#....#...#...#...........................a#",
+"a#...##..#.#.#.#...........#..............a#",
+"a#....#..#.#.#.#.#.#......#a..............a#",
+"a#....#..#.#.#.#..#......#.a..............a#",
+"a#...###..#...#..#.#....#...a.............a#",
+"a#.....................#....a.............a#",
+"a#....................#...a.a..a..........a#",
+"a#...................#.....a.a.a..........a#",
+"a#..................#.......aaa...........a#",
+"a#.................#.........a............a#",
+"a#................#.......................a#",
+"a#...............#........................a#",
+"a#..............#.........................a#",
+"a#.............#..........................a#",
+"a#............#...........................a#",
+"a#...........#............................a#",
+"a#..........#.............................a#",
+"a#.........#..............................a#",
+"a#........#...............................a#",
+"a#.......#................................a#",
+"a#......#....................##########...a#",
+"a#.....#..................................a#",
+"a#....#...................................a#",
+"a#...........................##########...a#",
+"a#........................................a#",
+"a#........................................a#",
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#",
+"a###########################################"
+};
diff --git a/scoptions b/scoptions
new file mode 100644 (file)
index 0000000..918b9a9
--- /dev/null
+++ b/scoptions
@@ -0,0 +1,25 @@
+DEBUG=FULLFLUSH
+MATH=FFP
+CPU=68010
+PARAMETERS=REGISTERS
+ANSI
+NOSTACKCHECK
+STRINGMERGE
+COMMENTNEST
+STRINGSCONST
+OPTIMIZERINLINELOCAL
+SMALLCODE
+SMALLDATA
+ADDSYMBOLS
+NOVERSION
+STRICT
+UTILITYLIBRARY
+NOICONS
+MEMORYSIZE=HUGE
+ONERROR=CONTINUE
+GENPROTOSTATICS
+OPTIMIZERTIME
+IGNORE=220
+LINKEROPTIONS=QUIET
+MAXIMUMERRORS=20
+MAXIMUMWARNINGS=100
diff --git a/wllib-Amiga.c b/wllib-Amiga.c
new file mode 100644 (file)
index 0000000..0da2a7c
--- /dev/null
@@ -0,0 +1,125 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <limits.h>
+#include <assert.h>
+#include <intuition/intuition.h>
+#include <intuition/intuitionbase.h>
+#include <exec/ports.h>
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <proto/graphics.h>
+#include "wllib.h"
+
+#define SAFE_BORDER (4)
+#define SIZE_MIN (16)
+
+extern void drawgfx(void);
+
+long xcur,ycur,xmin,xmax,ymin,ymax;
+int winx,winy,iniline,minimax=1;
+float coefx,coefy;
+int xofs,yofs,xbor,ybor;
+
+struct RastPort *rport;
+struct Window *win;
+char *pname;
+
+struct NewWindow nwin={0,0,0,0,UCHAR_MAX,UCHAR_MAX,
+IDCMP_NEWSIZE|IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_VANILLAKEY,
+WFLG_SIZEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_SIZEBRIGHT
+|WFLG_SMART_REFRESH|WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_NOCAREREFRESH,
+NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN};
+#define pubscr (nwin.Screen)
+
+#define gfxfail() { fprintf(stderr,"%s: Gfx subsys failed!\n",pname); \
+exit(EXIT_FAILURE); } while (0)
+
+void wl_line(long x,long y)
+{
+       if (iniline) {
+               iniline=0;
+               if (minimax) { xmin=xmax=x; ymin=ymax=y; }
+               else Move(rport,(long)(coefx*(x-xmin)+xofs),
+                               (long)(yofs-coefy*(y-ymin)));
+               }
+       else if (minimax) {
+               if (x<xmin) xmin=x; if (x>xmax) xmax=x;
+               if (y<ymin) ymin=y; if (y>ymax) ymax=y;
+               }
+       else Draw(rport,(long)(coefx*(x-xmin)+xofs),
+                       (long)(yofs-coefy*(y-ymin)));
+}
+
+static void wl_safeclose(void)
+{
+struct IntuiMessage *msg;
+       Forbid();
+       while (msg=(struct IntuiMessage *)GetMsg(win->UserPort))
+               ReplyMsg((struct Message *)msg);
+       ModifyIDCMP(win,0);
+       Permit();
+       CloseWindow(win);
+       win=NULL;
+}
+
+void wl_done(void)
+{
+struct IntuiMessage *msg;
+ULONG cls;
+       iniline=1; drawgfx();
+       minimax=0;
+       if (xmax==xmin) xmax++;
+       if (ymax==ymin) ymax++;
+       if (IntuitionBase->LibNode.lib_Version>=39) SetWindowPointer(win,TAG_DONE);
+       for (;;) {
+               if (!iniline) {
+                       coefx=(float)(winx-xbor-1)/(xmax-xmin);
+                       coefy=(float)(winy-ybor-1)/(ymax-ymin);
+                       yofs=winy-SAFE_BORDER-win->BorderBottom;
+                       SetAPen(rport,0);
+                       RectFill(rport,(long)win->BorderLeft,(long)win->BorderTop,
+                                       (long)(winx-win->BorderRight-1),(long)(winy-win->BorderBottom-1));
+                       SetAPen(rport,1);
+                       iniline=1; drawgfx();
+                       }
+               while (!(msg=(struct IntuiMessage *)GetMsg(win->UserPort)))
+                       WaitPort(win->UserPort);
+               cls=msg->Class;
+               ReplyMsg((struct Message *)msg);
+               if (cls!=IDCMP_NEWSIZE) { wl_safeclose(); return; }
+               winx=win->Width; winy=win->Height;
+               }
+}
+
+static void wl_cleanup(void)
+{
+       while (win) wl_safeclose();
+       if (pubscr) {
+               UnlockPubScreen(NULL,pubscr);
+               pubscr=NULL;
+               }
+}
+
+void wl_init(int *argcp,char **argv,const char *class)
+{
+       if ((pname=rindex(*argv,'/'))) pname++;
+       else pname=*argv;
+       atexit(wl_cleanup);
+       if (!(pubscr=LockPubScreen(NULL))) gfxfail();
+       nwin.Title=(char *)class;
+       nwin.LeftEdge=(winx=nwin.Width=pubscr->Width/2)/2;
+       nwin.TopEdge=(winy=nwin.Height=pubscr->Height/2)/2;
+       if (!(win=OpenWindow(&nwin))) gfxfail();
+       if (IntuitionBase->LibNode.lib_Version>=39)
+               SetWindowPointer(win,WA_BusyPointer,TRUE,WA_PointerDelay,TRUE,TAG_DONE);
+       WindowLimits(win,
+                       (long)(xbor=(xofs=win->BorderLeft+SAFE_BORDER)
+                                       +SAFE_BORDER+win->BorderRight )+SIZE_MIN,
+                       (long)(ybor=win->BorderTop +SAFE_BORDER
+                                       +SAFE_BORDER+win->BorderBottom)+SIZE_MIN,~0,~0);
+       SetDrMd(rport=win->RPort,JAM1);
+}
diff --git a/wllib-SVGA.c b/wllib-SVGA.c
new file mode 100644 (file)
index 0000000..eaf8c70
--- /dev/null
@@ -0,0 +1,87 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+#include <vga.h>
+#include "wllib.h"
+
+#define SAFE_BORDER (4)
+#define SIZE_MIN (16)
+
+#define DEFAULT_MODE G320x200x256
+
+extern void drawgfx(void);
+
+long xmin,xmax,ymin,ymax;
+int winx,winy,iniline,minimax=1,xcur,ycur;
+float coefx,coefy;
+
+char *pname;
+
+void wl_line(long x,long y)
+{
+       if (iniline) {
+               iniline=0;
+               if (minimax) { xmin=xmax=x; ymin=ymax=y; }
+               else {
+                       xcur=rint(coefx*(x-xmin))+SAFE_BORDER;
+                       ycur=winy-SAFE_BORDER-rint(coefy*(y-ymin));
+                       }
+               }
+       else {
+               if (minimax) {
+                       if (x<xmin) xmin=x; if (x>xmax) xmax=x;
+                       if (y<ymin) ymin=y; if (y>ymax) ymax=y;
+                       }
+               else {
+int xcur2,ycur2;
+                       vga_drawline(xcur,ycur,
+                                       xcur2=rint(coefx*(x-xmin))+SAFE_BORDER,ycur2=winy-SAFE_BORDER-rint(coefy*(y-ymin)));
+                       xcur=xcur2; ycur=ycur2;
+                       }
+               }
+}
+
+
+void wl_done(void)
+{
+       iniline=1; drawgfx();
+       minimax=0;
+       if (xmax==xmin) xmax++;
+       if (ymax==ymin) ymax++;
+       if (iniline) return;
+       coefx=(float)(winx-2*SAFE_BORDER-1)/(xmax-xmin);
+       coefy=(float)(winy-2*SAFE_BORDER-1)/(ymax-ymin);
+       iniline=1; drawgfx();
+       vga_getch();
+}
+
+static void wl_cleanup(void)
+{
+       vga_setmode(TEXT);
+}
+
+void wl_init(int *argcp,char **argv,const char *class)
+{
+int i,j;
+char *s=NULL;
+int mode=-1;
+       if ((pname=rindex(*argv,'/'))) pname++;
+       else pname=*argv;
+       for (j=i=1;i<*argcp;i++)
+               if (!strcmp(argv[i],"-m")||!strcmp(argv[i],"--mode")) {
+                       s=argv[++i]; j++;
+                       }
+               else argv[j++]=argv[i];
+       if (s) mode=vga_getmodenumber(s);
+       if (mode==-1) if ((mode=vga_getdefaultmode())==-1) mode=DEFAULT_MODE;
+       if (vga_setmode(mode)==-1) {
+               fprintf(stderr,"%s: Mode \"%s\" [%d] not available!\n",pname,
+                               vga_getmodename(mode),mode);
+               exit(EXIT_FAILURE);
+               }
+       atexit(wl_cleanup);
+       winx=vga_getxdim(); winy=vga_getydim();
+       vga_setcolor(vga_white());
+}
diff --git a/wllib-X11.c b/wllib-X11.c
new file mode 100644 (file)
index 0000000..96cb7cf
--- /dev/null
@@ -0,0 +1,286 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <math.h>
+#include <ctype.h>
+#include <limits.h>
+#include <assert.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
+#include <X11/xpm.h>
+#include <X11/extensions/shape.h>
+#include <X11/cursorfont.h>
+#include "wllib.h"
+
+#define SAFE_BORDER (4)
+#define SIZE_MIN (16)
+
+extern char *icon_xpm[];
+extern void drawgfx(void);
+
+long xcur,ycur,xmin,xmax,ymin,ymax;
+int winx,winy,iniline,minimax=1;
+float coefx,coefy;
+
+Display *dp;
+Screen *scr;
+int scrnum;
+Colormap cmap;
+unsigned long fgpen,bgpen;
+XrmDatabase rdb;
+Window win,rootw;
+GC gc;
+Cursor curs;
+Atom atdel;
+
+XrmOptionDescRec opts[]={
+{"-bg",          ".background",  XrmoptionSepArg,NULL}, /*  0! */
+{"-background",  ".background",  XrmoptionSepArg,NULL}, /*  1! */
+{"-bd",          ".borderColor", XrmoptionSepArg,NULL}, /*  2! */
+{"-bordercolor", ".borderColor", XrmoptionSepArg,NULL}, /*  3! */
+{"-bw",          ".borderWidth", XrmoptionSepArg,NULL}, /*  4! */
+{"-borderwidth", ".borderWidth", XrmoptionSepArg,NULL}, /*  5! */
+{"-display",     ".display",     XrmoptionSepArg,NULL}, /*  6! */
+{"-fg",          ".foreground",  XrmoptionSepArg,NULL}, /*  7! */
+{"-foreground",  ".foreground",  XrmoptionSepArg,NULL}, /*  8! */
+{"-geometry",    ".geometry",    XrmoptionSepArg,NULL}, /*  9! */
+{"-iconic",      ".iconStartup", XrmoptionNoArg, "on"}, /* 10! */
+{"-name",        ".name",        XrmoptionSepArg,NULL}, /* 11! */
+{"-rv",          ".reverseVideo",XrmoptionNoArg, "on"}, /* 12! */
+{"-reverse",     ".reverseVideo",XrmoptionNoArg, "on"}, /* 13! */
+{"+rv",          ".reverseVideo",XrmoptionNoArg, "on"}, /* 14! */
+{"+reverse",     ".reverseVideo",XrmoptionNoArg, "on"}, /* 15! */
+{"-title",       ".title",       XrmoptionSepArg,NULL}, /* 16! */
+{"-xrm",         NULL,           XrmoptionResArg,NULL}, /* 17! */
+};
+#define opts_num (sizeof(opts)/sizeof(*opts))
+
+char *pname;
+size_t pnamelen;
+char fn[128]="/usr/lib/X11/app-defaults/",resnam[sizeof(fn)],rescls[sizeof(fn)];
+#define APPDEFNL (26)
+size_t classlen;
+
+void wl_line(long x,long y)
+{
+       if (iniline) {
+               iniline=0;
+               if (minimax) { xmin=xmax=x; ymin=ymax=y; }
+               else {
+                       xcur=rint(coefx*(x-xmin))+SAFE_BORDER;
+                       ycur=winy-SAFE_BORDER-rint(coefy*(y-ymin));
+                       }
+               }
+       else {
+               if (minimax) {
+                       if (x<xmin) xmin=x; if (x>xmax) xmax=x;
+                       if (y<ymin) ymin=y; if (y>ymax) ymax=y;
+                       }
+               else {
+int xcur2,ycur2;
+                       XDrawLine(dp,win,gc,xcur,ycur,
+                                       xcur2=rint(coefx*(x-xmin))+SAFE_BORDER,ycur2=winy-SAFE_BORDER-rint(coefy*(y-ymin)));
+                       xcur=xcur2; ycur=ycur2;
+                       }
+               }
+}
+
+int stricmp(char *s1,char *s2)
+{
+int i;
+char c1,c2;
+       while (*s1&&*s2) if ((i=(c1=toupper(*s1++))>(c2=toupper(*s2++))-(c1<c2))) return(i);
+       return(0);
+}
+
+static char *res_string(int resn,const char *resc)
+{
+char *s;
+XrmValue val;
+       strncpy(&resnam[pnamelen],opts[resn].specifier,sizeof(resnam)-pnamelen);
+       strncpy(&rescls[classlen],resc                ,sizeof(rescls)-classlen);
+       if (XrmGetResource(rdb,resnam,rescls,&s,&val)) {
+               if (!(s=malloc(val.size))) iofail();
+               return(strncpy(s,val.addr,val.size));
+               }
+       return(NULL);
+}
+
+static int res_bool(char *s)
+{
+static char *yestr[4]={"1","on","yes","true"};
+#define YESTRL (sizeof(yestr)/sizeof(*yestr))
+int i;
+       if (s) for (i=0;i<YESTRL;i++)
+               if (!stricmp(s,yestr[i])) { free(s); return(1); }
+       free(s);
+       return(0);
+}
+
+static int res_int(char *s,int def)
+{
+char *ers;
+       if (s) {
+               def=strtol(s,&ers,0);
+               if (ers&&*ers) { fprintf(stderr,"strtol() error @\"%s\"\n",ers); iofail(); }
+               free(s);
+               }
+       return(def);
+}
+
+typedef enum { color_def_White,color_def_Black } color_def;
+static unsigned long get_color(char *desc,color_def def)
+{
+XColor xcol_scr,xcol_ex;
+       if (!desc) return(def==color_def_White?WhitePixelOfScreen(scr):BlackPixelOfScreen(scr));
+       else if (!XAllocNamedColor(dp,cmap=DefaultColormapOfScreen(scr),desc,&xcol_scr,&xcol_ex))
+                       { fprintf(stderr,"XAllocNamedColor(\"%s\")\n",desc); iofail(); }
+       return(xcol_scr.pixel);
+}
+
+void wl_done(void)
+{
+XEvent ev;
+       iniline=1; drawgfx();
+       minimax=0;
+       if (xmax==xmin) xmax++;
+       if (ymax==ymin) ymax++;
+       XUndefineCursor(dp,win);
+       XFreeCursor(dp,curs);
+       for (;;) {
+               XNextEvent(dp,&ev);
+               if (ev.xany.window==win) switch(ev.type) {
+                       case ConfigureNotify:
+                               winx=ev.xconfigure.width; winy=ev.xconfigure.height;
+                               break;
+                       case ClientMessage:
+                               if (ev.xclient.format==32) if (ev.xclient.data.l[0]==atdel)
+                       case ButtonPress:
+                       case KeyPress:
+                                       exit(EXIT_SUCCESS);
+                               break;
+                       case Expose:
+                               XClearArea(dp,win,ev.xexpose.x,ev.xexpose.y,ev.xexpose.width,ev.xexpose.height,False);
+                               if (ev.xexpose.count) break;
+                               if (!iniline) {
+                                       coefx=(float)(winx-1-2*SAFE_BORDER)/(xmax-xmin);
+                                       coefy=(float)(winy-1-2*SAFE_BORDER)/(ymax-ymin);
+                                       iniline=1; drawgfx();
+                                       }
+                       }
+               }
+}
+
+void wl_init(int *argcp,char **argv,const char *class)
+{
+char *s,*disp;
+size_t ts;
+unsigned long bdpen;
+unsigned bw;
+XSetWindowAttributes wina;
+XSizeHints *sizh;
+XWMHints *wmh;
+XClassHint *clsh;
+int xs,ys,i;
+struct {
+       Pixmap data,mask;
+       XpmAttributes attr;
+       Window win;
+       XIconSize *siz;
+       } icon;
+
+       if ((pname=rindex(*argv,'/'))) pname++;
+       else pname=*argv;
+       pnamelen=strlen(pname);
+       XrmInitialize();
+       strncpy(&fn[APPDEFNL],class,sizeof(fn)-APPDEFNL);
+       rdb=XrmGetFileDatabase(fn);
+       if (!(s=getenv("XUSERFILESEARCHPATH"))) s=getenv("XAPPLRESDIR");
+       if (s) if (!(ts=strlen(strncpy(fn,s,sizeof(fn))))) {
+               if (fn[ts-1]!='/') fn[ts++]='/';
+               strncpy(&fn[ts],class,sizeof(fn)-ts);
+               XrmCombineFileDatabase(fn,&rdb,True);
+               }
+       XrmParseCommand(&rdb,opts,opts_num,class,argcp,argv);
+       strncpy(resnam,pname,sizeof(resnam));
+       strncpy(rescls,class,sizeof(rescls));
+       classlen=strlen(class);
+       if ((s=res_string(11,".Name")))
+               pnamelen=strlen(pname=s);
+       if (!(dp=XOpenDisplay(disp=res_string(6,".Display"))))
+               { fprintf(stderr,"Display=\"%s\"\n",XDisplayName(disp)); iofail(); }
+       if (!(s=getenv("HOME"))) s="~";
+       ts=strlen(strncpy(fn,s,sizeof(fn)));
+       strncpy(&fn[ts],"/.Xdefaults-",sizeof(fn)-ts); ts+=12;
+       if (!(s=getenv("XENVIRONMENT"))) {
+               if (gethostname(&fn[ts],sizeof(fn)-ts)) iofail();
+               s=fn;
+               }
+       XrmCombineFileDatabase(s,&rdb,False);
+       if ((s=XScreenResourceString(scr=ScreenOfDisplay(dp,scrnum=DefaultScreen(dp)))))
+               XrmCombineDatabase(XrmGetStringDatabase(s),&rdb,False);
+       if ((s=XResourceManagerString(dp)))
+               XrmCombineDatabase(XrmGetStringDatabase(s),&rdb,False);
+       else {
+               fn[ts-1]='\0';
+               XrmCombineFileDatabase(fn,&rdb,False);
+               }
+       bw=res_int(res_string(4,".BorderWidth"),0);
+       bgpen=get_color(res_string(0,".Background" ),color_def_White);
+       fgpen=get_color(res_string(7,".Foreground" ),color_def_Black);
+       if (res_bool(res_string(12,".ReverseVideo")))
+               { bdpen=bgpen; bgpen=fgpen; fgpen=bdpen; }
+       bdpen=get_color(res_string(2,".BorderColor"),color_def_Black);
+       if (!(sizh=XAllocSizeHints())) iofail();
+       xs=WidthOfScreen(scr)/2; ys=HeightOfScreen(scr)/2;
+       sprintf(fn,"%dx%d+%d+%d",xs,ys,xs/2,ys/2);
+       sizh->flags=(i=XWMGeometry(dp,scrnum,res_string(9,".Geometry"),fn,bw,sizh,
+                                       &sizh->x,&sizh->y,&winx,&winy,&sizh->win_gravity)
+                       &(XValue|YValue)?USPosition:PPosition)|(i&(WidthValue|HeightValue)?USSize:PSize)
+                       |PMinSize|PWinGravity;
+       sizh->min_height=sizh->min_width=2*SAFE_BORDER+SIZE_MIN;
+       if (!(win=XCreateSimpleWindow(dp,rootw=RootWindowOfScreen(scr),
+                       sizh->x,sizh->y,sizh->width=winx,sizh->height=winy,bw,bdpen,bgpen))) iofail();
+       icon.attr.valuemask=0;
+       if ((i=XpmCreatePixmapFromData(dp,win,icon_xpm,&icon.data,&icon.mask,&icon.attr)))
+               { fprintf(stderr,"XpmCreatePixmapFromData() error #%d\n",i); iofail(); }
+       if (!(icon.siz=XAllocIconSize())) iofail();
+       icon.siz->max_width =icon.siz->min_width =icon.attr.width;
+       icon.siz->max_height=icon.siz->min_height=icon.attr.height;
+       icon.siz->height_inc=icon.siz->width_inc=0;
+       XSetIconSizes(dp,win,icon.siz,1);
+       XFree(icon.siz);
+       if (!(icon.win=XCreateSimpleWindow(dp,rootw,0,0,
+                       icon.attr.width,icon.attr.height,0,bdpen,bgpen))) iofail();
+       XpmFreeAttributes(&icon.attr);
+       XSetWindowBackgroundPixmap(dp,icon.win,icon.data);
+       XFreePixmap(dp,icon.data);
+       if (icon.mask) {
+               XShapeCombineMask(dp,icon.win,ShapeBounding,0,0,icon.mask,ShapeSet);
+               XFreePixmap(dp,icon.mask);
+               }
+       XClearWindow(dp,icon.win);
+       if (!(wmh=XAllocWMHints())) iofail();
+       wmh->flags=StateHint|IconWindowHint;
+       wmh->initial_state=res_bool(res_string(10,".IconStartup"))?IconicState:NormalState;
+       wmh->icon_window=icon.win;
+       if (!(clsh=XAllocClassHint())) iofail();
+       clsh->res_name=pname;
+       clsh->res_class=(char *)class;
+       if (!(s=res_string(16,".Title"))) s=(char *)class;
+       XmbSetWMProperties(dp,win,s,class,argv,*argcp,sizh,wmh,clsh);
+       XFree(sizh); XFree(wmh); XFree(clsh);
+       wina.backing_store=WhenMapped;
+       wina.event_mask=ButtonPressMask|KeyPressMask|StructureNotifyMask|ExposureMask;
+       wina.cursor=curs=XCreateFontCursor(dp,XC_watch);
+       XChangeWindowAttributes(dp,win,CWBackingStore|CWEventMask|CWCursor,&wina);
+       atdel=XInternAtom(dp,"WM_DELETE_WINDOW",False);
+       XSetWMProtocols(dp,win,&atdel,1);
+       XMapWindow(dp,win);
+       XFlush(dp);
+       gc=DefaultGCOfScreen(scr);
+}
diff --git a/wllib-none.c b/wllib-none.c
new file mode 100644 (file)
index 0000000..f73cabc
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <string.h>
+#include "wllib.h"
+
+char *pname;
+
+void wl_line(long x,long y)
+{
+}
+
+void wl_init(int *argcp,char **argv,const char *class)
+{
+       if ((pname=rindex(*argv,'/'))) pname++;
+       else pname=*argv;
+}
diff --git a/wllib.h b/wllib.h
new file mode 100644 (file)
index 0000000..4324aa4
--- /dev/null
+++ b/wllib.h
@@ -0,0 +1,21 @@
+#ifndef _WLLIB_H
+#define _WLLIB_H 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+extern char *pname;
+
+extern void wl_init(int *argcp,char **argv,const char *class);
+extern void wl_line(long x,long y);
+extern void wl_done(void);
+
+#define iofail() do { perror(pname); exit(EXIT_FAILURE); } while (0)
+#define iofailn(e) do { errno=(e); perror(pname); exit(EXIT_FAILURE); } while (0)
+
+#ifndef HAVE_RINT
+#define rint
+#endif
+
+#endif