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 )
70 #define ckalloc malloc
81 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_tkwin =
"tkwin:New tk driver:1:tkwin:45:tkwin\n";
84 void *
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 )
118 void CopyColour( XColor* from, XColor* to );
120 static int pltk_AreWeGrayscale(
PlPlotter *plf );
133 #define PHYSICAL 0 // Enables physical scaling..
151 #define XWM_COLORS 70
152 #define CMAP0_COLORS 16
153 #define CMAP1_COLORS 50
154 #define MAX_COLORS 256
160 static int sxwm_colors_set;
161 static XColor sxwm_colors[MAX_COLORS];
168 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
169 static unsigned char CreatePixmapStatus;
170 static int CreatePixmapErrorHandler( Display *
display, XErrorEvent *
error );
177 static void InitColors(
PLStream *pls );
178 static void AllocCustomMap(
PLStream *pls );
179 static void AllocCmap0(
PLStream *pls );
180 static void AllocCmap1(
PLStream *pls );
181 static void CreatePixmap(
PLStream *pls );
182 static void GetVisual(
PLStream *pls );
183 static void AllocBGFG(
PLStream *pls );
188 static void RedrawCmd(
PLStream *pls );
193 static void FillPolygonCmd(
PLStream *pls );
194 #ifdef USING_PLESC_COPY
195 static void CopyCommand(
PLStream *pls );
200 static void StoreCmap0(
PLStream *pls );
201 static void StoreCmap1(
PLStream *pls );
202 static void WaitForPage(
PLStream *pls );
207 void plD_line_tkwin(
PLStream *,
short,
short,
short,
short );
208 void plD_polyline_tkwin(
PLStream *,
short *,
short *,
PLINT );
218 #ifndef ENABLE_DYNDRIVERS
260 if ( pls->
dev == NULL )
269 dev->
xlen = (short) ( xmax - xmin );
270 dev->
ylen = (short) ( ymax - ymin );
310 if ( pls->
dev != NULL )
311 plwarn(
"plD_open_tkw: device pointer is already set" );
314 if ( pls->
dev == NULL )
315 plexit(
"plD_init_tkw: Out of memory." );
329 if ( tkwDisplay[i] == NULL )
335 dev->
tkwd = tkwDisplay[i];
342 else if ( strcmp( tkwDisplay[i]->displayName, pls->
FileName ) == 0 )
344 dev->
tkwd = tkwDisplay[i];
351 if ( dev->
tkwd == NULL )
354 if ( dev->
tkwd == NULL )
355 plexit(
"Init: Out of memory." );
359 if ( tkwDisplay[i] == NULL )
362 if ( i == PLTKDISPLAYS )
363 plexit(
"Init: Out of tkwDisplay's." );
374 plexit(
"No tk plframe widget to connect to" );
384 #if defined ( MAC_TCL ) || defined ( __WIN32__ )
400 plexit(
"Can't open display" );
406 XSynchronize( tkwd->
display, 1 );
450 plD_line_tkwin(
PLStream *pls,
short x1a,
short y1a,
short x2a,
short y2a )
455 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
457 if ( dev->
flags & 1 )
463 x1 = (int) ( x1 * dev->
xscale );
464 x2 = (int) ( x2 * dev->
xscale );
465 y1 = (int) ( y1 * dev->
yscale );
466 y2 = (int) ( y2 * dev->
yscale );
482 plD_polyline_tkwin(
PLStream *pls,
short *xa,
short *ya,
PLINT npts )
491 if ( dev->
flags & 1 )
496 pts = (XPoint *) malloc(
sizeof ( XPoint ) * (size_t) npts );
503 for ( i = 0; i < npts; i++ )
505 pts[i].x = (short) ( dev->
xscale * xa[i] );
506 pts[i].y = (short) ( dev->
yscale * ( dev->
ylen - ya[i] ) );
536 if ( dev->
flags & 1 )
541 ExposeCmd( pls, NULL );
565 plwarn(
"WaitForPage: Illegal call --- driver can't find enclosing PlPlotter" );
570 while ( !( dev->
flags ) && !Tcl_InterpDeleted( plf->
interp ) && ( Tk_GetNumMainWindows() > 0 ) )
575 if ( Tcl_InterpDeleted( plf->
interp ) || ( Tk_GetNumMainWindows() <= 0 ) )
597 xrect.x = 0; xrect.y = 0;
598 xrect.width = (
short unsigned) dev->
width;
599 xrect.height = (
short unsigned) dev->
height;
602 if ( dev->
flags & 1 )
644 int ixwd = tkwd->
ixwd;
646 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
647 XCloseDisplay( tkwd->
display );
674 if ( dev->
flags & 1 )
683 int icol0 = pls->
icol0;
708 if ( tkwd->
ncol1 == 0 )
711 if ( tkwd->
ncol1 < 2 )
759 if ( dev->
flags & 1 )
775 FillPolygonCmd( pls );
800 #ifdef USING_PLESC_COPY
808 #ifdef USING_PLESC_COPY
819 int x0, w, x1, y0, h, y1;
832 x0, y0, w, h, x1, y1 );
836 x0, y0, w, h, x1, y1 );
858 pts = (XPoint *) malloc(
sizeof ( XPoint ) * (size_t) ( pls->
dev_npts ) );
865 for ( i = 0; i < pls->
dev_npts; i++ )
867 pts[i].x = (short) ( dev->
xscale * pls->
dev_x[i] );
875 pts, pls->
dev_npts, Nonconvex, CoordModeOrigin );
879 pts, pls->
dev_npts, Nonconvex, CoordModeOrigin );
932 plwarn(
"Init: Illegal call --- driver can't find enclosing PlPlotter" );
953 gcValues.background = tkwd->
cmap0[0].pixel;
954 gcValues.foreground = 0xFF;
955 gcValues.function = GXxor;
956 mask = GCForeground | GCBackground | GCFunction;
962 dev->
width = (
unsigned int) Tk_Width( plf->
tkwin );
963 dev->
height = (
unsigned int) Tk_Height( plf->
tkwin );
964 dev->
border = (
unsigned int) Tk_InternalBorderWidth( plf->
tkwin );
965 tkwd->
depth = (
unsigned int) Tk_Depth( plf->
tkwin );
1009 int x, y, width, height;
1017 plwarn(
"ExposeCmd: Illegal call -- driver uninitialized" );
1023 if ( pldis == NULL )
1027 width = (int) dev->
width;
1028 height = (
int) dev->
height;
1034 width = (int) pldis->
width;
1035 height = (
int) pldis->
height;
1045 x, y, (
unsigned int) width, (
unsigned int) height, x, y );
1051 int x0 = x, x1 = x + width, y0 = y, y1 = y + height;
1052 pts[0].x = (short) x0; pts[0].y = (short) y0;
1053 pts[1].x = (short) x1; pts[1].y = (short) y0;
1054 pts[2].x = (short) x1; pts[2].y = (short) y1;
1055 pts[3].x = (short) x0; pts[3].y = (short) y1;
1056 pts[4].x = (short) x0; pts[4].y = (short) y0;
1089 plwarn(
"ResizeCmd: Illegal call -- driver uninitialized" );
1095 if ( pldis == NULL )
1097 plwarn(
"ResizeCmd: Illegal call -- window pointer uninitialized" );
1131 #if defined ( __WIN32__ ) || defined ( MAC_TCL )
1153 CreatePixmap( pls );
1158 plD_bop_tkwin( pls );
1193 plwarn(
"RedrawCmd: Illegal call -- driver uninitialized" );
1202 plD_bop_tkwin( pls );
1232 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
1233 int ( *oldErrorHandler )( Display *, XErrorEvent * );
1234 oldErrorHandler = XSetErrorHandler( CreatePixmapErrorHandler );
1235 CreatePixmapStatus = Success;
1240 if ( dev->
width == 0 )
1249 pldebug(
"CreatePixmap",
1250 "creating pixmap: width = %d, height = %d, depth = %d\n",
1267 dev->
pixmap = Tk_GetPixmap( tkwd->
display, Tk_WindowId( tkwin ),
1268 Tk_Width( tkwin ), Tk_Height( tkwin ),
1269 DefaultDepthOfScreen( Tk_Screen( tkwin ) ) );
1271 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
1272 if ( CreatePixmapStatus != Success )
1277 fprintf( stderr,
"\n\
1278 Warning: pixmap could not be allocated (insufficient memory on server).\n\
1279 Driver will redraw the entire plot to handle expose events.\n" );
1282 XSetErrorHandler( oldErrorHandler );
1310 tkwd->
depth = (
unsigned int) depth;
1329 unsigned long plane_masks[1], pixels[MAX_COLORS];
1341 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1342 plane_masks, 0, pixels, 1 ) )
1344 tkwd->
cmap0[0].pixel = pixels[0];
1348 plexit(
"couldn't allocate background color cell" );
1353 npixels = MAX_COLORS;
1356 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1357 plane_masks, 0, pixels, npixels ) )
1367 for ( i = 0; i < npixels - 1; i++ )
1369 if ( pixels[i] == ( ~tkwd->
cmap0[0].pixel & 0xFF ) )
1375 tkwd->
fgcolor.pixel = pixels[i];
1376 for ( j = 0; j < npixels; j++ )
1379 XFreeColors( tkwd->
display, tkwd->
map, &pixels[j], 1, 0 );
1397 int gslevbg, gslevfg;
1412 gslevbg = (int) ( ( (
long) pls->
cmap0[0].
r +
1414 (
long) pls->
cmap0[0].
b ) / 3 );
1428 if ( gslevbg > 0x7F )
1433 fgcolor.
r = fgcolor.
g = fgcolor.
b = (
unsigned char) gslevfg;
1476 AllocCustomMap( pls );
1517 XColor xwm_colors[MAX_COLORS];
1521 unsigned long plane_masks[1], pixels[MAX_COLORS];
1528 for ( i = 0; i < MAX_COLORS; i++ )
1530 xwm_colors[i].pixel = (
long unsigned) i;
1533 XQueryColors( tkwd->
display, tkwd->
map, xwm_colors, MAX_COLORS );
1547 tkwd->
visual, AllocNone );
1552 npixels = MAX_COLORS;
1555 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1556 plane_masks, 0, pixels, npixels ) )
1560 plexit(
"couldn't allocate any colors" );
1565 for ( i = 0; i < XWM_COLORS; i++ )
1567 XStoreColor( tkwd->
display, tkwd->
map, &xwm_colors[i] );
1568 pixels[xwm_colors[i].pixel] = 0;
1573 for ( i = 0; i < tkwd->
ncol0; i++ )
1576 pixels[tkwd->
cmap0[i].pixel] = 0;
1585 if ( sxwm_colors_set )
1587 for ( i = 0; i < MAX_COLORS; i++ )
1589 if ( ( xwm_colors[i].red != sxwm_colors[i].red ) ||
1590 ( xwm_colors[i].green != sxwm_colors[i].green ) ||
1591 ( xwm_colors[i].blue != sxwm_colors[i].blue ) )
1593 if ( pixels[i] != 0 )
1595 XStoreColor( tkwd->
display, tkwd->
map, &xwm_colors[i] );
1604 for ( i = 0; i < npixels; i++ )
1606 if ( pixels[i] != 0 )
1607 XFreeColors( tkwd->
display, tkwd->
map, &pixels[i], 1, 0 );
1630 unsigned long plane_masks[1], pixels[MAX_COLORS];
1638 npixels = pls->
ncol0 - 1;
1641 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1642 plane_masks, 0, &pixels[1], npixels ) )
1646 plexit(
"couldn't allocate any colors" );
1649 tkwd->
ncol0 = npixels + 1;
1650 for ( i = 1; i < tkwd->
ncol0; i++ )
1652 tkwd->
cmap0[i].pixel = pixels[i];
1677 unsigned long plane_masks[1], pixels[MAX_COLORS];
1684 npixels =
MAX( 2,
MIN( CMAP1_COLORS, pls->
ncol1 ) );
1688 if ( XAllocColorCells( tkwd->
display, tkwd->
map, False,
1689 plane_masks, 0, pixels, npixels ) )
1700 "Warning: unable to allocate sufficient colors in cmap1\n" );
1705 tkwd->
ncol1 = npixels;
1707 fprintf( stderr,
"AllocCmap1 (xwin.c): Allocated %d colors in cmap1\n", npixels );
1713 for ( j = i = 0; i < tkwd->
ncol1; i++ )
1715 while ( pixels[j] == 0 )
1718 tkwd->
cmap1[i].pixel = pixels[j];
1722 if ( j >= tkwd->
ncol1 )
1726 tkwd->
ncol1 = npixels;
1747 for ( i = 1; i < tkwd->
ncol0; i++ )
1758 void CopyColour( XColor* from, XColor* to )
1760 to->pixel = from->pixel;
1761 to->red = from->red;
1762 to->blue = from->blue;
1763 to->green = from->green;
1764 to->flags = from->flags;
1785 for ( i = 0; i < tkwd->
ncol1; i++ )
1801 XStoreColor( tkwd->
display, tkwd->
map, col );
1806 CopyColour( xc, col );
1818 #define ToXColor( a ) ( ( ( 0xFF & ( a ) ) << 8 ) | ( a ) )
1819 #define ToPLColor( a ) ( ( (U_LONG) a ) >> 8 )
1824 xcolor->red = (
short unsigned) ToXColor( plcolor->
r );
1825 xcolor->green = (
short unsigned) ToXColor( plcolor->
g );
1826 xcolor->blue = (
short unsigned) ToXColor( plcolor->
b );
1827 xcolor->flags = DoRed | DoGreen | DoBlue;
1840 plcolor->
r = (
unsigned char) ToPLColor( xcolor->red );
1841 plcolor->
g = (
unsigned char) ToPLColor( xcolor->green );
1842 plcolor->
b = (
unsigned char) ToPLColor( xcolor->blue );
1859 color = ToPLColor( xcolor->red );
1861 if ( plcolor->
r != color )
1864 plcolor->
r = (
unsigned char) color;
1866 color = ToPLColor( xcolor->green );
1867 if ( plcolor->
g != color )
1870 plcolor->
g = (
unsigned char) color;
1872 color = ToPLColor( xcolor->blue );
1873 if ( plcolor->
b != color )
1876 plcolor->
b = (
unsigned char) color;
1892 #if defined ( __cplusplus ) || defined ( c_plusplus )
1893 #define THING c_class
1900 visual = Tk_Visual( plf->
tkwin );
1901 if ( ( visual->THING != GrayScale ) && ( visual->THING != StaticGray ) )
1907 #if !defined ( MAC_TCL ) && !defined ( __WIN32__ )
1917 CreatePixmapErrorHandler( Display *
display, XErrorEvent *
error )
1919 if ( error->error_code == BadAlloc )
1921 CreatePixmapStatus = error->error_code;
1926 XGetErrorText( display, error->error_code, buffer, 256 );
1927 fprintf( stderr,
"Error in XCreatePixmap: %s.\n", buffer );
1947 ptr = (
long *) malloc( size );
1953 for ( size = ( size /
sizeof (
long ) ) + 1, p = ptr; --size; )
1958 for ( size = ( size /
sizeof (
long ) ) + 1, p = ptr - 1; --size; )