[BACK]Return to ox_plot_xevent.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / plot

Annotation of OpenXM_contrib2/asir2000/plot/ox_plot_xevent.c, Revision 1.26

1.2       noro        1: /*
                      2:  * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
                      3:  * All rights reserved.
                      4:  *
                      5:  * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
                      6:  * non-exclusive and royalty-free license to use, copy, modify and
                      7:  * redistribute, solely for non-commercial and non-profit purposes, the
                      8:  * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
                      9:  * conditions of this Agreement. For the avoidance of doubt, you acquire
                     10:  * only a limited right to use the SOFTWARE hereunder, and FLL or any
                     11:  * third party developer retains all rights, including but not limited to
                     12:  * copyrights, in and to the SOFTWARE.
                     13:  *
                     14:  * (1) FLL does not grant you a license in any way for commercial
                     15:  * purposes. You may use the SOFTWARE only for non-commercial and
                     16:  * non-profit purposes only, such as academic, research and internal
                     17:  * business use.
                     18:  * (2) The SOFTWARE is protected by the Copyright Law of Japan and
                     19:  * international copyright treaties. If you make copies of the SOFTWARE,
                     20:  * with or without modification, as permitted hereunder, you shall affix
                     21:  * to all such copies of the SOFTWARE the above copyright notice.
                     22:  * (3) An explicit reference to this SOFTWARE and its copyright owner
                     23:  * shall be made on your publication or presentation in any form of the
                     24:  * results obtained by use of the SOFTWARE.
                     25:  * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.3       noro       26:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2       noro       27:  * for such modification or the source code of the modified part of the
                     28:  * SOFTWARE.
                     29:  *
                     30:  * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
                     31:  * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
                     32:  * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
                     33:  * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
                     34:  * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
                     35:  * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
                     36:  * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
                     37:  * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
                     38:  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
                     39:  * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
                     40:  * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
                     41:  * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
                     42:  * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
                     43:  * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
                     44:  * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
                     45:  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
                     46:  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
                     47:  *
1.26    ! ohara      48:  * $OpenXM: OpenXM_contrib2/asir2000/plot/ox_plot_xevent.c,v 1.25 2005/05/18 03:27:00 noro Exp $
1.2       noro       49: */
1.1       noro       50: #include "ca.h"
                     51: #include "parse.h"
                     52: #include "ox.h"
                     53: #include "ifplot.h"
                     54: #include "cursor.h"
1.8       takayama   55: #include <X11/Xaw/MenuButton.h>
                     56: #include <X11/Xaw/Paned.h>
1.14      noro       57:
1.24      noro       58: static void Quit();
1.26    ! ohara      59: static void print_canvas(Widget w, struct canvas *can, XtPointer calldata);
        !            60: static void output_to_printer(Widget w, struct canvas *can, XtPointer calldata);
        !            61: static void print_canvas_to_file(Widget w, struct canvas *can, XtPointer calldata);
        !            62: static void printing_method(Widget w, struct canvas *can, XtPointer calldata);
1.24      noro       63:
1.23      noro       64: static Atom wm_delete_window;
                     65:
1.24      noro       66: void SetWM_Proto(Widget w)
                     67: {
                     68:        XtOverrideTranslations(w,
                     69:                XtParseTranslationTable("<Message>WM_PROTOCOLS: quit()"));
                     70:        XSetWMProtocols(display,XtWindow(w),&wm_delete_window,1);
                     71: }
                     72:
1.23      noro       73: static void quit(Widget w, XEvent *ev, String *params,Cardinal *nparams)
                     74: {
                     75:     XBell(display,0);
                     76: }
                     77:
1.14      noro       78: /* XXX : these lines are in plotg.c, but ld says they are not defined */
                     79: #if __DARWIN__
                     80: int stream;
                     81:
                     82: DISPLAY *display;
                     83: CURSOR normalcur,runningcur,errorcur;
                     84:
                     85: #if defined(VISUAL)
                     86: POINT start_point, end_point;
                     87: SIZE cansize;
                     88: #else
                     89: Window rootwin;
                     90: GC drawGC,dashGC,hlGC,scaleGC,clearGC,xorGC,colorGC,cdrawGC;
                     91: XFontStruct *sffs;
                     92: #endif
                     93:
                     94: struct canvas *canvas[MAXCANVAS];
1.19      noro       95: struct canvas *closed_canvas[MAXCANVAS];
1.14      noro       96: struct canvas *current_can;
                     97: #endif /* __DARWIN__ */
1.1       noro       98:
                     99: #ifdef ABS
                    100: #undef ABS
                    101: #define ABS(a) ((a)>0?(a):-(a))
                    102: #endif
                    103:
                    104: static char *dname;
                    105: static int depth,scrn;
                    106:
1.13      noro      107: extern JMP_BUF ox_env;
1.1       noro      108: static Widget toplevel;
                    109: static XtAppContext app_con;
                    110:
                    111: static int busy;
                    112:
                    113: static struct PlotResources {
                    114:        Pixel ForePixel,BackPixel,DashPixel;
                    115:        char *ForeName,*BackName,*DashName;
                    116:        Boolean Reverse;
1.18      noro      117:        Boolean UpsideDown;
1.1       noro      118: } PlotResources;
                    119:
                    120: #define forePixel PlotResources.ForePixel
                    121: #define backPixel PlotResources.BackPixel
                    122: #define dashPixel PlotResources.DashPixel
                    123: #define foreName PlotResources.ForeName
                    124: #define backName PlotResources.BackName
                    125: #define dashName PlotResources.DashName
                    126: #define reverse PlotResources.Reverse
