1 #include "SUMA_suma.h"
2 
3 /* local proto */
4 static char * read_file_text(FILE * fp);  /* 29 Jun 2012 [rickr] */
5 
usage_prompt_user(SUMA_GENERIC_ARGV_PARSE * ps)6 void usage_prompt_user (SUMA_GENERIC_ARGV_PARSE *ps)
7 {
8       static char FuncName[]={"usage_prompt_user"};
9       int i;
10       printf (
11          "\n"
12          "Mostly replaced by prompt_popup for more customization.\n"
13          "Usage: prompt_user <-pause MESSAGE> \n"
14          "  -pause MESSAGE: Pops a window prompting the user with MESSAGE.\n"
15          "                  Program does not return until user responds.\n"
16          "                  note: if MESSAGE is '-', it is read from stdin\n"
17          "  -timeout TT: Timeout in seconds of prompt message. Default answer\n"
18          "               is returned if TT seconds elapse without user\n"
19          "               input.\n"
20          "  -to TT: Same as -timeout TT\n"
21          "\n");
22 
23       printf("       Ziad S. Saad SSCC/NIMH/NIH saadz@mail.nih.gov     \n");
24       exit(0);
25 }
26 
SUMA_prompt_user_ParseInput(char * argv[],int argc,SUMA_GENERIC_ARGV_PARSE * ps)27 SUMA_GENERIC_PROG_OPTIONS_STRUCT *SUMA_prompt_user_ParseInput(
28    char *argv[], int argc, SUMA_GENERIC_ARGV_PARSE *ps)
29 {
30    static char FuncName[]={"SUMA_prompt_user_ParseInput"};
31    SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt=NULL;
32    int kar;
33    SUMA_Boolean brk;
34    SUMA_Boolean LocalHead = NOPE;
35 
36    SUMA_ENTRY;
37 
38    Opt = SUMA_Alloc_Generic_Prog_Options_Struct();
39    Opt->ps = ps;  /* just hold it there for convenience */
40    Opt->flt1 = -1.0;
41    kar = 1;
42    brk = NOPE;
43 	while (kar < argc) { /* loop accross command ine options */
44 		/*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
45 		if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
46 			 ps->hverb = 1;
47           usage_prompt_user(ps);
48           exit (0);
49 		}
50 
51 		SUMA_SKIP_COMMON_OPTIONS(brk, kar);
52 
53       if (!brk && (strcmp(argv[kar], "-debug") == 0))
54       {
55          if (kar+1 >= argc)
56          {
57             fprintf (SUMA_STDERR, "need a number after -debug \n");
58             exit (1);
59          }
60 
61          Opt->debug = atoi(argv[++kar]);
62          brk = YUP;
63       }
64 
65       if (!brk && (strcmp(argv[kar], "-pause") == 0))
66       {
67          if (kar+1 >= argc)
68          {
69             fprintf (SUMA_STDERR, "need a string after -pause \n");
70             exit (1);
71          }
72 
73          Opt->b1 = 1;
74          Opt->in_name = argv[++kar];
75          brk = YUP;
76 
77          if (!strcmp(Opt->in_name, "-")) Opt->in_name = read_file_text(stdin);
78       }
79 
80       if (!brk && (
81             (strcmp(argv[kar], "-timeout") == 0) ||
82             (strcmp(argv[kar], "-to") == 0)) )
83       {
84          if (kar+1 >= argc)
85          {
86             fprintf (SUMA_STDERR,
87                      "need a time in seconds after -timeout/-to \n");
88             exit (1);
89          }
90 
91          Opt->flt1 = atof(argv[++kar]);
92          brk = YUP;
93       }
94 
95       if (!brk && !ps->arg_checked[kar]) {
96 			SUMA_S_Errv("Option %s not understood.\n"
97                      "Try -help for usage\n",
98                      argv[kar]);
99 			exit (1);
100 		} else {
101 			brk = NOPE;
102 			kar ++;
103 		}
104    }
105 
106    SUMA_RETURN(Opt);
107 }
108 
109 /* return all of fp (stdin, probably) in a string */
read_file_text(FILE * fp)110 static char * read_file_text(FILE * fp)
111 {
112    static char FuncName[]={"read_file_text"};
113    char * str, ch;
114    int    i, len, nalloc;
115 
116    SUMA_ENTRY;
117 
118    if ( ! fp ) SUMA_RETURN(NULL);
119 
120    str = NULL;
121    len = 0;
122    nalloc = 1;  /* add space for nul term */
123    while ( ! feof(fp) ) {
124       nalloc += 100; /* read block size */
125       str = realloc(str, nalloc * sizeof(char));
126       if( !str ) {
127          fprintf(stderr,"** RFT alloc fail on len %d\n", nalloc);
128          SUMA_RETURN(NULL);
129       }
130       for( i=0; i < 100 && !feof(fp); i++ )
131          str[len++] = fgetc(fp);
132       if( feof(fp) ) len--;
133    }
134    str[len] = '\0'; /* terminate */
135 
136    SUMA_RETURN(str);
137 }
138 
main(int argc,char * argv[])139 int main (int argc,char *argv[])
140 {/* Main */
141    static char FuncName[]={"prompt_user"};
142    SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;
143    SUMA_GENERIC_ARGV_PARSE *ps=NULL;
144    char * esc_str = NULL;
145    int ii;
146    Widget w=NULL;
147    XtAppContext    app;
148    XEvent ev;
149    XtInputMask pp;
150    SUMA_Boolean LocalHead = NOPE;
151 
152    SUMA_STANDALONE_INIT;
153 	SUMA_mainENTRY;
154 
155    /* Allocate space for DO structure */
156 	SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
157    ps = SUMA_Parse_IO_Args(argc, argv, "");
158 
159    if (argc < 2) {
160       usage_prompt_user(ps);
161       exit (1);
162    }
163 
164    Opt = SUMA_prompt_user_ParseInput (argv, argc, ps);
165 
166    w = XtOpenApplication(&app, "prompt_user",
167                            NULL, 0, &argc, argv,
168                            SUMA_get_fallbackResources(),
169                            topLevelShellWidgetClass, NULL, 0);
170 
171    switch (Opt->b1) {
172       case 1:
173          /* apply some escape characters     31 Jul 2009 [rickr] */
174          esc_str = unescape_unix_str(Opt->in_name);
175          ii = SUMA_PauseForUser(w, esc_str, SWP_POINTER_LEFT_BOTTOM,
176                                 &app, 1, Opt->flt1);
177          fprintf(SUMA_STDOUT,"%d\n", ii);
178          break;
179       default:
180          SUMA_S_Err("Bad opt");
181          exit(1);
182 
183    }
184 
185    /* because you have no XtAppMainLoop, you'll need to process the next
186    event for when the XtDestroy command on w's child takes effect. So you'll
187    just have this zombie widget that stares at you.
188    In this simple command line program, the widget dies anyway when you
189    exit the program, so the call below is a teaching moment for when
190    functions like SUMA_PauseForUser are called from programs without an
191    XtAppMainLoop.
192    See also SUMA_PAUSE_PROMPT macro */
193 
194    while ((pp = XtAppPending(app))) {
195       XtAppProcessEvent(app, pp);
196    }
197 
198    if (Opt->debug > 2) LocalHead = YUP;
199    if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
200    if (Opt) Opt = SUMA_Free_Generic_Prog_Options_Struct(Opt);
201    if (!SUMA_Free_CommonFields(SUMAg_CF))
202       SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
203 
204    if( esc_str ) free(esc_str);
205 
206    exit(0);
207 
208 }
209