//=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // "nxgraph.h" // Convinient functions for Xlib, Elib, Flib. // Copyright(C) by Naoki Watanabe. // All rights reserved. // Last revised on Sep 18, 2000. //=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* #ifndef __NXGRAPH_H_INCLUDE #define __NXGRAPH_H_INCLUDE #include #include #include #include #include #include #include #include #include #include #include #include #include #include // This declaration might conflict with an original definition. // If so, please cut this line. //extern char* sys_errlist[]; /*********** Useful #define constants *****************************/ //---- arguments for NXSetColor() // symbols of fundermental colors #define NX_BLACK nx_colors[ 0].pixel #define NX_GRAY nx_colors[ 1].pixel #define NX_WHITE nx_colors[ 2].pixel #define NX_BROWN nx_colors[ 3].pixel #define NX_RED nx_colors[ 4].pixel #define NX_ORANGE nx_colors[ 5].pixel #define NX_YELLOW nx_colors[ 6].pixel #define NX_GRASS nx_colors[ 7].pixel #define NX_GREEN nx_colors[ 8].pixel #define NX_FOREST nx_colors[ 9].pixel #define NX_CYAN nx_colors[10].pixel #define NX_BLUE nx_colors[11].pixel #define NX_MARINE nx_colors[12].pixel #define NX_MAGENTA nx_colors[13].pixel #define NX_VIOLET nx_colors[14].pixel #define NX_PINK nx_colors[15].pixel //---- arguments for NXSetFont() // symbols of fundermental fonts #define NX_TIMES_ROMAN_TINY 0 #define NX_TIMES_ROMAN_SMALL 1 #define NX_TIMES_ROMAN_NORMAL 2 #define NX_TIMES_ROMAN_large 3 #define NX_TIMES_ROMAN_LARGE 4 #define NX_TIMES_ROMAN_HUGE 5 #define NX_TIMES_ITALIC_TINY 6 #define NX_TIMES_ITALIC_SMALL 7 #define NX_TIMES_ITALIC_NORMAL 8 #define NX_TIMES_ITALIC_large 9 #define NX_TIMES_ITALIC_LARGE 10 #define NX_TIMES_ITALIC_HUGE 11 #define NX_TIMES_BOLD_TINY 12 #define NX_TIMES_BOLD_SMALL 13 #define NX_TIMES_BOLD_NORMAL 14 #define NX_TIMES_BOLD_large 15 #define NX_TIMES_BOLD_LARGE 16 #define NX_TIMES_BOLD_HUGE 17 #define NX_TIMES_BOLDITALIC_TINY 18 #define NX_TIMES_BOLDITALIC_SMALL 19 #define NX_TIMES_BOLDITALIC_NORMAL 20 #define NX_TIMES_BOLDITALIC_large 21 #define NX_TIMES_BOLDITALIC_LARGE 22 #define NX_TIMES_BOLDITALIC_HUGE 23 //---- mask for ev.xkey.keycode #define NX_KeySpecMask (0xff80) //---- Ascii code of some keys #define BS (0x08) // Back space key #define TAB (0x09) // Tab key #define CLR (0x0B) // Home clear key #define CR (0x0D) // Return or enter key #define ESC (0x1B) // Escape key #define DEL (0xFF) // Delete key #define SPACE (0x20) // Space key //---- arguments for NXCheckEvent() #define NX_WAIT (0) #define NX_NOWAIT (1) //---- arguments for NXEnable() #define NX_SAVEFIGURE (1) #define NX_DOUBLEBUFFER (2) //---- Rename some #define constants // **** Attention **** // Xlib internaly #defines Complex for indicating a type of Polygon. // But it makes troubles for we can not use word Complex for // Complex numbers! // So we had better #undef Xlib's Complex and use another constants // for indicating types of Polygon. #define PolygonComplex Complex #define PolygonNonconvex Nonconvex #define PolygonConvex Convex #undef Complex /*********** End of useful #define constants **********************/ /*********** Internal variables ***********************************/ #ifdef NX_SUBMODULE extern Display* nx_dis; extern Drawable nx_drw, nx_win, nx_pix; extern GC nx_gc; extern XColor nx_colors[16]; #else // !NX_SUBMODULE // Comment out below line if you don't have a command "convert". #define __NX_HAVE_CONVERT // Specify the path of the convert command. #define __NX_PATH_OF_CONVERT "/usr/local/bin/convert" //---- check NX_EPS and NX_FIG #if defined(NX_EPS) && defined(NX_FIG) #error "Don't define both NX_EPS and NX_FIG" #endif // NX_EPS && NX_FIG #if defined(NX_EPS) || defined(NX_FIG) #define __NX_EPS_FIG #endif // NX_EPS || NX_FIG //---- include header files for eps and fig #ifdef NX_EPS #include "elib.h" #endif #ifdef NX_FIG #include "flib.h" #endif //---- list of listening events #define __NX_LISTENING_EVENTS ( ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | KeyPressMask ) //---- global variables for XWindow static Bool nx_last = False; XColor nx_colors[16] = { // RGB of fundermental colors { 0, 0, 0, 0 }, // black { 0, 48830, 48830, 48830 }, // gray { 0, 65535, 65535, 65535 }, // white { 0, 34048, 15872, 9728 }, // brawn { 0, 64000, 4864, 16384 }, // red { 0, 65535, 42405, 0 }, // orange { 0, 65535, 65535, 0 }, // yellow { 0, 15104, 64000, 13312 }, // grass { 0, 8738, 40000, 10000 }, // green { 0, 8738, 30000, 20000 }, // forest { 0, 0, 65535, 65535 }, // cyan { 0, 0, 0, 65535 }, // blue { 0, 41120, 8224, 61680 }, // marine { 0, 65535, 0, 65535 }, // magenta { 0, 61166, 33410, 61166 }, // violet { 0, 65535, 49344, 52171 } // pink }; Display* nx_dis; Drawable nx_drw, nx_win, nx_pix; GC nx_gc; //---- internal global variables for XWindow static Drawable nx_root; static GC nx_gc_pix, nx_gc_and, nx_gc_or; static Visual* nx_vis; static Colormap nx_cmap; static u_long nx_bgcolor; static Bool nx_doublebuffer = False; static u_int nx_width, nx_height; static int nx_last_x, nx_last_y; static int nx_depth, nx_bits;; //---- internal global variables for eps or fig #ifdef __NX_EPS_FIG static Bool nx_hasopened = False; static Bool nx_dosave = False; static u_int nx_vertex = 0; static XPoint nx_vertexes[257]; #ifdef NX_EPS static EPSID nx_file = NULL; static EPSGC nx_gc_file; #endif // NX_EPS #ifdef NX_FIG static FIGID nx_file = NULL; static FIGGC nx_gc_file; #endif // NX_FIG static void __TerminateLines( void ); #endif // __NX_EPS_FIG //---- fontnames of fundermental fonts const char* nx_fontnames[24] = { // TIMES_ROMAN "-adobe-times-medium-r-normal--8-80-75-75-p-44-iso8859-1", "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1", "-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1", "-adobe-times-medium-r-normal--14-140-75-75-p-74-iso8859-1", "-adobe-times-medium-r-normal--18-180-75-75-p-94-iso8859-1", "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1", // TIMES_ITALIC "-adobe-times-medium-i-normal--8-80-75-75-p-42-iso8859-1", "-adobe-times-medium-i-normal--10-100-75-75-p-52-iso8859-1", "-adobe-times-medium-i-normal--12-120-75-75-p-63-iso8859-1", "-adobe-times-medium-i-normal--14-140-75-75-p-73-iso8859-1", "-adobe-times-medium-i-normal--18-180-75-75-p-94-iso8859-1", "-adobe-times-medium-i-normal--24-240-75-75-p-125-iso8859-1", // TIMES_BOLD "-adobe-times-bold-r-normal--8-80-75-75-p-47-iso8859-1", "-adobe-times-bold-r-normal--10-100-75-75-p-57-iso8859-1", "-adobe-times-bold-r-normal--12-120-75-75-p-67-iso8859-1", "-adobe-times-bold-r-normal--14-140-75-75-p-77-iso8859-1", "-adobe-times-bold-r-normal--18-180-75-75-p-99-iso8859-1", "-adobe-times-bold-r-normal--24-240-75-75-p-132-iso8859-1", // TIMES_BOLDITALIC "-adobe-times-bold-i-normal--8-80-75-75-p-47-iso8859-1", "-adobe-times-bold-i-normal--10-100-75-75-p-57-iso8859-1", "-adobe-times-bold-i-normal--12-120-75-75-p-68-iso8859-1", "-adobe-times-bold-i-normal--14-140-75-75-p-77-iso8859-1", "-adobe-times-bold-i-normal--18-180-75-75-p-98-iso8859-1", "-adobe-times-bold-i-normal--24-240-75-75-p-128-iso8859-1" }; //---- fontsizes of fundermental fonts const int nx_fontsizes[24] = { 8, 10, 12, 14, 18, 24, // for TIMES_ROMAN 8, 10, 12, 14, 18, 24, // for TIMES_ITALIC 8, 10, 12, 14, 18, 24, // for TIMES_BOLD 8, 10, 12, 14, 18, 24 // for TIMES_BOLDITALIC }; #endif // !NX_SUBMODULE /************ End of internal variables ***************************/ //----------------------------------------------------------------- // This function outputs error messege and terminates the process. //----------------------------------------------------------------- void NXError( const char* msg ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { if( errno == 0 ){ fprintf( stderr, "Error: %s\n" "Abnormal process termination.\n", msg ); }else{ fprintf( stderr, "Error: %s : %s\n" "Abnormal process termination.\n", msg, sys_errlist[errno] ); } exit(1); } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function outputs warning messege. //----------------------------------------------------------------- void NXWarning( const char* msg ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { fprintf( stderr, "Warning: %s\nProcess keeps running.\n", msg ); } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function opens a new window in the display. //----------------------------------------------------------------- void NXOpenWindow( const char* title, u_int w, u_int h, u_long& bgcolor ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { // Copy given arguments to global variables. nx_width = w; nx_height = h; // Establish connection to the XServer on your display. nx_dis = XOpenDisplay( NULL ); nx_root = RootWindow(nx_dis,0); if( nx_dis == NULL ) NXError("NXOpenWindow(): Can not connect with your display."); nx_root = RootWindow(nx_dis,0); nx_depth = DefaultDepth(nx_dis,0); nx_vis = DefaultVisual(nx_dis,0); int kinds; XPixmapFormatValues* Format = XListPixmapFormats(nx_dis,&kinds); for( int i=0; i=257 ) NXError("NXDrawLineto(): Excuse me, too many vertexes."); nx_vertexes[nx_vertex].x = x; nx_vertexes[nx_vertex].y = y; nx_vertex++; } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws additive segments. //----------------------------------------------------------------- void NXDrawLinerel( int dx, int dy ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XDrawLine( nx_dis, nx_drw, nx_gc, nx_last_x, nx_last_y, nx_last_x+dx, nx_last_y+dy ); nx_last_x += dx; nx_last_y += dy; #ifdef __NX_EPS_FIG if( nx_dosave ){ if( nx_vertex >=257 ) NXError("NXDrawLinerel(): Excuse me, too many vertexes."); nx_vertexes[nx_vertex].x = nx_vertexes[nx_vertex-1].x + dx; nx_vertexes[nx_vertex].y = nx_vertexes[nx_vertex-1].y + dy; nx_vertex++; } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a rectangle with its border. //----------------------------------------------------------------- void NXDrawRectangle( int x, int y, u_int w, u_int h ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XDrawRectangle( nx_dis, nx_drw, nx_gc, x, y, w, h ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EDrawRectangle( nx_dis, nx_file, nx_gc_file, x, y, w, h ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FDrawRectangle( nx_dis, nx_file, nx_gc_file, x, y, w, h ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a rectangle with its interior filled. //----------------------------------------------------------------- void NXFillRectangle( int x, int y, u_int w, u_int h ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XFillRectangle( nx_dis, nx_drw, nx_gc, x, y, w, h ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EFillRectangle( nx_dis, nx_file, nx_gc_file, x, y, w, h ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FFillRectangle( nx_dis, nx_file, nx_gc_file, x, y, w, h ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a circle with its border. //----------------------------------------------------------------- void NXDrawCircle( int xc, int yc, u_int r ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XDrawArc( nx_dis, nx_drw, nx_gc, xc-r, yc-r, 2*r, 2*r, 0, 360*64 ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EDrawArc( nx_dis, nx_file, nx_gc_file, xc-r, yc-r, r*2, r*2, 0, 360 ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FDrawArc( nx_dis, nx_file, nx_gc_file, xc-r, yc-r, r*2, r*2, 0, 360 ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a circle with its interior filled. //----------------------------------------------------------------- void NXFillCircle( int xc, int yc, u_int r ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XFillArc( nx_dis, nx_drw, nx_gc, xc-r, yc-r, 2*r, 2*r, 0, 360*64 ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EFillArc( nx_dis, nx_file, nx_gc_file, xc-r, yc-r, r*2, r*2, 0, 360 ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FFillArc( nx_dis, nx_file, nx_gc_file, xc-r, yc-r, r*2, r*2, 0, 360 ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a ellipse with its border. //----------------------------------------------------------------- void NXDrawEllipse( int xc, int yc, u_int a, u_int b ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XDrawArc( nx_dis, nx_drw, nx_gc, xc-a, yc-b, 2*a, 2*b, 0, 360*64 ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EDrawArc( nx_dis, nx_file, nx_gc_file, xc-a, yc-b, a*2, b*2, 0, 360 ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FDrawArc( nx_dis, nx_file, nx_gc_file, xc-a, yc-b, a*2, b*2, 0, 360 ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a ellipse with its interior filled. //----------------------------------------------------------------- void NXFillEllipse( int xc, int yc, u_int a, u_int b ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XFillArc( nx_dis, nx_drw, nx_gc, xc-a, yc-b, 2*a, 2*b, 0, 360*64 ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EFillArc( nx_dis, nx_file, nx_gc_file, xc-a, yc-b, a*2, b*2, 0, 360 ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FFillArc( nx_dis, nx_file, nx_gc_file, xc-a, yc-b, a*2, b*2, 0, 360 ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a convex polygon with its border. //----------------------------------------------------------------- void NXDrawPolygon( XPoint p[], u_int np ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { p[np].x = p[0].x; p[np].y = p[0].y; XDrawLines( nx_dis, nx_drw, nx_gc, p, np+1, CoordModeOrigin ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EDrawPolygon( nx_dis, nx_file, nx_gc_file, p, np, CoordModeOrigin ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FDrawPolygon( nx_dis, nx_file, nx_gc_file, p, np, CoordModeOrigin ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a convex polygon with its interior filled. //----------------------------------------------------------------- void NXFillPolygon( XPoint p[], u_int np ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XFillPolygon( nx_dis, nx_drw, nx_gc, p, np, Convex, CoordModeOrigin ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EFillPolygon( nx_dis, nx_file, nx_gc_file, p, np, Convex, CoordModeOrigin ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FFillPolygon( nx_dis, nx_file, nx_gc_file, p, np, Convex, CoordModeOrigin ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a string in the window. //----------------------------------------------------------------- void NXDrawString( int x, int y, const char* str ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XDrawString( nx_dis, nx_drw, nx_gc, x, y, str, strlen(str) ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EDrawString( nx_dis, nx_file, nx_gc_file, x, y, str, 0 ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FDrawString( nx_dis, nx_file, nx_gc_file, x, y, str, 0 ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function draws a string with its back cleared. //----------------------------------------------------------------- void NXDrawImageString( int x, int y, const char* str ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XDrawImageString( nx_dis, nx_drw, nx_gc, x, y, str, strlen(str) ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EDrawString( nx_dis, nx_file, nx_gc_file, x, y, str, 0 ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FDrawString( nx_dis, nx_file, nx_gc_file, x, y, str, 0 ); } #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function "printf"s some data in the window. //----------------------------------------------------------------- int NXDrawPrintf( int x, int y, const char* format, ... ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { static char str[256]; int byte; va_list argptr; va_start( argptr, format ); vsprintf( str, format, argptr ); // In SunOS, vsprintf() does not byte = strlen(str); // return the length of string. XDrawImageString( nx_dis, nx_drw, nx_gc, x, y, str, byte ); #ifdef NX_EPS if( nx_dosave ){ __TerminateLines(); EDrawString( nx_dis, nx_file, nx_gc_file, x, y, str, 0 ); } #endif #ifdef NX_FIG if( nx_dosave ){ __TerminateLines(); FDrawString( nx_dis, nx_file, nx_gc_file, x, y, str, 0 ); } #endif return( byte ); } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function gets the image in the window to a given buffer. //----------------------------------------------------------------- char* NXGetImage( u_int w, u_int h, int xo, int yo ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XImage* ximage; ximage = XGetImage( nx_dis, nx_drw, xo, yo, w, h, AllPlanes, ZPixmap ); return ximage->data; } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function puts the image in the window from a given buffer. //----------------------------------------------------------------- void NXPutImage( char* buf, u_int w, u_int h, int xo, int yo ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XImage ximage; ximage.format = ZPixmap; ximage.byte_order = LSBFirst; ximage.bitmap_bit_order = LSBFirst; ximage.width = w; ximage.height = h; ximage.xoffset = 0; ximage.bitmap_unit = 32; ximage.bitmap_pad = 32; ximage.depth = nx_depth; ximage.bits_per_pixel = nx_bits; ximage.bytes_per_line = nx_bits/8 * w; ximage.data = buf; XPutImage( nx_dis, nx_drw, nx_gc, &ximage, 0, 0, xo, yo, w, h ); #ifdef __NX_EPS_FIG if( nx_dosave ) NXWarning("NXPutImage(): The image is not written to the file."); #endif } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function scroll the image inside the window. //----------------------------------------------------------------- void NXScrollArea( int xo, int yo, u_int w, u_int h, int dx, int dy ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XCopyArea( nx_dis, nx_drw, nx_drw, nx_gc_pix, xo, yo, w, h, xo+dx, yo+dy ); if( dx==0 ){ }else if( dx==+1 ){ XDrawLine( nx_dis, nx_drw, nx_gc_pix, xo, yo, xo, yo+h-1 ); }else if( dx==-1 ){ XDrawLine( nx_dis, nx_drw, nx_gc_pix, xo+w-1, yo, xo+w-1, yo+h-1 ); }else if( dx>0 ){ XFillRectangle( nx_dis, nx_drw, nx_gc_pix, xo, yo, dx, h ); }else if( dx<0 ){ XFillRectangle( nx_dis, nx_drw, nx_gc_pix, xo+w+dx, yo, -dx, h ); } if( dy==0 ){ }else if( dy==+1 ){ XDrawLine( nx_dis, nx_drw, nx_gc_pix, xo, yo, xo+w-1, yo ); }else if( dy==-1 ){ XDrawLine( nx_dis, nx_drw, nx_gc_pix, xo, yo+h-1, xo+w-1, yo+h-1 ); }else if( dy>0 ){ XFillRectangle( nx_dis, nx_drw, nx_gc_pix, xo, yo, w, dy ); }else if( dy<0 ){ XFillRectangle( nx_dis, nx_drw, nx_gc_pix, xo, yo+h+dy, w, -dy ); } } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function scrolls the image inside the window. //----------------------------------------------------------------- void NXScrollWindow( int dx, int dy ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { NXScrollArea( 0, 0, nx_width, nx_height, dx, dy ); } #endif // !NX_SUBMODULE #ifndef NX_SUBMODULE struct RGB8{ u_char RGB; RGB8( void ){} RGB8( u_long pixel ){ pixel = u_char( pixel ); } }; struct RGB16{ u_short RGB; RGB16( void ){} RGB16( u_long pixel ){ pixel = u_short( pixel ); } }; struct RGB24{ u_char R, G, B; RGB24( void ){} RGB24( u_long pixel ){ R = u_char((pixel>> 0) & 0xff); G = u_char((pixel>> 8) & 0xff); B = u_char((pixel>>16) & 0xff); } }; struct RGB32{ u_long RGBA; RGB32( void ){} RGB32( u_long pixel ){ RGBA = u_long( pixel ); } }; #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function rotates the image inside the window. //----------------------------------------------------------------- void NXRotateWindow( int xo, int yo, double rad ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XImage& oldimg = *XGetImage( nx_dis, nx_drw, 0, 0, nx_width, nx_height, AllPlanes, ZPixmap ); XImage newimg; newimg.data = new char [ nx_height * nx_width * nx_bits/8 ]; double co = cos(rad); double si = sin(rad); int RXW=abs(int(nx_width*co)), RYW=abs(int(nx_width*si)); int RYH=abs(int(nx_height*co)), RXH=abs(int(nx_height*si)); int sx = ( co > 0.0 ) ? +1 : -1; int sy = ( si > 0.0 ) ? +1 : -1; int bxo = int( yo*si + xo*(1.0-co) ); int byo = int( yo*(1.0-co) - xo*si ); switch( nx_bits ){ case 8 :{ for( u_int wy=0, acx0=0, acy0=0; wynx_height ){ acx0 -= nx_height; bxo-=sy; } acy0 += RYH; if( acy0>nx_height ){ acy0 -= nx_height; byo+=sx; } int bx=bxo, by=byo; for( u_int wx=0, acx1=0, acy1=0; wxnx_width ){ acx1 -= nx_width; bx+=sx; } acy1 += RYW; if( acy1>nx_width ){ acy1 -= nx_width; by+=sy; } ((RGB8*)newimg.data)[wy*nx_width+wx] = ( 0<=by && by<(int)nx_height && 0<=bx && bx<(int)nx_width ) ? ((RGB8*)oldimg.data)[by*nx_width+bx] : RGB8(nx_bgcolor); } } }break; case 16:{ for( u_int wy=0, acx0=0, acy0=0; wynx_height ){ acx0 -= nx_height; bxo-=sy; } acy0 += RYH; if( acy0>nx_height ){ acy0 -= nx_height; byo+=sx; } int bx=bxo, by=byo; for( u_int wx=0, acx1=0, acy1=0; wxnx_width ){ acx1 -= nx_width; bx+=sx; } acy1 += RYW; if( acy1>nx_width ){ acy1 -= nx_width; by+=sy; } ((RGB16*)newimg.data)[wy*nx_width+wx] = ( 0<=by && by<(int)nx_height && 0<=bx && bx<(int)nx_width ) ? ((RGB16*)oldimg.data)[by*nx_width+bx] : RGB16(nx_bgcolor); } } }break; case 24:{ for( u_int wy=0, acx0=0, acy0=0; wynx_height ){ acx0 -= nx_height; bxo-=sy; } acy0 += RYH; if( acy0>nx_height ){ acy0 -= nx_height; byo+=sx; } int bx=bxo, by=byo; for( u_int wx=0, acx1=0, acy1=0; wxnx_width ){ acx1 -= nx_width; bx+=sx; } acy1 += RYW; if( acy1>nx_width ){ acy1 -= nx_width; by+=sy; } ((RGB24*)newimg.data)[wy*nx_width+wx] = ( 0<=by && by<(int)nx_height && 0<=bx && bx<(int)nx_width ) ? ((RGB24*)oldimg.data)[by*nx_width+bx] : RGB24(nx_bgcolor); } } }break; case 32:{ for( u_int wy=0, acx0=0, acy0=0; wynx_height ){ acx0 -= nx_height; bxo-=sy; } acy0 += RYH; if( acy0>nx_height ){ acy0 -= nx_height; byo+=sx; } int bx=bxo, by=byo; for( u_int wx=0, acx1=0, acy1=0; wxnx_width ){ acx1 -= nx_width; bx+=sx; } acy1 += RYW; if( acy1>nx_width ){ acy1 -= nx_width; by+=sy; } ((RGB32*)newimg.data)[wy*nx_width+wx] = ( 0<=by && by<(int)nx_height && 0<=bx && bx<(int)nx_width ) ? ((RGB32*)oldimg.data)[by*nx_width+bx] : RGB32(nx_bgcolor); } } }break; } NXPutImage( (char*)newimg.data, nx_width, nx_height, 0, 0 ); delete [] newimg.data; XFree(&oldimg); } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function blocks the process until mouse or key are pressed. //----------------------------------------------------------------- void NXPause( unsigned int msec=0 ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { if( msec>0 ){ struct timeval tv; tv.tv_sec = 0; tv.tv_usec = msec*1000; select( 0, NULL, NULL, NULL, &tv ); }else{ XEvent ev; do{ XNextEvent( nx_dis, &ev ); }while( !( ev.type == ButtonPress || ev.type == KeyPress ) ); } } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function checks no events are reached. //----------------------------------------------------------------- Bool NXNoEvents( void ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XEvent ev; return !XCheckMaskEvent( nx_dis, ButtonPressMask|KeyPressMask, &ev ); } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function reports some changes about mouse and keyboard. //----------------------------------------------------------------- int NXCheckEvent( int wait, XEvent& ev ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { if( wait == NX_NOWAIT ){ if( XCheckMaskEvent( nx_dis, __NX_LISTENING_EVENTS, &ev )==False ){ return( ev.type = False ); } }else{ XNextEvent( nx_dis, &ev ); } switch( ev.type ){ case KeyPress :{ char ascii = 0; KeySym keysym = 0; // Overwrites ev.xkey.keycode for our purpose. if( XLookupString( &ev.xkey, &ascii, 1, &keysym, NULL ) ){ if( ev.xkey.state & ControlMask ){ if( keysym & NX_KeySpecMask ){ ev.xkey.keycode = u_int(ascii); }else{ ev.xkey.keycode = u_int(keysym); } }else{ ev.xkey.keycode = u_int(ascii); } }else{ ev.xkey.keycode = u_int(keysym); } }break; case ButtonPress : break; case ButtonRelease : break; case MotionNotify : // Overwrites ev.xbutton.button for our purpose. if( ev.xbutton.state & Button1Mask ){ ev.xbutton.button = Button1; }else if( ev.xbutton.state & Button2Mask ){ ev.xbutton.button = Button2; }else if( ev.xbutton.state & Button3Mask ){ ev.xbutton.button = Button3; } break; } return( ev.type ); } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function rings a bell. //----------------------------------------------------------------- void NXBell( void ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { XBell( nx_dis, 0 ); } #endif // !NX_SUBMODULE //---- sub function for NXSaveWindow() #if defined(__NX_HAVE_CONVERT) && !defined(NX_SUBMODULE) #include #include static void Wait( int ) { signal( SIGCHLD, SIG_IGN ); wait(0); signal( SIGCHLD, Wait ); } static FILE* __OpenConvert( const char* fname ) { // Launch a child process for command convert. int pid; int pipefds[2]; pipe( pipefds ); if( (pid = fork()) == 0 ){ close( 0 ); dup( pipefds[0] ); close( pipefds[1] ); execl( __NX_PATH_OF_CONVERT, "convert", "xwd:-", fname, 0 ); if( errno == ENOENT ){ errno = 0; NXError( "NXSaveWindow(): command \"convert\" does not exist in\n" __NX_PATH_OF_CONVERT "\n" "Set appropriate path to __NX_PATH_OF_CONVERT in nxgraph.h." ); } NXError( "NXSaveWindow(): can not execute command \"convert\""); exit(1); // actually, this code is not done. } signal( SIGCHLD, Wait ); close( pipefds[0] ); // Changes the pipe descriptor to a file stream. FILE* fptr = fdopen( pipefds[1], "w" ); if( fptr == NULL ){ NXError( "NXSaveWindow(): can not reopen a stream." ); } return fptr; } #else static FILE* __OpenConvert( const char* fname ) { // Opens a new file. FILE* fptr = fopen( fname, "w" ); if( fptr == NULL ){ NXError( "NXSaveWindow(): can not open a file." ); } return fptr; } #endif // __NX_HAVE_CONVERT //----------------------------------------------------------------- // This function saves image of the window in a file. //----------------------------------------------------------------- void NXSaveWindow( const char* expression, ... ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { static char fname[64]; va_list argptr; va_start( argptr, expression ); vsnprintf( fname, sizeof(fname), expression, argptr ); FILE* fptr = __OpenConvert( fname ); XWDFileHeader header; XImage* image = XGetImage( nx_dis, nx_drw, 0, 0, nx_width, nx_height, AllPlanes, ZPixmap ); header.header_size = sizeof(XWDFileHeader)+7; header.file_version = XWD_FILE_VERSION; header.pixmap_format = ZPixmap; header.pixmap_depth = image->depth; header.pixmap_width = image->width; header.pixmap_height = image->height; header.xoffset = image->xoffset; header.byte_order = image->byte_order; header.bitmap_unit = image->bitmap_unit; header.bitmap_bit_order = image->bitmap_bit_order; header.bitmap_pad = image->bitmap_pad; header.bits_per_pixel = image->bits_per_pixel; header.bytes_per_line = image->bytes_per_line; header.visual_class = nx_vis->c_class; header.red_mask = nx_vis->red_mask; header.green_mask = nx_vis->green_mask; header.blue_mask = nx_vis->blue_mask; header.bits_per_rgb = nx_vis->bits_per_rgb; header.colormap_entries = nx_vis->map_entries; header.ncolors = nx_vis->map_entries; header.window_width = header.pixmap_width; header.window_height = header.pixmap_height; header.window_x = 0; header.window_y = 0; header.window_bdrwidth = 0; const int cnum = nx_vis->map_entries; const int rmask = nx_vis->red_mask; const int gmask = nx_vis->green_mask; const int bmask = nx_vis->blue_mask; const int radd = (rmask & (~rmask+1)); const int gadd = (gmask & (~gmask+1)); const int badd = (bmask & (~bmask+1)); const int isize = image->bytes_per_line * image->height; XWDColor* pal = new XWDColor [cnum]; if( nx_vis->c_class == TrueColor || nx_vis->c_class == DirectColor ){ for( int i=0, r=0, g=0, b=0 ; idata, isize, 1, fptr ) ){ NXError( "NXSaveWindow(): can not write data." ); } delete [] pal; XDestroyImage( image ); fclose( fptr ); } #endif // !NX_SUBMODULE #ifdef NX_USEXPM #include //================================================================= // Definitions of XPM icon library. //================================================================= struct XPM { XpmAttributes xpatt; Pixmap pix, msk; GC gc; public: inline XPM( void ){ pix = msk = (Window)0; gc = NULL; } inline ~XPM(){ XFreePixmap( nx_dis, pix ); XFreePixmap( nx_dis, msk ); XFreeGC( nx_dis, gc ); } }; //----------------------------------------------------------------- // This function loads XPM from a xpm data. //----------------------------------------------------------------- void NXLoadXPM( XPM& xpm, char** data ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { #ifdef __NX_EPS_FIG if( nx_dosave ) NXWarning("NXLoadXPM(): The image is not written to the file."); #endif xpm.xpatt.valuemask = XpmColormap; xpm.xpatt.colormap = nx_cmap; xpm.gc = XCreateGC( nx_dis, nx_root, 0, 0 ); XpmCreatePixmapFromData( nx_dis, nx_drw, data, &xpm.pix, &xpm.msk, &xpm.xpatt ); } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function loads XPM from a xpm file. //----------------------------------------------------------------- void NXLoadXPM( XPM& xpm, char* fname ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { #ifdef __NX_EPS_FIG if( nx_dosave ) NXWarning("NXLoadXPM(): The image is not written to the file."); #endif xpm.xpatt.valuemask = XpmColormap; xpm.xpatt.colormap = nx_cmap; xpm.gc = XCreateGC( nx_dis, nx_root, 0, 0 ); XpmReadFileToPixmap( nx_dis, nx_drw, fname, &xpm.pix, &xpm.msk, &xpm.xpatt ); } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function puts XPM on the window. //----------------------------------------------------------------- void NXPutXPM( XPM& xpm, int x, int y ) #ifdef NX_SUBMODULE ; #else // !NX_SUBMODULE { #ifdef __NX_EPS_FIG if( nx_dosave ) NXWarning("NXLoadXPM(): The image is not written to the file."); #endif if( !xpm.pix ) NXError("NXPutXPM(): No images are loaded."); XSetClipOrigin( nx_dis, xpm.gc, x, y ); XSetClipMask( nx_dis, xpm.gc, xpm.msk ); XCopyArea( nx_dis, xpm.pix, nx_drw, xpm.gc, 0, 0, xpm.xpatt.width, xpm.xpatt.height, x, y ); } #endif // !NX_SUBMODULE //----------------------------------------------------------------- // This function returns the width of given XPM. //----------------------------------------------------------------- inline u_int NXWidthXPM( XPM& xpm ){ return xpm.xpatt.width; } //----------------------------------------------------------------- // This function returns the height of given XPM. //----------------------------------------------------------------- inline u_int NXHeightXPM( XPM& xpm ){ return xpm.xpatt.height; } #endif // NX_USEXPM #endif // __NXGRAPH_H_INCLUDE