#include "Xgraphics.h" void InitX() { char **fontlist; int i,count; Font myfont; char myfontpattern[40]; XColor col, colexact; /* set display to value of environment DISPLAY */ mydisplay=XOpenDisplay(""); if (mydisplay==NULL) { printf("Cannot connect to X Server\n"); exit(0); } myscreen=DefaultScreen(mydisplay); /* set colors */ mycmap = DefaultColormap(mydisplay,myscreen); black=BlackPixel(mydisplay,myscreen); white=WhitePixel(mydisplay,myscreen); global_color = black; global_function = GXcopy; mygc = XCreateGC(mydisplay,DefaultRootWindow(mydisplay),0,0); cleargc = XCreateGC(mydisplay,DefaultRootWindow(mydisplay),0,0); initgc = XCreateGC(mydisplay,DefaultRootWindow(mydisplay),0,0); XSetForeground(mydisplay,mygc,black); XSetBackground(mydisplay,mygc,white); XSetForeground(mydisplay,cleargc,white); XSetBackground(mydisplay,cleargc,black); XFlush(mydisplay); if( DefaultDepth(mydisplay,myscreen) == 1 ) { mycolors[0] = white; mycolors[1] = black; NofColors = 2; } else { if ( DefaultVisual(mydisplay,myscreen)->class < 2 ) { for(i=NofColors=0;iwin); /* free memory */ if ( buttonlist.buttons ) free ( buttonlist.buttons ); XFreeGC(mydisplay,mygc); XFreeGC(mydisplay,cleargc); XCloseDisplay(mydisplay); } /*****************************************************************************/ /* internal world- and win- handling */ struct world_node *make_world_node() { return( (struct world_node *) calloc(1,sizeof(struct world_node)) ); } struct win_node *make_win_node() { return( (struct win_node *) calloc(1,sizeof(struct win_node)) ); } struct win_node *find_win_node(Window window) { struct win_node *winptr; int notfound=1; winptr = worldlist; while(winptr && notfound) { if( winptr->win == window ) notfound = 0; else winptr = winptr->nextwin; } return winptr; } struct world_node *find_world_node(World world) { struct world_node *worldptr; int notfound=1; worldptr = find_win_node(world->win)->nextworld; while(worldptr && notfound) { if( worldptr->world == world ) notfound = 0; else worldptr = worldptr->nextworld; } return worldptr; } /*****************************************************************************/ Window CreateWindow(int width, int height, char *name) { Window tmp; struct win_node *winptr; XSizeHints *sizehints; XWMHints *wmhints; XClassHint *classhints; XTextProperty windowname, iconname; /* define window attributes */ if(!(sizehints=XAllocSizeHints())){ fprintf(stderr,"Xgraphics: failure allocating memory\n"); exit(-1); } if(!(wmhints=XAllocWMHints())){ fprintf(stderr,"Xgraphics: failure allocating memory\n"); exit(-1); } if(!(classhints=XAllocClassHint())){ fprintf(stderr,"Xgraphics: failure allocating memory\n"); exit(-1); } if(XStringListToTextProperty(&name,1,&windowname) ==0) { fprintf(stderr,"Xgraphics: failure allocating structure\n"); exit(-1); } if(XStringListToTextProperty(&name,1,&iconname) ==0) { fprintf(stderr,"Xgraphics: failure allocating structure\n"); exit(-1); } wmhints->initial_state = NormalState; wmhints->input = True; wmhints->flags = StateHint | InputHint; sizehints->base_width = width; sizehints->base_height = height; sizehints->flags = PBaseSize; attributes.backing_store = Always; attributes.background_pixel = white; /* create a window */ tmp = XCreateWindow(mydisplay,DefaultRootWindow(mydisplay), 200,200,width,height, /* coords */ 17,CopyFromParent, /* border width, depth */ InputOutput, /* class */ CopyFromParent, /* visual type */ CWBackingStore| CWBackPixel, /* valuemask */ &attributes); /* attributes */ XSelectInput(mydisplay,tmp, OwnerGrabButtonMask | ButtonPressMask | ButtonReleaseMask | /* Mouse */ EnterWindowMask | /* Mouse enters Window */ StructureNotifyMask | /* Geometry changes */ KeyPressMask | /* Keyboard */ ExposureMask); /* Window - Exposure */ XSetWMProperties(mydisplay,tmp,&windowname,&iconname,NULL,0,sizehints, wmhints,classhints); /* update window/world - database */ winptr = worldlist; worldlist = make_win_node(); worldlist->nextwin = winptr; worldlist->prevwin = (struct win_node *) NULL; worldlist->nextworld = (struct world_node *) NULL; worldlist->win = tmp; if(winptr) winptr->prevwin = worldlist; return tmp; } /*****************************************************************************/ void ShowWindow(Window win) { XMapRaised(mydisplay,win); } void HideWindow(Window win) { XUnmapWindow(mydisplay,win); XSync(mydisplay,True); } /*****************************************************************************/ void DestroyWindow(Window win) { struct win_node *winptr; struct world_node *worldptr,*tmp; /* find entry in database */ winptr = find_win_node(win); worldptr = winptr->nextworld; /* destroy worlds within this window */ while(winptr->nextworld) DestroyWorld(winptr->nextworld->world); /* delete database-entry */ if(winptr->nextwin) winptr->nextwin->prevwin = winptr->prevwin; if(winptr->prevwin) winptr->prevwin->nextwin = winptr->nextwin; else worldlist = winptr->nextwin; /* destroy window */ XDestroyWindow(mydisplay,win); free(winptr); } void DestroyWorld(World world) { struct world_node *worldptr; /* find database-entry */ worldptr = find_world_node(world); /* free GC's */ if(world->clipping) XFreeGC(mydisplay,world->gcw); if(world->gcp != mygc) XFreeGC(mydisplay,world->gcp); /* delete database-entry */ if(worldptr->nextworld) worldptr->nextworld->prevworld = worldptr->prevworld; if(worldptr->prevworld) worldptr->prevworld->nextworld = worldptr->nextworld; else find_win_node(world->win)->nextworld = worldptr->nextworld; /* destroy world */ free(world); free(worldptr); } /*****************************************************************************/ void ClearWindow(Window win) { XClearWindow(mydisplay,win); } /*****************************************************************************/ World CreateWorld(Window window, int px, int py, int pwidth, int pheight, float wx1, float wy1, float wx2, float wy2, int scalable, int gravity) { World tmpworld; struct win_node *winptr; struct world_node *worldptr; Window tmp; int gx,gy,gb,gd; XRectangle rect; /* create world (memory) */ tmpworld = (World) calloc(1,sizeof(Worldstruct)); /* if neccessary create window */ if(window == 0) { tmpworld->win = CreateWindow(px+pwidth,py+pheight,""); ShowWindow(tmpworld->win); } else tmpworld->win = window; /* create Backing-storage Pixmap */ if( !scalable ) { tmpworld->pixmap = XCreatePixmap(mydisplay,tmpworld->win,pwidth,pheight, DefaultDepth(mydisplay,myscreen)); XFillRectangle(mydisplay,tmpworld->pixmap,cleargc,0,0,pwidth,pheight); } else tmpworld->pixmap = 0; /* set coords */ tmpworld->px = px; tmpworld->py = py; tmpworld->pwidth = pwidth; tmpworld->pheight = pheight; tmpworld->bbx = px; tmpworld->bby = py; tmpworld->bbwidth = pwidth; tmpworld->bbheight = pheight; tmpworld->x1 = wx1; tmpworld->y1 = wy1; tmpworld->x2 = wx2; tmpworld->y2 = wy2; tmpworld->fx = (float)(pwidth-1)/(wx2-wx1); tmpworld->fy = (float)(pheight-1)/(wy2-wy1); tmpworld->aspect = (float)pheight/(float)pwidth; /* get coords of window */ XGetGeometry(mydisplay,tmpworld->win,&tmp,&gx,&gy, &(tmpworld->winwidth),&(tmpworld->winheight),&gb,&gd); /* set params */ tmpworld->scalable = scalable; tmpworld->gravity = gravity; tmpworld->clipping = CLIPPING; /* create CG for Pixmap */ tmpworld->gcp = XCreateGC(mydisplay,DefaultRootWindow(mydisplay),0,0); XCopyGC(mydisplay,initgc,-1,tmpworld->gcp); /* create CG for world */ if (CLIPPING) { tmpworld->gcw = XCreateGC(mydisplay,DefaultRootWindow(mydisplay),0,0); XCopyGC(mydisplay,initgc,-1,tmpworld->gcw); rect.x = px; rect.y = py; rect.width = pwidth; rect.height = pheight; XSetClipRectangles(mydisplay,tmpworld->gcw,0,0,&rect,1,Unsorted); } else tmpworld->gcw = tmpworld->gcp; /* set default color */ tmpworld->color = black; tmpworld->function = GXcopy; /* create database-entry */ winptr = find_win_node(tmpworld->win); if(winptr){ worldptr = winptr->nextworld; winptr->nextworld = make_world_node(); winptr->nextworld->world = tmpworld; winptr->nextworld->nextworld = worldptr; winptr->nextworld->prevworld = (struct world_node *) NULL; if(worldptr) worldptr->prevworld = winptr->nextworld; } else { fprintf(stderr,"Problems with alloc !\n"); exit(0); } return tmpworld; } /*****************************************************************************/ void ClearWorld(World world) { ClearArea(world->win,world->px,world->py,world->pwidth,world->pheight); if(world->pixmap) XFillRectangle(mydisplay,world->pixmap,cleargc, 0,0, world->pwidth,world->pheight); XFlush(mydisplay); } /*****************************************************************************/ void ExposeWorld(World world) { if(world->pixmap) { XCopyArea(mydisplay,world->pixmap,world->win,mygc,0,0, world->pwidth,world->pheight, world->px,world->py); XFlush(mydisplay); } } /*****************************************************************************/ void ResizeWorld(World world, int newwidth, int newheight) { int delta_width, delta_height, bbx_a, bby_a; XRectangle rect; /* differences in size */ delta_width = (newwidth-world->winwidth); delta_height = (newheight-world->winheight); /* bounding-box */ bbx_a = world->bbx; bby_a = world->bby; /* new coords for non-scalable worlds */ if( !(world->scalable) ) switch(world->gravity) { case NorthGravity: world->px += delta_width/2; break; case EastGravity: world->px += delta_width; world->py += delta_height/2; break; case SouthGravity: world->px += delta_width/2; world->py += delta_height; break; case WestGravity: world->py += delta_height/2; break; case NorthEastGravity: world->px += delta_width; break; case SouthEastGravity: world->px += delta_width; world->py += delta_height; break; case SouthWestGravity: world->py += delta_height; break; case NorthWestGravity: default: break; } else { /* scalable worlds */ if( world->scalable & FIXED_WIDTH ) { switch(world->gravity) { case NorthWestGravity: case WestGravity: case SouthWestGravity: break; case NorthEastGravity: case EastGravity: case SouthEastGravity: world->bbx += delta_width; break; default: world->bbx += delta_width/2; break; } } else { world->bbx += (world->scalable & FLOAT_WEST) ? world->bbx*(delta_width/(float)(world->winwidth)) : 0; world->bbwidth = (world->scalable & FLOAT_EAST) ? (bbx_a + world->bbwidth)* (newwidth/(float)(world->winwidth)) - world->bbx: (world->bbwidth + delta_width) + (bbx_a - world->bbx); } if( world->scalable & FIXED_HEIGHT ) { switch(world->gravity) { case NorthEastGravity: case NorthGravity: case NorthWestGravity: break; case SouthEastGravity: case SouthGravity: case SouthWestGravity: world->bby += delta_height; break; default: world->bby += delta_height/2; break; } } else { world->bby += (world->scalable & FLOAT_NORTH) ? world->bby*(delta_height/(float)(world->winheight)) : 0; world->bbheight = (world->scalable & FLOAT_SOUTH) ? (bby_a + world->bbheight)* (newheight/(float)(world->winheight)) - world->bby: (world->bbheight + delta_height) + (bby_a - world->bby); } if ( world->scalable & FREE_ASPECT ) { world->px = world->bbx; world->py = world->bby; world->pwidth = world->bbwidth; world->pheight = world->bbheight; } else { if ( world->bbwidth * world->aspect > world->bbheight ) { world->pheight = world->bbheight; world->pwidth = world->pheight/world->aspect; world->py = world->bby; world->px = world->bbx + (world->bbwidth - world->pwidth)/2; } else { world->pwidth = world->bbwidth; world->pheight = world->pwidth*world->aspect; world->px = world->bbx; world->py = world->bby + (world->bbheight - world->pheight)/2; } } world->fx = (float)(world->pwidth-1)/(world->x2 - world->x1); world->fy = (float)(world->pheight-1)/(world->y2 - world->y1); } world->winwidth = newwidth; world->winheight = newheight; if ( world->pwidth < 1 ) world->pwidth = 1; if ( world->pheight < 1 ) world->pheight = 1; world->aspect = (float)world->pheight/(float)world->pwidth; if (world->clipping) { rect.x = world->px; rect.y = world->py; rect.width = world->pwidth; rect.height = world->pheight; XSetClipRectangles(mydisplay,world->gcw,0,0,&rect,1,Unsorted); } } /*****************************************************************************/ void RescaleWorld(World world, float nx1, float ny1, float nx2, float ny2) { world->x1 = nx1; world->y1 = ny1; world->x2 = nx2; world->y2 = ny2; world->fx = (float)(world->pwidth-1)/(nx2-nx1); world->fy = (float)(world->pheight-1)/(ny2-ny1); } /*****************************************************************************/ void InitButtons(Window win, const char* buttonstring, int width) { struct blist { char type; char text[20]; char key; } *list; XSetWindowAttributes b_attributes; const char *ptr; char *ptr2; int i, j, count = 1,bcount = 0, x, height, gx, gy, gwidth, gheight, gb, gd; Window tmp; ptr = buttonstring; while(*ptr) if(*ptr++ == ',') (count)++; count /= 3; /* parse buttonstring */ list = (struct blist *) calloc(count,sizeof(struct blist)); ptr = buttonstring; i=0; while(*ptr && itype = 0; ret = 0; } }; /* serve standard-events */ if(ret) { switch(event->type) { case EnterNotify: /* mouse entered window */ /* XSetInputFocus(mydisplay,event->xcrossing.window, RevertToParent,CurrentTime); */ break; case MappingNotify: /* someone changed keyboard-layout */ XRefreshKeyboardMapping(&(event->xmapping)); break; case Expose: /* window gets visible again */ if(configure_flag) { XClearWindow(mydisplay,event->xexpose.window); winptr = find_win_node(event->xexpose.window); worldptr = winptr->nextworld; while(worldptr) { ExposeWorld(worldptr->world); worldptr = worldptr->nextworld; } } else { event->type = 0; ret = 0; } configure_flag = 0; break; case ConfigureNotify: /* window geometry changed */ newwidth = event->xconfigure.width; newheight = event->xconfigure.height; winptr = find_win_node(event->xconfigure.window); worldptr = winptr->nextworld; while(worldptr) { ResizeWorld(worldptr->world,newwidth,newheight); worldptr = worldptr->nextworld; } configure_flag = 1; break; case ButtonPress: /* someone pressed a mouse button */ if (buttonflag) { /* check whether it was in a 'button' and return key-event */ for(i=0; ixbutton.window == buttonlist.buttons[i].win) { event->type = KeyPress; event->xkey.keycode = buttonlist.buttons[i].keycode; event->xkey.state = buttonlist.buttons[i].state; } } } break; case KeyPress: /* someone pressed a key */ if (XLookupString(&(event->xkey),buffer,2,0,0) != 1) { event->type = 0; ret = 0; } break; default: break; } }; return ret; } /*****************************************************************************/ char ExtractChar(XEvent event) { char buffer[2]; if(XLookupString(&event.xkey,buffer,2,0,0)==1) return buffer[0]; else return 0; } /*****************************************************************************/ int WGetMousePos(World world, XEvent event, float *x, float *y) { int ret = 0; /* get coords and convert to world-coords */ *x = (event.xbutton.x - world->px)/world->fx + world->x1; *y = (event.xbutton.y - world->py)/world->fy + world->y1; /* in world ? */ if ( (*x >= world->x1) && (*x <= world->x2) && (*y >= world->y1) && (*y <= world->y2) ) ret = event.xbutton.button; return ret; } /*****************************************************************************/ int GetNumber( Window win, int x, int y, float *value ) { char str[30], zeichen = ' '; int i=1; /* double atof(char *); XEvent myevent; str[0] = ' ';str[1] = '\0'; while ( zeichen != '\15' ) /* repeat until RETURN pressed */ { GetEvent(&myevent,1); switch (myevent.type){ case KeyPress: zeichen = ExtractChar(myevent); switch(zeichen){ /********** BACK SPACE ***************************************/ case '\10': { if(i>0) { DrawString (win, x,y,str,1); str[i+1] = '\0'; str[i] = ' '; str[--i] = ' '; DrawString (win, x,y,str,1); break; } else XBell(mydisplay,0); } /********** RETURN ******************************************/ case '\15': { str[i] = '\0'; break; } /********** MINUS SIGN ***************************************/ case '-' : { if (i>0) i--; } /********** NUMBER ******************************************/ case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : case '.' : { str[i++] = zeichen; str[i] = ' '; str[i+1] = ' '; str[i+2] = '\0'; DrawString (win, x,y,str,1); break;} } /* switch zeichen */ break; default: break; } /* switch */ } /* while */ /************** Conversion to double *******************************/ if ( !( str[0] == '\0' || str[1] == '\0') ) { *value = atof(str); return 1; } else return 0; } /*****************************************************************************/ int WGetNumber( World world, float x, float y, float *value ) { char str[30], zeichen = ' '; int i=1; /* double atof(char *); XEvent myevent; str[0] = ' ';str[1] = '\0'; while ( zeichen != '\15' ) /* repeat until RETURN pressed */ { GetEvent(&myevent,1); switch (myevent.type){ case KeyPress: zeichen = ExtractChar(myevent); switch(zeichen){ /********** BACK SPACE ***************************************/ case '\10': { if(i>0) { WDrawString (world, x,y,str,1); str[i+1] = '\0'; str[i] = ' '; str[--i] = ' '; WDrawString (world, x,y,str,1); break; } else XBell(mydisplay,0); } /********** RETURN ******************************************/ case '\15': { str[i] = '\0'; break; } /********** MINUS SIGN ***************************************/ case '-' : { if (i>0) i--; } /********** NUMBER ******************************************/ case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : case '.' : { str[i++] = zeichen; str[i] = ' '; str[i+1] = ' '; str[i+2] = '\0'; WDrawString (world, x,y,str,1); break;} } /* switch zeichen */ break; default: break; } /* switch */ } /* while */ /************** Conversion to double *******************************/ if ( !( str[0] == '\0' || str[1] == '\0') ) { *value = atof(str); return 1; } else return 0; } /*****************************************************************************/ int GetString( Window win, int x, int y, int length, char *str ) { char zeichen = ' '; int i=0; XEvent myevent; str[0] = ' ';str[1] = '\0'; while ( zeichen != '\15' ) /* repeat until RETURN pressed */ { GetEvent(&myevent,1); switch (myevent.type){ case KeyPress: zeichen = ExtractChar(myevent); switch(zeichen){ /********** BACK SPACE ***************************************/ case '\10': { if(i>0) { DrawString (win, x,y,str,1); XBell(mydisplay,0); str[i+1] = '\0'; str[i] = ' '; str[--i] = ' '; DrawString (win, x,y,str,1); break; } else XBell(mydisplay,0); } /********** RETURN ******************************************/ case '\15': { str[i] = '\0'; break; } /********** CHARACTER ****************************************/ default : { str[i++] = zeichen; str[i] = ' '; str[i+1] = ' '; str[i+2] = '\0'; DrawString (win, x,y,str,1); break;} } /* switch zeichen */ break; } /* switch */ } /* while */ /******************************************************************/ if ( !( str[0] == '\0' || str[1] == '\0') ) { str[i] = '\0'; return 1; } else return 0; } /*****************************************************************************/ int WGetString( World world, float x, float y, int length, char *string ) { char str[30], zeichen = ' '; int i=0; XEvent myevent; str[0] = ' ';str[1] = '\0'; while ( zeichen != '\15' ) /* repeat until RETURN pressed */ { GetEvent(&myevent,1); switch (myevent.type){ case KeyPress: zeichen = ExtractChar(myevent); switch(zeichen){ /********** BACK SPACE ***************************************/ case '\10': { if(i>0) { WDrawString (world, x,y,str,1); str[i+1] = '\0'; str[i] = ' '; str[--i] = ' '; WDrawString (world, x,y,str,1); break; } else XBell(mydisplay,0); } /********** RETURN ******************************************/ case '\15': { str[i] = '\0'; break; } /********** CHARACTER ***************************************/ default : { str[i++] = zeichen; str[i] = ' '; str[i+1] = ' '; str[i+2] = '\0'; WDrawString (world, x,y,str,1); break;} } /* switch zeichen */ break; } /* switch */ } /* while */ /***************************************************************/ if ( !( str[0] == '\0' || str[1] == '\0') ) { str[i] = '\0'; strcpy(string,str); return 1; } else return 0; } /*****************************************************************************/ void WSetColor(World world, unsigned long color_func) { unsigned long color; unsigned function; /* extract color and drawing-function */ function = (color_func&4096)?(color_func/256)%16:3; color = (function==GXxor)? /* colors should appear */ mycolors[(color_func%256)%NofColors]^white: /* normal on white */ mycolors[(color_func%256)%NofColors]; /* background */ if(color != world->color) { XSetForeground(mydisplay,world->gcw,color); if(world->pixmap) XSetForeground(mydisplay,world->gcp,color); world->color = color; } if(function != world->function) { XSetFunction(mydisplay,world->gcw,function); if(world->pixmap) XSetFunction(mydisplay,world->gcp,function); world->function = function; } } void SetColor(unsigned long color_func) { unsigned long color; unsigned function; function = (color_func&4096)?(color_func/256)%16:3; color = (function==GXxor)? mycolors[(color_func%256)%NofColors]^white: mycolors[(color_func%256)%NofColors]; if(color != global_color) XSetForeground(mydisplay,mygc,color); if(function != global_function) XSetFunction(mydisplay,mygc,function); } /*****************************************************************************/ void ClearArea(Window win, int x, int y, int width, int height) { XClearArea(mydisplay,win,x,y,width,height,False); } /*****************************************************************************/ void DrawPoint(Window win, int x, int y, int c) { SetColor(c); XDrawPoint(mydisplay,win,mygc,x,y); } /*****************************************************************************/ void DrawPoints(Window win, XPoint *points, int NofPoints, int c) { SetColor(c); XDrawPoints(mydisplay, win, mygc, points, NofPoints, CoordModeOrigin); } /*****************************************************************************/ void DrawLine(Window win, int x1,int y1, int x2, int y2, int c) { SetColor(c); XDrawLine(mydisplay,win,mygc,x1,y1,x2,y2); } /*****************************************************************************/ void DrawLines(Window win, XPoint *points, int NofPoints, int c) { SetColor(c); XDrawLines(mydisplay, win, mygc, points, NofPoints, CoordModeOrigin); } /*****************************************************************************/ void DrawCircle(Window win, int x, int y, int r, int c) { int rr; rr = abs(r); SetColor(c); XDrawArc(mydisplay,win,mygc,x-rr,y-rr,2*rr,2*rr,0,23040); /* XFlush(mydisplay); */ } void FillCircle(Window win, int x, int y, int r, int c) { int rr; rr = abs(r); SetColor(c); XFillArc(mydisplay,win,mygc,x-rr,y-rr,2*rr,2*rr,0,23040); /* XFlush(mydisplay); */ } /*****************************************************************************/ void DrawString(Window win, int x, int y, const char* text, int c) { SetColor(c); XDrawImageString(mydisplay,win,mygc,x,y,text,strlen(text)); XFlush(mydisplay); } /*****************************************************************************/ void DrawRectangle(Window win, int x1, int y1, int x2, int y2, int c) { int temp; SetColor(c); if (x1 > x2) { temp=x1; x1=x2; x2=temp; }; if (y1 > y2) { temp=y1; y1=y2; y2=temp; }; XDrawRectangle(mydisplay, win, mygc, x1, y1, x2-x1, y2-y1); XFlush(mydisplay); } void FillRectangle(Window win, int x1, int y1, int x2, int y2, int c) { int temp; SetColor(c); if (x1 > x2) { temp=x1; x1=x2; x2=temp; }; if (y1 > y2) { temp=y1; y1=y2; y2=temp; }; XFillRectangle(mydisplay, win, mygc, x1, y1, x2-x1, y2-y1); XFlush(mydisplay); } /*****************************************************************************/ void DrawPoly(Window win, XPoint *points, int NofPoints, int c) { int i; XPoint *xpoints; if( !(xpoints = (XPoint*) calloc(NofPoints+1,sizeof(XPoint)) ) ) { fprintf(stderr,"Calloc error XLines !!!\n"); exit(-1); } for(i=0; ix1)*world->fx; py = (y-world->y1)*world->fy; WSetColor(world,c); XDrawPoint(mydisplay,world->win,world->gcw,world->px+px,world->py+py); if(world->pixmap) XDrawPoint(mydisplay,world->pixmap,world->gcp,px,py); XFlush(mydisplay); } /*****************************************************************************/ void WDrawPoints(World world, WPoint *points, int NofPoints, int c) { int i; XPoint *xpoints; if( !(xpoints = (XPoint*) calloc(NofPoints,sizeof(XPoint)) ) ) { fprintf(stderr,"Calloc error XPoints !!!\n"); exit(-1); } for(i=0; ipx + (points[i].x-world->x1)*world->fx; xpoints[i].y = world->py + (points[i].y-world->y1)*world->fy; } WSetColor(world,c); XDrawPoints(mydisplay,world->win,world->gcw, xpoints,NofPoints,CoordModeOrigin); if(world->pixmap){ for(i=0; ipx; xpoints[i].y -= world->py; } XDrawPoints(mydisplay,world->pixmap,world->gcp, xpoints,NofPoints,CoordModeOrigin); } free(xpoints); } /*****************************************************************************/ void WDrawLine(World world, float x1, float y1, float x2, float y2, int c) { int px1, px2, py1, py2; px1 = (x1-world->x1)*world->fx; py1 = (y1-world->y1)*world->fy; px2 = (x2-world->x1)*world->fx; py2 = (y2-world->y1)*world->fy; WSetColor(world,c); XDrawLine(mydisplay,world->win,world->gcw, world->px+px1,world->py+py1,world->px+px2,world->py+py2); if(world->pixmap) XDrawLine(mydisplay,world->pixmap,world->gcp, px1,py1,px2,py2); XFlush(mydisplay); } /*****************************************************************************/ void WDrawLines(World world, WPoint *points, int NofPoints, int c) { int i; XPoint *xpoints; if( !(xpoints = (XPoint*) calloc(NofPoints,sizeof(XPoint)) ) ) { fprintf(stderr,"Calloc error XLines !!!\n"); exit(-1); } for(i=0; ipx + (points[i].x-world->x1)*world->fx; xpoints[i].y = world->py + (points[i].y-world->y1)*world->fy; } WSetColor(world,c); XDrawLines(mydisplay,world->win,world->gcw, xpoints,NofPoints,CoordModeOrigin); if(world->pixmap){ for(i=0; ipx; xpoints[i].y -= world->py; } XDrawLines(mydisplay,world->pixmap,world->gcp, xpoints,NofPoints,CoordModeOrigin); } free(xpoints); XFlush(mydisplay); } /*****************************************************************************/ void WDrawCircle(World world, float x, float y, float r, int c) { int px, py, prx, pry; px = (x-world->x1)*world->fx; py = (y-world->y1)*world->fy; prx = abs((int) (r*world->fx)); pry = abs((int) (r*world->fy)); if(prx==0) prx=1; if(pry==0) pry=1; WSetColor(world,c); XDrawArc(mydisplay,world->win,world->gcw,world->px+px-prx, world->py+py-pry,2*prx,2*pry,0,23040); if(world->pixmap) XDrawArc(mydisplay,world->pixmap,world->gcp,px-prx, py-pry,2*prx,2*pry,0,23040); } void WFillCircle(World world, float x, float y, float r, int c) { int px, py, prx, pry; px = (x-world->x1)*world->fx; py = (y-world->y1)*world->fy; prx = abs((int) (r*world->fx)); pry = abs((int) (r*world->fy)); if(prx==0) prx=1; if(pry==0) pry=1; WSetColor(world,c); XFillArc(mydisplay,world->win,world->gcw,world->px+px-prx, world->py+py-pry,2*prx,2*pry,0,23040); if(world->pixmap) XFillArc(mydisplay,world->pixmap,world->gcp,px-prx, py-pry,2*prx,2*pry,0,23040); } /*****************************************************************************/ void WDrawString(World world, float x, float y, const char* text, int c) { int px,py; px = (x-world->x1)*world->fx; py = (y-world->y1)*world->fy; WSetColor(world,c); XDrawImageString(mydisplay,world->win,world->gcw, world->px+px,world->py+py,text,strlen(text)); if(world->pixmap) XDrawImageString(mydisplay,world->pixmap,world->gcp, px,py,text,strlen(text)); XFlush(mydisplay); } /*****************************************************************************/ void WDrawRectangle(World world, float x1, float y1, float x2, float y2, int c) { int px1,px2,py1,py2, temp; px1 = (x1-world->x1)*world->fx; py1 = (y1-world->y1)*world->fy; px2 = (x2-world->x1)*world->fx; py2 = (y2-world->y1)*world->fy; if (px1>px2) { temp=px1; px1=px2; px2=temp; }; if (py1>py2) { temp=py1; py1=py2; py2=temp; }; WSetColor(world,c); XDrawRectangle(mydisplay, world->win, world->gcw, world->px+px1, world->py+py1, px2-px1, py2-py1); if(world->pixmap) XDrawRectangle(mydisplay, world->pixmap, world->gcp, px1, py1, px2-px1, py2-py1); XFlush(mydisplay); } void WFillRectangle(World world, float x1, float y1, float x2, float y2, int c) { int px1,px2,py1,py2, temp; px1 = (x1-world->x1)*world->fx; py1 = (y1-world->y1)*world->fy; px2 = (x2-world->x1)*world->fx; py2 = (y2-world->y1)*world->fy; if (px1>px2) { temp=px1; px1=px2; px2=temp; }; if (py1>py2) { temp=py1; py1=py2; py2=temp; }; WSetColor(world,c); XFillRectangle(mydisplay, world->win, world->gcw, world->px+px1, world->py+py1, px2-px1, py2-py1); if(world->pixmap) XFillRectangle(mydisplay, world->pixmap, world->gcp, px1, py1, px2-px1, py2-py1); XFlush(mydisplay); } /*****************************************************************************/ void WDrawPoly(World world, WPoint *points, int NofPoints, int c) { int i; XPoint *xpoints; if( !(xpoints = (XPoint*) calloc(NofPoints+1,sizeof(XPoint)) ) ) { fprintf(stderr,"Calloc error XLines !!!\n"); exit(-1); } for(i=0; ipx + (points[i].x-world->x1)*world->fx; xpoints[i].y = world->py + (points[i].y-world->y1)*world->fy; } if ((xpoints[0].x != xpoints[NofPoints-1].x) ||(xpoints[0].y != xpoints[NofPoints-1].y)) { xpoints[NofPoints].x = xpoints[0].x; xpoints[NofPoints].y = xpoints[0].y; NofPoints ++; } WSetColor(world,c); XDrawLines(mydisplay,world->win,world->gcw, xpoints,NofPoints,CoordModeOrigin); if(world->pixmap){ for(i=0; ipx; xpoints[i].y -= world->py; } XDrawLines(mydisplay,world->pixmap,world->gcp, xpoints,NofPoints,CoordModeOrigin); } free(xpoints); XFlush(mydisplay); } /*****************************************************************************/ void WFillPoly(World world, WPoint *points, int NofPoints, int c, int cfill) { int i; XPoint *xpoints; if( !(xpoints = (XPoint*) calloc(NofPoints+1,sizeof(XPoint)) ) ) { fprintf(stderr,"Calloc error XLines !!!\n"); exit(-1); } for(i=0; ipx + (points[i].x-world->x1)*world->fx; xpoints[i].y = world->py + (points[i].y-world->y1)*world->fy; } WSetColor(world,cfill); XFillPolygon(mydisplay, world->win, world->gcw, xpoints, NofPoints, Complex, CoordModeOrigin); if ((xpoints[0].x != xpoints[NofPoints-1].x) ||(xpoints[0].y != xpoints[NofPoints-1].y)) { xpoints[NofPoints].x = xpoints[0].x; xpoints[NofPoints].y = xpoints[0].y; NofPoints ++; } WSetColor(world,c); XDrawLines(mydisplay,world->win,world->gcw, xpoints,NofPoints,CoordModeOrigin); if(world->pixmap){ for(i=0; ipx; xpoints[i].y -= world->py; } WSetColor(world,cfill); XFillPolygon(mydisplay, world->pixmap, world->gcp, xpoints, NofPoints, Complex, CoordModeOrigin); WSetColor(world,c); XDrawLines(mydisplay,world->pixmap,world->gcp, xpoints,NofPoints,CoordModeOrigin); } free(xpoints); XFlush(mydisplay); } /*****************************************************************************/