📄 mpe_graphics.c
字号:
/* (C) 2001 by Argonne National Laboratory. See COPYRIGHT in top-level directory.*/#include <math.h>#include "mpe_graphics_conf.h"#include "mpetools.h" #include "basex11.h" #ifdef MPE_NOMPI#define MPI_MAX_PROCESSOR_NAME 256#include "mpe_misc.h"#else#include "mpi.h"#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#elseextern char *getenv();#endif#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)#include <string.h>#endif#define MPE_INTERNAL#include "mpe_graphics.h" /*I "mpe.h" I*/#define DEBUG 0typedef struct xpand_list_Int_ { int *list; int nused; int size;} xpand_list_Int;#define ListHeadPtr( listPtr ) ( (listPtr)->list )#define ListSize( listPtr ) ( (listPtr)->nused )#define ListClose( listPtr, headPtr, nitems ) { \ headPtr = ListHeadPtr( listPtr ); \ nitems = ListSize( listPtr ); \ free( listPtr ); \}static xpand_list_Int *Int_CreateList(int initialLen);/* Forward refs */static void SortPoints ( MPE_Point *, int, XPoint **, MPE_Color **, int **, int * );static int Int_AddItem ( xpand_list_Int *, int );int MPE_buttonArray[] = { Button1, Button2, Button3, Button4, Button5};int MPE_logicArray[] = { GXclear, /* 0 */ GXand, /* src && dst */ GXandReverse, /* src && !dst */ GXcopy, /* src */ GXandInverted, /* !src && dst */ GXnoop, /* dst */ GXxor, /* src XOR dst */ GXor, /* src || !dst */ GXnor, /* !src && !dst */ GXequiv, /* !src XOR dst */ GXinvert, /* !dst */ GXorReverse, /* !src || dst */ GXcopyInverted, /* !src */ GXorInverted, /* !src || dst */ GXnand, /* !src || !dst */ GXset /* 1 */}; static void SetBackingStoreBitGrav (MPE_XGraph);#ifdef POINTER_64_BITS static int fort_index = 0;MPE_XGraph MPE_fort_head = 0;#endif/*N XGRAPHICS_FORTRAN Notes For Fortran Interface : The Fortran interface to this routine is different from its C counterpart and it has an additional argument, ierr, at the end of the argument list, i.e. the returned function value (the error code) in C interface is returned as the additional argument in Fortran interface. The Fortran interface is invoked with the CALL statement. All MPI and MPE objects, MPI_Comm, MPE_XGraph and MPE_Color, are of type INTEGER in Fortran.N*//*@ MPE_Open_graphics - (collectively) opens an X Windows display Input Parameters:+ comm - Communicator of participating processes. display - Name of X window display. If null, display will be taken from the DISPLAY variable on the process with rank 0 in 'comm'. If that is either undefined, or starts with w ":", then the value of display is ``hostname``:0. x,y - position of the window. If '(-1,-1)', then the user should be asked to position the window (this is a window manager issue).. w,h - width and height of the window, in pixels.- is_collective - true if the graphics operations are collective; this allows the MPE graphics operations to make fewer connections to the display. If false, then all processes in the communicator comm will open the display; this could exceed the number of connections that your X window server allows. Not yet implemented. Output Parameter:. handle - Graphics handle to be given to other MPE graphics routines. Notes: This is a collective routine. All processes in the given communicator must call it, and it has the same semantics as 'MPI_Barrier' (that is, other collective operations can not cross this routine)..N XGRAPHICS_FORTRAN Additional Notes for Fortran Interface : If Fortran 'display' argument is an empty string, "", display will be taken from the DISPLAY variable on the process with rank 0 in 'comm'. The trailing blanks in Fortran CHARACTER string argument will be ignored.@*/int MPE_Open_graphics( handle, comm, display, x, y, w, h, is_collective )MPE_XGraph *handle;MPI_Comm comm;char display[MPI_MAX_PROCESSOR_NAME+4];int x, y;int w, h;int is_collective;{#ifndef MPE_NOMPI Window win;#endif MPE_XGraph new;#ifdef FOO XFontStruct **font_info; XGCValues values; char fontname[128];#endif#ifndef MPE_NOMPI int numprocs, namelen;#endif int myid, successful=0; myid = 0; /* for the single processor version */ *handle = 0; /* In case of errors */ new = NEW(struct MPE_XGraph_s); /* CHKPTRN(new); */ new->Cookie = MPE_G_COOKIE; new->xwin = NEW(XBWindow); /* CHKPTRN(new->xwin); */ /* These are used to capture the images into xwd files */ new->capture_file = 0; new->capture_freq = 1; new->capture_num = 0; new->capture_cnt = 0; new->input_mask = 0; new->event_routine = 0;#ifdef POINTER_64_BITS /* In case we need to support fortran */ new->fort_index = fort_index++; new->next = MPE_fort_head; MPE_fort_head = new;#endif #ifndef MPE_NOMPI if (is_collective) { /* Not supported; just use individual connections */ is_collective = 0; } new->comm = comm; new->is_collective = is_collective; MPI_Comm_size(comm,&numprocs); MPI_Comm_rank(comm,&myid);#endif if (!display) {#ifndef MPE_NOMPI int str_len;#endif#if DEBUG fprintf( stderr, "[%d] Guessing at display name.\n", myid ); fflush( stderr );#endif if (myid == 0) { display = getenv( "DISPLAY" );#if DEBUG fprintf( stderr, "$DISPLAY = %s\n", display ); fflush( stderr );#endif if (!display || display[0] == ':') { /* Replace display with hostname:0 */#ifdef MPE_NOMPI display = (char *)malloc( 100 ); MPE_GetHostName( display, 100 );#else /* This is not correct, since there is no guarentee that this is the "correct" network name */ display = (char *)malloc( MPI_MAX_PROCESSOR_NAME ); MPI_Get_processor_name( display, &namelen );#endif#if DEBUG fprintf( stderr, "Process 0 is: %s\n", display ); fflush( stderr );#endif strcat( display, ":0" );#if DEBUG fprintf( stderr, "Process 0 is: %s\n", display ); fflush( stderr );#endif }#ifndef MPE_NOMPI str_len = strlen( display ) + 1; MPI_Bcast( &str_len, 1, MPI_INT, 0, comm );#endif } #ifndef MPE_NOMPI else { MPI_Bcast( &str_len, 1, MPI_INT, 0, comm ); display = (char *) malloc( sizeof( char ) * str_len ); } MPI_Bcast( display, str_len, MPI_CHAR, 0, comm );#endif } new->display_name = (char *)malloc( strlen(display) + 1 ); if (!new->display_name) return MPE_ERR_LOW_MEM; strcpy( new->display_name, display );#if DEBUG fprintf( stderr, "[%d] trying to open %s\n", myid, display ); fflush( stderr );#endif if (0 == myid) { successful = !XBQuickWindow( new->xwin, display, "MPE", x, y, w, h ); /* ALWAYS send the local host */ if (successful) {#ifndef MPE_NOMPI win = new->xwin->win; MPI_Bcast( &win, 1, MPI_UNSIGNED_LONG, 0, comm );#endif /* ifndef MPE_NOMPI */ } else {#ifndef MPE_NOMPI win = 0; MPI_Bcast( &win, 1, MPI_UNSIGNED_LONG, 0, comm );#endif /* ifndef MPE_NOMPI */ } }#ifndef MPE_NOMPI else { MPI_Bcast( &win, 1, MPI_UNSIGNED_LONG, 0, comm ); if (win) { /* if process 0 connected */ successful = !XBQuickWindowFromWindow( new->xwin, display, win ); } }#endif /* ifndef MPE_NOMPI */#if DEBUG fprintf( stderr, "%s to %s from process %d.\n", successful ? "Successfully connected" : "Failed to connect", display, myid ); fflush( stderr );#endif#ifdef FOO /* set a default font */ strcpy(fontname,"fixed"); if ((*font_info = XLoadQueryFont( new->xwin->disp, fontname )) == NULL) { fprintf( stderr, "Could not open %s font\n", fontname ); exit(1); } values.font = (*font_info)->fid; XChangeGC( new->xwin->disp, new->xwin->gc.set, GCFont, &values ); fprintf("successfully set default font\n");#endif if (!successful) {#ifndef MPE_NOMPI char myname[MPI_MAX_PROCESSOR_NAME]; int mynamelen; MPI_Get_processor_name( myname, &mynamelen ); fprintf( stderr, "Failed to connect to %s from %s\n", display, myname );#endif *handle = (MPE_XGraph) 0; return MPE_ERR_NOXCONNECT; } else { SetBackingStoreBitGrav( new ); *handle = new; return MPE_SUCCESS; }}static void SetBackingStoreBitGrav( MPE_XGraph graph ){ XSetWindowAttributes attrib; graph->backingStore = DoesBackingStore( ScreenOfDisplay( graph->xwin->disp, graph->xwin->screen ) );#if DEBUG fprintf( stderr, "Screen's backing store support is %s.\n", graph->backingStore==NotUseful ? "NotUseful" : graph->backingStore==WhenMapped ? "WhenMapped" : graph->backingStore==Always ? "Always" : "dunno" ); fflush( stderr );#endif attrib.bit_gravity = NorthWestGravity; attrib.backing_store = graph->backingStore; XChangeWindowAttributes( graph->xwin->disp, graph->xwin->win, CWBitGravity | CWBackingStore, &attrib );}/*@ MPE_CaptureFile - Sets the base filename used to capture output from updates Input Parameters:+ handle - MPE graphics handle. fname - base file name (see below)- freq - Frequency of updates Return Values:+ MPE_ERR_LOW_MEM - malloc for copy of the filename (fname) failed. MPE_ERR_BAD_ARGS - 'handle' parameter is bad- MPE_SUCCESS - success Notes: The output is written in xwd format to 'fname%d', where '%d' is the number of the file (starting from zero)..N XGRAPHICS_FORTRAN Additional Notes for Fortran Interface : The trailing blanks in Fortran 'CHARACTER' string argument will be ignored.@*/int MPE_CaptureFile( handle, fname, freq )MPE_XGraph handle;char *fname;int freq;{ if (handle->Cookie != MPE_G_COOKIE) { fprintf( stderr, "Handle argument is incorrect or corrupted\n" ); return MPE_ERR_BAD_ARGS; } handle->capture_file = (char *)malloc( strlen( fname ) + 1 ); if (!handle->capture_file) { fprintf( stderr, "Could not allocate memory for filename\n" ); return MPE_ERR_LOW_MEM; } strcpy( handle->capture_file, fname ); handle->capture_num = 0; handle->capture_freq = freq; handle->capture_cnt = 0; return MPE_SUCCESS;}/*@ MPE_Draw_point - Draws a point on an X Windows display Input Parameters:+ handle - MPE graphics handle . x,y - pixel position to draw. Coordinates are upper-left origin (standard X11)- color - Color `index` value. See 'MPE_MakeColorArray'. By default, the colors 'MPE_WHITE', 'MPE_BLACK', 'MPE_RED', 'MPE_YELLOW', 'MPE_GREEN', 'MPE_CYAN', 'MPE_BLUE', 'MPE_MAGENTA', 'MPE_AQUAMARINE', 'MPE_FORESTGREEN', 'MPE_ORANGE', 'MPE_VIOLET', 'MPE_BROWN', 'MPE_PINK', 'MPE_CORAL' and 'MPE_GRAY' are defined..N XGRAPHICS_FORTRAN@*/int MPE_Draw_point( handle, x, y, color )MPE_XGraph handle;int x, y;MPE_Color color;{ if (handle->Cookie != MPE_G_COOKIE) { fprintf( stderr, "Handle argument is incorrect or corrupted\n" ); return MPE_ERR_BAD_ARGS; }#ifndef MPE_NOMPI if (handle->is_collective) { } else#endif { XBSetPixVal( handle->xwin, handle->xwin->cmapping[color] ); XDrawPoint( handle->xwin->disp, handle->xwin->win, handle->xwin->gc.set, x, y ); } return MPE_SUCCESS;}/*@ MPE_Draw_points - Draws points on an X Windows display Input Parameters:+ handle - MPE graphics handle . points - list of points to draw- npoints - number of points to draw.N XGRAPHICS_FORTRAN@*/int MPE_Draw_points( handle, points, npoints )MPE_XGraph handle;MPE_Point *points;int npoints;{ XPoint *sortedPoints; int *colorRanges, ncolors, colorNum, n; MPE_Color *colorList; if (handle->Cookie != MPE_G_COOKIE) { fprintf( stderr, "Handle argument is incorrect or corrupted\n" ); return MPE_ERR_BAD_ARGS; }#if 0 /* temporary debug */ {int i; fprintf( stderr, "MPE_Draw_points\n" ); for (i=0; i<npoints; i++) { fprintf( stderr, "%d. (%d %d) %d\n", i, points[i].x, points[i].y, points[i].c ); }}#endif SortPoints( points, npoints, &sortedPoints, &colorList, &colorRanges, &ncolors );#if 0 /* another temporary debug */ fprintf( stderr, "Sorted points. %d colors\n", ncolors ); for (i=0; i<ncolors; i++) { fprintf( stderr, "%d %d's.\n", colorRanges[i], colorList[i] ); }#endif for (colorNum = 0; colorNum < ncolors; colorNum++) { n = (colorNum < ncolors-1) ? colorRanges[colorNum+1] - colorRanges[colorNum] : npoints - colorRanges[colorNum];/* printf( "xxx: %d %d %d %d\n", (colorNum < ncolors-1), colorRanges[colorNum+1] - colorRanges[colorNum], ncolors - colorNum, (colorNum < ncolors-1) ? colorRanges[colorNum+1] - colorRanges[colorNum] : npoints - colorRanges[colorNum] ); printf( "Sending %d points of color %d starting at %d\n", n, colorList[colorNum], colorRanges[colorNum] ); for (i = 0; i<n; i++) { printf( "sending (%hd %hd)\n", sortedPoints[colorRanges[colorNum]+i].x, sortedPoints[colorRanges[colorNum]+i].y ); }*/ XBSetPixVal( handle->xwin, handle->xwin->cmapping[colorList[colorNum]] ); XDrawPoints( handle->xwin->disp, handle->xwin->win, handle->xwin->gc.set, sortedPoints + colorRanges[colorNum], n, CoordModeOrigin ); } free( sortedPoints ); free( colorList ); free( colorRanges ); return MPE_SUCCESS;}static void SortPoints( lista, a, listb, colorList, boundaryPoints, ncolors )MPE_Point *lista;XPoint **listb;MPE_Color **colorList;int a, **boundaryPoints, *ncolors;{ int top, bottom, outoforder; MPE_Color thisColor, tempColor, *keyList; XPoint *list, tempPt; xpand_list_Int *boundaryList; boundaryList = Int_CreateList( 20 ); list = *listb = (XPoint *) malloc( sizeof( XPoint ) * a ); keyList = (MPE_Color *) malloc( sizeof( MPE_Color ) * a ); for (top = 0; top < a; top++) { list[top].x = lista[top].x; list[top].y = lista[top].y; keyList[top] = lista[top].c;/* fprintf( stderr, "unsorted %d = %d %d %d\n", top, lista[top].x, lista[top].y, lista[top].c );*/ } /* copy the list over */ top = 0; outoforder = 1; while (top < a && outoforder) { Int_AddItem( boundaryList, top ); /* keep a list of the start of each different color */ /* temp. debugging */ /* fprintf( */ thisColor = keyList[top]; bottom = a-1; outoforder = 0; while (top < bottom) { if (keyList[top] != thisColor) { outoforder = 1; while (bottom>top && keyList[bottom] != thisColor) bottom--; if (bottom>top) { tempPt = list[bottom]; list[bottom] = list[top]; list[top] = tempPt; tempColor = keyList[bottom]; keyList[bottom] = keyList[top]; keyList[top] = tempColor; top++; } } else { top++; } } } ListClose( boundaryList, *boundaryPoints, *ncolors ); *colorList = (MPE_Color *) malloc( sizeof( MPE_Color ) * *ncolors ); for (top=0; top < *ncolors; top++) { (*colorList)[top] = keyList[(*boundaryPoints)[top]];/* printf( "color %d = %d\n", top, (*colorList)[top] );*/ }/* bottom = 0; for (top = 0; top < a; top++) { if ((*boundaryPoints)[bottom] == top) { fprintf( stderr, "color = %d\n", (*colorList)[bottom] ); bottom++; } fprintf( stderr, "sorted %d = %hu %hu\n", top, list[top].x, list[top].y ); }*/ free( keyList );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -