00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #define NEED_PLDEBUG
00067 #include "plserver.h"
00068 #include "pltkwd.h"
00069 #include "tcpip.h"
00070
00071 #ifdef __WIN32__
00072 #define XSynchronize( display, bool ) { display->request++; }
00073 #define XSync( display, bool ) { display->request++; }
00074 #define XFlush( display )
00075 #endif
00076
00077 #ifdef DEBUG_ENTER
00078
00079 #undef dbug_enter
00080 #define dbug_enter( a ) if ( plsc->debug ) { \
00081 Tcl_Write( Tcl_GetStdChannel( TCL_STDERR ), a, -1 ); }
00082 #endif
00083
00084 #ifndef __WIN32__
00085 #ifdef PL_HAVE_UNISTD_H
00086 #include <unistd.h>
00087 #include <fcntl.h>
00088 #endif
00089 #endif
00090
00091
00092
00093
00094 #define NDEV 20 // Max number of output device types
00095
00096
00097
00098
00099
00100
00101 typedef struct PlPlotter
00102 {
00103
00104
00105 Tk_Window tkwin;
00106
00107
00108
00109 Display *display;
00110
00111
00112 Tcl_Interp *interp;
00113
00114
00115 Tcl_Command widgetCmd;
00116 Tk_3DBorder border;
00117
00118 int borderWidth;
00119 int relief;
00120 int width;
00121
00122 int height;
00123
00124 Tk_Cursor cursor;
00125 int flags;
00126
00127
00128
00129
00130
00131
00132 int tkwin_initted;
00133 PLStream *pls;
00134 PLINT ipls;
00135 PLINT ipls_save;
00136
00137 PLRDev *plr;
00138 char *plpr_cmd;
00139
00140
00141 int active_plot;
00142 int isActive;
00143
00144
00145
00146 PLDisplay pldis;
00147 int prevWidth;
00148 int prevHeight;
00149
00150
00151
00152 char *SaveFnam;
00153
00154 char **devDesc;
00155
00156 char **devName;
00157
00158
00159
00160
00161 GC xorGC;
00162 XPoint pts[5];
00163 int continue_draw;
00164 Tk_Cursor xhair_cursor;
00165 PLFLT xl, xr, yl, yr;
00166 char *xScrollCmd;
00167
00168
00169 char *yScrollCmd;
00170
00171
00172
00173
00174
00175 char *bopCmd;
00176 char *eopCmd;
00177
00178
00179
00180 int xhairs;
00181 int drawing_xhairs;
00182 XPoint xhair_x[2];
00183 XPoint xhair_y[2];
00184
00185
00186
00187 int rband;
00188 int drawing_rband;
00189 XPoint rband_pt[2];
00190 int double_buffer;
00191 } PlPlotter;
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 #define REFRESH_PENDING 1
00208 #define RESIZE_PENDING 2
00209 #define REDRAW_PENDING 4
00210 #define UPDATE_V_SCROLLBAR 8
00211 #define UPDATE_H_SCROLLBAR 16
00212
00213
00214
00215 #define DEF_PLFRAME_BG_COLOR "Black"
00216 #define DEF_PLFRAME_BG_MONO "White"
00217 #define DEF_PLFRAME_BORDER_WIDTH "0"
00218 #define DEF_PLFRAME_CURSOR ( (char *) NULL )
00219 #define DEF_PLFRAME_HEIGHT "250"
00220 #define DEF_PLFRAME_RELIEF "flat"
00221 #define DEF_PLFRAME_WIDTH "250"
00222
00223
00224
00225 static Tk_ConfigSpec configSpecs[] = {
00226 { TK_CONFIG_BOOLEAN, "-activeplot", (char *) NULL, (char *) NULL,
00227 "1", Tk_Offset( PlPlotter, active_plot ), TK_CONFIG_DONT_SET_DEFAULT },
00228 { TK_CONFIG_BORDER, "-background", "background", "Background",
00229 DEF_PLFRAME_BG_COLOR, Tk_Offset( PlPlotter, border ),
00230 TK_CONFIG_COLOR_ONLY },
00231 { TK_CONFIG_BORDER, "-background", "background", "Background",
00232 DEF_PLFRAME_BG_MONO, Tk_Offset( PlPlotter, border ),
00233 TK_CONFIG_MONO_ONLY },
00234 { TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
00235 (char *) NULL, 0, 0 },
00236 { TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
00237 (char *) NULL, 0, 0 },
00238 { TK_CONFIG_STRING, "-bopcmd", "bopcmd", "PgCommand",
00239 (char *) NULL, Tk_Offset( PlPlotter, bopCmd ), TK_CONFIG_NULL_OK },
00240 { TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
00241 DEF_PLFRAME_BORDER_WIDTH, Tk_Offset( PlPlotter, borderWidth ), 0 },
00242 { TK_CONFIG_BOOLEAN, "-doublebuffer", (char *) NULL, (char *) NULL,
00243 "0", Tk_Offset( PlPlotter, double_buffer ), TK_CONFIG_DONT_SET_DEFAULT },
00244 { TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
00245 DEF_PLFRAME_CURSOR, Tk_Offset( PlPlotter, cursor ), TK_CONFIG_NULL_OK },
00246 { TK_CONFIG_STRING, "-eopcmd", "eopcmd", "PgCommand",
00247 (char *) NULL, Tk_Offset( PlPlotter, eopCmd ), TK_CONFIG_NULL_OK },
00248 { TK_CONFIG_PIXELS, "-height", "height", "Height",
00249 DEF_PLFRAME_HEIGHT, Tk_Offset( PlPlotter, height ), 0 },
00250 { TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
00251 DEF_PLFRAME_RELIEF, Tk_Offset( PlPlotter, relief ), 0 },
00252 { TK_CONFIG_PIXELS, "-width", "width", "Width",
00253 DEF_PLFRAME_WIDTH, Tk_Offset( PlPlotter, width ), 0 },
00254 { TK_CONFIG_BOOLEAN, "-xhairs", (char *) NULL, (char *) NULL,
00255 "0", Tk_Offset( PlPlotter, xhairs ), TK_CONFIG_DONT_SET_DEFAULT },
00256 { TK_CONFIG_BOOLEAN, "-rubberband", (char *) NULL, (char *) NULL,
00257 "0", Tk_Offset( PlPlotter, rband ), TK_CONFIG_DONT_SET_DEFAULT },
00258 { TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
00259 (char *) NULL, Tk_Offset( PlPlotter, xScrollCmd ), TK_CONFIG_NULL_OK },
00260 { TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
00261 (char *) NULL, Tk_Offset( PlPlotter, yScrollCmd ), TK_CONFIG_NULL_OK },
00262 { TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
00263 (char *) NULL, 0, 0 }
00264 };
00265
00266
00267
00268
00269
00270 int plPlotterCmd( ClientData, Tcl_Interp *, int, const char ** );
00271 void PlplotterAtEop( Tcl_Interp *interp, register PlPlotter *plPlotterPtr );
00272 void PlplotterAtBop( Tcl_Interp *interp, register PlPlotter *plPlotterPtr );
00273
00274
00275
00276 static void DestroyPlPlotter( ClientData );
00277 static void DisplayPlPlotter( ClientData );
00278 static void PlPlotterInit( ClientData );
00279 static void PlPlotterFirstInit( ClientData clientData );
00280 static void PlPlotterConfigureEH( ClientData, XEvent * );
00281 static void PlPlotterExposeEH( ClientData, XEvent * );
00282 static void PlPlotterMotionEH( ClientData, register XEvent * );
00283 static void PlPlotterEnterEH( ClientData, register XEvent * );
00284 static void PlPlotterLeaveEH( ClientData, register XEvent * );
00285 static void PlPlotterButtonPressEH( ClientData clientData, register XEvent * );
00286 static int PlPlotterWidgetCmd( ClientData, Tcl_Interp *, int, CONST char ** );
00287 static int ReadData( ClientData, int );
00288 static void Install_cmap( PlPlotter *plPlotterPtr );
00289
00290
00291
00292 static int Closelink( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00293 static int Cmd( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00294 static int ConfigurePlPlotter( Tcl_Interp *, PlPlotter *, int, CONST char **, int );
00295 static int Draw( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00296 static int Info( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00297 static int Openlink( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00298 static int Orient( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00299 static int Page( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00300 static int NextPage( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00301 static int Print( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00302 static int Redraw( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00303 static int Save( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00304 static int View( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00305 static int Scroll( Tcl_Interp *, PlPlotter * );
00306 static int report( Tcl_Interp *, PlPlotter *, int, CONST char ** );
00307
00308
00309
00310 static void ActiveState( register PlPlotter *plPlotterPtr, int on );
00311 static void CreateXhairs( PlPlotter * );
00312 static void DestroyXhairs( PlPlotter * );
00313 static void DrawXhairs( PlPlotter *, int, int );
00314 static void UpdateXhairs( PlPlotter * );
00315
00316
00317
00318 static void CreateRband( PlPlotter * );
00319 static void DestroyRband( PlPlotter * );
00320 static void DrawRband( PlPlotter *, int, int );
00321 static void UpdateRband( PlPlotter * );
00322
00323
00324
00325 static void gbox( PLFLT *, PLFLT *, PLFLT *, PLFLT *, CONST char ** );
00326 static void UpdateVScrollbar( register PlPlotter * );
00327 static void UpdateHScrollbar( register PlPlotter * );
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 int
00348 plPlotterCmd( ClientData clientData, Tcl_Interp *interp,
00349 int argc, const char **argv )
00350 {
00351 Tk_Window tkwin;
00352 register PlPlotter *plPlotterPtr;
00353 register PLRDev *plr;
00354 int i, ndev;
00355
00356 dbug_enter( "plPlotterCmd" );
00357
00358 if ( argc < 2 )
00359 {
00360 Tcl_AppendResult( interp, "wrong # args: should be \"",
00361 argv[0], " pathName ?options?\"", (char *) NULL );
00362 return TCL_ERROR;
00363 }
00364
00365
00366
00367 tkwin = Tk_CreateWindowFromPath( interp, Tk_MainWindow( interp ), argv[1], (char *) NULL );
00368 if ( tkwin == NULL )
00369 {
00370 return TCL_ERROR;
00371 }
00372 Tk_SetClass( tkwin, "Plframe" );
00373
00374 plPlotterPtr = (PlPlotter *) malloc( sizeof ( PlPlotter ) );
00375 plPlotterPtr->tkwin = tkwin;
00376 plPlotterPtr->display = Tk_Display( tkwin );
00377 plPlotterPtr->interp = interp;
00378 plPlotterPtr->widgetCmd =
00379 Tcl_CreateCommand( interp, Tk_PathName( plPlotterPtr->tkwin ),
00380 (Tcl_CmdProc *) PlPlotterWidgetCmd, (ClientData) plPlotterPtr,
00381 (Tcl_CmdDeleteProc *) NULL );
00382 plPlotterPtr->xorGC = NULL;
00383 plPlotterPtr->border = NULL;
00384 plPlotterPtr->cursor = None;
00385 plPlotterPtr->xhair_cursor = None;
00386 plPlotterPtr->flags = 0;
00387 plPlotterPtr->width = Tk_Width( plPlotterPtr->tkwin );
00388 plPlotterPtr->height = Tk_Height( plPlotterPtr->tkwin );
00389 plPlotterPtr->prevWidth = 0;
00390 plPlotterPtr->prevHeight = 0;
00391 plPlotterPtr->continue_draw = 0;
00392 plPlotterPtr->ipls = 0;
00393 plPlotterPtr->ipls_save = 0;
00394 plPlotterPtr->tkwin_initted = 0;
00395 plPlotterPtr->plpr_cmd = NULL;
00396 plPlotterPtr->bopCmd = NULL;
00397 plPlotterPtr->eopCmd = NULL;
00398 plPlotterPtr->xhairs = 0;
00399 plPlotterPtr->active_plot = 1;
00400 plPlotterPtr->isActive = 0;
00401 plPlotterPtr->drawing_xhairs = 0;
00402 plPlotterPtr->rband = 0;
00403 plPlotterPtr->drawing_rband = 0;
00404 plPlotterPtr->xScrollCmd = NULL;
00405 plPlotterPtr->yScrollCmd = NULL;
00406 plPlotterPtr->xl = 0.;
00407 plPlotterPtr->yl = 0.;
00408 plPlotterPtr->xr = 1.;
00409 plPlotterPtr->yr = 1.;
00410 plPlotterPtr->SaveFnam = NULL;
00411
00412 plPlotterPtr->plr = (PLRDev *) malloc( sizeof ( PLRDev ) );
00413 plr = plPlotterPtr->plr;
00414 plr->pdfs = NULL;
00415 plr->iodev = (PLiodev *) malloc( sizeof ( PLiodev ) );
00416 plr_start( plr );
00417
00418
00419
00420 plmkstrm( &plPlotterPtr->ipls );
00421 plgpls( &plPlotterPtr->pls );
00422
00423 plPlotterPtr->pls->plPlotterPtr = plPlotterPtr;
00424
00425
00426
00427 plPlotterPtr->xhair_cursor =
00428 Tk_GetCursor( plPlotterPtr->interp, plPlotterPtr->tkwin, "crosshair" );
00429
00430
00431
00432 plD_open_tkwin( plPlotterPtr->pls );
00433
00434
00435
00436 plPlotterPtr->devDesc = (char **) malloc( NDEV * sizeof ( char ** ) );
00437 plPlotterPtr->devName = (char **) malloc( NDEV * sizeof ( char ** ) );
00438 for ( i = 0; i < NDEV; i++ )
00439 {
00440 plPlotterPtr->devDesc[i] = NULL;
00441 plPlotterPtr->devName[i] = NULL;
00442 }
00443 ndev = NDEV;
00444 plgFileDevs( (const char ***) &plPlotterPtr->devDesc, (const char ***) &plPlotterPtr->devName, &ndev );
00445
00446
00447
00448 Tk_CreateEventHandler( plPlotterPtr->tkwin, StructureNotifyMask,
00449 PlPlotterConfigureEH, (ClientData) plPlotterPtr );
00450
00451 Tk_CreateEventHandler( plPlotterPtr->tkwin, ExposureMask,
00452 PlPlotterExposeEH, (ClientData) plPlotterPtr );
00453
00454
00455 ActiveState( plPlotterPtr, 1 );
00456
00457 if ( ConfigurePlPlotter( interp, plPlotterPtr, argc - 2, (CONST char **) argv + 2, 0 ) != TCL_OK )
00458 {
00459 Tk_DestroyWindow( plPlotterPtr->tkwin );
00460 return TCL_ERROR;
00461 }
00462 Tk_MakeWindowExist( plPlotterPtr->tkwin );
00463 PlPlotterFirstInit( (ClientData) plPlotterPtr );
00464 Tk_GeometryRequest( plPlotterPtr->tkwin, 200, 200 );
00465
00466 interp->result = Tk_PathName( plPlotterPtr->tkwin );
00467
00468 return TCL_OK;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 static int
00490 PlPlotterWidgetCmd( ClientData clientData, Tcl_Interp *interp,
00491 int argc, CONST char **argv )
00492 {
00493 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
00494 int result = TCL_OK;
00495 int length;
00496 char c;
00497
00498 dbug_enter( "PlPlotterWidgetCmd" );
00499
00500 if ( argc < 2 )
00501 {
00502 Tcl_AppendResult( interp, "wrong # args: should be \"",
00503 argv[0], " option ?arg arg ...?\"", (char *) NULL );
00504 return TCL_ERROR;
00505 }
00506 Tk_Preserve( (ClientData) plPlotterPtr );
00507 c = argv[1][0];
00508 length = strlen( argv[1] );
00509
00510
00511
00512 if ( ( c == 'c' ) && ( strncmp( argv[1], "cmd", length ) == 0 ) )
00513 {
00514 result = Cmd( interp, plPlotterPtr, argc - 2, argv + 2 );
00515 }
00516
00517
00518
00519 else if ( ( c == 'c' ) && ( strncmp( argv[1], "cget", length ) == 0 )
00520 && ( length >= 2 ) )
00521 {
00522 if ( argc != 3 )
00523 {
00524 Tcl_AppendResult( interp, "wrong # args: should be \"",
00525 argv[0], " cget option\"",
00526 (char *) NULL );
00527 result = TCL_ERROR;
00528 goto done;
00529 }
00530 result = Tk_ConfigureValue( interp, plPlotterPtr->tkwin, configSpecs,
00531 (char *) plPlotterPtr, argv[2], 0 );
00532 }
00533 else if ( ( c == 'c' ) && ( strncmp( argv[1], "configure", length ) == 0 ) )
00534 {
00535 if ( argc == 2 )
00536 {
00537 result = Tk_ConfigureInfo( interp, plPlotterPtr->tkwin, configSpecs,
00538 (char *) plPlotterPtr, (char *) NULL, 0 );
00539 }
00540 else if ( argc == 3 )
00541 {
00542 result = Tk_ConfigureInfo( interp, plPlotterPtr->tkwin, configSpecs,
00543 (char *) plPlotterPtr, argv[2], 0 );
00544 }
00545 else
00546 {
00547 result = ConfigurePlPlotter( interp, plPlotterPtr, argc - 2, argv + 2,
00548 TK_CONFIG_ARGV_ONLY );
00549 }
00550 }
00551
00552
00553
00554 else if ( ( c == 'c' ) && ( strncmp( argv[1], "closelink", length ) == 0 ) )
00555 {
00556 if ( argc > 2 )
00557 {
00558 Tcl_AppendResult( interp, "wrong # args: should be \"",
00559 argv[0], (char *) NULL );
00560 result = TCL_ERROR;
00561 goto done;
00562 }
00563 else
00564 {
00565 result = Closelink( interp, plPlotterPtr, argc - 2, argv + 2 );
00566 }
00567 }
00568
00569
00570
00571 else if ( ( c == 'd' ) && ( strncmp( argv[1], "draw", length ) == 0 ) )
00572 {
00573 if ( argc == 2 )
00574 {
00575 Tcl_AppendResult( interp, "wrong # args: should be \"",
00576 argv[0], " draw op ?options?\"", (char *) NULL );
00577 result = TCL_ERROR;
00578 goto done;
00579 }
00580 else
00581 {
00582 result = Draw( interp, plPlotterPtr, argc - 2, argv + 2 );
00583 }
00584 }
00585
00586
00587
00588 else if ( ( c == 'i' ) && ( strncmp( argv[1], "info", length ) == 0 ) )
00589 {
00590 result = Info( interp, plPlotterPtr, argc - 2, argv + 2 );
00591 }
00592
00593
00594
00595 else if ( ( c == 'n' ) && ( strncmp( argv[1], "nextpage", length ) == 0 ) )
00596 {
00597 result = NextPage( interp, plPlotterPtr, argc - 2, argv + 2 );
00598 }
00599
00600
00601
00602 else if ( ( c == 'o' ) && ( strncmp( argv[1], "orient", length ) == 0 ) )
00603 {
00604 result = Orient( interp, plPlotterPtr, argc - 2, argv + 2 );
00605 }
00606
00607
00608
00609 else if ( ( c == 'o' ) && ( strncmp( argv[1], "openlink", length ) == 0 ) )
00610 {
00611 if ( argc < 3 )
00612 {
00613 Tcl_AppendResult( interp, "wrong # args: should be \"",
00614 argv[0], " option ?arg arg ...?\"", (char *) NULL );
00615 result = TCL_ERROR;
00616 goto done;
00617 }
00618 else
00619 {
00620 result = Openlink( interp, plPlotterPtr, argc - 2, argv + 2 );
00621 }
00622 }
00623
00624
00625
00626 else if ( ( c == 'p' ) && ( strncmp( argv[1], "page", length ) == 0 ) )
00627 {
00628 result = Page( interp, plPlotterPtr, argc - 2, argv + 2 );
00629 }
00630
00631
00632
00633 else if ( ( c == 'p' ) && ( strncmp( argv[1], "print", length ) == 0 ) )
00634 {
00635 result = Print( interp, plPlotterPtr, argc - 2, argv + 2 );
00636 }
00637
00638
00639
00640 else if ( ( c == 'r' ) && ( strncmp( argv[1], "redraw", length ) == 0 ) )
00641 {
00642 if ( argc > 2 )
00643 {
00644 Tcl_AppendResult( interp, "wrong # args: should be \"",
00645 argv[0], " redraw\"", (char *) NULL );
00646 result = TCL_ERROR;
00647 goto done;
00648 }
00649 else
00650 {
00651 result = Redraw( interp, plPlotterPtr, argc - 2, argv + 2 );
00652 }
00653 }
00654
00655
00656
00657 else if ( ( c == 'r' ) && ( strncmp( argv[1], "report", length ) == 0 ) )
00658 {
00659 result = report( interp, plPlotterPtr, argc - 2, argv + 2 );
00660 }
00661
00662
00663
00664 else if ( ( c == 's' ) && ( strncmp( argv[1], "save", length ) == 0 ) )
00665 {
00666 result = Save( interp, plPlotterPtr, argc - 2, argv + 2 );
00667 }
00668
00669
00670
00671 else if ( ( c == 'v' ) && ( strncmp( argv[1], "view", length ) == 0 ) )
00672 {
00673 result = View( interp, plPlotterPtr, argc - 2, argv + 2 );
00674 }
00675
00676
00677
00678 else if ( ( c == 'x' ) && ( strncmp( argv[1], "xview", length ) == 0 ) )
00679 {
00680 int count, type;
00681 double width = (double) ( plPlotterPtr->xr - plPlotterPtr->xl );
00682
00683 double fraction;
00684
00685 type = Tk_GetScrollInfo( interp, argc, argv, &fraction, &count );
00686 switch ( type )
00687 {
00688 case TK_SCROLL_ERROR:
00689 result = TCL_ERROR;
00690 goto done;
00691 case TK_SCROLL_MOVETO:
00692 plPlotterPtr->xl = (PLFLT) fraction;
00693 plPlotterPtr->xr = (PLFLT) ( fraction + width );
00694 break;
00695 case TK_SCROLL_PAGES:
00696 plPlotterPtr->xl += (PLFLT) ( count * width * .9 );
00697 plPlotterPtr->xr += (PLFLT) ( count * width * .9 );
00698 break;
00699 case TK_SCROLL_UNITS:
00700 plPlotterPtr->xl += (PLFLT) ( count * width / 50 );
00701 plPlotterPtr->xr += (PLFLT) ( count * width / 50 );
00702 break;
00703 }
00704 if ( plPlotterPtr->xr > 1.0 )
00705 {
00706 plPlotterPtr->xr = 1.0;
00707 plPlotterPtr->xl = (PLFLT) ( 1.0 - width );
00708 }
00709 else if ( plPlotterPtr->xl < 0.0 )
00710 {
00711 plPlotterPtr->xl = 0.0;
00712 plPlotterPtr->xr = (PLFLT) width;
00713 }
00714 Scroll( interp, plPlotterPtr );
00715 }
00716
00717
00718
00719 else if ( ( c == 'y' ) && ( strncmp( argv[1], "yview", length ) == 0 ) )
00720 {
00721 int count, type;
00722 double height = plPlotterPtr->yr - plPlotterPtr->yl;
00723
00724 double fraction;
00725
00726 type = Tk_GetScrollInfo( interp, argc, argv, &fraction, &count );
00727 switch ( type )
00728 {
00729 case TK_SCROLL_ERROR:
00730 result = TCL_ERROR;
00731 goto done;
00732 case TK_SCROLL_MOVETO:
00733 plPlotterPtr->yl = (PLFLT) ( 1.0 - fraction - height );
00734 plPlotterPtr->yr = (PLFLT) ( 1.0 - fraction );
00735 break;
00736 case TK_SCROLL_PAGES:
00737 plPlotterPtr->yl -= (PLFLT) ( count * height * .9 );
00738 plPlotterPtr->yr -= (PLFLT) ( count * height * .9 );
00739 break;
00740 case TK_SCROLL_UNITS:
00741 plPlotterPtr->yl -= (PLFLT) ( count * height / 50 );
00742 plPlotterPtr->yr -= (PLFLT) ( count * height / 50 );
00743 break;
00744 }
00745 if ( plPlotterPtr->yr > 1.0 )
00746 {
00747 plPlotterPtr->yr = 1.0;
00748 plPlotterPtr->yl = (PLFLT) ( 1.0 - height );
00749 }
00750 else if ( plPlotterPtr->yl < 0.0 )
00751 {
00752 plPlotterPtr->yl = 0.0;
00753 plPlotterPtr->yr = (PLFLT) height;
00754 }
00755 Scroll( interp, plPlotterPtr );
00756 }
00757
00758
00759
00760 else
00761 {
00762 Tcl_AppendResult( interp, "bad option \"", argv[1],
00763 "\": must be closelink, cmd, configure, draw, info, nextpage ",
00764 "openlink, orient, page, print, redraw, save, view, ",
00765 "xview, or yview", (char *) NULL );
00766
00767 result = TCL_ERROR;
00768 }
00769
00770 done:
00771 Tk_Release( (ClientData) plPlotterPtr );
00772 return result;
00773 }
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 static void DestroyPlPlotter( ClientData clientData )
00794 {
00795 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
00796 register PLRDev *plr = plPlotterPtr->plr;
00797 TkwDev *dev = (TkwDev *) plPlotterPtr->pls->dev;
00798
00799 dbug_enter( "DestroyPlPlotter" );
00800
00801 dev->flags |= 0x3;
00802
00803 if ( plPlotterPtr->border != NULL )
00804 {
00805 Tk_Free3DBorder( plPlotterPtr->border );
00806 }
00807 if ( plPlotterPtr->plpr_cmd != NULL )
00808 {
00809 free( (char *) plPlotterPtr->plpr_cmd );
00810 }
00811 if ( plPlotterPtr->cursor != None )
00812 {
00813 Tk_FreeCursor( plPlotterPtr->display, plPlotterPtr->cursor );
00814 }
00815 if ( plPlotterPtr->xhair_cursor != None )
00816 {
00817 Tk_FreeCursor( plPlotterPtr->display, plPlotterPtr->xhair_cursor );
00818 }
00819 if ( plPlotterPtr->xorGC != NULL )
00820 {
00821 Tk_FreeGC( plPlotterPtr->display, plPlotterPtr->xorGC );
00822 }
00823 if ( plPlotterPtr->yScrollCmd != NULL )
00824 {
00825 free( (char *) plPlotterPtr->yScrollCmd );
00826 }
00827 if ( plPlotterPtr->xScrollCmd != NULL )
00828 {
00829 free( (char *) plPlotterPtr->xScrollCmd );
00830 }
00831 if ( plPlotterPtr->SaveFnam != NULL )
00832 {
00833 free( (char *) plPlotterPtr->SaveFnam );
00834 }
00835 if ( plPlotterPtr->devDesc != NULL )
00836 {
00837 free( (char *) plPlotterPtr->devDesc );
00838 }
00839 if ( plPlotterPtr->devName != NULL )
00840 {
00841 free( (char *) plPlotterPtr->devName );
00842 }
00843
00844
00845
00846 pdf_close( plr->pdfs );
00847 free( (char *) plPlotterPtr->plr->iodev );
00848
00849
00850
00851 plsstrm( plPlotterPtr->ipls );
00852 plend1();
00853
00854
00855
00856 free( (char *) plPlotterPtr->plr );
00857 free( (char *) plPlotterPtr );
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 static void
00878 PlPlotterConfigureEH( ClientData clientData, register XEvent *eventPtr )
00879 {
00880 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
00881 register Tk_Window tkwin = plPlotterPtr->tkwin;
00882
00883 dbug_enter( "PlPlotterConfigureEH" );
00884
00885 switch ( eventPtr->type )
00886 {
00887 case ConfigureNotify:
00888 pldebug( "PLFrameConfigureEH", "ConfigureNotify\n" );
00889 plPlotterPtr->flags |= RESIZE_PENDING;
00890 plPlotterPtr->width = Tk_Width( tkwin );
00891 plPlotterPtr->height = Tk_Height( tkwin );
00892 if ( ( tkwin != NULL ) && !( plPlotterPtr->flags & REFRESH_PENDING ) )
00893 {
00894 Tcl_DoWhenIdle( DisplayPlPlotter, (ClientData) plPlotterPtr );
00895 plPlotterPtr->flags |= REFRESH_PENDING;
00896 plPlotterPtr->flags |= UPDATE_V_SCROLLBAR | UPDATE_H_SCROLLBAR;
00897 }
00898 break;
00899
00900 case DestroyNotify:
00901 pldebug( "PLFrameConfigureEH", "DestroyNotify\n" );
00902 Tcl_DeleteCommand( plPlotterPtr->interp, Tk_PathName( tkwin ) );
00903 plPlotterPtr->tkwin = NULL;
00904 if ( plPlotterPtr->flags & REFRESH_PENDING )
00905 {
00906 Tcl_CancelIdleCall( DisplayPlPlotter, (ClientData) plPlotterPtr );
00907 }
00908 Tk_EventuallyFree( (ClientData) plPlotterPtr, (Tcl_FreeProc *) DestroyPlPlotter );
00909 break;
00910
00911 case MapNotify:
00912 pldebug( "PLFrameConfigureEH", "MapNotify\n" );
00913 if ( plPlotterPtr->flags & REFRESH_PENDING )
00914 {
00915 Tcl_CancelIdleCall( DisplayPlPlotter, (ClientData) plPlotterPtr );
00916 }
00917
00918
00919
00920 #if 0
00921
00922
00923
00924
00925
00926 if ( !plPlotterPtr->tkwin_initted )
00927 {
00928 Tcl_VarEval( plPlotterPtr->interp, "update", (char *) NULL );
00929 }
00930 #endif
00931
00932
00933 Tcl_DoWhenIdle( PlPlotterInit, (ClientData) plPlotterPtr );
00934 break;
00935 }
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959 static void
00960 PlPlotterExposeEH( ClientData clientData, register XEvent *eventPtr )
00961 {
00962 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
00963 XExposeEvent *event = (XExposeEvent *) eventPtr;
00964 register Tk_Window tkwin = plPlotterPtr->tkwin;
00965
00966 dbug_enter( "PlPlotterExposeEH" );
00967
00968 pldebug( "PLFrameExposeEH", "Expose\n" );
00969
00970
00971
00972 if ( !( plPlotterPtr->drawing_xhairs || plPlotterPtr->drawing_rband ) )
00973 {
00974 int x0_old, x1_old, y0_old, y1_old, x0_new, x1_new, y0_new, y1_new;
00975
00976 x0_old = plPlotterPtr->pldis.x;
00977 y0_old = plPlotterPtr->pldis.y;
00978 x1_old = x0_old + plPlotterPtr->pldis.width;
00979 y1_old = y0_old + plPlotterPtr->pldis.height;
00980
00981 x0_new = event->x;
00982 y0_new = event->y;
00983 x1_new = x0_new + event->width;
00984 y1_new = y0_new + event->height;
00985
00986 plPlotterPtr->pldis.x = MIN( x0_old, x0_new );
00987 plPlotterPtr->pldis.y = MIN( y0_old, y0_new );
00988 plPlotterPtr->pldis.width = MAX( x1_old, x1_new ) - plPlotterPtr->pldis.x;
00989 plPlotterPtr->pldis.height = MAX( y1_old, y1_new ) - plPlotterPtr->pldis.y;
00990 }
00991
00992
00993
00994 if ( event->count == 0 )
00995 {
00996 if ( ( tkwin != NULL ) && !( plPlotterPtr->flags & REFRESH_PENDING ) )
00997 {
00998 Tcl_DoWhenIdle( DisplayPlPlotter, (ClientData) plPlotterPtr );
00999 plPlotterPtr->width = Tk_Width( tkwin );
01000 plPlotterPtr->height = Tk_Height( tkwin );
01001 plPlotterPtr->flags |= REFRESH_PENDING;
01002 }
01003 }
01004 }
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 static void
01024 PlPlotterMotionEH( ClientData clientData, register XEvent *eventPtr )
01025 {
01026 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
01027 XMotionEvent *event = (XMotionEvent *) eventPtr;
01028
01029 dbug_enter( "PlPlotterMotionEH" );
01030
01031 if ( plPlotterPtr->drawing_xhairs )
01032 {
01033 DrawXhairs( plPlotterPtr, event->x, event->y );
01034 }
01035 if ( plPlotterPtr->drawing_rband )
01036 {
01037 DrawRband( plPlotterPtr, event->x, event->y );
01038 }
01039 }
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 static void
01058 PlPlotterEnterEH( ClientData clientData, register XEvent *eventPtr )
01059 {
01060 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
01061 XCrossingEvent *crossingEvent = (XCrossingEvent *) eventPtr;
01062
01063 dbug_enter( "PlPlotterEnterEH" );
01064
01065 if ( plPlotterPtr->xhairs )
01066 {
01067 DrawXhairs( plPlotterPtr, crossingEvent->x, crossingEvent->y );
01068 plPlotterPtr->drawing_xhairs = 1;
01069 }
01070 if ( plPlotterPtr->rband )
01071 {
01072 plPlotterPtr->drawing_rband = 1;
01073 UpdateRband( plPlotterPtr );
01074 DrawRband( plPlotterPtr, crossingEvent->x, crossingEvent->y );
01075 }
01076 }
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 static void
01095 PlPlotterLeaveEH( ClientData clientData, register XEvent *eventPtr )
01096 {
01097 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
01098
01099 dbug_enter( "PlPlotterLeaveEH" );
01100
01101 if ( plPlotterPtr->drawing_xhairs )
01102 {
01103 UpdateXhairs( plPlotterPtr );
01104 plPlotterPtr->drawing_xhairs = 0;
01105 }
01106 if ( plPlotterPtr->drawing_rband )
01107 {
01108 UpdateRband( plPlotterPtr );
01109 plPlotterPtr->drawing_rband = 0;
01110 }
01111 }
01112
01113 static void
01114 PlPlotterButtonPressEH( ClientData clientData, register XEvent *eventPtr )
01115 {
01116 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
01117 XButtonEvent *event = (XButtonEvent *) eventPtr;
01118
01119
01120 switch ( event->state )
01121 {
01122 case 256:
01123 if ( plPlotterPtr->drawing_rband )
01124 {
01125 UpdateRband( plPlotterPtr );
01126 }
01127 if ( plPlotterPtr->rband )
01128 CreateRband( plPlotterPtr );
01129 break;
01130 }
01131 }
01132
01133
01134
01135
01136
01137
01138
01139 static void
01140 CreateXhairs( PlPlotter *plPlotterPtr )
01141 {
01142 register Tk_Window tkwin = plPlotterPtr->tkwin;
01143 Window root, child;
01144 int root_x, root_y, win_x, win_y;
01145 unsigned int mask;
01146
01147
01148
01149
01150
01151 if ( XQueryPointer( plPlotterPtr->display, Tk_WindowId( tkwin ),
01152 &root, &child, &root_x, &root_y, &win_x, &win_y,
01153 &mask ) )
01154 {
01155 #ifdef MAC_TCL
01156
01157
01158 Tk_GetRootCoords( tkwin, &win_x, &win_y );
01159 win_x = root_x - win_x;
01160 win_y = root_y - win_y;
01161 #endif
01162 if ( win_x >= 0 && win_x < Tk_Width( tkwin ) &&
01163 win_y >= 0 && win_y < Tk_Height( tkwin ) )
01164 {
01165 DrawXhairs( plPlotterPtr, win_x, win_y );
01166 plPlotterPtr->drawing_xhairs = 1;
01167 }
01168 }
01169 }
01170
01171
01172
01173
01174
01175
01176
01177 static void
01178 DestroyXhairs( PlPlotter *plPlotterPtr )
01179 {
01180
01181
01182 UpdateXhairs( plPlotterPtr );
01183 plPlotterPtr->drawing_xhairs = 0;
01184 }
01185
01186
01187
01188
01189
01190
01191
01192 static void
01193 DrawXhairs( PlPlotter *plPlotterPtr, int x0, int y0 )
01194 {
01195 register Tk_Window tkwin = plPlotterPtr->tkwin;
01196 int xmin = 0, xmax = Tk_Width( tkwin ) - 1;
01197 int ymin = 0, ymax = Tk_Height( tkwin ) - 1;
01198
01199 if ( plPlotterPtr->drawing_xhairs )
01200 UpdateXhairs( plPlotterPtr );
01201
01202 plPlotterPtr->xhair_x[0].x = xmin; plPlotterPtr->xhair_x[0].y = y0;
01203 plPlotterPtr->xhair_x[1].x = xmax; plPlotterPtr->xhair_x[1].y = y0;
01204
01205 plPlotterPtr->xhair_y[0].x = x0; plPlotterPtr->xhair_y[0].y = ymin;
01206 plPlotterPtr->xhair_y[1].x = x0; plPlotterPtr->xhair_y[1].y = ymax;
01207
01208 UpdateXhairs( plPlotterPtr );
01209 }
01210
01211
01212
01213
01214
01215
01216
01217 static void
01218 UpdateXhairs( PlPlotter *plPlotterPtr )
01219 {
01220 register Tk_Window tkwin = plPlotterPtr->tkwin;
01221
01222 XDrawLines( Tk_Display( tkwin ), Tk_WindowId( tkwin ),
01223 plPlotterPtr->xorGC, plPlotterPtr->xhair_x, 2,
01224 CoordModeOrigin );
01225
01226 XDrawLines( Tk_Display( tkwin ), Tk_WindowId( tkwin ),
01227 plPlotterPtr->xorGC, plPlotterPtr->xhair_y, 2,
01228 CoordModeOrigin );
01229 }
01230
01231
01232
01233
01234
01235
01236
01237 static void
01238 CreateRband( PlPlotter *plPlotterPtr )
01239 {
01240 register Tk_Window tkwin = plPlotterPtr->tkwin;
01241 Window root, child;
01242 int root_x, root_y, win_x, win_y;
01243 unsigned int mask;
01244
01245
01246
01247 if ( XQueryPointer( plPlotterPtr->display, Tk_WindowId( tkwin ),
01248 &root, &child, &root_x, &root_y, &win_x, &win_y,
01249 &mask ) )
01250 {
01251 #ifdef MAC_TCL
01252
01253
01254 Tk_GetRootCoords( tkwin, &win_x, &win_y );
01255 win_x = root_x - win_x;
01256 win_y = root_y - win_y;
01257 #endif
01258 if ( win_x >= 0 && win_x < Tk_Width( tkwin ) &&
01259 win_y >= 0 && win_y < Tk_Height( tkwin ) )
01260 {
01261
01262 plPlotterPtr->rband_pt[0].x = win_x;
01263 plPlotterPtr->rband_pt[0].y = win_y;
01264
01265 DrawRband( plPlotterPtr, win_x, win_y );
01266 plPlotterPtr->drawing_rband = 1;
01267 }
01268 else
01269 {
01270
01271
01272
01273
01274 plPlotterPtr->rband_pt[0].x = 0;
01275 plPlotterPtr->rband_pt[0].y = 0;
01276
01277 DrawRband( plPlotterPtr, win_x, win_y );
01278 plPlotterPtr->drawing_rband = 1;
01279 }
01280 }
01281 }
01282
01283
01284
01285
01286
01287
01288
01289 static void
01290 DestroyRband( PlPlotter *plPlotterPtr )
01291 {
01292
01293
01294 UpdateRband( plPlotterPtr );
01295 plPlotterPtr->drawing_rband = 0;
01296 }
01297
01298
01299
01300
01301
01302
01303
01304 static void
01305 DrawRband( PlPlotter *plPlotterPtr, int x0, int y0 )
01306 {
01307
01308
01309 if ( plPlotterPtr->drawing_rband )
01310 UpdateRband( plPlotterPtr );
01311
01312 plPlotterPtr->rband_pt[1].x = x0; plPlotterPtr->rband_pt[1].y = y0;
01313
01314 UpdateRband( plPlotterPtr );
01315 }
01316
01317
01318
01319
01320
01321
01322
01323 static void
01324 UpdateRband( PlPlotter *plPlotterPtr )
01325 {
01326 register Tk_Window tkwin = plPlotterPtr->tkwin;
01327
01328 XDrawLines( Tk_Display( tkwin ), Tk_WindowId( tkwin ),
01329 plPlotterPtr->xorGC, plPlotterPtr->rband_pt, 2,
01330 CoordModeOrigin );
01331 }
01332
01333
01334 static void PlPlotterFirstInit( ClientData clientData )
01335 {
01336 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
01337 register Tk_Window tkwin = plPlotterPtr->tkwin;
01338
01339 plsstrm( plPlotterPtr->ipls );
01340 plsdev( "tkwin" );
01341
01342 plsxwin( Tk_WindowId( tkwin ) );
01343 plspause( 0 );
01344 plinit();
01345 if ( plplot_tkwin_ccmap )
01346 {
01347 Install_cmap( plPlotterPtr );
01348 }
01349 plbop();
01350
01351 plPlotterPtr->tkwin_initted = 1;
01352 plPlotterPtr->width = Tk_Width( tkwin );
01353 plPlotterPtr->height = Tk_Height( tkwin );
01354 plPlotterPtr->prevWidth = plPlotterPtr->width;
01355 plPlotterPtr->prevHeight = plPlotterPtr->height;
01356 }
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374 static void
01375 PlPlotterInit( ClientData clientData )
01376 {
01377 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
01378
01379
01380
01381 plPlotterPtr->flags |= REFRESH_PENDING;
01382 plPlotterPtr->flags |= UPDATE_V_SCROLLBAR | UPDATE_H_SCROLLBAR;
01383
01384
01385
01386 DisplayPlPlotter( clientData );
01387
01388 if ( plPlotterPtr->xhairs )
01389 CreateXhairs( plPlotterPtr );
01390
01391 if ( plPlotterPtr->rband )
01392 CreateRband( plPlotterPtr );
01393 }
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412 static void
01413 Install_cmap( PlPlotter *plPlotterPtr )
01414 {
01415 TkwDev *dev;
01416
01417 #define INSTALL_COLORMAP_IN_TK
01418 #ifdef INSTALL_COLORMAP_IN_TK
01419 dev = (TkwDev *) plPlotterPtr->pls->dev;
01420 Tk_SetWindowColormap( Tk_MainWindow( plPlotterPtr->interp ), dev->tkwd->map );
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 #else
01431 int count = 0;
01432 Window top, colormap_windows[5];
01433
01434 top = Tk_WindowId( Tk_MainWindow( plPlotterPtr->interp ) );
01435
01436 colormap_windows[count++] = Tk_WindowId( plPlotterPtr->tkwin );
01437 colormap_windows[count++] = top;
01438
01439 if ( !XSetWMColormapWindows( plPlotterPtr->display,
01440 top, colormap_windows, count ) )
01441 fprintf( stderr, "Unable to set color map property!\n" );
01442 #endif
01443 }
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462 static void
01463 DisplayPlPlotter( ClientData clientData )
01464 {
01465 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
01466 register Tk_Window tkwin = plPlotterPtr->tkwin;
01467
01468 dbug_enter( "DisplayPlPlotter" );
01469
01470
01471
01472 if ( plPlotterPtr->flags & UPDATE_V_SCROLLBAR )
01473 {
01474 UpdateVScrollbar( plPlotterPtr );
01475 }
01476 if ( plPlotterPtr->flags & UPDATE_H_SCROLLBAR )
01477 {
01478 UpdateHScrollbar( plPlotterPtr );
01479 }
01480 plPlotterPtr->flags &= ~( UPDATE_V_SCROLLBAR | UPDATE_H_SCROLLBAR );
01481
01482
01483
01484 if ( ( plPlotterPtr->tkwin == NULL ) || !Tk_IsMapped( tkwin ) )
01485 {
01486 plPlotterPtr->flags &= ~REFRESH_PENDING;
01487 return;
01488 }
01489
01490
01491
01492 if ( plPlotterPtr->flags & REFRESH_PENDING )
01493 {
01494 plPlotterPtr->flags &= ~REFRESH_PENDING;
01495
01496
01497
01498
01499 if ( plPlotterPtr->flags & RESIZE_PENDING )
01500 {
01501 plPlotterPtr->flags |= REFRESH_PENDING;
01502 plPlotterPtr->flags &= ~RESIZE_PENDING;
01503 Tcl_DoWhenIdle( DisplayPlPlotter, clientData );
01504 return;
01505 }
01506
01507
01508
01509 if ( ( plPlotterPtr->border != NULL ) &&
01510 ( plPlotterPtr->relief != TK_RELIEF_FLAT ) )
01511 {
01512 Tk_Draw3DRectangle( plPlotterPtr->tkwin, Tk_WindowId( tkwin ),
01513 plPlotterPtr->border, 0, 0, Tk_Width( tkwin ), Tk_Height( tkwin ),
01514 plPlotterPtr->borderWidth, plPlotterPtr->relief );
01515 }
01516
01517
01518
01519 if ( plPlotterPtr->flags & REDRAW_PENDING )
01520 {
01521 plPlotterPtr->flags &= ~REDRAW_PENDING;
01522 plsstrm( plPlotterPtr->ipls );
01523 pl_cmd( PLESC_REDRAW, (void *) NULL );
01524 }
01525
01526
01527
01528 else if ( ( plPlotterPtr->width != plPlotterPtr->prevWidth ) ||
01529 ( plPlotterPtr->height != plPlotterPtr->prevHeight ) )
01530 {
01531 plPlotterPtr->pldis.width = plPlotterPtr->width;
01532 plPlotterPtr->pldis.height = plPlotterPtr->height;
01533
01534 plsstrm( plPlotterPtr->ipls );
01535 pl_cmd( PLESC_RESIZE, (void *) &( plPlotterPtr->pldis ) );
01536 plPlotterPtr->prevWidth = plPlotterPtr->width;
01537 plPlotterPtr->prevHeight = plPlotterPtr->height;
01538 }
01539
01540
01541
01542 else
01543 {
01544 if ( plPlotterPtr->drawing_xhairs )
01545 {
01546 #ifdef MAC_TCL
01547
01548 Tk_Draw3DRectangle( plPlotterPtr->tkwin, Tk_WindowId( tkwin ),
01549 plPlotterPtr->border, 0, 0, Tk_Width( tkwin ), Tk_Height( tkwin ),
01550 plPlotterPtr->borderWidth, plPlotterPtr->relief );
01551 #else
01552 XClearWindow( plPlotterPtr->display, Tk_WindowId( tkwin ) );
01553 #endif
01554 XFlush( plPlotterPtr->display );
01555 plsstrm( plPlotterPtr->ipls );
01556 pl_cmd( PLESC_EXPOSE, NULL );
01557 }
01558 else
01559 {
01560 plsstrm( plPlotterPtr->ipls );
01561 pl_cmd( PLESC_EXPOSE, (void *) &( plPlotterPtr->pldis ) );
01562 }
01563
01564
01565
01566 plPlotterPtr->pldis.x = Tk_X( tkwin ) + Tk_Width( tkwin );
01567 plPlotterPtr->pldis.y = Tk_Y( tkwin ) + Tk_Height( tkwin );
01568 plPlotterPtr->pldis.width = -Tk_Width( tkwin );
01569 plPlotterPtr->pldis.height = -Tk_Height( tkwin );
01570 }
01571
01572
01573
01574 if ( plPlotterPtr->drawing_xhairs )
01575 {
01576 UpdateXhairs( plPlotterPtr );
01577 }
01578
01579
01580
01581 if ( plPlotterPtr->drawing_rband )
01582 {
01583 UpdateRband( plPlotterPtr );
01584 }
01585 }
01586 }
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598 static int
01599 scol0( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
01600 int i, CONST char *col, int *p_changed )
01601 {
01602 PLStream *pls = plPlotterPtr->pls;
01603 XColor xcol;
01604 PLINT r, g, b;
01605
01606 if ( col == NULL )
01607 {
01608 Tcl_AppendResult( interp, "color value not specified",
01609 (char *) NULL );
01610 return TCL_ERROR;
01611 }
01612
01613 if ( !XParseColor( plPlotterPtr->display,
01614 Tk_Colormap( plPlotterPtr->tkwin ), col, &xcol ) )
01615 {
01616 Tcl_AppendResult( interp, "Couldn't parse color ", col,
01617 (char *) NULL );
01618 return TCL_ERROR;
01619 }
01620
01621 r = (unsigned) ( xcol.red & 0xFF00 ) >> 8;
01622 g = (unsigned) ( xcol.green & 0xFF00 ) >> 8;
01623 b = (unsigned) ( xcol.blue & 0xFF00 ) >> 8;
01624
01625 if ( ( pls->cmap0[i].r != r ) ||
01626 ( pls->cmap0[i].g != g ) ||
01627 ( pls->cmap0[i].b != b ) )
01628 {
01629 pls->cmap0[i].r = r;
01630 pls->cmap0[i].g = g;
01631 pls->cmap0[i].b = b;
01632 *p_changed = 1;
01633 }
01634
01635 return TCL_OK;
01636 }
01637
01638
01639
01640
01641
01642
01643
01644 static int
01645 scol1( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
01646 int i, CONST char *col, CONST char *pos, CONST char *rev, int *p_changed )
01647 {
01648 PLStream *pls = plPlotterPtr->pls;
01649 XColor xcol;
01650 PLFLT h, l, s, r, g, b, p;
01651 int reverse;
01652
01653 if ( col == NULL )
01654 {
01655 Tcl_AppendResult( interp, "color value not specified",
01656 (char *) NULL );
01657 return TCL_ERROR;
01658 }
01659
01660 if ( pos == NULL )
01661 {
01662 Tcl_AppendResult( interp, "control point position not specified",
01663 (char *) NULL );
01664 return TCL_ERROR;
01665 }
01666
01667 if ( rev == NULL )
01668 {
01669 Tcl_AppendResult( interp, "interpolation sense not specified",
01670 (char *) NULL );
01671 return TCL_ERROR;
01672 }
01673
01674 if ( !XParseColor( plPlotterPtr->display,
01675 Tk_Colormap( plPlotterPtr->tkwin ), col, &xcol ) )
01676 {
01677 Tcl_AppendResult( interp, "Couldn't parse color ", col,
01678 (char *) NULL );
01679 return TCL_ERROR;
01680 }
01681
01682 r = (PLFLT) ( ( (unsigned) ( xcol.red & 0xFF00 ) >> 8 ) / 255.0 );
01683 g = (PLFLT) ( ( (unsigned) ( xcol.green & 0xFF00 ) >> 8 ) / 255.0 );
01684 b = (PLFLT) ( ( (unsigned) ( xcol.blue & 0xFF00 ) >> 8 ) / 255.0 );
01685
01686 plrgbhls( r, g, b, &h, &l, &s );
01687
01688 p = (PLFLT) ( atof( pos ) / 100.0 );
01689 reverse = atoi( rev );
01690
01691 if ( ( pls->cmap1cp[i].h != h ) ||
01692 ( pls->cmap1cp[i].l != l ) ||
01693 ( pls->cmap1cp[i].s != s ) ||
01694 ( pls->cmap1cp[i].p != p ) ||
01695 ( pls->cmap1cp[i].rev != reverse ) )
01696 {
01697 pls->cmap1cp[i].h = h;
01698 pls->cmap1cp[i].l = l;
01699 pls->cmap1cp[i].s = s;
01700 pls->cmap1cp[i].p = p;
01701 pls->cmap1cp[i].rev = reverse;
01702 *p_changed = 1;
01703 }
01704 return TCL_OK;
01705 }
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715 static int
01716 Cmd( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
01717 int argc, CONST char **argv )
01718 {
01719 PLStream *pls = plPlotterPtr->pls;
01720 int length;
01721 char c3;
01722 int result = TCL_OK;
01723 char cmdlist[] = "plgcmap0 plgcmap1 plscmap0 plscmap1 plscol0 plscol1";
01724
01725 #ifdef DEBUG
01726 if ( pls->debug )
01727 {
01728 int i;
01729 fprintf( stderr, "There are %d arguments to Cmd:", argc );
01730 for ( i = 0; i < argc; i++ )
01731 {
01732 fprintf( stderr, " %s", argv[i] );
01733 }
01734 fprintf( stderr, "\n" );
01735 }
01736 #endif
01737
01738
01739
01740 if ( argc == 0 )
01741 return plTclCmd( cmdlist, interp, argc, argv );
01742
01743
01744
01745 if ( !plPlotterPtr->tkwin_initted )
01746 {
01747 Tcl_VarEval( plPlotterPtr->interp, "update", (char *) NULL );
01748 }
01749
01750
01751
01752 plsstrm( plPlotterPtr->ipls );
01753
01754 c3 = argv[0][2];
01755 length = strlen( argv[0] );
01756
01757
01758
01759
01760 if ( ( c3 == 'g' ) && ( strncmp( argv[0], "plgcmap0", length ) == 0 ) )
01761 {
01762 int i;
01763 unsigned long plcolor;
01764 char str[10];
01765
01766 sprintf( str, "%d", (int) pls->ncol0 );
01767 Tcl_AppendElement( interp, str );
01768 for ( i = 0; i < pls->ncol0; i++ )
01769 {
01770 plcolor = ( ( pls->cmap0[i].r << 16 ) |
01771 ( pls->cmap0[i].g << 8 ) |
01772 ( pls->cmap0[i].b ) );
01773
01774 sprintf( str, "#%06lx", ( plcolor & 0xFFFFFF ) );
01775 Tcl_AppendElement( interp, str );
01776 }
01777 result = TCL_OK;
01778 }
01779
01780
01781
01782
01783
01784 else if ( ( c3 == 'g' ) && ( strncmp( argv[0], "plgcmap1", length ) == 0 ) )
01785 {
01786 int i;
01787 unsigned long plcolor;
01788 char str[10];
01789 PLFLT h, l, s, r, g, b;
01790 int r1, g1, b1;
01791
01792 sprintf( str, "%d", (int) pls->ncp1 );
01793 Tcl_AppendElement( interp, str );
01794 for ( i = 0; i < pls->ncp1; i++ )
01795 {
01796 h = pls->cmap1cp[i].h;
01797 l = pls->cmap1cp[i].l;
01798 s = pls->cmap1cp[i].s;
01799
01800 plhlsrgb( h, l, s, &r, &g, &b );
01801
01802 r1 = MAX( 0, MIN( 255, (int) ( 256. * r ) ) );
01803 g1 = MAX( 0, MIN( 255, (int) ( 256. * g ) ) );
01804 b1 = MAX( 0, MIN( 255, (int) ( 256. * b ) ) );
01805
01806 plcolor = ( ( r1 << 16 ) | ( g1 << 8 ) | ( b1 ) );
01807
01808 sprintf( str, "#%06lx", ( plcolor & 0xFFFFFF ) );
01809 Tcl_AppendElement( interp, str );
01810
01811 sprintf( str, "%02d", (int) ( 100 * pls->cmap1cp[i].p ) );
01812 Tcl_AppendElement( interp, str );
01813
01814 sprintf( str, "%01d", (int) ( pls->cmap1cp[i].rev ) );
01815 Tcl_AppendElement( interp, str );
01816 }
01817 result = TCL_OK;
01818 }
01819
01820
01821
01822
01823 else if ( ( c3 == 's' ) && ( strncmp( argv[0], "plscmap0", length ) == 0 ) )
01824 {
01825 int i, changed = 1, ncol0 = atoi( argv[1] );
01826 char *col;
01827
01828 if ( ncol0 > 16 || ncol0 < 1 )
01829 {
01830 Tcl_AppendResult( interp, "illegal number of colors in cmap0: ",
01831 argv[1], (char *) NULL );
01832 return TCL_ERROR;
01833 }
01834
01835 pls->ncol0 = ncol0;
01836 for ( i = 0; i < pls->ncol0; i++ )
01837 {
01838 col = strtok( (char *) argv[2 + i], " " );
01839 if ( col == NULL )
01840 break;
01841
01842 if ( scol0( interp, plPlotterPtr, i, col, &changed ) != TCL_OK )
01843 return TCL_ERROR;
01844 }
01845
01846 if ( changed )
01847 plP_state( PLSTATE_CMAP0 );
01848 }
01849
01850
01851
01852
01853 else if ( ( c3 == 's' ) && ( strncmp( argv[0], "plscmap1", length ) == 0 ) )
01854 {
01855 int i, changed = 1, ncp1 = atoi( argv[1] );
01856 char *col, *pos, *rev;
01857
01858 if ( ncp1 > 32 || ncp1 < 1 )
01859 {
01860 Tcl_AppendResult( interp,
01861 "illegal number of control points in cmap1: ",
01862 argv[1], (char *) NULL );
01863 return TCL_ERROR;
01864 }
01865
01866 col = strtok( (char *) argv[2], " " );
01867 pos = strtok( NULL, " " );
01868 rev = strtok( NULL, " " );
01869 for ( i = 0; i < ncp1; i++ )
01870 {
01871 if ( col == NULL )
01872 break;
01873
01874 if ( scol1( interp, plPlotterPtr,
01875 i, col, pos, rev, &changed ) != TCL_OK )
01876 return TCL_ERROR;
01877
01878 col = strtok( NULL, " " );
01879 pos = strtok( NULL, " " );
01880 rev = strtok( NULL, " " );
01881 }
01882
01883 if ( changed )
01884 {
01885 plsc->ncp1 = ncp1;
01886 plcmap1_calc();
01887 }
01888 }
01889
01890
01891
01892
01893 else if ( ( c3 == 's' ) && ( strncmp( argv[0], "plscol0", length ) == 0 ) )
01894 {
01895 int i = atoi( argv[1] ), changed = 1;
01896
01897 if ( i > pls->ncol0 || i < 0 )
01898 {
01899 Tcl_AppendResult( interp, "illegal color number in cmap0: ",
01900 argv[1], (char *) NULL );
01901 return TCL_ERROR;
01902 }
01903
01904 if ( scol0( interp, plPlotterPtr, i, argv[2], &changed ) != TCL_OK )
01905 return TCL_ERROR;
01906
01907 if ( changed )
01908 plP_state( PLSTATE_CMAP0 );
01909 }
01910
01911
01912
01913
01914 else if ( ( c3 == 's' ) && ( strncmp( argv[0], "plscol1", length ) == 0 ) )
01915 {
01916 int i = atoi( argv[1] ), changed = 1;
01917
01918 if ( i > pls->ncp1 || i < 0 )
01919 {
01920 Tcl_AppendResult( interp, "illegal control point number in cmap1: ",
01921 argv[1], (char *) NULL );
01922 return TCL_ERROR;
01923 }
01924
01925 if ( scol1( interp, plPlotterPtr,
01926 i, argv[2], argv[3], argv[4], &changed ) != TCL_OK )
01927 return TCL_ERROR;
01928
01929 if ( changed )
01930 plcmap1_calc();
01931 }
01932
01933
01934 #ifdef USING_PLESC_COPY
01935
01936
01937
01938 else if ( ( c3 == 'c' ) && ( strncmp( argv[0], "plcopy", length ) == 0 ) )
01939 {
01940 PLFLT xx[3], yy[3];
01941 if ( argc != 7 )
01942 {
01943 Tcl_AppendResult( interp, "Need exactly 6 arguments to copy.",
01944 (char *) NULL );
01945 return TCL_ERROR;
01946 }
01947 xx[0] = atof( argv[1] );
01948 yy[0] = atof( argv[2] );
01949 xx[1] = atof( argv[3] );
01950 yy[1] = atof( argv[4] );
01951 xx[2] = atof( argv[5] );
01952 yy[2] = atof( argv[6] );
01953 plcopy( xx, yy );
01954 }
01955 #endif
01956
01957
01958
01959 else
01960 result = plTclCmd( cmdlist, interp, argc, argv );
01961
01962 plflush();
01963 return result;
01964 }
01965
01966 static void ActiveState( register PlPlotter *plPlotterPtr, int on )
01967 {
01968 if ( on )
01969 {
01970 if ( !plPlotterPtr->isActive )
01971 {
01972 Tk_CreateEventHandler( plPlotterPtr->tkwin, ButtonPressMask,
01973 PlPlotterButtonPressEH, (ClientData) plPlotterPtr );
01974
01975 Tk_CreateEventHandler( plPlotterPtr->tkwin, PointerMotionMask,
01976 PlPlotterMotionEH, (ClientData) plPlotterPtr );
01977
01978 Tk_CreateEventHandler( plPlotterPtr->tkwin, EnterWindowMask,
01979 PlPlotterEnterEH, (ClientData) plPlotterPtr );
01980
01981 Tk_CreateEventHandler( plPlotterPtr->tkwin, LeaveWindowMask,
01982 PlPlotterLeaveEH, (ClientData) plPlotterPtr );
01983
01984
01985 Tk_DefineCursor( plPlotterPtr->tkwin, plPlotterPtr->xhair_cursor );
01986 }
01987 }
01988 else
01989 {
01990 if ( plPlotterPtr->isActive )
01991 {
01992 Tk_DeleteEventHandler( plPlotterPtr->tkwin, ButtonPressMask,
01993 PlPlotterButtonPressEH, (ClientData) plPlotterPtr );
01994 Tk_DeleteEventHandler( plPlotterPtr->tkwin, PointerMotionMask,
01995 PlPlotterMotionEH, (ClientData) plPlotterPtr );
01996
01997 Tk_DeleteEventHandler( plPlotterPtr->tkwin, EnterWindowMask,
01998 PlPlotterEnterEH, (ClientData) plPlotterPtr );
01999
02000 Tk_DeleteEventHandler( plPlotterPtr->tkwin, LeaveWindowMask,
02001 PlPlotterLeaveEH, (ClientData) plPlotterPtr );
02002
02003
02004 Tk_DefineCursor( plPlotterPtr->tkwin, plPlotterPtr->cursor );
02005 }
02006 }
02007 }
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031 static int
02032 ConfigurePlPlotter( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02033 int argc, CONST char **argv, int flags )
02034 {
02035 register Tk_Window tkwin = plPlotterPtr->tkwin;
02036 PLStream *pls = plPlotterPtr->pls;
02037 TkwDev *dev = (TkwDev *) pls->dev;
02038 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
02039 XGCValues gcValues;
02040 unsigned long mask;
02041 int need_redisplay = 0;
02042
02043 #ifdef DEBUG
02044 if ( pls->debug )
02045 {
02046 int i;
02047 fprintf( stderr, "Arguments to configure are:" );
02048 for ( i = 0; i < argc; i++ )
02049 {
02050 fprintf( stderr, " %s", argv[i] );
02051 }
02052 fprintf( stderr, "\n" );
02053 }
02054 #endif
02055
02056 dbug_enter( "ConfigurePlPlotter" );
02057
02058 if ( Tk_ConfigureWidget( interp, tkwin, configSpecs,
02059 argc, argv, (char *) plPlotterPtr, flags ) != TCL_OK )
02060 {
02061 return TCL_ERROR;
02062 }
02063
02064
02065
02066
02067
02068
02069
02070 plsstrm( plPlotterPtr->ipls );
02071 if ( PLColor_from_TkColor_Changed( &pls->cmap0[0],
02072 Tk_3DBorderColor( plPlotterPtr->border ) ) )
02073 {
02074 need_redisplay = 1;
02075
02076 plPlotterPtr->flags |= REDRAW_PENDING;
02077 }
02078 pltkwin_setBGFG( pls );
02079
02080 Tk_SetWindowBackground( tkwin, tkwd->cmap0[0].pixel );
02081 Tk_SetWindowBorder( tkwin, tkwd->cmap0[0].pixel );
02082
02083
02084
02085 gcValues.background = tkwd->cmap0[0].pixel;
02086 gcValues.foreground = 0xFF;
02087 gcValues.function = GXxor;
02088 mask = GCForeground | GCBackground | GCFunction;
02089
02090 if ( plPlotterPtr->xorGC != NULL )
02091 Tk_FreeGC( plPlotterPtr->display, plPlotterPtr->xorGC );
02092
02093 plPlotterPtr->xorGC = Tk_GetGC( plPlotterPtr->tkwin, mask, &gcValues );
02094
02095
02096
02097 Tk_SetInternalBorder( tkwin, plPlotterPtr->borderWidth );
02098 if ( ( plPlotterPtr->width > 0 ) || ( plPlotterPtr->height > 0 ) )
02099 {
02100 Tk_GeometryRequest( tkwin, plPlotterPtr->width, plPlotterPtr->height );
02101 if ( ( plPlotterPtr->width != plPlotterPtr->prevWidth ) ||
02102 ( plPlotterPtr->height != plPlotterPtr->prevHeight ) )
02103 need_redisplay = 1;
02104 }
02105
02106
02107
02108 if ( Tk_IsMapped( tkwin ) )
02109 {
02110 if ( plPlotterPtr->xhairs )
02111 {
02112 if ( !plPlotterPtr->drawing_xhairs )
02113 CreateXhairs( plPlotterPtr );
02114 }
02115 else
02116 {
02117 if ( plPlotterPtr->drawing_xhairs )
02118 DestroyXhairs( plPlotterPtr );
02119 }
02120 }
02121
02122
02123
02124 if ( Tk_IsMapped( tkwin ) )
02125 {
02126 if ( plPlotterPtr->rband )
02127 {
02128 if ( !plPlotterPtr->drawing_rband )
02129 CreateRband( plPlotterPtr );
02130 }
02131 else
02132 {
02133 if ( plPlotterPtr->drawing_rband )
02134 DestroyRband( plPlotterPtr );
02135 }
02136 }
02137
02138 ActiveState( plPlotterPtr, plPlotterPtr->active_plot );
02139
02140 if ( !pls->nopixmap )
02141 {
02142
02143 if ( plPlotterPtr->double_buffer != pls->db )
02144 {
02145 pls->db = plPlotterPtr->double_buffer;
02146
02147 dev->write_to_window = !pls->db;
02148 }
02149 }
02150 else
02151 {
02152 plPlotterPtr->double_buffer = 0;
02153 }
02154
02155
02156 if ( need_redisplay && Tk_IsMapped( tkwin )
02157 && !( plPlotterPtr->flags & REFRESH_PENDING ) )
02158 {
02159 Tcl_DoWhenIdle( DisplayPlPlotter, (ClientData) plPlotterPtr );
02160 plPlotterPtr->flags |= REFRESH_PENDING;
02161 plPlotterPtr->flags |= UPDATE_V_SCROLLBAR | UPDATE_H_SCROLLBAR;
02162 }
02163
02164 return TCL_OK;
02165 }
02166
02167
02168
02169
02170
02171
02172
02173
02174 static int
02175 Draw( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02176 int argc, CONST char **argv )
02177 {
02178 register Tk_Window tkwin = plPlotterPtr->tkwin;
02179 int result = TCL_OK;
02180 char c = argv[0][0];
02181 int length = strlen( argv[0] );
02182
02183
02184
02185 if ( !plPlotterPtr->tkwin_initted )
02186 {
02187 Tcl_VarEval( plPlotterPtr->interp, "update", (char *) NULL );
02188 }
02189
02190
02191
02192 if ( ( c == 'i' ) && ( strncmp( argv[0], "init", length ) == 0 ) )
02193 {
02194 Tk_DefineCursor( tkwin, plPlotterPtr->xhair_cursor );
02195 }
02196
02197
02198
02199 else if ( ( c == 'e' ) && ( strncmp( argv[0], "end", length ) == 0 ) )
02200 {
02201 Tk_DefineCursor( tkwin, plPlotterPtr->cursor );
02202 if ( plPlotterPtr->continue_draw )
02203 {
02204 XDrawLines( Tk_Display( tkwin ), Tk_WindowId( tkwin ),
02205 plPlotterPtr->xorGC, plPlotterPtr->pts, 5,
02206 CoordModeOrigin );
02207 XSync( Tk_Display( tkwin ), 0 );
02208 }
02209
02210 plPlotterPtr->continue_draw = 0;
02211 }
02212
02213
02214
02215
02216 else if ( ( c == 'r' ) && ( strncmp( argv[0], "rect", length ) == 0 ) )
02217 {
02218 if ( argc < 5 )
02219 {
02220 Tcl_AppendResult( interp, "wrong # args: should be \"",
02221 " draw rect x0 y0 x1 y1\"", (char *) NULL );
02222 result = TCL_ERROR;
02223 }
02224 else
02225 {
02226 int x0, y0, x1, y1;
02227 int xmin = 0, xmax = Tk_Width( tkwin ) - 1;
02228 int ymin = 0, ymax = Tk_Height( tkwin ) - 1;
02229
02230 x0 = atoi( argv[1] );
02231 y0 = atoi( argv[2] );
02232 x1 = atoi( argv[3] );
02233 y1 = atoi( argv[4] );
02234
02235 x0 = MAX( xmin, MIN( xmax, x0 ) );
02236 y0 = MAX( ymin, MIN( ymax, y0 ) );
02237 x1 = MAX( xmin, MIN( xmax, x1 ) );
02238 y1 = MAX( ymin, MIN( ymax, y1 ) );
02239
02240 if ( plPlotterPtr->continue_draw )
02241 {
02242 XDrawLines( Tk_Display( tkwin ), Tk_WindowId( tkwin ),
02243 plPlotterPtr->xorGC, plPlotterPtr->pts, 5,
02244 CoordModeOrigin );
02245 XSync( Tk_Display( tkwin ), 0 );
02246 }
02247
02248 plPlotterPtr->pts[0].x = x0; plPlotterPtr->pts[0].y = y0;
02249 plPlotterPtr->pts[1].x = x1; plPlotterPtr->pts[1].y = y0;
02250 plPlotterPtr->pts[2].x = x1; plPlotterPtr->pts[2].y = y1;
02251 plPlotterPtr->pts[3].x = x0; plPlotterPtr->pts[3].y = y1;
02252 plPlotterPtr->pts[4].x = x0; plPlotterPtr->pts[4].y = y0;
02253
02254 XDrawLines( Tk_Display( tkwin ), Tk_WindowId( tkwin ),
02255 plPlotterPtr->xorGC, plPlotterPtr->pts, 5,
02256 CoordModeOrigin );
02257 XSync( Tk_Display( tkwin ), 0 );
02258
02259 plPlotterPtr->continue_draw = 1;
02260 }
02261 }
02262
02263 return result;
02264 }
02265
02266
02267
02268
02269
02270
02271
02272
02273 static int
02274 Info( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02275 int argc, CONST char **argv )
02276 {
02277 int length;
02278 char c;
02279 int result = TCL_OK;
02280
02281
02282
02283 if ( argc == 0 )
02284 {
02285 Tcl_SetResult( interp, "devkeys devnames", TCL_STATIC );
02286 return TCL_OK;
02287 }
02288
02289 c = argv[0][0];
02290 length = strlen( argv[0] );
02291
02292
02293
02294 if ( ( c == 'd' ) && ( strncmp( argv[0], "devkeys", length ) == 0 ) )
02295 {
02296 int i = 0;
02297 while ( plPlotterPtr->devName[i] != NULL )
02298 Tcl_AppendElement( interp, plPlotterPtr->devName[i++] );
02299
02300 result = TCL_OK;
02301 }
02302
02303
02304
02305 else if ( ( c == 'd' ) && ( strncmp( argv[0], "devnames", length ) == 0 ) )
02306 {
02307 int i = 0;
02308 while ( plPlotterPtr->devDesc[i] != NULL )
02309 Tcl_AppendElement( interp, plPlotterPtr->devDesc[i++] );
02310
02311 result = TCL_OK;
02312 }
02313
02314
02315
02316 else
02317 {
02318 Tcl_AppendResult( interp, "bad option to \"info\": must be ",
02319 "devkeys, devnames", (char *) NULL );
02320
02321 result = TCL_ERROR;
02322 }
02323
02324 return result;
02325 }
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335 static int
02336 Openlink( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02337 int argc, CONST char **argv )
02338 {
02339 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
02340 register PLRDev *plr = plPlotterPtr->plr;
02341 register PLiodev *iodev = plr->iodev;
02342
02343 char c = argv[0][0];
02344 int length = strlen( argv[0] );
02345
02346 dbug_enter( "Openlink" );
02347
02348
02349
02350 if ( ( c == 'f' ) && ( strncmp( argv[0], "fifo", length ) == 0 ) )
02351 {
02352 if ( argc < 1 )
02353 {
02354 Tcl_AppendResult( interp, "bad command -- must be: ",
02355 "openlink fifo <pathname>",
02356 (char *) NULL );
02357 return TCL_ERROR;
02358 }
02359 if ( ( iodev->fd = open( argv[1], O_RDONLY ) ) == -1 )
02360 {
02361 Tcl_AppendResult( interp, "cannot open fifo ", argv[1],
02362 " for read", (char *) NULL );
02363 return TCL_ERROR;
02364 }
02365 iodev->type = 0;
02366 iodev->typeName = "fifo";
02367 iodev->file = fdopen( iodev->fd, "rb" );
02368 }
02369
02370
02371
02372 else if ( ( c == 's' ) && ( strncmp( argv[0], "socket", length ) == 0 ) )
02373 {
02374 if ( argc < 1 )
02375 {
02376 Tcl_AppendResult( interp, "bad command -- must be: ",
02377 "openlink socket <sock-id>",
02378 (char *) NULL );
02379 return TCL_ERROR;
02380 }
02381 iodev->type = 1;
02382 iodev->typeName = "socket";
02383 iodev->fileHandle = (char *) argv[1];
02384
02385 if ( Tcl_GetOpenFile( interp, iodev->fileHandle,
02386 0, 1, ( ClientData ) & iodev->file ) != TCL_OK )
02387 {
02388 return TCL_ERROR;
02389 }
02390 iodev->fd = fileno( iodev->file );
02391 }
02392
02393
02394
02395 else
02396 {
02397 Tcl_AppendResult( interp, "bad option to \"openlink\": must be ",
02398 "fifo or socket", (char *) NULL );
02399
02400 return TCL_ERROR;
02401 }
02402
02403 plr->pdfs = pdf_bopen( NULL, 4200 );
02404 Tcl_CreateFileHandler( iodev->fd,
02405 TK_READABLE, (Tk_FileProc *) ReadData,
02406 (ClientData) plPlotterPtr );
02407
02408 #endif
02409
02410 return TCL_OK;
02411 }
02412
02413
02414
02415
02416
02417
02418
02419
02420 static int
02421 Closelink( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02422 int argc, CONST char **argv )
02423 {
02424 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
02425 register PLRDev *plr = plPlotterPtr->plr;
02426 register PLiodev *iodev = plr->iodev;
02427
02428 dbug_enter( "Closelink" );
02429
02430 if ( iodev->fd == 0 )
02431 {
02432 Tcl_AppendResult( interp, "no link currently open", (char *) NULL );
02433 return TCL_ERROR;
02434 }
02435
02436 Tcl_DeleteFileHandler( iodev->fd );
02437 pdf_close( plr->pdfs );
02438 iodev->fd = 0;
02439 #endif
02440 return TCL_OK;
02441 }
02442
02443
02444
02445
02446
02447
02448
02449 static int
02450 process_data( Tcl_Interp *interp, register PlPlotter *plPlotterPtr )
02451 {
02452 register PLRDev *plr = plPlotterPtr->plr;
02453 register PLiodev *iodev = plr->iodev;
02454 int result = TCL_OK;
02455
02456
02457
02458 if ( plr_process( plr ) == -1 )
02459 {
02460 Tcl_AppendResult( interp, "unable to read from ", iodev->typeName,
02461 (char *) NULL );
02462 result = TCL_ERROR;
02463 }
02464
02465
02466
02467 if ( plr->at_bop && plPlotterPtr->bopCmd != NULL )
02468 {
02469 plr->at_bop = 0;
02470 if ( Tcl_Eval( interp, plPlotterPtr->bopCmd ) != TCL_OK )
02471 fprintf( stderr, "Command \"%s\" failed:\n\t %s\n",
02472 plPlotterPtr->bopCmd, interp->result );
02473 }
02474
02475
02476
02477 if ( plr->at_eop && plPlotterPtr->eopCmd != NULL )
02478 {
02479 plr->at_eop = 0;
02480 if ( Tcl_Eval( interp, plPlotterPtr->eopCmd ) != TCL_OK )
02481 fprintf( stderr, "Command \"%s\" failed:\n\t %s\n",
02482 plPlotterPtr->eopCmd, interp->result );
02483 }
02484
02485 return result;
02486 }
02487
02488 void PlplotterAtEop( Tcl_Interp *interp, register PlPlotter *plPlotterPtr )
02489 {
02490 if ( plPlotterPtr->eopCmd != NULL )
02491 {
02492 if ( Tcl_Eval( interp, plPlotterPtr->eopCmd ) != TCL_OK )
02493 fprintf( stderr, "Command \"%s\" failed:\n\t %s\n",
02494 plPlotterPtr->eopCmd, interp->result );
02495 }
02496 }
02497
02498 void PlplotterAtBop( Tcl_Interp *interp, register PlPlotter *plPlotterPtr )
02499 {
02500 if ( plPlotterPtr->bopCmd != NULL )
02501 {
02502 if ( Tcl_Eval( interp, plPlotterPtr->bopCmd ) != TCL_OK )
02503 fprintf( stderr, "Command \"%s\" failed:\n\t %s\n",
02504 plPlotterPtr->bopCmd, interp->result );
02505 }
02506 }
02507
02508
02509
02510
02511
02512
02513
02514
02515 static int
02516 ReadData( ClientData clientData, int mask )
02517 {
02518 register PlPlotter *plPlotterPtr = (PlPlotter *) clientData;
02519 register Tcl_Interp *interp = plPlotterPtr->interp;
02520
02521 register PLRDev *plr = plPlotterPtr->plr;
02522 register PLiodev *iodev = plr->iodev;
02523 register PDFstrm *pdfs = plr->pdfs;
02524 int result = TCL_OK;
02525
02526 if ( mask & TK_READABLE )
02527 {
02528
02529
02530 plsstrm( plPlotterPtr->ipls );
02531 #ifndef MAC_TCL
02532 if ( pl_PacketReceive( interp, iodev, pdfs ) )
02533 {
02534 #else
02535 if ( 1 )
02536 {
02537 #endif
02538 Tcl_AppendResult( interp, "Packet receive failed:\n\t %s\n",
02539 interp->result, (char *) NULL );
02540 return TCL_ERROR;
02541 }
02542
02543
02544
02545
02546
02547 if ( pdfs->bp == 0 )
02548 return TCL_OK;
02549
02550 plr->nbytes = pdfs->bp;
02551 pdfs->bp = 0;
02552 result = process_data( interp, plPlotterPtr );
02553 }
02554
02555 return result;
02556 }
02557
02558
02559
02560
02561
02562
02563
02564
02565 static int
02566 Orient( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02567 int argc, CONST char **argv )
02568 {
02569 int result = TCL_OK;
02570
02571
02572
02573 plsstrm( plPlotterPtr->ipls );
02574
02575 if ( argc == 0 )
02576 {
02577 PLFLT rot;
02578 char result_str[128];
02579 plgdiori( &rot );
02580 sprintf( result_str, "%f", rot );
02581 Tcl_SetResult( interp, result_str, TCL_VOLATILE );
02582 }
02583
02584
02585
02586 else
02587 {
02588 plsdiori( (PLFLT) atof( argv[0] ) );
02589 result = Redraw( interp, plPlotterPtr, argc - 1, argv + 1 );
02590 }
02591
02592 return result;
02593 }
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608 static int
02609 Print( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02610 int argc, CONST char **argv )
02611 {
02612 PLINT ipls;
02613 int result = TCL_OK;
02614 char *sfnam;
02615 FILE *sfile;
02616 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
02617 pid_t pid;
02618 #endif
02619
02620
02621
02622 if ( !plPlotterPtr->tkwin_initted )
02623 {
02624 Tcl_AppendResult( interp, "Error -- widget not plotted to yet",
02625 (char *) NULL );
02626 return TCL_ERROR;
02627 }
02628
02629
02630
02631 plmkstrm( &ipls );
02632 if ( ipls < 0 )
02633 {
02634 Tcl_AppendResult( interp, "Error -- cannot create stream",
02635 (char *) NULL );
02636 return TCL_ERROR;
02637 }
02638
02639
02640
02641
02642
02643 if ( ( sfile = pl_create_tempfile( &sfnam ) ) == NULL )
02644 {
02645 Tcl_AppendResult( interp,
02646 "Error -- cannot open plot file for writing",
02647 (char *) NULL );
02648 plend1();
02649 if ( sfnam != NULL )
02650 free( sfnam );
02651 return TCL_ERROR;
02652 }
02653
02654
02655
02656 plsdev( "plmeta" );
02657 plsfile( sfile );
02658 plcpstrm( plPlotterPtr->ipls, 0 );
02659 pladv( 0 );
02660
02661
02662
02663 plreplot();
02664 plend1();
02665 plsstrm( plPlotterPtr->ipls );
02666
02667
02668
02669 if ( plPlotterPtr->plpr_cmd == NULL )
02670 plPlotterPtr->plpr_cmd = plFindCommand( "plpr" );
02671
02672 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
02673 if ( ( plPlotterPtr->plpr_cmd == NULL ) || ( pid = fork() ) < 0 )
02674 {
02675 Tcl_AppendResult( interp,
02676 "Error -- cannot fork print process",
02677 (char *) NULL );
02678 result = TCL_ERROR;
02679 }
02680 else if ( pid == 0 )
02681 {
02682 if ( execl( plPlotterPtr->plpr_cmd, plPlotterPtr->plpr_cmd, sfnam,
02683 (char *) 0 ) )
02684 {
02685 fprintf( stderr, "Unable to exec print command.\n" );
02686 free( sfnam );
02687 _exit( 1 );
02688 }
02689 }
02690 #endif
02691 free( sfnam );
02692 return result;
02693 }
02694
02695
02696
02697
02698
02699
02700
02701 static int
02702 NextPage( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02703 int argc, CONST char **argv )
02704 {
02705 TkwDev *dev = (TkwDev *) plPlotterPtr->pls->dev;
02706 if ( argc == 0 )
02707 {
02708 dev->flags |= 2;
02709 }
02710 else
02711 {
02712 Tcl_AppendResult( interp, "wrong # args: should be \"",
02713 " nextpage\"", (char *) NULL );
02714 return TCL_ERROR;
02715 }
02716 return TCL_OK;
02717 }
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727 static int
02728 Page( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02729 int argc, CONST char **argv )
02730 {
02731
02732
02733 plsstrm( plPlotterPtr->ipls );
02734
02735 if ( argc == 0 )
02736 {
02737 PLFLT mar, aspect, jx, jy;
02738 char result_str[128];
02739
02740 plgdidev( &mar, &aspect, &jx, &jy );
02741 sprintf( result_str, "%g %g %g %g", mar, aspect, jx, jy );
02742 Tcl_SetResult( interp, result_str, TCL_VOLATILE );
02743 return TCL_OK;
02744 }
02745
02746
02747
02748 if ( argc < 4 )
02749 {
02750 Tcl_AppendResult( interp, "wrong # args: should be \"",
02751 " page mar aspect jx jy\"", (char *) NULL );
02752 return TCL_ERROR;
02753 }
02754
02755 plsdidev( (PLFLT) atof( argv[0] ), (PLFLT) atof( argv[1] ),
02756 (PLFLT) atof( argv[2] ), (PLFLT) atof( argv[3] ) );
02757 return ( Redraw( interp, plPlotterPtr, argc - 1, argv + 1 ) );
02758 }
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768 static int
02769 Redraw( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02770 int argc, CONST char **argv )
02771 {
02772 dbug_enter( "Redraw" );
02773
02774 plPlotterPtr->flags |= REDRAW_PENDING;
02775 if ( ( plPlotterPtr->tkwin != NULL ) &&
02776 !( plPlotterPtr->flags & REFRESH_PENDING ) )
02777 {
02778 Tcl_DoWhenIdle( DisplayPlPlotter, (ClientData) plPlotterPtr );
02779 plPlotterPtr->flags |= REFRESH_PENDING;
02780 }
02781
02782 return TCL_OK;
02783 }
02784
02785
02786
02787
02788
02789
02790
02791
02792 static int
02793 Save( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02794 int argc, CONST char **argv )
02795 {
02796 int length;
02797 char c;
02798 FILE *sfile;
02799
02800
02801
02802 if ( !plPlotterPtr->tkwin_initted )
02803 {
02804 Tcl_AppendResult( interp, "Error -- widget not plotted to yet",
02805 (char *) NULL );
02806 return TCL_ERROR;
02807 }
02808
02809
02810
02811 if ( argc == 0 )
02812 {
02813 if ( !plPlotterPtr->ipls_save )
02814 {
02815 Tcl_AppendResult( interp, "Error -- no current save file",
02816 (char *) NULL );
02817 return TCL_ERROR;
02818 }
02819 plsstrm( plPlotterPtr->ipls_save );
02820 plcpstrm( plPlotterPtr->ipls, 0 );
02821 pladv( 0 );
02822 plreplot();
02823 plflush();
02824 plsstrm( plPlotterPtr->ipls );
02825 return TCL_OK;
02826 }
02827
02828 c = argv[0][0];
02829 length = strlen( argv[0] );
02830
02831
02832
02833 if ( ( c == 'a' ) && ( strncmp( argv[0], "as", length ) == 0 ) )
02834 {
02835 if ( argc < 3 )
02836 {
02837 Tcl_AppendResult( interp, "wrong # args: should be \"",
02838 " save as device file\"", (char *) NULL );
02839 return TCL_ERROR;
02840 }
02841
02842
02843
02844 if ( plPlotterPtr->ipls_save )
02845 {
02846 plsstrm( plPlotterPtr->ipls_save );
02847 plend1();
02848 }
02849
02850
02851
02852 plmkstrm( &plPlotterPtr->ipls_save );
02853 if ( plPlotterPtr->ipls_save < 0 )
02854 {
02855 Tcl_AppendResult( interp, "Error -- cannot create stream",
02856 (char *) NULL );
02857 plPlotterPtr->ipls_save = 0;
02858 return TCL_ERROR;
02859 }
02860
02861
02862
02863 if ( ( sfile = fopen( argv[2], "wb+" ) ) == NULL )
02864 {
02865 Tcl_AppendResult( interp, "Error -- cannot open file ", argv[2],
02866 " for writing", (char *) NULL );
02867 plPlotterPtr->ipls_save = 0;
02868 plend1();
02869 return TCL_ERROR;
02870 }
02871
02872
02873
02874 plsdev( argv[1] );
02875 plsfile( sfile );
02876 plcpstrm( plPlotterPtr->ipls, 0 );
02877 pladv( 0 );
02878
02879
02880
02881 plreplot();
02882 plflush();
02883 plsstrm( plPlotterPtr->ipls );
02884 }
02885
02886
02887
02888 else if ( ( c == 'c' ) && ( strncmp( argv[0], "close", length ) == 0 ) )
02889 {
02890 if ( !plPlotterPtr->ipls_save )
02891 {
02892 Tcl_AppendResult( interp, "Error -- no current save file",
02893 (char *) NULL );
02894 return TCL_ERROR;
02895 }
02896 else
02897 {
02898 plsstrm( plPlotterPtr->ipls_save );
02899 plend1();
02900 plPlotterPtr->ipls_save = 0;
02901 }
02902 }
02903
02904
02905
02906 else
02907 {
02908 Tcl_AppendResult( interp, "bad option to \"save\": must be ",
02909 "as or close", (char *) NULL );
02910
02911 return TCL_ERROR;
02912 }
02913
02914 return TCL_OK;
02915 }
02916
02917
02918
02919
02920
02921
02922
02923
02924 static int
02925 View( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
02926 int argc, CONST char **argv )
02927 {
02928 int length;
02929 int dontRedraw = 0;
02930 char c;
02931 PLFLT xl, xr, yl, yr;
02932
02933
02934
02935 plsstrm( plPlotterPtr->ipls );
02936
02937 if ( argc == 0 )
02938 {
02939 char result_str[128];
02940 plgdiplt( &xl, &yl, &xr, &yr );
02941 sprintf( result_str, "%g %g %g %g", xl, yl, xr, yr );
02942 Tcl_SetResult( interp, result_str, TCL_VOLATILE );
02943 return TCL_OK;
02944 }
02945
02946 c = argv[0][0];
02947 length = strlen( argv[0] );
02948
02949
02950
02951
02952 if ( ( c == 'b' ) && ( strncmp( argv[0], "bounds", length ) == 0 ) )
02953 {
02954 char result_str[128];
02955 xl = 0.; yl = 0.;
02956 xr = 1.; yr = 1.;
02957 pldip2dc( &xl, &yl, &xr, &yr );
02958 sprintf( result_str, "%g %g %g %g", xl, yl, xr, yr );
02959 Tcl_SetResult( interp, result_str, TCL_VOLATILE );
02960 return TCL_OK;
02961 }
02962
02963
02964
02965 if ( ( c == 'r' ) && ( strncmp( argv[0], "reset", length ) == 0 ) )
02966 {
02967 xl = 0.; yl = 0.;
02968 xr = 1.; yr = 1.;
02969 plsdiplt( xl, yl, xr, yr );
02970 if ( argc > 1 && ( strcmp( argv[1], "wait" ) == 0 ) )
02971 {
02972
02973 dontRedraw = 1;
02974 }
02975 }
02976
02977
02978
02979
02980 else if ( ( c == 's' ) && ( strncmp( argv[0], "select", length ) == 0 ) )
02981 {
02982 if ( argc < 5 )
02983 {
02984 Tcl_AppendResult( interp, "wrong # args: should be \"",
02985 " view select xmin ymin xmax ymax\"",
02986 (char *) NULL );
02987 return TCL_ERROR;
02988 }
02989 else
02990 {
02991 gbox( &xl, &yl, &xr, &yr, argv + 1 );
02992 plsdiplt( xl, yl, xr, yr );
02993 }
02994 }
02995
02996
02997
02998
02999 else if ( ( c == 'z' ) && ( strncmp( argv[0], "zoom", length ) == 0 ) )
03000 {
03001 if ( argc < 5 )
03002 {
03003 Tcl_AppendResult( interp, "wrong # args: should be \"",
03004 " view zoom xmin ymin xmax ymax\"",
03005 (char *) NULL );
03006 return TCL_ERROR;
03007 }
03008 else
03009 {
03010 gbox( &xl, &yl, &xr, &yr, argv + 1 );
03011 pldid2pc( &xl, &yl, &xr, &yr );
03012 plsdiplz( xl, yl, xr, yr );
03013 if ( argc > 5 && ( strcmp( argv[5], "wait" ) == 0 ) )
03014 {
03015
03016 dontRedraw = 1;
03017 }
03018 }
03019 }
03020
03021
03022
03023 else
03024 {
03025 Tcl_AppendResult( interp, "bad option \"", argv[1],
03026 "\": options to \"view\" are: bounds, reset, select, or zoom",
03027 (char *) NULL );
03028
03029 return TCL_ERROR;
03030 }
03031
03032
03033
03034 plgdiplt( &xl, &yl, &xr, &yr );
03035 plPlotterPtr->xl = xl;
03036 plPlotterPtr->yl = yl;
03037 plPlotterPtr->xr = xr;
03038 plPlotterPtr->yr = yr;
03039 plPlotterPtr->flags |= UPDATE_V_SCROLLBAR | UPDATE_H_SCROLLBAR;
03040
03041 if ( dontRedraw )
03042 {
03043 return TCL_OK;
03044 }
03045 else
03046 {
03047 return Redraw( interp, plPlotterPtr, argc, argv );
03048 }
03049 }
03050
03051
03052
03053
03054
03055
03056
03057
03058 static int
03059 Scroll( Tcl_Interp *interp, register PlPlotter *plPlotterPtr )
03060 {
03061 plsstrm( plPlotterPtr->ipls );
03062 plsdiplt( plPlotterPtr->xl, plPlotterPtr->yl, plPlotterPtr->xr, plPlotterPtr->yr );
03063
03064 plPlotterPtr->flags |= UPDATE_V_SCROLLBAR | UPDATE_H_SCROLLBAR;
03065 return ( Redraw( interp, plPlotterPtr, 0, NULL ) );
03066 }
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076 static int
03077 report( Tcl_Interp *interp, register PlPlotter *plPlotterPtr,
03078 int argc, CONST char **argv )
03079 {
03080 PLFLT x, y;
03081
03082
03083 if ( argc == 0 )
03084 {
03085 interp->result = "report what?";
03086 return TCL_ERROR;
03087 }
03088
03089 if ( !strcmp( argv[0], "wc" ) )
03090 {
03091 TkwDev *dev = (TkwDev *) plPlotterPtr->pls->dev;
03092 PLGraphicsIn *gin = &( dev->gin );
03093
03094 if ( argc != 3 )
03095 {
03096 interp->result = "Wrong # of args: report wc x y";
03097 return TCL_ERROR;
03098 }
03099
03100 x = (PLFLT) atof( argv[1] );
03101 y = (PLFLT) atof( argv[2] );
03102
03103 gin->dX = (PLFLT) x / ( dev->width - 1 );
03104 gin->dY = (PLFLT) 1.0 - (PLFLT) y / ( dev->height - 1 );
03105
03106
03107
03108 if ( plTranslateCursor( gin ) )
03109 {
03110 sprintf( interp->result, "%f %f", gin->wX, gin->wY );
03111 return TCL_OK;
03112 }
03113
03114 interp->result = "Cannot locate";
03115 return TCL_OK;
03116 }
03117
03118 interp->result = "nonsensical request.";
03119 return TCL_ERROR;
03120 }
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132 static void
03133 UpdateVScrollbar( register PlPlotter *plPlotterPtr )
03134 {
03135 char string[60];
03136 int result;
03137
03138 if ( plPlotterPtr->yScrollCmd == NULL )
03139 return;
03140
03141 sprintf( string, " %f %f", 1. - plPlotterPtr->yr, 1. - plPlotterPtr->yl );
03142
03143 result = Tcl_VarEval( plPlotterPtr->interp, plPlotterPtr->yScrollCmd, string,
03144 (char *) NULL );
03145
03146 if ( result != TCL_OK )
03147 {
03148 Tcl_BackgroundError( plPlotterPtr->interp );
03149 }
03150 }
03151
03152
03153
03154
03155
03156
03157
03158 static void
03159 UpdateHScrollbar( register PlPlotter *plPlotterPtr )
03160 {
03161 char string[60];
03162 int result;
03163
03164 if ( plPlotterPtr->xScrollCmd == NULL )
03165 return;
03166
03167 sprintf( string, " %f %f", plPlotterPtr->xl, plPlotterPtr->xr );
03168
03169 result = Tcl_VarEval( plPlotterPtr->interp, plPlotterPtr->xScrollCmd, string,
03170 (char *) NULL );
03171
03172 if ( result != TCL_OK )
03173 {
03174 Tcl_BackgroundError( plPlotterPtr->interp );
03175 }
03176 }
03177
03178
03179
03180
03181
03182
03183
03184
03185 static void
03186 gbox( PLFLT *xl, PLFLT *yl, PLFLT *xr, PLFLT *yr, CONST char **argv )
03187 {
03188 PLFLT x0, y0, x1, y1;
03189
03190 x0 = (PLFLT) atof( argv[0] );
03191 y0 = (PLFLT) atof( argv[1] );
03192 x1 = (PLFLT) atof( argv[2] );
03193 y1 = (PLFLT) atof( argv[3] );
03194
03195 x0 = MAX( (PLFLT) 0., MIN( (PLFLT) 1., x0 ) );
03196 y0 = MAX( (PLFLT) 0., MIN( (PLFLT) 1., y0 ) );
03197 x1 = MAX( (PLFLT) 0., MIN( (PLFLT) 1., x1 ) );
03198 y1 = MAX( (PLFLT) 0., MIN( (PLFLT) 1., y1 ) );
03199
03200
03201
03202 *xl = MIN( x0, x1 );
03203 *yl = MIN( y0, y1 );
03204 *xr = MAX( x0, x1 );
03205 *yr = MAX( y0, y1 );
03206 }
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221