From 58b60d1455a6670cbfb1572257460065fe7e6207 Mon Sep 17 00:00:00 2001 From: Ian C Date: Wed, 13 May 2020 20:25:51 +0000 Subject: Builds (just) and runs. --- Xbit.c | 1877 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1877 insertions(+) create mode 100644 Xbit.c (limited to 'Xbit.c') diff --git a/Xbit.c b/Xbit.c new file mode 100644 index 0000000..83fdb3c --- /dev/null +++ b/Xbit.c @@ -0,0 +1,1877 @@ +/* + + Xbit - Simple xlib interface + + Copyright (C) 2005 Ian Cowburn (ianc@noddybox.demon.co.uk) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------- + + This is a bit messy as it based on very old K&R code. + +*/ +static char rcs_id[]="$Id: Xbit.c 11 2006-05-02 19:02:49Z ianc $"; + +#include +#include +#include +#include + +#include + +/* #include */ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "Xbit.h" + +#include "icon.bmp" + +#define WARN(x) fprintf(stderr,"%s(%d) : Warning:%s\n",__FILE__,__LINE__,x); +#define WARN1(x,y) fprintf(stderr,"%s(%d) : Warning:%s %s\n",__FILE__,__LINE__,x,y); + + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) + + +/* GLOBALS +*/ + +#define MAXPM 256 + +typedef struct WEntry +{ + Window w; + Pixmap pm[MAXPM]; + int used_MIT_SHM; + XShmSegmentInfo + shm_info; + int pmi; + int buffer; + int use_pm; + int multi; + int multino; + ulong multicls; + GC gc; + int ox; + int oy; + int ww; + int wh; + int pw; + int ph; + int func; + int lastuserfunc; + ulong lastfg; + int spline_thresh; + struct WEntry *next; +} WEntry; + + +static WEntry *whead=NULL; +static WEntry *wtail=NULL; + +static WEntry *current=NULL; + +static WEntry *stack[128]; +static int sttop; + +static Display *display=NULL; +static XVisualInfo vinfo; +static int screen; + +static int use_shm=True; + +static ulong xb_black; +static ulong xb_white; + +/* Buffer for Xprintf() and XIprintf() +*/ +static char prbuf[1024]; + +/* Definitions for XImage 8x8 charset +*/ +#include "fontset.h" + + +/* Put globals +*/ +static int no_plots; +static XPoint points[MAX_PUTPLOTS]; + + +/* Set write mode +*/ +#define WM(c) do {if ((c)!=current->func) { \ + XSetFunction(display,current->gc,c); \ + current->func=c; } } while(0) + + +/* Set foreground funcrion +*/ +#define FG(c) do {if ((c)!=current->lastfg) { \ + XSetForeground(display,current->gc,c); \ + current->lastfg=c; } } while(0) + + +/* Stack current windows +*/ +#define PUSHW do {stack[sttop++]=current;} while(0) +#define POPW do {current=stack[--sttop];} while(0) + + +/* ------------- FUNCTIONS ------------- */ + +static void CreateWEntry(Window w, GC g, int ww, int wh) +{ + WEntry *new; + + if (!(new=malloc(sizeof(WEntry)))) + { + fprintf(stderr,"%s(%d) : FATAL:%s\n",__FILE__,__LINE__, + "Couldn't malloc() WEntry"); + exit(1); + } + + if (!whead) + { + whead=new; + wtail=new; + } + else + { + wtail->next=new; + wtail=new; + } + + new->next=NULL; + + new->w=w; + new->gc=g; + + new->pm[0]=0; + new->pm[1]=0; + new->pmi=0; + new->buffer=True; + new->use_pm=True; + new->multi=False; + new->ox=0; + new->oy=0; + new->ww=ww; + new->wh=wh; + new->pw=0; + new->ph=0; + new->func=GXcopy; + new->lastuserfunc=GXcopy; + new->lastfg=-1; + new->spline_thresh=1; + new->used_MIT_SHM=False; +} + + +XImage *CreateXImage(void) +{ + XImage *img; + char *p; + + if (!use_shm) + { + switch(vinfo.depth) + { + case 8: + p=malloc(current->pw*current->ph*1); + break; + case 16: + p=malloc(current->pw*current->ph*2); + break; + default: + p=malloc(current->pw*current->ph*4); + break; + } + + if (!p) + { + fprintf(stderr,"%s(%d) : FATAL:%s\n",__FILE__,__LINE__, + "Couldn't malloc() XImage data"); + exit(1); + } + + img=XCreateImage + (display, + vinfo.visual, + vinfo.depth, /* Image depth */ + ZPixmap, /* Image format */ + 0, /* Offset */ + p, /* Data */ + current->pw, /* Width */ + current->ph, /* Height */ + 8, /* Bitmap pad */ + 0); + } + else + { + img=XShmCreateImage(display, + vinfo.visual, + vinfo.depth, + ZPixmap, + NULL, + &(current->shm_info), + current->pw, + current->ph); + + if (!img) + return(NULL); + + current->used_MIT_SHM=True; + + /* Get shared memory for image + */ + current->shm_info.shmid=shmget(IPC_PRIVATE, + img->bytes_per_line*img->height, + IPC_CREAT|0777); + + if (current->shm_info.shmid<0) + { + WARN("Couldn't get MITSHM mem"); + exit(1); + } + + current->shm_info.shmaddr=shmat(current->shm_info.shmid,0,0); + img->data=current->shm_info.shmaddr; + + current->shm_info.readOnly=False; + + /* Try and attached shared memory + */ + if (!XShmAttach(display,&(current->shm_info))) + { + WARN("Failed to attach MITSHM block"); + exit(1); + } + + XSync(display,False); + } + + ClsXImage(img); + return img; +} + + +void ClsXImage(XImage *img) +{ + memset(img->data,0,img->bytes_per_line*img->height); +} + + +void DestroyXImage(XImage *img) +{ + if (current->used_MIT_SHM) + { + XShmDetach(display,&(current->shm_info)); + + if (current->shm_info.shmaddr) + shmdt(current->shm_info.shmaddr); + + if (current->shm_info.shmid>=0) + shmctl(current->shm_info.shmid,IPC_RMID,0); + + current->used_MIT_SHM=False; + } + + XDestroyImage(img); + XSync(display,False); +} + + +void SetCurrentWin(Window w) +{ + WEntry *l; + + l=whead; + + while(l) + { + if (l->w==w) + { + current=l; + return; + } + + l=l->next; + } + + WARN("Asked for non-existant window"); +} + + +int GetVisualDepth(void) +{ + return vinfo.depth; +} + + +Window OpenWin (int argc, + char **argv, + char *title, + int wx, int wy, int ww, int wh, + int pw, int ph, + unsigned long ev, + XSizeHints *hints, + ulong *black, ulong *white) +{ + Window window; + GC gc; + char *display_name=NULL; + Pixmap icon_pixmap; + int i,j,k; + + if (!display) + { + if ((display=XOpenDisplay(display_name))==NULL) + { + fprintf(stderr,"%s: can't connect to %s\n", + argv[0], XDisplayName(display_name)); + exit(-1); + } + + /* Try and find shared memory extension + */ + use_shm=XQueryExtension(display,"MIT-SHM",&i,&j,&k); + + /* Find a nice 8-bit visual for us to use... + */ + if (!XMatchVisualInfo(display,DefaultScreen(display),8, + PseudoColor,&vinfo)) + if (!XMatchVisualInfo(display,DefaultScreen(display),16, + TrueColor,&vinfo)) + if (!XMatchVisualInfo(display,DefaultScreen(display),24, + TrueColor,&vinfo)) + if (!XMatchVisualInfo(display,DefaultScreen(display),32, + TrueColor,&vinfo)) + { + WARN("no visual found!\n"); + exit(1); + } + } + + screen=DefaultScreen(display); + + xb_black=BlackPixel(display,screen); + xb_white=WhitePixel(display,screen); + *black=xb_black; + *white=xb_white; + + window=XCreateWindow(display, + RootWindow(display,screen), + wx,wy,ww,wh,1, + vinfo.depth, + InputOutput, + vinfo.visual, + 0,NULL); + + icon_pixmap=XCreateBitmapFromData( + display, + window, + icon_bits, + icon_width,icon_height); + + XSetStandardProperties( + display, + window, + title, + title, + icon_pixmap, + argv,argc, + hints); + + XSelectInput (display,window,ev); + + gc=XCreateGC(display,window,0,NULL); + + XSetForeground(display,gc,*black); + XSetBackground(display,gc,*white); + XSetPlaneMask(display,gc,AllPlanes); + XSetGraphicsExposures(display,gc,False); + + XMapWindow (display,window); + + CreateWEntry(window,gc,ww,wh); + SetCurrentWin(window); + + Resize(pw,ph); + + return window; +} + + +Window OpenRootWin (ulong *black,ulong *white,int *w,int *h,int pw,int ph) +{ + Window window; + GC gc; + char *display_name=NULL; + int i,j,k; + + if (!display) + { + int depth; + + if ((display=XOpenDisplay(display_name))==NULL) + { + fprintf(stderr,"can't connect to %s\n",XDisplayName(display_name)); + exit(-1); + } + + screen=DefaultScreen(display); + + depth=DefaultDepth(display,screen); + + /* Try and find shared memory extension + */ + use_shm=XQueryExtension(display,"MIT-SHM",&i,&j,&k); + + /* Find a visual for us to use... + */ + if (!XMatchVisualInfo(display,DefaultScreen(display),depth, + depth==8 ? PseudoColor:TrueColor,&vinfo)) + { + WARN("no visual to match the root window!"); + exit(1); + } + } + + xb_black=BlackPixel(display,screen); + xb_white=WhitePixel(display,screen); + *black=xb_black; + *white=xb_white; + + window=RootWindow(display,screen); + + gc=XCreateGC(display,window,0,NULL); + + XSetForeground(display,gc,*black); + XSetBackground(display,gc,*white); + XSetPlaneMask(display,gc,AllPlanes); + + XMapWindow (display,window); + + *w=DisplayWidth(display,screen); + *h=DisplayHeight(display,screen); + + CreateWEntry(window,gc,*w,*h); + SetCurrentWin(window); + + Resize(pw,ph); + + return window; +} + + +XFontStruct *XUseFont(const char *n) +{ + XFontStruct *ft; + + if (ft=XLoadQueryFont(display,n)) + XSetFont(display,current->gc,ft->fid); + else + WARN1("couldn't load font:",n); + + return ft; +} + + +void XUseCursor(const char *bm, const char *mask, XColor fg, XColor bg) +{ + Pixmap b,m; + Cursor curs; + int bmw,bmh,bmx,bmy; + int maskw,maskh,maskx,masky; + + if (XReadBitmapFile(display,current->w,bm,&bmw,&bmh,&b,&bmx,&bmy) + ==BitmapOpenFailed) + { + WARN1("Couldn't read in cursor file:",bm); + return; + } + + if (XReadBitmapFile(display,current->w,mask,&maskw,&maskh,&m,&maskx,&masky) + ==BitmapOpenFailed) + { + WARN1("Couldn't read in mask file:",bm); + return; + } + + curs=XCreatePixmapCursor(display,b,m,&fg,&bg,bmx,bmy); + + XDefineCursor(display,current->w,curs); + + XFreePixmap(display,b); + XFreePixmap(display,m); +} + + +void LoadBitmap(const char *fn,int x,int y, int resize) +{ + Pixmap bm; + int w,h,hx,hy; + int cw,ch; + + if (!current->use_pm) + { + WARN("Need pixmaps to load in bitmap"); + } + + if (XReadBitmapFile(display,current->w,fn,&w,&h,&bm,&hx,&hy) + ==BitmapOpenFailed) + { + WARN1("Couldn't read in bitmap file:",fn); + return; + } + + if ((w!=current->pw)||(h!=current->ph)) + { + if (resize) + { + Resize(w+x,h+y); + cw=w; + ch=h; + } + else + { + cw=current->pw-x; + ch=current->ph-y; + } + } + + XCopyPlane(display,bm,current->pm[current->pmi], + current->gc,0,0,cw,ch,x,y,1L); + + XFreePixmap(display,bm); +} + + +Pixmap GetBitmap(const char *fn, int *w, int *h, int *hx, int *hy) +{ + Pixmap bm,ret; + + if (XReadBitmapFile(display,current->w,fn,w,h,&bm,hx,hy) + ==BitmapOpenFailed) + { + WARN1("Couldn't read in bitmap file:",fn); + return(0); + } + + ret=XCreatePixmap(display,current->w,*w,*h,vinfo.depth); + + XCopyPlane(display,bm,ret,current->gc,0,0,*w,*h,0,0,1L); + + XFreePixmap(display,bm); + + return ret; +} + + +void DrawXImage(XImage *img) +{ + if (use_shm) + XShmPutImage (display, + current->pm[0], + current->gc, + img, + 0,0, + 0,0, + current->pw,current->ph, + False); + else + XPutImage (display, + current->pm[0], + current->gc, + img, + 0,0, + 0,0, + current->pw,current->ph); +} + + +void Resize(int w,int h) +{ + int f; + + if (www) + w=current->ww; + + if (hwh) + h=current->wh; + + current->pw=w; + current->ph=h; + + if (!current->use_pm) + return; + + if (current->multi) + { + WM(GXcopy); + FG(current->multicls); + for(f=0;fmultino;f++) + { + XFreePixmap(display,current->pm[f]); + current->pm[f]=XCreatePixmap(display,current->w,w,h,vinfo.depth); + XFillRectangle(display,current->pm[f], + current->gc,0,0,current->pw,current->ph); + } + WM(current->lastuserfunc); + return; + } + + if (current->pm[0]) + { + XFreePixmap(display,current->pm[0]); + + if (current->buffer) + XFreePixmap(display,current->pm[1]); + } + + current->pmi=0; + + current->pm[0]=XCreatePixmap(display,current->w,w,h,vinfo.depth); + + if (current->buffer) + current->pm[1]=XCreatePixmap(display,current->w,w,h,vinfo.depth); +} + + +void Redraw(int x,int y) +{ + if ((x+current->ww)>current->pw) + x=current->pw-current->ww; + + if ((y+current->wh)>current->ph) + y=current->ph-current->wh; + + current->ox=x; + current->oy=y; + + if (!current->use_pm) + { + XSync(display,False); + return; + } + + WM(GXcopy); + + if (current->buffer) + { + XCopyArea(display,current->pm[current->pmi^1],current->w, + current->gc,x,y,current->ww,current->wh,0,0); + XSync(display,False); + } + else + { + XCopyArea(display,current->pm[current->pmi],current->w, + current->gc,x,y,current->ww,current->wh,0,0); + XSync(display,False); + } + + WM(current->lastuserfunc); +} + + +Pixmap GetCurrentPixmap(void) + +{ + if (!current->use_pm) + return(0); + + return current->pm[current->pmi]; +} + +GC GetCurrentGC(void) + +{ + return current->gc; +} + + +void DisableDoubleBuffer(void) + +{ + current->pmi=0; + XFreePixmap(display,current->pm[1]); + current->buffer=False; +} + + +void DisablePixmap(void) + +{ + current->pmi=0; + + if (current->use_pm) + XFreePixmap(display,current->pm[0]); + + if (current->buffer) + XFreePixmap(display,current->pm[1]); + + current->buffer=False; + current->use_pm=False; + current->pm[0]=current->w; +} + + +void DisableShm(void) +{ + use_shm=False; +} + + +void EnableBuffers(int no, ulong clscol) +{ + int f; + + current->pmi=0; + + if (current->use_pm) + XFreePixmap(display,current->pm[0]); + + if (current->buffer) + XFreePixmap(display,current->pm[1]); + + current->buffer=False; + current->use_pm=True; + current->multi=True; + + if (no>MAXPM) + current->multino=MAXPM; + else + current->multino=no; + + current->multicls=clscol; + + WM(GXcopy); + FG(current->multicls); + for(f=0;fmultino;f++) + { + current->pm[f]=XCreatePixmap(display,current->w,current->ww,current->wh, + vinfo.depth); + XFillRectangle(display,current->pm[f], + current->gc,0,0,current->pw,current->ph); + } + + WM(current->lastuserfunc); +} + + +void Pageflip(void) +{ + if (current->buffer) + current->pmi=current->pmi^1; + + if (current->multi) + if ((++current->pmi)>=current->multino) + current->pmi=0; +} + + +void SetAsBackdrop(void) +{ + XSetWindowBackgroundPixmap (display, current->w, current->pm[current->pmi]); + XSync(display,False); +} + + +void XUseFunction(int f) +{ + WM(f); + current->lastuserfunc=f; +} + + +void XSetLineStyle(unsigned int w, int ls, int cs, int js) +{ + XSetLineAttributes(display,current->gc,w,ls,cs,js); +} + + +void XCls(ulong c) +{ + if (current->use_pm) + { + WM(GXcopy); + FG(c); + XFillRectangle(display,current->pm[current->pmi], + current->gc,0,0,current->pw,current->ph); + WM(current->lastuserfunc); + } + else + { + /* + XSetBackground(display,current->gc,c); + XClearWindow(display,current->pm[0]); + */ + WM(GXcopy); + FG(c); + XFillRectangle(display,current->pm[current->pmi], + current->gc,0,0,current->pw,current->ph); + WM(current->lastuserfunc); + } +} + + +void XPlot(int x,int y, ulong c) +{ + FG(c); + XDrawPoint(display,current->pm[current->pmi],current->gc,x,y); +} + + +void XLine(int x1,int y1,int x2,int y2, ulong c) +{ + FG(c); + XDrawLine(display,current->pm[current->pmi],current->gc,x1,y1,x2,y2); +} + + +void SetSplineThresh(int t) +{ + current->spline_thresh=t; +} + + +static void XDoSpline(int x0,int y0,int x1,int y1,int x2,int y2,ulong c) +{ + int xa, ya, xb, yb, xc, yc, xp, yp; + + if ((x0==x1==x2)&&(y0==y1==y2)) + { + XPlot(x0,y0,c); + return; + } + + if ((x0==x1)&&(y0==y1)) + { + XLine(x1,y1,x2,y2,c); + return; + } + + if ((x0==x2)&&(y0==y2)) + { + XLine(x0,y0,x1,y1,c); + return; + } + + if ((x1==x2)&&(y1==y2)) + { + XLine(x0,y0,x2,y2,c); + return; + } + + xa = ( x0 + x1 ) / 2; + ya = ( y0 + y1 ) / 2; + xc = ( x1 + x2 ) / 2; + yc = ( y1 + y2 ) / 2; + xb = ( xa + xc ) / 2; + yb = ( ya + yc ) / 2; + + xp = ( x0 + xb ) / 2; + yp = ( y0 + yb ) / 2; + + if ( ABS( xa - xp ) + ABS( ya - yp ) > current->spline_thresh ) + XDoSpline(x0,y0,xa,ya,xb,yb,c); + else + XDrawLine(display,current->pm[current->pmi],current->gc,x0,y0,xb,yb); + + xp = ( x2 + xb ) / 2; + yp = ( y2 + yb ) / 2; + if ( ABS( xc - xp ) + ABS( yc - yp ) > current->spline_thresh ) + XDoSpline(xb,yb,xc,yc,x2,y2,c); + else + XDrawLine(display,current->pm[current->pmi],current->gc,xb,yb,x2,y2); +} + + +void XSpline(int x1,int y1,int x2,int y2,int x3,int y3,ulong c) +{ + FG(c); + + if ((x1==x2==x3)&&(y1==y2==y3)) + { + XPlot(x1,y1,c); + return; + } + + if ((x1==x2)&&(y1==y2)) + { + XLine(x2,y2,x3,y3,c); + return; + } + + if ((x1==x3)&&(y1==y3)) + { + XLine(x1,y1,x2,y2,c); + return; + } + + if ((x2==x3)&&(y2==y3)) + { + XLine(x1,y1,x3,y3,c); + return; + } + + XDoSpline(x1,y1,x2,y2,x3,y3,c); +} + + +void XPrint(int x,int y, const char *s, ulong c) + +{ + FG(c); + XDrawString(display,current->pm[current->pmi],current->gc,x,y,s,strlen(s)); +} + + +void Xprintf(int x, int y, ulong colour, const char *fmt, ...) +{ + va_list va; + + va_start(va,fmt); + vsprintf(prbuf,fmt,va); + va_end(va); + + FG(colour); + XDrawString(display,current->pm[current->pmi],current->gc, + x,y,prbuf,strlen(prbuf)); +} + + +void XISetFont(XImageFont n) +{ + switch(n) + { + case XI_FONT1: + xifont=xifont1; + break; + case XI_FONT2: + xifont=xifont2; + break; + } +} + + +static void XIPlot(XImage *img,int x,int y, ulong c) +{ + if ((y<0)||(y>=img->height)||(x<0)||(x>=img->width)) + return; + + XPutPixel(img,x,y,c); +} + + +void XIprintf(XImage *img, int x, int y, int sx, int sy, ulong col, + const char *fmt, ...) +{ + int f,px,py,psx,psy,ch; + char *data; + va_list arg; + + va_start(arg,fmt); + vsprintf(prbuf,fmt,arg); + va_end(arg); + + if ((sx==1)&&(sy==1)) + { + for(f=0;f=0)&&(y+pyheight)) + for(px=0;px=0)&&(x+pxwidth)) + if (xifont[ch].data[py][px]) + XPutPixel(img,x+px,y+py,col); + + x+=XIFONTW; + } + } + else + { + for(f=0;fpm[current->pmi],current->gc,x,y,w,h); +} + + +void XFillBox(int x,int y,int w,int h,ulong c) +{ + FG(c); + XFillRectangle(display,current->pm[current->pmi],current->gc,x,y,w,h); +} + + +void XCircle(int x,int y,int rx,int ry,int a1,int a2,ulong c) +{ + FG(c); + XDrawArc(display,current->pm[current->pmi],current->gc,x,y,rx,ry,a1,a2); +} + + +void XFillCircle(int x,int y,int rx,int ry,int a1,int a2,ulong c) +{ + FG(c); + XFillArc(display,current->pm[current->pmi],current->gc,x,y,rx,ry,a1,a2); +} + + +void XStartPlots(void) +{ + no_plots=0; +} + + +void XAddPlot(int x,int y) +{ + points[no_plots].x=x; + points[no_plots].y=y; + + no_plots++; +} + + +void XPutPlots(ulong c) +{ + FG(c); + XDrawPoints(display,current->pm[current->pmi],current->gc, + points,no_plots,CoordModeOrigin); +} + + +void XPutPlotsAsLines(ulong c) +{ + FG(c); + XDrawLines(display,current->pm[current->pmi],current->gc, + points,no_plots,CoordModeOrigin); +} + + +void XFillPoly(XPoint *xp,int n,int shape,ulong c) +{ + FG(c); + XFillPolygon(display,current->pm[current->pmi],current->gc,xp,n, + shape,CoordModeOrigin); +} + + +void XScroll(int dx,int dy) +{ + int destx,desty,srcx,srcy; + int w,h; + + if (dx>=0) + { + destx=0; + srcx=dx; + w=current->pw-dx; + } + + if (dx<0) + { + destx=-(dx); + srcx=0; + w=current->pw+dx; + } + + if (dy>=0) + { + desty=0; + srcy=dy; + h=current->ph-dy; + } + + if (dy<0) + { + desty=-(dy); + srcy=0; + h=current->ph+dy; + } + + WM(GXcopy); + XCopyArea(display,current->pm[current->pmi],current->pm[current->pmi], + current->gc,srcx,srcy,current->pw-dx,current->ph,destx,desty); + WM(current->lastuserfunc); +} + + +void XCopy(int sx,int sy,int w,int h,int dx,int dy) +{ + WM(GXcopy); + XCopyArea(display,current->pm[current->pmi],current->pm[current->pmi], + current->gc,sx,sy,current->pw,current->ph,dx,dy); + WM(current->lastuserfunc); +} + + +void XPut(Pixmap spm,int sx,int sy,int w,int h,int dx,int dy) +{ + WM(GXcopy); + XCopyArea(display,spm,current->pm[current->pmi], + current->gc,sx,sy,w,h,dx,dy); + WM(current->lastuserfunc); +} + + +void XGet(Pixmap dpm,int sx,int sy,int w,int h,int dx,int dy) +{ + WM(GXcopy); + XCopyArea(display,dpm,current->pm[current->pmi], + current->gc,sx,sy,w,h,dx,dy); + WM(current->lastuserfunc); +} + + +void ScreenCopy(void) +{ + if (current->buffer) + { + WM(GXcopy); + XCopyArea(display,current->pm[current->pmi^1], + current->pm[current->pmi],current->gc,0,0, + current->pw,current->ph,0,0); + WM(current->lastuserfunc); + } +} + + +Display *GetDisplay(void) +{ + return display; +} + + + +void XFinished(void) +{ + XCloseDisplay(display); +} + + +void XDoTillButtonPress(XVoidCallback func) +{ + XEvent event; + int ignore=True; + + while (True) + if (XPending(display)) + { + XNextEvent(display,&event); + + switch (event.type) + { + case Expose: + if (event.xexpose.count) + break; + Redraw(current->ox,current->oy); + break; + + case ButtonPress: + if (event.xbutton.button) + if (!ignore) + return; + break; + } + } + else + if (func) + switch (func()) + { + case XFUNCCONT: + ignore=False; + break; + + case XFUNCIGNORE: + ignore=True; + break; + + case XFUNCSTOP: + return; + break; + } + +} + + +void XDoMouse(XButtonCallback button, XMoveCallBack move, XVoidCallback process) +{ + XEvent event; + + while (True) + if ((XPending(display))||(!process)) + { + XNextEvent(display,&event); + + switch (event.type) + { + case Expose: + if (event.xexpose.count) + break; + Redraw(current->ox,current->oy); + break; + + case MotionNotify: + if (move) + switch(move(event.xmotion.window, + event.xmotion.x,event.xmotion.y)) + { + case XFUNCSTOP: + return; + break; + } + break; + + case ButtonPress: + if (button) + switch(button(event.xbutton.window,XPRESS, + event.xbutton.button, + event.xbutton.x,event.xbutton.y)) + { + case XFUNCSTOP: + return; + break; + } + break; + } + } + else + if (process) + switch (process()) + { + case XFUNCCONT: + case XFUNCIGNORE: + break; + + case XFUNCSTOP: + return; + break; + } + +} + + +static int IsMoveWin(Window w, XWindowMoveCallBack call[] ,int *i) +{ + int f; + + if (!call) + { + return(False); + } + + f=0; + + while(call[f].w) + { + if (call[f].w==w) + { + *i=f; + return call[f].func ? True:False; + } + else + { + f++; + } + } + + return False; +} + + +static int IsButtonWin(Window w, XWindowButtonCallback call[] ,int *i) +{ + int f; + + if (!call) + { + return(False); + } + + f=0; + + while(call[f].w) + { + if (call[f].w==w) + { + *i=f; + return call[f].func ? True:False; + } + else + { + f++; + } + } + + return False; +} + + +static int IsKeyWin(Window w, XWindowKeyCallback call[] ,int *i) +{ + int f; + + if (!call) + { + return(False); + } + + f=0; + + while(call[f].w) + { + if (call[f].w==w) + { + *i=f; + return call[f].func ? True:False; + } + else + { + f++; + } + } + + return False; +} + + +void XDoWindows(XWindowButtonCallback button[], + XWindowMoveCallBack move[], + XWindowKeyCallback key[], + XVoidCallback process) +{ + int i; + XEvent event; + + while (True) + if ((XPending(display))||(!process)) + { + XNextEvent(display,&event); + + switch (event.type) + { + case Expose: + if (event.xexpose.count) + break; + + PUSHW; + SetCurrentWin(event.xexpose.window); + Redraw(current->ox,current->oy); + POPW; + + break; + + case MotionNotify: + if (IsMoveWin(event.xmotion.window,move,&i)) + { + switch(move[i].func(event.xmotion.window, + event.xmotion.x, + event.xmotion.y)) + { + case XFUNCSTOP: + return; + break; + } + } + break; + + case ButtonPress: + if (IsButtonWin(event.xbutton.window,button,&i)) + { + switch(button[i].func + (event.xbutton.window, + XPRESS, + event.xbutton.button, + event.xbutton.x,event.xbutton.y)) + { + case XFUNCSTOP: + return; + break; + } + } + break; + + case ButtonRelease: + if (IsButtonWin(event.xbutton.window,button,&i)) + { + switch(button[i].func + (event.xbutton.window, + XRELEASE, + event.xbutton.button, + event.xbutton.x,event.xbutton.y)) + { + case XFUNCSTOP: + return; + break; + } + } + break; + + case KeyPress: + if (IsKeyWin(event.xkey.window,key,&i)) + { + switch(key[i].func(event.xkey.window, + XPRESS, + &event)) + { + case XFUNCSTOP: + return; + break; + } + } + break; + + case KeyRelease: + if (IsKeyWin(event.xkey.window,key,&i)) + { + switch(key[i].func(event.xkey.window, + XRELEASE, + &event)) + { + case XFUNCSTOP: + return; + break; + } + } + break; + + default: + break; + } + } + else + if (process) + { + switch (process()) + { + case XFUNCCONT: + case XFUNCIGNORE: + break; + + case XFUNCSTOP: + return; + break; + } + } +} + + +/* Sprite routines */ +void LoadSprite(const char *fn, XSprite *spr, const XColor xc[256]) +{ + Pixmap piximg,pixmask,pixsave; + int fd,x,y; + char magic[11]; + unsigned char *data,*p; + unsigned short us; + GC gc; + + if ((fd=open(fn,O_RDONLY))==-1) + { + WARN1("Couldn't open sprite file",fn); + return; + } + + read(fd,magic,11); + + if (strncmp(magic,"XbitSprite",10)) + { + WARN1(fn,"is not a sprite file!"); + close(fd); + return; + } + + spr->x=spr->y=0; + + read(fd,&us,sizeof(unsigned short)); + spr->w=ntohs(us); + read(fd,&us,sizeof(unsigned short)); + spr->h=ntohs(us); + + if (!(data=malloc(spr->w*spr->h))) + { + WARN("Couldn't grab memory for sprite image"); + close(fd); + return; + } + + if (read(fd,data,spr->w*spr->h)!=spr->w*spr->h) + { + WARN("Couldn't load sprite image"); + close(fd); + free(data); + return; + } + + close(fd); + + gc=XCreateGC(display,current->w,0,NULL); + + XSetPlaneMask(display,gc,AllPlanes); + XSetGraphicsExposures(display,gc,False); + + piximg=XCreatePixmap(display,current->w,spr->w,spr->h,vinfo.depth); + pixmask=XCreatePixmap(display,current->w,spr->w,spr->h,vinfo.depth); + pixsave=XCreatePixmap(display,current->w,spr->w,spr->h,vinfo.depth); + + p=data; + + for(y=0;yh;y++) + { + for(x=0;xw;x++) + { + XSetForeground(display,gc,xc[*p].pixel); + XDrawPoint(display,piximg,gc,x,y); + + if (*p) + XSetForeground(display,gc,xb_white); + else + XSetForeground(display,gc,xb_black); + + XDrawPoint(display,pixmask,gc,x,y); + + p++; + } + } + + spr->data=piximg; + spr->mask=pixmask; + spr->save=pixsave; + + free(data); +} + + +void XDrawSprites(XSprite *spr[],int no, XSpriteControl ctl) +{ + int f; + + WM(GXcopy); + + if (!(ctl&XSPRNOSAVE)) + for(f=0;fbuffer) + { + spr[f]->lx=spr[f]->x; + spr[f]->ly=spr[f]->y; + XCopyArea(display,current->pm[current->pmi^1], + spr[f]->save,current->gc,spr[f]->x,spr[f]->y, + spr[f]->w,spr[f]->h,0,0); + } + else + { + spr[f]->lx=spr[f]->x; + spr[f]->ly=spr[f]->y; + XCopyArea(display,current->pm[current->pmi], + spr[f]->save,current->gc,spr[f]->x,spr[f]->y, + spr[f]->w,spr[f]->h,0,0); + } + + WM(GXand); + for(f=0;fbuffer) + XCopyArea(display,spr[f]->mask,current->pm[current->pmi^1], + current->gc,0,0, + spr[f]->w,spr[f]->h,spr[f]->x,spr[f]->y); + else + XCopyArea(display,spr[f]->mask,current->pm[current->pmi], + current->gc,0,0, + spr[f]->w,spr[f]->h,spr[f]->x,spr[f]->y); + + WM(GXor); + for(f=0;fbuffer) + XCopyArea(display,spr[f]->data,current->pm[current->pmi^1], + current->gc,0,0, + spr[f]->w,spr[f]->h,spr[f]->x,spr[f]->y); + else + XCopyArea(display,spr[f]->data,current->pm[current->pmi], + current->gc,0,0, + spr[f]->w,spr[f]->h,spr[f]->x,spr[f]->y); + + WM(current->lastuserfunc); +} + + +void XEraseSprites(XSprite *spr[],int no) +{ + int f; + + WM(GXcopy); + + for(f=0;fbuffer) + XCopyArea(display,spr[f]->save,current->pm[current->pmi^1], + current->gc,0,0, + spr[f]->w,spr[f]->h,spr[f]->lx,spr[f]->ly); + else + XCopyArea(display,spr[f]->save,current->pm[current->pmi], + current->gc,0,0, + spr[f]->w,spr[f]->h,spr[f]->lx,spr[f]->ly); + + WM(current->lastuserfunc); +} + + +void LoadColormap(const char *fn, XColor xc[256]) +{ + int fd,f; + unsigned short us; + + if ((fd=open(fn,O_RDONLY))==-1) + { + WARN1("Couldn't open cmap",fn); + return; + } + + for(f=0;f<256;f++) + { + xc[f].flags=DoRed|DoGreen|DoBlue; + read(fd,&us,sizeof(unsigned short)); + xc[f].red=ntohs(us); + read(fd,&us,sizeof(unsigned short)); + xc[f].green=ntohs(us); + read(fd,&us,sizeof(unsigned short)); + xc[f].blue=ntohs(us); + + XAllocColor(display,DefaultColormap(display,screen),xc + f); + } +} + + +void AllocColors(int no,ulong pix[],const char *name[]) +{ + int f,col; + XColor xc; + + for(f=0;f(0x8000*3)) + { + WARN("defaulting to white"); + pix[f]=WhitePixel(display,screen); + } + else + { + WARN("defaulting to black"); + pix[f]=BlackPixel(display,screen); + } + } + } + else + { + WARN1("not a color ",name[f]); + pix[f]=WhitePixel(display,screen); + } + } +} + + +void AllocColorsRGB(int no, ulong pix[], const Colour col[]) +{ + int f; + XColor xc; + + for(f=0;f(0x8000*3)) + { + WARN("defaulting to white"); + pix[f]=WhitePixel(display,screen); + } + else + { + WARN("defaulting to black"); + pix[f]=BlackPixel(display,screen); + } + } + } +} + + +void LoadSpriteDataSet (const char *cmapfn, + const char *sprfn[], + SpriteDataSet *set) +{ + int f,r,fd; + char magic[11]; + XColor xcol[256]; + Colour col[256]; + SpriteData *spr; + int no; + int used[256]; + unsigned short us; + unsigned char byte; + + + /* Allocate referenced table + */ + for(f=0;f<256;f++) + used[f]=-1; + + /* Count and allocate referenced sprites + */ + no=0; + while(sprfn[no]) + no++; + + /* Load in colourmap + */ + LoadColormap(cmapfn,xcol); + + set->no_col=0; + set->no_spr=no; + + /* Load in sprites and sort out colour usage + */ + spr=malloc(sizeof(SpriteData)*no); + + for(f=0;fno_col].r=xcol[byte].red; + col[set->no_col].g=xcol[byte].green; + col[set->no_col].b=xcol[byte].blue; + + used[byte]=set->no_col++; + } + + spr[f].data[r]=used[byte]; + } + + close(fd); + } + + /* Got all sprites - allocate and remap colours + */ + AllocColoursRGB(set->no_col,set->pix,col); + + /* Remap sprites + */ + for(f=0;fpix[spr[f].data[r]]; + + /* Set up return, all done + */ + set->spr=spr; +} + + +/* END OF FILE */ -- cgit v1.2.3