00001 #include "coxplot.h"
00002 #include <Xm/XmAll.h>
00003 
00004 
00005 
00006 
00007 
00008 
00009 static char print_command[256] = "\0" ;
00010 static char * redcolor = NULL ;
00011 
00012 #ifndef LABEL_ARG
00013 #define LABEL_ARG(str) \
00014   XtVaTypedArg , XmNlabelString , XmRString , (str) , strlen(str)+1
00015 #endif
00016 
00017 #ifndef BGCOLOR_ARG
00018 #define BGCOLOR_ARG(str) \
00019   XtVaTypedArg , XmNbackground , XmRString , (str) , strlen(str)+1
00020 #endif
00021 
00022 #ifndef HOTCOLOR
00023 #define HOTCOLOR(ww,ss)                                                        \
00024   { char * xdef = XGetDefault(XtDisplay(ww),"AFNI","hotcolor") ;               \
00025     if( xdef == NULL ) xdef = getenv("AFNI_hotcolor") ;                        \
00026     if( xdef == NULL ) xdef = getenv("AFNI_HOTCOLOR") ;                        \
00027     if( xdef == NULL ) xdef = XGetDefault(XtDisplay(ww),"AFNI","background") ; \
00028     (ss) = (xdef != NULL) ? (xdef) : ("gray40") ; }
00029 #endif
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 static void beep_CB( Widget w , XtPointer cd , XtPointer cb )
00038 {
00039    char * str = (char *) cd ;
00040 
00041    if( w != NULL ) XBell(XtDisplay(w),100) ;
00042    if( str != NULL ) fprintf(stderr,"%s\a\n",str) ;
00043    return ;
00044 }
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 static void pscancel_CB( Widget w , XtPointer cd , XtPointer cb )
00053 {
00054    MEM_topshell_data * mpcb = (MEM_topshell_data *) cd ;
00055 
00056    if( mpcb == NULL || ! MTD_VALID(mpcb) ) return ;
00057 
00058    if( mpcb->dial != NULL ) XtDestroyWidget( mpcb->dial ) ;
00059    mpcb->dial = mpcb->wtf = NULL ;
00060    return ;
00061 }
00062 
00063 
00064 
00065 static void psfinalize_CB( Widget w , XtPointer cd , XtPointer cb )
00066 {
00067    MEM_topshell_data * mpcb = (MEM_topshell_data *) cd ;
00068    char * text , fname[64] ;
00069    int ii , ll ;
00070 
00071    if( mpcb == NULL || ! MTD_VALID(mpcb) ) return ;
00072 
00073    if( mpcb->dial == NULL ){ XBell(XtDisplay(w),100) ; return ; }
00074 
00075    text = XmTextFieldGetString( mpcb->wtf ) ;
00076    if( text == NULL || text[0] == '\0' ){ XBell(XtDisplay(w),100) ; return ; }
00077 
00078    ll = strlen(text) ;
00079    for( ii=0 ; ii < ll ; ii++ ){
00080       if( iscntrl(text[ii]) || isspace(text[ii]) ||
00081           text[ii] == '/'   || text[ii] == ';'   ||
00082           text[ii] == '*'   || text[ii] == '?'   ||
00083           text[ii] == '&'   || text[ii] == '|'   ||
00084           text[ii] == '"'   || text[ii] == '>'   ||
00085           text[ii] == '<'   || text[ii] == '\''  ||
00086           text[ii] == '['   || text[ii] == ']'     ){
00087 
00088         XBell(XtDisplay(w),100) ; return ;
00089       }
00090    }
00091 
00092    strcpy(fname,text) ;
00093    if( !(ll > 2 && text[ll-2] == 'p' && text[ll-1] == 's' ) )
00094       strcat(fname,".ps") ;
00095 
00096    memplot_to_postscript( fname , mpcb->mp ) ;
00097 
00098    XtDestroyWidget( mpcb->dial ) ;
00099    mpcb->dial = mpcb->wtf = NULL ;
00100    return ;
00101 }
00102 
00103 
00104 
00105 static void psfile_CB( Widget w , XtPointer cd , XtPointer cb )
00106 {
00107    MEM_topshell_data * mpcb = (MEM_topshell_data *) cd ;
00108    Widget wpop , wrc , wlab , wtf , form , but0 , but1 ;
00109    int ibut = 0 ;
00110    Position xx,yy ;
00111 
00112    if( mpcb == NULL || ! MTD_VALID(mpcb) ) return ;
00113 
00114    if( mpcb->dial != NULL ){ XBell(XtDisplay(w),100) ; return ; }
00115 
00116    mpcb->dial = wpop = XtVaCreatePopupShell(
00117              "AFNI" , xmDialogShellWidgetClass , mpcb->top ,
00118                 XmNtraversalOn , False ,
00119                 XmNinitialResourcesPersistent , False ,
00120              NULL ) ;
00121 
00122    XtVaSetValues( wpop ,
00123                      XmNmwmDecorations , MWM_DECOR_BORDER ,
00124                      XmNmwmFunctions   ,  MWM_FUNC_MOVE ,
00125                   NULL ) ;
00126 
00127    wrc  = XtVaCreateWidget(
00128              "menu" , xmRowColumnWidgetClass , wpop ,
00129                 XmNpacking      , XmPACK_TIGHT ,
00130                 XmNorientation  , XmVERTICAL ,
00131                 XmNtraversalOn , False ,
00132                 XmNinitialResourcesPersistent , False ,
00133              NULL ) ;
00134 
00135    wlab = XtVaCreateManagedWidget(
00136              "menu" , xmLabelWidgetClass , wrc ,
00137                 LABEL_ARG("PostScript filename:") ,
00138                 XmNinitialResourcesPersistent , False ,
00139              NULL ) ;
00140 
00141    mpcb->wtf = wtf = XtVaCreateManagedWidget(
00142              "menu" , xmTextFieldWidgetClass , wrc ,
00143                  XmNcolumns         , 20 ,
00144                  XmNeditable        , True ,
00145                  XmNmaxLength       , 32 ,
00146                  XmNresizeWidth     , False ,
00147                  XmNmarginHeight    , 1 ,
00148                  XmNmarginWidth     , 1 ,
00149                  XmNcursorPositionVisible , True ,
00150                  XmNblinkRate , 0 ,
00151                  XmNautoShowCursorPosition , True ,
00152                  XmNinitialResourcesPersistent , False ,
00153                  XmNtraversalOn , False ,
00154               NULL ) ;
00155    XtAddCallback( wtf, XmNactivateCallback, psfinalize_CB, cd ) ; 
00156 
00157 #undef TIG
00158 #undef NBUT
00159 #define TIG  20
00160 #define NBUT 2
00161 
00162    form = XtVaCreateWidget( "menu" , xmFormWidgetClass , wrc ,
00163                                XmNborderWidth , 0 ,
00164                                XmNfractionBase , TIG*NBUT - 1 ,
00165                                XmNinitialResourcesPersistent , False ,
00166                             NULL ) ;
00167 
00168    ibut = 0 ;
00169    but0 = XtVaCreateManagedWidget(
00170                  "menu" , xmPushButtonWidgetClass , form ,
00171                     LABEL_ARG("Cancel") ,
00172                     XmNtopAttachment  , XmATTACH_FORM ,
00173 
00174                     XmNleftAttachment   ,
00175                         (ibut!=0) ? XmATTACH_POSITION : XmATTACH_FORM ,
00176                     XmNleftPosition , ibut*TIG ,
00177 
00178                     XmNrightAttachment  ,
00179                      (ibut==NBUT-1) ? XmATTACH_FORM : XmATTACH_POSITION ,
00180                     XmNrightPosition , ibut*TIG + (TIG-1) ,
00181 
00182                     XmNrecomputeSize , False ,
00183                     XmNtraversalOn   , False ,
00184                     XmNinitialResourcesPersistent , False ,
00185                  NULL ) ;
00186    XtAddCallback( but0 , XmNactivateCallback , pscancel_CB , cd ) ;
00187 
00188 
00189    if( redcolor == NULL ){ HOTCOLOR(form,redcolor) ; }
00190    ibut++ ;
00191    but1 = XtVaCreateManagedWidget(
00192                  "menu" , xmPushButtonWidgetClass , form ,
00193                     LABEL_ARG("Save") ,
00194 #if 1
00195                     BGCOLOR_ARG(redcolor) ,
00196 #endif
00197 
00198                     XmNtopAttachment  , XmATTACH_FORM ,
00199 
00200                     XmNleftAttachment   ,
00201                         (ibut!=0) ? XmATTACH_POSITION : XmATTACH_FORM ,
00202                     XmNleftPosition , ibut*TIG ,
00203 
00204                     XmNrightAttachment  ,
00205                      (ibut==NBUT-1) ? XmATTACH_FORM : XmATTACH_POSITION ,
00206                     XmNrightPosition , ibut*TIG + (TIG-1) ,
00207 
00208                     XmNrecomputeSize , False ,
00209                     XmNtraversalOn   , False ,
00210                     XmNinitialResourcesPersistent , False ,
00211                  NULL ) ;
00212    XtAddCallback( but1 , XmNactivateCallback , psfinalize_CB , cd ) ;
00213 
00214    XtTranslateCoords( mpcb->top , 15,15 , &xx , &yy ) ;
00215    XtVaSetValues( wpop , XmNx , (int) xx , XmNy , (int) yy , NULL ) ;
00216 
00217    XtManageChild( form ) ;
00218    XtManageChild( wrc ) ;
00219    XtPopup( wpop , XtGrabNone ) ;
00220    return ;
00221 }
00222 
00223 
00224 
00225 
00226 
00227 static void psprint_CB( Widget w , XtPointer cd , XtPointer cb )
00228 {
00229    MEM_topshell_data * mpcb = (MEM_topshell_data *) cd ;
00230    MEM_plotdata * mp ;
00231 
00232    if( mpcb == NULL ) return ;
00233    mp = mpcb->mp ; if( mp == NULL ) return ;
00234    memplot_to_postscript( print_command , mp ) ;
00235    return ;
00236 }
00237 
00238 
00239 
00240 
00241 
00242 static void donebut_CB( Widget w , XtPointer cd , XtPointer cb )
00243 {
00244    MEM_topshell_data * mpcb = (MEM_topshell_data *) cd ;
00245 
00246    if( mpcb == NULL || ! MTD_VALID(mpcb) ) return ;
00247 
00248    mpcb->valid = 0 ;
00249 
00250    if( mpcb->killfunc != NULL ) mpcb->killfunc( mpcb ) ;
00251 
00252    if( mpcb->dial != NULL ) XtDestroyWidget( mpcb->dial ) ;
00253 #ifdef HAVE_XDBE
00254    if( mpcb->have_xdbe )
00255       XdbeDeallocateBackBufferName( XtDisplay(mpcb->top) , mpcb->buf_xdbe ) ;
00256 #endif
00257    XtDestroyWidget( mpcb->top ) ;
00258    delete_memplot( mpcb->mp ) ;
00259    free(mpcb) ;
00260 
00261    return ;
00262 }
00263 
00264 
00265 
00266 
00267 
00268 static void expose_CB( Widget w , XtPointer cd , XtPointer cb )
00269 {
00270    XmDrawingAreaCallbackStruct * cbs = (XmDrawingAreaCallbackStruct *) cb ;
00271    MEM_topshell_data * mpcb = (MEM_topshell_data *) cd ;
00272    MEM_plotdata * mp ;
00273    XEvent evjunk ;
00274    Display * dpy = XtDisplay(w) ;
00275    Window  win   = XtWindow(w) ;
00276    Drawable dw   = win ;                               
00277 
00278    if( win == (Window) 0 ) return ;  
00279    if( mpcb == NULL ) return ;
00280    mp = mpcb->mp ; if( mp == NULL ) return ;
00281 
00282    if( cbs != NULL ){
00283       XExposeEvent * ev = (XExposeEvent *) cbs->event ;
00284       if( ev->count > 0 ) return ;
00285    }
00286 
00287 #ifdef HAVE_XDBE
00288    if( use_xdbe > 0 && mpcb->have_xdbe == 0 ){
00289       XdbeSwapInfo info_xdbe ;
00290 
00291       mpcb->buf_xdbe  = XdbeAllocateBackBufferName( dpy,win,XdbeBackground );
00292       mpcb->have_xdbe = 1 ;
00293 
00294       set_X11_background( dpy , win , 255,255,255 ) ;
00295       info_xdbe.swap_window = win ;
00296       info_xdbe.swap_action = XdbeBackground ;
00297       XdbeSwapBuffers( dpy , &info_xdbe , 1 ) ;
00298    }
00299 
00300    if( mpcb->have_xdbe ) dw = mpcb->buf_xdbe ;         
00301 #endif
00302 
00303    set_X11_background( dpy , win , 255,255,255 ) ;
00304    if( dw == win ) XClearWindow( dpy , win ) ;
00305    memplot_to_X11_sef( dpy , dw , mp , 0,0,1 ) ;
00306 
00307 #ifdef HAVE_XDBE
00308    if( mpcb->have_xdbe ){
00309       XdbeSwapInfo info_xdbe ;
00310       info_xdbe.swap_window = win ;
00311       info_xdbe.swap_action = XdbeBackground ;
00312       XdbeSwapBuffers( dpy , &info_xdbe , 1 ) ;
00313     }
00314 #endif
00315 
00316    while( XCheckWindowEvent(dpy, win ,
00317                             ExposureMask|StructureNotifyMask,&evjunk) ) ;
00318 
00319    return ;
00320 }
00321 
00322 void redraw_topshell( MEM_topshell_data * mpcb )
00323 {
00324    if( mpcb == NULL ) return ;
00325    expose_CB( mpcb->drawing , mpcb , NULL ) ;
00326    return ;
00327 }
00328 
00329 
00330 
00331 
00332 
00333 static void resize_CB( Widget w , XtPointer cd , XtPointer cb )
00334 {
00335    expose_CB( w , cd , NULL ) ;
00336    return ;
00337 }
00338 
00339 
00340 
00341 
00342 
00343 void plotkill_topshell( MEM_topshell_data * mpcb )
00344 {
00345    if( mpcb == NULL || ! MTD_VALID(mpcb) ) return ;
00346 
00347    donebut_CB( NULL , (XtPointer) mpcb , NULL ) ;
00348    return ;
00349 }
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 MEM_topshell_data * memplot_to_topshell( Display * dpy,
00368                                          MEM_plotdata * mp, void_func * kfun )
00369 {
00370    Widget topshell , drawing , donebut , form , psfilebut , psprintbut ;
00371    MEM_topshell_data * mpcb ;
00372    int hmin=200 , wmin , ibut=0 ;
00373    char * prc ;
00374 
00375    
00376 
00377    if( dpy == NULL || mp == NULL ) return NULL ;
00378 
00379    mpcb = (MEM_topshell_data *) malloc( sizeof(MEM_topshell_data) ) ;
00380    mpcb->valid = 0 ;
00381 
00382 #ifdef HAVE_XDBE
00383    init_XDBE(dpy) ; mpcb->have_xdbe = 0 ;
00384 #endif
00385 
00386    wmin = MEMPLOT_ASPECT(mp) * hmin ;
00387 
00388    
00389 
00390    topshell = XtVaAppCreateShell(
00391                  "AFNI" , "AFNI" , topLevelShellWidgetClass , dpy ,
00392                    XmNborderWidth ,   0  ,
00393                    XmNminHeight   , hmin , XmNheight , hmin ,
00394                    XmNminWidth    , wmin , XmNwidth  , wmin ,
00395                    XmNallowShellResize , False ,
00396                    XmNinitialResourcesPersistent , False ,
00397                    XmNdeleteResponse   , XmDO_NOTHING ,   
00398                  NULL ) ;
00399 
00400    XmAddWMProtocolCallback(
00401         topshell , XmInternAtom(dpy,"WM_DELETE_WINDOW",False) ,
00402         donebut_CB , (XtPointer) mpcb ) ;
00403 
00404    mpcb->top = topshell ;
00405    mpcb->mp  = mp ;
00406    mpcb->dial= NULL ;
00407    mpcb->wtf = NULL ;
00408 
00409    mpcb->killfunc = kfun ;
00410 
00411    
00412 
00413 #undef TIG
00414 #undef NBUT
00415 #define TIG  20
00416 #define NBUT 3
00417 
00418    mpcb->form = form =
00419         XtVaCreateWidget( "dialog" , xmFormWidgetClass , topshell ,
00420                              XmNborderWidth , 0 ,
00421                              XmNfractionBase , TIG*NBUT - 1 ,
00422                              XmNinitialResourcesPersistent , False ,
00423                           NULL ) ;
00424 
00425    
00426 
00427    if( redcolor == NULL ){ HOTCOLOR(form,redcolor) ; }
00428 
00429    ibut = 0 ;
00430    psfilebut = XtVaCreateManagedWidget(
00431                  "dialog" , xmPushButtonWidgetClass , form ,
00432                     LABEL_ARG("PS->file") ,
00433                     XmNtopAttachment  , XmATTACH_FORM ,
00434 
00435                     XmNleftAttachment   ,
00436                         (ibut!=0) ? XmATTACH_POSITION : XmATTACH_FORM ,
00437                     XmNleftPosition , ibut*TIG ,
00438 
00439                     XmNrightAttachment  ,
00440                      (ibut==NBUT-1) ? XmATTACH_FORM : XmATTACH_POSITION ,
00441                     XmNrightPosition , ibut*TIG + (TIG-1) ,
00442 
00443                     XmNrecomputeSize , False ,
00444                     XmNtraversalOn   , False ,
00445                     XmNinitialResourcesPersistent , False ,
00446                  NULL ) ;
00447    XtAddCallback( psfilebut , XmNactivateCallback , psfile_CB , (XtPointer) mpcb ) ;
00448 
00449    ibut++ ;
00450    psprintbut = XtVaCreateManagedWidget(
00451                  "dialog" , xmPushButtonWidgetClass , form ,
00452                     LABEL_ARG("->printer") ,
00453                     XmNtopAttachment  , XmATTACH_FORM ,
00454 
00455                     XmNleftAttachment   ,
00456                         (ibut!=0) ? XmATTACH_POSITION : XmATTACH_FORM ,
00457                     XmNleftPosition , ibut*TIG ,
00458 
00459                     XmNrightAttachment  ,
00460                      (ibut==NBUT-1) ? XmATTACH_FORM : XmATTACH_POSITION ,
00461                     XmNrightPosition , ibut*TIG + (TIG-1) ,
00462 
00463                     XmNrecomputeSize , False ,
00464                     XmNtraversalOn   , False ,
00465                     XmNinitialResourcesPersistent , False ,
00466                  NULL ) ;
00467    prc = getenv( "AFNI_PSPRINT" ) ;
00468    if( prc != NULL ){
00469       sprintf( print_command , "|%.250s" , prc ) ;
00470       XtAddCallback( psprintbut , XmNactivateCallback , psprint_CB , (XtPointer) mpcb ) ;
00471    } else {
00472       XtAddCallback( psprintbut , XmNactivateCallback , beep_CB ,
00473                      (XtPointer) "*** AFNI_PSPRINT not defined - see README.environment" ) ;
00474    }
00475 
00476    ibut++ ;
00477    donebut = XtVaCreateManagedWidget(
00478                  "dialog" , xmPushButtonWidgetClass , form ,
00479                     LABEL_ARG("Done") ,
00480 #if 1
00481                     BGCOLOR_ARG(redcolor) ,
00482 #endif
00483 
00484                     XmNtopAttachment  , XmATTACH_FORM ,
00485 
00486                     XmNleftAttachment   ,
00487                         (ibut!=0) ? XmATTACH_POSITION : XmATTACH_FORM ,
00488                     XmNleftPosition , ibut*TIG ,
00489 
00490                     XmNrightAttachment  ,
00491                      (ibut==NBUT-1) ? XmATTACH_FORM : XmATTACH_POSITION ,
00492                     XmNrightPosition , ibut*TIG + (TIG-1) ,
00493 
00494                     XmNrecomputeSize , False ,
00495                     XmNtraversalOn   , False ,
00496                     XmNinitialResourcesPersistent , False ,
00497                  NULL ) ;
00498    XtAddCallback( donebut , XmNactivateCallback , donebut_CB , (XtPointer) mpcb ) ;
00499 
00500    
00501 
00502    drawing = XtVaCreateManagedWidget( "dialog" , xmDrawingAreaWidgetClass , form ,
00503                                           XmNtopAttachment    , XmATTACH_WIDGET ,
00504                                           XmNtopWidget        , donebut ,
00505                                           XmNleftAttachment   , XmATTACH_FORM ,
00506                                           XmNrightAttachment  , XmATTACH_FORM ,
00507                                           XmNbottomAttachment , XmATTACH_FORM ,
00508                                           XmNinitialResourcesPersistent , False ,
00509                                         NULL ) ;
00510 
00511    XtAddCallback( drawing , XmNexposeCallback , expose_CB , (XtPointer) mpcb ) ;
00512    XtAddCallback( drawing , XmNresizeCallback , resize_CB , (XtPointer) mpcb ) ;
00513 
00514    
00515 
00516    XtVaSetValues( form , BGCOLOR_ARG("white") , NULL ) ;
00517 
00518    XtManageChild(form) ;
00519    XtRealizeWidget(topshell);
00520 
00521    mpcb->valid = 1 ; mpcb->userdata = NULL ; mpcb->drawing = drawing ;
00522    return mpcb ;
00523 }