1MODULE oocXYplane; 2(* 3Module XYplane provides some basic facilities for graphics programming. Its 4interface is kept as simple as possible and is therefore more suited for 5programming exercises than for serious graphics applications. 6 7XYplane provides a Cartesian plane of pixels that can be drawn and erased. The 8plane is mapped to some location on the screen. The variables X and Y indicate 9its lower left corner, W its width and H its height. All variables are 10read-only. 11*) 12 13IMPORT 14 Out := Console, C := oocC, X11 := oocX11, Xu := oocXutil, SYSTEM; 15 16 17CONST 18 erase* = 0; 19 draw* = 1; 20 (*sizeSet = MAX (SET)+1;*) 21 sizeSet = 32; (* in ooc SET is always 32 bit *) 22 23TYPE string = ARRAY 32 OF CHAR; 24 25VAR 26 X-, Y-, W-, H-: INTEGER; 27 28 display: X11.DisplayPtr; 29 window: X11.Window; 30 fg, bg: X11.GC; 31 32 initialized: BOOLEAN; (* first call to Open sets this to TRUE *) 33 image: X11.XImagePtr; 34 map: POINTER TO ARRAY OF ARRAY OF SET; 35 36 37 38PROCEDURE -aincludexlib "#include <X11/Xlib.h>"; 39PROCEDURE -aincludexutil "#include <X11/Xutil.h>"; 40PROCEDURE -aincludexresource "#include <X11/Xresource.h>"; 41 42 43PROCEDURE Error (msg: ARRAY OF CHAR); 44 BEGIN 45 Out.String ("Error: "); 46 Out.String (msg); 47 Out.Ln; 48 HALT (1) 49 END Error; 50 51PROCEDURE Clear*; 52(* Erases all pixels in the drawing plane. *) 53 VAR 54 x, y: INTEGER; 55 BEGIN 56 X11.XFillRectangle (display, window, bg, 0, 0, W+1, H+1); 57 FOR y := 0 TO SHORT (LEN (map^, 0))-1 DO 58 FOR x := 0 TO SHORT (LEN (map^, 1))-1 DO 59 map[y, x] := {} 60 END 61 END; 62 X11.XFlush (display) 63 END Clear; 64 65PROCEDURE Dot* (x, y, mode: INTEGER); 66(* Dot(x, y, m) draws or erases the pixel at the coordinates (x, y) relative to 67 the lower left corner of the plane. If m=draw the pixel is drawn, if m=erase 68 the pixel is erased. *) 69 VAR 70 dummy: C.int; 71 BEGIN 72 IF (x >= X) & (x < X+W) & (y >= Y) & (y < Y+H) THEN 73 dummy := image. f. putpixel(image, x, H-1-y, mode); 74 CASE mode OF 75 | draw: 76 X11.XDrawPoint (display, window, fg, x, H-1-y) 77 | erase: 78 X11.XDrawPoint (display, window, bg, x, H-1-y) 79 ELSE 80 END; 81 X11.XFlush (display); 82 END 83 END Dot; 84 85PROCEDURE IsDot* (x, y: INTEGER): BOOLEAN; 86(* IsDot(x, y) returns TRUE if the pixel at the coordinates (x, y) relative to 87 the lower left corner of the plane is drawn, otherwise it returns FALSE. *) 88 BEGIN 89 IF (x < X) OR (x >= X+W) OR (y < Y) OR (y >= Y+H) THEN 90 RETURN FALSE 91 ELSE 92 RETURN (image. f. getpixel (image, x, H-1-y) # erase) 93 END 94 END IsDot; 95 96PROCEDURE Key* (): CHAR; 97(* Reads the keyboard. If a key was pressed prior to invocation, its 98 character value is returned, otherwise the result is 0X. *) 99 CONST 100 sizeBuffer = 16; 101 VAR 102 event: X11.XEvent; 103 buffer: ARRAY sizeBuffer OF C.char; 104 keySym: X11.KeySym; 105 numChars: C.int; 106 nl : C.longint; 107 108 PROCEDURE Redraw (x0, y0, w0, h0: INTEGER); 109 BEGIN 110 (* clip width and height to size of initial window *) 111 IF (x0+w0 > W) THEN 112 w0 := W-x0 113 END; 114 IF (y0+h0 > H) THEN 115 h0 := H-y0 116 END; 117 IF (w0 > 0) & (h0 > 0) THEN 118 X11.XPutImage (display, window, fg, image, x0, y0, x0, y0, w0, h0) 119 END 120 END Redraw; 121 122 BEGIN 123 WHILE initialized & 124 (X11.XEventsQueued (display, X11.QueuedAfterReading) > 0) DO 125 X11.XNextEvent (display, event); 126 nl := 0; 127 IF (event. type = X11.KeyPress) THEN 128 numChars := Xu.XLookupString ( 129 (*event. xkey, buffer, sizeBuffer, keySym, NIL);*) 130 event, buffer, sizeBuffer, keySym, nl); 131 IF (numChars > 0) THEN 132 RETURN SYSTEM.VAL (CHAR, buffer[0]) 133 END 134 ELSIF (event. type = X11.Expose) THEN 135 Redraw (SHORT (event. xexpose. x), SHORT (event. xexpose. y), 136 SHORT (event. xexpose. width), SHORT (event. xexpose. height)) 137 END 138 END; 139 RETURN 0X 140 END Key; 141 142PROCEDURE Open*; 143(* Initializes the drawing plane. *) 144 VAR 145 screen: C.int; 146 parent: X11.Window; 147 bgColor: C.longint; 148 fgColor: C.longint; 149 gcValue: X11.XGCValues; 150 event: X11.XEvent; 151 x, y: INTEGER; 152 tmpstr: string; 153 scrn : C.int; 154 vis : X11.VisualPtr; 155 BEGIN 156 IF ~initialized THEN 157 initialized := TRUE; 158 159 tmpstr[0] := 0X; 160 (*display := X11.XOpenDisplay (NIL);*) 161 display := X11.XOpenDisplay(tmpstr); 162 (*display := X11.OpenDisplay (NIL);*) 163 IF (display = NIL) THEN 164 Error("Couldn't open display") 165 ELSE 166 screen := X11.XDefaultScreen(display); 167 X := 0; Y := 0; 168 W := SHORT (X11.XDisplayWidth (display, screen)); 169 H := SHORT (X11.XDisplayHeight(display, screen)); 170 (* adjust ratio W:H to 3:4 [for no paritcular reason] *) 171 IF (W > 3*H DIV 4) THEN 172 W := 3*H DIV 4 173 END; 174 parent := X11.XRootWindow(display, screen); 175 fgColor := X11.XBlackPixel(display, screen); 176 bgColor := X11.XWhitePixel(display, screen); 177 window := X11.XCreateSimpleWindow(display, parent, 0, 0, 178 W, H, 0, 0, bgColor); 179 X11.XStoreName(display, window, "XYplane"); 180 X11.XSelectInput(display, window, X11.KeyPressMask+X11.ExposureMask); 181 X11.XMapWindow(display, window); 182 X11.XFlush (display); 183 (*tmpint := W + ((*sizeSet*)32-1); 184 tmpint := tmpint DIV 32(*sizeSet*);*) 185 NEW (map, H, (W+(sizeSet-1)) DIV sizeSet); 186 (*NEW (map, H, tmpint);*) 187 FOR y := 0 TO SHORT (LEN (map^, 0))-1 DO 188 FOR x := 0 TO SHORT (LEN (map^, 1))-1 DO 189 map[y, x] := {} 190 END 191 END; 192 193 scrn := X11.XDefaultScreen(display); 194 vis := X11.XDefaultVisual(display, scrn); 195 image := X11.XCreateImage (display, 196 (*X11.XDefaultVisual (display, X11.XDefaultScreen (display)),*) 197 vis, 198 (*1, X11.XYBitmap, 0, SYSTEM.ADR (map^), W, H, sizeSet, 0);*) 199 1, X11.ZPixmap, 0, SYSTEM.VAL(C.address,SYSTEM.ADR(map^)), W, H, (*sizeSet*)32, 0); 200 201 (* wait until the window manager gives its ok to draw things *) 202 X11.XMaskEvent(display, X11.ExposureMask, event); 203 204 (* create graphic context to draw resp. erase a point *) 205 gcValue. foreground := fgColor; 206 gcValue. background := bgColor; 207 fg := X11.XCreateGC (display, parent, 208 X11.GCForeground+X11.GCBackground, gcValue); 209 gcValue. foreground := bgColor; 210 gcValue. background := fgColor; 211 bg := X11.XCreateGC (display, parent, 212 X11.GCForeground+X11.GCBackground, gcValue) 213 END 214 END 215 END Open; 216 217PROCEDURE Close*; 218 219 BEGIN 220 (* X11.XDestroyImage(image); 221 X11.XDestroyWindow(display, window);*) 222 X11.XCloseDisplay(display); 223 224 END Close; 225 226 227BEGIN 228 initialized := FALSE; 229 X := 0; Y := 0; W := 0; H := 0; 230 image := NIL; map := NIL 231END oocXYplane. 232