[wadalabfont-kit] / lisp / window.c  

View of /lisp/window.c

Parent Directory | Revision Log
Revision: 1.1 - (download) (as text) (annotate)
Thu Dec 28 08:54:18 2000 UTC (23 years, 11 months ago) by ktanaka
Branch point for: ktanaka, MAIN
Initial revision
#include <stdio.h>
#include <alloca.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <constdef.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <ctype.h>
#ifdef DEBUG
#define MAIN
#endif
#include <defvar.h>
#include <cmpdef.h>

static WORD init_window_f(),drawline_f(),redraw_f(),checkevent_f(),close_window_f();
static WORD fillpolygon_f(),drawlines_f(),loadpbm_f(),loadjis_f(),copybg_f();
static WORD getimage_f(),getpixel_f(),fillrectangle_f(),freeimage_f();

static struct code_inf init_window_info={0,0,0,0,init_window_f,"init_window "};
static struct code_inf drawline_info={0,0,0,0,drawline_f,"drawline "};
static struct code_inf redraw_info={0,0,0,0,redraw_f,"redraw "};
static struct code_inf checkevent_info={0,6,0,0,checkevent_f,"checkevent ButtonPress ButtonRelease button1 button2 button3 KeyPress "};
static struct code_inf close_window_info={0,0,0,0,close_window_f,"close_window "};
static struct code_inf fillpolygon_info={0,0,0,0,fillpolygon_f,"fillpolygon "};
static struct code_inf drawlines_info={0,0,0,0,drawlines_f,"drawlines "};
static struct code_inf loadpbm_info={0,0,0,0,loadpbm_f,"loadpbm "};
static struct code_inf loadjis_info={0,0,0,0,loadjis_f,"loadjis "};
static struct code_inf copybg_info={0,0,0,0,copybg_f,"copybg "};
static struct code_inf getpixel_info={0,0,0,0,getpixel_f,"getpixel "};
static struct code_inf getimage_info={0,0,0,0,getimage_f,"getimage "};
static struct code_inf freeimage_info={0,0,0,0,freeimage_f,"freeimage "};
static struct code_inf fillrectangle_info={0,0,0,0,fillrectangle_f,"fillrectangle "};
static struct code_inf *inf_array[]={
  &init_window_info,
  &drawline_info,
  &redraw_info,
  &checkevent_info,
  &close_window_info,
  &fillpolygon_info,
  &drawlines_info,
  &loadpbm_info,
  &loadjis_info,
  &copybg_info,
  &getpixel_info,
  &getimage_info,
  &freeimage_info,
  &fillrectangle_info,
  (struct code_inf *)0
};
WORD init_code_window(fp)
WORD *fp;
{
  WORD make_codepiece();

  return(make_codepiece(inf_array,fp));
}

/* init_window width, height */
static XWMHints xwmh={
  (InputHint|StateHint),
  False,
  NormalState,
  0,0,0,0,0,0,};
static Display *dpy;
static Window win;
static GC curgc,white_gc,gray_gc;
static int w_width,w_height;
static XEvent event;
static Pixmap save,background;
static XSetWindowAttributes xswa;
static Colormap cmap;
static unsigned long pad,fg,bg,bd,bw;
static char *av[1]={"utilisp"};

static char tilebitmap[]={0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55};
static Pixmap tilepixmap;
int flag;