1.18      noro      127: #define upsidedown PlotResources.UpsideDown
1.1       noro      128:
                    129: Cursor create_cursor();
                    130:
                    131: #define blackPixel     BlackPixel(display,scrn)
                    132: #define whitePixel     WhitePixel(display,scrn)
                    133:
                    134: #define LABELWIDTH 150
                    135:
                    136: process_xevent() {
                    137:        XEvent ev;
                    138:
                    139:        while ( XPending(display) ) {
                    140:                XtAppNextEvent(app_con,&ev);
                    141:                XtDispatchEvent(&ev);
                    142:        }
                    143: }
                    144:
                    145: /* event handlers */
                    146:
                    147: static POINT spos,cpos;
                    148:
                    149: void press(w,can,ev)
                    150: Widget w;
                    151: struct canvas *can;
                    152: XButtonEvent *ev;
                    153: {
                    154:        POINT p;
                    155:
                    156:        switch ( ev->button ) {
                    157:                case Button1:
                    158:                        XC(spos) = ev->x; YC(spos) = ev->y; cpos = spos; break;
                    159:                case Button3:
                    160:                        XC(p) = ev->x; YC(p) = ev->y; draw_coord(can,&p); break;
                    161:                default:
                    162:                        break;
                    163:        }
                    164: }
                    165:
                    166: void motion(w,can,ev)
                    167: Widget w;
                    168: struct canvas *can;
                    169: XMotionEvent *ev;
                    170: {
                    171:
                    172:        POINT o,p;
                    173:
                    174:        if ( ev->state & Button1Mask ) {
                    175:                o = cpos; XC(cpos) = ev->x; YC(cpos) = ev->y;
                    176:                draw_frame(can->window,spos,o,cpos);
                    177:        } else if ( ev->state & Button3Mask ) {
                    178:                XC(p) = ev->x; YC(p) = ev->y;
                    179:                draw_coord(can,p);
                    180:        }
                    181: }
                    182:
                    183: void release(w,can,ev)
                    184: Widget w;
                    185: struct canvas *can;
                    186: XButtonEvent *ev;
                    187: {
                    188:        POINT e;
                    189:
                    190:        switch ( ev->button ) {
                    191:                case Button1:
                    192:                        e.x = ev->x; e.y = ev->y;
                    193:                        draw_frame0(can->window,spos,e);
1.22      noro      194:                        if ( !busy
                    195:                        && can->mode != MODE_INTERACTIVE
                    196:                        && can->mode != MODE_POLARPLOT) {
1.1       noro      197:                                if ( can->mode == MODE_PLOT )
                    198:                                        plot_resize(can,spos,e);
                    199:                                else
                    200:                                        ifplot_resize(can,spos,e);
                    201:                        }
                    202:                        break;
                    203:                default:
                    204:                        break;
                    205:        }
                    206: }
                    207:
                    208: void structure(w,can,ev)
                    209: Widget w;
                    210: struct canvas *can;
                    211: XEvent *ev;
                    212: {
                    213:        switch ( ev->xany.type ) {
                    214:                case Expose:
                    215:                                if ( !ev->xexpose.count )
                    216:                                        redraw_canvas(can);
                    217:                        break;
                    218:                case ConfigureNotify:
                    219:                        redraw_canvas(can); break;
                    220:                default:
                    221:                        break;
                    222:        }
                    223: }
                    224:
                    225: static int lindex;
                    226:
                    227: void lpress(w,can,ev)
                    228: Widget w;
                    229: struct canvas *can;
                    230: XButtonEvent *ev;
                    231: {
                    232:        lindex = (can->height-ev->y)/(can->height/can->nzstep);
                    233:        draw_level(can,lindex,hlGC);
                    234: }
                    235:
                    236: void jumpproc(w,can,percent)
                    237: Widget w;
                    238: struct canvas *can;
                    239: float *percent;
                    240: {
                    241:        int index;
                    242:
                    243:        index = can->nzstep * (1.0-*percent);
                    244:        if ( index == lindex )
                    245:                return;
                    246:        if ( lindex >= 0 )
                    247:                draw_level(can,lindex,drawGC);
                    248:        lindex = index;
                    249:        draw_level(can,lindex,hlGC);
                    250: }
                    251:
                    252: void jumpproc_m(w,can,percent)
                    253: Widget w;
                    254: struct canvas *can;
                    255: float *percent;
                    256: {
                    257:        int index;
                    258:
                    259:        index = can->nzstep * (1.0-*percent);
                    260:        if ( index != lindex ) {
                    261:                draw_level(can,lindex,drawGC);
                    262:                draw_level(can,lindex,hlGC);
                    263:        }
                    264: }
                    265:
                    266: void lrelease(w,can,ev)
                    267: Widget w;
                    268: struct canvas *can;
                    269: XButtonEvent *ev;
                    270: {
                    271:        draw_level(can,lindex,drawGC); lindex = -1;
                    272: }
                    273:
                    274: void lrelease_m(w,can,ev)
                    275: Widget w;
                    276: struct canvas *can;
                    277: XButtonEvent *ev;
                    278: {
                    279:        lindex = -1;
                    280: }
                    281:
                    282: draw_level(can,index,gc)
                    283: struct canvas *can;
                    284: int index;
                    285: GC gc;
                    286: {
                    287:        Pixmap pix;
                    288:        struct pa *pa;
                    289:        int i,len;
                    290:        POINT *p;
                    291:        Arg arg[2];
                    292:        char buf[BUFSIZ];
                    293:
                    294:        if ( busy || can->wide || index < 0 || index > can->nzstep )
                    295:                return;
                    296:        pix = can->pix; pa = &can->pa[index]; len = pa->length; p = pa->pos;
                    297:        for ( i = 0; i < len; i++ )
                    298:                XDrawPoint(display,pix,gc,p[i].x,p[i].y);
                    299:        sprintf(buf,"level:%g",can->zmin+(can->zmax-can->zmin)*index/can->nzstep);
                    300:        XtSetArg(arg[0],XtNlabel,buf); XtSetArg(arg[1],XtNwidth,LABELWIDTH);
                    301:        XtSetValues(can->level,arg,2);
                    302:        copy_to_canvas(can);
                    303: }
                    304:
                    305: draw_frame(window,spos,opos,epos)
                    306: Window window;
                    307: POINT spos,opos,epos;
                    308: {
                    309:        if ( XC(opos) != XC(epos) || YC(opos) != YC(epos) )
                    310:                draw_frame0(window,spos,opos);
                    311:        draw_frame0(window,spos,epos);
                    312: }
                    313:
                    314: draw_frame0(window,spos,epos)
                    315: Window window;
                    316: POINT spos,epos;
                    317: {
                    318:        int ulx,uly,w,h;
                    319:
                    320:        ulx = MIN(XC(spos),XC(epos)); uly = MIN(YC(spos),YC(epos));
                    321:        w = ABS(XC(spos)-XC(epos)); h = ABS(YC(spos)-YC(epos));
                    322:        if ( !w || !h )
                    323:                return;
                    324:        XDrawRectangle(display,window,xorGC,ulx,uly,w,h);
                    325:        XFlush(display);
                    326: }
                    327:
                    328: draw_coord(can,pos)
                    329: struct canvas *can;
                    330: POINT pos;
                    331: {
                    332:        char buf[BUFSIZ];
                    333:        Arg arg[2];
                    334:        double x,y,xmin,ymax,dx,dy;
                    335:
                    336:        if ( can->wide ) {
                    337:                dx = 10*(can->xmax-can->xmin); dy = 10*(can->ymax-can->ymin);
                    338:                xmin = (can->xmax+can->xmin-dx)/2;
                    339:                ymax = (can->ymax+can->ymin+dy)/2;
                    340:        } else {
                    341:                dx = can->xmax-can->xmin; dy = can->ymax-can->ymin;
                    342:                xmin = can->xmin; ymax = can->ymax;
                    343:        }
                    344:        x = xmin+XC(pos)*dx/can->width;
                    345:        y = ymax-YC(pos)*dy/can->height;
                    346:        sprintf(buf,"%s:%g",can->vx?can->vx->name:"horiz",x);
                    347:        XtSetArg(arg[0],XtNlabel,buf); XtSetArg(arg[1],XtNwidth,LABELWIDTH);
                    348:        XtSetValues(can->xcoord,arg,2);
                    349:        sprintf(buf,"%s:%g",can->vy?can->vy->name:"vert",y);
                    350:        XtSetArg(arg[0],XtNlabel,buf); XtSetArg(arg[1],XtNwidth,LABELWIDTH);
                    351:        XtSetValues(can->ycoord,arg,2);
                    352: }
                    353:
                    354: redraw_canvas(can)
                    355: struct canvas *can;
                    356: {
                    357:        if ( can->wide )
                    358:                draw_wideframe(can);
                    359:        else
                    360:                copy_to_canvas(can);
                    361: }
                    362:
                    363: search_canvas()
                    364: {
                    365:        int i;
                    366:
                    367:        for ( i = 0; i < MAXCANVAS; i++ )
                    368:                if ( !canvas[i] ) {
                    369:                        canvas[i] = (struct canvas *)MALLOC(sizeof(struct canvas));
                    370:                        canvas[i]->index = i; return i;
                    371:                }
                    372: }
                    373:
                    374: search_active_canvas()
                    375: {
                    376:        int i;
                    377:
                    378:        for ( i = 0; i < MAXCANVAS; i++ )
                    379:                if ( canvas[i] )
                    380:                        return i;
                    381:        return -1;
                    382: }
                    383:
