/* $Header: /s/parsons/d/fac/goss/cs510/s94/Labs/RCS/xparms.c,v 1.3 1994/02/14 18:13:17 goss Exp $ */ /********************************************************************** * * Written by Chuck Anderson 1992-1993 * Modified by: * Jeff Walls 1993 Added dialog box to print button. * Mike Goss 1994 Mods to work with HP-UX and Motif 1.2 * and select correct visual on machines * with overlay planes **********************************************************************/ /* $Log: xparms.c,v $ * Revision 1.3 1994/02/14 18:13:17 goss * Use default color map if best Pseudocolor visual is also default visual. * This will preserve the readability of the rest of the screen when * running xparms. * * Revision 1.2 1994/01/26 21:07:31 goss * CS510 Spring94 Initial released version * */ #include #include #include #include #include #include #include #include #include #include #include "xparms.h" /********************************************************************** * Limits you may want to change. **********************************************************************/ /* Limits of files */ /*** HARD-CODED UPPER BOUNDS Text widgets, and therefore data files, can have at most 2000 lines each Each line can have at most 200 characters. ***/ #define MAXLINES 1000 /*1000*/ #define MAXLINESIZE 200 #define MAXGRAY 1024 /* maximum number of gray levels allowed */ #define MINCMAP 64 /* minimum colormap size needed */ /* ** Save ourselves some typing when adding XmStrings */ #define XmSDC XmSTRING_DEFAULT_CHARSET Widget g_toplevel, g_verify; /** g_ for global **/ Widget g_drawing_canvas; /* widget into which all graphics are drawn */ GC g_gc; /* graphics context for all graphics operations */ int g_num_gray = 0; /* number of gray levels */ int g_first_gray; /* first colormap entry for gray scale */ Colormap g_cmap; /* colormap used */ int g_cmap_size; /* size of colormap */ unsigned long g_pixels[MAXGRAY]; /* pixels allocated for grayscale */ int g_argc; /* number of program arguments */ char **g_argv; /* pointer to array of program arguments */ /* ** Command to send output to printer */ #ifdef _HPUX_SOURCE #define PRINTCMD "lp -onb" #else #define PRINTCMD "lpr -h" #endif /*hpux*/ /**********************************************************************/ /*********************************************************** * Prototypes ***********************************************************/ /* Other function prototypes defined in this file, not callable by user. */ void process_parm_text(Widget w, Widget widgets[2], XtPointer call_data); void load_file(Widget w, Widget widgets[2], XtPointer call_data); void save_file(Widget w, Widget widgets[2], XtPointer call_data); void process_data_text(Widget w, Widget widgets[2], XtPointer call_data); void canvasinit_callback(Widget w, XtPointer client_data, XmDrawingAreaCallbackStruct *call_data); void canvasredraw_callback(Widget w, Widget canvas, XtPointer call_data); void canvasdump_callback(Widget w, XtPointer string, XtPointer call_data); void quit_callback(Widget w, XtPointer string, XtPointer call_data); void PrintCallback(Widget w, XtPointer name, XtPointer call_data); void NothingCallback(Widget w, XtPointer name, XtPointer call_data); void ViewCallback(Widget w, XtPointer name, XtPointer call_data); typedef struct { Widget filename; Widget filenametext; Widget top; Widget scrolledwindow; Widget text; Widget scroll; Widget apply; Widget save; Widget load; Widget call_data[2]; } all_widgets; main(int argc, char *argv[]) { XtAppContext app_context; Widget canvasframe, canvas, mainwindow, canvasredraw, canvasdump, quit; all_widgets parmw, dataw; XColor color; XGCValues values; Arg wargs[20]; int n; char * user_name; XSetWindowAttributes setwinattr; /* page 93, O'Reilly Vol. 1 */ XVisualInfo vinfo_template; /* template for XGetVisualInfo */ XVisualInfo *vinfo_match; /* visuals matching template */ int deepest; /* index of deepest visual */ int vinfo_match_count; /* count of matching visuals */ Display *display; /* X display pointer */ String fallback_resources[] = { /* default resources */ "Xparms*background: lightgray", "Xparms*foreground: black", NULL }; VisualID dflt_visual, use_visual; /* IDs of dflt and selected visuals*/ /* Initialize the toolkit and display */ XtToolkitInitialize(); app_context = XtCreateApplicationContext(); XtAppSetFallbackResources( app_context, fallback_resources ); display = XtOpenDisplay( app_context, NULL, argv[0], "Xparms", NULL, 0, & argc, argv ); #ifdef XSYNC XSynchronize( display, True ); #endif /* Find the PseudoColor visual with the greatest colormap size */ memset( & vinfo_template, 0, sizeof(vinfo_template) ); /* clear template */ vinfo_template.screen = DefaultScreen( display ); /* set screen */ vinfo_template.class = TrueColor;//PseudoColor; vinfo_match = XGetVisualInfo( display, VisualScreenMask | VisualClassMask, & vinfo_template, & vinfo_match_count ); if ( vinfo_match == NULL ) { fprintf( stderr, "Error: no PseudoColor visual on this X11 server\n" ); exit( 2 ); } deepest = 0; for ( n = 1; n < vinfo_match_count; n++ ) { if ( vinfo_match[n].colormap_size > vinfo_match[deepest].colormap_size ) deepest = n; } if ( vinfo_match[deepest].colormap_size < MINCMAP ) { fprintf( stderr, "Error: biggest PseudoColor colormap on this X11 server is %d" " (%d required)\n", vinfo_match[deepest].colormap_size, MINCMAP ); exit( 2 ); } printf( "Using X11 server PseudoColor visual depth %d, colormap size %d\n", vinfo_match[deepest].depth, vinfo_match[deepest].colormap_size ); /* Get IDs of selected visual and default visual; if they are the same use the default colormap */ use_visual = XVisualIDFromVisual( vinfo_match[deepest].visual ); dflt_visual = XVisualIDFromVisual(DefaultVisualOfScreen(DefaultScreenOfDisplay(display))); if ( use_visual == dflt_visual ) { /* if the same */ printf( "Using default color map\n" ); g_cmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(display)); } else { /* not the same; create color map */ /* Create a color map for the visual */ printf( "Creating new color map\n" ); g_cmap = XCreateColormap( display, DefaultRootWindow(display), vinfo_match[deepest].visual, AllocNone ); } g_cmap_size = vinfo_match[deepest].colormap_size; /* Create the top level window shell */ n = 0; XtSetArg(wargs[n], XmNvisual, vinfo_match[deepest].visual ); n++; XtSetArg(wargs[n], XmNdepth, vinfo_match[deepest].depth ); n++; XtSetArg(wargs[n], XmNcolormap, g_cmap ); n++; g_toplevel = XtAppCreateShell(argv[0], "Xparms", applicationShellWidgetClass, display, wargs, n ); /* Container for the drawing area and parameter side. */ n = 0; XtSetArg(wargs[n], XmNwidth, 900); n++; XtSetArg(wargs[n], XmNheight, 500); n++; mainwindow = XtCreateManagedWidget("mainwindow", xmFormWidgetClass, g_toplevel, wargs, n); /* Create the drawing area widget within the toplevel shell. */ n = 0; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftPosition, 20); n++; XtSetArg(wargs[n], XmNrightPosition, 30); n++; XtSetArg(wargs[n], XmNtopPosition, 0); n++; XtSetArg(wargs[n], XmNbottomPosition, 10); n++; XtSetArg(wargs[n], XmNlabelString, XmStringCreate("Redraw", XmSDC)); n++; canvasredraw = XtCreateManagedWidget("canvasredraw", xmPushButtonWidgetClass, mainwindow, wargs, n); /* ** Create a label widget with the user name on it */ user_name = getenv( "LOGNAME" ); /* get user name */ if ( user_name == NULL ) { /* if not found */ user_name = "(unknown user)"; } n = 0; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftPosition, 30); n++; XtSetArg(wargs[n], XmNrightPosition, 50); n++; XtSetArg(wargs[n], XmNtopPosition, 0); n++; XtSetArg(wargs[n], XmNbottomPosition, 10); n++; XtSetArg(wargs[n], XmNlabelString, XmStringCreate(user_name, XmSDC)); n++; XtCreateManagedWidget("username", xmLabelWidgetClass, mainwindow, wargs, n); /* ** Create the g_verify question dialog */ n = 0; XtSetArg(wargs[n], XmNdialogTitle, XmStringCreate("Question", XmSDC)); n++; XtSetArg(wargs[n], XmNmessageString, XmStringCreate ("What do you want to do with: window.xwd\?", XmSDC)); n++; XtSetArg(wargs[n], XmNokLabelString, XmStringCreate("Print", XmSDC)); n++; XtSetArg(wargs[n], XmNcancelLabelString, XmStringCreate("View", XmSDC)); n++; XtSetArg(wargs[n], XmNhelpLabelString, XmStringCreate("Keep", XmSDC)); n++; XtSetArg(wargs[n], XmNvisual, DefaultVisualOfScreen(DefaultScreenOfDisplay(display)) ); n++; XtSetArg(wargs[n], XmNdepth, DefaultDepthOfScreen(DefaultScreenOfDisplay(display)) ); n++; XtSetArg(wargs[n], XmNcolormap, DefaultColormapOfScreen(DefaultScreenOfDisplay(display)) ); n++; g_verify = XmCreateQuestionDialog(g_toplevel, "g_verify", wargs, n); /* ** Create the quit button */ n = 0; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftPosition, 0); n++; XtSetArg(wargs[n], XmNrightPosition, 10); n++; XtSetArg(wargs[n], XmNtopPosition, 0); n++; XtSetArg(wargs[n], XmNbottomPosition, 10); n++; XtSetArg(wargs[n], XmNlabelString, XmStringCreate("Quit", XmSDC)); n++; quit = XtCreateManagedWidget("quit", xmPushButtonWidgetClass, mainwindow, wargs, n); /* ** Create the file button */ n = 0; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftPosition, 10); n++; XtSetArg(wargs[n], XmNrightPosition, 20); n++; XtSetArg(wargs[n], XmNtopPosition, 0); n++; XtSetArg(wargs[n], XmNbottomPosition, 10); n++; XtSetArg(wargs[n], XmNlabelString, XmStringCreate("File", XmSDC)); n++; canvasdump = XtCreateManagedWidget("canvasdump", xmPushButtonWidgetClass, mainwindow, wargs, n); n = 0; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftPosition, 0); n++; XtSetArg(wargs[n], XmNrightPosition, 50); n++; XtSetArg(wargs[n], XmNtopPosition, 10); n++; XtSetArg(wargs[n], XmNbottomPosition, 99); n++; canvasframe = XtCreateManagedWidget("canvasframe", xmFrameWidgetClass, mainwindow, wargs, n); /* Create the drawing area widget with appropriate depth */ n = 0; canvas = XtCreateManagedWidget("canvas", xmDrawingAreaWidgetClass, canvasframe, wargs, n); g_drawing_canvas = canvas; /* save in global variable */ XtAddCallback(canvas, XmNexposeCallback, (XtCallbackProc) canvasinit_callback, NULL ); /* initialize canvas after 1st expose*/ XtAddCallback(canvasdump, XmNactivateCallback, (XtCallbackProc)canvasdump_callback, (XtPointer)argv[0]); XtAddCallback(quit, XmNactivateCallback, (XtCallbackProc)quit_callback, (XtPointer)argv[0]); XtAddCallback(canvasredraw, XmNactivateCallback, (XtCallbackProc)canvasredraw_callback,canvas); XtAddCallback(g_verify,XmNokCallback, PrintCallback, NULL); XtAddCallback(g_verify,XmNcancelCallback, ViewCallback, NULL); XtAddCallback(g_verify,XmNhelpCallback, NothingCallback, NULL); /* Create text widget for parameter file. */ create_all_widgets(&parmw,mainwindow,process_parm_text,51,75, "parmtop","parmapply","parmload","parmsave", "parmfilename","parmfilenametext","parmscrolledwindow", "parmtext"); /* Create text widget for data file. */ create_all_widgets(&dataw,mainwindow,process_data_text,75,99, "datatop","dataapply","dataload","datasave", "datafilename","datafilenametext","datascrolledwindow", "datatext"); /* Make the widget real. */ XtRealizeWidget(g_toplevel); /* Maintain backing store so window is refreshed when exposed and ** also so xwd will dump entire contents, even when partially covered. ** From O'Reilly Vol. 1, pg 103 Might need to do this for other windows. ** xwd works only for the canvas widget when all are covered. */ setwinattr.backing_store = Always; XChangeWindowAttributes(XtDisplay(g_drawing_canvas), XtWindow(g_drawing_canvas), CWBackingStore, &setwinattr); /* Create graphics context for drawing area widget */ XtSetArg(wargs[0], XmNforeground, &(color.pixel)); XtGetValues(g_drawing_canvas, wargs, 1); values.foreground = color.pixel; g_gc = XCreateGC(XtDisplay(g_drawing_canvas), XtWindow(g_drawing_canvas), GCForeground, &values); /* Save argc and argv for later use */ g_argc = argc; g_argv = argv; /* Enter the infinite loop for processing X events. */ XtAppMainLoop(app_context); } /********************************************************************** **********************************************************************/ void get_width_height(int *width, int *height) { Arg wargs[2]; int n; Dimension w,h; n = 0; XtSetArg(wargs[n], XmNwidth, &w); n++; XtSetArg(wargs[n], XmNheight, &h); n++; XtGetValues(g_drawing_canvas,wargs,2); *width =w; *height = h; } /********************************************************************** **********************************************************************/ create_all_widgets(all_widgets *widgets, Widget mainwindow, void (*process)(), int left, int right, char *top_name, char *apply_name, char *load_name, char *save_name, char *filename_name, char *filenametext_name, char *scrolledwindow_name, char *text_name) { Arg wargs[20]; int n; n = 0; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftPosition, left); n++; XtSetArg(wargs[n], XmNrightPosition, right); n++; XtSetArg(wargs[n], XmNtopPosition, 0); n++; XtSetArg(wargs[n], XmNbottomPosition, 99); n++; widgets->top = XtCreateManagedWidget(top_name,xmFormWidgetClass, mainwindow, wargs, n); /* Create buttons. */ n = 0; XtSetArg(wargs[n], XmNlabelString, XmStringCreate("Apply", XmSDC)); n++; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftPosition, 0); n++; XtSetArg(wargs[n], XmNrightPosition, 30); n++; XtSetArg(wargs[n], XmNtopPosition, 0); n++; XtSetArg(wargs[n], XmNbottomPosition, 5); n++; widgets->apply = XtCreateManagedWidget(apply_name, xmPushButtonWidgetClass, widgets->top, wargs, n); XtAddCallback(widgets->apply,XmNactivateCallback,process,widgets->call_data); n = 0; XtSetArg(wargs[n], XmNlabelString, XmStringCreate("Load", XmSDC)); n++; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftPosition, 33); n++; XtSetArg(wargs[n], XmNrightPosition, 64); n++; XtSetArg(wargs[n], XmNtopPosition, 0); n++; XtSetArg(wargs[n], XmNbottomPosition, 5); n++; widgets->load = XtCreateManagedWidget(load_name, xmPushButtonWidgetClass, widgets->top, wargs, n); XtAddCallback(widgets->load, XmNactivateCallback, (XtCallbackProc)load_file, widgets->call_data); n = 0; XtSetArg(wargs[n], XmNlabelString, XmStringCreate("Save", XmSDC)); n++; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNleftPosition, 67); n++; XtSetArg(wargs[n], XmNrightPosition, 99); n++; XtSetArg(wargs[n], XmNtopPosition, 0); n++; XtSetArg(wargs[n], XmNbottomPosition, 5); n++; widgets->save = XtCreateManagedWidget(save_name, xmPushButtonWidgetClass, widgets->top, wargs, n); XtAddCallback(widgets->save, XmNactivateCallback, (XtCallbackProc)save_file, widgets->call_data); /* Text widget containing parameter file name */ n = 0; XtSetArg(wargs[n], XmNscrollingPolicy, XmAUTOMATIC); n++; XtSetArg(wargs[n], XmNheight, 60); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopPosition, 5); n++; XtSetArg(wargs[n], XmNbottomPosition, 15); n++; widgets->filename = XtCreateManagedWidget(filename_name, xmScrolledWindowWidgetClass, widgets->top, wargs, n); widgets->filenametext = XtCreateManagedWidget(filenametext_name, xmTextWidgetClass, widgets->filename, NULL,0); n = 0; XtSetArg(wargs[n], XmNworkWindow, widgets->filenametext); n++; XtSetValues(widgets->filename, wargs, n); n = 0; XtSetArg(wargs[n], XmNscrollingPolicy, XmAUTOMATIC); n++; XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg(wargs[n], XmNtopPosition, 15); n++; XtSetArg(wargs[n], XmNbottomPosition, 99); n++; widgets->scrolledwindow = XtCreateManagedWidget(scrolledwindow_name, xmScrolledWindowWidgetClass, widgets->top, wargs, n); n = 0; XtSetArg(wargs[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; widgets->text = XtCreateManagedWidget(text_name, xmTextWidgetClass, widgets->scrolledwindow, wargs, n); n = 0; XtSetArg(wargs[n], XmNworkWindow, widgets->text); n++; XtSetValues(widgets->scrolledwindow, wargs, n); widgets->call_data[0] = widgets->filenametext; widgets->call_data[1] = widgets->text; } /********************************************************************** * Called to change the current gray level to a value in [0.0,1.0] **********************************************************************/ void set_intensity(float I) { long gray_val; unsigned long foreground; gray_val = (int) (I * g_num_gray); foreground = g_first_gray + ( gray_val < 0 ? 0 : ( gray_val >= g_num_gray ? g_num_gray-1 : gray_val )); XSetForeground( XtDisplay(g_drawing_canvas), g_gc, foreground ); } /********************************************************************** * User-callable routine. Changing the color map. **********************************************************************/ void change_colormap_to_grayscale(int num_levels) { int i, j; Status status; int max_levels; XColor colors[MAXGRAY]; Display *display; display = XtDisplay( g_toplevel ); /* Release any previously allocated colors */ if ( g_num_gray != 0 ) { XFreeColors( display, g_cmap, g_pixels, g_num_gray, 0 ); } /* Find the max number of levels supported by the colormap for this window */ max_levels = min( g_cmap_size, MAXGRAY ); g_num_gray = min( max_levels, num_levels ); /* Try to allocate sufficient color cells in current color map (doesn't overwrite colors already in use within this window by Motif) */ while( g_num_gray >= 16 ) { if ( XAllocColorCells( display, g_cmap, True, NULL, 0, g_pixels, g_num_gray ) ) break; --g_num_gray; } if ( g_num_gray < 16 ) { fprintf( stderr, "Error: fewer than 16 contiguous color map entries\n" " available for gray scale\n" ); exit( 2 ); } printf( "Allocated %d level gray map (%d levels requested)\n", g_num_gray, num_levels ); /* Set color map entries for gray scale */ g_first_gray = min(g_pixels[0],g_pixels[g_num_gray-1]); printf( "Using color map cells from %lu to %lu.\n", g_pixels[0], g_pixels[g_num_gray-1] ); /* Build gray scale */ for ( i = 0; i < g_num_gray; i++) { colors[i].pixel = g_first_gray+i; colors[i].flags = DoRed | DoGreen | DoBlue; colors[i].red = colors[i].green = colors[i].blue = 0xffffL * (long) i / (g_num_gray-1); } XStoreColors(display, g_cmap, colors, g_num_gray); /* Set window and canvas background to white end of gray scale, and initial foreground drawing color to black end of gray scale */ XSetWindowBackground( display, XtWindow(g_drawing_canvas), g_first_gray+g_num_gray-1 ); XSetBackground( display, g_gc, g_first_gray+g_num_gray-1 ); XSetForeground( display, g_gc, g_first_gray ); XClearWindow( display, XtWindow(g_drawing_canvas) ); } /**********************************************************************/ void clear_window(void) { XClearWindow(XtDisplay(g_drawing_canvas),XtWindow(g_drawing_canvas)); } /**********************************************************************/ void draw_line(int x1, int y1, int x2, int y2) { XDrawLine(XtDisplay(g_drawing_canvas), XtWindow(g_drawing_canvas), g_gc, x1,y1, x2,y2); } /**********************************************************************/ void draw_disk(int x, int y, int radius) { XFillArc(XtDisplay(g_drawing_canvas), XtWindow(g_drawing_canvas), g_gc, x, y, radius, radius, 0, 64*360); } /**********************************************************************/ int min(int a, int b) { return ((a < b) ? a : b); } /**********************************************************************/ int max(int a, int b) { return ((a > b) ? a : b); } /********************************************************************** * Called to draw a pixel at u,v at intensity I (between 0 and 1) **********************************************************************/ void set_pixel(int u, int v, float I) { set_intensity( I ); XDrawPoint(XtDisplay(g_drawing_canvas),XtWindow(g_drawing_canvas), g_gc, u, v); } /********************************************************************** * Called to draw a pixel at u,v using cmap address addr **********************************************************************/ void set_pixel_addr(int u, int v, int addr) { XGCValues values; values.foreground = min(255, addr); values.function = GXcopy; XChangeGC(XtDisplay(g_drawing_canvas), g_gc, GCForeground | GCFunction, &values); XDrawPoint(XtDisplay(g_drawing_canvas),XtWindow(g_drawing_canvas), g_gc, u, v); } /********************************************************************** * Callbacks **********************************************************************/ /********************************************************************** * Called when REDRAW button pressed. **********************************************************************/ void canvasredraw_callback(Widget w, Widget canvas, XtPointer call_data) { int width, height; int i; get_width_height(&width,&height); if (width < height) height = width; else width = height; redraw(width,height); XFlush(XtDisplay(w)); } /* ** This is called when the user presses the "File" button and then selects ** the "Keep" option from the Question Dialog */ void NothingCallback (Widget w, XtPointer name, XtPointer call_data) { XtUnmanageChild (w); } /* ** This is called when the user presses the "File" button and then selects ** the "Print" option from the Question Dialog */ void PrintCallback (Widget w, XtPointer name, XtPointer call_data) { static char print_cmd[] = /* define command string */ "( xwd2ps window.xwd > window.ps ;" PRINTCMD " window.ps ;" " echo 'Done converting and printing your picture.' ;" " echo 'window.xwd and window.ps remain in your directory.' ) &"; printf("Converting to postscript and printing in background...\n"); /* printf( "Issuing print command: %s\n", command );*/ system( print_cmd ); } /* ** This is called when the user presses the "File" button and then selects ** the "View" option from the Question Dialog */ void ViewCallback (Widget w, XtPointer name, XtPointer call_data) { /* ** get rid of our Question Dialog */ XtUnmanageChild (w); XFlush (XtDisplay (g_toplevel)); printf("Preparing to view...\n"); /* ** Do not do this in the background because it takes some time for the ** image to appear, so the user could get confused and hit the button ** a few times and get many many windows :) */ system("xwud -in window.xwd"); /* ** re-manage the widget so that the user has the option to print it at ** this time without having to select "Print" again */ XtManageChild (w); } void canvasinit_callback(Widget w, XtPointer client_data, XmDrawingAreaCallbackStruct *call_data) { static first_time = 1; /* true if first time called */ if ( first_time ) { setup_drawing_area( g_argc, g_argv ); /* User routine to init canvas */ first_time = 0; /* don't do it again */ } } void canvasdump_callback(Widget w, XtPointer name, XtPointer call_data) { char string[100]; char response[80]; sprintf(string,"xwd -id 0x%x -frame -out window.xwd", XtWindow(g_toplevel) ); /* sprintf(string,"xwd -name %s -frame -out window.xwd",name);*/ printf("Dumping window ID 0x%x...\n", XtWindow(g_toplevel) ); /* printf("String sent to system is %s\n",string);*/ system(string); printf("Window dump is in window.xwd\n"); /* ** Make our question dialog visible */ XtManageChild (g_verify); } /********************************************************************** * Exit the program gracefully **********************************************************************/ void quit_callback(Widget w, XtPointer name, XtPointer call_data) { exit(0); } /********************************************************************** * Called when APPLY button of parameter widgets pressed. **********************************************************************/ void process_parm_text(Widget w, Widget widgets[2], XtPointer call_data) { char *string = XmTextGetString(widgets[1]); printf("In process_parm_text %s\n",string); process_parameters(string); XtFree(string); } /********************************************************************** * Called when APPLY button of data widgets pressed. **********************************************************************/ void process_data_text(Widget w, Widget widgets[2], XtPointer call_data) { char *string = XmTextGetString(widgets[1]); process_data(string); XtFree(string); } /********************************************************************** * Called when either LOAD button is pressed. **********************************************************************/ void load_file(Widget w, Widget widgets[2], XtPointer call_data) { char *filename = XmTextGetString(widgets[0]); FILE *file; char contents[MAXLINES*MAXLINESIZE] = "", line[MAXLINESIZE]; Arg wargs[20]; int i, n; if ((file = fopen(filename,"r")) == NULL) { printf("Can't open %s\n",filename); return; } i = 0; while ((fgets(line,MAXLINESIZE-1,file)) != NULL && i < MAXLINES) { strcat(contents,line); i++; } if (i == MAXLINES) printf("Warning: Too many lines in %s\n",filename); fclose(file); XmTextSetString(widgets[1],contents); } /********************************************************************** * Called when either SAVE button pressed. **********************************************************************/ void save_file(Widget w, Widget widgets[2], XtPointer call_data) { char *filename = XmTextGetString(widgets[0]); char *contents; FILE *file; if ((file = fopen(filename,"w")) == NULL) { printf("Can't open %s\n",filename); return; } contents = XmTextGetString(widgets[1]); fputs(contents,file); fclose(file); } /******************************************************************* * x_Beep will simply sound the system bell to alert you of anything * you want it to alert you to. * This must be done in xparms.c unless you want to pass g_toplevel * around to your application ********************************************************************/ void x_Beep () { XBell(XtDisplay(g_toplevel), 100); }