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 #include "plDevs.h"
00027
00028 #ifdef PLD_ntk
00029
00030 #include "plplotP.h"
00031 #include "drivers.h"
00032 #include "plevent.h"
00033
00034 #include <tk.h>
00035
00036
00037 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_ntk = "ntk:New tk driver:1:ntk:43:ntk\n";
00038
00039
00040 void plD_dispatch_init_ntk( PLDispatchTable *pdt );
00041
00042 void plD_init_ntk( PLStream * );
00043 void plD_line_ntk( PLStream *, short, short, short, short );
00044 void plD_polyline_ntk( PLStream *, short *, short *, PLINT );
00045 void plD_eop_ntk( PLStream * );
00046 void plD_bop_ntk( PLStream * );
00047 void plD_tidy_ntk( PLStream * );
00048 void plD_state_ntk( PLStream *, PLINT );
00049 void plD_esc_ntk( PLStream *, PLINT, void * );
00050
00051 void plD_dispatch_init_ntk( PLDispatchTable *pdt )
00052 {
00053 #ifndef ENABLE_DYNDRIVERS
00054 pdt->pl_MenuStr = "New Tk device";
00055 pdt->pl_DevName = "ntk";
00056 #endif
00057 pdt->pl_type = plDevType_Interactive;
00058 pdt->pl_seq = 43;
00059 pdt->pl_init = (plD_init_fp) plD_init_ntk;
00060 pdt->pl_line = (plD_line_fp) plD_line_ntk;
00061 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_ntk;
00062 pdt->pl_eop = (plD_eop_fp) plD_eop_ntk;
00063 pdt->pl_bop = (plD_bop_fp) plD_bop_ntk;
00064 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_ntk;
00065 pdt->pl_state = (plD_state_fp) plD_state_ntk;
00066 pdt->pl_esc = (plD_esc_fp) plD_esc_ntk;
00067 }
00068
00069
00070 #define XPIXELS 600
00071 #define YPIXELS 400
00072
00073 static PLFLT scale = 10.0;
00074 static PLFLT ppm;
00075
00076 static Tcl_Interp *interp = NULL;
00077 static Tk_Window mainw;
00078
00079 static char curcolor[80];
00080 static char cmd[10000];
00081 static int ccanv = 0;
00082 static char base[80];
00083 static char dash[80];
00084
00085
00086 #define NPTS 1000
00087 static short xold = -1, yold = -1;
00088 static short xb[NPTS], yb[NPTS];
00089 static int curpts = 0;
00090
00091 static int local = 1;
00092 static char rem_interp[80];
00093
00094
00095 static PLINT xmin = 0;
00096 static PLINT xmax = XPIXELS;
00097 static PLINT ymin = 0;
00098 static PLINT ymax = YPIXELS;
00099
00100
00101 static PLGraphicsIn gin;
00102
00103 static void
00104 tk_cmd( char *cmd )
00105 {
00106 static char scmd[10000];
00107
00108 if ( local )
00109 Tcl_Eval( interp, cmd );
00110 else
00111 {
00112
00113
00114
00115
00116 sprintf( scmd, "send %s {%s}", rem_interp, cmd );
00117 if ( Tcl_Eval( interp, scmd ) != TCL_OK )
00118 fprintf( stderr, "%s\n", interp->result );
00119 }
00120 }
00121
00122 static void
00123 create_canvas( PLStream *pls )
00124 {
00125 ccanv++;
00126
00127
00128 sprintf( cmd, "set ccanv %d; canvas $plf.f2.c$ccanv -width $xmax -height $ymax -background #%02x%02x%02x -xscrollcommand \"$hs set\" -yscrollcommand \"$vs set\" -scrollregion \"0 0 $xmax $ymax\"", ccanv, pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b );
00129 tk_cmd( cmd );
00130
00131
00132 sprintf( cmd, "$plf.f1.mb.menu add command -label \"Page $ccanv\" -command {\n"
00133 "set w $plf.f2.c%d;\n"
00134 "$hs configure -command \"$w xview\";\n"
00135 "$vs configure -command \"$w yview\";\n"
00136 "set dname \"Page %d\";\n"
00137 "pack forget $ocanvas;\n"
00138 "set ocanvas $plf.f2.c%d;\n"
00139 "pack $ocanvas -fill both -expand 1;\n"
00140 "scan [$w xview] \"%%f %%f\" i j;\n"
00141 "$hs set $i $j;\n"
00142 "scan [$w yview] \"%%f %%f\" i j;\n"
00143 "$vs set $i $j;}",
00144 ccanv, ccanv, ccanv );
00145 tk_cmd( cmd );
00146
00147 sprintf( cmd, "set item(%d) 0", ccanv );
00148 tk_cmd( cmd );
00149
00150
00151
00152
00153 sprintf( cmd, "bind $plf.f2.c$ccanv <Shift-Button-1> {\n"
00154 "set cc %d;\n"
00155 "incr item($cc); set tt $item($cc);\n"
00156 "if {$tt == 1} {\n"
00157 "incr scroll_use;\n"
00158 "pack $hs -side bottom -fill x;\n"
00159 "pack $vs -side right -fill y;\n"
00160 "pack forget %%W; pack %%W -fill both -expand 1}\n"
00161 "set zx($cc,$tt) %%x;\n"
00162 "set zy($cc,$tt) %%y;\n"
00163 "%%W scale all %%x %%y 1.6 1.6;\n"
00164 "%%W configure -scrollregion [%%W bbox all];\n"
00165 "}", ccanv );
00166
00167 tk_cmd( cmd );
00168
00169
00170 sprintf( cmd, "bind $plf.f2.c$ccanv <Shift-Button-3> {\n"
00171 "set cc %d; set tt $item($cc);\n"
00172 "if {$tt != 0} {\n"
00173 "%%W scale all $zx($cc,$tt) $zy($cc,$tt) 0.625 0.625\n"
00174 "%%W configure -scrollregion [%%W bbox all];\n"
00175 "set item($cc) [expr $tt - 1]}\n"
00176 "if { $item($cc) == 0} {\n"
00177 "set scroll_use [expr $scroll_use - 1];\n"
00178 "if {$scroll_use == 0} {\n"
00179 "pack forget $plf.f2.hscroll $plf.f2.vscroll}\n"
00180 "%%W configure -scrollregion \"0 0 $xmax $ymax\"}}", ccanv );
00181 tk_cmd( cmd );
00182
00183
00184 sprintf( cmd, "bind $plf.f2.c$ccanv <Shift-Button-2> {\n"
00185 "set cc %d; set tt $item($cc); \n"
00186 "while {$tt != 0} {\n"
00187 "%%W scale all $zx($cc,$tt) $zy($cc,$tt) 0.625 0.625\n"
00188 "set tt [expr $tt - 1]};\n"
00189 "set item($cc) 0;\n"
00190 "%%W configure -scrollregion \"0 0 $xmax $ymax\";\n"
00191 "set scroll_use [expr $scroll_use - 1];\n"
00192 "if {$scroll_use == 0} {\n"
00193 "pack forget $plf.f2.hscroll $plf.f2.vscroll}}", ccanv );
00194 tk_cmd( cmd );
00195
00196
00197 sprintf( cmd, "bind $plf.f2.c$ccanv <Control-Button-1> \"$plf.f2.c%d scan mark %%x %%y\"", ccanv );
00198 tk_cmd( cmd );
00199
00200 sprintf( cmd, "bind $plf.f2.c$ccanv <Control-Button1-Motion> \"$plf.f2.c%d scan dragto %%x %%y\"", ccanv );
00201 tk_cmd( cmd );
00202
00203
00204 tk_cmd( "bind $plf.f2.c$ccanv <Control-Button-2> {\n"
00205 "set xx [ expr [winfo pointerx .] - [winfo rootx %W]];\n"
00206 "set yy [ expr [winfo pointery .] - [winfo rooty %W]];\n"
00207 "set near [%W find closest $xx $yy];\n"
00208 "%W move $near 20 20;\n"
00209 "after 500 \"%W move $near -20 -20\"}" );
00210
00211
00212 sprintf( cmd, "$plf.f1.mb.menu invoke %d", ccanv - 1 );
00213 tk_cmd( cmd );
00214 }
00215
00216
00217
00218
00219
00220
00221
00222 void
00223 plD_init_ntk( PLStream *pls )
00224 {
00225 pls->dev_fill0 = 1;
00226 pls->dev_fill1 = 1;
00227 pls->color = 1;
00228 pls->dev_dash = 1;
00229 pls->plbuf_write = 1;
00230
00231 strcpy( curcolor, "black" );
00232
00233 if ( pls->server_name != NULL )
00234 {
00235 local = 0;
00236 strcpy( rem_interp, pls->server_name );
00237 }
00238
00239 if ( pls->geometry != NULL )
00240 sscanf( pls->geometry, "%dx%d", &xmax, &ymax );
00241
00242 if ( pls->plwindow != NULL )
00243 strcpy( base, pls->plwindow );
00244 else
00245 strcpy( base, ".plf" );
00246
00247 interp = Tcl_CreateInterp();
00248
00249 if ( Tcl_Init( interp ) != TCL_OK )
00250 plexit( "Unable to initialize Tcl." );
00251
00252 if ( Tk_Init( interp ) )
00253 plexit( "Unable to initialize Tk." );
00254
00255 mainw = Tk_MainWindow( interp );
00256 Tcl_Eval( interp, "rename exec {}" );
00257
00258 Tcl_Eval( interp, "tk appname PLplot_ntk" );
00259
00260 if ( !local )
00261 {
00262 Tcl_Eval( interp, "wm withdraw ." );
00263
00264 sprintf( cmd, "send %s \"set client [tk appname]; wm deiconify .\"", rem_interp );
00265 if ( Tcl_Eval( interp, cmd ) != TCL_OK )
00266 {
00267 fprintf( stderr, "%s\n", interp->result );
00268 plexit( "No such tk server." );
00269 }
00270 }
00271
00272 sprintf( cmd, "set scroll_use 0; set plf %s; set vs $plf.f2.vscroll; set hs $plf.f2.hscroll; set xmax %d; set ymax %d; set ocanvas .;", base, xmax, ymax );
00273 tk_cmd( cmd );
00274
00275 tk_cmd( "catch \"frame $plf\"; pack $plf -fill both -expand 1" );
00276
00277 sprintf( cmd, "frame $plf.f1;\n"
00278 "frame $plf.f2 -width %d -height %d;\n"
00279 "pack $plf.f1 -fill x;\n"
00280 "pack $plf.f2 -fill both -expand 1", xmax, ymax );
00281 tk_cmd( cmd );
00282
00283 tk_cmd( "scrollbar $plf.f2.hscroll -orient horiz;\n"
00284 "scrollbar $plf.f2.vscroll" );
00285
00286 tk_cmd( "menubutton $plf.f1.mb -text \"Page 1\" -textvariable dname -relief raised -indicatoron 1 -menu $plf.f1.mb.menu;\n"
00287 "menu $plf.f1.mb.menu -tearoff 0;\n"
00288 "pack $plf.f1.mb -side left" );
00289
00290 if ( local )
00291 tk_cmd( "button $plf.f1.quit -text Quit -command exit;\n"
00292 "pack $plf.f1.quit -side right" );
00293 else
00294 tk_cmd( "button $plf.f1.quit -text Quit -command {send -async $client exit;\n"
00295 "destroy $plf;\n"
00296 "wm withdraw .};\n"
00297 "pack $plf.f1.quit -side right" );
00298
00299
00300
00301
00302
00303 Tcl_Eval( interp, "tk scaling" );
00304 ppm = (PLFLT) atof( interp->result ) / ( 25.4 / 72. );
00305 plP_setpxl( ppm, ppm );
00306 plP_setphy( xmin, xmax * scale, ymin, ymax * scale );
00307 }
00308
00309 static void
00310 flushbuffer( PLStream *pls )
00311 {
00312 if ( curpts )
00313 {
00314 plD_polyline_ntk( pls, xb, yb, curpts );
00315
00316 xold = yold = -1; curpts = 0;
00317 }
00318 }
00319
00320 void
00321 plD_line_ntk( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
00322 {
00323 if ( xold == x1a && yold == y1a )
00324 {
00325 xold = xb[curpts] = x2a; yold = yb[curpts] = y2a; curpts++;
00326 }
00327 else
00328 {
00329 flushbuffer( pls );
00330 xb[curpts] = x1a; yb[curpts] = y1a; curpts++;
00331 xold = xb[curpts] = x2a; yold = yb[curpts] = y2a; curpts++;
00332 }
00333
00334 if ( curpts == NPTS )
00335 {
00336 fprintf( stderr, "\nflush: %d ", curpts );
00337 flushbuffer( pls );
00338 }
00339 }
00340
00341 void
00342 plD_polyline_ntk( PLStream *pls, short *xa, short *ya, PLINT npts )
00343 {
00344 PLINT i, j;
00345
00346
00347 j = sprintf( cmd, "$plf.f2.c%d create line ", ccanv );
00348 for ( i = 0; i < npts; i++ )
00349 j += sprintf( &cmd[j], "%.1f %.1f ", xa[i] / scale, ymax - ya[i] / scale );
00350
00351 j += sprintf( &cmd[j], " -fill %s", curcolor );
00352 if ( dash[0] == '-' )
00353 j += sprintf( &cmd[j], " %s", dash );
00354
00355 tk_cmd( cmd );
00356 }
00357
00358
00359
00360 static void
00361 waitforpage( PLStream *pls )
00362 {
00363 int key = 0, st = 0;
00364
00365
00366 tk_cmd( "bind . <KeyPress> {set keypress %N}" );
00367
00368 while ( ( key & 0xff ) != PLK_Return && ( key & 0xff ) != PLK_Linefeed && key != PLK_Next && key != 'Q' )
00369 {
00370 while ( st != 1 )
00371 {
00372 tk_cmd( "update" );
00373 tk_cmd( "info exists keypress" );
00374 sscanf( interp->result, "%d", &st );
00375 }
00376
00377 tk_cmd( "set keypress" );
00378 sscanf( interp->result, "%d", &key );
00379
00380 tk_cmd( "unset keypress" );
00381 st = 0;
00382 }
00383
00384 tk_cmd( "bind . <Key> {};" );
00385 }
00386
00387 void
00388 plD_eop_ntk( PLStream *pls )
00389 {
00390 flushbuffer( pls );
00391 tk_cmd( "update" );
00392 }
00393
00394 void
00395 plD_bop_ntk( PLStream *pls )
00396 {
00397 create_canvas( pls );
00398 }
00399
00400 void
00401 plD_tidy_ntk( PLStream *pls )
00402 {
00403 if ( !pls->nopause )
00404 waitforpage( pls );
00405
00406 tk_cmd( "destroy $plf; wm withdraw ." );
00407 }
00408
00409 void
00410 plD_state_ntk( PLStream *pls, PLINT op )
00411 {
00412 switch ( op )
00413 {
00414 case PLSTATE_COLOR0:
00415 case PLSTATE_COLOR1:
00416 flushbuffer( pls );
00417 sprintf( curcolor, "#%02x%02x%02x",
00418 pls->curcolor.r, pls->curcolor.g, pls->curcolor.b );
00419 break;
00420 }
00421 }
00422
00423 static void
00424 getcursor( PLStream *pls, PLGraphicsIn *ptr )
00425 {
00426 int st = 0;
00427
00428 plGinInit( &gin );
00429
00430 if ( 0 )
00431 {
00432 while ( st != 1 )
00433 {
00434 tk_cmd( "update" );
00435 tk_cmd( "winfo exists $plf.f2.c$ccanv" );
00436 sscanf( interp->result, "%d", &st );
00437 }
00438 st = 0;
00439
00440 tk_cmd( "set ocursor [lindex [$plf.f2.c$ccanv configure -cursor] 4]" );
00441 }
00442
00443 tk_cmd( "$plf.f2.c$ccanv configure -cursor cross;\n"
00444 "bind $plf.f2.c$ccanv <Button> {set xloc %x; set yloc %y; set bloc %b; set sloc %s};\n"
00445 "bind $plf.f2.c$ccanv <B1-Motion> {set xloc %x; set yloc %y; set bloc %b; set sloc %s};\n"
00446 "bind $plf.f2.c$ccanv <B2-Motion> {set xloc %x; set yloc %y; set bloc %b; set sloc %s};\n"
00447 "bind $plf.f2.c$ccanv <B3-Motion> {set xloc %x; set yloc %y; set bloc %b; set sloc %s};" );
00448
00449 while ( st != 1 )
00450 {
00451 tk_cmd( "update" );
00452 tk_cmd( "info exists xloc" );
00453 sscanf( interp->result, "%d", &st );
00454 }
00455 tk_cmd( "set xloc" );
00456 sscanf( interp->result, "%d", &gin.pX );
00457 tk_cmd( "set yloc" );
00458 sscanf( interp->result, "%d", &gin.pY );
00459 tk_cmd( "set bloc" );
00460 sscanf( interp->result, "%d", &gin.button );
00461 tk_cmd( "set sloc" );
00462 sscanf( interp->result, "%d", &gin.state );
00463
00464 gin.dX = (PLFLT) gin.pX / xmax;
00465 gin.dY = 1. - (PLFLT) gin.pY / ymax;
00466
00467 tk_cmd( "bind $plf.f2.c$ccanv <ButtonPress> {};\n"
00468 "bind $plf.f2.c$ccanv <ButtonMotion> {};\n"
00469 "bind $plf.f2.c$ccanv <B2-Motion> {};\n"
00470 "bind $plf.f2.c$ccanv <B3-Motion> {};\n"
00471 "unset xloc" );
00472
00473
00474 tk_cmd( "$plf.f2.c$ccanv configure -cursor {}" );
00475
00476 *ptr = gin;
00477 }
00478
00479 void
00480 plD_esc_ntk( PLStream *pls, PLINT op, void *ptr )
00481 {
00482 PLINT i, j;
00483 short *xa, *ya;
00484 Pixmap bitmap;
00485 static unsigned char bit_pat[] = {
00486 0x24, 0x01, 0x92, 0x00, 0x49, 0x00, 0x24, 0x00, 0x12, 0x00, 0x09, 0x00,
00487 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff
00489 };
00490
00491 switch ( op )
00492 {
00493 case PLESC_DASH:
00494 xa = (short *) malloc( sizeof ( short ) * pls->dev_npts );
00495 ya = (short *) malloc( sizeof ( short ) * pls->dev_npts );
00496 for ( i = 0; i < pls->dev_npts; i++ )
00497 {
00498 xa[i] = pls->dev_x[i];
00499 ya[i] = pls->dev_y[i];
00500 }
00501
00502 j = sprintf( dash, "-dash {" );
00503 for ( i = 0; i < pls->nms; i++ )
00504 j += sprintf( &dash[j], " %d %d",
00505 (int) ceil( pls->mark[i] / 1e3 * ppm ),
00506 (int) ceil( pls->space[i] / 1e3 * ppm ) );
00507 sprintf( &dash[j], "}" );
00508 plD_polyline_ntk( pls, xa, ya, pls->dev_npts );
00509 free( xa ); free( ya );
00510 dash[0] = 0;
00511 break;
00512
00513 case PLESC_FLUSH:
00514 tk_cmd( "update" );
00515 break;
00516
00517 case PLESC_GETC:
00518 getcursor( pls, (PLGraphicsIn *) ptr );
00519 break;
00520
00521 case PLESC_FILL:
00522 if ( pls->patt != 0 )
00523 {
00524
00525 pls->xpmm *= scale;
00526 pls->ypmm *= scale;
00527 plfill_soft( pls->dev_x, pls->dev_y, pls->dev_npts );
00528 pls->xpmm /= scale;
00529 pls->ypmm /= scale;
00530 }
00531 else
00532 {
00533 j = sprintf( cmd, "$plf.f2.c%d create polygon ", ccanv );
00534 for ( i = 0; i < pls->dev_npts; i++ )
00535 j += sprintf( &cmd[j], "%.1f %.1f ", pls->dev_x[i] / scale,
00536 ymax - pls->dev_y[i] / scale );
00537 j += sprintf( &cmd[j], " -fill %s", curcolor );
00538 tk_cmd( cmd );
00539 }
00540
00541 if ( 0 )
00542 {
00543 if ( pls->patt != 0 )
00544 {
00545 Tk_DefineBitmap( interp, Tk_GetUid( "foo" ), bit_pat, 16, 16 );
00546 bitmap = Tk_GetBitmap( interp, mainw, Tk_GetUid( "patt" ) );
00547 }
00548 j = sprintf( cmd, "$plf.f2.c%d create polygon ", ccanv );
00549 for ( i = 0; i < pls->dev_npts; i++ )
00550 j += sprintf( &cmd[j], "%.1f %.1f ", pls->dev_x[i] / scale,
00551 ymax - pls->dev_y[i] / scale );
00552 j += sprintf( &cmd[j], " -fill %s", curcolor );
00553 if ( pls->patt != 0 )
00554 sprintf( &cmd[j], " -stipple patt -outline black" );
00555
00556 tk_cmd( cmd );
00557
00558 }
00559 break;
00560 }
00561 }
00562
00563 #else
00564 int
00565 pldummy_ntk()
00566 {
00567 return 0;
00568 }
00569
00570 #endif // PLD_ntkdev