Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

draw.c

Go to the documentation of this file.
00001 /* draw.c
00002  * Biao Lu                     biao@eagle.drexel.edu
00003  */
00004 
00005 #include "win.h"
00006 
00007 extern GC        redrawgc, defaultgc;
00008 extern int       pmpallocflag;
00009 extern XFontStruct  *font_info;
00010 extern lux_wins *get_currentwin();
00011 extern unsigned  long lux_get_bgcolor();
00012 
00013 #define RESIZED              1
00014 #define ONE_MORE_EXPOSE      2
00015 #define ABORT_REDRAW         3
00016 
00017 
00018 #define DEBUG 0
00019 
00020 
00021 Bool lux_expose_pred(display, event, msg)
00022 Display  *display;
00023 XEvent   *event;
00024 char     *msg;
00025 {
00026     register Window *win;
00027 
00028     win = (Window *)msg;
00029 
00030     switch (event->type) {
00031         case ConfigureNotify:
00032           if (win[0] == event->xany.window) win[1] = 1;
00033           break;
00034         case Expose:
00035           if (win[0] == event->xany.window) win[2] = 2;
00036           break;
00037         case ButtonPress:   
00038           if ((win[0] == event->xany.window) && 
00039               (event->xbutton.button == Button2)) {
00040             win[1] = win[2] = 3;
00041             return(True);
00042           }
00043           break;
00044         default:
00045           break;
00046     }
00047     return(False);
00048 }
00049 
00050 lux_peek_expose(display,win)
00051 Display *display;
00052 Window   win;
00053 {
00054     XEvent   report;
00055     Window  *w;
00056     char     msg[3*sizeof(Window)];
00057     
00058     w = (Window *)msg;
00059     w[0] = win; 
00060 
00061     w[1] = w[2] = 0;
00062     XCheckIfEvent(display,&report,lux_expose_pred,msg);
00063 
00064     if (w[2] == 2) {
00065 /*      fprintf(stderr,"lux_msg: One more expose in win %u\n", win);*/
00066       return(ONE_MORE_EXPOSE);
00067     }
00068     if (w[1] == 3 || w[2] == 3) {
00069 /*      fprintf(stderr,"lux_msg: Abort in redraw in win %u\n", win);*/
00070       return(ABORT_REDRAW);
00071     }
00072 
00073     return 0;
00074 }
00075 
00076 lux_peek_expose_config(display,win)
00077 Display *display;
00078 Window   win;
00079 {
00080     XEvent   report;
00081     Window  *w;
00082     char     msg[3*sizeof(Window)];
00083     
00084     w = (Window *)msg;
00085     w[0] = win; 
00086 
00087     w[1] = w[2] = 0;
00088     XCheckIfEvent(display,&report,lux_expose_pred,msg);
00089 
00090     if (w[1] == 1) {
00091 /*      fprintf(stderr,"lux_msg: Size changed in win %u\n", win);*/
00092       return(RESIZED);
00093     }
00094     if (w[2] == 2) {
00095 /*      fprintf(stderr,"lux_msg: One more expose in win %u\n", win);*/
00096       return(ONE_MORE_EXPOSE);
00097     }
00098     if (w[1] == 3 || w[2] == 3) {
00099 /*      fprintf(stderr,"lux_msg: Abort in redraw in win %u\n", win);*/
00100       return(ABORT_REDRAW);
00101     }
00102 
00103     return 0;
00104 }
00105 
00106 lux_data *get_newdata(wins)
00107 lux_wins *wins;
00108 {
00109     register lux_data *newdata, *current;
00110 
00111     if (wins->win.data == NULL) {
00112 
00113       if ( (wins->win.data = (lux_data *)malloc(sizeof(lux_data))) == 
00114             (lux_data *)NULL ) return((lux_data *)NULL);
00115 
00116       (wins->win.data)->next = wins->win.data;
00117       wins->win.currentdata = wins->win.data;
00118       wins->win.data->data.d = (double *)NULL;
00119       newdata = wins->win.data;
00120 
00121     } else {
00122 
00123       newdata = (lux_data *)malloc(sizeof(lux_data));
00124 
00125       if ( newdata == (lux_data *)NULL )
00126           return((lux_data *)NULL);
00127 
00128       newdata->data.d = (double *)NULL;
00129       current = wins->win.currentdata;
00130       while(current->next != current) current = current->next;
00131       current->next = newdata;
00132       newdata->next = newdata;
00133       wins->win.currentdata = newdata;
00134 
00135     }
00136 
00137     return(newdata);
00138 }
00139 
00140 lux_clear_window(win)    /* Just clear the graph not data */
00141 Window win;
00142 {
00143     register lux_wins *current;
00144     register lux_data *newdata;
00145 
00146     current = get_currentwin(win);
00147   
00148     if (current->win.pixmap) 
00149       lux_clear_pixmap(current->win.display,current->win.pixmap,
00150                        current->win.gc,0,0,
00151                        current->win.width,current->win.height);
00152     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) {
00153       lux_clear_pixmap(current->win.display,current->win.window,
00154                        current->win.gc,0,0,
00155                        current->win.width,current->win.height);
00156       XFlush(current->win.display);
00157     }
00158 
00159     if (current->win.discard_flag)  return 1;
00160 
00161     if ( (newdata = get_newdata(current)) == (lux_data *)NULL )
00162       { fprintf(stderr,"Can't clear window -- not enough memory\n"); 
00163         return 0;}
00164 
00165     newdata->type = CLEAR_WINDOW;
00166 
00167 
00168 }
00169 
00170 lux_reclear_window(win)    /* Just clear the graph not data */
00171 Window win;
00172 {
00173     register lux_wins *current;
00174 
00175     current = get_currentwin(win);
00176   
00177     if (current->win.pixmap) 
00178       lux_clear_pixmap(current->win.display,current->win.pixmap,
00179                        redrawgc,0,0,
00180                        current->win.width,current->win.height);
00181     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL))  {
00182       lux_clear_pixmap(current->win.display,current->win.window,
00183                        redrawgc,0,0,
00184                        current->win.width,current->win.height);
00185       XFlush(current->win.display);
00186     }
00187 
00188 }
00189 
00190 lux_clear_current_region(win)
00191 Window win;
00192 {
00193     register lux_wins *current;
00194     register lux_data *newdata;
00195     int x,y,width,height;
00196 
00197     current = get_currentwin(win);
00198 
00199     x = current->win.xorg*current->win.xresizefactor+0.5;
00200     y = current->win.yorg*current->win.yresizefactor+0.5;
00201     width  = current->win.xsize*current->win.xresizefactor+0.5;
00202     height = current->win.ysize*current->win.yresizefactor+0.5;
00203 
00204     if (current->win.pixmap) {
00205       lux_clear_pixmap(current->win.display, current->win.pixmap, 
00206                        current->win.gc, 
00207                        x+1, y+1, width-2, height-2);
00208     }
00209     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL))  
00210       lux_clear_pixmap(current->win.display, current->win.window, 
00211                        current->win.gc, 
00212                        x+1, y+1, width-2, height-2);
00213 
00214     if (current->win.discard_flag)  return 1;
00215 
00216     if ( (newdata = get_newdata(current)) == (lux_data *)NULL )
00217       { fprintf(stderr,"Can't clear display -- not enough memory\n"); 
00218         return 0;}
00219 
00220     newdata->type = CLEAR_CURRENT_REGION;
00221 
00222     return 1;
00223 }
00224 
00225 lux_reclear_current_region(win)
00226 Window win;
00227 {
00228     register lux_wins *current;
00229     int x,y,width,height;
00230 
00231     current = get_currentwin(win);
00232 
00233     x = current->win.xorg*current->win.xresizefactor+0.5;
00234     y = current->win.yorg*current->win.yresizefactor+0.5;
00235     width  = current->win.xsize*current->win.xresizefactor+0.5;
00236     height = current->win.ysize*current->win.yresizefactor+0.5;
00237 
00238     if (current->win.pixmap) {
00239 /*
00240         XCopyArea(current->win.display, current->win.pixmap,
00241                   current->win.window,
00242                   redrawgc, 
00243                   0, 0, current->win.width, current->win.height, 0, 0);
00244         XFlush(current->win.display);
00245 */
00246       lux_clear_pixmap(current->win.display, current->win.pixmap, redrawgc, 
00247                        x+1, y+1, width-2, height-2);
00248     }
00249 
00250     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL))  
00251       lux_clear_pixmap(current->win.display, current->win.window, redrawgc, 
00252                        x+1, y+1, width-2, height-2);
00253 
00254 }
00255 
00256 lux_update_fg(win)
00257 Window win;
00258 {
00259     register lux_wins *current;
00260     register lux_data *newdata;
00261 
00262     current = get_currentwin(win);
00263 
00264     if (current->win.update_flag) return;
00265 
00266     if (current->win.pixmap) {
00267       XCopyArea(current->win.display, current->win.pixmap, current->win.window,
00268                 current->win.gc, 
00269                 0, 0, current->win.width, current->win.height, 0, 0);
00270       XFlush(current->win.display);
00271     }
00272 
00273     if (current->win.discard_flag)  return 1;
00274 
00275     if ( (newdata = get_newdata(current)) == (lux_data *)NULL )
00276       { fprintf(stderr,"Can't clear display -- not enough memory\n"); 
00277         return 0;}
00278 
00279     newdata->type = UPDATE_FOREGROUND;
00280 
00281     return 1;
00282 }
00283 
00284 lux_reupdate_fg(win)
00285 Window win;
00286 {
00287     register lux_wins *current;
00288 
00289     current = get_currentwin(win);
00290 
00291     if (current->win.pixmap) {
00292       XCopyArea(current->win.display, current->win.pixmap, current->win.window,
00293                 current->win.gc, 
00294                 0, 0, current->win.width, current->win.height, 0, 0);
00295       XFlush(current->win.display);
00296     }
00297 
00298     return 1;
00299 }
00300 
00301 lux_setup_region(win, fxorg, fyorg, fxsize, fysize)
00302 Window win;
00303 float  fxorg, fyorg, fxsize, fysize;
00304 {
00305     register float    *ptr;
00306     register lux_wins *current;
00307     register lux_data *newdata;
00308 
00309     current = get_currentwin(win);
00310 
00311     current->win.fxorg  = fxorg;
00312     current->win.fyorg  = fyorg;
00313     current->win.fxsize = fxsize;
00314     current->win.fysize = fysize;
00315 
00316     current->win.xsize = (int)(fxsize*current->win.user_width/10.0);
00317     current->win.ysize = (int)(fysize*current->win.user_height/10.0);
00318     current->win.xorg  = (int)(current->win.fxorg*current->win.user_width/10.0);
00319     current->win.yorg  = (int)((10.0-current->win.fyorg)*
00320                                current->win.user_height/10.0)-
00321                                current->win.ysize;
00322 
00323     if (current->win.discard_flag)  return 1;
00324 
00325     if ( (newdata = get_newdata(current)) == (lux_data *)NULL )
00326       { fprintf(stderr,"Can't set up coord -- not enough memory\n"); 
00327         return 0;}
00328 
00329     newdata->type = SETUP_REGION;
00330     ptr = newdata->data.f = (float *)malloc(4*sizeof(float));
00331     
00332     if (ptr == (float *)NULL) {
00333       fprintf(stderr,"Can't set up coord -- not enough memory\n"); 
00334       fprintf(stderr,"Error may occur!!\n");
00335       newdata->type = NOOP;
00336       return 0;
00337     }
00338 
00339     ptr[0] = fxorg;
00340     ptr[1] = fyorg;
00341     ptr[2] = fxsize;
00342     ptr[3] = fysize;
00343     return 1;
00344 }
00345 
00346 lux_resetup_region(win)
00347 Window win;
00348 {
00349     register float *ptr;
00350     register lux_wins *current;
00351   
00352     current = get_currentwin(win);
00353 
00354     ptr = (current->win.currentdata)->data.f;
00355 
00356     current->win.fxorg = ptr[0];
00357     current->win.fyorg = ptr[1];
00358     current->win.fxsize = ptr[2];
00359     current->win.fysize = ptr[3];
00360 
00361     current->win.xsize = (int)(current->win.fxsize*
00362                                current->win.user_width/10.0+0.5);
00363     current->win.ysize = (int)(current->win.fysize*
00364                                current->win.user_height/10.0+0.5);
00365     current->win.xorg  = (int)(current->win.fxorg*
00366                                current->win.user_width/10.0+0.5);
00367     current->win.yorg  = (int)((10.0-current->win.fyorg)*
00368                                current->win.user_height/10.0+0.5)-
00369                                current->win.ysize;
00370 
00371 }
00372 
00373 lux_setup_axis(win, xmin, xmax, ymin, ymax)
00374 Window win;
00375 float  xmin, xmax, ymin, ymax;
00376 {
00377     register float    *ptr;
00378     register lux_wins *current;
00379     register lux_data *newdata;
00380 
00381     current = get_currentwin(win);
00382 
00383     current->win.xmin = xmin;
00384     current->win.xmax = xmax;
00385     current->win.ymin = ymin;
00386     current->win.ymax = ymax;
00387 
00388     if (current->win.lnx == 0) 
00389       current->win.xfactor = (float)current->win.xsize/(xmax-xmin);
00390     else {
00391         if ( xmin <= 0.0 || xmax <= 0.0) {
00392             fprintf(stderr,
00393                     "For log axis, the limit must be greater than zero\n");
00394             return 0;
00395         }
00396         current->win.xfactor = (float)current->win.xsize
00397                                     /(log10(xmax)-log10(xmin));
00398     }
00399     if (current->win.lny == 0) 
00400         current->win.yfactor = (float)current->win.ysize/(ymax-ymin);
00401     else {
00402         if ( ymin <= 0.0 || ymax <= 0.0) {
00403             fprintf(stderr,
00404                     "For log axis, the limit must be greater than zero\n");
00405             return 0;
00406         }
00407         current->win.yfactor = (float)current->win.ysize
00408                                     /(log10(ymax)-log10(ymin));
00409     }
00410 
00411     if (current->win.discard_flag) return 1;
00412 
00413     if ( (newdata = get_newdata(current)) == (lux_data *)NULL ) {
00414         fprintf(stderr, "Can't set up axis -- not enough memory\n"); 
00415         return 0;
00416     }
00417 
00418     newdata->type = SETUP_AXIS;
00419 
00420     ptr = newdata->data.f = (float *)malloc(4*sizeof(float));
00421 
00422     if ( newdata->data.f == (float *)NULL) {
00423         fprintf(stderr,"Can't set up axis -- not enough memory\n"); 
00424         fprintf(stderr,"Error may occur!!\n"); 
00425         newdata->type = NOOP;
00426         return 0;
00427     }
00428     ptr[0] = xmin;
00429     ptr[1] = xmax;
00430     ptr[2] = ymin;
00431     ptr[3] = ymax;
00432 
00433     return 1;
00434 }
00435 
00436 lux_resetup_axis(win)
00437 Window win;
00438 {
00439     register float *ptr;
00440     register lux_wins *current;
00441 
00442     current = get_currentwin(win);
00443 
00444     ptr = (current->win.currentdata)->data.f;
00445 
00446     current->win.xmin = ptr[0];
00447     current->win.xmax = ptr[1];
00448     current->win.ymin = ptr[2];
00449     current->win.ymax = ptr[3];
00450 
00451     if (current->win.lnx == 0) 
00452         current->win.xfactor = (float)current->win.xsize/(ptr[1]-ptr[0]);
00453     else 
00454         current->win.xfactor = (float)current->win.xsize
00455                                     /(log10(ptr[1])-log10(ptr[0]));
00456     if (current->win.lny == 0) 
00457         current->win.yfactor = (float)current->win.ysize/(ptr[3]-ptr[2]);
00458     else 
00459         current->win.yfactor = (float)current->win.ysize
00460                                     /(log10(ptr[3])-log10(ptr[2]));
00461 }
00462 
00463 lux_setup_axis_style(win, lnx, lny)
00464 Window win;
00465 int lnx, lny;
00466 {
00467     register lux_wins *current;
00468     register lux_data *newdata;
00469     int               *ptr;
00470 
00471     current = get_currentwin(win);
00472 
00473     current->win.lnx = lnx;
00474     current->win.lny = lny;
00475 
00476     if (current->win.lnx == 0) 
00477         current->win.xfactor=(float)current->win.xsize
00478                                   /(current->win.xmax-current->win.xmin);
00479     else {
00480         if ( current->win.xmin <= 0.0 || current->win.xmax <= 0.0) {
00481             fprintf(stderr,
00482                     "For log axis, the limit must be greater than zero\n");
00483             return 0;
00484         }
00485         current->win.xfactor=(float)current->win.xsize
00486                     /(log10(current->win.xmax)-log10(current->win.xmin));
00487     } 
00488     if (current->win.lny == 0) 
00489         current->win.yfactor=(float)current->win.ysize
00490                     /(current->win.ymax-current->win.ymin);      
00491     else {
00492         if ( current->win.ymin <= 0.0 || current->win.ymax <= 0.0) {
00493             fprintf(stderr,
00494                     "For log axis, the limit must be greater than zero\n");
00495             return 0;
00496         }
00497         current->win.yfactor=(float)current->win.ysize
00498                     /(log10(current->win.ymax)-log10(current->win.ymin));
00499     }
00500 
00501     if (current->win.discard_flag)  return 1;
00502 
00503     if ( (newdata = get_newdata(current)) == (lux_data *)NULL ) {
00504         fprintf(stderr,"Can't set up axis style -- not enough memory\n"); 
00505         return 0;
00506     }
00507 
00508     newdata->type = SETUP_AXIS_STYLE;
00509 
00510     ptr = newdata->data.i = (int *)malloc(2*sizeof(int));
00511 
00512     if ( newdata->data.i == (int *)NULL) {
00513         fprintf(stderr,"Can't set up axis style -- not enough memory\n"); 
00514         fprintf(stderr,"Error may occur!!\n"); 
00515         newdata->type = NOOP;
00516         return 0;
00517     }
00518     ptr[0] = lnx;
00519     ptr[1] = lny;
00520 
00521     return 1;     
00522 }
00523 
00524 lux_resetup_axis_style(win)
00525 Window win;
00526 {
00527     register int *ptr;
00528     register lux_wins *current;
00529 
00530     current = get_currentwin(win);
00531 
00532     ptr = (current->win.currentdata)->data.i;
00533 
00534     current->win.lnx = ptr[0];
00535     current->win.lny = ptr[1];
00536 
00537     if (current->win.lnx == 0)
00538         current->win.xfactor=(float)current->win.xsize
00539                           /(current->win.xmax-current->win.xmin);
00540     else
00541         current->win.xfactor=(float)current->win.xsize
00542                     /(log10(current->win.xmax)-log10(current->win.xmin));
00543     if (current->win.lny == 0)
00544         current->win.yfactor=(float)current->win.ysize
00545                     /(current->win.ymax-current->win.ymin);      
00546     else
00547         current->win.yfactor=(float)current->win.ysize
00548                     /(log10(current->win.ymax)-log10(current->win.ymin));
00549 }
00550 
00551 lux_draw_line(win, x1, y1, x2, y2)
00552 Window win;
00553 int x1, y1, x2, y2;
00554 {
00555     register lux_wins *current;
00556     register lux_data *newdata;
00557     register int      *ptr;
00558     int xx1,yy1,xx2,yy2;
00559 
00560     current = get_currentwin(win);
00561 
00562     xx1 = (int)(x1*current->win.xresizefactor+0.5);
00563     yy1 = (int)(y1*current->win.yresizefactor+0.5);
00564     xx2 = (int)(x2*current->win.xresizefactor+0.5);
00565     yy2 = (int)(y2*current->win.yresizefactor+0.5);
00566 
00567     if (current->win.pixmap) 
00568         XDrawLine(current->win.display,current->win.pixmap,
00569                   current->win.gc,xx1,yy1,xx2,yy2);
00570     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) {
00571         XDrawLine(current->win.display,current->win.window,
00572                   current->win.gc,xx1,yy1,xx2,yy2);
00573         XFlush(current->win.display);
00574     }
00575 
00576     if (current->win.discard_flag)  return 1;
00577 
00578     if ( (newdata = get_newdata(current)) == (lux_data *)NULL ) {
00579         fprintf(stderr,"Can't draw line -- not enough memory\n"); 
00580         return 0;
00581     }
00582 
00583     newdata->type = DRAW_LINE;
00584     ptr = newdata->data.i = (int *)malloc(4*sizeof(int));
00585 
00586     if (ptr == (int *)NULL) {
00587         fprintf(stderr,"Can't draw line -- not enough memory\n"); 
00588         fprintf(stderr,"Error may occur!!\n"); 
00589         newdata->type = NOOP;
00590         return 0;
00591     }
00592 
00593     ptr[0] = x1;
00594     ptr[1] = y1;
00595     ptr[2] = x2;
00596     ptr[3] = y2;
00597 
00598     return 1;
00599 }
00600 
00601 lux_redraw_line(win)
00602 Window win;
00603 {
00604     register int *ptr;
00605     register lux_wins *current;
00606     int      x1, x2, y1, y2;
00607   
00608     current = get_currentwin(win);
00609 
00610     ptr = (current->win.currentdata)->data.i;
00611     x1  = ptr[0]*current->win.xresizefactor+0.5;
00612     y1  = ptr[1]*current->win.yresizefactor+0.5;
00613     x2  = ptr[2]*current->win.xresizefactor+0.5;
00614     y2  = ptr[3]*current->win.yresizefactor+0.5;
00615 
00616     if (current->win.pixmap) 
00617         XDrawLine(current->win.display, current->win.pixmap,
00618                   redrawgc, x1, y1, x2, y2);
00619    
00620     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) {
00621         XDrawLine(current->win.display,current->win.window,
00622                   redrawgc, x1, y1, x2, y2);
00623 
00624 /*      XFlush(current->win.display); */
00625 
00626     }
00627 }
00628 
00629 lux_convert_coords(win,fx,fy,x,y,n)
00630 Window   win;
00631 float   *fx,*fy;
00632 int     *x, *y;
00633 unsigned int n;
00634 {
00635     register unsigned i;
00636     register lux_wins *current;
00637     float    logxmin, logxmax, logymin, logymax;
00638 
00639     current = get_currentwin(win);
00640 
00641     if (current->win.lnx != 0) {
00642         logxmin = log10(current->win.xmin);
00643         logxmax = log10(current->win.xmax);
00644     }
00645     if (current->win.lny != 0) {
00646         logymin = log10(current->win.ymin);
00647         logymax = log10(current->win.ymax);
00648     }
00649 
00650     if (fx == fy)  /* x == y too */
00651       for(i=0;i<2*n;i+=2) {
00652           if ( current->win.lnx == 0)
00653               x[i] = (int)(((fx[i] - current->win.xmin)*current->win.xfactor +
00654                           current->win.xorg)*current->win.xresizefactor + 0.5);
00655           else 
00656               x[i] = (int)(((log10(fx[i]) - logxmin)*current->win.xfactor +
00657                           current->win.xorg)*current->win.xresizefactor + 0.5);
00658           if ( current->win.lny == 0)
00659               y[i+1] = (int)((current->win.ysize - (fy[i+1]-current->win.ymin)*
00660                             current->win.yfactor + current->win.yorg)*
00661                            current->win.yresizefactor + 0.5);
00662           else
00663               y[i+1] = (int)((current->win.ysize - (log10(fy[i+1])-logymin)*
00664                             current->win.yfactor + current->win.yorg)*
00665                             current->win.yresizefactor + 0.5);
00666       }  
00667     else if (x == y) 
00668       for(i=0;i<n;i++) {
00669           if ( current->win.lnx == 0)
00670             x[i*2] = (int)(((fx[i] - current->win.xmin)*current->win.xfactor +
00671                             current->win.xorg)*current->win.xresizefactor
00672                                                                         + 0.5);
00673           else 
00674             x[i*2] = (int)(((log10(fx[i]) - logxmin)*current->win.xfactor +
00675                             current->win.xorg)*current->win.xresizefactor
00676                                                                         + 0.5);
00677           if ( current->win.lny == 0)
00678             x[i*2+1] = (int)((current->win.ysize - (fy[i]-current->win.ymin)*
00679                               current->win.yfactor + current->win.yorg)*
00680                              current->win.yresizefactor + 0.5);
00681           else
00682             x[i*2+1] = (int)((current->win.ysize - (log10(fy[i])-logymin)*
00683                               current->win.yfactor + current->win.yorg)*
00684                              current->win.yresizefactor + 0.5);
00685         
00686       }        
00687     else 
00688       for(i=0;i<n;i++) {
00689           if ( current->win.lnx == 0)
00690             x[i] = (int)(((fx[i]-current->win.xmin)*current->win.xfactor+
00691                           current->win.xorg)*current->win.xresizefactor+0.5);
00692           else 
00693             x[i] = (int)(((log10(fx[i])-logxmin)*current->win.xfactor+
00694                           current->win.xorg)*current->win.xresizefactor+0.5);
00695           if ( current->win.lny == 0)
00696             y[i] = (int)((current->win.ysize-(fy[i]-current->win.ymin)*
00697                           current->win.yfactor+current->win.yorg)*
00698                          current->win.yresizefactor+0.5);
00699           else
00700             y[i] = (int)((current->win.ysize-(log10(fy[i])-logymin)*
00701                           current->win.yfactor+current->win.yorg)*
00702                          current->win.yresizefactor+0.5);
00703       }
00704     
00705 }
00706 
00707 lux_convert_coord(win,fx,fy,x,y)
00708 Window   win;
00709 float    fx,fy;
00710 int     *x, *y;
00711 {
00712     register lux_wins *current;
00713     float    logxmin, logxmax, logymin, logymax;
00714 
00715     current = get_currentwin(win);
00716 
00717     if (current->win.lnx != 0) {
00718       logxmin = log10(current->win.xmin);
00719       logxmax = log10(current->win.xmax);
00720     }
00721     if (current->win.lny != 0) {
00722       logymin = log10(current->win.ymin);
00723       logymax = log10(current->win.ymax);
00724     }
00725 
00726     if ( current->win.lnx == 0)
00727       *x = (int)(((fx-current->win.xmin)*current->win.xfactor+
00728                   current->win.xorg)*current->win.xresizefactor+0.5);
00729     else
00730       *x = (int)(((log10(fx)-logxmin)*current->win.xfactor+
00731                   current->win.xorg)*current->win.xresizefactor+0.5);
00732     if ( current->win.lny == 0)
00733       *y = (int)((current->win.ysize-(fy-current->win.ymin)*
00734                   current->win.yfactor+current->win.yorg)*
00735                  current->win.yresizefactor+0.5);
00736     else
00737       *y = (int)((current->win.ysize-(log10(fy)-logymin)*
00738                   current->win.yfactor+current->win.yorg)*
00739                  current->win.yresizefactor+0.5);
00740       
00741 }      
00742 
00743 lux_reconvert_coord(win,ix,iy,fx,fy)
00744 Window   win;
00745 int      ix, iy;
00746 float    *fx,*fy;
00747 {
00748     register long i;
00749     register lux_wins *current;
00750 
00751     current = get_currentwin(win);
00752 /*
00753     *x = (int)(((fx-current->win.xmin)*current->win.xfactor+
00754                  current->win.xorg)*current->win.xresizefactor+0.5);
00755     *y = (int)((current->win.ysize-(fy-current->win.ymin)*
00756                 current->win.yfactor+current->win.yorg)*
00757                 current->win.yresizefactor+0.5);
00758 */
00759     if ( current->win.lnx == 0)
00760       *fx = (((float)ix)/current->win.xresizefactor-current->win.xorg)/
00761               current->win.xfactor+current->win.xmin;
00762     else
00763       *fx = pow(10.0,((((float)ix)/current->win.xresizefactor
00764                        -current->win.xorg)/
00765               current->win.xfactor+log10(current->win.xmin)));
00766     if ( current->win.lny == 0)
00767       *fy = (current->win.ysize-((float)iy)/current->win.yresizefactor+
00768              current->win.yorg)/current->win.yfactor+current->win.ymin;
00769     else
00770       *fy = pow(10.0,((current->win.ysize-((float)iy)
00771                        /current->win.yresizefactor+
00772                        current->win.yorg)/current->win.yfactor
00773                       +log10(current->win.ymin)));
00774         
00775 }
00776       
00777 lux_reconvert_rcoord(win,ix,iy,fx,fy)/*input coord are relative to the old one*/
00778 Window   win;
00779 int      ix, iy;
00780 float    *fx,*fy;
00781 {
00782     register long i;
00783     register lux_wins *current;
00784 
00785     current = get_currentwin(win);
00786 
00787     if ( current->win.lnx == 0)
00788       *fx = (((float)ix)-current->win.xorg)/
00789                   current->win.xfactor+current->win.xmin;
00790     else
00791       *fx = pow(10.0,((((float)ix)-current->win.xorg)/
00792                   current->win.xfactor+log10(current->win.xmin)));
00793     if ( current->win.lny == 0)
00794       *fy = (current->win.ysize-((float)iy)+current->win.yorg)/
00795             current->win.yfactor+current->win.ymin;
00796     else
00797       *fy = pow(10.0,((current->win.ysize-((float)iy)+current->win.yorg)/
00798             current->win.yfactor+log10(current->win.ymin)));
00799 
00800 }      
00801 
00802 
00803 lux_draw_linef(win, x1, y1, x2, y2)
00804 Window win;
00805 float x1, y1, x2, y2;
00806 {
00807     register lux_wins *current;
00808     register lux_data *newdata;
00809     register float    *ptr;
00810     int      xx1,yy1,xx2,yy2;
00811 
00812     current = get_currentwin(win);
00813 
00814     lux_convert_coord(win,x1,y1,&xx1,&yy1);
00815     lux_convert_coord(win,x2,y2,&xx2,&yy2);
00816 
00817     if (current->win.pixmap) 
00818       XDrawLine(current->win.display,current->win.pixmap,
00819                 current->win.gc,xx1,yy1,xx2,yy2);
00820     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) {
00821       XDrawLine(current->win.display,current->win.window,
00822                 current->win.gc,xx1,yy1,xx2,yy2);
00823       XFlush(current->win.display);
00824     }
00825 
00826     if (current->win.discard_flag)  return 1;
00827 
00828     if ( (newdata = get_newdata(current)) == (lux_data *)NULL )
00829       { fprintf(stderr,"Can't draw line -- not enough memory\n"); 
00830         return 0;}
00831 
00832     newdata->type = DRAW_LINE_F;
00833     ptr = newdata->data.f = (float *)malloc(4*sizeof(float));
00834 
00835     if (ptr == (float *)NULL) {
00836       fprintf(stderr,"Can't draw line -- not enough memory\n"); 
00837       fprintf(stderr,"Error may occur!!\n"); 
00838       newdata->type = NOOP;
00839       return 0;
00840     }
00841 
00842 
00843     ptr[0] = x1;
00844     ptr[1] = y1;
00845     ptr[2] = x2;
00846     ptr[3] = y2;
00847 
00848     return 1;
00849 }
00850 
00851 lux_redraw_linef(win)
00852 Window win;
00853 {
00854     register float *ptr;
00855     register lux_wins *current;
00856     int      x1, x2, y1, y2;
00857     int      data[4];
00858   
00859     current = get_currentwin(win);
00860 
00861     ptr = (current->win.currentdata)->data.f;
00862 
00863     lux_convert_coords(win,ptr,ptr,data,data,2);
00864 
00865     if (current->win.pixmap) 
00866       XDrawLine(current->win.display, current->win.pixmap,
00867                 redrawgc, data[0], data[1], data[2], data[3]);
00868    
00869     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL))  {
00870       XDrawLine(current->win.display,current->win.window,
00871                 redrawgc, data[0], data[1], data[2], data[3]);
00872  /*     XFlush(current->win.display);*/
00873     }
00874 
00875 }
00876 
00877 lux_draw_pointf(win, x1, y1)
00878 Window win;
00879 float x1, y1;
00880 {
00881     register lux_wins *current;
00882     register lux_data *newdata;
00883     register float    *ptr;
00884     int      xx1,yy1;
00885 
00886     current = get_currentwin(win);
00887 
00888     lux_convert_coord(win,x1,y1,&xx1,&yy1);
00889 
00890     if (current->win.pixmap) 
00891       XDrawPoint(current->win.display,current->win.pixmap,
00892                 current->win.gc,xx1,yy1);
00893     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) {
00894       XDrawPoint(current->win.display,current->win.window,
00895                  current->win.gc,xx1,yy1);
00896       XFlush(current->win.display);
00897     }
00898 
00899     if (current->win.discard_flag)  return 1;
00900 
00901     if ( (newdata = get_newdata(current)) == (lux_data *)NULL )
00902       { fprintf(stderr,"Can't draw line -- not enough memory\n"); 
00903         return 0;}
00904 
00905     newdata->type = DRAW_POINT_F;
00906     ptr = newdata->data.f = (float *)malloc(4*sizeof(float));
00907 
00908     if (ptr == (float *)NULL) {
00909       fprintf(stderr,"Can't draw line -- not enough memory\n"); 
00910       fprintf(stderr,"Error may occur!!\n"); 
00911       newdata->type = NOOP;
00912       return 0;
00913     }
00914 
00915     ptr[0] = x1;
00916     ptr[1] = y1;
00917     return 1;
00918 }
00919 
00920 lux_redraw_pointf(win)
00921 Window win;
00922 {
00923     register float *ptr;
00924     register lux_wins *current;
00925     int      x1, x2, y1, y2;
00926     int      data[2];
00927   
00928     current = get_currentwin(win);
00929 
00930     ptr = (current->win.currentdata)->data.f;
00931 
00932     lux_convert_coords(win,ptr,ptr,data,data,1);
00933 
00934     if (current->win.pixmap) 
00935       XDrawPoint(current->win.display, current->win.pixmap,
00936                 redrawgc, data[0], data[1]);
00937    
00938     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL))  {
00939       XDrawPoint(current->win.display,current->win.window,
00940                 redrawgc, data[0], data[1]);
00941  /*     XFlush(current->win.display);*/
00942     }
00943 
00944 }
00945 
00946 lux_set_linewidth(win,width)
00947 Window win;
00948 unsigned int width;
00949 {
00950     register lux_wins  *current;
00951     register lux_data  *newdata;
00952     XGCValues  values;
00953 
00954     current = get_currentwin(win);
00955 
00956     XGetGCValues(current->win.display, current->win.gc, 
00957                  GCLineStyle | GCCapStyle | GCJoinStyle,
00958                  &values);
00959 
00960     XSetLineAttributes(current->win.display, current->win.gc, width, 
00961                       values.line_style,values.cap_style,values.join_style);
00962 
00963     if (current->win.discard_flag)  return 1;
00964 
00965     if ( (newdata = get_newdata(current)) == (lux_data *)NULL )
00966       { fprintf(stderr,"Can't set line width -- not enough memory\n"); 
00967         return 0;}
00968 
00969     newdata->type = SET_LINE_WIDTH;
00970     newdata->data.u = (unsigned int *)malloc(sizeof(int));
00971     if ( newdata->data.u == (unsigned int *)NULL) {
00972       fprintf(stderr,"Can't setlinewidth -- not enough memory\n"); 
00973       fprintf(stderr,"Error may occur!!\n"); 
00974       newdata->type = NOOP;
00975       return 0;
00976     }
00977 
00978     newdata->data.u[0] = width;
00979     return 1;
00980 }
00981 
00982 lux_reset_linewidth(win)
00983 Window win;
00984 {
00985     register lux_wins  *current;
00986     unsigned int width;
00987     XGCValues  values;
00988 
00989     current = get_currentwin(win);
00990 
00991     width = (current->win.currentdata)->data.u[0];
00992 
00993     XGetGCValues(current->win.display, redrawgc, 
00994                  GCLineStyle | GCCapStyle | GCJoinStyle,
00995                  &values);
00996 
00997     XSetLineAttributes(current->win.display, redrawgc, width, 
00998                       values.line_style,values.cap_style,values.join_style);
00999 }
01000 
01001 #define MAX_LINE_STYLE           11 
01002 
01003 #define SHORT_DASHED_LIST_LENGTH 2
01004 #define LONG_DASHED_LIST_LENGTH  2
01005 #define DOTTED_LIST_LENGTH       2
01006 #define DOT_DASHED_LIST_LENGTH   4
01007 #define ODD_DASHED_LIST_LENGTH   3
01008 
01009 static int dash_list_length[] = {
01010     SHORT_DASHED_LIST_LENGTH,
01011     LONG_DASHED_LIST_LENGTH,
01012     DOTTED_LIST_LENGTH,
01013     DOT_DASHED_LIST_LENGTH,
01014     ODD_DASHED_LIST_LENGTH
01015 };
01016 
01017 
01018 /* must be at least one element in each list */
01019 
01020 static char short_dashed[SHORT_DASHED_LIST_LENGTH] = {4, 4};
01021 static char long_dashed[LONG_DASHED_LIST_LENGTH] = {4, 7};
01022 static char dotted[DOTTED_LIST_LENGTH] = {3, 1};
01023 static char dot_dashed[DOT_DASHED_LIST_LENGTH] = {3, 4, 3, 1};
01024 static char odd_dashed[ODD_DASHED_LIST_LENGTH] = {1,2,3};
01025 
01026 static char *dash_list[] = {
01027     short_dashed,
01028     long_dashed,
01029     dotted,
01030     dot_dashed,
01031     odd_dashed,
01032 };
01033 
01034 static int dash_offset = 0;
01035 
01036 lux_set_linestyle(win,style)
01037 Window win;
01038 int    style; /* 0 Solid line, 1-5 OnOffDash, 6-10 DoubleDash(with background */
01039 {
01040     register lux_wins  *current;
01041     register lux_data  *newdata;
01042     XGCValues  values;
01043     int      line_style;
01044 
01045     current = get_currentwin(win);
01046 
01047     XGetGCValues(current->win.display, current->win.gc, 
01048                  GCLineWidth | GCCapStyle | GCJoinStyle,
01049                  &values);
01050 
01051     if (style>=MAX_LINE_STYLE) style = (style>0)?style%(MAX_LINE_STYLE):(-style)%(MAX_LINE_STYLE);
01052 
01053     line_style = style;
01054 
01055     if (style>5) {
01056         XSetDashes(current->win.display, current->win.gc, dash_offset, 
01057                    dash_list[style-6], dash_list_length[style-6]);
01058         style = 2; /* Set to LineDoubleDash (With background color)*/
01059     } else if (style>0) {
01060         XSetDashes(current->win.display, current->win.gc, dash_offset, 
01061                    dash_list[style-1], dash_list_length[style-1]);
01062         style = 1; /* Set to LineOnOffDash */
01063     }   
01064       
01065 
01066     XSetLineAttributes(current->win.display,current->win.gc, values.line_width, 
01067                        style,values.cap_style,values.join_style);
01068 
01069     if (current->win.discard_flag)  return 1;
01070 
01071     if ( (newdata = get_newdata(current)) == (lux_data *)NULL )
01072       { fprintf(stderr,"Can't set line style -- not enough memory\n"); 
01073         return 0;}
01074 
01075     newdata->type = SET_LINE_STYLE;
01076     newdata->data.u = (unsigned int *)malloc(sizeof(int));
01077     if ( newdata->data.u == (unsigned int *)NULL) {
01078       fprintf(stderr,"Can't setlinestyle -- not enough memory\n"); 
01079       fprintf(stderr,"Error may occur!!\n"); 
01080       newdata->type = NOOP;
01081       return 0;
01082     }
01083 
01084     newdata->data.i[0] = line_style;  /* Save the old value */
01085     return 1;
01086 }
01087 
01088 lux_reset_linestyle(win)
01089 Window win;
01090 {
01091     register lux_wins  *current;
01092     int      style;
01093     XGCValues  values;
01094 
01095     current = get_currentwin(win);
01096 
01097     style = (current->win.currentdata)->data.i[0];
01098 
01099     XGetGCValues(current->win.display, redrawgc, 
01100                  GCLineWidth | GCCapStyle | GCJoinStyle,
01101                  &values);
01102 
01103     if (style>5) {
01104         XSetDashes(current->win.display, redrawgc, dash_offset, 
01105                    dash_list[style-6], dash_list_length[style-6]);
01106         style = 2; /* Set to LineDoubleDash (With background color)*/
01107     } else if (style>0) {
01108         XSetDashes(current->win.display, redrawgc, dash_offset, 
01109                    dash_list[style-1], dash_list_length[style-1]);
01110         style = 1; /* Set to LineOnOffDash */
01111     }   
01112       
01113     XSetLineAttributes(current->win.display, redrawgc, values.line_width, 
01114                        style,values.cap_style,values.join_style);
01115 }
01116 
01117 lux_string_dimensions(char* s, int* length, int* height) /* Results in PIXELS */
01118 {
01119     *length = XTextWidth(font_info, s, strlen(s));
01120     *height = font_info->ascent + font_info->descent;
01121 }
01122 
01123 
01124 
01125 static int buffer_gfx = 1;
01126 
01127 void lux_set_nobuffer()
01128 {
01129     /* Suppress buffering for *next* lux_draw*string call.
01130        Flag buffer_gfx is ALWAYS reset to 1 in lux_draw*string. */
01131 
01132     buffer_gfx = 0;
01133 }
01134 
01135 
01136 
01137 lux_draw_string(win, fx, fy, fh, s, position)
01138 Window  win;
01139 float   fx,fy,fh;     /* x,y position, h is offset in units of font height */ 
01140 char   *s, position;  /* -1 -> left, 0 -> center, 1->right */
01141 {
01142     int ix,iy;
01143     lux_wins *current;
01144     lux_data *newdata;
01145     char    *string;
01146     int      stringwidth, slength;
01147 
01148     current = get_currentwin(win);
01149     
01150     lux_convert_coord(win, fx, fy, &ix, &iy);
01151 
01152     slength = strlen(s);    
01153     stringwidth = XTextWidth(font_info, s, slength);
01154 
01155     if (position == 0) ix = ix - (stringwidth+1)/2;
01156     else if (position == 1) ix = ix-stringwidth;
01157 
01158     iy -= (int)(0.5 + fh * (font_info->ascent+font_info->descent)); 
01159 
01160     if (current->win.pixmap) 
01161       XDrawString(current->win.display, current->win.pixmap, current->win.gc,
01162                   ix, iy, s, slength);
01163     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) {
01164         XDrawString(current->win.display, current->win.window, current->win.gc,
01165                     ix, iy, s, slength);
01166         XFlush(current->win.display);
01167     }
01168 
01169     if (current->win.discard_flag)  return 1;
01170 
01171     if ( (newdata = get_newdata(current)) == (lux_data *)NULL ) {
01172         fprintf(stderr,"Can't set line width -- not enough memory\n"); 
01173         return 0;
01174     }
01175 
01176     if (buffer_gfx) {
01177 
01178         newdata->type = DRAW_STRING;
01179         newdata->data.f=
01180             (float *)malloc((slength+2)*sizeof(char)+3*sizeof(float));
01181 
01182         if ( newdata->data.f == (float *)NULL) {
01183             fprintf(stderr,"Can't drawstring -- not enough memory\n"); 
01184             fprintf(stderr,"Error may occur!!\n"); 
01185             newdata->type = NOOP;
01186             return 0;
01187         }
01188 
01189         string = &newdata->data.b[3*sizeof(float)];
01190 
01191         newdata->data.f[0] = fx;
01192         newdata->data.f[1] = fy;
01193         newdata->data.f[2] = fh;
01194         string[0] = position;
01195         strcpy(&string[1],s);
01196     }
01197 
01198     buffer_gfx = 1;
01199     return 1;
01200 } 
01201 
01202 lux_redraw_string(win)
01203 Window  win;
01204 {
01205     int ix,iy;
01206     char *string;
01207     register lux_wins *current;
01208     register lux_data *newdata;
01209     int      stringwidth, slength;
01210     char     position;
01211 
01212     current = get_currentwin(win);
01213 
01214     lux_convert_coord(win, (current->win.currentdata)->data.f[0],
01215                       (current->win.currentdata)->data.f[1],&ix, &iy);
01216 
01217     string = &((current->win.currentdata)->data.b[3*sizeof(float)]);
01218 
01219     slength = strlen(&string[1]);    
01220     stringwidth = XTextWidth(font_info, &string[1], slength);
01221 
01222     position = string[0];
01223     if (position == 0) ix = ix - (stringwidth+1)/2;
01224     else if (position == 1) ix = ix-stringwidth;
01225 
01226     iy = iy - (int)(0.5+(current->win.currentdata)->data.f[2]
01227                         *(font_info->ascent+font_info->descent));
01228 
01229     if (current->win.pixmap) 
01230       XDrawString(current->win.display, current->win.pixmap, redrawgc,
01231                   ix, iy, &string[1], slength);
01232     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) 
01233       XDrawString(current->win.display, current->win.window, redrawgc,
01234                   ix, iy, &string[1], slength);
01235 
01236 /*      XFlush(current->win.display); */
01237     
01238 }
01239 
01240 lux_draw_image_string(win, fx, fy, fh, s, position)
01241 Window  win;
01242 float   fx,fy,fh;     /* x,y position, h is times of font height */ 
01243 char   *s, position;  /* -1 -> left, 0 -> center, 1->right */
01244 {
01245     int ix,iy;
01246     lux_wins *current;
01247     lux_data *newdata;
01248     char     *string;
01249     int      stringwidth, slength;
01250 
01251     current = get_currentwin(win);
01252 
01253     lux_convert_coord(win, fx, fy, &ix, &iy);
01254 
01255     slength = strlen(s);    
01256     stringwidth = XTextWidth(font_info, s, slength);
01257 
01258     if (position == 0) ix = ix - (stringwidth+1)/2;
01259     else if (position == 1) ix = ix-stringwidth;
01260 
01261     iy = iy - (int)(0.5+fh*(font_info->ascent+font_info->descent));
01262 
01263     if (current->win.pixmap) 
01264       XDrawImageString(current->win.display, current->win.pixmap, 
01265                        current->win.gc, ix, iy, s, slength);
01266     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) {
01267       XDrawImageString(current->win.display, current->win.window, 
01268                        current->win.gc, ix, iy, s, slength);
01269       XFlush(current->win.display);
01270     }
01271 
01272     if (current->win.discard_flag)
01273         return 1;
01274 
01275     if (buffer_gfx) {
01276 
01277         /* Buffer graphics operations for replay. */
01278 
01279         newdata = get_newdata(current);
01280 
01281         if ( newdata == (lux_data *)NULL ) {
01282             fprintf(stderr,"Can't set line width -- not enough memory\n"); 
01283             return 0;
01284         }
01285 
01286         newdata->type = DRAW_IMAGE_STRING;
01287         newdata->data.f=(float *)malloc((slength+2)*sizeof(char)
01288                                          + 3*sizeof(float));
01289 
01290         if ( newdata->data.f == (float *)NULL) {
01291             fprintf(stderr,"Can't draw image string -- not enough memory\n"); 
01292             fprintf(stderr,"Error may occur!!\n"); 
01293             newdata->type = NOOP;
01294             return 0;
01295         }
01296         string = &newdata->data.b[3*sizeof(float)];
01297 
01298         newdata->data.f[0] = fx;
01299         newdata->data.f[1] = fy;
01300         newdata->data.f[2] = fh;
01301         string[0] = position;
01302         strcpy(&string[1], s);
01303     }
01304 
01305     buffer_gfx = 1;
01306     return 1;
01307 } 
01308 
01309 lux_redraw_image_string(win)
01310 Window  win;
01311 {
01312     int ix,iy;
01313     char *string;
01314     register lux_wins *current;
01315     register lux_data *newdata;
01316     int      stringwidth, slength;
01317     char     position;
01318 
01319     current = get_currentwin(win);
01320 
01321     lux_convert_coord(win, (current->win.currentdata)->data.f[0],
01322                       (current->win.currentdata)->data.f[1],&ix, &iy);
01323 
01324     string = &((current->win.currentdata)->data.b[3*sizeof(float)]);
01325 
01326     slength = strlen(&string[1]);    
01327     stringwidth = XTextWidth(font_info, &string[1], slength);
01328 
01329     position = string[0];
01330     if (position == 0) ix = ix - (stringwidth+1)/2;
01331     else if (position == 1) ix = ix-stringwidth;
01332 
01333     iy = iy - (int)(0.5+(current->win.currentdata)->data.f[2]
01334                         *(font_info->ascent+font_info->descent));
01335 
01336     if (current->win.pixmap) 
01337       XDrawImageString(current->win.display, current->win.pixmap, redrawgc,
01338                   ix, iy, &string[1], slength);
01339     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) 
01340       XDrawImageString(current->win.display, current->win.window, redrawgc,
01341                   ix, iy, &string[1], slength);
01342 /*      XFlush(current->win.display);*/
01343     
01344 } 
01345 
01346 lux_draw_vstring(win, fx, fy, fh, s, position) 
01347 Window  win;
01348 float   fx,fy,fh;
01349 char   *s, position;  /* -1 -> left, 0 -> center, 1->right */
01350 {
01351     int ix,iy;
01352     register lux_wins *current;
01353     register lux_data *newdata;
01354     int      stringwidth, slength, charheight, height, *ptr;
01355     Pixmap   pixmap, pixmapwhite;
01356     XImage   *in, *out;
01357     register int i,j;
01358     unsigned long c;
01359     XGCValues value;
01360 
01361     current = get_currentwin(win);
01362     
01363     lux_convert_coord(current->win.window, fx, fy, &ix, &iy);
01364 
01365     slength = strlen(s);    
01366     stringwidth = XTextWidth(font_info, s, slength);
01367     charheight = font_info->ascent+font_info->descent;
01368     pixmap = XCreatePixmap(current->win.display, current->win.window, 
01369                   stringwidth, charheight,  current->win.window_depth);
01370     if (!pmpallocflag) {
01371       fprintf(stderr, "In draw_vstring, not enough video memory\n");
01372       pixmap=(Pixmap)NULL; pmpallocflag=1;return 0;}
01373 
01374     XDrawImageString(current->win.display, pixmap, current->win.gc,
01375                 0, font_info->ascent, s, slength);
01376 /*    XCopyArea(current->win.display, pixmap, current->win.pixmap, 
01377                 current->win.gc, 0, 0, stringwidth, charheight, 0, 0);
01378 */
01379     in = XGetImage(current->win.display, pixmap, 
01380                       0, 0, stringwidth, charheight, AllPlanes, XYPixmap);
01381 
01382 /*    XPutImage(current->win.display, current->win.pixmap, current->win.gc,
01383               in, 0, 0, 0, 0, stringwidth, charheight);*/ /* Looks Bad ! */
01384 
01385     XFreePixmap(current->win.display, pixmap);
01386 
01387     pixmap = XCreatePixmap(current->win.display, current->win.window, 
01388                            charheight, stringwidth, current->win.window_depth);
01389     if (!pmpallocflag) {
01390       fprintf(stderr, "In draw_vstring, not enough video memory\n");
01391       pixmap=(Pixmap)NULL; pmpallocflag=1;
01392       XDestroyImage(in);
01393       return 0;}
01394     pixmapwhite = XCreatePixmap(current->win.display, current->win.window, 
01395                            charheight, stringwidth, current->win.window_depth);
01396     if (!pmpallocflag) {
01397       fprintf(stderr, "In draw_vstring, not enough video memory\n");
01398       pixmap=(Pixmap)NULL; pmpallocflag=1;
01399       XFreePixmap(current->win.display,pixmap);
01400       XDestroyImage(in);
01401       return 0;}
01402 
01403     XGetGCValues(current->win.display, current->win.gc,
01404                  GCBackground | GCForeground, &value);
01405     c = value.foreground;
01406     XSetForeground(current->win.display, current->win.gc, value.background);
01407     lux_clear_pixmap(current->win.display, pixmapwhite, current->win.gc,
01408                      0, 0, charheight, stringwidth);
01409     XSetForeground(current->win.display, current->win.gc, c);
01410 
01411     out = XGetImage(current->win.display, pixmap, 
01412                       0, 0, charheight, stringwidth, AllPlanes, XYPixmap);
01413 
01414     for(i=0;i<stringwidth;i++)
01415       for(j=0;j<charheight;j++) 
01416         XPutPixel(out, j, stringwidth-i-1, XGetPixel(in, i, j));
01417 
01418     XPutImage(current->win.display, pixmap, current->win.gc,
01419               out, 0, 0, 0, 0, charheight, stringwidth); /* Looks Bad ! */
01420 
01421     if (position == (char)(-1)) {ix=ix-charheight;iy=iy-stringwidth;}
01422     else if (position == 0) {ix=ix-charheight;iy=iy-(stringwidth+1)/2;}
01423     else if (position == 1) {ix=ix-charheight;iy=iy-stringwidth;}
01424 
01425     ix = ix - (int)(0.5 + fh*charheight);
01426 
01427     XGetGCValues(current->win.display, current->win.gc, GCFunction, &value);
01428     XSetFunction(current->win.display, current->win.gc, GXxor);
01429     XCopyArea(current->win.display, pixmapwhite, pixmap, 
01430                 current->win.gc, 0, 0, charheight, stringwidth, 0, 0);
01431 
01432     if (current->win.pixmap) 
01433       XCopyArea(current->win.display, pixmapwhite, current->win.pixmap, 
01434                 current->win.gc, 0, 0, charheight, stringwidth, ix, iy);
01435     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) 
01436       XCopyArea(current->win.display, pixmapwhite, current->win.window, 
01437                 current->win.gc, 0, 0, charheight, stringwidth, ix, iy);
01438     XSetFunction(current->win.display, current->win.gc, GXor);
01439 
01440     if (current->win.pixmap) 
01441       XCopyArea(current->win.display, pixmap, current->win.pixmap, 
01442                 current->win.gc, 0, 0, charheight, stringwidth, ix, iy);
01443     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL))
01444       XCopyArea(current->win.display, pixmap, current->win.window, 
01445                 current->win.gc, 0, 0, charheight, stringwidth, ix, iy);
01446 
01447     XSetFunction(current->win.display, current->win.gc, GXxor);
01448 
01449     if (current->win.pixmap) 
01450       XCopyArea(current->win.display, pixmapwhite, current->win.pixmap, 
01451                 current->win.gc, 0, 0, charheight, stringwidth, ix, iy);
01452     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) {
01453       XCopyArea(current->win.display, pixmapwhite, current->win.window, 
01454                 current->win.gc, 0, 0, charheight, stringwidth, ix, iy);
01455       XFlush(current->win.display);
01456     }
01457 
01458     XSetFunction(current->win.display, current->win.gc, value.function);
01459 
01460     XFreePixmap(current->win.display, pixmap);
01461     XFreePixmap(current->win.display, pixmapwhite);
01462     XDestroyImage(in);
01463 
01464     if (current->win.discard_flag)  {XDestroyImage(out);return 1;}
01465 
01466     if (buffer_gfx) {
01467 
01468         if ( (newdata = get_newdata(current)) == (lux_data *)NULL ) {
01469             fprintf(stderr,"Can't draw_vstring -- not enough memory\n"); 
01470             return 0;
01471         }
01472 
01473         newdata->type = DRAW_VSTRING;
01474         newdata->data.b = (char *)malloc(3*sizeof(float) + 2*sizeof(int)
01475                                          + sizeof(XImage*)+1);
01476 
01477         if (newdata->data.b == (char *)NULL) {
01478             fprintf(stderr,"Can't draw_vstring -- not enough memory\n"); 
01479             fprintf(stderr,"Error may occur!!\n"); 
01480             newdata->type = NOOP;
01481             return 0;
01482         }
01483 
01484         newdata->data.f[0] = fx;
01485         newdata->data.f[1] = fy;
01486         newdata->data.f[2] = fh;
01487         ptr = (int *)&newdata->data.f[3];
01488         ptr[0] = charheight;
01489         ptr[1] = stringwidth;
01490 
01491 
01492         /* NO idea what Biao was doing here...  SLWM 4/98.
01493            However, it is necessary when redrawing windows... */
01494 
01495         *((XImage **)(&ptr[2])) = out;  /* Causes "unaligned access" warning
01496                                            in DEC UNIX... */
01497 
01498 
01499         newdata->data.b[3*sizeof(float)+2*sizeof(int)+sizeof(XImage*)]
01500                                                                     = position;
01501     }
01502 
01503     buffer_gfx = 1;
01504     return 1;
01505 } 
01506 
01507 lux_redraw_vstring(win)
01508 Window  win;
01509 {
01510     int       ix,iy,*ptr;
01511     register  lux_wins *current;
01512     int       stringwidth, charheight;
01513     unsigned  long c;
01514     Pixmap    pixmap, pixmapwhite;
01515     XImage   *out;
01516     XGCValues value;
01517     float     fx,fy,fh;
01518     char      position;
01519 
01520 
01521     current = get_currentwin(win);
01522 
01523     fx = (current->win.currentdata)->data.f[0];
01524     fy = (current->win.currentdata)->data.f[1];
01525     fh = (current->win.currentdata)->data.f[2];
01526     ptr = (int*)(&(current->win.currentdata)->data.f[3]);
01527     charheight = ptr[0];
01528     stringwidth = ptr[1];
01529     out = ((XImage **)(&ptr[2]))[0];
01530     position = (current->win.currentdata)->data.b[3*sizeof(float)+
01531                                      2*sizeof(int)+sizeof(XImage*)];
01532 
01533     lux_convert_coord(current->win.window, fx, fy, &ix, &iy);
01534 
01535     pixmap = XCreatePixmap(current->win.display, current->win.window, 
01536                            charheight, stringwidth, current->win.window_depth);
01537     if (!pmpallocflag) {pixmap=(Pixmap)NULL; pmpallocflag=1;
01538       fprintf(stderr, "In redraw_vstring, not enough video memory\n");
01539       return 0;
01540     }
01541     pixmapwhite = XCreatePixmap(current->win.display, current->win.window, 
01542                            charheight, stringwidth, current->win.window_depth);
01543     if (!pmpallocflag) {pixmap=(Pixmap)NULL; pmpallocflag=1;
01544       fprintf(stderr, "In redraw_vstring, not enough video memory\n");
01545       XFreePixmap(current->win.display, pixmap);
01546       return 0;
01547     }
01548 
01549     XGetGCValues(current->win.display, redrawgc,
01550                  GCBackground | GCForeground, &value);
01551     c = value.foreground;
01552     XSetForeground(current->win.display, redrawgc, value.background);
01553     lux_clear_pixmap(current->win.display, pixmapwhite, redrawgc,
01554                      0, 0, charheight, stringwidth);
01555     XSetForeground(current->win.display, redrawgc, c);
01556 
01557     XPutImage(current->win.display, pixmap, redrawgc,
01558               out, 0, 0, 0, 0, charheight, stringwidth);
01559 
01560     if (position == (char)(-1)) {ix=ix-charheight;iy=iy-stringwidth;}
01561     else if (position == 0) {ix=ix-charheight;iy=iy-(stringwidth+1)/2;}
01562     else if (position == 1) {ix=ix-charheight;iy=iy-stringwidth;}
01563 
01564     ix = ix - (int)(0.5 + fh*charheight);
01565 
01566     XGetGCValues(current->win.display, redrawgc, GCFunction, &value);
01567     XSetFunction(current->win.display, redrawgc, GXxor);
01568     XCopyArea(current->win.display, pixmapwhite, pixmap, 
01569                 redrawgc, 0, 0, charheight, stringwidth, 0, 0);
01570     if (current->win.pixmap) 
01571       XCopyArea(current->win.display, pixmapwhite, current->win.pixmap, 
01572                 redrawgc, 0, 0, charheight, stringwidth, ix, iy);
01573     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) 
01574       XCopyArea(current->win.display, pixmapwhite, current->win.window, 
01575                 redrawgc, 0, 0, charheight, stringwidth, ix, iy);
01576     XSetFunction(current->win.display, redrawgc, GXor);
01577     if (current->win.pixmap) 
01578       XCopyArea(current->win.display, pixmap, current->win.pixmap, 
01579                 redrawgc, 0, 0, charheight, stringwidth, ix, iy);
01580     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) 
01581       XCopyArea(current->win.display, pixmap, current->win.window, 
01582                 redrawgc, 0, 0, charheight, stringwidth, ix, iy);
01583     XSetFunction(current->win.display, redrawgc, GXxor);
01584     if (current->win.pixmap) 
01585       XCopyArea(current->win.display, pixmapwhite, current->win.pixmap, 
01586                 redrawgc, 0, 0, charheight, stringwidth, ix, iy);
01587     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) 
01588       XCopyArea(current->win.display, pixmapwhite, current->win.window, 
01589                 redrawgc, 0, 0, charheight, stringwidth, ix, iy);
01590 
01591     XSetFunction(current->win.display, redrawgc, value.function);
01592     XFreePixmap(current->win.display, pixmap);
01593     XFreePixmap(current->win.display, pixmapwhite);
01594     return 1;
01595 } 
01596 
01597 lux_draw_axis1(win)
01598 Window win;
01599 {
01600     register lux_wins *current;
01601     register lux_data *newdata;
01602     unsigned int       x,y,width,height,i;
01603     char msg[20];
01604     float fx,fy;
01605 
01606     current = get_currentwin(win);
01607 
01608     x = current->win.xorg*current->win.xresizefactor+0.5;
01609     y = current->win.yorg*current->win.yresizefactor+0.5;
01610     width  = current->win.xsize*current->win.xresizefactor+0.5;
01611     height = current->win.ysize*current->win.yresizefactor+0.5;
01612 
01613     if (current->win.pixmap) 
01614       XDrawRectangle(current->win.display, current->win.pixmap, 
01615                      current->win.gc, x, y, width, height);
01616 
01617     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL)) {
01618       XDrawRectangle(current->win.display, current->win.window, 
01619                      current->win.gc, x, y, width, height);
01620       XFlush(current->win.display);
01621     }
01622 
01623     fy = current->win.ymin;
01624     for(i=0;i<5;i++) {
01625       fx = current->win.xmin+(current->win.xmax-current->win.xmin)*i/4.0;
01626       sprintf(msg,"%6.2f",fx);
01627       lux_draw_string(current->win.window,fx,fy,-1.1,msg,0);
01628     }
01629     fx = current->win.xmin;
01630     for(i=0;i<5;i++) {
01631       fy = current->win.ymin+(current->win.ymax-current->win.ymin)*i/4.0;
01632       sprintf(msg,"%6.2f",fy);
01633       lux_draw_vstring(current->win.window,fx,fy,0.1,msg,0);
01634     }
01635 
01636     if (current->win.discard_flag) return 1;
01637 
01638     if ((newdata = get_newdata(current)) == (lux_data *)NULL)
01639       {fprintf(stderr,"Can't draw axis -- not enough memory\n"); 
01640        return 0;}
01641 
01642     newdata->type = DRAW_AXIS;
01643 }
01644 
01645 lux_redraw_axis1(win)
01646 Window win;
01647 {
01648     register lux_wins *current;
01649     unsigned int       x,y,width,height;
01650 
01651     current = get_currentwin(win);
01652 
01653     x = current->win.xorg*current->win.xresizefactor+0.5;
01654     y = current->win.yorg*current->win.yresizefactor+0.5;
01655     width  = current->win.xsize*current->win.xresizefactor+0.5;
01656     height = current->win.ysize*current->win.yresizefactor+0.5;
01657 
01658     if (current->win.pixmap) 
01659       XDrawRectangle(current->win.display, current->win.pixmap, redrawgc,
01660                      x, y, width, height);
01661     if (current->win.update_flag || (current->win.pixmap == (Pixmap)NULL))  {
01662       XDrawRectangle(current->win.display, current->win.window, redrawgc,
01663                      x, y, width, height);
01664 /*      XFlush(current->win.display);*/
01665     }
01666 }
01667 
01668 redraw(win, status)
01669 Window win;
01670 int status;
01671 {
01672 
01673     register lux_wins *current;
01674 
01675     current = get_currentwin(win);
01676 
01677     if (current->win.data == (lux_data *)NULL) return;
01678 
01679 /* Important for redraw if you have large amount of points */
01680     XSync(current->win.display,False);
01681 
01682     if (lux_peek_expose(current->win.display,current->win.window)) return;
01683 
01684     if ( status == 0 ) { /* added for movie */
01685         if (current->win.old_width  == current->win.width  &&
01686             current->win.old_height == current->win.height &&
01687             current->win.pixmap) {
01688             XCopyArea(current->win.display, current->win.pixmap, current->win.window,
01689                       current->win.gc, 0, 0, current->win.width, current->win.height,
01690                       0, 0);
01691             return;
01692         }            
01693 
01694         if (current->win.pixmap) {
01695             XFreePixmap(current->win.display, current->win.pixmap);
01696 
01697 /*If you remove comment it will insist to alloc pixmap everytime you resize*
01698         }
01699         {
01700  *If you remove comment it will insist to alloc pixmap everytime you resize*/
01701 
01702             current->win.pixmap = XCreatePixmap(current->win.display, 
01703                                                 current->win.window,
01704                                                 current->win.width, current->win.height,
01705                                                 current->win.window_depth);
01706 
01707             XSync(current->win.display,False); 
01708         
01709             if (!pmpallocflag) {current->win.pixmap=(Pixmap)NULL; pmpallocflag=1;}
01710 
01711             if (current->win.pixmap)         /* Here is to clear the pixmap  */
01712               lux_clear_pixmap(current->win.display, current->win.pixmap, defaultgc,
01713                                0, 0, current->win.width, current->win.height);
01714         }
01715 
01716         if ((current->win.old_width  != current->win.width  ||
01717              current->win.old_height != current->win.height) /*&&
01718             current->win.pixmap == (Pixmap)NULL*/)
01719           XClearWindow(current->win.display,current->win.window);
01720     }
01721     else {
01722         if (current->win.pixmap)         /* Here is to clear the pixmap  */
01723           lux_clear_pixmap(current->win.display, current->win.pixmap, defaultgc,
01724                            0, 0, current->win.width, current->win.height);
01725         XClearWindow(current->win.display,current->win.window);
01726     }
01727 
01728     XCopyGC(current->win.display, defaultgc, (long)0x003FFFFF, redrawgc);
01729 
01730     current->win.currentdata = current->win.data;
01731 
01732     while(1) {
01733 
01734       switch((current->win.currentdata)->type) {
01735       case SETUP_REGION:
01736         lux_resetup_region(current->win.window);
01737         break;
01738       case SETUP_AXIS:
01739         lux_resetup_axis(current->win.window);
01740         break;
01741       case SETUP_AXIS_STYLE:
01742         lux_resetup_axis_style(current->win.window);
01743         break;
01744       case DRAW_AXIS:
01745         lux_redraw_axis1(current->win.window);
01746         break;
01747       case DRAW_LINE:
01748         lux_redraw_line(current->win.window);
01749         break;
01750       case DRAW_LINE_F:
01751         lux_redraw_linef(current->win.window);
01752         break;
01753       case DRAW_LINES_F:
01754         lux_redraw_linesf(current->win.window);
01755         break;
01756       case SET_LINE_WIDTH:
01757         lux_reset_linewidth(current->win.window);
01758         break;
01759       case SET_LINE_STYLE:
01760         lux_reset_linestyle(current->win.window);
01761         break;
01762       case SET_COLOR:
01763         lux_reset_color(current->win.window);
01764         break;
01765       case SET_BG_COLOR:
01766         lux_reset_bgcolor(current->win.window);
01767         break;
01768       case DRAW_STRING:
01769         lux_redraw_string(current->win.window);
01770         break;
01771       case DRAW_IMAGE_STRING:
01772         lux_redraw_image_string(current->win.window);
01773         break;
01774       case DRAW_VSTRING:
01775         lux_redraw_vstring(current->win.window);
01776         break;
01777       case DRAW_SEGMENTS_F:
01778         lux_redraw_segmentsf(current->win.window);
01779         break;
01780       case DRAW_RECTANGLES_F:
01781         lux_redraw_rectanglesf(current->win.window);
01782         break;
01783       case DRAW_RECTANGLE_F:
01784         lux_redraw_rectanglef(current->win.window);
01785         break;
01786       case DRAW_ARCS_F:
01787         lux_redraw_arcsf(current->win.window);
01788         break;
01789       case DRAW_ARC_F:
01790         lux_redraw_arcf(current->win.window);
01791         break;
01792       case FILL_RECTANGLES_F:
01793         lux_refill_rectanglesf(current->win.window);
01794         break;
01795       case FILL_RECTANGLE_F:
01796         lux_refill_rectanglef(current->win.window);
01797         break;
01798       case FILL_ARCS_F:
01799         lux_refill_arcsf(current->win.window);
01800         break;
01801       case FILL_ARC_F:
01802         lux_refill_arcf(current->win.window);
01803         break;
01804       case FILL_POLYGON_F:
01805         lux_refill_polygonf(current->win.window);
01806         break;
01807       case DRAW_POINTS_F:
01808         lux_redraw_pointsf(current->win.window);
01809         break;
01810       case DRAW_POINT_F:
01811         lux_redraw_pointf(current->win.window);
01812         break;
01813       case SET_UPDATE:
01814         lux_reset_update(current->win.window);
01815         break;
01816       case SET_NO_UPDATE:
01817         lux_reset_noupdate(current->win.window);
01818         break;
01819       case UPDATE_FOREGROUND:
01820         lux_reupdate_fg(current->win.window);
01821 /* Added for pause in animation */
01822         if (lux_check_keypress(current->win.window, 'p')) {
01823             XBell(current->win.display,50);
01824             while(!lux_check_keypress(current->win.window, 'c'));
01825             XBell(current->win.display,50);
01826         }
01827         break;
01828       case CLEAR_WINDOW:
01829         lux_reclear_window(current->win.window);
01830         break;
01831       case CLEAR_CURRENT_REGION:   
01832         lux_reclear_current_region(current->win.window);
01833         break;
01834       default:
01835         break;
01836       }
01837       
01838       if ((current->win.currentdata)->next == current->win.currentdata) break;
01839 
01840 
01841       switch(lux_peek_expose_config(current->win.display,current->win.window)) {
01842           case ABORT_REDRAW:
01843 /* You must hit r to finish redraw  for these two lines*/
01844           current->win.old_width  = current->win.width;
01845           current->win.old_height = current->win.height;
01846 /* You must hit r to finish redraw  for these two lines*/
01847           if (current->win.pixmap) {
01848               XCopyArea(current->win.display, current->win.pixmap, 
01849                         current->win.window, redrawgc, 0, 0, 
01850                         current->win.width, current->win.height, 0, 0);
01851               XFlush(current->win.display);
01852           }
01853           return;
01854           case ONE_MORE_EXPOSE:
01855           if (current->win.pixmap == (Pixmap)NULL) {
01856 /* This not good for catching the expose event */
01857               if (current->win.old_width  == current->win.width &&
01858                   current->win.old_height == current->win.height) {
01859                   current->win.old_width  = current->win.width + 1;
01860                   current->win.old_height = current->win.height+ 1;
01861               }
01862               return;
01863           }
01864           break;
01865           case RESIZED:
01866 /* Check if it is really resized */
01867           {
01868               Window root;       
01869               int x,y;
01870               XEvent event; 
01871               unsigned int width,height,border_width,depth;
01872               XGetGeometry(current->win.display,current->win.window,
01873                            &root,&x,&y,&width,&height,&border_width,&depth);
01874               if (current->win.width  != width ||
01875                   current->win.height != height) return;
01876 /* Remove the useless events */
01877               XCheckTypedWindowEvent(current->win.display,current->win.window,
01878                                      ConfigureNotify,&event);
01879           }
01880           break;
01881           default:
01882           break;
01883       }
01884 
01885       current->win.currentdata = (current->win.currentdata)->next;
01886 
01887     }
01888     current->win.old_width  = current->win.width;
01889     current->win.old_height = current->win.height;
01890     
01891     if (current->win.pixmap) 
01892       XCopyArea(current->win.display, current->win.pixmap, current->win.window,
01893                 redrawgc, 0, 0, current->win.width, current->win.height, 0, 0);
01894     XFlush(current->win.display);
01895     
01896 /*    fprintf(stderr,"Finish redraw in win %u\n",current->win.window);*/
01897 }
01898 
01899 

Generated at Sun Feb 24 09:56:58 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001