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 #include "plDevs.h"
00033
00034 #define DEBUG
00035
00036 #ifdef PLD_tkwin
00037
00038
00039 #define NEED_PLDEBUG
00040 #include "plplotP.h"
00041 #include "pltkwd.h"
00042 #include "drivers.h"
00043 #include "plevent.h"
00044
00045 #define _TCLINT
00046 #ifdef USE_TCL_STUBS
00047
00048
00049 #undef malloc
00050 #undef free
00051 #undef realloc
00052 #undef calloc
00053 #if defined ( __WIN32__ ) || defined ( MAC_TCL )
00054 #include <tkInt.h>
00055 #else
00056 #include <tk.h>
00057 #endif
00058 #define malloc ckalloc
00059 #define free( m ) ckfree( (char *) m )
00060 #define realloc ckrealloc
00061 #define calloc ckcalloc
00062 #else
00063 #if defined ( __WIN32__ ) || defined ( MAC_TCL )
00064 #include <tkInt.h>
00065 #else
00066 #include <tk.h>
00067 #endif
00068 #endif
00069
00070 #ifdef ckalloc
00071 #undef ckalloc
00072 #define ckalloc malloc
00073 #endif
00074 #ifdef ckfree
00075 #undef ckfree
00076 #define ckfree free
00077 #endif
00078 #ifdef free
00079 #undef free
00080 #endif
00081
00082
00083 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_tkwin = "tkwin:New tk driver:1:tkwin:45:tkwin\n";
00084
00085
00086 void * ckcalloc( size_t nmemb, size_t size );
00087
00088
00089
00090
00091
00092
00093
00094 #define USE_TK
00095
00096 #ifdef __WIN32__
00097 #define XSynchronize( display, bool ) { display->request++; }
00098 #define XSync( display, bool ) { display->request++; }
00099 #define XFlush( display )
00100 #endif
00101
00102
00103 typedef struct PlPlotter
00104 {
00105 Tk_Window tkwin;
00106
00107
00108
00109
00110 Display *display;
00111
00112
00113
00114 Tcl_Interp *interp;
00115
00116
00117
00118 } PlPlotter;
00119
00120 void CopyColour( XColor* from, XColor* to );
00121 void Tkw_StoreColor( PLStream* pls, TkwDisplay* tkwd, XColor* col );
00122 static int pltk_AreWeGrayscale( PlPlotter *plf );
00123 void PlplotterAtEop( Tcl_Interp *interp, register PlPlotter *plPlotterPtr );
00124 void PlplotterAtBop( Tcl_Interp *interp, register PlPlotter *plPlotterPtr );
00125
00126 static int synchronize = 0;
00127
00128
00129
00130
00131 #define MAX_INSTR 20
00132
00133
00134
00135 #define PHYSICAL 0 // Enables physical scaling..
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 #define XWM_COLORS 70
00154 #define CMAP0_COLORS 16
00155 #define CMAP1_COLORS 50
00156 #define MAX_COLORS 256
00157
00158 #ifndef USE_TK
00159
00160
00161
00162 static int sxwm_colors_set;
00163 static XColor sxwm_colors[MAX_COLORS];
00164 #endif
00165
00166
00167
00168 static TkwDisplay *tkwDisplay[PLTKDISPLAYS];
00169
00170 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
00171 static unsigned char CreatePixmapStatus;
00172 static int CreatePixmapErrorHandler( Display *display, XErrorEvent *error );
00173 #endif
00174
00175
00176
00177
00178 static void Init( PLStream *pls );
00179 static void InitColors( PLStream *pls );
00180 static void AllocCustomMap( PLStream *pls );
00181 static void AllocCmap0( PLStream *pls );
00182 static void AllocCmap1( PLStream *pls );
00183 static void CreatePixmap( PLStream *pls );
00184 static void GetVisual( PLStream *pls );
00185 static void AllocBGFG( PLStream *pls );
00186
00187
00188
00189 static void ExposeCmd( PLStream *pls, PLDisplay *ptr );
00190 static void RedrawCmd( PLStream *pls );
00191 static void ResizeCmd( PLStream *pls, PLDisplay *ptr );
00192 #ifndef USE_TK
00193 static void GetCursorCmd( PLStream *pls, PLGraphicsIn *ptr );
00194 #endif
00195 static void FillPolygonCmd( PLStream *pls );
00196 #ifdef USING_PLESC_COPY
00197 static void CopyCommand( PLStream *pls );
00198 #endif
00199
00200
00201
00202 static void StoreCmap0( PLStream *pls );
00203 static void StoreCmap1( PLStream *pls );
00204 static void WaitForPage( PLStream *pls );
00205
00206 void plD_dispatch_init_tkwin( PLDispatchTable *pdt );
00207
00208 void plD_init_tkwin( PLStream * );
00209 void plD_line_tkwin( PLStream *, short, short, short, short );
00210 void plD_polyline_tkwin( PLStream *, short *, short *, PLINT );
00211 void plD_eop_tkwin( PLStream * );
00212 void plD_bop_tkwin( PLStream * );
00213 void plD_tidy_tkwin( PLStream * );
00214 void plD_state_tkwin( PLStream *, PLINT );
00215 void plD_esc_tkwin( PLStream *, PLINT, void * );
00216 void plD_open_tkwin( PLStream *pls );
00217
00218 void plD_dispatch_init_tkwin( PLDispatchTable *pdt )
00219 {
00220 #ifndef ENABLE_DYNDRIVERS
00221 pdt->pl_MenuStr = "PLplot Tk plotter";
00222 pdt->pl_DevName = "tkwin";
00223 #endif
00224 pdt->pl_type = plDevType_Interactive;
00225 pdt->pl_seq = 45;
00226 pdt->pl_init = (plD_init_fp) plD_init_tkwin;
00227 pdt->pl_line = (plD_line_fp) plD_line_tkwin;
00228 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_tkwin;
00229 pdt->pl_eop = (plD_eop_fp) plD_eop_tkwin;
00230 pdt->pl_bop = (plD_bop_fp) plD_bop_tkwin;
00231 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_tkwin;
00232 pdt->pl_state = (plD_state_fp) plD_state_tkwin;
00233 pdt->pl_esc = (plD_esc_fp) plD_esc_tkwin;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243 void
00244 plD_init_tkwin( PLStream *pls )
00245 {
00246 TkwDev *dev;
00247 float pxlx, pxly;
00248 int xmin = 0;
00249 int xmax = PIXELS_X - 1;
00250 int ymin = 0;
00251 int ymax = PIXELS_Y - 1;
00252
00253 dbug_enter( "plD_init_tkw" );
00254
00255 pls->termin = 1;
00256 pls->dev_flush = 1;
00257 pls->dev_fill0 = 1;
00258 pls->plbuf_write = 1;
00259
00260
00261
00262 if ( pls->dev == NULL )
00263 plD_open_tkwin( pls );
00264
00265 dev = (TkwDev *) pls->dev;
00266
00267 Init( pls );
00268
00269
00270
00271 dev->xlen = xmax - xmin;
00272 dev->ylen = ymax - ymin;
00273
00274 dev->xscale_init = dev->init_width / (double) dev->xlen;
00275 dev->yscale_init = dev->init_height / (double) dev->ylen;
00276
00277 dev->xscale = dev->xscale_init;
00278 dev->yscale = dev->yscale_init;
00279
00280 #if PHYSICAL
00281 pxlx = (PLFLT) ( (double) PIXELS_X / dev->width * DPMM );
00282 pxly = (PLFLT) ( (double) PIXELS_Y / dev->height * DPMM );
00283 #else
00284 pxlx = (PLFLT) ( (double) PIXELS_X / LPAGE_X );
00285 pxly = (PLFLT) ( (double) PIXELS_Y / LPAGE_Y );
00286 #endif
00287
00288 plP_setpxl( pxlx, pxly );
00289 plP_setphy( xmin, xmax, ymin, ymax );
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 void
00302 plD_open_tkwin( PLStream *pls )
00303 {
00304 TkwDev *dev;
00305 TkwDisplay *tkwd;
00306 int i;
00307
00308 dbug_enter( "plD_open_tkw" );
00309
00310
00311
00312 if ( pls->dev != NULL )
00313 plwarn( "plD_open_tkw: device pointer is already set" );
00314
00315 pls->dev = (TkwDev *) calloc( 1, (size_t) sizeof ( TkwDev ) );
00316 if ( pls->dev == NULL )
00317 plexit( "plD_init_tkw: Out of memory." );
00318
00319 dev = (TkwDev *) pls->dev;
00320
00321
00322
00323 dev->instr = 0;
00324 dev->max_instr = MAX_INSTR;
00325
00326
00327
00328 dev->tkwd = NULL;
00329 for ( i = 0; i < PLTKDISPLAYS; i++ )
00330 {
00331 if ( tkwDisplay[i] == NULL )
00332 {
00333 continue;
00334 }
00335 else if ( pls->FileName == NULL && tkwDisplay[i]->displayName == NULL )
00336 {
00337 dev->tkwd = tkwDisplay[i];
00338 break;
00339 }
00340 else if ( pls->FileName == NULL || tkwDisplay[i]->displayName == NULL )
00341 {
00342 continue;
00343 }
00344 else if ( strcmp( tkwDisplay[i]->displayName, pls->FileName ) == 0 )
00345 {
00346 dev->tkwd = tkwDisplay[i];
00347 break;
00348 }
00349 }
00350
00351
00352
00353 if ( dev->tkwd == NULL )
00354 {
00355 dev->tkwd = (TkwDisplay *) calloc( 1, (size_t) sizeof ( TkwDisplay ) );
00356 if ( dev->tkwd == NULL )
00357 plexit( "Init: Out of memory." );
00358
00359 for ( i = 0; i < PLTKDISPLAYS; i++ )
00360 {
00361 if ( tkwDisplay[i] == NULL )
00362 break;
00363 }
00364 if ( i == PLTKDISPLAYS )
00365 plexit( "Init: Out of tkwDisplay's." );
00366
00367 tkwDisplay[i] = tkwd = (TkwDisplay *) dev->tkwd;
00368 tkwd->nstreams = 1;
00369
00370
00371
00372
00373
00374 if ( pls->plPlotterPtr == NULL )
00375 {
00376 plexit( "No tk plframe widget to connect to" );
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386 #if defined ( MAC_TCL ) || defined ( __WIN32__ )
00387 if ( !pls->FileName )
00388 {
00389
00390
00391
00392
00393
00394 pls->FileName = strdup( TkGetDefaultScreenName( NULL, NULL ) );
00395 }
00396 tkwd->display = pls->plPlotterPtr->display;
00397 #else
00398 tkwd->display = XOpenDisplay( pls->FileName );
00399 #endif
00400 if ( tkwd->display == NULL )
00401 {
00402 plexit( "Can't open display" );
00403 }
00404 tkwd->displayName = pls->FileName;
00405 tkwd->screen = DefaultScreen( tkwd->display );
00406 if ( synchronize )
00407 {
00408 XSynchronize( tkwd->display, 1 );
00409 }
00410
00411
00412 tkwd->map = Tk_Colormap( pls->plPlotterPtr->tkwin );
00413 GetVisual( pls );
00414
00415
00416
00417
00418
00419
00420
00421 if ( pls->colorset )
00422 tkwd->color = pls->color;
00423 else
00424 {
00425 pls->color = 1;
00426 tkwd->color = !pltk_AreWeGrayscale( pls->plPlotterPtr );
00427 }
00428
00429
00430
00431 AllocBGFG( pls );
00432 pltkwin_setBGFG( pls );
00433 }
00434
00435
00436
00437 else
00438 {
00439 tkwd = (TkwDisplay *) dev->tkwd;
00440 tkwd->nstreams++;
00441 }
00442 tkwd->ixwd = i;
00443 }
00444
00445
00446
00447
00448
00449
00450
00451 void
00452 plD_line_tkwin( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
00453 {
00454 TkwDev *dev = (TkwDev *) pls->dev;
00455 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00456
00457 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
00458
00459 if ( dev->flags & 1 )
00460 return;
00461
00462 y1 = dev->ylen - y1;
00463 y2 = dev->ylen - y2;
00464
00465 x1 = (int) ( x1 * dev->xscale );
00466 x2 = (int) ( x2 * dev->xscale );
00467 y1 = (int) ( y1 * dev->yscale );
00468 y2 = (int) ( y2 * dev->yscale );
00469
00470 if ( dev->write_to_window )
00471 XDrawLine( tkwd->display, dev->window, dev->gc, x1, y1, x2, y2 );
00472
00473 if ( dev->write_to_pixmap )
00474 XDrawLine( tkwd->display, dev->pixmap, dev->gc, x1, y1, x2, y2 );
00475 }
00476
00477
00478
00479
00480
00481
00482
00483 void
00484 plD_polyline_tkwin( PLStream *pls, short *xa, short *ya, PLINT npts )
00485 {
00486 TkwDev *dev = (TkwDev *) pls->dev;
00487 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00488
00489 PLINT i;
00490 XPoint _pts[PL_MAXPOLY];
00491 XPoint *pts;
00492
00493 if ( dev->flags & 1 )
00494 return;
00495
00496 if ( npts > PL_MAXPOLY )
00497 {
00498 pts = (XPoint *) malloc( sizeof ( XPoint ) * npts );
00499 }
00500 else
00501 {
00502 pts = _pts;
00503 }
00504
00505 for ( i = 0; i < npts; i++ )
00506 {
00507 pts[i].x = (short) ( dev->xscale * xa[i] );
00508 pts[i].y = (short) ( dev->yscale * ( dev->ylen - ya[i] ) );
00509 }
00510
00511 if ( dev->write_to_window )
00512 XDrawLines( tkwd->display, dev->window, dev->gc, pts, npts,
00513 CoordModeOrigin );
00514
00515 if ( dev->write_to_pixmap )
00516 XDrawLines( tkwd->display, dev->pixmap, dev->gc, pts, npts,
00517 CoordModeOrigin );
00518
00519 if ( npts > PL_MAXPOLY )
00520 {
00521 free( pts );
00522 }
00523 }
00524
00525
00526
00527
00528
00529
00530
00531 void
00532 plD_eop_tkwin( PLStream *pls )
00533 {
00534 TkwDev *dev = (TkwDev *) pls->dev;
00535 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00536
00537 dbug_enter( "plD_eop_tkw" );
00538 if ( dev->flags & 1 )
00539 return;
00540
00541 XFlush( tkwd->display );
00542 if ( pls->db )
00543 ExposeCmd( pls, NULL );
00544
00545 if ( !pls->nopause )
00546 WaitForPage( pls );
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556 static void
00557 WaitForPage( PLStream *pls )
00558 {
00559 PlPlotter *plf = pls->plPlotterPtr;
00560 TkwDev *dev = (TkwDev *) pls->dev;
00561
00562 dbug_enter( "WaitForPage" );
00563
00564 dev->flags &= 1;
00565 if ( plf == NULL )
00566 {
00567 plwarn( "WaitForPage: Illegal call --- driver can't find enclosing PlPlotter" );
00568 return;
00569 }
00570 PlplotterAtEop( plf->interp, plf );
00571
00572 while ( !( dev->flags ) && !Tcl_InterpDeleted( plf->interp ) && ( Tk_GetNumMainWindows() > 0 ) )
00573 {
00574 Tcl_DoOneEvent( 0 );
00575 }
00576
00577 if ( Tcl_InterpDeleted( plf->interp ) || ( Tk_GetNumMainWindows() <= 0 ) )
00578 {
00579 dev->flags |= 1;
00580 }
00581
00582 dev->flags &= 1;
00583 }
00584
00585
00586
00587
00588
00589
00590
00591 void
00592 plD_bop_tkwin( PLStream *pls )
00593 {
00594 PlPlotter *plf = pls->plPlotterPtr;
00595 TkwDev *dev = (TkwDev *) pls->dev;
00596 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00597
00598 XRectangle xrect;
00599 xrect.x = 0; xrect.y = 0;
00600 xrect.width = dev->width; xrect.height = dev->height;
00601
00602 dbug_enter( "plD_bop_tkw" );
00603 if ( dev->flags & 1 )
00604 return;
00605
00606 if ( dev->write_to_window )
00607 {
00608 #ifdef MAC_TCL
00609
00610 XSetForeground( tkwd->display, dev->gc, tkwd->cmap0[0].pixel );
00611 XFillRectangles( tkwd->display, dev->window, dev->gc, &xrect, 1 );
00612 XSetForeground( tkwd->display, dev->gc, dev->curcolor.pixel );
00613 #else
00614 XClearWindow( tkwd->display, dev->window );
00615 #endif
00616 }
00617 if ( dev->write_to_pixmap )
00618 {
00619 XSetForeground( tkwd->display, dev->gc, tkwd->cmap0[0].pixel );
00620 XFillRectangles( tkwd->display, dev->pixmap, dev->gc, &xrect, 1 );
00621 XSetForeground( tkwd->display, dev->gc, dev->curcolor.pixel );
00622 }
00623 XSync( tkwd->display, 0 );
00624 pls->page++;
00625 PlplotterAtBop( plf->interp, plf );
00626 }
00627
00628
00629
00630
00631
00632
00633
00634 void
00635 plD_tidy_tkwin( PLStream *pls )
00636 {
00637 TkwDev *dev = (TkwDev *) pls->dev;
00638 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00639
00640 dbug_enter( "plD_tidy_tkw" );
00641
00642 tkwd->nstreams--;
00643 if ( tkwd->nstreams == 0 )
00644 {
00645 int ixwd = tkwd->ixwd;
00646 XFreeGC( tkwd->display, dev->gc );
00647 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
00648 XCloseDisplay( tkwd->display );
00649 #endif
00650 free_mem( tkwDisplay[ixwd] );
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 }
00662
00663
00664
00665
00666
00667
00668
00669 void
00670 plD_state_tkwin( PLStream *pls, PLINT op )
00671 {
00672 TkwDev *dev = (TkwDev *) pls->dev;
00673 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00674 dbug_enter( "plD_state_tkw" );
00675 if ( dev->flags & 1 )
00676 return;
00677
00678 switch ( op )
00679 {
00680 case PLSTATE_WIDTH:
00681 break;
00682
00683 case PLSTATE_COLOR0: {
00684 int icol0 = pls->icol0;
00685 if ( tkwd->color )
00686 {
00687 if ( icol0 == PL_RGB_COLOR )
00688 {
00689 PLColor_to_TkColor( &pls->curcolor, &dev->curcolor );
00690 Tkw_StoreColor( pls, tkwd, &dev->curcolor );
00691 }
00692 else
00693 {
00694 dev->curcolor = tkwd->cmap0[icol0];
00695 }
00696 XSetForeground( tkwd->display, dev->gc, dev->curcolor.pixel );
00697 }
00698 else
00699 {
00700 dev->curcolor = tkwd->fgcolor;
00701 XSetForeground( tkwd->display, dev->gc, dev->curcolor.pixel );
00702 }
00703 break;
00704 }
00705
00706 case PLSTATE_COLOR1: {
00707 int icol1;
00708
00709 if ( tkwd->ncol1 == 0 )
00710 AllocCmap1( pls );
00711
00712 if ( tkwd->ncol1 < 2 )
00713 break;
00714
00715 icol1 = ( pls->icol1 * ( tkwd->ncol1 - 1 ) ) / ( pls->ncol1 - 1 );
00716 if ( tkwd->color )
00717 dev->curcolor = tkwd->cmap1[icol1];
00718 else
00719 dev->curcolor = tkwd->fgcolor;
00720
00721 XSetForeground( tkwd->display, dev->gc, dev->curcolor.pixel );
00722 break;
00723 }
00724
00725 case PLSTATE_CMAP0:
00726 pltkwin_setBGFG( pls );
00727 StoreCmap0( pls );
00728 break;
00729
00730 case PLSTATE_CMAP1:
00731 StoreCmap1( pls );
00732 break;
00733 }
00734 }
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 void
00753 plD_esc_tkwin( PLStream *pls, PLINT op, void *ptr )
00754 {
00755 TkwDev *dev = (TkwDev *) pls->dev;
00756 #ifndef USE_TK
00757 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00758 #endif
00759 dbug_enter( "plD_esc_tkw" );
00760 if ( dev->flags & 1 )
00761 return;
00762
00763 switch ( op )
00764 {
00765 case PLESC_EH:
00766 #ifndef USE_TK
00767 HandleEvents( pls );
00768 #endif
00769 break;
00770
00771 case PLESC_EXPOSE:
00772 ExposeCmd( pls, (PLDisplay *) ptr );
00773 break;
00774
00775 case PLESC_FILL:
00776 FillPolygonCmd( pls );
00777 break;
00778
00779 case PLESC_FLUSH:
00780 #ifndef USE_TK
00781 HandleEvents( pls );
00782 XFlush( tkwd->display );
00783 #endif
00784 break;
00785
00786 case PLESC_GETC:
00787 #ifndef USE_TK
00788 GetCursorCmd( pls, (PLGraphicsIn *) ptr );
00789 #endif
00790 break;
00791
00792 case PLESC_REDRAW:
00793 RedrawCmd( pls );
00794 break;
00795
00796 case PLESC_RESIZE:
00797 ResizeCmd( pls, (PLDisplay *) ptr );
00798 break;
00799
00800
00801 #ifdef USING_PLESC_COPY
00802 case PLESC_COPY:
00803 CopyCommand( pls );
00804 break;
00805 #endif
00806 }
00807 }
00808
00809 #ifdef USING_PLESC_COPY
00810
00811
00812
00813
00814
00815
00816
00817 static void
00818 CopyCommand( PLStream *pls )
00819 {
00820 int x0, w, x1, y0, h, y1;
00821 TkwDev *dev = (TkwDev *) pls->dev;
00822 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00823
00824 x0 = (int) ( dev->xscale * pls->dev_x[0] );
00825 x1 = (int) ( dev->xscale * pls->dev_x[2] );
00826 y0 = (int) ( dev->yscale * ( dev->ylen - pls->dev_y[0] ) );
00827 y1 = (int) ( dev->yscale * ( dev->ylen - pls->dev_y[2] ) );
00828 w = (int) ( dev->xscale * ( pls->dev_x[1] - pls->dev_x[0] ) );
00829 h = (int) ( -dev->yscale * ( pls->dev_y[1] - pls->dev_y[0] ) );
00830
00831 if ( dev->write_to_window )
00832 XCopyArea( tkwd->display, dev->window, dev->window, dev->gc,
00833 x0, y0, w, h, x1, y1 );
00834
00835 if ( dev->write_to_pixmap )
00836 XCopyArea( tkwd->display, dev->pixmap, dev->pixmap, dev->gc,
00837 x0, y0, w, h, x1, y1 );
00838 }
00839 #endif
00840
00841
00842
00843
00844
00845
00846
00847
00848 static void
00849 FillPolygonCmd( PLStream *pls )
00850 {
00851 TkwDev *dev = (TkwDev *) pls->dev;
00852 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00853 XPoint _pts[PL_MAXPOLY];
00854 XPoint *pts;
00855 int i;
00856
00857 if ( pls->dev_npts > PL_MAXPOLY )
00858 {
00859 pts = (XPoint *) malloc( sizeof ( XPoint ) * pls->dev_npts );
00860 }
00861 else
00862 {
00863 pts = _pts;
00864 }
00865
00866 for ( i = 0; i < pls->dev_npts; i++ )
00867 {
00868 pts[i].x = (short) ( dev->xscale * pls->dev_x[i] );
00869 pts[i].y = (short) ( dev->yscale * ( dev->ylen - pls->dev_y[i] ) );
00870 }
00871
00872
00873
00874 if ( dev->write_to_window )
00875 XFillPolygon( tkwd->display, dev->window, dev->gc,
00876 pts, pls->dev_npts, Nonconvex, CoordModeOrigin );
00877
00878 if ( dev->write_to_pixmap )
00879 XFillPolygon( tkwd->display, dev->pixmap, dev->gc,
00880 pts, pls->dev_npts, Nonconvex, CoordModeOrigin );
00881
00882
00883
00884 #ifdef DEBUG
00885 if ( pls->debug )
00886 {
00887 XSetForeground( tkwd->display, dev->gc, tkwd->fgcolor.pixel );
00888 if ( dev->write_to_window )
00889 XDrawLines( tkwd->display, dev->window, dev->gc, pts, pls->dev_npts,
00890 CoordModeOrigin );
00891
00892 if ( dev->write_to_pixmap )
00893 XDrawLines( tkwd->display, dev->pixmap, dev->gc, pts, pls->dev_npts,
00894 CoordModeOrigin );
00895
00896 XSetForeground( tkwd->display, dev->gc, dev->curcolor.pixel );
00897 }
00898 #endif
00899
00900 if ( pls->dev_npts > PL_MAXPOLY )
00901 {
00902 free( pts );
00903 }
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919 static void
00920 Init( PLStream *pls )
00921 {
00922 PlPlotter *plf;
00923 TkwDev *dev = (TkwDev *) pls->dev;
00924 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
00925
00926 dbug_enter( "Init" );
00927
00928 dev->window = pls->window_id;
00929
00930 plf = pls->plPlotterPtr;
00931 if ( plf == NULL )
00932 {
00933 plwarn( "Init: Illegal call --- driver can't find enclosing PlPlotter" );
00934 return;
00935 }
00936
00937
00938 InitColors( pls );
00939 #ifndef MAC_TCL
00940 XSetWindowColormap( tkwd->display, dev->window, tkwd->map );
00941 #else
00942 #endif
00943
00944
00945 if ( !dev->gc )
00946 dev->gc = XCreateGC( tkwd->display, dev->window, 0, 0 );
00947
00948
00949 if ( !tkwd->gcXor )
00950 {
00951 XGCValues gcValues;
00952 unsigned long mask;
00953
00954 gcValues.background = tkwd->cmap0[0].pixel;
00955 gcValues.foreground = 0xFF;
00956 gcValues.function = GXxor;
00957 mask = GCForeground | GCBackground | GCFunction;
00958
00959 tkwd->gcXor = XCreateGC( tkwd->display, dev->window, mask, &gcValues );
00960 }
00961
00962
00963 dev->width = Tk_Width( plf->tkwin );
00964 dev->height = Tk_Height( plf->tkwin );
00965 dev->border = Tk_InternalBorderWidth( plf->tkwin );
00966 tkwd->depth = Tk_Depth( plf->tkwin );
00967
00968 dev->init_width = dev->width;
00969 dev->init_height = dev->height;
00970
00971
00972
00973
00974 if ( pls->nopixmap )
00975 {
00976 dev->write_to_pixmap = 0;
00977 pls->db = 0;
00978 }
00979 else
00980 {
00981 dev->write_to_pixmap = 1;
00982 }
00983 dev->write_to_window = !pls->db;
00984
00985
00986
00987 if ( dev->write_to_pixmap )
00988 CreatePixmap( pls );
00989
00990
00991
00992 plD_state_tkwin( pls, PLSTATE_COLOR0 );
00993
00994 XSetWindowBackground( tkwd->display, dev->window, tkwd->cmap0[0].pixel );
00995 XSetBackground( tkwd->display, dev->gc, tkwd->cmap0[0].pixel );
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005 static void
01006 ExposeCmd( PLStream *pls, PLDisplay *pldis )
01007 {
01008 TkwDev *dev = (TkwDev *) pls->dev;
01009 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01010 int x, y, width, height;
01011
01012 dbug_enter( "ExposeCmd" );
01013
01014
01015
01016 if ( dev == NULL )
01017 {
01018 plwarn( "ExposeCmd: Illegal call -- driver uninitialized" );
01019 return;
01020 }
01021
01022
01023
01024 if ( pldis == NULL )
01025 {
01026 x = 0;
01027 y = 0;
01028 width = dev->width;
01029 height = dev->height;
01030 }
01031 else
01032 {
01033 x = pldis->x;
01034 y = pldis->y;
01035 width = pldis->width;
01036 height = pldis->height;
01037 }
01038
01039
01040
01041
01042 XSync( tkwd->display, 0 );
01043 if ( dev->write_to_pixmap )
01044 {
01045 XCopyArea( tkwd->display, dev->pixmap, dev->window, dev->gc,
01046 x, y, width, height, x, y );
01047 XSync( tkwd->display, 0 );
01048 #ifdef DEBUG
01049 if ( pls->debug )
01050 {
01051 XPoint pts[5];
01052 int x0 = x, x1 = x + width, y0 = y, y1 = y + height;
01053 pts[0].x = x0; pts[0].y = y0;
01054 pts[1].x = x1; pts[1].y = y0;
01055 pts[2].x = x1; pts[2].y = y1;
01056 pts[3].x = x0; pts[3].y = y1;
01057 pts[4].x = x0; pts[4].y = y0;
01058
01059 XDrawLines( tkwd->display, dev->window, dev->gc, pts, 5,
01060 CoordModeOrigin );
01061 }
01062 #endif
01063 }
01064 else
01065 {
01066 plRemakePlot( pls );
01067 XFlush( tkwd->display );
01068 }
01069 }
01070
01071
01072
01073
01074
01075
01076
01077 static void
01078 ResizeCmd( PLStream *pls, PLDisplay *pldis )
01079 {
01080 TkwDev *dev = (TkwDev *) pls->dev;
01081 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01082 int write_to_window = dev->write_to_window;
01083
01084 dbug_enter( "ResizeCmd" );
01085
01086
01087
01088 if ( dev == NULL )
01089 {
01090 plwarn( "ResizeCmd: Illegal call -- driver uninitialized" );
01091 return;
01092 }
01093
01094
01095
01096 if ( pldis == NULL )
01097 {
01098 plwarn( "ResizeCmd: Illegal call -- window pointer uninitialized" );
01099 return;
01100 }
01101
01102
01103
01104 dev->width = pldis->width;
01105 dev->height = pldis->height;
01106
01107 dev->xscale = dev->width / (double) dev->init_width;
01108 dev->yscale = dev->height / (double) dev->init_height;
01109
01110 dev->xscale = dev->xscale * dev->xscale_init;
01111 dev->yscale = dev->yscale * dev->yscale_init;
01112
01113 #if PHYSICAL
01114 {
01115 float pxlx = (double) PIXELS_X / dev->width * DPMM;
01116 float pxly = (double) PIXELS_Y / dev->height * DPMM;
01117 plP_setpxl( pxlx, pxly );
01118 }
01119 #endif
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129 if ( dev->write_to_pixmap )
01130 {
01131 dev->write_to_window = 0;
01132 #if defined ( __WIN32__ ) || defined ( MAC_TCL )
01133 Tk_FreePixmap( tkwd->display, dev->pixmap );
01134 #else
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152 XFreePixmap( tkwd->display, dev->pixmap );
01153 #endif
01154 CreatePixmap( pls );
01155 }
01156
01157
01158
01159 plD_bop_tkwin( pls );
01160 plRemakePlot( pls );
01161 XSync( tkwd->display, 0 );
01162
01163
01164
01165 if ( dev->write_to_pixmap )
01166 {
01167 dev->write_to_window = write_to_window;
01168 XCopyArea( tkwd->display, dev->pixmap, dev->window, dev->gc, 0, 0,
01169 dev->width, dev->height, 0, 0 );
01170 XSync( tkwd->display, 0 );
01171 }
01172 }
01173
01174
01175
01176
01177
01178
01179
01180
01181 static void
01182 RedrawCmd( PLStream *pls )
01183 {
01184 TkwDev *dev = (TkwDev *) pls->dev;
01185 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01186 int write_to_window = dev->write_to_window;
01187
01188 dbug_enter( "RedrawCmd" );
01189
01190
01191
01192 if ( dev == NULL )
01193 {
01194 plwarn( "RedrawCmd: Illegal call -- driver uninitialized" );
01195 return;
01196 }
01197
01198
01199
01200 if ( dev->write_to_pixmap )
01201 dev->write_to_window = 0;
01202
01203 plD_bop_tkwin( pls );
01204 plRemakePlot( pls );
01205 XSync( tkwd->display, 0 );
01206
01207 dev->write_to_window = write_to_window;
01208
01209
01210
01211 if ( dev->write_to_pixmap )
01212 {
01213 XCopyArea( tkwd->display, dev->pixmap, dev->window, dev->gc, 0, 0,
01214 dev->width, dev->height, 0, 0 );
01215 XSync( tkwd->display, 0 );
01216 }
01217 }
01218
01219
01220
01221
01222
01223
01224
01225
01226 static void
01227 CreatePixmap( PLStream *pls )
01228 {
01229 TkwDev *dev = (TkwDev *) pls->dev;
01230 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01231 Tk_Window tkwin = pls->plPlotterPtr->tkwin;
01232
01233 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
01234 int ( *oldErrorHandler )();
01235 oldErrorHandler = XSetErrorHandler( CreatePixmapErrorHandler );
01236 CreatePixmapStatus = Success;
01237 #endif
01238
01239 #ifdef MAC_TCL
01240
01241 if ( dev->width == 0 )
01242 {
01243 dev->width = 10;
01244 }
01245 if ( dev->height == 0 )
01246 {
01247 dev->height = 10;
01248 }
01249 #endif
01250 pldebug( "CreatePixmap",
01251 "creating pixmap: width = %d, height = %d, depth = %d\n",
01252 dev->width, dev->height, tkwd->depth );
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268 dev->pixmap = Tk_GetPixmap( tkwd->display, Tk_WindowId( tkwin ),
01269 Tk_Width( tkwin ), Tk_Height( tkwin ),
01270 DefaultDepthOfScreen( Tk_Screen( tkwin ) ) );
01271 XSync( tkwd->display, 0 );
01272 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
01273 if ( CreatePixmapStatus != Success )
01274 {
01275 dev->write_to_pixmap = 0;
01276 dev->write_to_window = 1;
01277 pls->db = 0;
01278 fprintf( stderr, "\n\
01279 Warning: pixmap could not be allocated (insufficient memory on server).\n\
01280 Driver will redraw the entire plot to handle expose events.\n" );
01281 }
01282
01283 XSetErrorHandler( oldErrorHandler );
01284 #endif
01285 }
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298 static void
01299 GetVisual( PLStream *pls )
01300 {
01301 int depth;
01302 TkwDev *dev = (TkwDev *) pls->dev;
01303 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01304
01305 dbug_enter( "GetVisual" );
01306
01307 tkwd->visual = Tk_GetVisual( pls->plPlotterPtr->interp,
01308 pls->plPlotterPtr->tkwin,
01309 "best",
01310 &depth, NULL );
01311 tkwd->depth = depth;
01312 }
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 static void
01323 AllocBGFG( PLStream *pls )
01324 {
01325 TkwDev *dev = (TkwDev *) pls->dev;
01326 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01327
01328 #ifndef USE_TK
01329 int i, j, npixels;
01330 unsigned long plane_masks[1], pixels[MAX_COLORS];
01331 #endif
01332
01333 dbug_enter( "AllocBGFG" );
01334
01335
01336
01337 if ( !tkwd->color )
01338 return;
01339 #ifndef USE_TK
01340
01341
01342 if ( XAllocColorCells( tkwd->display, tkwd->map, False,
01343 plane_masks, 0, pixels, 1 ) )
01344 {
01345 tkwd->cmap0[0].pixel = pixels[0];
01346 }
01347 else
01348 {
01349 plexit( "couldn't allocate background color cell" );
01350 }
01351
01352
01353
01354 npixels = MAX_COLORS;
01355 for (;; )
01356 {
01357 if ( XAllocColorCells( tkwd->display, tkwd->map, False,
01358 plane_masks, 0, pixels, npixels ) )
01359 break;
01360 npixels--;
01361 if ( npixels == 0 )
01362 break;
01363 }
01364
01365
01366
01367
01368 for ( i = 0; i < npixels - 1; i++ )
01369 {
01370 if ( pixels[i] == ( ~tkwd->cmap0[0].pixel & 0xFF ) )
01371 break;
01372 }
01373
01374
01375
01376 tkwd->fgcolor.pixel = pixels[i];
01377 for ( j = 0; j < npixels; j++ )
01378 {
01379 if ( j != i )
01380 XFreeColors( tkwd->display, tkwd->map, &pixels[j], 1, 0 );
01381 }
01382 #endif
01383 }
01384
01385
01386
01387
01388
01389
01390
01391
01392 void
01393 pltkwin_setBGFG( PLStream *pls )
01394 {
01395 TkwDev *dev = (TkwDev *) pls->dev;
01396 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01397 PLColor fgcolor;
01398 int gslevbg, gslevfg;
01399
01400 dbug_enter( "pltkwin_setBGFG" );
01401
01402
01403
01404
01405
01406
01407
01408
01409 if ( !tkwd->color )
01410 {
01411 pls->cmap0[0].r = pls->cmap0[0].g = pls->cmap0[0].b = 0xFF;
01412 }
01413 gslevbg = ( (long) pls->cmap0[0].r +
01414 (long) pls->cmap0[0].g +
01415 (long) pls->cmap0[0].b ) / 3;
01416
01417 PLColor_to_TkColor( &pls->cmap0[0], &tkwd->cmap0[0] );
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 if ( gslevbg > 0x7F )
01430 gslevfg = 0;
01431 else
01432 gslevfg = 0xFF;
01433
01434 fgcolor.r = fgcolor.g = fgcolor.b = gslevfg;
01435
01436 PLColor_to_TkColor( &fgcolor, &tkwd->fgcolor );
01437
01438
01439 #ifndef USE_TK
01440 if ( tkwd->color )
01441 {
01442 XStoreColor( tkwd->display, tkwd->map, &tkwd->fgcolor );
01443 XStoreColor( tkwd->display, tkwd->map, &tkwd->cmap0[0] );
01444 }
01445 else
01446 {
01447 XAllocColor( tkwd->display, tkwd->map, &tkwd->cmap0[0] );
01448 XAllocColor( tkwd->display, tkwd->map, &tkwd->fgcolor );
01449 }
01450 #else
01451 Tkw_StoreColor( pls, tkwd, &tkwd->cmap0[0] );
01452 Tkw_StoreColor( pls, tkwd, &tkwd->fgcolor );
01453 #endif
01454 }
01455
01456
01457
01458
01459
01460
01461
01462 static void
01463 InitColors( PLStream *pls )
01464 {
01465 TkwDev *dev = (TkwDev *) pls->dev;
01466 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01467
01468 dbug_enter( "InitColors" );
01469
01470
01471
01472
01473 if ( tkwd->color )
01474 {
01475 if ( plplot_tkwin_ccmap )
01476 {
01477 AllocCustomMap( pls );
01478 }
01479 else
01480 {
01481 AllocCmap0( pls );
01482 }
01483 }
01484 }
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512 static void
01513 AllocCustomMap( PLStream *pls )
01514 {
01515 TkwDev *dev = (TkwDev *) pls->dev;
01516 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01517
01518 XColor xwm_colors[MAX_COLORS];
01519 int i;
01520 #ifndef USE_TK
01521 int npixels;
01522 unsigned long plane_masks[1], pixels[MAX_COLORS];
01523 #endif
01524
01525 dbug_enter( "AllocCustomMap" );
01526
01527
01528
01529 for ( i = 0; i < MAX_COLORS; i++ )
01530 {
01531 xwm_colors[i].pixel = i;
01532 }
01533 #ifndef MAC_TCL
01534 XQueryColors( tkwd->display, tkwd->map, xwm_colors, MAX_COLORS );
01535 #endif
01536
01537
01538
01539
01540
01541
01542 AllocCmap0( pls );
01543 XAllocColor( tkwd->display, tkwd->map, &tkwd->fgcolor );
01544
01545
01546
01547 tkwd->map = XCreateColormap( tkwd->display, DefaultRootWindow( tkwd->display ),
01548 tkwd->visual, AllocNone );
01549
01550
01551
01552 #ifndef USE_TK
01553 npixels = MAX_COLORS;
01554 for (;; )
01555 {
01556 if ( XAllocColorCells( tkwd->display, tkwd->map, False,
01557 plane_masks, 0, pixels, npixels ) )
01558 break;
01559 npixels--;
01560 if ( npixels == 0 )
01561 plexit( "couldn't allocate any colors" );
01562 }
01563
01564
01565
01566 for ( i = 0; i < XWM_COLORS; i++ )
01567 {
01568 XStoreColor( tkwd->display, tkwd->map, &xwm_colors[i] );
01569 pixels[xwm_colors[i].pixel] = 0;
01570 }
01571
01572
01573
01574 for ( i = 0; i < tkwd->ncol0; i++ )
01575 {
01576 XStoreColor( tkwd->display, tkwd->map, &tkwd->cmap0[i] );
01577 pixels[tkwd->cmap0[i].pixel] = 0;
01578 }
01579
01580
01581
01582
01583
01584
01585
01586 if ( sxwm_colors_set )
01587 {
01588 for ( i = 0; i < MAX_COLORS; i++ )
01589 {
01590 if ( ( xwm_colors[i].red != sxwm_colors[i].red ) ||
01591 ( xwm_colors[i].green != sxwm_colors[i].green ) ||
01592 ( xwm_colors[i].blue != sxwm_colors[i].blue ) )
01593 {
01594 if ( pixels[i] != 0 )
01595 {
01596 XStoreColor( tkwd->display, tkwd->map, &xwm_colors[i] );
01597 pixels[i] = 0;
01598 }
01599 }
01600 }
01601 }
01602
01603
01604
01605 for ( i = 0; i < npixels; i++ )
01606 {
01607 if ( pixels[i] != 0 )
01608 XFreeColors( tkwd->display, tkwd->map, &pixels[i], 1, 0 );
01609 }
01610 #endif
01611
01612
01613 AllocCmap1( pls );
01614 }
01615
01616
01617
01618
01619
01620
01621
01622 static void
01623 AllocCmap0( PLStream *pls )
01624 {
01625 TkwDev *dev = (TkwDev *) pls->dev;
01626 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01627
01628 #ifndef USE_TK
01629 int npixels;
01630 int i;
01631 unsigned long plane_masks[1], pixels[MAX_COLORS];
01632 #endif
01633
01634 dbug_enter( "AllocCmap0" );
01635
01636
01637
01638 #ifndef USE_TK
01639 npixels = pls->ncol0 - 1;
01640 for (;; )
01641 {
01642 if ( XAllocColorCells( tkwd->display, tkwd->map, False,
01643 plane_masks, 0, &pixels[1], npixels ) )
01644 break;
01645 npixels--;
01646 if ( npixels == 0 )
01647 plexit( "couldn't allocate any colors" );
01648 }
01649
01650 tkwd->ncol0 = npixels + 1;
01651 for ( i = 1; i < tkwd->ncol0; i++ )
01652 {
01653 tkwd->cmap0[i].pixel = pixels[i];
01654 }
01655 #else
01656
01657 tkwd->ncol0 = pls->ncol0;
01658 #endif
01659 StoreCmap0( pls );
01660 }
01661
01662
01663
01664
01665
01666
01667
01668
01669 static void
01670 AllocCmap1( PLStream *pls )
01671 {
01672 TkwDev *dev = (TkwDev *) pls->dev;
01673 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01674
01675 int npixels;
01676 #ifndef USE_TK
01677 int i, j;
01678 unsigned long plane_masks[1], pixels[MAX_COLORS];
01679 #endif
01680
01681 dbug_enter( "AllocCmap1" );
01682
01683
01684
01685 npixels = MAX( 2, MIN( CMAP1_COLORS, pls->ncol1 ) );
01686 #ifndef USE_TK
01687 for (;; )
01688 {
01689 if ( XAllocColorCells( tkwd->display, tkwd->map, False,
01690 plane_masks, 0, pixels, npixels ) )
01691 break;
01692 npixels--;
01693 if ( npixels == 0 )
01694 break;
01695 }
01696
01697 if ( npixels < 2 )
01698 {
01699 tkwd->ncol1 = -1;
01700 fprintf( stderr,
01701 "Warning: unable to allocate sufficient colors in cmap1\n" );
01702 return;
01703 }
01704 else
01705 {
01706 tkwd->ncol1 = npixels;
01707 if ( pls->verbose )
01708 fprintf( stderr, "AllocCmap1 (xwin.c): Allocated %d colors in cmap1\n", npixels );
01709 }
01710
01711
01712
01713
01714 for ( j = i = 0; i < tkwd->ncol1; i++ )
01715 {
01716 while ( pixels[j] == 0 )
01717 j++;
01718
01719 tkwd->cmap1[i].pixel = pixels[j];
01720 pixels[j] = 0;
01721
01722 j += 2;
01723 if ( j >= tkwd->ncol1 )
01724 j = 0;
01725 }
01726 #else
01727 tkwd->ncol1 = npixels;
01728 #endif
01729 StoreCmap1( pls );
01730 }
01731
01732
01733
01734
01735
01736
01737
01738 static void
01739 StoreCmap0( PLStream *pls )
01740 {
01741 TkwDev *dev = (TkwDev *) pls->dev;
01742 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01743 int i;
01744
01745 if ( !tkwd->color )
01746 return;
01747
01748 for ( i = 1; i < tkwd->ncol0; i++ )
01749 {
01750 PLColor_to_TkColor( &pls->cmap0[i], &tkwd->cmap0[i] );
01751 #ifndef USE_TK
01752 XStoreColor( tkwd->display, tkwd->map, &tkwd->cmap0[i] );
01753 #else
01754 Tkw_StoreColor( pls, tkwd, &tkwd->cmap0[i] );
01755 #endif
01756 }
01757 }
01758
01759 void CopyColour( XColor* from, XColor* to )
01760 {
01761 to->pixel = from->pixel;
01762 to->red = from->red;
01763 to->blue = from->blue;
01764 to->green = from->green;
01765 to->flags = from->flags;
01766 }
01767
01768
01769
01770
01771
01772
01773
01774 static void
01775 StoreCmap1( PLStream *pls )
01776 {
01777 TkwDev *dev = (TkwDev *) pls->dev;
01778 TkwDisplay *tkwd = (TkwDisplay *) dev->tkwd;
01779
01780 PLColor cmap1color;
01781 int i;
01782
01783 if ( !tkwd->color )
01784 return;
01785
01786 for ( i = 0; i < tkwd->ncol1; i++ )
01787 {
01788 plcol_interp( pls, &cmap1color, i, tkwd->ncol1 );
01789 PLColor_to_TkColor( &cmap1color, &tkwd->cmap1[i] );
01790 #ifndef USE_TK
01791 XStoreColor( tkwd->display, tkwd->map, &tkwd->cmap1[i] );
01792 #else
01793 Tkw_StoreColor( pls, tkwd, &tkwd->cmap1[i] );
01794 #endif
01795 }
01796 }
01797
01798 void Tkw_StoreColor( PLStream* pls, TkwDisplay* tkwd, XColor* col )
01799 {
01800 XColor *xc;
01801 #ifndef USE_TK
01802 XStoreColor( tkwd->display, tkwd->map, col );
01803 #else
01804
01805 xc = Tk_GetColorByValue( pls->plPlotterPtr->tkwin, col );
01806 CopyColour( xc, col );
01807 #endif
01808 }
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818 #define ToXColor( a ) ( ( ( 0xFF & ( a ) ) << 8 ) | ( a ) )
01819 #define ToPLColor( a ) ( ( (U_LONG) a ) >> 8 )
01820
01821 void
01822 PLColor_to_TkColor( PLColor *plcolor, XColor *xcolor )
01823 {
01824 xcolor->red = ToXColor( plcolor->r );
01825 xcolor->green = ToXColor( plcolor->g );
01826 xcolor->blue = ToXColor( plcolor->b );
01827 xcolor->flags = DoRed | DoGreen | DoBlue;
01828 }
01829
01830
01831
01832
01833
01834
01835
01836
01837 void
01838 PLColor_from_TkColor( PLColor *plcolor, XColor *xcolor )
01839 {
01840 plcolor->r = (unsigned char) ToPLColor( xcolor->red );
01841 plcolor->g = (unsigned char) ToPLColor( xcolor->green );
01842 plcolor->b = (unsigned char) ToPLColor( xcolor->blue );
01843 }
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854 int
01855 PLColor_from_TkColor_Changed( PLColor *plcolor, XColor *xcolor )
01856 {
01857 int changed = 0;
01858 int color;
01859 color = ToPLColor( xcolor->red );
01860
01861 if ( plcolor->r != color )
01862 {
01863 changed = 1;
01864 plcolor->r = color;
01865 }
01866 color = ToPLColor( xcolor->green );
01867 if ( plcolor->g != color )
01868 {
01869 changed = 1;
01870 plcolor->g = color;
01871 }
01872 color = ToPLColor( xcolor->blue );
01873 if ( plcolor->b != color )
01874 {
01875 changed = 1;
01876 plcolor->b = color;
01877 }
01878 return changed;
01879 }
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889 static int
01890 pltk_AreWeGrayscale( PlPlotter *plf )
01891 {
01892 #if defined ( __cplusplus ) || defined ( c_plusplus )
01893 #define THING c_class
01894 #else
01895 #define THING class
01896 #endif
01897
01898 Visual* visual;
01899
01900 visual = Tk_Visual( plf->tkwin );
01901 if ( ( visual->THING != GrayScale ) && ( visual->THING != StaticGray ) )
01902 return ( 0 );
01903
01904 return ( 1 );
01905 }
01906
01907 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
01908
01909
01910
01911
01912
01913
01914
01915
01916 static int
01917 CreatePixmapErrorHandler( Display *display, XErrorEvent *error )
01918 {
01919 if ( error->error_code == BadAlloc )
01920 {
01921 CreatePixmapStatus = error->error_code;
01922 }
01923 else
01924 {
01925 char buffer[256];
01926 XGetErrorText( display, error->error_code, buffer, 256 );
01927 fprintf( stderr, "Error in XCreatePixmap: %s.\n", buffer );
01928 }
01929 return 1;
01930 }
01931 #endif
01932
01933 #else
01934 int
01935 pldummy_tkwin()
01936 {
01937 return 0;
01938 }
01939
01940 #endif // PLD_tkwin
01941
01942 void * ckcalloc( size_t nmemb, size_t size )
01943 {
01944 long *ptr;
01945 long *p;
01946 size *= nmemb;
01947 ptr = (long *) malloc( size );
01948 if ( !ptr )
01949 return ( 0 );
01950
01951 #if !__POWERPC__
01952
01953 for ( size = ( size / sizeof ( long ) ) + 1, p = ptr; --size; )
01954 *p++ = 0;
01955
01956 #else
01957
01958 for ( size = ( size / sizeof ( long ) ) + 1, p = ptr - 1; --size; )
01959 *++p = 0;
01960
01961 #endif
01962
01963 return ( ptr );
01964 }