36 #ifdef PL_HAVE_PTHREAD
39 int pthread_mutexattr_settype( pthread_mutexattr_t *attr,
int kind );
40 static void events_thread(
void *
pls );
41 static pthread_mutex_t events_mutex;
42 static int already = 0;
46 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_xwin =
"xwin:X-Window (Xlib):1:xwin:5:xw\n";
51 static int nobuffered = 0;
54 static int noinitcolors = 0;
57 static int defaultvisual = 1;
59 static int usepthreads = 1;
81 #define LOCATE_INVOKED_VIA_API 1
82 #define LOCATE_INVOKED_VIA_DRIVER 2
105 #define CCMAP_XWM_COLORS 70
107 #define RWMAP_CMAP1_COLORS 50
108 #define RWMAP_MAX_COLORS 256
110 #define ROMAP_CMAP1_COLORS 50
111 #define TC_CMAP1_COLORS 200
116 static int sxwm_colors_set;
117 static XColor sxwm_colors[RWMAP_MAX_COLORS];
130 void plD_line_xw(
PLStream *,
short,
short,
short,
short );
152 static int AreWeGrayscale( Display *
display );
162 static void MasterEH(
PLStream *
pls, XEvent *event );
163 static void ClientEH(
PLStream *
pls, XEvent *event );
164 static void ExposeEH(
PLStream *
pls, XEvent *event );
165 static void ResizeEH(
PLStream *
pls, XEvent *event );
166 static void MotionEH(
PLStream *
pls, XEvent *event );
167 static void EnterEH(
PLStream *
pls, XEvent *event );
168 static void LeaveEH(
PLStream *
pls, XEvent *event );
170 static void ButtonEH(
PLStream *
pls, XEvent *event );
171 static void LookupXKeyEvent(
PLStream *
pls, XEvent *event );
172 static void LookupXButtonEvent(
PLStream *
pls, XEvent *event );
205 static void SaveColormap( Display *
display, Colormap colormap );
207 static void PLColor_to_XColor(
PLColor *plcolor, XColor *xcolor );
208 static void PLColor_from_XColor(
PLColor *plcolor, XColor *xcolor );
211 {
"nobuffered",
DRV_INT, &nobuffered,
"Sets unbuffered operation (0|1)" },
212 {
"noinitcolors",
DRV_INT, &noinitcolors,
"Sets cmap0 allocation (0|1)" },
213 {
"defvis",
DRV_INT, &defaultvisual,
"Use the Default Visual (0|1)" },
214 {
"usepth",
DRV_INT, &usepthreads,
"Use pthreads (0|1)" },
215 { NULL,
DRV_INT, NULL, NULL } };
219 #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 );
493 #ifdef PL_HAVE_PTHREAD
495 pthread_mutex_unlock( &events_mutex );
513 #ifdef PL_HAVE_PTHREAD
515 pthread_mutex_lock( &events_mutex );
522 XSetWindowBackground( xwd->display, dev->
window, dev->
bgcolor.pixel );
523 XSetBackground( xwd->display, dev->
gc, dev->
bgcolor.pixel );
524 XClearWindow( xwd->display, dev->
window );
528 XSetForeground( xwd->display, dev->
gc, dev->
bgcolor.pixel );
529 XFillRectangle( xwd->display, dev->
pixmap, dev->
gc, 0, 0,
531 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
533 XSync( xwd->display, 0 );
536 #ifdef PL_HAVE_PTHREAD
538 pthread_mutex_unlock( &events_mutex );
556 #ifdef PL_HAVE_PTHREAD
559 pthread_mutex_lock( &events_mutex );
560 if ( pthread_cancel( dev->updater ) == 0 )
561 pthread_join( dev->updater, NULL );
563 pthread_mutex_unlock( &events_mutex );
564 if ( --already == 0 )
565 pthread_mutex_destroy( &events_mutex );
571 XDestroyWindow( xwd->display, dev->
window );
573 XFreePixmap( xwd->display, dev->
pixmap );
574 XFlush( xwd->display );
578 if ( xwd->nstreams == 0 )
580 int ixwd = xwd->ixwd;
581 XFreeGC( xwd->display, dev->
gc );
582 XFreeGC( xwd->display, xwd->gcXor );
583 XCloseDisplay( xwd->display );
605 #ifdef PL_HAVE_PTHREAD
607 pthread_mutex_lock( &events_mutex );
613 #ifdef PL_HAVE_PTHREAD
615 pthread_mutex_unlock( &events_mutex );
633 #ifdef PL_HAVE_PTHREAD
635 pthread_mutex_lock( &events_mutex );
638 CheckForEvents( pls );
643 XSetLineAttributes( xwd->display, dev->
gc, (
unsigned int) pls->
width,
644 LineSolid, CapRound, JoinMiter );
648 int icol0 = pls->
icol0;
654 if ( !XAllocColor( xwd->display, xwd->map, &dev->
curcolor ) )
656 fprintf( stderr,
"Warning: could not allocate color\n" );
657 dev->
curcolor.pixel = xwd->fgcolor.pixel;
664 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
669 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
677 if ( xwd->ncol1 == 0 )
680 if ( xwd->ncol1 < 2 )
683 icol1 = ( pls->
icol1 * ( xwd->ncol1 - 1 ) ) / ( pls->
ncol1 - 1 );
689 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
696 if ( pls->
ncol0 != xwd->ncol0 )
706 #ifdef PL_HAVE_PTHREAD
708 pthread_mutex_unlock( &events_mutex );
747 #ifdef PL_HAVE_PTHREAD
749 pthread_mutex_lock( &events_mutex );
763 FillPolygonCmd( pls );
770 XFlush( xwd->display );
786 XorMod( pls, (
PLINT *) ptr );
798 imageops( pls, (
PLINT *) ptr );
802 PLColor_to_XColor( &pls->
tmpcolor, (XColor *) ptr );
806 PLColor_from_XColor( &pls->
tmpcolor, (XColor *) ptr );
818 #ifdef PL_HAVE_PTHREAD
820 pthread_mutex_unlock( &events_mutex );
849 XNextEvent( xwd->display, &event );
850 MasterEH( pls, &event );
878 pts = (XPoint *) malloc(
sizeof ( XPoint ) * (size_t) ( pls->
dev_npts ) );
885 CheckForEvents( pls );
887 for ( i = 0; i < pls->
dev_npts; i++ )
889 pts[i].x = (short) ( dev->
xscale * pls->
dev_x[i] );
896 XFillPolygon( xwd->display, dev->
window, dev->
gc,
897 pts, pls->
dev_npts, Complex, CoordModeOrigin );
900 XFillPolygon( xwd->display, dev->
pixmap, dev->
gc,
901 pts, pls->
dev_npts, Complex, CoordModeOrigin );
908 XSetForeground( xwd->display, dev->
gc, xwd->fgcolor.pixel );
917 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
947 if ( pls->
dev != NULL )
948 plwarn(
"OpenXwin: device pointer is already set" );
950 pls->
dev = calloc( 1, (
size_t)
sizeof (
XwDev ) );
951 if ( pls->
dev == NULL )
952 plexit(
"plD_init_xw: Out of memory." );
966 if ( xwDisplay[i] == NULL )
972 dev->
xwd = xwDisplay[i];
979 else if ( strcmp( xwDisplay[i]->displayName, pls->
FileName ) == 0 )
981 dev->
xwd = xwDisplay[i];
988 if ( dev->
xwd == NULL )
991 if ( dev->
xwd == NULL )
992 plexit(
"Init: Out of memory." );
996 if ( xwDisplay[i] == NULL )
999 if ( i == PLXDISPLAYS )
1000 plexit(
"Init: Out of xwDisplay's." );
1008 if ( !XInitThreads() )
1009 plexit(
"xwin: XInitThreads() not successful." );
1014 plexit(
"Can't open display" );
1019 XSynchronize( xwd->
display, 1 );
1041 xwd->
cmap0 = (XColor *) calloc( (
size_t) ( pls->
ncol0 ),
sizeof ( XColor ) );
1042 if ( xwd->
cmap0 == 0 )
1043 plexit(
"couldn't allocate space for cmap0 colors" );
1099 if ( noinitcolors == 0 )
1115 gcValues.background = xwd->
cmap0[0].pixel;
1116 gcValues.foreground = 0xFF;
1117 gcValues.function = GXxor;
1118 mask = GCForeground | GCBackground | GCFunction;
1125 (void) XGetGeometry( xwd->
display, dev->
window, &root, &x, &y,
1148 CreatePixmap( pls );
1159 XSetFillRule( xwd->
display, dev->
gc, EvenOddRule );
1161 XSetFillRule( xwd->
display, dev->
gc, WindingRule );
1184 U_INT width, height, border, depth;
1190 (void) XGetGeometry( xwd->
display, DefaultRootWindow( xwd->
display ),
1191 &root, &x, &y, &width, &height, &border, &depth );
1198 hint.flags |= PSize;
1200 hint.flags |= USSize;
1207 if ( pls->
xlength > (
short) width )
1209 if ( pls->
ylength > (
short) height )
1212 hint.width = (int) pls->
xlength;
1213 hint.height = (
int) pls->
ylength;
1221 hint.flags |= USPosition;
1235 DefaultRootWindow( xwd->
display ),
1236 hint.x, hint.y, (
unsigned int) hint.width, (
unsigned int) hint.height,
1238 InputOutput, xwd->
visual,
1242 None, 0, 0, &hint );
1267 StructureNotifyMask;
1275 Atom wmDelete = XInternAtom( xwd->
display,
"WM_DELETE_WINDOW", False );
1284 if ( event.type == Expose )
1287 ExposureMask, &event ) )
1313 XNextEvent( xwd->
display, &event );
1314 MasterEH( pls, &event );
1340 #ifdef PL_HAVE_PTHREAD
1342 events_thread(
void *pls )
1350 struct timespec delay;
1371 event_mask = ExposureMask | StructureNotifyMask;
1374 sigemptyset( &set );
1376 sigaddset( &set, SIGINT );
1378 sigprocmask( SIG_BLOCK, &set, NULL );
1380 pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
1381 pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
1384 delay.tv_nsec = 10000000;
1388 pthread_mutex_lock( &events_mutex );
1394 while ( XCheckWindowEvent( xwd->
display, dev->
window, event_mask, &event ) )
1403 switch ( event.type )
1406 ExposeEH( lpls, &event );
1408 case ConfigureNotify:
1409 ResizeEH( lpls, &event );
1416 pthread_mutex_unlock( &events_mutex );
1417 nanosleep( &delay, NULL );
1449 HandleEvents( pls );
1468 ClientMessage, &event ) ||
1471 MasterEH( pls, &event );
1491 MasterEH(
PLStream *pls, XEvent *event )
1498 switch ( event->type )
1501 KeyEH( pls, event );
1505 ButtonEH( pls, event );
1509 ExposeEH( pls, event );
1512 case ConfigureNotify:
1513 ResizeEH( pls, event );
1517 if ( event->xmotion.state )
1518 ButtonEH( pls, event );
1519 MotionEH( pls, event );
1523 EnterEH( pls, event );
1527 LeaveEH( pls, event );
1531 ClientEH( pls, event );
1543 ClientEH(
PLStream *pls, XEvent *event )
1548 if ( (Atom)
event->xclient.data.l[0] == XInternAtom( xwd->
display,
"WM_DELETE_WINDOW", False ) )
1565 KeyEH(
PLStream *pls, XEvent *event )
1571 LookupXKeyEvent( pls, event );
1585 ButtonEH(
PLStream *pls, XEvent *event )
1591 LookupXButtonEvent( pls, event );
1593 LocateButton( pls );
1595 ProcessButton( pls );
1620 LookupXKeyEvent(
PLStream *pls, XEvent *event )
1624 XKeyEvent *keyEvent = (XKeyEvent *) event;
1629 gin->
pX = keyEvent->x;
1630 gin->
pY = keyEvent->y;
1634 gin->
state = keyEvent->state;
1636 nchars = XLookupString( keyEvent, gin->
string, ncmax, &keysym, &cs );
1637 gin->
string[nchars] =
'\0';
1639 pldebug(
"LookupXKeyEvent",
1640 "Keysym %x, translation: %s\n", keysym, gin->
string );
1650 gin->
keysym = 0xFF & keysym;
1654 gin->
keysym = (
unsigned int) keysym;
1665 LookupXButtonEvent(
PLStream *pls, XEvent *event )
1669 XButtonEvent *buttonEvent = (XButtonEvent *) event;
1671 pldebug(
"LookupXButtonEvent",
1672 "Button: %d, x: %d, y: %d\n",
1673 buttonEvent->button, buttonEvent->x, buttonEvent->y );
1675 gin->
pX = buttonEvent->x;
1676 gin->
pY = buttonEvent->y;
1678 gin->
dY = 1.0 - (
PLFLT) buttonEvent->y / ( dev->
height - 1 );
1680 gin->
button = buttonEvent->button;
1681 gin->
state = buttonEvent->state;
1702 if ( pls->
KeyEH != NULL )
1794 else if ( IsModifierKey( gin->
keysym ) )
1801 else if ( IsCursorKey( gin->
keysym ) )
1803 int x1, y1, dx = 0, dy = 0;
1804 int xmin = 0, xmax = (int) dev->
width - 1, ymin = 0, ymax = (
int) dev->
height - 1;
1826 if ( gin->
state & 0x01 )
1834 if ( gin->
state & 0x02 )
1842 if ( gin->
state & 0x04 )
1850 if ( gin->
state & 0x08 )
1862 dx = xmin - gin->
pX;
1864 dy = ymin - gin->
pY;
1866 dx = xmax - gin->
pX;
1868 dy = ymax - gin->
pY;
1872 XWarpPointer( xwd->
display, dev->
window, None, 0, 0, 0, 0, dx, dy );
1956 if ( dev->
locate_mode == LOCATE_INVOKED_VIA_DRIVER )
1960 printf(
"%f %f %c\n", gin->
wX, gin->
wY, gin->
keysym );
1962 printf(
"%f %f 0x%02x\n", gin->
wX, gin->
wY, gin->
keysym );
1985 MotionEH(
PLStream *pls, XEvent *event )
1988 XMotionEvent *motionEvent = (XMotionEvent *) event;
1992 DrawXhairs( pls, motionEvent->x, motionEvent->y );
2004 EnterEH(
PLStream *pls, XEvent *event )
2007 XCrossingEvent *crossingEvent = (XCrossingEvent *) event;
2009 DrawXhairs( pls, crossingEvent->x, crossingEvent->y );
2042 int root_x, root_y, win_x, win_y;
2056 if ( XQueryPointer( xwd->
display, dev->
window, &root, &child,
2057 &root_x, &root_y, &win_x, &win_y, &mask ) )
2059 if ( win_x >= 0 && win_x < (
int) dev->
width &&
2060 win_y >= 0 && win_y < (
int) dev->
height )
2071 PointerMotionMask, &event ) )
2076 dev->
event_mask |= PointerMotionMask | EnterWindowMask | LeaveWindowMask;
2099 ~PointerMotionMask & ~EnterWindowMask & ~LeaveWindowMask;
2119 int xmin = 0, xmax = (
int) dev->
width - 1;
2120 int ymin = 0, ymax = (int) dev->
height - 1;
2125 dev->
xhair_x[0].x = (short) xmin; dev->
xhair_x[0].y = (short) y0;
2126 dev->
xhair_x[1].x = (short) xmax; dev->
xhair_x[1].y = (short) y0;
2128 dev->
xhair_y[0].x = (short) x0; dev->
xhair_y[0].y = (short) ymin;
2129 dev->
xhair_y[1].x = (short) x0; dev->
xhair_y[1].y = (short) ymax;
2161 ExposeEH(
PLStream *pls, XEvent *event )
2165 XExposeEvent *exposeEvent = (XExposeEvent *) event;
2171 pldebug(
"ExposeEH",
2172 "x = %d, y = %d, width = %d, height = %d, count = %d, pending = %d\n",
2173 exposeEvent->x, exposeEvent->y,
2174 exposeEvent->width, exposeEvent->height,
2175 exposeEvent->count, XPending( xwd->
display ) );
2186 ExposeCmd( pls, NULL );
2192 pldis.
x = (
unsigned int) exposeEvent->x;
2193 pldis.
y = (
unsigned int) exposeEvent->y;
2194 pldis.
width = (
unsigned int) exposeEvent->width;
2195 pldis.
height = (
unsigned int) exposeEvent->height;
2197 ExposeCmd( pls, &pldis );
2205 ExposureMask | StructureNotifyMask, event ) )
2217 ResizeEH(
PLStream *pls, XEvent *event )
2221 XConfigureEvent *configEvent = (XConfigureEvent *) event;
2226 pldis.
width = (
unsigned int) configEvent->width;
2227 pldis.
height = (
unsigned int) configEvent->height;
2234 pldebug(
"ResizeEH",
2235 "x = %d, y = %d, pending = %d\n",
2236 configEvent->width, configEvent->height, XPending( xwd->
display ) );
2240 ResizeCmd( pls, &pldis );
2251 ExposureMask | StructureNotifyMask, event ) )
2268 unsigned int width, height;
2276 plwarn(
"ExposeCmd: Illegal call -- driver uninitialized" );
2282 if ( pldis == NULL )
2293 width = pldis->
width;
2304 x, y, width, height, x, y );
2310 int x0 = x, x1 = x + (int) width, y0 = y, y1 = y + (
int) height;
2311 pts[0].x = (
short) x0; pts[0].y = (
short) y0;
2312 pts[1].x = (
short) x1; pts[1].y = (
short) y0;
2313 pts[2].x = (
short) x1; pts[2].y = (
short) y1;
2314 pts[3].x = (
short) x0; pts[3].y = (
short) y1;
2315 pts[4].x = (
short) x0; pts[4].y = (
short) y0;
2317 XDrawLines( xwd->
display, dev->window, dev->gc, pts, 5,
2348 plwarn(
"ResizeCmd: Illegal call -- driver uninitialized" );
2354 if ( pldis == NULL )
2356 plwarn(
"ResizeCmd: Illegal call -- window pointer uninitialized" );
2391 CreatePixmap( pls );
2453 printf(
"Unrecognized buffering request ignored.\n" );
2478 plwarn(
"RedrawCmd: Illegal call -- driver uninitialized" );
2519 static unsigned char CreatePixmapStatus;
2522 CreatePixmapErrorHandler( Display *
display, XErrorEvent *
error )
2524 CreatePixmapStatus = error->error_code;
2525 if ( error->error_code != BadAlloc )
2528 XGetErrorText( display, error->error_code, buffer, 256 );
2529 fprintf( stderr,
"Error in XCreatePixmap: %s.\n", buffer );
2547 int ( *oldErrorHandler )( Display *, XErrorEvent * );
2549 oldErrorHandler = XSetErrorHandler( CreatePixmapErrorHandler );
2551 CreatePixmapStatus = Success;
2552 pldebug(
"CreatePixmap",
2553 "creating pixmap: width = %d, height = %d, depth = %d\n",
2559 if ( CreatePixmapStatus != Success )
2564 fprintf( stderr,
"\n\
2565 Warning: pixmap could not be allocated (insufficient memory on server).\n\
2566 Driver will redraw the entire plot to handle expose events.\n" );
2569 XSetErrorHandler( oldErrorHandler );
2588 int visuals_matched = 0;
2592 if ( !defaultvisual )
2594 XVisualInfo vTemplate, *visualList;
2598 vTemplate.screen = xwd->
screen;
2599 vTemplate.depth = 8;
2601 visualList = XGetVisualInfo( xwd->
display,
2602 VisualScreenMask | VisualDepthMask,
2603 &vTemplate, &visuals_matched );
2605 #ifdef HACK_STATICCOLOR
2606 if ( visuals_matched )
2609 printf(
"visuals_matched = %d\n", visuals_matched );
2610 for ( i = 0; i < visuals_matched && !found; i++ )
2612 Visual *v = visualList[i].visual;
2613 printf(
"Checking visual %d: ", i );
2617 printf(
"PseudoColor\n" );
2620 printf(
"GrayScale\n" );
2623 printf(
"DirectColor\n" );
2626 printf(
"TrueColor\n" );
2629 printf(
"StaticColor\n" );
2632 printf(
"StaticGray\n" );
2635 printf(
"Unknown.\n" );
2638 if ( v->class == StaticColor )
2641 xwd->
depth = visualList[i].depth;
2647 plexit(
"Unable to get a StaticColor visual." );
2649 printf(
"Found StaticColor visual, depth=%d\n", xwd->
depth );
2652 if ( visuals_matched )
2654 xwd->
visual = visualList->visual;
2655 xwd->
depth = (
unsigned int) vTemplate.depth;
2657 #endif // HACK_STATICCOLOR
2660 if ( !visuals_matched )
2668 switch ( xwd->
visual->class )
2685 fprintf( stderr,
"XVisual class == " );
2686 switch ( xwd->
visual->class )
2689 fprintf( stderr,
"PseudoColor\n" );
2692 fprintf( stderr,
"GrayScale\n" );
2695 fprintf( stderr,
"DirectColor\n" );
2698 fprintf( stderr,
"TrueColor\n" );
2701 fprintf( stderr,
"StaticColor\n" );
2704 fprintf( stderr,
"StaticGray\n" );
2707 fprintf( stderr,
"Unknown.\n" );
2710 fprintf( stderr,
"xwd->rw_cmap = %d\n", xwd->
rw_cmap );
2729 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
2739 XAllocColorCells( xwd->
display, xwd->
map, False,
2740 plane_masks, 0, pixels, 1 ) )
2743 xwd->
cmap0[0].pixel = pixels[0];
2751 fprintf( stderr,
"Downgrading to r/o cmap.\n" );
2758 npixels = RWMAP_MAX_COLORS;
2761 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
2762 plane_masks, 0, pixels, (
unsigned int) npixels ) )
2772 for ( i = 0; i < npixels - 1; i++ )
2774 if ( pixels[i] == ( ~xwd->
cmap0[0].pixel & 0xFF ) )
2780 xwd->
fgcolor.pixel = pixels[i];
2781 for ( j = 0; j < npixels; j++ )
2784 XFreeColors( xwd->
display, xwd->
map, &pixels[j], 1, 0 );
2802 unsigned int gslevbg, gslevfg;
2817 gslevbg = (
unsigned int) ( ( (
long) pls->
cmap0[0].
r +
2819 (
long) pls->
cmap0[0].
b ) / 3 );
2821 PLColor_to_XColor( &pls->
cmap0[0], &xwd->
cmap0[0] );
2833 if ( gslevbg > 0x7F )
2838 fgcolor.
r = fgcolor.
g = fgcolor.
b = (
unsigned char) gslevfg;
2840 PLColor_to_XColor( &fgcolor, &xwd->
fgcolor );
2877 AllocCustomMap( pls );
2917 XColor xwm_colors[RWMAP_MAX_COLORS];
2919 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
2925 for ( i = 0; i < RWMAP_MAX_COLORS; i++ )
2927 xwm_colors[i].pixel = (
unsigned long int) i;
2929 XQueryColors( xwd->
display, xwd->
map, xwm_colors, RWMAP_MAX_COLORS );
2942 xwd->
visual, AllocNone );
2946 npixels = RWMAP_MAX_COLORS;
2949 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
2950 plane_masks, 0, pixels, (
unsigned int) npixels ) )
2954 plexit(
"couldn't allocate any colors" );
2959 for ( i = 0; i < CCMAP_XWM_COLORS; i++ )
2961 XStoreColor( xwd->
display, xwd->
map, &xwm_colors[i] );
2962 pixels[xwm_colors[i].pixel] = 0;
2967 for ( i = 0; i < xwd->
ncol0; i++ )
2970 pixels[xwd->
cmap0[i].pixel] = 0;
2979 if ( sxwm_colors_set )
2981 for ( i = 0; i < RWMAP_MAX_COLORS; i++ )
2983 if ( ( xwm_colors[i].red != sxwm_colors[i].red ) ||
2984 ( xwm_colors[i].green != sxwm_colors[i].green ) ||
2985 ( xwm_colors[i].blue != sxwm_colors[i].blue ) )
2987 if ( pixels[i] != 0 )
2989 XStoreColor( xwd->
display, xwd->
map, &xwm_colors[i] );
2998 for ( i = 0; i < npixels; i++ )
3000 if ( pixels[i] != 0 )
3001 XFreeColors( xwd->
display, xwd->
map, &pixels[i], 1, 0 );
3025 for ( i = 1; i < xwd->
ncol0; i++ )
3027 unsigned long pixel = xwd->
cmap0[i].pixel;
3028 XFreeColors( xwd->
display, xwd->
map, &pixel, 1, 0 );
3035 xwd->
cmap0 = (XColor *)
3036 realloc( xwd->
cmap0, (
size_t) pls->
ncol0 *
sizeof ( XColor ) );
3037 if ( xwd->
cmap0 == 0 )
3038 plexit(
"couldn't allocate space for cmap0 colors" );
3044 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
3048 npixels = pls->
ncol0 - 1;
3051 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
3052 plane_masks, 0, &pixels[1], (
unsigned int) npixels ) )
3056 plexit(
"couldn't allocate any colors" );
3059 xwd->
ncol0 = npixels + 1;
3060 for ( i = 1; i < xwd->
ncol0; i++ )
3062 xwd->
cmap0[i].pixel = pixels[i];
3070 fprintf( stderr,
"Attempting to allocate r/o colors in cmap0.\n" );
3072 for ( i = 1; i < pls->
ncol0; i++ )
3076 PLColor_to_XColor( &pls->
cmap0[i], &c );
3077 r = XAllocColor( xwd->
display, xwd->
map, &c );
3079 fprintf( stderr,
"i=%d, r=%d, pixel=%d\n", i, r, (
int) c.pixel );
3083 xwd->
cmap0[i].pixel = c.pixel;
3087 XColor screen_def, exact_def;
3091 "color alloc failed, trying by name: %s.\n",
3095 r = XAllocNamedColor( xwd->
display, xwd->
map,
3097 &screen_def, &exact_def );
3104 fprintf( stderr,
"yes, got a color by name.\n" );
3106 xwd->
cmap0[i] = screen_def;
3107 xwd->
cmap0[i].pixel = screen_def.pixel;
3111 r = XAllocNamedColor( xwd->
display, xwd->
map,
3113 &screen_def, &exact_def );
3116 xwd->
cmap0[i] = screen_def;
3117 xwd->
cmap0[i].pixel = screen_def.pixel;
3120 printf(
"Can't find white?! Giving up...\n" );
3127 fprintf( stderr,
"Allocated %d colors in cmap0.\n", xwd->
ncol0 );
3144 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
3151 fprintf( stderr,
"Attempting to allocate r/w colors in cmap1.\n" );
3156 npixels =
MAX( 2,
MIN( RWMAP_CMAP1_COLORS, pls->
ncol1 ) );
3159 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
3160 plane_masks, 0, pixels, (
unsigned int) npixels ) )
3170 fprintf( stderr,
"Warning: unable to allocate sufficient colors in cmap1.\n" );
3174 xwd->
ncol1 = npixels;
3176 fprintf( stderr,
"AllocCmap1 (xwin.c): Allocated %d colors in cmap1.\n", npixels );
3182 xwd->
cmap1 = (XColor *) calloc( (
size_t) ( xwd->
ncol1 ),
sizeof ( XColor ) );
3184 plexit(
"couldn't allocate space for cmap1 colors" );
3190 for ( j = i = 0; i < xwd->
ncol1; i++ )
3192 while ( pixels[j] == 0 )
3195 xwd->
cmap1[i].pixel = pixels[j];
3199 if ( j >= xwd->
ncol1 )
3212 fprintf( stderr,
"Attempting to allocate r/o colors in cmap1.\n" );
3214 switch ( xwd->
visual->class )
3217 ncolors = TC_CMAP1_COLORS;
3220 ncolors = ROMAP_CMAP1_COLORS;
3227 xwd->
cmap1 = (XColor *) calloc( (
size_t) ncolors,
sizeof ( XColor ) );
3229 plexit(
"couldn't allocate space for cmap1 colors" );
3232 for ( i = 0; i < ncolors; i++ )
3235 PLColor_to_XColor( &cmap1color, &xcol );
3237 r = XAllocColor( xwd->
display, xwd->
map, &xcol );
3239 fprintf( stderr,
"i=%d, r=%d, pixel=%d\n", i, r, (
int) xcol.pixel );
3241 xwd->
cmap1[i] = xcol;
3249 "Warning: unable to allocate sufficient colors in cmap1\n" );
3254 xwd->
ncol1 = ncolors;
3256 fprintf( stderr,
"AllocCmap1 (xwin.c): Allocated %d colors in cmap1\n", ncolors );
3277 for ( i = 1; i < xwd->
ncol0; i++ )
3279 PLColor_to_XColor( &pls->
cmap0[i], &xwd->
cmap0[i] );
3305 for ( i = 0; i < xwd->
ncol1; i++ )
3308 PLColor_to_XColor( &cmap1color, &xwd->
cmap1[i] );
3324 #define ToXColor( a ) ( ( ( 0xFF & ( a ) ) << 8 ) | ( a ) )
3325 #define ToPLColor( a ) ( ( (U_LONG) a ) >> 8 )
3328 PLColor_to_XColor(
PLColor *plcolor, XColor *xcolor )
3330 xcolor->red = (
short unsigned) ToXColor( plcolor->
r );
3331 xcolor->green = (
short unsigned) ToXColor( plcolor->
g );
3332 xcolor->blue = (
short unsigned) ToXColor( plcolor->
b );
3333 xcolor->flags = DoRed | DoGreen | DoBlue;
3344 PLColor_from_XColor(
PLColor *plcolor, XColor *xcolor )
3346 plcolor->
r = (
unsigned char) ToPLColor( xcolor->red );
3347 plcolor->
g = (
unsigned char) ToPLColor( xcolor->green );
3348 plcolor->
b = (
unsigned char) ToPLColor( xcolor->blue );
3360 AreWeGrayscale( Display *display )
3362 #if defined ( __cplusplus ) || defined ( c_plusplus )
3363 #define THING c_class
3368 XVisualInfo *visuals;
3369 int nitems, i, igray;
3372 visuals = XGetVisualInfo( display, 0, NULL, &nitems );
3376 for ( i = 0; i < nitems; i++ )
3377 if ( ( visuals[i].THING != GrayScale ) &&
3378 ( visuals[i].THING != StaticGray ) )
3405 SaveColormap( Display *display, Colormap colormap )
3412 sxwm_colors_set = 1;
3413 for ( i = 0; i < RWMAP_MAX_COLORS; i++ )
3415 sxwm_colors[i].pixel = i;
3417 XQueryColors( display, colormap, sxwm_colors, RWMAP_MAX_COLORS );
3437 GetImageErrorHandler( Display *display, XErrorEvent *error )
3439 if ( error->error_code != BadMatch )
3442 XGetErrorText( display, error->error_code, buffer, 256 );
3443 fprintf( stderr,
"xwin: Error in XGetImage: %s.\n", buffer );
3460 XImage *ximg = NULL;
3462 PLINT xmin, xmax, ymin, ymax, icol1;
3464 int ( *oldErrorHandler )( Display *, XErrorEvent * );
3467 float blt, brt, brb, blb;
3471 int i, corners[4], r[4] = { 0, 0, 0, 0 };
3478 CheckForEvents( pls );
3489 oldErrorHandler = XSetErrorHandler( GetImageErrorHandler );
3494 AllPlanes, ZPixmap );
3498 AllPlanes, ZPixmap );
3500 XSetErrorHandler( oldErrorHandler );
3504 plabort(
"Can't get image, the window must be partly off-screen, move it to fit screen" );
3508 if ( xwd->
ncol1 == 0 )
3510 if ( xwd->
ncol1 < 2 )
3514 switch ( (
int) ( pls->
diorot - 4. * floor( pls->
diorot / 4. ) ) )
3517 r[0] = 0; r[1] = 1; r[2] = 2; r[3] = 3;
break;
3519 r[0] = 1; r[1] = 2; r[2] = 3; r[3] = 0;
break;
3521 r[0] = 2; r[1] = 3; r[2] = 0; r[3] = 1;
break;
3523 r[0] = 3; r[1] = 0; r[2] = 1; r[3] = 2;
3548 for ( ix = 0; ix < nx - 1; ix++ )
3550 for ( iy = 0; iy < ny - 1; iy++ )
3552 corners[0] = ix * ny + iy;
3553 corners[1] = ( ix + 1 ) * ny + iy;
3554 corners[2] = ( ix + 1 ) * ny + iy + 1;
3555 corners[3] = ix * ny + iy + 1;
3557 for ( i = 0; i < 4; i++ )
3559 Ppts[i].x = (float) ( dev->
xscale * ( pls->
dev_ix[corners[r[i]]] ) );
3560 Ppts[i].y = (float) ( dev->
yscale * ( pls->
dev_iy[corners[r[i]]] ) );
3564 if ( Ppts[0].x >= xmin || Ppts[2].x <= xmax ||
3565 Ppts[1].y >= ymin || Ppts[3].y <= ymax )
3567 Ppts[0].x =
MAX( Ppts[0].x, (
float) xmin );
3568 Ppts[2].x =
MIN( Ppts[2].x, (
float) xmax );
3569 Ppts[1].y =
MAX( Ppts[1].y, (
float) ymin );
3570 Ppts[3].y =
MIN( Ppts[3].y, (
float) ymax );
3573 icol1 = pls->
dev_z[ix * ( ny - 1 ) + iy];
3576 if ( icol1 < pls->dev_zmin || icol1 > pls->
dev_zmax )
3579 icol1 = (
PLINT) ( (
float) icol1 / (float) USHRT_MAX * (
float) ( xwd->
ncol1 - 1 ) );
3581 curcolor = xwd->
cmap1[icol1];
3588 if ( ( fabs( Ppts[2].x - Ppts[0].x ) == 1 ) &&
3589 ( fabs( Ppts[3].y - Ppts[1].y ) == 1 ) )
3591 XPutPixel( ximg, (
int) Ppts[0].x, (
int) dev->
height - 1 - (
int) Ppts[0].y, (
unsigned long) curcolor.pixel );
3597 for ( ky = (
int) Ppts[1].y; ky < (int) Ppts[3].y; ky++ )
3598 for ( kx = (
int) Ppts[0].x; kx < (int) Ppts[2].x; kx++ )
3599 XPutPixel( ximg, kx, (
int) dev->
height - 1 - ky, (
unsigned int) curcolor.pixel );
3606 blt = Ppts[0].y - mlr * Ppts[0].x;
3607 brb = Ppts[2].y - mlr * Ppts[2].x;
3609 brt = Ppts[2].y - mtb * Ppts[2].x;
3610 blb = Ppts[0].y - mtb * Ppts[0].x;
3612 for ( ky = (
int) Ppts[1].y; ky < (int) Ppts[3].y; ky++ )
3614 left =
MAX( ( ( (
float) ky - blt ) / mlr ), ( ( (
float) ky - blb ) / mtb ) );
3615 right =
MIN( ( ( (
float) ky - brt ) / mtb ), ( ( (
float) ky - brb ) / mlr ) );
3616 for ( kx = (
int) Ppts[0].x; kx < (int) Ppts[2].x; kx++ )
3618 if ( kx >= rint( left ) && kx <= rint( right ) )
3620 XPutPixel( ximg, kx, (
int) dev->
height - 1 - ky, (
unsigned int) curcolor.pixel );
3636 XDestroyImage( ximg );
int plParseDrvOpts(DrvOpt *acc_opt)
void(* plD_line_fp)(struct PLStream_struct *, short, short, short, short)
void plexit(PLCHAR_VECTOR errormsg)
#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(* 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)
PLINT plTranslateCursor(PLGraphicsIn *plg)
void(* plD_wait_fp)(struct PLStream_struct *)
void plabort(PLCHAR_VECTOR errormsg)
void(* plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT)
static void CreateXhairs(PlFrame *)
void(* plD_esc_fp)(struct PLStream_struct *, PLINT, void *)
static void DestroyXhairs(PlFrame *)
#define PLPLOT_MUTEX_RECURSIVE
void(* plD_bop_fp)(struct PLStream_struct *)
static void DrawXhairs(PlFrame *, int, int)
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
#define PLDLLIMPEXP_DRIVER
static PLStream * pls[PL_NSTREAMS]
void plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
PLDLLIMPEXP_DRIVER void plD_dispatch_init_xw(PLDispatchTable *pdt)
static void UpdateXhairs(PlFrame *)
void plRemakePlot(PLStream *pls)
#define PLESC_DOUBLEBUFFERING_DISABLE
void(* KeyEH)(PLGraphicsIn *gin, void *KeyEH_data, int *exit_eventloop)
void plwarn(PLCHAR_VECTOR errormsg)
static const char * display
void(* MasterEH)(PLStream *, XEvent *)
plD_polyline_fp pl_polyline
void(* plD_init_fp)(struct PLStream_struct *)