static WORD init_window_f(na,fp)
WORD *fp;
{
  WORD a;
  XSizeHints xsh;
  XGCValues gcv;

  if(na<2)parerr();
  flag=1;
  if(na==3){
    a=ag(0);
    fp++;
    if(a!=nil)flag=0;
  }
  w_width=fixtoi(checkfix(a,ag(1)));
  w_height=fixtoi(checkfix(a,ag(0)));
  if((dpy=XOpenDisplay(NULL))==NULL){
    fprintf(stderr," can't open %s\n",XDisplayName(NULL));
    exit(1);
  }
  fg=BlackPixel(dpy,DefaultScreen(dpy));
  bg=WhitePixel(dpy,DefaultScreen(dpy));
  if(flag){
    xsh.flags=(PPosition|PSize);
    xsh.height=w_height+2;
    xsh.width=w_width+2;
    xsh.x=(DisplayWidth(dpy,DefaultScreen(dpy))-xsh.width)/2;
    xsh.y=(DisplayHeight(dpy,DefaultScreen(dpy))-xsh.height)/2;
    win=XCreateSimpleWindow(dpy,DefaultRootWindow(dpy),
			    xsh.x,xsh.y,xsh.width,xsh.height,bw,bd,bg);
    XSetStandardProperties(dpy,win,"utilisp","utilisp",None,av,1,&xsh);
    XSetWMHints(dpy,win,&xwmh);
    cmap=xswa.colormap=DefaultColormap(dpy,DefaultScreen(dpy));
    xswa.bit_gravity=CenterGravity;
    XChangeWindowAttributes(dpy,win,(CWColormap|CWBitGravity),&xswa);
  }
  else win=DefaultRootWindow(dpy);
  gcv.function=GXcopy;
  gcv.foreground=fg;
  gcv.fill_rule=WindingRule;
  curgc=XCreateGC(dpy,win,(GCFunction|GCForeground|GCFillRule),&gcv);
  gcv.function=GXcopy;
  gcv.foreground=bg;
  white_gc=XCreateGC(dpy,win,(GCFunction|GCForeground),&gcv);
  gcv.function=GXcopy;
  gcv.foreground=fg;
  gcv.fill_rule=WindingRule;
  gcv.fill_style=FillTiled;
  tilepixmap=XCreatePixmapFromBitmapData(dpy,win,tilebitmap,8,8,fg,bg,DefaultDepth(dpy,DefaultScreen(dpy)));
  gcv.tile=tilepixmap;
  gray_gc=XCreateGC(dpy,win,(GCFunction|GCForeground|GCFillRule|GCFillStyle|GCTile),&gcv);
  save=XCreatePixmap(dpy,DefaultRootWindow(dpy),w_width,w_height,DefaultDepth(dpy,DefaultScreen(dpy)));
  XFillRectangle(dpy,save,white_gc,0,0,w_width,w_height);
  if(flag){
    XSelectInput(dpy,win,ExposureMask|ButtonPressMask|ButtonReleaseMask|KeyPressMask);
    XCopyArea(dpy,save,win,curgc,0,0,w_width,w_height,0,0);
    XMapWindow(dpy,win);
  }
  return(nil);
}

static WORD drawline_f(na,fp)
WORD *fp;
{
  WORD a;
  int x0,y0,x1,y1;

  if(na!=4)parerr();
  x0=fixtoi(checkfix(a,ag(3)));
  y0=fixtoi(checkfix(a,ag(2)));
  x1=fixtoi(checkfix(a,ag(1)));
  y1=fixtoi(checkfix(a,ag(0)));
  XDrawLine(dpy,save,curgc,x0,y0,x1,y1);
  return(nil);
}

static WORD redraw_f(na,fp)
WORD *fp;
{
  WORD a;

  if(na!=0)parerr();
  if(flag)
    XCopyArea(dpy,save,win,curgc,0,0,w_width,w_height,0,0);
  return(nil);
}

static WORD checkevent_f(na,fp)
WORD *fp;
{
  WORD a;
  unsigned char c_buf;
  XComposeStatus status;
  KeySym last_key;
  
  if(na!=0)parerr();
  if(!flag)return(nil);
  while(1){
    XNextEvent(dpy,&event);
    if(event.type==Expose && event.xexpose.count==0){
      XCopyArea(dpy,save,win,curgc,0,0,w_width,w_height,0,0);
    }
    else if(event.type==KeyPress){
      XLookupString(&event, &c_buf, 1, &last_key, &status);
      l(0)=lit(5);
      l(1)=itofix(c_buf);
      return(allist(2,fp-2,nil));
    }
    else if(event.type==ButtonPress){
      if(event.xbutton.button==Button1){
	l(0)=lit(0);
	l(1)=lit(2);
	l(2)=itofix(event.xbutton.x);
	l(3)=itofix(event.xbutton.y);
	return(allist(4,fp-4,nil));
      }
      if(event.xbutton.button==Button2){
	l(0)=lit(0);
	l(1)=lit(3);
	l(2)=itofix(event.xbutton.x);
	l(3)=itofix(event.xbutton.y);
	return(allist(4,fp-4,nil));
      }
      if(event.xbutton.button==Button3){
	l(0)=lit(0);
	l(1)=lit(4);
	l(2)=itofix(event.xbutton.x);
	l(3)=itofix(event.xbutton.y);
	return(allist(4,fp-4,nil));
      }
    }
    else if(event.type==ButtonRelease){
      if(event.xbutton.button==Button1){
	l(0)=lit(1);
	l(1)=lit(2);
	l(2)=itofix(event.xbutton.x);
	l(3)=itofix(event.xbutton.y);
	return(allist(4,fp-4,nil));
      }
      if(event.xbutton.button==Button2){
	l(0)=lit(1);
	l(1)=lit(3);
	l(2)=itofix(event.xbutton.x);
	l(3)=itofix(event.xbutton.y);
	return(allist(4,fp-4,nil));
      }
      if(event.xbutton.button==Button3){
	l(0)=lit(1);
	l(1)=lit(4);
	l(2)=itofix(event.xbutton.x);
	l(3)=itofix(event.xbutton.y);
	return(allist(4,fp-4,nil));
      }
    }
  }
}