1.19      noro      384: void popup_canvas(index)
                    385: {
1.20      noro      386:        clear_pixmap(canvas[index]);
1.19      noro      387:        XtPopup(canvas[index]->shell,XtGrabNone);
1.20      noro      388:        copy_to_canvas(canvas[index]);
1.19      noro      389: }
1.4       takayama  390:
1.1       noro      391: void destroy_canvas(w,can,calldata)
                    392: Widget w;
                    393: struct canvas *can;
                    394: XtPointer calldata;
                    395: {
                    396:        XtPopdown(can->shell);
1.19      noro      397: /*     XtDestroyWidget(can->shell); */
1.1       noro      398:        XFlush(display);
                    399:        if ( can == current_can ) {
                    400:                reset_busy(can); current_can = 0;
                    401:        }
1.19      noro      402:        if ( closed_canvas[can->index] )
                    403:                XtDestroyWidget(closed_canvas[can->index]->shell);
                    404:        closed_canvas[can->index] = can;
1.1       noro      405:        canvas[can->index] = 0;
                    406: }
                    407:
                    408: void precise_canvas(w,can,calldata)
                    409: Widget w;
                    410: struct canvas *can;
                    411: XtPointer calldata;
                    412: {
                    413:        if ( can->precise )
                    414:                can->precise = 0;
                    415:        else
                    416:                can->precise = 1;
                    417: }
                    418:
                    419: void wide_canvas(w,can,calldata)
                    420: Widget w;
                    421: struct canvas *can;
                    422: XtPointer calldata;
                    423: {
                    424:        if ( can->wide ) {
                    425:                can->wide = 0; copy_to_canvas(can);
                    426:        } else {
                    427:                can->wide = 1; draw_wideframe(can);
                    428:        }
                    429: }
                    430:
                    431: void noaxis_canvas(w,can,calldata)
                    432: Widget w;
                    433: struct canvas *can;
                    434: XtPointer calldata;
                    435: {
                    436:        if ( can->noaxis )
                    437:                can->noaxis = 0;
                    438:        else
                    439:                can->noaxis = 1;
                    440:        if ( can->wide )
                    441:                draw_wideframe(can);
                    442:        else
                    443:                copy_to_canvas(can);
                    444: }
                    445:
                    446: toggle_button(w,flag)
                    447: Widget w;
                    448: int flag;
                    449: {
                    450:        Arg arg[2];
                    451:
                    452:        if ( flag ) {
                    453:                XtSetArg(arg[0],XtNforeground,backPixel);
                    454:                XtSetArg(arg[1],XtNbackground,forePixel);
                    455:        } else {
                    456:                XtSetArg(arg[0],XtNforeground,forePixel);
                    457:                XtSetArg(arg[1],XtNbackground,backPixel);
                    458:        }
                    459:        XtSetValues(w,arg,2); XFlush(display);
                    460: }
                    461:
                    462: draw_wideframe(can)
                    463: struct canvas *can;
                    464: {
                    465:        struct canvas fakecan;
                    466:        double xmin,xmax,ymin,ymax,xmid,ymid,dx,dy;
                    467:        POINT s,e;
                    468:
                    469:        fakecan = *can;
                    470:        dx = 10*(can->xmax-can->xmin); dy = 10*(can->ymax-can->ymin);
                    471:        xmid = (can->xmax+can->xmin)/2; ymid = (can->ymax+can->ymin)/2;
                    472:
                    473:        fakecan.xmin = xmid-dx/2; fakecan.xmax = xmid+dx/2;
                    474:        fakecan.ymin = ymid-dy/2; fakecan.ymax = ymid+dy/2;
                    475:
                    476:        XFillRectangle(display,can->window,clearGC,
                    477:                0,0,can->width,can->height);
                    478:        pline(display,&fakecan,can->window);
                    479:        XC(s) = can->width*9/20; YC(s) = can->height*9/20;
                    480:        XC(e) = can->width*11/20; YC(e) = can->height*11/20;
                    481:        draw_frame0(can->window,s,e);
                    482: }
                    483:
                    484: create_popup(parent,name,str,shell,dialog)
                    485: Widget parent;
                    486: char *name,*str;
                    487: Widget *shell,*dialog;
                    488: {
                    489:        Arg arg[3];
                    490:        Position x,y;
                    491:
                    492:        XtTranslateCoords(parent,0,0,&x,&y);
                    493:        XtSetArg(arg[0],XtNx,x); XtSetArg(arg[1],XtNy,y);
                    494:        *shell = XtCreatePopupShell(name,transientShellWidgetClass,parent,arg,2);
                    495:        XtSetArg(arg[0],XtNlabel,str);
                    496:        *dialog = XtCreateManagedWidget("dialog",dialogWidgetClass,*shell,arg,1);
                    497: }
                    498:
                    499: warning(can,s)
                    500: struct canvas *can;
                    501: char *s;
                    502: {
                    503:        void popdown_warning();
                    504:        Widget warnshell,warndialog;
                    505:        Position x,y;
                    506:        Arg arg[3];
                    507:
                    508:        if ( !can->shell )
                    509:                return;
                    510:        create_popup(can->shell,"warning",s,&warnshell,&warndialog);
                    511:        XawDialogAddButton(warndialog,"dismiss",popdown_warning,warnshell);
                    512:        XtPopup(warnshell,XtGrabNone);
1.24      noro      513:        SetWM_Proto(warnshell);
1.1       noro      514: }
                    515:
                    516: void popdown_warning(w,client,call)
                    517: Widget w;
                    518: XtPointer client,call;
                    519: {
                    520:        XtPopdown(client); XtDestroyWidget(client);
                    521: }
                    522:
                    523: void show_formula(w,can,calldata)
                    524: Widget w;
                    525: struct canvas *can;
                    526: XtPointer calldata;
                    527: {
                    528:        void popdown_formula();
                    529:        Widget fshell,fdialog;
                    530:        char buf[BUFSIZ];
                    531:
                    532:        soutput_init(buf); sprintexpr(CO,(Obj)can->formula);
                    533:        create_popup(can->shell,"formula",buf,&fshell,&fdialog);
                    534:        XawDialogAddButton(fdialog,"dismiss",popdown_formula,w);
                    535:        XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.24      noro      536:        SetWM_Proto(fshell);
1.1       noro      537: }
                    538:
                    539: void popdown_formula(w,fbutton,call)
                    540: Widget w,fbutton;
                    541: XtPointer call;
                    542: {
                    543:        Widget shell = XtParent(XtParent(w));
                    544:        XtPopdown(shell); XtDestroyWidget(shell);
                    545:        XtSetSensitive(fbutton,True);
                    546: }
                    547:
                    548: #define NormalSelection ButtonPressMask|ButtonReleaseMask|Button1MotionMask|Button3MotionMask|StructureNotifyMask| ExposureMask
                    549:
                    550: create_canvas(can)
                    551: struct canvas *can;
                    552: {
                    553:        XEvent event;
                    554:        Widget box,frame,commands,
1.4       takayama  555:                coords,quit,print,wide,precise,canvas,formula;
1.1       noro      556:        Window window;
                    557:        Pixmap pix;
                    558:        int i,width,height;
                    559:        Arg arg[6];
                    560:        char buf[BUFSIZ];
                    561:
                    562:        width = can->width; height = can->height;
                    563:
1.21      noro      564:        sprintf(buf,"%s : %d", can->wname?can->wname:"Plot",can->index);
1.1       noro      565:        XtSetArg(arg[0],XtNiconName,buf);
                    566:        can->shell =
                    567:                XtCreatePopupShell("shell",topLevelShellWidgetClass,toplevel,arg,1);
                    568:
                    569:        XtSetArg(arg[0],XtNhSpace,0);
                    570:        XtSetArg(arg[1],XtNvSpace,0);
                    571:        XtSetArg(arg[2],XtNborderWidth,0);
                    572:        box = XtCreateManagedWidget("box",boxWidgetClass,can->shell,arg,3);
                    573:
                    574:        frame = XtCreateManagedWidget("form",formWidgetClass,box,NULL,0);
                    575:
                    576:        XtSetArg(arg[0],XtNorientation,XtorientHorizontal);
                    577:        XtSetArg(arg[1],XtNborderWidth,0);
                    578:        commands = XtCreateManagedWidget("commands",boxWidgetClass,frame,arg,2);
                    579:
                    580:        quit = XtCreateManagedWidget("quit",commandWidgetClass,commands,NULL,0);
                    581:        XtAddCallback(quit,XtNcallback,destroy_canvas,can);
1.4       takayama  582:        print = XtCreateManagedWidget("print",commandWidgetClass,commands,NULL,0);
                    583:        XtAddCallback(print,XtNcallback,print_canvas,can);
1.1       noro      584:        can->wideb = wide =
                    585:                XtCreateManagedWidget("wide",toggleWidgetClass,commands,NULL,0);
                    586:        XtAddCallback(wide,XtNcallback,wide_canvas,can);
                    587:        can->preciseb = precise =
                    588:                XtCreateManagedWidget("precise",toggleWidgetClass,commands,NULL,0);
                    589:        XtAddCallback(precise,XtNcallback,precise_canvas,can);
                    590:        formula =
                    591:                XtCreateManagedWidget("formula",commandWidgetClass,commands,NULL,0);
                    592:        XtAddCallback(formula,XtNcallback,show_formula,can);
                    593:        can->noaxisb =
                    594:                XtCreateManagedWidget("noaxis",toggleWidgetClass,commands,NULL,0);
                    595:        XtAddCallback(can->noaxisb,XtNcallback,noaxis_canvas,can);
                    596:
                    597:        XtSetArg(arg[0],XtNfromVert,commands);
                    598:        XtSetArg(arg[1],XtNwidth,width);
                    599:        XtSetArg(arg[2],XtNheight,height);
                    600:        canvas = XtCreateManagedWidget("canvas",simpleWidgetClass,frame,arg,3);
                    601:
                    602:        XtSetArg(arg[0],XtNfromVert,canvas);
                    603:        XtSetArg(arg[1],XtNheight,5);
                    604:        XtSetArg(arg[2],XtNwidth,width);
                    605:        XtSetArg(arg[3],XtNorientation,XtorientHorizontal);
                    606:        XtSetArg(arg[4],XtNsensitive,False);
                    607:        can->xdone =
                    608:                XtCreateManagedWidget("xdone",scrollbarWidgetClass,frame,arg,5);
                    609:
                    610:        XtSetArg(arg[0],XtNfromHoriz,canvas);
                    611:        XtSetArg(arg[1],XtNfromVert,commands);
                    612:        XtSetArg(arg[2],XtNwidth,5);
                    613:        XtSetArg(arg[3],XtNheight,height);
                    614:        XtSetArg(arg[4],XtNorientation,XtorientVertical);
                    615:        XtSetArg(arg[5],XtNsensitive,False);
                    616:        can->ydone =
                    617:                XtCreateManagedWidget("ydone",scrollbarWidgetClass,frame,arg,6);
                    618:
                    619:        XtSetArg(arg[0],XtNfromVert,can->xdone);
                    620:        XtSetArg(arg[1],XtNorientation,XtorientHorizontal);
                    621:        XtSetArg(arg[2],XtNborderWidth,0);
                    622:        coords = XtCreateManagedWidget("coords",boxWidgetClass,frame,arg,3);
                    623:
                    624:        XtSetArg(arg[0],XtNwidth,LABELWIDTH);
                    625:        can->xcoord = XtCreateManagedWidget("xcoord",labelWidgetClass,coords,arg,1);
                    626:        XtSetArg(arg[0],XtNwidth,LABELWIDTH);
                    627:        can->ycoord = XtCreateManagedWidget("ycoord",labelWidgetClass,coords,arg,1);
                    628:
                    629:        XtAddEventHandler(canvas,ButtonPressMask,False,press,can);
                    630:        XtAddEventHandler(canvas,ButtonReleaseMask,False,release,can);
                    631:        XtAddEventHandler(canvas,Button1MotionMask,False,motion,can);
                    632:        XtAddEventHandler(canvas,Button3MotionMask,False,motion,can);
                    633:        XtAddEventHandler(canvas,StructureNotifyMask,False,structure,can);
                    634:        XtAddEventHandler(canvas,ExposureMask,False,structure,can);
                    635:
                    636:        if ( can->mode == MODE_CONPLOT ) {
                    637:                Widget scale;
                    638:
                    639:                XtSetArg(arg[0],XtNwidth,LABELWIDTH);
                    640:                can->level = XtCreateManagedWidget("level",labelWidgetClass,
                    641:                        commands,arg,1);
                    642:
                    643:                XtSetArg(arg[0],XtNsensitive,True);
                    644:                XtSetValues(can->ydone,arg,1);
                    645:                if ( depth >= 2 ) {
                    646:                        XtAddCallback(can->ydone,XtNjumpProc,jumpproc,can);
                    647:                        XtAddEventHandler(can->ydone,ButtonReleaseMask,False,lrelease,can);
                    648:                } else {
                    649:                        XtAddCallback(can->ydone,XtNjumpProc,jumpproc_m,can);
                    650:                        XtAddEventHandler(can->ydone,ButtonReleaseMask,False,lrelease_m,can);
                    651:                }
                    652:        }
                    653:        if ( can->mode != MODE_IFPLOT || !qpcheck((Obj)can->formula) )
                    654:                XtSetSensitive(precise,False);
                    655:        XtPopup(can->shell,XtGrabNone);
1.24      noro      656:        SetWM_Proto(can->shell);
1.1       noro      657:        window = can->window = XtWindow(canvas);
                    658:        pix = can->pix = XCreatePixmap(display,window,width,height,depth);
                    659:        XFillRectangle(display,pix,clearGC,0,0,width,height);
                    660:        XDefineCursor(display,window,normalcur);
                    661:        XFlush(display);
                    662:        current_can = can;
                    663: }
                    664:
                    665: alloc_pixmap(can)
                    666: struct canvas *can;
                    667: {
                    668:        can->pix = XCreatePixmap(display,can->window,
                    669:                can->width,can->height,depth);
                    670:        XFillRectangle(display,can->pix,clearGC,0,0,can->width,can->height);
                    671: }
                    672:
                    673: static XrmOptionDescRec options[] = {
1.18      noro      674: {"-upsidedown","*upsidedown",XrmoptionNoArg,"on"},
1.1       noro      675: {"-reverse","*reverse",XrmoptionNoArg,"on"},
                    676: {"-fg","*foreground",XrmoptionSepArg,NULL},
                    677: {"-bg","*background",XrmoptionSepArg,NULL},
                    678: };
                    679:
                    680: #define offset(name) XtOffset(struct PlotResources *,name)
                    681:
                    682: static XtResource resources[] = {
1.18      noro      683: {"upsidedown","UpsideDown",XtRBoolean,sizeof(Boolean),
                    684:        offset(UpsideDown),XtRBoolean,&upsidedown},
1.1       noro      685: {"reverse","Reverse",XtRBoolean,sizeof(Boolean),
                    686:        offset(Reverse),XtRBoolean,&reverse},
                    687: {"foreground","Foreground",XtRString,sizeof(char *),
                    688:        offset(ForeName),XtRString,NULL},
                    689: {"foreground","Foreground",XtRPixel,sizeof(Pixel),
                    690:        offset(ForePixel),XtRPixel,(XtPointer)&forePixel},
                    691: {"background","Background",XtRString,sizeof(char *),
                    692:        offset(BackName),XtRString,NULL},
                    693: {"background","Background",XtRPixel,sizeof(Pixel),
                    694:        offset(BackPixel),XtRPixel,(XtPointer)&backPixel},
                    695: {"dash","Dash",XtRString,sizeof(char *),
                    696:        offset(DashName),XtRString,NULL},
                    697: {"dash","Dash",XtRPixel,sizeof(Pixel),
                    698:        offset(DashPixel),XtRPixel,(XtPointer)&dashPixel},
                    699: };
                    700:
