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