static WORD close_window_f(na,fp)
WORD *fp;
{
  if(na!=0)parerr();
  XCloseDisplay(dpy);
  return(nil);
}

static WORD fillpolygon_f(na,fp)
WORD *fp;
{
  int npoints,i;
  WORD a,b;
  XPoint *points;

  if(na!=1)parerr();
  for(npoints=0,a=ag(0);tag(a)==CONS;npoints++,a=cdr(a));
  points=(XPoint *)alloca(npoints*sizeof(XPoint));
  for(i=0,a=ag(0);tag(a)==CONS;i++,a=cdr(a)){
    points[i].x=fixtoi(checkfix(b,car(car(a))));
    points[i].y=fixtoi(checkfix(b,cdr(car(a))));
  }
  XFillPolygon(dpy,save,curgc,points,npoints,Complex,CoordModeOrigin);
  return(nil);
}

static WORD drawlines_f(na,fp)
WORD *fp;
{
  int npoints,i;
  WORD a,b;
  XPoint *points;

  if(na!=1)parerr();
  for(npoints=0,a=ag(0);tag(a)==CONS;npoints++,a=cdr(a));
  points=(XPoint *)alloca(npoints*sizeof(XPoint));
  for(i=0,a=ag(0);tag(a)==CONS;i++,a=cdr(a)){
    points[i].x=fixtoi(checkfix(b,car(car(a))));
    points[i].y=fixtoi(checkfix(b,cdr(car(a))));
  }
  XDrawLines(dpy,save,curgc,points,npoints,CoordModeOrigin);
  return(nil);
}
static unsigned char revtable[256];
static makerevbit()
{
  int i,j,k;

  for(i=0;i<256;i++){
    for(k=j=0;j<8;j++)
      if((i>>j)&1)k|=1<<(7-j);
    revtable[i]=k;
  }
}

static revbit(buf,width,height)
unsigned char *buf;
{
  int i,j;

  makerevbit();
  for(j=0;j<height;j++){
    if(j&1)
      for(i=0;i<width/8;i++)
	buf[i+j*width/8]= revtable[buf[i+j*width/8]]&0xaa;
    else
      for(i=0;i<width/8;i++)
	buf[i+j*width/8]= revtable[buf[i+j*width/8]]&0x55;
  }
}

static readtokens(fd,tokens,n)
  FILE *fd;
  char tokens[10][256];
{
  int i,j;
  char lastc,c;

  for(i=0;i<n;i++){
    for(j=0;j<256;j++){
      c=getc(fd);
      if(isspace(c)){
	tokens[i][j]=0;
	break;
      }
      tokens[i][j]=c;
    }
  }
}
static FILE *fileopen(filename,compressed)
char *filename;
{
  char buf[256];

  if(compressed){
    sprintf(buf,"zcat %s",filename);
    return(popen(buf,"r"));
  }
  else
    return(fopen(filename,"r"));
}

static fileclose(fd,compressed)
FILE *fd;
{
  if(compressed)
    pclose(fd);
  else
    fclose(fd);
}

static WORD loadpbm_f(na,fp)
WORD *fp;
{
  char tokens[10][256];
  int width,height,size,len,compressed;
  char strbuf[256];
  FILE *fd;
  unsigned char *filename,*buf;
  struct  stat stbuf;
  WORD a;

  if(na!=1)parerr();
  filename=stringcodes(checkstr(a,ag(0)));
  strcpy(strbuf,filename);
  len=strlen(strbuf);
  if(strbuf[len-2]=='.' && strbuf[len-1]=='Z')compressed=1;
  if(stat(strbuf,&stbuf)<0){
    strcat(strbuf,".Z");
    if(stat(strbuf,&stbuf)>=0){
      compressed=1;
    }
    else{
      fprintf(stderr,"stat rror\n");
      return(nil);
    }
  }
  if((fd=fileopen(strbuf,compressed))==NULL){
    fprintf(stderr,"file %s is not found\n",filename);
    return(nil);
  }
  readtokens(fd,tokens,3);
  if(strcmp(tokens[0],"P4")){
    fprintf(stderr,"Not a ppm file\n");
    exit(1);
  }
  width=atoi(tokens[1]);
  height=atoi(tokens[2]);
  size=width*height/8;
  buf=(unsigned char *)alloca(size);
  fread(buf,1,size,fd);
  fileclose(fd,compressed);
  revbit(buf,width,height);
  background=XCreatePixmapFromBitmapData(dpy,DefaultRootWindow(dpy),(char *)buf,width,height,fg,bg,DefaultDepth(dpy,DefaultScreen(dpy)));
  XCopyArea(dpy,background,save,curgc,0,0,width,height,0,0);
  return(nil);
}