1.24      noro      701: static XtActionsRec actions_table[] = {
                    702:        {"quit",Quit},
                    703: };
                    704:
                    705: static void Quit(Widget w, XEvent *ev, String *params,Cardinal *nparams)
                    706: {
                    707:     XBell(XtDisplay(w),0);
                    708: }
                    709:
1.12      noro      710: int init_plot_display(argc,argv)
1.1       noro      711: int argc;
                    712: char **argv;
                    713: {
                    714:        int ac;
                    715:        char **av;
                    716:        unsigned int tmp;
                    717:
                    718:        for ( ac = argc, av = argv; ac; ac--, av++ )
1.12      noro      719:                if ( !strcmp(*av,"nox") )
                    720:                        return 0;
                    721:                else if ( index(*av,':') )
1.1       noro      722:                        dname = *av;
                    723:        XtToolkitInitialize();
                    724:        app_con = XtCreateApplicationContext();
1.24      noro      725:        XtAppAddActions(app_con,actions_table, XtNumber(actions_table));
1.1       noro      726:        display = XtOpenDisplay(app_con,dname,"plot","Plot",
                    727:                options,XtNumber(options),&argc,argv);
                    728:        if ( !display ) {
                    729:                fprintf(stderr,"Can't open display\n");
1.12      noro      730:                return 0;
1.1       noro      731:        }
                    732:        toplevel = XtAppCreateShell(0,"Plot",applicationShellWidgetClass,
                    733:                display,0,0);
                    734:
                    735:        forePixel = blackPixel; backPixel = whitePixel;
                    736:        dashPixel = blackPixel;
                    737:        XtGetApplicationResources(toplevel,&PlotResources,
                    738:                resources,XtNumber(resources),NULL,0);
                    739:        display = XtDisplay(toplevel);
                    740:        scrn = DefaultScreen(display);
                    741:        depth = DefaultDepth(display,scrn);
                    742:        rootwin = RootWindow(display,scrn);
                    743:
1.23      noro      744:        /* for handling DELETE message */
                    745:        wm_delete_window = XInternAtom(display,"WM_DELETE_WINDOW",False);
                    746:        XtOverrideTranslations(toplevel,
                    747:                XtParseTranslationTable("<Message>WM_PROTOCOLS: quit()"));
                    748:
1.1       noro      749:        if ( reverse ) {
                    750:                tmp = forePixel; forePixel = backPixel; backPixel = tmp;
                    751:        }
                    752:
                    753:        create_gc();
                    754:        create_font();
                    755:        create_cursors();
1.12      noro      756:        return 1;
1.1       noro      757: }
                    758:
                    759: static char *scalefont = "*-8-80-*";
                    760:
                    761: create_font() {
                    762:        Font sfid;
                    763:
                    764:        sfid = XLoadFont(display,scalefont);
                    765:        sffs = XQueryFont(display,sfid);
                    766:        XSetFont(display,scaleGC,sfid);
                    767: }
                    768:
                    769: create_gc() {
                    770:        static XColor color = {0,0x0,0x0,0x0,DoRed|DoGreen|DoBlue,0};
                    771:        int i,b,step;
                    772:
                    773:        drawGC = XCreateGC(display,rootwin,0,NULL);
                    774:        dashGC = XCreateGC(display,rootwin,0,NULL);
                    775:        hlGC = XCreateGC(display,rootwin,0,NULL);
                    776:        clearGC = XCreateGC(display,rootwin,0,NULL);
                    777:        scaleGC = XCreateGC(display,rootwin,0,NULL);
                    778:        xorGC = XCreateGC(display,rootwin,0,NULL);
                    779:        colorGC = XCreateGC(display,rootwin,0,NULL);
1.11      noro      780:        cdrawGC = XCreateGC(display,rootwin,0,NULL);
1.1       noro      781:        XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,drawGC);
                    782:        XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,dashGC);
                    783:        XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,clearGC);
                    784:        XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,scaleGC);
                    785:        XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,xorGC);
                    786:        XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,colorGC);
