/* SWILL Mandelbrot example */

#include "swill.h"
#include "gd.h"

/* Structure containing plot data */
typedef struct {
  double  Xmin;
  double  Xmax;
  double  Ymin;
  double  Ymax;
  int     Tolerance;
  gdImagePtr  im;
} MandelData;

/* Handler function that draws an image */

void mandel(FILE *f, MandelData *m) {
  double scalingx;
  double scalingy;
  double zr,zi,ztr,zti,cr,ci;
  double cscale;
  int    i,j,n;

  scalingx = (m->Xmax-m->Xmin)/m->im->sx;
  scalingy = (m->Ymax-m->Ymin)/m->im->sy;
  cscale = 256.0/m->Tolerance;
  for (i = 0; i < m->im->sx; i++) {
    for (j = 0; j < m->im->sy; j++) {
      zr = scalingx*i + m->Xmin;
      zi = scalingy*j + m->Ymin;
      cr = zr;
      ci = zi;
      n = 0;
      while (n < m->Tolerance) {
	ztr = zr*zr-zi*zi + cr;
	zti = 2*zr*zi + ci;
	zr = ztr;
	zi = zti;
	if (ztr*ztr + zti*zti > 20) break;
	n = n + 1;
      }
      if (n >= m->Tolerance) gdImageSetPixel(m->im,i,j,0);
      else gdImageSetPixel(m->im,i,j,(int) (n*cscale));
    }
  }
  gdImagePng(m->im,f);
}

/* Handler that produces HTML form for changing values */

void mandelpage(FILE *f, MandelData *m) {
  double xmin, xmax, ymin, ymax;
  double xshift,yshift;
  int tol;
  fprintf(f,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
  if (!swill_getargs("d(xmin)d(xmax)d(ymin)d(ymax)i(tol)", &xmin,&xmax,&ymin,&ymax,&tol)) {
    fprintf(f,"<b>Missing form variable!</b>\n");
  } else {
    m->Xmin = xmin;
    m->Xmax = xmax;
    m->Ymin = ymin;
    m->Ymax = ymax;
    m->Tolerance = tol;
  }

  /* Link to image picture */
  fprintf(f,"<p><center><img src=\"mandel.png\"></center>\n");

  xshift = (m->Xmax - m->Xmin)/4;
  yshift = (m->Ymax - m->Ymin)/4;

  fprintf(f,"<center><p>\n");
  fprintf(f,"<a href=\"");
  swill_printurl(f,"mandelpage.html","d(xmin)d(xmax)d(ymin)d(ymax)i(tol)",
		 m->Xmin-xshift,m->Xmax-xshift,m->Ymin,m->Ymax,m->Tolerance);
  fprintf(f,"\">[ Left ]</a>");

  fprintf(f,"<a href=\"");
  swill_printurl(f,"mandelpage.html","d(xmin)d(xmax)d(ymin)d(ymax)i(tol)",
		 m->Xmin+xshift,m->Xmax+xshift,m->Ymin,m->Ymax,m->Tolerance);
  fprintf(f,"\">[ Right ]</a>");

  fprintf(f,"<a href=\"");
  swill_printurl(f,"mandelpage.html","d(xmin)d(xmax)d(ymin)d(ymax)i(tol)",
		 m->Xmin,m->Xmax,m->Ymin-yshift,m->Ymax-yshift,m->Tolerance);
  fprintf(f,"\">[ Up ]</a>");

  fprintf(f,"<a href=\"");
  swill_printurl(f,"mandelpage.html","d(xmin)d(xmax)d(ymin)d(ymax)i(tol)",
		 m->Xmin,m->Xmax,m->Ymin+yshift,m->Ymax+yshift,m->Tolerance);
  fprintf(f,"\">[ Down ]</a>");

  fprintf(f,"<a href=\"");
  swill_printurl(f,"mandelpage.html","d(xmin)d(xmax)d(ymin)d(ymax)i(tol)",
		 m->Xmin+xshift,m->Xmax-xshift,m->Ymin+yshift,m->Ymax-yshift,m->Tolerance);
  fprintf(f,"\">[ Zoom in ]</a>");

  fprintf(f,"<a href=\"");
  swill_printurl(f,"mandelpage.html","d(xmin)d(xmax)d(ymin)d(ymax)i(tol)",
		 m->Xmin-xshift,m->Xmax+xshift,m->Ymin-yshift,m->Ymax+yshift,m->Tolerance);
  fprintf(f,"\">[ Zoom out ]</a>");
  
  fprintf(f,"</center>\n");

  /* Form to change values manually */
  fprintf(f,"<p><form action=\"mandelpage.html\" method=GET>\n");
  fprintf(f,"Xmin : <input type=text name=xmin width=10 value=\"%g\"></input><br>\n", m->Xmin);
  fprintf(f,"Xmax : <input type=text name=xmax width=10 value=\"%g\"></input><br>\n", m->Xmax);
  fprintf(f,"Ymin : <input type=text name=ymin width=10 value=\"%g\"></input><br>\n", m->Ymin);
  fprintf(f,"Ymax : <input type=text name=ymax width=10 value=\"%g\"></input><br>\n", m->Ymax);
  fprintf(f,"Tolerance : <input type=text name=tol width=10 value=\"%d\"></input><br>\n", m->Tolerance);
  fprintf(f,"<input type=submit value=\"Submit\"></input>\n");
  fprintf(f,"</form>\n");
  fprintf(f,"</body></html>\n");
}

int main(int argc, char **argv) {
  int i;
  MandelData *m;

  printf("Mandelbrot set viewer\n");
  
  m = (MandelData *) malloc(sizeof(MandelData));
  m->Xmin = -2.0;
  m->Xmax = 2.0;
  m->Ymin = -2.0;
  m->Ymax = 2.0;
  m->Tolerance = 50;
  m->im = gdImageCreate(400,400);

  /* Allocate colormap */
  for (i = 0; i < 256; i++) {
    gdImageColorAllocate(m->im,i/2,i,i);
  }
  
  if (swill_init(8080)) {
    printf("Server listening on port 8080\n");
  } else {
    printf("Couldn't start server!\n");
    exit(1);
  }
  swill_handle("mandel.png", mandel, m);
  swill_handle("mandelpage.html", mandelpage,m);
  swill_handle("index.html",mandelpage,m);
  while (1) {
    swill_serve();
  }

}






syntax highlighted by Code2HTML, v. 0.9.1