#define JISFONT "/home/misa/kanji/jisfont/jis24"

static WORD loadjis_f(na,fp)
WORD *fp;
{
  FILE *fd;
  WORD a;
  int jiscode,offset;
  unsigned char buf[72],buf1[50*400];

  if(na!=1)parerr();
  if((fd=fopen(JISFONT,"r"))==NULL){
    fprintf(stderr,"Open Failed\n");
    exit(1);
  }
  jiscode=strtol(stringcodes(checkstr(a,ag(0))),NULL,16);
  offset=((jiscode/256)-0x21)*94+(jiscode%256)-0x21;
  fseek(fd,offset*72,0);
  fread(buf,1,72,fd);
  fclose(fd);
  extendbit(buf,buf1);
  background=XCreatePixmapFromBitmapData(dpy,DefaultRootWindow(dpy),(char *)buf1,400,400,fg,bg,DefaultDepth(dpy,DefaultScreen(dpy)));
  XCopyArea(dpy,background,save,curgc,0,0,400,400,0,0);
  return(nil);
}  

static extendbit(buf,buf1)
unsigned char *buf,*buf1;
{
  int i,j,k;

  bzero(buf1,50*400);
  for(j=0;j<24;j++)
    for(i=0;i<24;i++)
      if(buf[j*3+(i/8)]&(0x80>>(i&7))){
	for(k=0;k<16;k+=2){
	  buf1[(j*16+k+8)*50+(i*2+1)]=0xaa;
	  buf1[(j*16+k+9)*50+(i*2+1)]=0x55;
	  buf1[(j*16+k+8)*50+(i*2+2)]=0xaa;
	  buf1[(j*16+k+9)*50+(i*2+2)]=0x55;
	}
      }
}

static WORD copybg_f(na,fp)
WORD *fp;
{
  if(na!=0)parerr();
  XCopyArea(dpy,background,save,curgc,0,0,w_width,w_height,0,0);
  return(nil);
}  

static XImage* ximage;
static WORD getimage_f(na,fp)
WORD *fp;
{
  if(na!=0)parerr();
  ximage=XGetImage(dpy,save,0,0,w_width,w_height,-1,ZPixmap);
  return(nil);
}
static WORD freeimage_f(na,fp)
WORD *fp;
{
  if(na!=0)parerr();
  free(ximage->data);
  XFree(ximage);
  return nil;
}

static WORD getpixel_f(na,fp)
WORD *fp;
{
  WORD a;
  int x,y,r;

  if(na!=2)parerr();
  x=fixtoi(checkfix(a,ag(1)));
  y=fixtoi(checkfix(a,ag(0)));
  r=XGetPixel(ximage,x,y);
  return itofix(r);
}

static WORD fillrectangle_f(na,fp)
WORD *fp;
{
  WORD a;
  int x,y,w,h,col;

  if(na!=5)parerr();
  col=fixtoi(checkfix(a,ag(0)));
  h=fixtoi(checkfix(a,ag(1)));
  w=fixtoi(checkfix(a,ag(2)));
  y=fixtoi(checkfix(a,ag(3)));
  x=fixtoi(checkfix(a,ag(4)));
  if(col>1)
    XFillRectangle(dpy,save,curgc,x,y,w,h);
  else if(col==1)
    XFillRectangle(dpy,save,gray_gc,x,y,w,h);
  else
    XFillRectangle(dpy,save,white_gc,x,y,w,h);
  return(nil);
}


#ifdef DEBUG
main()
{
  WORD buf[20];

  buf[19]=itofix(100);
  buf[18]=itofix(100);
  buf[17]=itofix(100);
  init_window(2,&buf[17]);
  for(;;);
}


WORD make_codepiece(){}
#endif


ktanaka

Powered by ViewCVS 1.0-dev

ViewCVS and CVS Help