/* File Name: Xgraphics.c Version: 1.00 ( 28/04/96 ) By: Martin Lueders (lueders@physik.uni-wuerzburg.de)
Copyright (C) ** 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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;i<MAX_COLORS;++i) { if (XAllocNamedColor(mydisplay,mycmap,graylist[i],&col,&colexact) ) mycolors[NofColors++] = col.pixel; } } else { for(i=NofColors=0;i<MAX_COLORS;++i) { if (XAllocNamedColor(mydisplay,mycmap,colorlist[i],&col,&colexact) ) mycolors[NofColors++] = col.pixel; } } }
/* set default font */ strcpy(myfontpattern,"-*-helvetica-bold-r-normal--14*");
fontlist = XListFonts(mydisplay,myfontpattern,20,&count); if(count) { myfont=XLoadFont(mydisplay,myfontpattern); XSetFont(mydisplay,mygc,myfont); } /* if */ XFreeFontNames(fontlist);
XCopyGC(mydisplay,mygc,-1,initgc);
/* reset internal lists */
worldlist = (struct win_node *) NULL; buttonflag = 0; buttonlist.buttons = (ButtonType *) NULL; buttonlist.NofButtons = 0; }
/*=====*\ void ExitX(){ /* destroy remaining windows */ while(worldlist) DestroyWindow(worldlist->win);
/* 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;
/* 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, double wx1, double wy1, double wx2, double wy2, int scalable, int gravity) {
World tmpworld; struct win_node *winptr; struct world_node *worldptr; Window tmp; int gx,gy; unsigned int 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 = (double)(pwidth-1)/(wx2-wx1); tmpworld->fy = (double)(pheight-1)/(wy2-wy1);
tmpworld->aspect = (double)pheight/(double)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/(double)(world->winwidth)) : 0;
world->bbwidth = (world->scalable & FLOAT_EAST) ? (bbx_a + world->bbwidth)* (newwidth/(double)(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/(double)(world->winheight)) : 0;
world->bbheight = (world->scalable & FLOAT_SOUTH) ? (bby_a + world->bbheight)* (newheight/(double)(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 = (double)(world->pwidth-1)/(world->x2 - world->x1); world->fy = (double)(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 = (double)world->pheight/(double)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, double nx1, double ny1, double nx2, double ny2) { world->x1 = nx1; world->y1 = ny1; world->x2 = nx2; world->y2 = ny2;
world->fx = (double)(world->pwidth-1)/(nx2-nx1); world->fy = (double)(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; unsigned int 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 && i<count) { list[i].type = *ptr++; while ( (*ptr++ != ',') && *ptr); ptr2 = list[i].text; for(j=0; (*ptr!=',') && (*ptr) && j<30 ; *ptr2++ = *ptr++,j++ ); if(*ptr++ !=',') { printf("Fehler 2 ! %d \n",i); exit(0); }; if (list[i].type == 'b' ) list[i].key = *ptr++; else list[i].key = ' '; while (*ptr++ !=',' && i<count-1); i++; }
/* count buttons */ for(i=0,bcount=0;i<count;++i) if (list[i].type == 'b') ++bcount;
/* calculate geometry */ height = (count + 1) * BUTTONHEIGHT; XGetGeometry(mydisplay, win, &tmp, &gx, &gy, &gwidth, &gheight, &gb, &gd ); x = gwidth - width;
/* remove existing buttons */ if ( buttonlist.buttons ) { free( buttonlist.buttons ); ClearWorld( buttonlist.world ); DestroyWorld( buttonlist.world ); }
/* create button-world */ buttonlist.buttons = (ButtonType *) calloc(bcount,sizeof(ButtonType)); buttonlist.world = CreateWorld(win,x,0,width,height,0,0, width-1,height-1,0,NorthEastGravity); buttonlist.NofButtons = bcount;
b_attributes.win_gravity = NorthEastGravity;
/* create buttons */ for(i=0,j=0;i<count;++i) { if ( list[i].type == 'b' ) { /* WFillRectangle(buttonlist.world,5,i*BUTTONHEIGHT+2, width-10,(i+1)*BUTTONHEIGHT-4,0); */ WDrawRectangle(buttonlist.world,5,i*BUTTONHEIGHT+2, width-10,(i+1)*BUTTONHEIGHT-4,1); WDrawString(buttonlist.world,10,(i+1)*BUTTONHEIGHT-13,list[i].text,1);
buttonlist.buttons[j].win = XCreateWindow(mydisplay,win,x+5,i*BUTTONHEIGHT+2, width-12,BUTTONHEIGHT-4,0,CopyFromParent, InputOnly,CopyFromParent, CWWinGravity,&b_attributes);
XSelectInput(mydisplay,buttonlist.buttons[j].win,ButtonPressMask); ShowWindow(buttonlist.buttons[j].win); buttonlist.buttons[j].keycode = XKeysymToKeycode(mydisplay,list[i].key); if ( XKeycodeToKeysym(mydisplay,buttonlist.buttons[j].keycode,0) == list[i].key ) buttonlist.buttons[j++].state = 0; else buttonlist.buttons[j++].state = 1;
} else {
WDrawString(buttonlist.world,5,(i+1)*BUTTONHEIGHT-13,list[i].text,1); } } buttonflag = 1; free(list); }
/*=====*\
int GetEvent(XEvent* event, int wait_flag) { int i, ret; int newwidth, newheight; struct win_node *winptr; struct world_node *worldptr; static int configure_flag=0; char buffer[2];
if(wait_flag) { /* wait for next event */ XNextEvent(mydisplay,event); ret = 1; } else { /* check whether an event is queued */ if(XEventsQueued(mydisplay,QueuedAfterFlush)) { /* read event */ XNextEvent(mydisplay,event); ret = 1; } else { /* if no event queued, return 0 */ event->type = 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; i<buttonlist.NofButtons; i++) { if (event->xbutton.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(event.type != KeyPress) return 0; if(XLookupString(&event.xkey,buffer,2,0,0)==1) return buffer[0]; else return 0; }
/*=====*\
int WGetMousePos(World world, XEvent event, double *x, double *y) { int ret = 0;
if(event.type != ButtonPress) return 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, double *value ) { char str[30], zeichen = ' '; int i=1; 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, double x, double y, double *value ) { char str[30], zeichen = ' '; int i=1; 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, double x, double 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); global_color = color; }
if(function != global_function) { XSetFunction(mydisplay,mygc,function); global_function = 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); }
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); }
/*=====*\
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; i<NofPoints; ++i) { xpoints[i].x = points[i].x; xpoints[i].y = points[i].y; }
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 ++; }
SetColor(c);
XDrawLines(mydisplay,win,mygc, xpoints,NofPoints,CoordModeOrigin);
free(xpoints);
XFlush(mydisplay); }
/*=====*\
void FillPoly(Window win, XPoint *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; i<NofPoints; ++i) { xpoints[i].x = points[i].x; xpoints[i].y = points[i].y; }
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 ++; }
SetColor(cfill);
XFillPolygon(mydisplay, win, mygc, points, NofPoints, Complex, CoordModeOrigin);
SetColor(c);
XDrawLines(mydisplay,win,mygc, xpoints,NofPoints,CoordModeOrigin);
free(xpoints);
XFlush(mydisplay); }
/*=====*\
void WDrawPoint(World world, double x, double y, int c) { int px, py;
px = (x-world->x1)*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; i<NofPoints; ++i) { xpoints[i].x = world->px + (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; i<NofPoints; ++i) { xpoints[i].x -= world->px; xpoints[i].y -= world->py; }
XDrawPoints(mydisplay,world->pixmap,world->gcp, xpoints,NofPoints,CoordModeOrigin); } free(xpoints); }
/*=====*\
void WDrawLine(World world, double x1, double y1, double x2, double 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; i<NofPoints; ++i) { xpoints[i].x = world->px + (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; i<NofPoints; ++i) { xpoints[i].x -= world->px; xpoints[i].y -= world->py; }
XDrawLines(mydisplay,world->pixmap,world->gcp, xpoints,NofPoints,CoordModeOrigin); } free(xpoints);
XFlush(mydisplay); }
/*=====*\
void WDrawCircle(World world, double x, double y, double 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, double x, double y, double 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, double x, double 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, double x1, double y1, double x2, double 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, double x1, double y1, double x2, double 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; i<NofPoints; ++i) { xpoints[i].x = world->px + (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; i<NofPoints; ++i) { xpoints[i].x -= world->px; 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; i<NofPoints; ++i) { xpoints[i].x = world->px + (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; i<NofPoints; ++i) { xpoints[i].x -= world->px; 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); } /*End*/
|