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 );
140 static void OpenXwin(
PLStream *pls );
142 static void InitMain(
PLStream *pls );
143 static void InitColors(
PLStream *pls );
144 static void AllocCustomMap(
PLStream *pls );
145 static void AllocCmap0(
PLStream *pls );
146 static void AllocCmap1(
PLStream *pls );
147 static void MapMain(
PLStream *pls );
148 static void CreatePixmap(
PLStream *pls );
149 static void GetVisual(
PLStream *pls );
150 static void AllocBGFG(
PLStream *pls );
151 static int AreWeGrayscale( Display *
display );
155 static void WaitForPage(
PLStream *pls );
156 static void CheckForEvents(
PLStream *pls );
157 static void HandleEvents(
PLStream *pls );
161 static void MasterEH(
PLStream *pls, XEvent *event );
162 static void ClientEH(
PLStream *pls, XEvent *event );
163 static void ExposeEH(
PLStream *pls, XEvent *event );
164 static void ResizeEH(
PLStream *pls, XEvent *event );
165 static void MotionEH(
PLStream *pls, XEvent *event );
166 static void EnterEH(
PLStream *pls, XEvent *event );
167 static void LeaveEH(
PLStream *pls, XEvent *event );
168 static void KeyEH(
PLStream *pls, XEvent *event );
169 static void ButtonEH(
PLStream *pls, XEvent *event );
170 static void LookupXKeyEvent(
PLStream *pls, XEvent *event );
171 static void LookupXButtonEvent(
PLStream *pls, XEvent *event );
173 static void ProcessKey(
PLStream *pls );
174 static void LocateKey(
PLStream *pls );
175 static void ProcessButton(
PLStream *pls );
176 static void LocateButton(
PLStream *pls );
177 static void Locate(
PLStream *pls );
189 static void RedrawCmd(
PLStream *pls );
193 static void FillPolygonCmd(
PLStream *pls );
195 static void DrawImage(
PLStream *pls );
199 static void StoreCmap0(
PLStream *pls );
200 static void StoreCmap1(
PLStream *pls );
202 static void SetBGFG(
PLStream *pls );
204 static void SaveColormap( Display *
display, Colormap colormap );
206 static void PLColor_to_XColor(
PLColor *plcolor, XColor *xcolor );
207 static void PLColor_from_XColor(
PLColor *plcolor, XColor *xcolor );
210 {
"nobuffered",
DRV_INT, &nobuffered,
"Sets unbuffered operation (0|1)" },
211 {
"noinitcolors",
DRV_INT, &noinitcolors,
"Sets cmap0 allocation (0|1)" },
212 {
"defvis",
DRV_INT, &defaultvisual,
"Use the Default Visual (0|1)" },
213 {
"usepth",
DRV_INT, &usepthreads,
"Use pthreads (0|1)" },
214 { NULL,
DRV_INT, NULL, NULL } };
218 #ifndef ENABLE_DYNDRIVERS
260 #ifndef PL_HAVE_PTHREAD
266 #ifndef PL_HAVE_PTHREAD
268 plwarn(
"You said you want pthreads, but they are not available." );
276 if ( pls->
dev == NULL )
285 dev->
xlen = (short) ( xmax - xmin );
286 dev->
ylen = (short) ( ymax - ymin );
305 #ifdef PL_HAVE_PTHREAD
308 pthread_mutexattr_t mutexatt;
309 pthread_attr_t pthattr;
313 pthread_mutexattr_init( &mutexatt );
315 plexit(
"xwin: pthread_mutexattr_settype() failed!\n" );
317 pthread_mutex_init( &events_mutex, &mutexatt );
322 pthread_mutex_lock( &events_mutex );
324 pthread_mutex_unlock( &events_mutex );
327 pthread_attr_init( &pthattr );
328 pthread_attr_setdetachstate( &pthattr, PTHREAD_CREATE_JOINABLE );
330 if ( pthread_create( &( dev->updater ), &pthattr, (
void *( * )(
void * ) ) & events_thread, (
void *) pls ) )
332 pthread_mutex_lock( &events_mutex );
334 pthread_mutex_unlock( &events_mutex );
338 pthread_mutex_destroy( &events_mutex );
339 plexit(
"xwin: pthread_create() failed!\n" );
342 plwarn(
"xwin: couldn't create thread for this plot window!\n" );
355 plD_line_xw(
PLStream *pls,
short x1a,
short y1a,
short x2a,
short y2a )
360 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
364 #ifdef PL_HAVE_PTHREAD
366 pthread_mutex_lock( &events_mutex );
369 CheckForEvents( pls );
374 x1 = (int) ( x1 * dev->
xscale );
375 x2 = (int) ( x2 * dev->
xscale );
376 y1 = (int) ( y1 * dev->
yscale );
377 y2 = (int) ( y2 * dev->
yscale );
380 XDrawLine( xwd->display, dev->
window, dev->
gc, x1, y1, x2, y2 );
383 XDrawLine( xwd->display, dev->
pixmap, dev->
gc, x1, y1, x2, y2 );
385 #ifdef PL_HAVE_PTHREAD
387 pthread_mutex_unlock( &events_mutex );
404 XSetFunction( xwd->display, dev->
gc, GXcopy );
406 XSetFunction( xwd->display, dev->
gc, GXxor );
416 plD_polyline_xw(
PLStream *pls,
short *xa,
short *ya,
PLINT npts )
427 pts = (XPoint *) malloc(
sizeof ( XPoint ) * (size_t) npts );
436 #ifdef PL_HAVE_PTHREAD
438 pthread_mutex_lock( &events_mutex );
441 CheckForEvents( pls );
443 for ( i = 0; i < npts; i++ )
445 pts[i].x = (short) ( dev->
xscale * xa[i] );
446 pts[i].y = (short) ( dev->
yscale * ( dev->
ylen - ya[i] ) );
450 XDrawLines( xwd->display, dev->
window, dev->
gc, pts, npts,
454 XDrawLines( xwd->display, dev->
pixmap, dev->
gc, pts, npts,
457 #ifdef PL_HAVE_PTHREAD
459 pthread_mutex_unlock( &events_mutex );
482 #ifdef PL_HAVE_PTHREAD
484 pthread_mutex_lock( &events_mutex );
487 XFlush( xwd->display );
489 ExposeCmd( pls, NULL );
494 #ifdef PL_HAVE_PTHREAD
496 pthread_mutex_unlock( &events_mutex );
514 #ifdef PL_HAVE_PTHREAD
516 pthread_mutex_lock( &events_mutex );
523 XSetWindowBackground( xwd->display, dev->
window, dev->
bgcolor.pixel );
524 XSetBackground( xwd->display, dev->
gc, dev->
bgcolor.pixel );
525 XClearWindow( xwd->display, dev->
window );
529 XSetForeground( xwd->display, dev->
gc, dev->
bgcolor.pixel );
530 XFillRectangle( xwd->display, dev->
pixmap, dev->
gc, 0, 0,
532 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
534 XSync( xwd->display, 0 );
537 #ifdef PL_HAVE_PTHREAD
539 pthread_mutex_unlock( &events_mutex );
557 #ifdef PL_HAVE_PTHREAD
560 pthread_mutex_lock( &events_mutex );
561 if ( pthread_cancel( dev->updater ) == 0 )
562 pthread_join( dev->updater, NULL );
564 pthread_mutex_unlock( &events_mutex );
565 if ( --already == 0 )
566 pthread_mutex_destroy( &events_mutex );
572 XDestroyWindow( xwd->display, dev->
window );
574 XFreePixmap( xwd->display, dev->
pixmap );
575 XFlush( xwd->display );
579 if ( xwd->nstreams == 0 )
581 int ixwd = xwd->ixwd;
582 XFreeGC( xwd->display, dev->
gc );
583 XFreeGC( xwd->display, xwd->gcXor );
584 XCloseDisplay( xwd->display );
608 #ifdef PL_HAVE_PTHREAD
610 pthread_mutex_lock( &events_mutex );
613 CheckForEvents( pls );
618 XSetLineAttributes( xwd->display, dev->
gc, (
unsigned int) pls->
width,
619 LineSolid, CapRound, JoinMiter );
623 int icol0 = pls->
icol0;
629 if ( !XAllocColor( xwd->display, xwd->map, &dev->
curcolor ) )
631 fprintf( stderr,
"Warning: could not allocate color\n" );
632 dev->
curcolor.pixel = xwd->fgcolor.pixel;
639 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
644 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
652 if ( xwd->ncol1 == 0 )
655 if ( xwd->ncol1 < 2 )
658 icol1 = ( pls->
icol1 * ( xwd->ncol1 - 1 ) ) / ( pls->
ncol1 - 1 );
664 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
671 if ( pls->
ncol0 != xwd->ncol0 )
681 #ifdef PL_HAVE_PTHREAD
683 pthread_mutex_unlock( &events_mutex );
722 #ifdef PL_HAVE_PTHREAD
724 pthread_mutex_lock( &events_mutex );
738 FillPolygonCmd( pls );
745 XFlush( xwd->display );
761 XorMod( pls, (
PLINT *) ptr );
773 imageops( pls, (
PLINT *) ptr );
777 PLColor_to_XColor( &pls->
tmpcolor, (XColor *) ptr );
781 PLColor_from_XColor( &pls->
tmpcolor, (XColor *) ptr );
793 #ifdef PL_HAVE_PTHREAD
795 pthread_mutex_unlock( &events_mutex );
824 XNextEvent( xwd->display, &event );
825 MasterEH( pls, &event );
853 pts = (XPoint *) malloc(
sizeof ( XPoint ) * (size_t) ( pls->
dev_npts ) );
860 CheckForEvents( pls );
862 for ( i = 0; i < pls->
dev_npts; i++ )
864 pts[i].x = (short) ( dev->
xscale * pls->
dev_x[i] );
871 XFillPolygon( xwd->display, dev->
window, dev->
gc,
872 pts, pls->
dev_npts, Complex, CoordModeOrigin );
875 XFillPolygon( xwd->display, dev->
pixmap, dev->
gc,
876 pts, pls->
dev_npts, Complex, CoordModeOrigin );
883 XSetForeground( xwd->display, dev->
gc, xwd->fgcolor.pixel );
892 XSetForeground( xwd->display, dev->
gc, dev->
curcolor.pixel );
922 if ( pls->
dev != NULL )
923 plwarn(
"OpenXwin: device pointer is already set" );
925 pls->
dev = calloc( 1, (
size_t)
sizeof (
XwDev ) );
926 if ( pls->
dev == NULL )
927 plexit(
"plD_init_xw: Out of memory." );
941 if ( xwDisplay[i] == NULL )
947 dev->
xwd = xwDisplay[i];
954 else if ( strcmp( xwDisplay[i]->displayName, pls->
FileName ) == 0 )
956 dev->
xwd = xwDisplay[i];
963 if ( dev->
xwd == NULL )
966 if ( dev->
xwd == NULL )
967 plexit(
"Init: Out of memory." );
971 if ( xwDisplay[i] == NULL )
974 if ( i == PLXDISPLAYS )
975 plexit(
"Init: Out of xwDisplay's." );
983 if ( !XInitThreads() )
984 plexit(
"xwin: XInitThreads() not successful." );
989 plexit(
"Can't open display" );
994 XSynchronize( xwd->
display, 1 );
1016 xwd->
cmap0 = (XColor *) calloc( (
size_t) ( pls->
ncol0 ),
sizeof ( XColor ) );
1017 if ( xwd->
cmap0 == 0 )
1018 plexit(
"couldn't allocate space for cmap0 colors" );
1074 if ( noinitcolors == 0 )
1090 gcValues.background = xwd->
cmap0[0].pixel;
1091 gcValues.foreground = 0xFF;
1092 gcValues.function = GXxor;
1093 mask = GCForeground | GCBackground | GCFunction;
1123 CreatePixmap( pls );
1134 XSetFillRule( xwd->
display, dev->
gc, EvenOddRule );
1136 XSetFillRule( xwd->
display, dev->
gc, WindingRule );
1159 U_INT width, height, border, depth;
1166 &root, &x, &y, &width, &height, &border, &depth );
1173 hint.flags |= PSize;
1175 hint.flags |= USSize;
1182 if ( pls->
xlength > (
short) width )
1184 if ( pls->
ylength > (
short) height )
1187 hint.width = (int) pls->
xlength;
1188 hint.height = (
int) pls->
ylength;
1196 hint.flags |= USPosition;
1210 DefaultRootWindow( xwd->
display ),
1211 hint.x, hint.y, (
unsigned int) hint.width, (
unsigned int) hint.height,
1213 InputOutput, xwd->
visual,
1217 None, 0, 0, &hint );
1242 StructureNotifyMask;
1250 Atom wmDelete = XInternAtom( xwd->
display,
"WM_DELETE_WINDOW", False );
1259 if ( event.type == Expose )
1262 ExposureMask, &event ) )
1288 XNextEvent( xwd->
display, &event );
1289 MasterEH( pls, &event );
1315 #ifdef PL_HAVE_PTHREAD
1317 events_thread(
void *pls )
1325 struct timespec delay;
1346 event_mask = ExposureMask | StructureNotifyMask;
1349 sigemptyset( &
set );
1351 sigaddset( &
set, SIGINT );
1353 sigprocmask( SIG_BLOCK, &
set, NULL );
1355 pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
1356 pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
1359 delay.tv_nsec = 10000000;
1363 pthread_mutex_lock( &events_mutex );
1369 while ( XCheckWindowEvent( xwd->
display, dev->
window, event_mask, &event ) )
1378 switch ( event.type )
1381 ExposeEH( lpls, &event );
1383 case ConfigureNotify:
1384 ResizeEH( lpls, &event );
1391 pthread_mutex_unlock( &events_mutex );
1392 nanosleep( &delay, NULL );
1424 HandleEvents( pls );
1443 ClientMessage, &event ) ||
1446 MasterEH( pls, &event );
1466 MasterEH(
PLStream *pls, XEvent *event )
1473 switch ( event->type )
1476 KeyEH( pls, event );
1480 ButtonEH( pls, event );
1484 ExposeEH( pls, event );
1487 case ConfigureNotify:
1488 ResizeEH( pls, event );
1492 if ( event->xmotion.state )
1493 ButtonEH( pls, event );
1494 MotionEH( pls, event );
1498 EnterEH( pls, event );
1502 LeaveEH( pls, event );
1506 ClientEH( pls, event );
1518 ClientEH(
PLStream *pls, XEvent *event )
1523 if ( (Atom)
event->xclient.data.l[0] == XInternAtom( xwd->
display,
"WM_DELETE_WINDOW", False ) )
1540 KeyEH(
PLStream *pls, XEvent *event )
1546 LookupXKeyEvent( pls, event );
1560 ButtonEH(
PLStream *pls, XEvent *event )
1566 LookupXButtonEvent( pls, event );
1568 LocateButton( pls );
1570 ProcessButton( pls );
1595 LookupXKeyEvent(
PLStream *pls, XEvent *event )
1599 XKeyEvent *keyEvent = (XKeyEvent *) event;
1604 gin->
pX = keyEvent->x;
1605 gin->
pY = keyEvent->y;
1609 gin->
state = keyEvent->state;
1611 nchars = XLookupString( keyEvent, gin->
string, ncmax, &keysym, &cs );
1612 gin->
string[nchars] =
'\0';
1614 pldebug(
"LookupXKeyEvent",
1615 "Keysym %x, translation: %s\n", keysym, gin->
string );
1625 gin->
keysym = 0xFF & keysym;
1629 gin->
keysym = (
unsigned int) keysym;
1640 LookupXButtonEvent(
PLStream *pls, XEvent *event )
1644 XButtonEvent *buttonEvent = (XButtonEvent *) event;
1646 pldebug(
"LookupXButtonEvent",
1647 "Button: %d, x: %d, y: %d\n",
1648 buttonEvent->button, buttonEvent->x, buttonEvent->y );
1650 gin->
pX = buttonEvent->x;
1651 gin->
pY = buttonEvent->y;
1653 gin->
dY = 1.0 - (
PLFLT) buttonEvent->y / ( dev->
height - 1 );
1655 gin->
button = buttonEvent->button;
1656 gin->
state = buttonEvent->state;
1677 if ( pls->
KeyEH != NULL )
1769 else if ( IsModifierKey( gin->
keysym ) )
1776 else if ( IsCursorKey( gin->
keysym ) )
1778 int x1, y1,
dx = 0,
dy = 0;
1779 int xmin = 0, xmax = (int) dev->
width - 1, ymin = 0, ymax = (
int) dev->
height - 1;
1801 if ( gin->
state & 0x01 )
1809 if ( gin->
state & 0x02 )
1817 if ( gin->
state & 0x04 )
1825 if ( gin->
state & 0x08 )
1837 dx = xmin - gin->
pX;
1839 dy = ymin - gin->
pY;
1841 dx = xmax - gin->
pX;
1843 dy = ymax - gin->
pY;
1931 if ( dev->
locate_mode == LOCATE_INVOKED_VIA_DRIVER )
1935 printf(
"%f %f %c\n", gin->
wX, gin->
wY, gin->
keysym );
1937 printf(
"%f %f 0x%02x\n", gin->
wX, gin->
wY, gin->
keysym );
1960 MotionEH(
PLStream *pls, XEvent *event )
1963 XMotionEvent *motionEvent = (XMotionEvent *) event;
1967 DrawXhairs( pls, motionEvent->x, motionEvent->y );
1979 EnterEH(
PLStream *pls, XEvent *event )
1982 XCrossingEvent *crossingEvent = (XCrossingEvent *) event;
1984 DrawXhairs( pls, crossingEvent->x, crossingEvent->y );
2017 int root_x, root_y, win_x, win_y;
2031 if ( XQueryPointer( xwd->
display, dev->
window, &root, &child,
2032 &root_x, &root_y, &win_x, &win_y, &mask ) )
2034 if ( win_x >= 0 && win_x < (
int) dev->
width &&
2035 win_y >= 0 && win_y < (
int) dev->
height )
2046 PointerMotionMask, &event ) )
2051 dev->
event_mask |= PointerMotionMask | EnterWindowMask | LeaveWindowMask;
2074 ~PointerMotionMask & ~EnterWindowMask & ~LeaveWindowMask;
2094 int xmin = 0, xmax = (
int) dev->
width - 1;
2095 int ymin = 0, ymax = (int) dev->
height - 1;
2100 dev->
xhair_x[0].x = (short) xmin; dev->
xhair_x[0].y = (short) y0;
2101 dev->
xhair_x[1].x = (short) xmax; dev->
xhair_x[1].y = (short) y0;
2103 dev->
xhair_y[0].x = (short) x0; dev->
xhair_y[0].y = (short) ymin;
2104 dev->
xhair_y[1].x = (short) x0; dev->
xhair_y[1].y = (short) ymax;
2136 ExposeEH(
PLStream *pls, XEvent *event )
2140 XExposeEvent *exposeEvent = (XExposeEvent *) event;
2146 pldebug(
"ExposeEH",
2147 "x = %d, y = %d, width = %d, height = %d, count = %d, pending = %d\n",
2148 exposeEvent->x, exposeEvent->y,
2149 exposeEvent->width, exposeEvent->height,
2150 exposeEvent->count, XPending( xwd->
display ) );
2161 ExposeCmd( pls, NULL );
2167 pldis.
x = (
unsigned int) exposeEvent->x;
2168 pldis.
y = (
unsigned int) exposeEvent->y;
2169 pldis.
width = (
unsigned int) exposeEvent->width;
2170 pldis.
height = (
unsigned int) exposeEvent->height;
2172 ExposeCmd( pls, &pldis );
2180 ExposureMask | StructureNotifyMask, event ) )
2192 ResizeEH(
PLStream *pls, XEvent *event )
2196 XConfigureEvent *configEvent = (XConfigureEvent *) event;
2201 pldis.
width = (
unsigned int) configEvent->width;
2202 pldis.
height = (
unsigned int) configEvent->height;
2209 pldebug(
"ResizeEH",
2210 "x = %d, y = %d, pending = %d\n",
2211 configEvent->width, configEvent->height, XPending( xwd->
display ) );
2215 ResizeCmd( pls, &pldis );
2226 ExposureMask | StructureNotifyMask, event ) )
2243 unsigned int width, height;
2251 plwarn(
"ExposeCmd: Illegal call -- driver uninitialized" );
2257 if ( pldis == NULL )
2268 width = pldis->
width;
2279 x, y, width, height, x, y );
2285 int x0 = x, x1 = x + (int) width, y0 = y, y1 = y + (
int) height;
2286 pts[0].x = (
short) x0; pts[0].y = (
short) y0;
2287 pts[1].x = (
short) x1; pts[1].y = (
short) y0;
2288 pts[2].x = (
short) x1; pts[2].y = (
short) y1;
2289 pts[3].x = (
short) x0; pts[3].y = (
short) y1;
2290 pts[4].x = (
short) x0; pts[4].y = (
short) y0;
2292 XDrawLines( xwd->
display, dev->window, dev->gc, pts, 5,
2323 plwarn(
"ResizeCmd: Illegal call -- driver uninitialized" );
2329 if ( pldis == NULL )
2331 plwarn(
"ResizeCmd: Illegal call -- window pointer uninitialized" );
2366 CreatePixmap( pls );
2428 printf(
"Unrecognized buffering request ignored.\n" );
2453 plwarn(
"RedrawCmd: Illegal call -- driver uninitialized" );
2494 static unsigned char CreatePixmapStatus;
2497 CreatePixmapErrorHandler( Display *
display, XErrorEvent *
error )
2499 CreatePixmapStatus = error->error_code;
2500 if ( error->error_code != BadAlloc )
2503 XGetErrorText( display, error->error_code, buffer, 256 );
2504 fprintf( stderr,
"Error in XCreatePixmap: %s.\n", buffer );
2522 int ( *oldErrorHandler )( Display *, XErrorEvent * );
2524 oldErrorHandler = XSetErrorHandler( CreatePixmapErrorHandler );
2526 CreatePixmapStatus = Success;
2527 pldebug(
"CreatePixmap",
2528 "creating pixmap: width = %d, height = %d, depth = %d\n",
2534 if ( CreatePixmapStatus != Success )
2539 fprintf( stderr,
"\n\
2540 Warning: pixmap could not be allocated (insufficient memory on server).\n\
2541 Driver will redraw the entire plot to handle expose events.\n" );
2544 XSetErrorHandler( oldErrorHandler );
2563 int visuals_matched = 0;
2567 if ( !defaultvisual )
2569 XVisualInfo vTemplate, *visualList;
2573 vTemplate.screen = xwd->
screen;
2574 vTemplate.depth = 8;
2576 visualList = XGetVisualInfo( xwd->
display,
2577 VisualScreenMask | VisualDepthMask,
2578 &vTemplate, &visuals_matched );
2580 #ifdef HACK_STATICCOLOR
2581 if ( visuals_matched )
2584 printf(
"visuals_matched = %d\n", visuals_matched );
2585 for ( i = 0; i < visuals_matched && !found; i++ )
2587 Visual *v = visualList[i].visual;
2588 printf(
"Checking visual %d: ", i );
2592 printf(
"PseudoColor\n" );
2595 printf(
"GrayScale\n" );
2598 printf(
"DirectColor\n" );
2601 printf(
"TrueColor\n" );
2604 printf(
"StaticColor\n" );
2607 printf(
"StaticGray\n" );
2610 printf(
"Unknown.\n" );
2613 if ( v->class == StaticColor )
2616 xwd->
depth = visualList[i].depth;
2622 plexit(
"Unable to get a StaticColor visual." );
2624 printf(
"Found StaticColor visual, depth=%d\n", xwd->
depth );
2627 if ( visuals_matched )
2629 xwd->
visual = visualList->visual;
2630 xwd->
depth = (
unsigned int) vTemplate.depth;
2632 #endif // HACK_STATICCOLOR
2635 if ( !visuals_matched )
2643 switch ( xwd->
visual->class )
2660 fprintf( stderr,
"XVisual class == " );
2661 switch ( xwd->
visual->class )
2664 fprintf( stderr,
"PseudoColor\n" );
2667 fprintf( stderr,
"GrayScale\n" );
2670 fprintf( stderr,
"DirectColor\n" );
2673 fprintf( stderr,
"TrueColor\n" );
2676 fprintf( stderr,
"StaticColor\n" );
2679 fprintf( stderr,
"StaticGray\n" );
2682 fprintf( stderr,
"Unknown.\n" );
2685 fprintf( stderr,
"xwd->rw_cmap = %d\n", xwd->
rw_cmap );
2704 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
2714 XAllocColorCells( xwd->
display, xwd->
map, False,
2715 plane_masks, 0, pixels, 1 ) )
2718 xwd->
cmap0[0].pixel = pixels[0];
2726 fprintf( stderr,
"Downgrading to r/o cmap.\n" );
2733 npixels = RWMAP_MAX_COLORS;
2736 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
2737 plane_masks, 0, pixels, (
unsigned int) npixels ) )
2747 for ( i = 0; i < npixels - 1; i++ )
2749 if ( pixels[i] == ( ~xwd->
cmap0[0].pixel & 0xFF ) )
2755 xwd->
fgcolor.pixel = pixels[i];
2756 for ( j = 0; j < npixels; j++ )
2759 XFreeColors( xwd->
display, xwd->
map, &pixels[j], 1, 0 );
2777 unsigned int gslevbg, gslevfg;
2792 gslevbg = (
unsigned int) ( ( (
long) pls->
cmap0[0].
r +
2794 (
long) pls->
cmap0[0].
b ) / 3 );
2796 PLColor_to_XColor( &pls->
cmap0[0], &xwd->
cmap0[0] );
2808 if ( gslevbg > 0x7F )
2813 fgcolor.
r = fgcolor.
g = fgcolor.
b = (
unsigned char) gslevfg;
2815 PLColor_to_XColor( &fgcolor, &xwd->
fgcolor );
2852 AllocCustomMap( pls );
2892 XColor xwm_colors[RWMAP_MAX_COLORS];
2894 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
2900 for ( i = 0; i < RWMAP_MAX_COLORS; i++ )
2902 xwm_colors[i].pixel = (
unsigned long int) i;
2904 XQueryColors( xwd->
display, xwd->
map, xwm_colors, RWMAP_MAX_COLORS );
2917 xwd->
visual, AllocNone );
2921 npixels = RWMAP_MAX_COLORS;
2924 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
2925 plane_masks, 0, pixels, (
unsigned int) npixels ) )
2929 plexit(
"couldn't allocate any colors" );
2934 for ( i = 0; i < CCMAP_XWM_COLORS; i++ )
2936 XStoreColor( xwd->
display, xwd->
map, &xwm_colors[i] );
2937 pixels[xwm_colors[i].pixel] = 0;
2942 for ( i = 0; i < xwd->
ncol0; i++ )
2945 pixels[xwd->
cmap0[i].pixel] = 0;
2954 if ( sxwm_colors_set )
2956 for ( i = 0; i < RWMAP_MAX_COLORS; i++ )
2958 if ( ( xwm_colors[i].red != sxwm_colors[i].red ) ||
2959 ( xwm_colors[i].green != sxwm_colors[i].green ) ||
2960 ( xwm_colors[i].blue != sxwm_colors[i].blue ) )
2962 if ( pixels[i] != 0 )
2964 XStoreColor( xwd->
display, xwd->
map, &xwm_colors[i] );
2973 for ( i = 0; i < npixels; i++ )
2975 if ( pixels[i] != 0 )
2976 XFreeColors( xwd->
display, xwd->
map, &pixels[i], 1, 0 );
3000 for ( i = 1; i < xwd->
ncol0; i++ )
3002 unsigned long pixel = xwd->
cmap0[i].pixel;
3003 XFreeColors( xwd->
display, xwd->
map, &pixel, 1, 0 );
3010 xwd->
cmap0 = (XColor *)
3011 realloc( xwd->
cmap0, (
size_t) pls->
ncol0 *
sizeof ( XColor ) );
3012 if ( xwd->
cmap0 == 0 )
3013 plexit(
"couldn't allocate space for cmap0 colors" );
3019 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
3023 npixels = pls->
ncol0 - 1;
3026 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
3027 plane_masks, 0, &pixels[1], (
unsigned int) npixels ) )
3031 plexit(
"couldn't allocate any colors" );
3034 xwd->
ncol0 = npixels + 1;
3035 for ( i = 1; i < xwd->
ncol0; i++ )
3037 xwd->
cmap0[i].pixel = pixels[i];
3045 fprintf( stderr,
"Attempting to allocate r/o colors in cmap0.\n" );
3047 for ( i = 1; i < pls->
ncol0; i++ )
3051 PLColor_to_XColor( &pls->
cmap0[i], &c );
3052 r = XAllocColor( xwd->
display, xwd->
map, &c );
3054 fprintf( stderr,
"i=%d, r=%d, pixel=%d\n", i, r, (
int) c.pixel );
3058 xwd->
cmap0[i].pixel = c.pixel;
3062 XColor screen_def, exact_def;
3066 "color alloc failed, trying by name: %s.\n",
3070 r = XAllocNamedColor( xwd->
display, xwd->
map,
3072 &screen_def, &exact_def );
3079 fprintf( stderr,
"yes, got a color by name.\n" );
3081 xwd->
cmap0[i] = screen_def;
3082 xwd->
cmap0[i].pixel = screen_def.pixel;
3086 r = XAllocNamedColor( xwd->
display, xwd->
map,
3088 &screen_def, &exact_def );
3091 xwd->
cmap0[i] = screen_def;
3092 xwd->
cmap0[i].pixel = screen_def.pixel;
3095 printf(
"Can't find white?! Giving up...\n" );
3102 fprintf( stderr,
"Allocated %d colors in cmap0.\n", xwd->
ncol0 );
3119 unsigned long plane_masks[1], pixels[RWMAP_MAX_COLORS];
3126 fprintf( stderr,
"Attempting to allocate r/w colors in cmap1.\n" );
3131 npixels =
MAX( 2,
MIN( RWMAP_CMAP1_COLORS, pls->
ncol1 ) );
3134 if ( XAllocColorCells( xwd->
display, xwd->
map, False,
3135 plane_masks, 0, pixels, (
unsigned int) npixels ) )
3145 fprintf( stderr,
"Warning: unable to allocate sufficient colors in cmap1.\n" );
3149 xwd->
ncol1 = npixels;
3151 fprintf( stderr,
"AllocCmap1 (xwin.c): Allocated %d colors in cmap1.\n", npixels );
3157 xwd->
cmap1 = (XColor *) calloc( (
size_t) ( xwd->
ncol1 ),
sizeof ( XColor ) );
3159 plexit(
"couldn't allocate space for cmap1 colors" );
3165 for ( j = i = 0; i < xwd->
ncol1; i++ )
3167 while ( pixels[j] == 0 )
3170 xwd->
cmap1[i].pixel = pixels[j];
3174 if ( j >= xwd->
ncol1 )
3187 fprintf( stderr,
"Attempting to allocate r/o colors in cmap1.\n" );
3189 switch ( xwd->
visual->class )
3192 ncolors = TC_CMAP1_COLORS;
3195 ncolors = ROMAP_CMAP1_COLORS;
3202 xwd->
cmap1 = (XColor *) calloc( (
size_t) ncolors,
sizeof ( XColor ) );
3204 plexit(
"couldn't allocate space for cmap1 colors" );
3207 for ( i = 0; i < ncolors; i++ )
3210 PLColor_to_XColor( &cmap1color, &xcol );
3212 r = XAllocColor( xwd->
display, xwd->
map, &xcol );
3214 fprintf( stderr,
"i=%d, r=%d, pixel=%d\n", i, r, (
int) xcol.pixel );
3216 xwd->
cmap1[i] = xcol;
3224 "Warning: unable to allocate sufficient colors in cmap1\n" );
3229 xwd->
ncol1 = ncolors;
3231 fprintf( stderr,
"AllocCmap1 (xwin.c): Allocated %d colors in cmap1\n", ncolors );
3252 for ( i = 1; i < xwd->
ncol0; i++ )
3254 PLColor_to_XColor( &pls->
cmap0[i], &xwd->
cmap0[i] );
3280 for ( i = 0; i < xwd->
ncol1; i++ )
3283 PLColor_to_XColor( &cmap1color, &xwd->
cmap1[i] );
3299 #define ToXColor( a ) ( ( ( 0xFF & ( a ) ) << 8 ) | ( a ) )
3300 #define ToPLColor( a ) ( ( (U_LONG) a ) >> 8 )
3303 PLColor_to_XColor(
PLColor *plcolor, XColor *xcolor )
3305 xcolor->red = (
short unsigned) ToXColor( plcolor->
r );
3306 xcolor->green = (
short unsigned) ToXColor( plcolor->
g );
3307 xcolor->blue = (
short unsigned) ToXColor( plcolor->
b );
3308 xcolor->flags = DoRed | DoGreen | DoBlue;
3319 PLColor_from_XColor(
PLColor *plcolor, XColor *xcolor )
3321 plcolor->
r = (
unsigned char) ToPLColor( xcolor->red );
3322 plcolor->
g = (
unsigned char) ToPLColor( xcolor->green );
3323 plcolor->
b = (
unsigned char) ToPLColor( xcolor->blue );
3335 AreWeGrayscale( Display *display )
3337 #if defined ( __cplusplus ) || defined ( c_plusplus )
3338 #define THING c_class
3343 XVisualInfo *visuals;
3344 int nitems, i, igray;
3347 visuals = XGetVisualInfo( display, 0, NULL, &nitems );
3351 for ( i = 0; i < nitems; i++ )
3352 if ( ( visuals[i].THING != GrayScale ) &&
3353 ( visuals[i].THING != StaticGray ) )
3380 SaveColormap( Display *display, Colormap colormap )
3387 sxwm_colors_set = 1;
3388 for ( i = 0; i < RWMAP_MAX_COLORS; i++ )
3390 sxwm_colors[i].pixel = i;
3392 XQueryColors( display, colormap, sxwm_colors, RWMAP_MAX_COLORS );
3412 GetImageErrorHandler( Display *display, XErrorEvent *error )
3414 if ( error->error_code != BadMatch )
3417 XGetErrorText( display, error->error_code, buffer, 256 );
3418 fprintf( stderr,
"xwin: Error in XGetImage: %s.\n", buffer );
3435 XImage *ximg = NULL;
3439 int ( *oldErrorHandler )( Display *, XErrorEvent * );
3442 float blt, brt, brb, blb;
3446 int i, corners[4], r[4] = { 0, 0, 0, 0 };
3453 CheckForEvents( pls );
3464 oldErrorHandler = XSetErrorHandler( GetImageErrorHandler );
3469 AllPlanes, ZPixmap );
3473 AllPlanes, ZPixmap );
3475 XSetErrorHandler( oldErrorHandler );
3479 plabort(
"Can't get image, the window must be partly off-screen, move it to fit screen" );
3483 if ( xwd->
ncol1 == 0 )
3485 if ( xwd->
ncol1 < 2 )
3489 switch ( (
int) ( pls->
diorot - 4. * floor( pls->
diorot / 4. ) ) )
3492 r[0] = 0; r[1] = 1; r[2] = 2; r[3] = 3;
break;
3494 r[0] = 1; r[1] = 2; r[2] = 3; r[3] = 0;
break;
3496 r[0] = 2; r[1] = 3; r[2] = 0; r[3] = 1;
break;
3498 r[0] = 3; r[1] = 0; r[2] = 1; r[3] = 2;
3523 for ( ix = 0; ix < nx - 1; ix++ )
3525 for ( iy = 0; iy < ny - 1; iy++ )
3527 corners[0] = ix * ny + iy;
3528 corners[1] = ( ix + 1 ) * ny + iy;
3529 corners[2] = ( ix + 1 ) * ny + iy + 1;
3530 corners[3] = ix * ny + iy + 1;
3532 for ( i = 0; i < 4; i++ )
3534 Ppts[i].x = (float) ( dev->
xscale * ( pls->
dev_ix[corners[r[i]]] ) );
3535 Ppts[i].y = (float) ( dev->
yscale * ( pls->
dev_iy[corners[r[i]]] ) );
3539 if ( Ppts[0].x >= xmin || Ppts[2].x <= xmax ||
3540 Ppts[1].y >= ymin || Ppts[3].y <= ymax )
3542 Ppts[0].x =
MAX( Ppts[0].x, (
float) xmin );
3543 Ppts[2].x =
MIN( Ppts[2].x, (
float) xmax );
3544 Ppts[1].y =
MAX( Ppts[1].y, (
float) ymin );
3545 Ppts[3].y =
MIN( Ppts[3].y, (
float) ymax );
3548 icol1 = pls->
dev_z[ix * ( ny - 1 ) + iy];
3551 if ( icol1 < pls->dev_zmin || icol1 > pls->
dev_zmax )
3554 icol1 = (
PLINT) ( (
float) icol1 / (float) USHRT_MAX * (
float) ( xwd->
ncol1 - 1 ) );
3556 curcolor = xwd->
cmap1[icol1];
3563 if ( ( fabs( Ppts[2].x - Ppts[0].x ) == 1 ) &&
3564 ( fabs( Ppts[3].y - Ppts[1].y ) == 1 ) )
3566 XPutPixel( ximg, (
int) Ppts[0].x, (
int) dev->
height - 1 - (
int) Ppts[0].y, (
unsigned long) curcolor.pixel );
3572 for ( ky = (
int) Ppts[1].y; ky < (int) Ppts[3].y; ky++ )
3573 for ( kx = (
int) Ppts[0].x; kx < (int) Ppts[2].x; kx++ )
3574 XPutPixel( ximg, kx, (
int) dev->
height - 1 - ky, (
unsigned int) curcolor.pixel );
3581 blt = Ppts[0].y - mlr * Ppts[0].x;
3582 brb = Ppts[2].y - mlr * Ppts[2].x;
3584 brt = Ppts[2].y - mtb * Ppts[2].x;
3585 blb = Ppts[0].y - mtb * Ppts[0].x;
3587 for ( ky = (
int) Ppts[1].y; ky < (int) Ppts[3].y; ky++ )
3589 left =
MAX( ( ( (
float) ky - blt ) / mlr ), ( ( (
float) ky - blb ) / mtb ) );
3590 right =
MIN( ( ( (
float) ky - brt ) / mtb ), ( ( (
float) ky - brb ) / mlr ) );
3591 for ( kx = (
int) Ppts[0].x; kx < (int) Ppts[2].x; kx++ )
3593 if ( kx >= rint( left ) && kx <= rint( right ) )
3595 XPutPixel( ximg, kx, (
int) dev->
height - 1 - ky, (
unsigned int) curcolor.pixel );
3611 XDestroyImage( ximg );