/* *H * Title cmprss - User interface to the "arch" script * for file compression or uncompression *h *C * Wesley W. Wooten, Ph.D. * Saint Agnes Medical Center * Fresno, CA * * Picker International, Inc. Ohio Imaging Nuclear Medicine Division * Bedford Heights, Ohio 44128-5443 * Copyright 1990-1994 * All Rights Reserved *c *R * %W% %G% * * Revision History: * 1.1 08/04/90 J. Brack (imager.c) * 1.2 05/14/92 J. Brack (imager.c) * Cleanup for release. * 1.3 03/24/93 J. Brack (imager.c) * Port to Motif and Baseline 6. * 2.0 05/15/95 W. Wooten (cmprss.c) * Modify imager.c into first version of cmprss.c * 2.1 06/26/95 W. Wooten * call to version 2.3 of arch instead of arch3VP * use -f flag in call to arch so that individual files * will be processed instead of directories * Increase maximum number of files to 100, (that can be * passed from the workbench to the arch script). * 2.2 08/18/95 W. Wooten / Eugene Mah * check for gated files, if found, add a wild card to * the file name so that all intervals will be included. * 2.2a 08/22/95 W. Wooten * fix up to process a lightbox of a gated, without * looking for all of the intervals. *r *D * Description: * Use a widget to allow the user to select either the Compress or Uncompress * function. * Get file names from the workbench, and pass to the arch script * This code is not very clean because it was built by modifying the * "imager.c" program, and there is lots of unnecessary "stuff" left over * from the "imager" program. * * x resources are defined in the file Cmprss. To use cmprss, you must * copy the file "Cmprss" into the $XAPPLRESDIR directory (/prism/site/adf/) * also copy the file "cmprss.hlp" into the $DATA/help/english directory * *d */ /* Unix includes */ #include #include #include /* X Window and Xt Intrinsics includes */ #include #include #include /* OSF/Motif Widget includes */ #include #include #include #include #include #include #include #include /* Picker includes */ #include "OIXt.h" /* image display window definitions */ #include "OIlib.h" /* library functions */ #include "dials.h" /* interface to Control */ #include "iib.h" /* Odyssey image file format */ #include "index.h" /* Odyssey Clinical Index format */ #include "res_util.h" /* X resource utilities */ #include "oi_cursor.h" /* mouse cursors */ #include "oi_edit.h" /* keyboard mappings for Text widget */ /* X Windows control structures */ static XtAppContext app; /* applications context */ static Display *display; /* display device */ static XEvent report; /* X window event reports */ static XFontStruct *img_font; /* Font for imager window */ /* Xt and Xw Toolkit stuff */ #define NUM_BUT 4 /* number of buttons */ static Widget toplevel; /* top level widget */ static Widget FormW; /* Form holds all other widgets */ static Widget RowColW; /* Row/Column widget for buttons */ static Widget PButtonW[NUM_BUT];/* array of pushbutton widgets */ static Widget HelpShell; /* shell for help window */ static Cursor dot, arrow; /* mouse cursors */ /* Index structure pointers */ static struct pi_s *top; /* top of catalog list */ static struct ci_s *catalog; /* catalog pointer */ static struct pi_s *patient; /* patient index pointer */ /* general varible storage */ static char idxfile[80]; /* name of index input file */ static char idnum[4]; /* our workbench ID */ static char title_buf[40]; /* our Title */ static char title[] = "Compression Utility "; static char our_class[] = "Cmprss"; /* resource class */ static char our_widget[] = "cmprss"; /* use widget name "cmprss" in order to find resources in the Cmprss class */ static struct iib iib; /* IIB data */ static struct iib *piib = &iib; /* pointer to IIB data */ static int popup_x, popup_y; /* coords for popups */ static char filelist[103][40]; /* list of files to be passed */ static char *list[103]; /* in execvp to arch */ /* String resources */ static char *helppath; /* path to help file */ static char *helpfilename; /* name of help file */ static char *no_files, *no_patients; static struct strlod imager_strings[] = { {(char *)"HelpPath", &helppath }, {(char *)"HelpFilename", &helpfilename }, {(char *)"NoFiles", &no_files }, {(char *)"NoPatients", &no_patients }, }; #define NSTRINGS sizeof(imager_strings)/sizeof(struct strlod) /* Font resources */ static struct fontlod imager_fonts[] = { {(char *)"ImagerFont",&img_font } }; #define NFONTS sizeof(imager_fonts)/sizeof(struct fontlod) /******************************************************************************/ /* This function is called before a popup is created. It locates the current control panel and loads the variables "popup_x" and "popup_y" with the coordinates of the lower left corner of the panel. Popups are passed these coordinates as an origin for their application shells. We call this often because the user may "move" the panel between invocations of the popups. */ static void get_popup_coords() { Window ph_shell; XWindowAttributes shell_att; /* The "get_gramps()" function is in OIlib. Given the window of a widget, it returns the most ancestral (hence "gramps") X window containing the widget. */ ph_shell = get_gramps(display,XtWindow(toplevel)); XGetWindowAttributes(display,ph_shell,&shell_att); popup_x = shell_att.x; /* grab left edge X */ popup_y = shell_att.y + shell_att.height; /* get top edge Y, add height */ } /******************************************************************************/ /* Clean up the user interface before exiting the program. */ static void done_cb() { XFlush(display); /* flush all pending X operations on server */ exit( 0 ); /* and exit (the "0" tells Workbench we are happy) */ } /******************************************************************************/ /* This function sets a widget to its "insensitive mode". */ static void go_insensitive(button) Widget button; { XtSetSensitive(button,False); /* deactivate */ if(XtWindow(button) != NULL) XDefineCursor(display,XtWindow(button),dot); /* assign dot */ } /******************************************************************************/ /* This function sets a widget to its "sensitive mode". */ static void go_sensitive(button) Widget button; { XtSetSensitive(button,True); /* activate */ XDefineCursor(display,XtWindow(button),arrow); /* point to it */ } /******************************************************************************/ /* This function is called when the "Compress Workbench" button is hit */ static void cmp_cb() { strcpy (filelist[1], "-C"); list[1]=filelist[1]; execvp (list[0],list); done_cb(); } /******************************************************************************/ /* This function is called when the "Uncompress Workbench" button is hit */ static void uncmp_cb() { strcpy (filelist[1], "-U"); list[1]=filelist[1]; execvp (list[0],list); done_cb(); } /******************************************************************************/ /* This function is called when the "Help" button is hit. It calls the OIlib oi_help() function, passing it the name of a text file containing information of note. Note that the file "cmprss.hlp" must be in the $DATA directory for the help function to work properly! */ static void help_cb() { char hfn[80]; strcpy(hfn,helppath); strcat(hfn,helpfilename); get_popup_coords(); HelpShell = oi_help(popup_x,popup_y,hfn,HELP_WORKBENCH); } /******************************************************************************/ main(argc,argv) int argc; char *argv[]; { #ifdef ardent /* this means we do this only on Titan-based Odysseys */ extern char getopt(); #endif extern char *optarg; Arg arglist[20]; int i; int idx; char flag; char *lab; Bool xt_flag; XtTranslations etable; struct btbl { /* Button definition table */ char *name; /* "name" of button */ void *call; /* button callback */ }; static struct btbl bt[NUM_BUT] = { /* Push button definitions */ { "compressn", cmp_cb }, { "uncompressn", uncmp_cb }, { "help", help_cb }, { "done", done_cb } }; /* * Report version info if requested. * Version info has been requested if cmprss -v was used * Check the first argument, and if it's a -v, then print * the version info and quit. If not, then continue on. */ if (argc==2 && !strcmp(argv[1], "-v")) { fprintf(stdout, "%s version 2.2b", argv[0]); exit(0); } /* Do the general Xwindows environment setup for the user interface. Initialize toolkit making this application a member of the "Cmprss" class. See the file "Cmprss" for resource definitions! */ toplevel = XtInitialize(our_widget,our_class,NULL,NULL,&argc,argv); display = XtDisplay(toplevel); /* obtain the display ID */ app = XtWidgetToApplicationContext(toplevel); /* Tell the vendor shell widget and mwm that we want our "exit callback" to be called when someone closes us with the mwm "close" function. The mwm close is chosen from the menu that appears when you click on (or double-click) the "-" gadget in the upper left corner of the mwm titlebar. */ XtSetArg(arglist[0],XmNdeleteResponse,XmDO_NOTHING); XtSetValues(toplevel,arglist,1); XmAddWMProtocolCallback(toplevel, XmInternAtom(display,"WM_DELETE_WINDOW",True),done_cb,NULL); /* Get X resources from the "Cmprss" file in $XAPPLRESDIR (/prism/site/adf) */ oi_strings(display,argv[0],our_class,our_widget,imager_strings,NSTRINGS); oi_fonts(display,argv[0],our_class,our_widget,imager_fonts,NFONTS); /* Parse the Workbench command line. */ while((flag = getopt(argc,argv,WORKBENCH_OPTIONS)) != -1) switch(flag) { case 'N': /* get workbench number from "-N" switch */ strcpy(idnum,optarg); break; case 'I': /* get name of index input file from "-I" */ strcpy(idxfile,optarg); break; } /* set up arguments for the execvp to the arch script */ strcpy (filelist[0],"/prism/site/arch"); list[0]=filelist[0]; /* The contents of filelist[1] will be set to either "-C" or "-U" later, after a button is pushed. The contents of filelist[2] will be set to "-f" (now) so that arch will process files instead of directories, then walk the list of files on the workbench and load the rest of the patients to be compressed into filelist[3], filelist[4], ... */ strcpy (filelist[2], "-f"); list[2]=filelist[2]; catalog = NULL; /* no catalog references yet */ patient = NULL; /* no patient references yet */ if((top = LoadInput(idxfile)) == NULL) { fprintf(stderr,no_files); done_cb(); } catalog = NextPatient(top,&patient); if(catalog == NULL) { fprintf(stderr,no_patients); done_cb(); } i=3; do { strcpy (filelist[i],"/"); strcat (filelist[i],catalog->disk); strcat (filelist[i],"/P"); strcat (filelist[i],catalog->asn); strcat (filelist[i],"/"); strcat (filelist[i],patient->filename); if(((patient->typ & IIBPRJ) >0) | ((patient->typ & IIBIMG) >0)) if((patient->at & IIBEKG) >0) strcat(filelist[i],"_*"); list[i]=filelist[i]; i++; list[i]=NULL; if(i > 102) break; } while (( patient= NextFile(patient,&catalog)) != NULL); /* Set our name and Workbench number into the mwm titlebar */ strcpy(title_buf,title); strcat(title_buf,idnum); XtSetArg(arglist[0],XtNtitle,title_buf); XtSetValues(toplevel,arglist,1); /* Make a "Form" widget to contain all other widgets and manage their geometry and layout requirements. */ XtSetArg(arglist[0],XmNshadowThickness,0); FormW = XtCreateManagedWidget("Form",xmFormWidgetClass,toplevel,arglist,1); /* Use a Row and Column manager under the name that will manage the pushbutton geometries and layout. */ i = 0; XtSetArg(arglist[i],XmNleftAttachment,XmATTACH_FORM);i++; XtSetArg(arglist[i],XmNtopAttachment,XmATTACH_FORM);i++; XtSetArg(arglist[i],XmNnumColumns,1);i++; XtSetArg(arglist[i],XmNorientation,XmVERTICAL);i++; XtSetArg(arglist[i],XmNpacking,XmPACK_COLUMN);i++; XtSetArg(arglist[i],XmNentryAlignment,XmALIGNMENT_CENTER);i++; RowColW = XtCreateManagedWidget("RowCol",xmRowColumnWidgetClass, FormW,arglist,i); /* Create the pushbuttons within the RowCol in a table driven loop. */ for(idx = 0; idx < NUM_BUT; idx++) { i = 0; PButtonW[idx] = XtCreateManagedWidget(bt[idx].name, xmPushButtonWidgetClass,RowColW,arglist,i); XtAddCallback(PButtonW[idx],XmNactivateCallback,bt[idx].call,NULL); } /* Realize Widgets */ XtRealizeWidget(toplevel); /* assign mouse cursors */ dot = oi_cursor(display,XC_dot,NULL,NULL); XDefineCursor(display,XtWindow(FormW),dot); /* assign dot to Form */ arrow = oi_cursor(display,XC_top_left_arrow,NULL,NULL); XDefineCursor(display,XtWindow(RowColW),arrow); /* arrow on buttons */ /* Enter an infinite loop, waiting for things to happen. */ while(True) { /* start infinite loop */ XtNextEvent(&report); /* read an X event */ xt_flag = True; /* assume it is an Xt (widget) event */ /* Xt and/or Xm Toolkit events are handled here */ if(xt_flag) XtDispatchEvent(&report); } /* endwhile events are queued */ } /* end main */