Skip to content

Commit 2d8e4ea

Browse files
committed
Added XWindows version, fixed a bug in UNIX version.
1 parent eade680 commit 2d8e4ea

File tree

3 files changed

+237
-6
lines changed

3 files changed

+237
-6
lines changed

unix/Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
CC=cc
2-
CCOPTS=
2+
CCOPTS=-Wall -Wpedantic
33

4-
all: mandelbrot
4+
all: mandelbrot xmandelbrot
55

66
mandelbrot: mandelbrot.c
77
$(CC) $(CCOPTS) -o mandelbrot mandelbrot.c -lcurses
8+
9+
xmandelbrot: xmandelbrot.c
10+
$(CC) $(CCOPTS) -o xmandelbrot xmandelbrot.c -lX11
11+
812
clean:
913
rm -f *.o
1014
rm -f mandelbrot
15+
rm -f xmandelbrot

unix/mandelbrot.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright 2025, Andrew C. Young <[email protected]>
44
* License: MIT
55
*
6+
* To compile: cc -o mandelbrot mandelbrot.c -lcurses
7+
*
68
* This program was written on a Macintosh Quadra 700 running A/UX 3.1.
79
* A/UX was Apple's first version of UNIX, based on both SYSV and BSD.
810
* A/UX 3.1 was released in 1994, and its default C compiler did not
@@ -80,7 +82,7 @@ void cleanup()
8082
void calculate()
8183
{
8284
int i, col, row, iteration;
83-
double width, height, x0, y0, x, y, x_scale, y_scale, xtemp;
85+
double width, height, x0, y0, x, y, xtemp;
8486

8587
width = (double)cols;
8688
height = (double)lines;
@@ -115,7 +117,6 @@ void display()
115117
{
116118
int i, col, row;
117119
int value;
118-
int color;
119120
char symbol;
120121

121122
/* Clear the screen */
@@ -155,7 +156,7 @@ double time_in_seconds()
155156
return t / 60.0;
156157
}
157158

158-
void main()
159+
int main()
159160
{
160161
double start, after_calc, after_display, calc_time, display_time;
161162

@@ -173,5 +174,5 @@ void main()
173174

174175
printf("\nCalculation Time: %0.3f secs, Display Time: %0.3f secs, Total Time: %0.3f secs\n", calc_time, display_time, calc_time + display_time);
175176

176-
exit(0);
177+
return 0;
177178
}

unix/xmandelbrot.c

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
/*
2+
* Mandelbrot for X11.
3+
* Copyright 2025, Andrew C. Young <[email protected]>
4+
* License: MIT
5+
*
6+
* To compile: cc -o xmandelbrot xmandelbrot.c -lX11
7+
*/
8+
9+
#include <stdio.h>
10+
#include <stdlib.h>
11+
#include <string.h>
12+
#include <X11/Xlib.h>
13+
#include <X11/Xutil.h>
14+
#include <sys/types.h>
15+
#include <sys/times.h>
16+
17+
#define MAX_ITERATIONS 16
18+
19+
char *title = "xmandelbrot";
20+
21+
void get_window_size(display, window, height, width)
22+
Display *display;
23+
Window window;
24+
unsigned int *height;
25+
unsigned int *width;
26+
{
27+
Window root;
28+
int x, y;
29+
unsigned int border, depth;
30+
XGetGeometry(display, window, &root, &x, &y, width, height, &border, &depth);
31+
}
32+
33+
unsigned long lookup_color(display, colormap, color_name, color)
34+
Display *display;
35+
Colormap colormap;
36+
char *color_name;
37+
XColor *color;
38+
{
39+
XColor exact, screen;
40+
if (!XAllocNamedColor(display, colormap, color_name, &exact, &screen))
41+
{
42+
printf("Color Not Found: %s\n", color_name);
43+
return 0;
44+
}
45+
return screen.pixel;
46+
}
47+
48+
double time_in_seconds()
49+
{
50+
struct tms buffer;
51+
clock_t t = times(&buffer);
52+
return t / 60.0;
53+
}
54+
55+
void calculate(display, window, gc, palette, palette_size)
56+
Display *display;
57+
Window window;
58+
GC gc;
59+
unsigned long int *palette;
60+
size_t palette_size;
61+
{
62+
unsigned int i, col, row, iteration;
63+
double width, height, x0, y0, x, y, xtemp;
64+
unsigned int lines, cols;
65+
unsigned long color;
66+
double start, finish;
67+
68+
start = time_in_seconds();
69+
70+
get_window_size(display, window, &lines, &cols);
71+
height = (double)lines;
72+
width = (double)cols;
73+
74+
XClearWindow(display, window);
75+
76+
for (row = 0; row < lines; row++)
77+
{
78+
// printf("Row: %u\n", row);
79+
y0 = (row * 2.1 / height) - 1;
80+
for (col = 0; col < cols; col++)
81+
{
82+
x0 = (col * 3.5 / width) - 2.5;
83+
x = 0.0;
84+
y = 0.0;
85+
iteration = 0;
86+
while ( ((x*x) + (y*y) <= 4) && (iteration < MAX_ITERATIONS))
87+
{
88+
xtemp = (x*x) - (y*y) + x0;
89+
y = (2*x*y) + y0;
90+
x = xtemp;
91+
iteration++;
92+
}
93+
94+
i = (iteration % palette_size);
95+
color = palette[i];
96+
97+
XSetForeground(display, gc, color);
98+
XDrawPoint(display, window, gc, col, row);
99+
}
100+
}
101+
102+
finish = time_in_seconds();
103+
printf("Height: %u, Width: %u, Time: %0.3f Seconds\n", lines, cols, (finish-start));
104+
105+
}
106+
107+
int main(argc,argv)
108+
int argc;
109+
char **argv;
110+
{
111+
Display *display;
112+
Window window;
113+
114+
GC gc;
115+
116+
XEvent event;
117+
KeySym key;
118+
119+
XSizeHints hint;
120+
121+
int screen;
122+
unsigned long fg, bg;
123+
int i;
124+
char text[10];
125+
int done;
126+
127+
Colormap colormap;
128+
129+
unsigned long palette[16];
130+
char *color_names[16];
131+
color_names[0] = "Black";
132+
color_names[1] = "DarkBlue";
133+
color_names[2] = "DarkGreen";
134+
color_names[3] = "DarkCyan";
135+
color_names[4] = "DarkRed";
136+
color_names[5] = "DarkMagenta";
137+
color_names[6] = "Brown";
138+
color_names[7] = "LightGray";
139+
color_names[8] = "Gray";
140+
color_names[9] = "Blue";
141+
color_names[10] = "Green";
142+
color_names[11] = "Cyan";
143+
color_names[12] = "Red";
144+
color_names[13] = "Magenta";
145+
color_names[14] = "Yellow";
146+
color_names[15] = "White";
147+
148+
/* setup display/screen */
149+
display = XOpenDisplay("");
150+
151+
screen = DefaultScreen(display);
152+
153+
colormap = DefaultColormap(display, screen);
154+
155+
for (i = 0; i < 16; i++)
156+
{
157+
palette[i] = lookup_color(display, colormap, color_names[i]);
158+
}
159+
160+
/* drawing contexts for an window */
161+
bg = BlackPixel(display, screen);
162+
fg = WhitePixel(display, screen);
163+
hint.x = 100;
164+
hint.y = 100;
165+
hint.width = 500;
166+
hint.height = 300;
167+
hint.flags = PPosition|PSize;
168+
169+
/* create window */
170+
window = XCreateSimpleWindow(display, DefaultRootWindow(display),
171+
hint.x, hint.y,
172+
hint.width, hint.height,
173+
5, fg, bg);
174+
175+
/* window manager properties (yes, use of StdProp is obsolete) */
176+
XSetStandardProperties(display, window, title, title,
177+
None, argv, argc, &hint);
178+
179+
/* graphics context */
180+
gc = XCreateGC(display, window, 0, 0);
181+
XSetBackground(display, gc, bg);
182+
XSetForeground(display, gc, fg);
183+
184+
/* allow receiving mouse events */
185+
XSelectInput(display,window,
186+
ButtonPressMask|KeyPressMask|ExposureMask);
187+
188+
/* show up window */
189+
XMapRaised(display, window);
190+
191+
/* event loop */
192+
done = 0;
193+
while(done==0){
194+
195+
/* fetch event */
196+
XNextEvent(display, &event);
197+
198+
switch(event.type){
199+
case Expose:
200+
/* Window was showed. */
201+
if(event.xexpose.count==0)
202+
calculate(display, window, gc, palette, 16);
203+
break;
204+
case MappingNotify:
205+
/* Modifier key was up/down. */
206+
XRefreshKeyboardMapping(&event.xmapping);
207+
break;
208+
case ButtonPress:
209+
/* Mouse button was pressed. */
210+
break;
211+
case KeyPress:
212+
/* Key input. */
213+
i = XLookupString(&event.xkey, text, 10, &key, 0);
214+
if(i==1 && text[0]=='q') done = 1;
215+
break;
216+
}
217+
}
218+
219+
/* finalization */
220+
XFreeGC(display,gc);
221+
XDestroyWindow(display, window);
222+
XCloseDisplay(display);
223+
224+
exit(0);
225+
}

0 commit comments

Comments
 (0)