51#if defined ( _WIN32 ) || defined ( MAC_TCL )
56 #define malloc ckalloc
57 #define free( m ) ckfree( (char *) m )
58 #define realloc ckrealloc
59 #define calloc ckcalloc
61#if defined ( _WIN32 ) || defined ( MAC_TCL )
81PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_tkwin =
"tkwin:New tk driver:1:tkwin:45:tkwin\n";
84void *
ckcalloc(
size_t nmemb,
size_t size );
95#define XSynchronize( display, bool ) { display->request++; }
96#define XSync( display, bool ) { display->request++; }
97#define XFlush( display )
118void CopyColour( XColor* from, XColor* to );
120static int pltk_AreWeGrayscale(
PlPlotter *plf );
152#define CMAP0_COLORS 16
153#define CMAP1_COLORS 50
154#define MAX_COLORS 256
160static int sxwm_colors_set;
161static XColor sxwm_colors[MAX_COLORS];
168#if !defined ( MAC_TCL ) && !defined ( _WIN32 )
169static unsigned char CreatePixmapStatus;
170static int CreatePixmapErrorHandler( Display *
display, XErrorEvent *
error );
194#ifdef USING_PLESC_COPY
207void plD_line_tkwin(
PLStream *,
short,
short,
short,
short );
208void plD_polyline_tkwin(
PLStream *,
short *,
short *,
PLINT );
219#ifndef ENABLE_DYNDRIVERS
258 pls->plbuf_write = 1;
262 if (
pls->dev == NULL )
271 dev->
xlen = (short) ( xmax - xmin );
272 dev->
ylen = (short) ( ymax - ymin );
312 if (
pls->dev != NULL )
313 plwarn(
"plD_open_tkw: device pointer is already set" );
316 if (
pls->dev == NULL )
317 plexit(
"plD_init_tkw: Out of memory." );
331 if ( tkwDisplay[i] == NULL )
335 else if (
pls->FileName == NULL && tkwDisplay[i]->displayName == NULL )
337 dev->
tkwd = tkwDisplay[i];
340 else if (
pls->FileName == NULL || tkwDisplay[i]->displayName == NULL )
344 else if ( strcmp( tkwDisplay[i]->displayName,
pls->FileName ) == 0 )
346 dev->
tkwd = tkwDisplay[i];
353 if ( dev->
tkwd == NULL )
356 if ( dev->
tkwd == NULL )
357 plexit(
"Init: Out of memory." );
361 if ( tkwDisplay[i] == NULL )
365 plexit(
"Init: Out of tkwDisplay's." );
374 if (
pls->plPlotterPtr == NULL )
376 plexit(
"No tk plframe widget to connect to" );
386#if defined ( MAC_TCL ) || defined ( _WIN32 )
387 if ( !
pls->FileName )
394 pls->FileName =
plstrdup( TkGetDefaultScreenName( NULL, NULL ) );
398 tkwd->
display = XOpenDisplay(
pls->FileName );
402 plexit(
"Can't open display" );
408 XSynchronize( tkwd->
display, 1 );
412 tkwd->
map = Tk_Colormap(
pls->plPlotterPtr->tkwin );
426 tkwd->
color = !pltk_AreWeGrayscale(
pls->plPlotterPtr );
452plD_line_tkwin(
PLStream *
pls,
short x1a,
short y1a,
short x2a,
short y2a )
457 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
459 if ( dev->
flags & 1 )
465 x1 = (int) ( x1 * dev->
xscale );
466 x2 = (int) ( x2 * dev->
xscale );
467 y1 = (int) ( y1 * dev->
yscale );
468 y2 = (int) ( y2 * dev->
yscale );
493 if ( dev->
flags & 1 )
498 pts = (XPoint *) malloc(
sizeof ( XPoint ) * (
size_t) npts );
505 for ( i = 0; i < npts; i++ )
507 pts[i].x = (short) ( dev->
xscale * xa[i] );
508 pts[i].y = (short) ( dev->
yscale * ( dev->
ylen - ya[i] ) );
538 if ( dev->
flags & 1 )
543 ExposeCmd(
pls, NULL );
559 if ( dev->
flags & 1 )
583 plwarn(
"WaitForPage: Illegal call --- driver can't find enclosing PlPlotter" );
588 while ( !( dev->
flags ) && !Tcl_InterpDeleted( plf->interp ) && ( Tk_GetNumMainWindows() > 0 ) )
593 if ( Tcl_InterpDeleted( plf->interp ) || ( Tk_GetNumMainWindows() <= 0 ) )
615 xrect.x = 0; xrect.y = 0;
616 xrect.width = (
short unsigned) dev->
width;
617 xrect.height = (
short unsigned) dev->
height;
620 if ( dev->
flags & 1 )
662 int ixwd = tkwd->
ixwd;
664#if !defined ( MAC_TCL ) && !defined ( _WIN32 )
665 XCloseDisplay( tkwd->
display );
692 if ( dev->
flags & 1 )
701 int icol0 =
pls->icol0;
726 if ( tkwd->
ncol1 == 0 )
729 if ( tkwd->
ncol1 < 2 )
732 icol1 = (
pls->icol1 * ( tkwd->
ncol1 - 1 ) ) / (
pls->ncol1 - 1 );
777 if ( dev->
flags & 1 )
793 FillPolygonCmd(
pls );
818#ifdef USING_PLESC_COPY
826#ifdef USING_PLESC_COPY
837 int x0, w, x1, y0, h, y1;
841 x0 = (int) ( dev->
xscale *
pls->dev_x[0] );
842 x1 = (int) ( dev->
xscale *
pls->dev_x[2] );
845 w = (int) ( dev->
xscale * (
pls->dev_x[1] -
pls->dev_x[0] ) );
846 h = (int) ( -dev->
yscale * (
pls->dev_y[1] -
pls->dev_y[0] ) );
850 x0, y0, w, h, x1, y1 );
854 x0, y0, w, h, x1, y1 );
876 pts = (XPoint *) malloc(
sizeof ( XPoint ) * (
size_t) (
pls->dev_npts ) );
883 for ( i = 0; i <
pls->dev_npts; i++ )
885 pts[i].x = (short) ( dev->
xscale *
pls->dev_x[i] );
886 pts[i].y = (short) ( dev->
yscale * ( dev->
ylen -
pls->dev_y[i] ) );
893 pts,
pls->dev_npts, Nonconvex, CoordModeOrigin );
897 pts,
pls->dev_npts, Nonconvex, CoordModeOrigin );
947 plf =
pls->plPlotterPtr;
950 plwarn(
"Init: Illegal call --- driver can't find enclosing PlPlotter" );
971 gcValues.background = tkwd->
cmap0[0].pixel;
972 gcValues.foreground = 0xFF;
973 gcValues.function = GXxor;
974 mask = GCForeground | GCBackground | GCFunction;
980 dev->
width = (
unsigned int) Tk_Width( plf->tkwin );
981 dev->
height = (
unsigned int) Tk_Height( plf->tkwin );
982#if defined( TK_MAJOR_VERSION ) && TK_MAJOR_VERSION >= 9
983 dev->
border = (
unsigned int) Tk_InternalBorderLeft( plf->tkwin );
985 dev->
border = (
unsigned int) Tk_InternalBorderWidth( plf->tkwin );
987 tkwd->
depth = (
unsigned int) Tk_Depth( plf->tkwin );
1009 CreatePixmap(
pls );
1031 int x, y, width, height;
1039 plwarn(
"ExposeCmd: Illegal call -- driver uninitialized" );
1045 if ( pldis == NULL )
1049 width = (int) dev->
width;
1050 height = (int) dev->
height;
1056 width = (int) pldis->width;
1057 height = (int) pldis->height;
1067 x, y, (
unsigned int) width, (
unsigned int) height, x, y );
1073 int x0 = x, x1 = x + width, y0 = y, y1 = y + height;
1074 pts[0].x = (short) x0; pts[0].y = (short) y0;
1075 pts[1].x = (short) x1; pts[1].y = (short) y0;
1076 pts[2].x = (short) x1; pts[2].y = (short) y1;
1077 pts[3].x = (short) x0; pts[3].y = (short) y1;
1078 pts[4].x = (short) x0; pts[4].y = (short) y0;
1111 plwarn(
"ResizeCmd: Illegal call -- driver uninitialized" );
1117 if ( pldis == NULL )
1119 plwarn(
"ResizeCmd: Illegal call -- window pointer uninitialized" );
1125 dev->
width = pldis->width;
1126 dev->
height = pldis->height;
1153#if defined ( _WIN32 ) || defined ( MAC_TCL )
1175 CreatePixmap(
pls );
1180 plD_bop_tkwin(
pls );
1215 plwarn(
"RedrawCmd: Illegal call -- driver uninitialized" );
1224 plD_bop_tkwin(
pls );
1252 Tk_Window tkwin =
pls->plPlotterPtr->tkwin;
1254#if !defined ( MAC_TCL ) && !defined ( _WIN32 )
1255 int ( *oldErrorHandler )( Display *, XErrorEvent * );
1256 oldErrorHandler = XSetErrorHandler( CreatePixmapErrorHandler );
1257 CreatePixmapStatus = Success;
1262 if ( dev->
width == 0 )
1271 pldebug(
"CreatePixmap",
1272 "creating pixmap: width = %d, height = %d, depth = %d\n",
1289 dev->
pixmap = Tk_GetPixmap( tkwd->
display, Tk_WindowId( tkwin ),
1290 Tk_Width( tkwin ), Tk_Height( tkwin ),
1291 DefaultDepthOfScreen( Tk_Screen( tkwin ) ) );
1293#if !defined ( MAC_TCL ) && !defined ( _WIN32 )
1294 if ( CreatePixmapStatus != Success )
1299 fprintf( stderr,
"\n\
1300 Warning: pixmap could not be allocated (insufficient memory on server).\n\
1301 Driver will redraw the entire plot to handle expose events.\n" );
1304 XSetErrorHandler( oldErrorHandler );
1328 tkwd->
visual = Tk_GetVisual(
pls->plPlotterPtr->interp,
1329 pls->plPlotterPtr->tkwin,
1332 tkwd->
depth = (
unsigned int) depth;
1351 unsigned long plane_masks[1], pixels[MAX_COLORS];
1363 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1364 plane_masks, 0, pixels, 1 ) )
1366 tkwd->
cmap0[0].pixel = pixels[0];
1370 plexit(
"couldn't allocate background color cell" );
1375 npixels = MAX_COLORS;
1378 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1379 plane_masks, 0, pixels, npixels ) )
1389 for ( i = 0; i < npixels - 1; i++ )
1391 if ( pixels[i] == ( ~tkwd->
cmap0[0].pixel & 0xFF ) )
1397 tkwd->
fgcolor.pixel = pixels[i];
1398 for ( j = 0; j < npixels; j++ )
1401 XFreeColors( tkwd->
display, tkwd->
map, &pixels[j], 1, 0 );
1419 int gslevbg, gslevfg;
1432 pls->cmap0[0].r =
pls->cmap0[0].g =
pls->cmap0[0].b = 0xFF;
1434 gslevbg = (int) ( ( (
long)
pls->cmap0[0].r +
1435 (
long)
pls->cmap0[0].g +
1436 (
long)
pls->cmap0[0].b ) / 3 );
1450 if ( gslevbg > 0x7F )
1455 fgcolor.
r = fgcolor.
g = fgcolor.
b = (
unsigned char) gslevfg;
1498 AllocCustomMap(
pls );
1539 XColor xwm_colors[MAX_COLORS];
1543 unsigned long plane_masks[1], pixels[MAX_COLORS];
1550 for ( i = 0; i < MAX_COLORS; i++ )
1552 xwm_colors[i].pixel = (
long unsigned) i;
1555 XQueryColors( tkwd->
display, tkwd->
map, xwm_colors, MAX_COLORS );
1569 tkwd->
visual, AllocNone );
1574 npixels = MAX_COLORS;
1577 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1578 plane_masks, 0, pixels, npixels ) )
1582 plexit(
"couldn't allocate any colors" );
1587 for ( i = 0; i < XWM_COLORS; i++ )
1589 XStoreColor( tkwd->
display, tkwd->
map, &xwm_colors[i] );
1590 pixels[xwm_colors[i].pixel] = 0;
1595 for ( i = 0; i < tkwd->
ncol0; i++ )
1598 pixels[tkwd->
cmap0[i].pixel] = 0;
1607 if ( sxwm_colors_set )
1609 for ( i = 0; i < MAX_COLORS; i++ )
1611 if ( ( xwm_colors[i].red != sxwm_colors[i].red ) ||
1612 ( xwm_colors[i].green != sxwm_colors[i].green ) ||
1613 ( xwm_colors[i].blue != sxwm_colors[i].blue ) )
1615 if ( pixels[i] != 0 )
1617 XStoreColor( tkwd->
display, tkwd->
map, &xwm_colors[i] );
1626 for ( i = 0; i < npixels; i++ )
1628 if ( pixels[i] != 0 )
1629 XFreeColors( tkwd->
display, tkwd->
map, &pixels[i], 1, 0 );
1652 unsigned long plane_masks[1], pixels[MAX_COLORS];
1660 npixels =
pls->ncol0 - 1;
1663 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1664 plane_masks, 0, &pixels[1], npixels ) )
1668 plexit(
"couldn't allocate any colors" );
1671 tkwd->
ncol0 = npixels + 1;
1672 for ( i = 1; i < tkwd->
ncol0; i++ )
1674 tkwd->
cmap0[i].pixel = pixels[i];
1699 unsigned long plane_masks[1], pixels[MAX_COLORS];
1706 npixels =
MAX( 2,
MIN( CMAP1_COLORS,
pls->ncol1 ) );
1710 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1711 plane_masks, 0, pixels, npixels ) )
1722 "Warning: unable to allocate sufficient colors in cmap1\n" );
1727 tkwd->
ncol1 = npixels;
1729 fprintf( stderr,
"AllocCmap1 (xwin.c): Allocated %d colors in cmap1\n", npixels );
1735 for ( j = i = 0; i < tkwd->
ncol1; i++ )
1737 while ( pixels[j] == 0 )
1740 tkwd->
cmap1[i].pixel = pixels[j];
1744 if ( j >= tkwd->
ncol1 )
1748 tkwd->
ncol1 = npixels;
1769 for ( i = 1; i < tkwd->
ncol0; i++ )
1780void CopyColour( XColor* from, XColor* to )
1782 to->pixel = from->pixel;
1783 to->red = from->red;
1784 to->blue = from->blue;
1785 to->green = from->green;
1786 to->flags = from->flags;
1807 for ( i = 0; i < tkwd->
ncol1; i++ )
1823 XStoreColor( tkwd->
display, tkwd->
map, col );
1827 xc = Tk_GetColorByValue(
pls->plPlotterPtr->tkwin, col );
1828 CopyColour( xc, col );
1840#define ToXColor( a ) ( ( ( 0xFF & ( a ) ) << 8 ) | ( a ) )
1841#define ToPLColor( a ) ( ( (U_LONG) a ) >> 8 )
1846 xcolor->red = (
short unsigned) ToXColor( plcolor->
r );
1847 xcolor->green = (
short unsigned) ToXColor( plcolor->
g );
1848 xcolor->blue = (
short unsigned) ToXColor( plcolor->
b );
1849 xcolor->flags = DoRed | DoGreen | DoBlue;
1862 plcolor->
r = (
unsigned char) ToPLColor( xcolor->red );
1863 plcolor->
g = (
unsigned char) ToPLColor( xcolor->green );
1864 plcolor->
b = (
unsigned char) ToPLColor( xcolor->blue );
1881 color = ToPLColor( xcolor->red );
1883 if ( plcolor->
r !=
color )
1886 plcolor->
r = (
unsigned char)
color;
1888 color = ToPLColor( xcolor->green );
1889 if ( plcolor->
g !=
color )
1892 plcolor->
g = (
unsigned char)
color;
1894 color = ToPLColor( xcolor->blue );
1895 if ( plcolor->
b !=
color )
1898 plcolor->
b = (
unsigned char)
color;
1914#if defined ( __cplusplus ) || defined ( c_plusplus )
1915#define THING c_class
1922 visual = Tk_Visual( plf->
tkwin );
1923 if ( ( visual->THING != GrayScale ) && ( visual->THING != StaticGray ) )
1929#if !defined ( MAC_TCL ) && !defined ( _WIN32 )
1939CreatePixmapErrorHandler( Display *
display, XErrorEvent *
error )
1941 if (
error->error_code == BadAlloc )
1943 CreatePixmapStatus =
error->error_code;
1949 fprintf( stderr,
"Error in XCreatePixmap: %s.\n",
buffer );
1969 ptr = (
long *) malloc( size );
1975 for ( size = ( size /
sizeof (
long ) ) + 1, p = ptr; --size; )
1980 for ( size = ( size /
sizeof (
long ) ) + 1, p = ptr - 1; --size; )
void(* plD_line_fp)(struct PLStream_struct *, short, short, short, short)
void(* plD_tidy_fp)(struct PLStream_struct *)
void(* plD_bop_fp)(struct PLStream_struct *)
void(* plD_wait_fp)(struct PLStream_struct *)
void(* plD_state_fp)(struct PLStream_struct *, PLINT)
void(* plD_eop_fp)(struct PLStream_struct *)
void(* plD_init_fp)(struct PLStream_struct *)
void(* plD_esc_fp)(struct PLStream_struct *, PLINT, void *)
void(* plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT)
PLDLLIMPEXP_DRIVER void plD_dispatch_init_tkwin(PLDispatchTable *pdt)
void plRemakePlot(PLStream *pls)
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
void plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
static PLStream * pls[PL_NSTREAMS]
void plwarn(PLCHAR_VECTOR errormsg)
void plcol_interp(PLStream *pls, PLColor *newcolor, int i, int ncol)
void plexit(PLCHAR_VECTOR errormsg)
char PLDLLIMPEXP * plstrdup(PLCHAR_VECTOR src)
#define PLDLLIMPEXP_DRIVER
void PlplotterAtEop(Tcl_Interp *interp, register PlPlotter *plPlotterPtr)
void PlplotterAtBop(Tcl_Interp *interp, register PlPlotter *plPlotterPtr)
void pltkwin_setBGFG(PLStream *pls)
static int plplot_tkwin_ccmap
int PLColor_from_TkColor_Changed(PLColor *plcolor, XColor *xcolor)
void Tkw_StoreColor(PLStream *pls, TkwDisplay *tkwd, XColor *col)
void PLColor_from_TkColor(PLColor *plcolor, XColor *xcolor)
void PLColor_to_TkColor(PLColor *plcolor, XColor *xcolor)
void plD_open_tkwin(PLStream *pls)
plD_polyline_fp pl_polyline
static Tcl_Interp * interp
static const char * display
void * ckcalloc(size_t nmemb, size_t size)