/* The original file is at Texts/text-92/glib.c, Texts/text-99/Joho/glib.c */
/*  
    どうやって, 文字を書くの? とか どうやって マウスの event を取り出すの?
    とか疑問におもったときは, 
    参考文献
    (1) http://www.wakhok.ac.jp/JJ/JJ.html   X window 概論
    (2) Xlib のマニュアル.  man XDrawLine, 等

*/
/* gcc -DTEST -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 glib.c */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>

/* prototypes */
void gopen();
void gclose();
void gFlush();
void moveto(int x,int y);
void lineto(int x,int y);
void setpixel(int x,int y);
void glib_window(double xmin,double ymin, double xmax, double ymax);
void glib_line(double x0,double y0, double x1, double y1);
void glib_putpixel(double x0,double y0);
void glib_flush();
void glib_clear();
void glib_color(int c);
void glib_set_frame_no(int n);
void glib_init_frame_no(int n);
void glib_close();
void glib_cgif_pen_up();

#ifdef TEST
int main() {
  int k;
  gopen();
  for (k=10; k<=500; k++) {
    setpixel(k,k);
  }
  moveto(100,50);
  lineto(400,50);
  for (k=10; k<=300; k += 20) {
    lineto(k,2*k);
  }
  gFlush();
  gclose();
  getchar();
  return(0);
}
  
#endif


double Glib_xmin, Glib_xmax, Glib_ymin, Glib_ymax;

/* -------------------- main code of glib.c ---------------- */
#define XSIZE 600
#define YSIZE 600

/* global variables */
Display *glib_d;
Window glib_w;
GC glib_gc;
XSetWindowAttributes glib_a;

static int glib_x = 0;
static int glib_y = 0;

/* functions exported */
void gopen() {
  glib_d = XOpenDisplay(NULL);
  glib_w = XCreateSimpleWindow(glib_d,RootWindow(glib_d,0),0,0,
			  XSIZE,YSIZE,2,0,WhitePixel(glib_d,0));
  /*  xsize, ysize, border color, border, background */
  glib_a.override_redirect = 1;
  XChangeWindowAttributes(glib_d,glib_w,CWOverrideRedirect, &glib_a); 
  XMapWindow(glib_d,glib_w);
  glib_gc = XCreateGC(glib_d,glib_w,0,0);
  /*                0 : default of mask, 0 : default XGCvalues * */

  /* intialize line attributes */
  XSetLineAttributes(glib_d,glib_gc,1,LineSolid,CapButt,JoinMiter);
}

void gclose() {
  XFlush(glib_d);
}

void gFlush() {
  XFlush(glib_d);
}


void moveto(x,y)
int x,y;
{
  glib_x = x;
  glib_y = y;
}

void lineto(x,y)
int x,y;
{
  XDrawLine(glib_d,glib_w,glib_gc,glib_x,glib_y,x,y);
  glib_x = x; glib_y = y;
}

void setpixel(x,y)
int x,y;
{
  XDrawPoint(glib_d,glib_w,glib_gc,x,y);
}


void glib_window(double xmin,double ymin, double xmax, double ymax) {
  Glib_xmin = xmin;
  Glib_ymin = ymin;
  Glib_xmax = xmax;
  Glib_ymax = ymax; 
  gopen();
}

#define P(x)  (((x-Glib_xmin)/(Glib_xmax-Glib_xmin))*(double)XSIZE)
#define Q(y)  ((double)YSIZE-((y-Glib_ymin)/(Glib_ymax-Glib_ymin))*(double)YSIZE)
void glib_line(double x0,double y0, double x1, double y1) {
  int p0,q0,p1,q1;
  p0 = (int) P(x0);
  q0 = (int) Q(y0);
  p1 = (int) P(x1);
  q1 = (int) Q(y1);
  moveto(p0,q0);
  lineto(p1,q1);
}

void glib_putpixel(double x0,double y0) {
  int p0,q0;
  p0 = (int) P(x0);
  q0 = (int) Q(y0);
  setpixel(p0,q0);  
}

void glib_flush() {
  gFlush();
}


void glib_clear() {
  XClearArea(glib_d,glib_w,0,0,XSIZE,YSIZE,False);
}

void glib_color(int c) {
  /* not implemented */
}

void glib_set_frame_no(int n) {
  /* not implemented */
}

void glib_init_frame_no(int n) {
  /* not implemented */
}

void glib_close() {
  gclose();
}

void glib_cgif_pen_up() {
  /* do nothing */
}