1.11      noro      787:        XCopyGC(display,DefaultGC(display,scrn),(1L<<(GCLastBit+1))-1,cdrawGC);
1.1       noro      788:        XSetForeground(display,drawGC,forePixel);
                    789:        XSetForeground(display,scaleGC,forePixel);
                    790:        XSetForeground(display,clearGC,backPixel);
                    791:        XSetForeground(display,xorGC,forePixel^backPixel);
                    792:        XSetFunction(display,xorGC,GXxor);
                    793:        XSetForeground(display,dashGC,dashPixel);
                    794:        XSetLineAttributes(display,dashGC,1,LineOnOffDash,CapButt,JoinRound);
                    795:
                    796:        color.red = color.green = color.blue = 0xffff/2;
                    797:        XAllocColor(display,DefaultColormap(display,scrn),&color);
                    798:        XSetForeground(display,hlGC,color.pixel);
                    799:        color.red = 0xffff; color.green = color.blue = 0;
                    800:        XAllocColor(display,DefaultColormap(display,scrn),&color);
                    801:        XSetForeground(display,colorGC,color.pixel);
1.11      noro      802: }
                    803:
                    804: set_drawcolor(c)
                    805: unsigned int c;
                    806: {
                    807:        XColor color = {0,0x0,0x0,0x0,DoRed|DoGreen|DoBlue,0};
                    808:
                    809:        color.red = (c&0xff0000)>>8;
                    810:        color.green = (c&0xff00);
                    811:        color.blue = (c&0xff)<<8;
                    812:        XAllocColor(display,DefaultColormap(display,scrn),&color);
                    813:        XSetForeground(display,cdrawGC,color.pixel);
1.1       noro      814: }
                    815:
                    816: create_cursors() {
                    817:        static XColor fg = {0, 0x0, 0x0, 0x0,DoRed|DoGreen|DoBlue,0};
                    818:        static XColor bg = {0, 0xffff, 0xffff, 0xffff,DoRed|DoGreen|DoBlue,0};
                    819:
                    820:        XAllocColor(display,DefaultColormap(display,scrn),&fg);
                    821:        XAllocColor(display,DefaultColormap(display,scrn),&bg);
                    822:        normalcur = create_cursor(h_bits,h_m_bits,h_width,h_height,
                    823:                h_x_hot,h_y_hot,&fg,&bg);
                    824:        runningcur = create_cursor(ht_bits,ht_m_bits,ht_width,ht_height,
                    825:                ht_width/2,ht_height/2,&fg,&bg);
                    826:        errorcur = create_cursor(m_bits,m_m_bits,m_width,m_height,
                    827:                m_width/2,m_height/2,&fg,&bg);
                    828: }
                    829:
                    830: Cursor create_cursor(image,mask,width,height,xhot,yhot,fg,bg)
                    831: char *image,*mask;
                    832: int width,height,xhot,yhot;
                    833: XColor *fg,*bg;
                    834: {
                    835:        Pixmap ipix,mpix;
                    836:
                    837:        ipix = XCreateBitmapFromData(display,rootwin,image,width,height);
                    838:        mpix = XCreateBitmapFromData(display,rootwin,mask,width,height);
                    839:        return XCreatePixmapCursor(display,ipix,mpix,fg,bg,xhot,yhot);
                    840: }
                    841:
                    842: copy_to_canvas(can)
                    843: struct canvas *can;
                    844: {
                    845:        if ( display ) {
1.25      noro      846:                if ( can->color ) {
                    847:                        set_drawcolor(can->color);
                    848:                        XCopyArea(display,can->pix,can->window,
                    849:                                cdrawGC,0,0,can->width,can->height,0,0);
                    850:                } else
                    851:                        XCopyArea(display,can->pix,can->window,
                    852:                                drawGC,0,0,can->width,can->height,0,0);
1.1       noro      853:                pline(display,can,can->window);
                    854:                XFlush(display);
                    855:        }
                    856: }
                    857:
                    858: copy_subimage(subcan,can,pos)
                    859: struct canvas *subcan,*can;
                    860: XPoint pos;
                    861: {
                    862:        if ( display ) {
                    863:                XCopyArea(display,subcan->pix,can->pix,
                    864:                        drawGC,0,0,subcan->width,subcan->height,pos.x,pos.y);
                    865:                XFlush(display);
                    866:        }
                    867: }
                    868:
                    869: #include <signal.h>
                    870: #include <fcntl.h>
                    871:
                    872: set_selection() {
                    873:        if ( current_can ) {
                    874:                XSelectInput(display,current_can->window,0);
                    875:                XFlush(display);
                    876:        }
                    877: }
                    878:
                    879: reset_selection() {
                    880:        if ( current_can ) {
                    881:                XSelectInput(display,current_can->window,NormalSelection);
                    882:                XFlush(display);
                    883:        }
                    884: }
                    885:
                    886: set_busy(can)
                    887: struct canvas *can;
                    888: {
                    889:        busy = 1;
                    890:        XtSetSensitive(can->wideb,False);
                    891:        XtSetSensitive(can->preciseb,False);
                    892:        XtSetSensitive(can->noaxisb,False);
                    893:        XFlush(display);
                    894: }
                    895:
                    896: reset_busy(can)
                    897: struct canvas *can;
                    898: {
                    899:        busy = 0;
                    900:        if ( can->window ) {
                    901:                XtSetSensitive(can->wideb,True);
                    902:                XtSetSensitive(can->noaxisb,True);
                    903:                if ( can->mode == MODE_IFPLOT && qpcheck((Obj)can->formula) )
                    904:                        XtSetSensitive(can->preciseb,True);
                    905:                XFlush(display);
                    906:        }
                    907: }
                    908:
                    909: reset_current_computation()
                    910: {
                    911:        if ( current_can ) {
                    912:                reset_selection(); reset_busy(current_can);
                    913:                define_cursor(current_can->window,normalcur);
                    914:        }
1.8       takayama  915: }
                    916:
                    917: static struct canvas *Can;
                    918: /* void print_canvas(Widget w,struct canvas *can, XtPointer calldata); */
                    919: static void output_to_file(Widget , XtPointer, XtPointer );
                    920: static void output_to_ps_printer(Widget , XtPointer, XtPointer );
                    921: static void cancel_output_to_file(Widget , XtPointer,XtPointer);
                    922: static void generate_psfile(struct canvas *can, FILE *fp);
                    923: static void set_printing_method(Widget,XtPointer,XtPointer);
                    924: static void method_is_not_available();
                    925: static Widget PrintDialog;
                    926: static Widget PrintDialog_lp;
                    927: static Widget W;
                    928: static char *Fname = NULL;
                    929: static char *PrinterName = NULL;
                    930: #define PRINTING_METHOD_BITMAP 0
                    931: #define PRINTING_METHOD_VECTOR 1
                    932: static int PrintingMethod = PRINTING_METHOD_BITMAP;
                    933: static String Printing_methods[]={
                    934:   "bitMap","vector",
                    935: };
                    936: static int N_printing_methods = 2;
                    937:
                    938: /*
                    939: static Widget create_printing_method_bar(Widget parent) {
                    940:   Widget panel, button;
                    941:   int i,n;
                    942:   Arg wargs[1];
                    943:   panel = XtCreateManagedWidget("printing methods",panedWidgetClass,
                    944:                                                                parent,NULL,0);
                    945:   for (i=0; i<N_printing_methods; i++) {
                    946:        button = XtCreateManagedWidget(Printing_methods[i],menuButtonWidgetClass,
                    947:                                                                   panel,NULL,0);
                    948:        fprintf(stderr,"button=%x\n",(int) button);
                    949:        XtAddCallback(button,XtNcallback,set_printing_method,(XtPointer) i);
                    950:   }
                    951:   return(panel);
                    952: }
                    953: */
                    954:
                    955:
                    956: static void print_canvas(w,can,calldata)
                    957:         Widget w;
                    958:         struct canvas *can;
                    959:         XtPointer calldata;
                    960: {
                    961:   Widget fshell,fdialog;
                    962:   extern struct canvas *Can;
                    963:   extern Widget W;
                    964:   Widget entry;
                    965:   int i;
                    966:   Arg arg[1];
                    967:
                    968:   W = w;
                    969:   Can = can;
                    970:   create_popup(can->shell,"Print/Output PS file","",&fshell,&fdialog);
                    971:   XawDialogAddButton(fdialog,"print",output_to_printer,w);
                    972:   XawDialogAddButton(fdialog,"output PS file",print_canvas_to_file,w);
                    973:   XawDialogAddButton(fdialog,"method",printing_method,w);
                    974:   XawDialogAddButton(fdialog,"dismiss",cancel_output_to_file,w);
                    975:   XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.24      noro      976:   SetWM_Proto(fshell);
1.8       takayama  977: }
                    978:
                    979: static void set_printing_method(Widget w,XtPointer number,XtPointer call_data) {
                    980:   Widget shell;
                    981:   extern int PrintingMethod;
                    982:   PrintingMethod = (int) number;
                    983:   fprintf(stderr,"PrintingMethod=%d\n",number);
                    984:   shell = XtParent(XtParent(w));
                    985:   XtPopdown(shell); XtDestroyWidget(shell);
                    986: }
                    987:
                    988: static void printing_method(w,can,calldata)
                    989:         Widget w;
                    990:         struct canvas *can;
                    991:         XtPointer calldata;
                    992: {
                    993:   Arg arg[10];
                    994:   int i,n;
                    995:   Widget fshell,fdialog;
                    996:   extern struct canvas *Can;
                    997:   extern int PrintingMethod;
                    998:
                    999:   w = W;
                   1000:   can = Can;
                   1001:   create_popup(can->shell,"Printing method",Printing_methods[PrintingMethod],
                   1002:                           &fshell,&fdialog);
                   1003:   n = 0;
                   1004:   XtSetArg(arg[n], XtNlabel, "Method: "); n++;
                   1005:   XtSetArg(arg[n], XtNvalue, Printing_methods[PrintingMethod]); n++;
                   1006:   XtSetValues(fdialog,arg,n);
                   1007:   for (i=0; i<N_printing_methods; i++) {
                   1008:        XawDialogAddButton(fdialog,Printing_methods[i],set_printing_method,(XtPointer) i);
                   1009:   }
                   1010:   XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.24      noro     1011:   SetWM_Proto(fshell);
1.8       takayama 1012: }
                   1013: static void print_canvas_to_file(w,can,calldata)
                   1014:         Widget w;
                   1015:         struct canvas *can;
                   1016:         XtPointer calldata;
                   1017: {
                   1018:   FILE *fp;
                   1019:   Arg arg[10];
                   1020:   int n;
                   1021:   static char *psfile = NULL;
                   1022:   Widget fshell,fdialog;
                   1023:   extern struct canvas *Can;
                   1024:   extern Widget PrintDialog;
                   1025:   extern char *Fname;
                   1026:
                   1027:   w = W;
                   1028:   can = Can;
                   1029:   if (psfile == NULL || Fname == NULL) psfile = "ox_plot.eps";
                   1030:   else psfile = Fname;
                   1031:   create_popup(can->shell,"Output as PS file",psfile,&fshell,&fdialog);
                   1032:   n = 0;
                   1033:   XtSetArg(arg[n], XtNlabel, "File : "); n++;
                   1034:   XtSetArg(arg[n], XtNvalue, psfile); n++;
                   1035:   XtSetValues(fdialog,arg,n);
                   1036:   XawDialogAddButton(fdialog,"output to file",output_to_file,w);
                   1037:   XawDialogAddButton(fdialog,"cancel",cancel_output_to_file,w);
                   1038:   PrintDialog = fdialog;
                   1039:   XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.24      noro     1040:   SetWM_Proto(fshell);
1.8       takayama 1041: }
                   1042: static void output_to_printer(w,can,calldata)
                   1043:         Widget w;
                   1044:         struct canvas *can;
                   1045:         XtPointer calldata;
                   1046: {
                   1047:   FILE *fp;
                   1048:   Arg arg[10];
                   1049:   int n;
                   1050:   static char *psfile = NULL;
                   1051:   Widget fshell,fdialog;
                   1052:   extern struct canvas *Can;
                   1053:   extern Widget PrintDialog_lp;
                   1054:   extern char *PrinterName;
                   1055:
                   1056:   w = W;
                   1057:   can = Can;
                   1058:   if (psfile  == NULL || PrinterName == NULL) psfile = "lp";
                   1059:   else psfile = PrinterName;
                   1060:   create_popup(can->shell,"Output PS file to printer",psfile,&fshell,&fdialog);
                   1061:   n = 0;
                   1062:   XtSetArg(arg[n], XtNlabel, "PS Printer Name : "); n++;
                   1063:   XtSetArg(arg[n], XtNvalue, psfile); n++;
                   1064:   XtSetValues(fdialog,arg,n);
                   1065:   XawDialogAddButton(fdialog,"output to PS printer",output_to_ps_printer,w);
                   1066:   XawDialogAddButton(fdialog,"cancel",cancel_output_to_file,w);
                   1067:   PrintDialog_lp = fdialog;
                   1068:   XtSetSensitive(w,False); XtPopup(fshell,XtGrabNone);
1.24      noro     1069:   SetWM_Proto(fshell);
1.8       takayama 1070: }
                   1071:
                   1072: static void cancel_output_to_file(w,fbutton,call)
                   1073:         Widget w;
                   1074:         XtPointer fbutton, call;
                   1075: {
                   1076:   Widget shell = XtParent(XtParent(w));
                   1077:   XtPopdown(shell); XtDestroyWidget(shell);
                   1078:   XtSetSensitive(fbutton,True);
                   1079: }
                   1080:
                   1081: static void output_to_file(w,fbutton,call)
                   1082:         Widget w;
                   1083:         XtPointer fbutton, call;
                   1084: {
                   1085:   char *fname;
                   1086:   FILE *fp;
                   1087:   int i;
                   1088:   char *m;
                   1089:   extern struct canvas *Can;
                   1090:   extern Widget PrintDialog;
                   1091:   extern int PrintingMethod;
                   1092:   Widget shell = XtParent(XtParent(w));
                   1093:
                   1094:   if (PrintingMethod == PRINTING_METHOD_BITMAP) {
                   1095:   }else{
                   1096:        method_is_not_available();
                   1097:        XtPopdown(shell); XtDestroyWidget(shell);
                   1098:        XtSetSensitive(fbutton,True);
                   1099:        return;
                   1100:   }
                   1101:
                   1102:   fname = XawDialogGetValueString(PrintDialog);
                   1103:   Fname = (char *)malloc(sizeof(char)*strlen(fname)+1);
                   1104:   strcpy(Fname,fname);
                   1105:   for (i=0; i<strlen(Fname); i++) {
                   1106:        if (Fname[i] == 0xd || Fname[i] == 0xa) {
                   1107:          Fname[i] = 0; break;
                   1108:        }
                   1109:   }
                   1110:   fprintf(stderr,"fname=%s\n",Fname); fflush(NULL);
                   1111:   fp = fopen(Fname,"w");
                   1112:   if (fp == NULL) {
                   1113:        warning(Can,"Could not open the output file.");
                   1114:   }else{
                   1115:        generate_psfile(Can,fp);
                   1116:        fclose(fp);
                   1117:   }
                   1118:
                   1119:   XtPopdown(shell); XtDestroyWidget(shell);
                   1120:   XtSetSensitive(fbutton,True);
                   1121: }
                   1122:
                   1123: static void output_to_ps_printer(w,fbutton,call)
                   1124:         Widget w;
                   1125:         XtPointer fbutton, call;
                   1126: {
                   1127:   char *printerName;
                   1128:   FILE *fp;
                   1129:   extern struct canvas *Can;
                   1130:   extern Widget PrintDialog_lp;
                   1131:   char fname[256];
                   1132:   char cmd[512];
                   1133:   static int id = 0;
                   1134:   int i;
                   1135:   Widget shell = XtParent(XtParent(w));
                   1136:
                   1137:   if (PrintingMethod == PRINTING_METHOD_BITMAP) {
                   1138:   }else{
                   1139:        method_is_not_available();
                   1140:        XtPopdown(shell); XtDestroyWidget(shell);
                   1141:        XtSetSensitive(fbutton,True);
                   1142:        return;
                   1143:   }
                   1144:
                   1145:   sprintf(fname,"/tmp/ox_plot_%d.eps",(int) getpid(),id++);
                   1146:
                   1147:   printerName = XawDialogGetValueString(PrintDialog_lp);
                   1148:   PrinterName = (char *)malloc(sizeof(char)*strlen(printerName)+1);
                   1149:   strcpy(PrinterName,printerName);
                   1150:   for (i=0; i<strlen(PrinterName); i++) {
                   1151:        if (PrinterName[i] == 0xd || PrinterName[i] == 0xa) {
                   1152:          PrinterName[i] = 0; break;
                   1153:        }
                   1154:   }
                   1155:   fprintf(stderr,"printerName=%s\n",PrinterName); fflush(NULL);
                   1156:   fp = fopen(fname,"w");
                   1157:   if (fp == NULL) {
                   1158:        warning(Can,"Could not open the output file.");
                   1159:   }else{
                   1160:        generate_psfile(Can,fp);
                   1161:        fclose(fp);
                   1162:   }
                   1163:
                   1164:   sprintf(cmd,"lpr -P%s %s",PrinterName,fname);
                   1165:   if (system(cmd)) {
                   1166:        warning(Can,"Unknown printer?");
                   1167:   }
                   1168:   sprintf(cmd,"rm -f %s",fname);
                   1169:   system(cmd);
                   1170:   XtPopdown(shell); XtDestroyWidget(shell);
                   1171:   XtSetSensitive(fbutton,True);
                   1172: }
                   1173:
                   1174:
                   1175: /* test sequence
                   1176:    ox_launch(0,"ox_plot");
                   1177:    ifplot(x^2-y^3);
                   1178:    drawcircle(0,0,100,0,0);
                   1179:    */
