38 #ifdef PL_HAVE_PTHREAD
41 int pthread_mutexattr_settype( pthread_mutexattr_t *attr,
int kind );
42 static void events_thread(
void *
pls );
43 static pthread_mutex_t events_mutex;
44 static int already = 0;
48 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_xwin =
"xwin:X-Window (Xlib):1:xwin:5:xw\n";
53 static int nobuffered = 0;
56 static int noinitcolors = 0;
59 static int defaultvisual = 1;
61 static int usepthreads = 1;
83 #define LOCATE_INVOKED_VIA_API 1
84 #define LOCATE_INVOKED_VIA_DRIVER 2
107 #define CCMAP_XWM_COLORS 70
109 #define RWMAP_CMAP1_COLORS 50
110 #define RWMAP_MAX_COLORS 256
112 #define ROMAP_CMAP1_COLORS 50
113 #define TC_CMAP1_COLORS 200
118 static int sxwm_colors_set;
119 static XColor sxwm_colors[RWMAP_MAX_COLORS];
132 void plD_line_xw(
PLStream *,
short,
short,
short,
short );
153 static int AreWeGrayscale( Display *
display );
163 static void MasterEH(
PLStream *
pls, XEvent *event );
164 static void ClientEH(
PLStream *
pls, XEvent *event );
165 static void ExposeEH(
PLStream *
pls, XEvent *event );
166 static void ResizeEH(
PLStream *
pls, XEvent *event );
167 static void MotionEH(
PLStream *
pls, XEvent *event );
168 static void EnterEH(
PLStream *
pls, XEvent *event );
169 static void LeaveEH(
PLStream *
pls, XEvent *event );
171 static void ButtonEH(
PLStream *
pls, XEvent *event );
172 static void LookupXKeyEvent(
PLStream *
pls, XEvent *event );
173 static void LookupXButtonEvent(
PLStream *
pls, XEvent *event );
206 static void SaveColormap( Display *
display, Colormap colormap );
208 static void PLColor_to_XColor(
PLColor *plcolor, XColor *xcolor );
209 static void PLColor_from_XColor(
PLColor *plcolor, XColor *xcolor );
212 {
"nobuffered",
DRV_INT, &nobuffered,
"Sets unbuffered operation (0|1)" },
213 {
"noinitcolors",
DRV_INT, &noinitcolors,
"Sets cmap0 allocation (0|1)" },
214 {
"defvis",
DRV_INT, &defaultvisual,
"Use the Default Visual (0|1)" },
215 {
"usepth",
DRV_INT, &usepthreads,
"Use pthreads (0|1)" },
216 { NULL,
DRV_INT, NULL, NULL } };
220 #ifndef ENABLE_DYNDRIVERS
262 #ifndef PL_HAVE_PTHREAD
268 #ifndef PL_HAVE_PTHREAD
270 plwarn(
"You said you want pthreads, but they are not available." );
278 if ( pls->
dev == NULL )
287 dev->
xlen = (short) ( xmax - xmin );
288 dev->
ylen = (short) ( ymax - ymin );
307 #ifdef PL_HAVE_PTHREAD
310 pthread_mutexattr_t mutexatt;
311 pthread_attr_t pthattr;
315 pthread_mutexattr_init( &mutexatt );
317 plexit(
"xwin: pthread_mutexattr_settype() failed!\n" );
319 pthread_mutex_init( &events_mutex, &mutexatt );
324 pthread_mutex_lock( &events_mutex );
326 pthread_mutex_unlock( &events_mutex );
329 pthread_attr_init( &pthattr );
330 pthread_attr_setdetachstate( &pthattr, PTHREAD_CREATE_JOINABLE );
332 if ( pthread_create( &( dev->updater ), &pthattr, (
void *( * )(
void * ) ) & events_thread, (
void *) pls ) )
334 pthread_mutex_lock( &events_mutex );
336 pthread_mutex_unlock( &events_mutex );
340 pthread_mutex_destroy( &events_mutex );
341 plexit(
"xwin: pthread_create() failed!\n" );
344 plwarn(
"xwin: couldn't create thread for this plot window!\n" );
357 plD_line_xw(
PLStream *pls,
short x1a,
short y1a,
short x2a,
short y2a )
362 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
366 #ifdef PL_HAVE_PTHREAD
368 pthread_mutex_lock( &events_mutex );
371 CheckForEvents( pls );
376 x1 = (int) ( x1 * dev->
xscale );
377 x2 = (int) ( x2 * dev->
xscale );
378 y1 = (int) ( y1 * dev->
yscale );
379 y2 = (int) ( y2 * dev->
yscale );
382 XDrawLine( xwd->display, dev->
window, dev->
gc, x1, y1, x2, y2 );
385 XDrawLine( xwd->display, dev->
pixmap, dev->
gc, x1, y1, x2, y2 );
387 #ifdef PL_HAVE_PTHREAD
389 pthread_mutex_unlock( &events_mutex );
406 XSetFunction( xwd->display, dev->
gc, GXcopy );
408 XSetFunction( xwd->display, dev->
gc, GXxor );
418 plD_polyline_xw(
PLStream *pls,
short *xa,
short *ya,
PLINT npts )
429 pts = (XPoint *) malloc(
sizeof ( XPoint ) * (size_t) npts );
438 #ifdef PL_HAVE_PTHREAD
440 pthread_mutex_lock( &events_mutex );
443 CheckForEvents( pls );
445 for ( i = 0; i < npts; i++ )
447 pts[i].x = (short) ( dev->
xscale * xa[i] );
448 pts[i].y = (short) ( dev->
yscale * ( dev->
ylen - ya[i] ) );
452 XDrawLines( xwd->display, dev->
window, dev->
gc, pts, npts,
456 XDrawLines( xwd->display, dev->
pixmap, dev->
gc, pts, npts,
459 #ifdef PL_HAVE_PTHREAD
461 pthread_mutex_unlock( &events_mutex );
484 #ifdef PL_HAVE_PTHREAD
486 pthread_mutex_lock( &events_mutex );
489 XFlush( xwd->display );
491 ExposeCmd( pls, NULL );
496 #ifdef PL_HAVE_PTHREAD
498 pthread_mutex_unlock( &events_mutex );
516 #ifdef PL_HAVE_PTHREAD
518 pthread_mutex_lock( &events_mutex );
525 XSetWindowBackground( xwd->display, dev->
window, dev->
bgcolor.pixel );
526 XSetBackground( xwd->display, dev->
gc, dev->
bgcolor.pixel );
527 XClearWindow( xwd->display, dev->
window );
531 XSetForeground( xwd->display, dev->
gc, dev->
bgcolor.pixel );
532 XFillRectangle( xwd->display, dev->
pixmap, dev->
gc, 0, 0,
534 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
536 XSync( xwd->display, 0 );
539 #ifdef PL_HAVE_PTHREAD
541 pthread_mutex_unlock( &events_mutex );
559 #ifdef PL_HAVE_PTHREAD
562 pthread_mutex_lock( &events_mutex );
563 if ( pthread_cancel( dev->updater ) == 0 )
564 pthread_join( dev->updater, NULL );
566 pthread_mutex_unlock( &events_mutex );
567 if ( --already == 0 )
568 pthread_mutex_destroy( &events_mutex );
574 XDestroyWindow( xwd->display, dev->
window );
576 XFreePixmap( xwd->display, dev->
pixmap );
577 XFlush( xwd->display );
581 if ( xwd->nstreams == 0 )
583 int ixwd = xwd->ixwd;
584 XFreeGC( xwd->display, dev->
gc );
585 XFreeGC( xwd->display, xwd->gcXor );
586 XCloseDisplay( xwd->display );
610 #ifdef PL_HAVE_PTHREAD
612 pthread_mutex_lock( &events_mutex );
615 CheckForEvents( pls );
620 XSetLineAttributes( xwd->display, dev->
gc, (
unsigned int) pls->
width,
621 LineSolid, CapRound, JoinMiter );
625 int icol0 = pls->
icol0;
631 if ( !XAllocColor( xwd->display, xwd->map, &dev->
curcolor ) )
633 fprintf( stderr,
"Warning: could not allocate color\n" );
634 dev->
curcolor.pixel = xwd->fgcolor.pixel;
641 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
646 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
654 if ( xwd->ncol1 == 0 )
657 if ( xwd->ncol1 < 2 )
660 icol1 = ( pls->
icol1 * ( xwd->ncol1 - 1 ) ) / ( pls->
ncol1 - 1 );
666 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
673 if ( pls->
ncol0 != xwd->ncol0 )
683 #ifdef PL_HAVE_PTHREAD
685 pthread_mutex_unlock( &events_mutex );
724 #ifdef PL_HAVE_PTHREAD
726 pthread_mutex_lock( &events_mutex );
740 FillPolygonCmd( pls );
747 XFlush( xwd->display );
763 XorMod( pls, (
PLINT *) ptr );
775 imageops( pls, (
PLINT *) ptr );
779 PLColor_to_XColor( &pls->
tmpcolor, (XColor *) ptr );
783 PLColor_from_XColor( &pls->
tmpcolor, (XColor *) ptr );
795 #ifdef PL_HAVE_PTHREAD
797 pthread_mutex_unlock( &events_mutex );
826 XNextEvent( xwd->display, &event );
827 MasterEH( pls, &event );
855 pts = (XPoint *) malloc(
sizeof ( XPoint ) * (size_t) ( pls->
dev_npts ) );
862 CheckForEvents( pls );
864 for ( i = 0; i < pls->
dev_npts; i++ )
866 pts[i].x = (short) ( dev->
xscale * pls->
dev_x[i] );
873 XFillPolygon( xwd->display, dev->
window, dev->
gc,
874 pts, pls->
dev_npts, Complex, CoordModeOrigin );
877 XFillPolygon( xwd->display, dev->
pixmap, dev->
gc,
878 pts, pls->
dev_npts, Complex, CoordModeOrigin );
885 XSetForeground( xwd->display, dev->
gc, xwd->fgcolor.pixel );
894 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
924 if ( pls->
dev != NULL )
925 plwarn(
"OpenXwin: device pointer is already set" );
927 pls->
dev = calloc( 1, (
size_t)
sizeof (
XwDev ) );
928 if ( pls->
dev == NULL )
929 plexit(
"plD_init_xw: Out of memory." );
943 if ( xwDisplay[i] == NULL )
949 dev->
xwd = xwDisplay[i];
956 else if ( strcmp( xwDisplay[i]->displayName, pls->
FileName ) == 0 )
958 dev->
xwd = xwDisplay[i];
965 if ( dev->
xwd == NULL )
968 if ( dev->
xwd == NULL )
969 plexit(
"Init: Out of memory." );
973 if ( xwDisplay[i] == NULL )
976 if ( i == PLXDISPLAYS )
977 plexit(
"Init: Out of xwDisplay's." );
985 if ( !XInitThreads() )
986 plexit(
"xwin: XInitThreads() not successful." );
991 plexit(
"Can't open display" );
996 XSynchronize( xwd->
display, 1 );
1018 xwd->
cmap0 = (XColor *) calloc( (
size_t) ( pls->
ncol0 ),
sizeof ( XColor ) );
1019 if ( xwd->
cmap0 == 0 )
1020 plexit(
"couldn't allocate space for cmap0 colors" );
1076 if ( noinitcolors == 0 )
1092 gcValues.background = xwd->
cmap0[0].pixel;
1093 gcValues.foreground = 0xFF;
1094 gcValues.function = GXxor;
1095 mask = GCForeground | GCBackground | GCFunction;
1125 CreatePixmap( pls );
1136 XSetFillRule( xwd->
display, dev->
gc, EvenOddRule );
1138 XSetFillRule( xwd->
display, dev->
gc, WindingRule );
1161 U_INT width, height, border, depth;
1168 &root, &
x, &
y, &width, &height, &border, &depth );
1175 hint.flags |= PSize;
1177 hint.flags |= USSize;
1184 if ( pls->
xlength > (
short) width )
1186 if ( pls->
ylength > (
short) height )
1189 hint.width = (int) pls->
xlength;
1190 hint.height = (
int) pls->
ylength;
1198 hint.flags |= USPosition;
1212 DefaultRootWindow( xwd->
display ),
1213 hint.x, hint.y, (
unsigned int) hint.width, (
unsigned int) hint.height,
1215 InputOutput, xwd->
visual,
1219 None, 0, 0, &hint );
1244 StructureNotifyMask;
1252 Atom wmDelete = XInternAtom( xwd->
display,
"WM_DELETE_WINDOW", False );
1261 if ( event.type == Expose )
1264 ExposureMask, &event ) )
1290 XNextEvent( xwd->
display, &event );
1291 MasterEH( pls, &event );
1317 #ifdef PL_HAVE_PTHREAD
1319 events_thread(
void *pls )
1327 struct timespec delay;
1348 event_mask = ExposureMask | StructureNotifyMask;
1351 sigemptyset( &set );
1353 sigaddset( &set, SIGINT );
1355 sigprocmask( SIG_BLOCK, &set, NULL );
1357 pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
1358 pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
1361 delay.tv_nsec = 10000000;
1365 pthread_mutex_lock( &events_mutex );
1371 while ( XCheckWindowEvent( xwd->
display, dev->
window, event_mask, &event ) )
1380 switch ( event.type )
1383 ExposeEH( lpls, &event );
1385 case ConfigureNotify:
1386 ResizeEH( lpls, &event );
1393 pthread_mutex_unlock( &events_mutex );
1394 nanosleep( &delay, NULL );
1426 HandleEvents( pls );
1445 ClientMessage, &event ) ||
1448 MasterEH( pls, &event );
1468 MasterEH(
PLStream *pls, XEvent *event )
1475 switch ( event->type )
1478 KeyEH( pls, event );
1482 ButtonEH( pls, event );
1486 ExposeEH( pls, event );
1489 case ConfigureNotify:
1490 ResizeEH( pls, event );
1494 if ( event->xmotion.state )
1495 ButtonEH( pls, event );
1496 MotionEH( pls, event );
1500 EnterEH( pls, event );
1504 LeaveEH( pls, event );
1508 ClientEH( pls, event );
1520 ClientEH(
PLStream *pls, XEvent *event )
1525 if ( (Atom)
event->xclient.data.l[0] == XInternAtom( xwd->
display,
"WM_DELETE_WINDOW", False ) )
1542 KeyEH(
PLStream *pls, XEvent *event )
1548 LookupXKeyEvent( pls, event );
1562 ButtonEH(
PLStream *pls, XEvent *event )
1568 LookupXButtonEvent( pls, event );
1570 LocateButton( pls );
1572 ProcessButton( pls );
1597 LookupXKeyEvent(
PLStream *pls, XEvent *event )
1601 XKeyEvent *keyEvent = (XKeyEvent *) event;
1606 gin->
pX = keyEvent->x;
1607 gin->
pY = keyEvent->y;
1611 gin->
state = keyEvent->state;
1613 nchars = XLookupString( keyEvent, gin->
string, ncmax, &keysym, &cs );
1614 gin->
string[nchars] =
'\0';
1616 pldebug(
"LookupXKeyEvent",
1617 "Keysym %x, translation: %s\n", keysym, gin->
string );
1627 gin->
keysym = 0xFF & keysym;
1631 gin->
keysym = (
unsigned int) keysym;
1642 LookupXButtonEvent(
PLStream *pls, XEvent *event )
1646 XButtonEvent *buttonEvent = (XButtonEvent *) event;
1648 pldebug(
"LookupXButtonEvent",
1649 "Button: %d, x: %d, y: %d\n",
1650 buttonEvent->button, buttonEvent->x, buttonEvent->y );
1652 gin->
pX = buttonEvent->x;
1653 gin->
pY = buttonEvent->y;
1655 gin->
dY = 1.0 - (
PLFLT) buttonEvent->y / ( dev->
height - 1 );
1657 gin->
button = buttonEvent->button;
1658 gin->
state = buttonEvent->state;
1679 if ( pls->
KeyEH != NULL )
1771 else if ( IsModifierKey( gin->
keysym ) )
1778 else if ( IsCursorKey( gin->
keysym ) )
1780 int x1, y1,
dx = 0,
dy = 0;
1781 int xmin = 0, xmax = (int) dev->
width - 1, ymin = 0, ymax = (
int) dev->
height - 1;
1803 if ( gin->
state & 0x01 )
1811 if ( gin->
state & 0x02 )
1819 if ( gin->
state & 0x04 )
1827 if ( gin->
state & 0x08 )
1839 dx = xmin - gin->
pX;
1841 dy = ymin - gin->
pY;
1843 dx = xmax - gin->
pX;
1845 dy = ymax - gin->
pY;
1937 printf(
"%f %f %c\n", gin->
wX, gin->
wY, gin->
keysym );
1939 printf(
"%f %f 0x%02x\n", gin->
wX, gin->
wY, gin->
keysym );
1962 MotionEH(
PLStream *pls, XEvent *event )
1965 XMotionEvent *motionEvent = (XMotionEvent *) event;
1969 DrawXhairs( pls, motionEvent->x, motionEvent->y );
1981 EnterEH(
PLStream *pls, XEvent *event )
1984 XCrossingEvent *crossingEvent = (XCrossingEvent *) event;
1986 DrawXhairs( pls, crossingEvent->x, crossingEvent->y );
2019 int root_x, root_y, win_x, win_y;
2033 if ( XQueryPointer( xwd->
display, dev->
window, &root, &child,
2034 &root_x, &root_y, &win_x, &win_y, &mask ) )
2036 if ( win_x >= 0 && win_x < (
int) dev->
width &&
2037 win_y >= 0 && win_y < (
int) dev->
height )
2048 PointerMotionMask, &event ) )
2053 dev->
event_mask |= PointerMotionMask | EnterWindowMask | LeaveWindowMask;
2076 ~PointerMotionMask & ~EnterWindowMask & ~LeaveWindowMask;
2096 int xmin = 0, xmax = (
int) dev->
width - 1;
2097 int ymin = 0, ymax = (int) dev->
height - 1;
2102 dev->
xhair_x[0].x = (short) xmin; dev->
xhair_x[0].y = (short) y0;
2103 dev->
xhair_x[1].x = (short) xmax; dev->
xhair_x[1].y = (short) y0;
2105 dev->
xhair_y[0].x = (short) x0; dev->
xhair_y[0].y = (short) ymin;
2106 dev->
xhair_y[1].x = (short) x0; dev->
xhair_y[1].y = (short) ymax;
2138 ExposeEH(
PLStream *pls, XEvent *event )
2142 XExposeEvent *exposeEvent = (XExposeEvent *) event;
2148 pldebug(
"ExposeEH",
2149 "x = %d, y = %d, width = %d, height = %d, count = %d, pending = %d\n",
2150 exposeEvent->x, exposeEvent->y,
2151 exposeEvent->width, exposeEvent->height,
2152 exposeEvent->count, XPending( xwd->
display ) );
2163 ExposeCmd( pls, NULL );
2169 pldis.
x = (
unsigned int) exposeEvent->x;
2170 pldis.
y = (
unsigned int) exposeEvent->y;
2171 pldis.
width = (
unsigned int) exposeEvent->width;
2172 pldis.
height = (
unsigned int) exposeEvent->height;
2174 ExposeCmd( pls, &pldis );
2182 ExposureMask | StructureNotifyMask, event ) )
2194 ResizeEH(
PLStream *pls, XEvent *event )
2198 XConfigureEvent *configEvent = (XConfigureEvent *) event;
2203 pldis.
width = (
unsigned int) configEvent->width;
2204 pldis.
height = (
unsigned int) configEvent->height;
2211 pldebug(
"ResizeEH",
2212 "x = %d, y = %d, pending = %d\n",
2213 configEvent->width, configEvent->height, XPending( xwd->
display ) );
2217 ResizeCmd( pls, &pldis );
2228 ExposureMask | StructureNotifyMask, event ) )
2245 unsigned int width, height;
2253 plwarn(
"ExposeCmd: Illegal call -- driver uninitialized" );
2259 if ( pldis == NULL )
2270 width = pldis->
width;
2281 x, y, width, height, x, y );
2287 int x0 =
x, x1 = x + (int) width, y0 = y, y1 = y + (
int) height;
2288 pts[0].x = (
short) x0; pts[0].y = (
short) y0;
2289 pts[1].x = (
short) x1; pts[1].y = (
short) y0;
2290 pts[2].x = (
short) x1; pts[2].y = (
short) y1;
2291 pts[3].x = (
short) x0; pts[3].y = (
short) y1;
2292 pts[4].x = (
short) x0; pts[4].y = (
short) y0;
2294 XDrawLines( xwd->
display, dev->window, dev->gc, pts, 5,
2325 plwarn(
"ResizeCmd: Illegal call -- driver uninitialized" );
2331 if ( pldis == NULL )
2333 plwarn(
"ResizeCmd: Illegal call -- window pointer uninitialized" );
2368 CreatePixmap( pls );
2430 printf(
"Unrecognized buffering request ignored.\n" );
2455 plwarn(
"RedrawCmd: Illegal call -- driver uninitialized" );
2496 static unsigned char CreatePixmapStatus;
2499 CreatePixmapErrorHandler( Display *
display, XErrorEvent *
error )
2501 CreatePixmapStatus = error->error_code;
2502 if ( error->error_code != BadAlloc )
2505 XGetErrorText( display, error->error_code, buffer, 256 );
2506 fprintf( stderr,
"Error in XCreatePixmap: %s.\n", buffer );
2524 int ( *oldErrorHandler )( Display *, XErrorEvent * );
2526 oldErrorHandler = XSetErrorHandler( CreatePixmapErrorHandler );
2528 CreatePixmapStatus = Success;
2529 pldebug(
"CreatePixmap",
2530 "creating pixmap: width = %d, height = %d, depth = %d\n",
2536 if ( CreatePixmapStatus != Success )
2541 fprintf( stderr,
"\n\
2542 Warning: pixmap could not be allocated (insufficient memory on server).\n\
2543 Driver will redraw the entire plot to handle expose events.\n" );
2546 XSetErrorHandler( oldErrorHandler );
2565 int visuals_matched = 0;
2569 if ( !defaultvisual )
2571 XVisualInfo vTemplate, *visualList;
2575 vTemplate.screen = xwd->
screen;
2576 vTemplate.depth = 8;
2578 visualList = XGetVisualInfo( xwd->
display,
2579 VisualScreenMask | VisualDepthMask,
2580 &vTemplate, &visuals_matched );
2582 #ifdef HACK_STATICCOLOR
2583 if ( visuals_matched )
2586 printf(
"visuals_matched = %d\n", visuals_matched );
2587 for ( i = 0; i < visuals_matched && !found; i++ )
2589 Visual *v = visualList[i].visual;
2590 printf(
"Checking visual %d: ", i );
2594 printf(
"PseudoColor\n" );
2597 printf(
"GrayScale\n" );
2600 printf(
"DirectColor\n" );
2603 printf(
"TrueColor\n" );
2606 printf(
"StaticColor\n" );
2609 printf(
"StaticGray\n" );
2612 printf(
"Unknown.\n" );
2615 if ( v->class == StaticColor )
2618 xwd->
depth = visualList[i].depth;
2624 plexit(
"Unable to get a StaticColor visual." );
2626 printf(
"Found StaticColor visual, depth=%d\n", xwd->
depth );
2629 if ( visuals_matched )
2631 xwd->
visual = visualList->visual;
2632 xwd->
depth = (
unsigned int) vTemplate.depth;
2634 #endif // HACK_STATICCOLOR
2637 if ( !visuals_matched )
2645 switch ( xwd->
visual->class )
2662 fprintf( stderr,
"XVisual class == " );
2663 switch ( xwd->
visual->class )
2666 fprintf( stderr,
"PseudoColor\n" );
2669 fprintf( stderr,
"GrayScale\n" );
2672 fprintf( stderr,
"DirectColor\n" );
2675 fprintf( stderr,
"TrueColor\n" );
2678 fprintf( stderr,
"StaticColor\n" );
2681 fprintf( stderr,
"StaticGray\n" );
2684 fprintf( stderr,
"Unknown.\n" );
2687 fprintf( stderr,
"xwd->rw_cmap = %d\n", xwd->
rw_cmap );
2706 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
2716 XAllocColorCells( xwd->
display, xwd->
map, False,
2717 plane_masks, 0, pixels, 1 ) )
2720 xwd->
cmap0[0].pixel = pixels[0];
2728 fprintf( stderr,
"Downgrading to r/o cmap.\n" );
2735 npixels = RWMAP_MAX_COLORS;
2738 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
2739 plane_masks, 0, pixels, (
unsigned int) npixels ) )
2749 for ( i = 0; i < npixels - 1; i++ )
2751 if ( pixels[i] == ( ~xwd->
cmap0[0].pixel & 0xFF ) )
2757 xwd->
fgcolor.pixel = pixels[i];
2758 for ( j = 0; j < npixels; j++ )
2761 XFreeColors( xwd->
display, xwd->
map, &pixels[j], 1, 0 );
2779 unsigned int gslevbg, gslevfg;
2794 gslevbg = (
unsigned int) ( ( (
long) pls->
cmap0[0].
r +
2796 (
long) pls->
cmap0[0].
b ) / 3 );
2798 PLColor_to_XColor( &pls->
cmap0[0], &xwd->
cmap0[0] );
2810 if ( gslevbg > 0x7F )
2815 fgcolor.
r = fgcolor.
g = fgcolor.
b = (
unsigned char) gslevfg;
2817 PLColor_to_XColor( &fgcolor, &xwd->
fgcolor );
2854 AllocCustomMap( pls );
2894 XColor xwm_colors[RWMAP_MAX_COLORS];
2896 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
2902 for ( i = 0; i < RWMAP_MAX_COLORS; i++ )
2904 xwm_colors[i].pixel = (
unsigned long int) i;
2906 XQueryColors( xwd->
display, xwd->
map, xwm_colors, RWMAP_MAX_COLORS );
2919 xwd->
visual, AllocNone );
2923 npixels = RWMAP_MAX_COLORS;
2926 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
2927 plane_masks, 0, pixels, (
unsigned int) npixels ) )
2931 plexit(
"couldn't allocate any colors" );
2936 for ( i = 0; i < CCMAP_XWM_COLORS; i++ )
2938 XStoreColor( xwd->
display, xwd->
map, &xwm_colors[i] );
2939 pixels[xwm_colors[i].pixel] = 0;
2944 for ( i = 0; i < xwd->
ncol0; i++ )
2947 pixels[xwd->
cmap0[i].pixel] = 0;
2956 if ( sxwm_colors_set )
2958 for ( i = 0; i < RWMAP_MAX_COLORS; i++ )
2960 if ( ( xwm_colors[i].red != sxwm_colors[i].red ) ||
2961 ( xwm_colors[i].green != sxwm_colors[i].green ) ||
2962 ( xwm_colors[i].blue != sxwm_colors[i].blue ) )
2964 if ( pixels[i] != 0 )
2966 XStoreColor( xwd->
display, xwd->
map, &xwm_colors[i] );
2975 for ( i = 0; i < npixels; i++ )
2977 if ( pixels[i] != 0 )
2978 XFreeColors( xwd->
display, xwd->
map, &pixels[i], 1, 0 );
3002 for ( i = 1; i < xwd->
ncol0; i++ )
3004 unsigned long pixel = xwd->
cmap0[i].pixel;
3005 XFreeColors( xwd->
display, xwd->
map, &pixel, 1, 0 );
3012 xwd->
cmap0 = (XColor *)
3013 realloc( xwd->
cmap0, (
size_t) pls->
ncol0 *
sizeof ( XColor ) );
3014 if ( xwd->
cmap0 == 0 )
3015 plexit(
"couldn't allocate space for cmap0 colors" );
3021 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
3025 npixels = pls->
ncol0 - 1;
3028 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
3029 plane_masks, 0, &pixels[1], (
unsigned int) npixels ) )
3033 plexit(
"couldn't allocate any colors" );
3036 xwd->
ncol0 = npixels + 1;
3037 for ( i = 1; i < xwd->
ncol0; i++ )
3039 xwd->
cmap0[i].pixel = pixels[i];
3047 fprintf( stderr,
"Attempting to allocate r/o colors in cmap0.\n" );
3049 for ( i = 1; i < pls->
ncol0; i++ )
3053 PLColor_to_XColor( &pls->
cmap0[i], &c );
3054 r = XAllocColor( xwd->
display, xwd->
map, &c );
3056 fprintf( stderr,
"i=%d, r=%d, pixel=%d\n", i, r, (
int) c.pixel );
3060 xwd->
cmap0[i].pixel = c.pixel;
3064 XColor screen_def, exact_def;
3068 "color alloc failed, trying by name: %s.\n",
3072 r = XAllocNamedColor( xwd->
display, xwd->
map,
3074 &screen_def, &exact_def );
3081 fprintf( stderr,
"yes, got a color by name.\n" );
3083 xwd->
cmap0[i] = screen_def;
3084 xwd->
cmap0[i].pixel = screen_def.pixel;
3088 r = XAllocNamedColor( xwd->
display, xwd->
map,
3090 &screen_def, &exact_def );
3093 xwd->
cmap0[i] = screen_def;
3094 xwd->
cmap0[i].pixel = screen_def.pixel;
3097 printf(
"Can't find white?! Giving up...\n" );
3104 fprintf( stderr,
"Allocated %d colors in cmap0.\n", xwd->
ncol0 );
3121 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
3128 fprintf( stderr,
"Attempting to allocate r/w colors in cmap1.\n" );
3133 npixels =
MAX( 2,
MIN( RWMAP_CMAP1_COLORS, pls->
ncol1 ) );
3136 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
3137 plane_masks, 0, pixels, (
unsigned int) npixels ) )
3147 fprintf( stderr,
"Warning: unable to allocate sufficient colors in cmap1.\n" );
3151 xwd->
ncol1 = npixels;
3153 fprintf( stderr,
"AllocCmap1 (xwin.c): Allocated %d colors in cmap1.\n", npixels );
3159 xwd->
cmap1 = (XColor *) calloc( (
size_t) ( xwd->
ncol1 ),
sizeof ( XColor ) );
3161 plexit(
"couldn't allocate space for cmap1 colors" );
3167 for ( j = i = 0; i < xwd->
ncol1; i++ )
3169 while ( pixels[j] == 0 )
3172 xwd->
cmap1[i].pixel = pixels[j];
3176 if ( j >= xwd->
ncol1 )
3189 fprintf( stderr,
"Attempting to allocate r/o colors in cmap1.\n" );
3191 switch ( xwd->
visual->class )
3194 ncolors = TC_CMAP1_COLORS;
3197 ncolors = ROMAP_CMAP1_COLORS;
3204 xwd->
cmap1 = (XColor *) calloc( (
size_t) ncolors,
sizeof ( XColor ) );
3206 plexit(
"couldn't allocate space for cmap1 colors" );
3209 for ( i = 0; i < ncolors; i++ )
3212 PLColor_to_XColor( &cmap1color, &xcol );
3214 r = XAllocColor( xwd->
display, xwd->
map, &xcol );
3216 fprintf( stderr,
"i=%d, r=%d, pixel=%d\n", i, r, (
int) xcol.pixel );
3218 xwd->
cmap1[i] = xcol;
3226 "Warning: unable to allocate sufficient colors in cmap1\n" );
3231 xwd->
ncol1 = ncolors;
3233 fprintf( stderr,
"AllocCmap1 (xwin.c): Allocated %d colors in cmap1\n", ncolors );
3254 for ( i = 1; i < xwd->
ncol0; i++ )
3256 PLColor_to_XColor( &pls->
cmap0[i], &xwd->
cmap0[i] );
3282 for ( i = 0; i < xwd->
ncol1; i++ )
3285 PLColor_to_XColor( &cmap1color, &xwd->
cmap1[i] );
3301 #define ToXColor( a ) ( ( ( 0xFF & ( a ) ) << 8 ) | ( a ) )
3302 #define ToPLColor( a ) ( ( (U_LONG) a ) >> 8 )
3305 PLColor_to_XColor(
PLColor *plcolor, XColor *xcolor )
3307 xcolor->red = (
short unsigned) ToXColor( plcolor->
r );
3308 xcolor->green = (
short unsigned) ToXColor( plcolor->
g );
3309 xcolor->blue = (
short unsigned) ToXColor( plcolor->
b );
3310 xcolor->flags = DoRed | DoGreen | DoBlue;
3321 PLColor_from_XColor(
PLColor *plcolor, XColor *xcolor )
3323 plcolor->
r = (
unsigned char) ToPLColor( xcolor->red );
3324 plcolor->
g = (
unsigned char) ToPLColor( xcolor->green );
3325 plcolor->
b = (
unsigned char) ToPLColor( xcolor->blue );
3337 AreWeGrayscale( Display *display )
3339 #if defined ( __cplusplus ) || defined ( c_plusplus )
3340 #define THING c_class
3345 XVisualInfo *visuals;
3346 int nitems, i, igray;
3349 visuals = XGetVisualInfo( display, 0, NULL, &nitems );
3353 for ( i = 0; i < nitems; i++ )
3354 if ( ( visuals[i].THING != GrayScale ) &&
3355 ( visuals[i].THING != StaticGray ) )
3382 SaveColormap( Display *display, Colormap colormap )
3389 sxwm_colors_set = 1;
3390 for ( i = 0; i < RWMAP_MAX_COLORS; i++ )
3392 sxwm_colors[i].pixel = i;
3394 XQueryColors( display, colormap, sxwm_colors, RWMAP_MAX_COLORS );
3414 GetImageErrorHandler( Display *display, XErrorEvent *error )
3416 if ( error->error_code != BadMatch )
3419 XGetErrorText( display, error->error_code, buffer, 256 );
3420 fprintf( stderr,
"xwin: Error in XGetImage: %s.\n", buffer );
3437 XImage *ximg = NULL;
3441 int ( *oldErrorHandler )( Display *, XErrorEvent * );
3444 float blt, brt, brb, blb;
3448 int i, corners[4], r[4] = { 0, 0, 0, 0 };
3455 CheckForEvents( pls );
3466 oldErrorHandler = XSetErrorHandler( GetImageErrorHandler );
3471 AllPlanes, ZPixmap );
3475 AllPlanes, ZPixmap );
3477 XSetErrorHandler( oldErrorHandler );
3481 plabort(
"Can't get image, the window must be partly off-screen, move it to fit screen" );
3485 if ( xwd->
ncol1 == 0 )
3487 if ( xwd->
ncol1 < 2 )
3491 switch ( (
int) ( pls->
diorot - 4. * floor( pls->
diorot / 4. ) ) )
3494 r[0] = 0; r[1] = 1; r[2] = 2; r[3] = 3;
break;
3496 r[0] = 1; r[1] = 2; r[2] = 3; r[3] = 0;
break;
3498 r[0] = 2; r[1] = 3; r[2] = 0; r[3] = 1;
break;
3500 r[0] = 3; r[1] = 0; r[2] = 1; r[3] = 2;
3525 for ( ix = 0; ix < nx - 1; ix++ )
3527 for ( iy = 0; iy < ny - 1; iy++ )
3529 corners[0] = ix * ny + iy;
3530 corners[1] = ( ix + 1 ) * ny + iy;
3531 corners[2] = ( ix + 1 ) * ny + iy + 1;
3532 corners[3] = ix * ny + iy + 1;
3534 for ( i = 0; i < 4; i++ )
3536 Ppts[i].x = (float) ( dev->
xscale * ( pls->
dev_ix[corners[r[i]]] ) );
3537 Ppts[i].y = (float) ( dev->
yscale * ( pls->
dev_iy[corners[r[i]]] ) );
3541 if ( Ppts[0].x >= xmin || Ppts[2].x <= xmax ||
3542 Ppts[1].y >= ymin || Ppts[3].y <= ymax )
3544 Ppts[0].x =
MAX( Ppts[0].x, (
float) xmin );
3545 Ppts[2].x =
MIN( Ppts[2].x, (
float) xmax );
3546 Ppts[1].y =
MAX( Ppts[1].y, (
float) ymin );
3547 Ppts[3].y =
MIN( Ppts[3].y, (
float) ymax );
3550 icol1 = pls->
dev_z[ix * ( ny - 1 ) + iy];
3553 if ( icol1 < pls->dev_zmin || icol1 > pls->
dev_zmax )
3556 icol1 = (
PLINT) ( (
float) icol1 / (float) USHRT_MAX * (
float) ( xwd->
ncol1 - 1 ) );
3558 curcolor = xwd->
cmap1[icol1];
3565 if ( ( fabs( Ppts[2].x - Ppts[0].x ) == 1 ) &&
3566 ( fabs( Ppts[3].y - Ppts[1].y ) == 1 ) )
3568 XPutPixel( ximg, (
int) Ppts[0].x, (
int) dev->
height - 1 - (
int) Ppts[0].y, (
unsigned long) curcolor.pixel );
3574 for ( ky = (
int) Ppts[1].y; ky < (int) Ppts[3].y; ky++ )
3575 for ( kx = (
int) Ppts[0].x; kx < (int) Ppts[2].x; kx++ )
3576 XPutPixel( ximg, kx, (
int) dev->
height - 1 - ky, (
unsigned int) curcolor.pixel );
3583 blt = Ppts[0].y - mlr * Ppts[0].x;
3584 brb = Ppts[2].y - mlr * Ppts[2].x;
3586 brt = Ppts[2].y - mtb * Ppts[2].x;
3587 blb = Ppts[0].y - mtb * Ppts[0].x;
3589 for ( ky = (
int) Ppts[1].y; ky < (int) Ppts[3].y; ky++ )
3591 left =
MAX( ( ( (
float) ky - blt ) / mlr ), ( ( (
float) ky - blb ) / mtb ) );
3592 right =
MIN( ( ( (
float) ky - brt ) / mtb ), ( ( (
float) ky - brb ) / mlr ) );
3593 for ( kx = (
int) Ppts[0].x; kx < (int) Ppts[2].x; kx++ )
3595 if ( kx >= rint( left ) && kx <= rint( right ) )
3597 XPutPixel( ximg, kx, (
int) dev->
height - 1 - ky, (
unsigned int) curcolor.pixel );
3613 XDestroyImage( ximg );
int plParseDrvOpts(DrvOpt *acc_opt)
void(* plD_line_fp)(struct PLStream_struct *, short, short, short, short)
#define PLESC_DOUBLEBUFFERING_ENABLE
#define PLESC_DOUBLEBUFFERING_QUERY
void(* ButtonEH)(PLGraphicsIn *gin, void *ButtonEH_data, int *exit_eventloop)
void(* plD_eop_fp)(struct PLStream_struct *)
void PLFLT PLINT PLINT PLFLT PLFLT PLFLT PLFLT PLINT PLINT PLINT PLFLT PLFLT PLINT PLFLT PLINT const PLINT const char *const PLINT nx
void(* plD_state_fp)(struct PLStream_struct *, PLINT)
void(* plD_tidy_fp)(struct PLStream_struct *)
#define PLESC_DOUBLEBUFFERING
void plGinInit(PLGraphicsIn *gin)
void plcol_interp(PLStream *pls, PLColor *newcolor, int i, int ncol)
void(* LocateEH)(PLGraphicsIn *gin, void *LocateEH_data, int *locate_mode)
void PLFLT PLINT PLINT PLFLT x
for(i=0;i< nx;i++) if(n_values[i]< ny) ny
void(* plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT)
static void CreateXhairs(PlFrame *)
void(* plD_esc_fp)(struct PLStream_struct *, PLINT, void *)
int plTranslateCursor(PLGraphicsIn *plg)
static void DestroyXhairs(PlFrame *)
void(* plD_bop_fp)(struct PLStream_struct *)
#define PLPLOT_MUTEX_RECURSIVE
void PLFLT PLINT PLINT PLFLT PLFLT y
static void DrawXhairs(PlFrame *, int, int)
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
#define PLDLLIMPEXP_DRIVER
void plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
PLDLLIMPEXP_DRIVER void plD_dispatch_init_xw(PLDispatchTable *pdt)
void plabort(const char *errormsg)
static void UpdateXhairs(PlFrame *)
void plRemakePlot(PLStream *pls)
void plwarn(const char *errormsg)
#define PLESC_DOUBLEBUFFERING_DISABLE
void(* KeyEH)(PLGraphicsIn *gin, void *KeyEH_data, int *exit_eventloop)
static const char * display
void(* MasterEH)(PLStream *, XEvent *)
dx
if { $zoomopts($this,1) == 0 } then {
plD_polyline_fp pl_polyline
void(* plD_init_fp)(struct PLStream_struct *)
void plexit(const char *errormsg)