1.15      takayama 1180: static int getColorSizeOfImageForPS(int xsize,int ysize,XImage *image,
                   1181:                                     struct xcolorForPS **tableOfxcolorForPS);
                   1182:
1.8       takayama 1183: static void generate_psfile(can,fp)
                   1184:         struct canvas *can;
                   1185:         FILE *fp;
                   1186: {
                   1187:   int x,y;
                   1188:   XImage *image;
                   1189:   int color[1];
                   1190:   int colorSize = 1;
                   1191:   char *m;
1.15      takayama 1192:   struct xcolorForPS *tableOfxcolorForPS;
1.8       takayama 1193:   extern int PrintingMethod;
                   1194:   fprintf(stderr,"generate_psfile\n");
                   1195:   if (PrintingMethod == PRINTING_METHOD_BITMAP) {
                   1196:        if ( display ) {
                   1197:          fprintf(stderr,"generate_psfile: output to a file.\n");
                   1198:          image = XGetImage(display,can->pix,
                   1199:                                                0,0,can->width,can->height,-1,ZPixmap);
1.15      takayama 1200:          colorSize =
                   1201:                getColorSizeOfImageForPS(can->width,can->height,image,&tableOfxcolorForPS);
                   1202:          color[0] = 0; /* black line */
1.18      noro     1203:          generatePS_from_image(fp,image,can->width,can->height,color,colorSize,can,tableOfxcolorForPS,upsidedown);
1.8       takayama 1204:        }else{
                   1205:          fprintf(stderr,"Cannot print on this system\n");
                   1206:        }
                   1207:   }else{
                   1208:        method_is_not_available();
                   1209:   }
                   1210:   fflush(NULL);
                   1211: }
                   1212:
                   1213: static void method_is_not_available() {
                   1214:   char *m;
                   1215: #define MSG1 "Printing method \""
                   1216: #define MSG2 "\" is not available for this picture."
                   1217:   m = (char *)malloc(strlen(MSG1)+strlen(MSG2)+strlen(Printing_methods[PrintingMethod])+1);
                   1218:   strcpy(m,MSG1);
                   1219:   strcat(m,Printing_methods[PrintingMethod]);
                   1220:   strcat(m,MSG2);
                   1221:   warning(Can,m);
1.9       noro     1222: }
                   1223:
                   1224: clear_pixmap(can)
                   1225: struct canvas *can;
                   1226: {
                   1227:        XFillRectangle(display,can->pix,clearGC,0,0,can->width,can->height);
                   1228:        XFlush(display);
1.1       noro     1229: }
1.15      takayama 1230:
                   1231: /*
                   1232:    The following functions are used to generate color postscript file.
                   1233: */
                   1234: /* In order to count colorSize, binary tree (sm_btree) is used. */
                   1235: static struct sm_btree *sm_newNode(unsigned long v);
                   1236: static int sm_insert(struct sm_btree *node,unsigned long v);
                   1237: static int sm_count(struct sm_btree *rootp);
1.17      takayama 1238:
1.15      takayama 1239: struct sm_btree {
                   1240:   unsigned long p;
                   1241:   struct sm_btree * left;
                   1242:   struct sm_btree * right;
                   1243: };
                   1244: static struct sm_btree *sm_newNode(unsigned long v) {
                   1245:   struct sm_btree * n;
                   1246:   n = (struct sm_btree *)MALLOC(sizeof(struct sm_btree));
                   1247:   if (n == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
                   1248:   n->p = v;
                   1249:   n->left = NULL;
                   1250:   n->right = NULL;
                   1251:   return n;
                   1252: }
                   1253: static int sm_insert(struct sm_btree *node,unsigned long v)
                   1254: {
                   1255:   if (node->p == v) return;
                   1256:   if (node->p > v) {
                   1257:     if (node->left == NULL) {
                   1258:       node->left = sm_newNode(v);
                   1259:       return;
                   1260:     }
                   1261:     sm_insert(node->left,v);
                   1262:   }
                   1263:   if (node->p < v) {
                   1264:     if (node->right == NULL) {
                   1265:       node->right = sm_newNode(v);
                   1266:       return;
                   1267:     }
                   1268:     sm_insert(node->right,v);
                   1269:   }
                   1270: }
                   1271: static int sm_count(struct sm_btree *rootp)
                   1272: {
                   1273:   if (rootp == NULL) return 0;
                   1274:   return (1+sm_count(rootp->left)+sm_count(rootp->right));
                   1275: }
                   1276:
1.16      takayama 1277: static int setTableOfxcolorForPS(struct sm_btree *rootp,
                   1278:                                  struct xcolorForPS *table,int k,int size)
                   1279: {
                   1280:   int m;
                   1281:   m = k;
                   1282:   if (rootp == NULL) return;
                   1283:   if (k >= size) {
                   1284:     warning(Can,"internal error of setTableOfxcolorForPS");
                   1285:   }
                   1286:   if (rootp->left != NULL) {
                   1287:     m = setTableOfxcolorForPS(rootp->left,table,k,size);
                   1288:   }
                   1289:
                   1290:   (table[m]).pixel = rootp->p;
                   1291:   m++;
                   1292:   if (rootp->right != NULL) {
                   1293:     m = setTableOfxcolorForPS(rootp->right,table,m,size);
                   1294:   }
                   1295:   return m;
                   1296: }
                   1297:
                   1298:
1.15      takayama 1299: static int getColorSizeOfImageForPS(int xsize,int ysize,XImage *image,
                   1300:                                     struct xcolorForPS **tableOfxcolorForPS)
                   1301: {
                   1302:   int x,y;
                   1303:   int size;
                   1304:   struct sm_btree root;
                   1305:   struct xcolorForPS *table;
1.16      takayama 1306:   XStandardColormap scm;
                   1307:   Colormap cm;
                   1308:   XColor color;
                   1309:   XColor white;
                   1310:   int screen,i;
                   1311:
1.15      takayama 1312:   root.p = 0;
                   1313:   root.left = NULL; root.right=NULL;
                   1314:   /* get color size */
                   1315:   for (x=0; x<xsize; x++) {
                   1316:     for (y=0; y<ysize; y++) {
                   1317:       sm_insert(&root,XGetPixel(image,x,y));
                   1318:     }
                   1319:   }
                   1320:   size=sm_count(&root);
                   1321:
                   1322:   table = (struct xcolorForPS *)MALLOC((size+1)*sizeof(struct xcolorForPS));
                   1323:   if (table == NULL) {
                   1324:        fprintf(stderr,"No more memory in getColorSizeOfImageForPS.\n");
                   1325:        return 0;
                   1326:   }
                   1327:   /* Set rgb values standing for the pixel values.
                   1328:   */
1.16      takayama 1329:   if (setTableOfxcolorForPS(&root,table,0,size) != size) {
                   1330:        warning(Can,"internal error.");
                   1331:        return ;
                   1332:   }
                   1333:
                   1334:   screen = DefaultScreen(display);
                   1335:   cm = DefaultColormap(display,screen);
                   1336:   /*  BUG: it does not work.
                   1337:   if (!XGetStandardColormap(display,RootWindow(display,DefaultScreen(display)),&scm,XA_RGB_DEFAULT_MAP)) {
                   1338:        warning(Can,"failed to open the X Standard Colormap.");
                   1339:        scm.red_max = 0xffff;
                   1340:        scm.green_max = 0xffff;
                   1341:        scm.blue_max = 0xffff;
                   1342:   }
                   1343:   */
                   1344:   /* Set by hand. */
                   1345:   scm.red_max = 0xffff;
                   1346:   scm.green_max = 0xffff;
                   1347:   scm.blue_max = 0xffff;
                   1348:   XParseColor(display,cm,"White",&white);
                   1349:   for (i=0; i<size; i++) {
                   1350:     color.pixel=(table[i]).pixel;
                   1351:     /*
                   1352:     {
                   1353:       char s[254];
                   1354:       sprintf(s,"%ld",color.pixel);
                   1355:       warning(Can,s);
                   1356:     }
                   1357:     */
                   1358:     XQueryColor(display,cm,&color);
                   1359:     (table[i]).r = ((double) color.red)/((double) scm.red_max);
                   1360:     (table[i]).g = ((double) color.green)/((double) scm.green_max);
                   1361:     (table[i]).b = ((double) color.blue)/((double) scm.blue_max);
                   1362:     if ((table[i]).r > 1.0) (table[i]).r = 1.0;
                   1363:     if ((table[i]).g > 1.0) (table[i]).g = 1.0;
                   1364:     if ((table[i]).b > 1.0) (table[i]).b = 1.0;
                   1365:     if (color.red == white.red && color.green == white.green
                   1366:         && color.blue == white.blue) {
                   1367:       (table[i]).print = 0;
                   1368:     }else{
                   1369:       (table[i]).print = 1;
                   1370:     }
                   1371:   }
1.15      takayama 1372:
                   1373:   *tableOfxcolorForPS = table;
                   1374:   return size;
                   1375: }
                   1376:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>