1 /* $Id: cdkmentry.c,v 1.14 2016/12/04 15:22:16 tom Exp $ */
2 
3 #include <cdk_test.h>
4 
5 #ifdef XCURSES
6 char *XCursesProgramName = "cdkmentry";
7 #endif
8 
9 /*
10  * Declare file local prototypes.
11  */
12 static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
13 
14 /*
15  * Define file local variables.
16  */
17 static const char *FPUsage = "-f Field Width -s Screen Rows -v Virtual Rows [-d Display Type] [-F Field Character] [-i Initial Value] [-m Minimum Length] [-T Title] [-L Label] [-B Buttons] [-O Output file] [-X X Position] [-Y Y Position] [-N] [-S]";
18 
19 /*
20  *
21  */
main(int argc,char ** argv)22 int main (int argc, char **argv)
23 {
24    /* *INDENT-EQLS* */
25    CDKSCREEN *cdkScreen         = 0;
26    CDKMENTRY *widget            = 0;
27    CDKBUTTONBOX *buttonWidget   = 0;
28    chtype *holder               = 0;
29    chtype fieldAttr             = 0;
30    char *answer                 = 0;
31    char *CDK_WIDGET_COLOR       = 0;
32    char *temp                   = 0;
33    char filler                  = '.';
34    EDisplayType dType           = vMIXED;
35    int buttonCount              = 0;
36    int selection                = 0;
37    int shadowHeight             = 0;
38    FILE *fp                     = stderr;
39    char **buttonList            = 0;
40    int j1, j2;
41 
42    CDK_PARAMS params;
43    boolean boxWidget;
44    boolean shadowWidget;
45    char *buttons;
46    char *initValue;
47    char *label;
48    char *outputFile;
49    char *tempFiller;
50    char *title;
51    int fieldWidth;
52    int min;
53    int screenRows;
54    int virtualRows;
55    int xpos;
56    int ypos;
57 
58    CDKparseParams (argc, argv, &params, "d:f:i:m:s:v:B:F:L:O:T:" CDK_MIN_PARAMS);
59 
60    /* *INDENT-EQLS* */
61    xpos         = CDKparamValue (&params, 'X', CENTER);
62    ypos         = CDKparamValue (&params, 'Y', CENTER);
63    boxWidget    = CDKparamValue (&params, 'N', TRUE);
64    shadowWidget = CDKparamValue (&params, 'S', FALSE);
65    fieldWidth   = CDKparamValue (&params, 'f', 0);
66    min          = CDKparamValue (&params, 'm', 0);
67    screenRows   = CDKparamValue (&params, 's', 0);
68    virtualRows  = CDKparamValue (&params, 'v', 0);
69    initValue    = CDKparamString (&params, 'i');
70    buttons      = CDKparamString (&params, 'B');
71    tempFiller   = CDKparamString (&params, 'F');
72    label        = CDKparamString (&params, 'L');
73    outputFile   = CDKparamString (&params, 'O');
74    title        = CDKparamString (&params, 'T');
75 
76    if ((temp = CDKparamString (&params, 'd')) != 0)
77       dType = char2DisplayType (temp);
78 
79    /* Make sure all the command line parameters were provided. */
80    if ((fieldWidth <= 0) || (screenRows <= 0) || (virtualRows <= 0))
81    {
82       fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
83       ExitProgram (CLI_ERROR);
84    }
85 
86    /* If the user asked for an output file, try to open it. */
87    if (outputFile != 0)
88    {
89       if ((fp = fopen (outputFile, "w")) == 0)
90       {
91 	 fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
92 	 ExitProgram (CLI_ERROR);
93       }
94    }
95 
96    cdkScreen = initCDKScreen (NULL);
97 
98    /* Start color. */
99    initCDKColor ();
100 
101    /* Check if the user wants to set the background of the main screen. */
102    if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
103    {
104       holder = char2Chtype (temp, &j1, &j2);
105       wbkgd (cdkScreen->window, holder[0]);
106       wrefresh (cdkScreen->window);
107       freeChtype (holder);
108    }
109 
110    /* Get the widget color background color. */
111    if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
112    {
113       CDK_WIDGET_COLOR = 0;
114    }
115 
116    /* If the set the filler character, set it now. */
117    if (tempFiller != 0)
118    {
119       holder = char2Chtype (tempFiller, &j1, &j2);
120       fieldAttr = A_ATTRIBUTES & holder[0];
121       filler = (char)holder[0];
122       freeChtype (holder);
123    }
124    /* Create the mentry widget. */
125    widget = newCDKMentry (cdkScreen, xpos, ypos,
126 			  title, label,
127 			  fieldAttr,
128 			  (chtype)filler | fieldAttr,
129 			  dType, fieldWidth,
130 			  screenRows, virtualRows,
131 			  min, boxWidget, shadowWidget);
132 
133    /* Check to make sure we created the dialog box. */
134    if (widget == 0)
135    {
136       /* Shut down curses and CDK. */
137       destroyCDKScreen (cdkScreen);
138       endCDK ();
139 
140       fprintf (stderr,
141 	       "Error: Could not create the multiple line entry field. "
142 	       "Is the window too small?\n");
143 
144       ExitProgram (CLI_ERROR);
145    }
146 
147    /* Split the buttons if they supplied some. */
148    if (buttons != 0)
149    {
150       buttonList = CDKsplitString (buttons, '\n');
151       buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
152 
153       /* We need to create a buttonbox widget. */
154       buttonWidget = newCDKButtonbox (cdkScreen,
155 				      getbegx (widget->win),
156 				      (getbegy (widget->win)
157 				       + widget->boxHeight - 1),
158 				      1, widget->boxWidth - 1,
159 				      NULL, 1, buttonCount,
160 				      (CDK_CSTRING2) buttonList, buttonCount,
161 				      A_REVERSE, boxWidget, FALSE);
162       CDKfreeStrings (buttonList);
163 
164       setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
165       setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
166 
167       /*
168        * We need to set the lower left and right
169        * characters of the widget.
170        */
171       setCDKMentryLLChar (widget, ACS_LTEE);
172       setCDKMentryLRChar (widget, ACS_RTEE);
173 
174       /*
175        * Bind the Tab key in the widget to send a
176        * Tab key to the button box widget.
177        */
178       bindCDKObject (vMENTRY, widget, KEY_TAB, widgetCB, buttonWidget);
179       bindCDKObject (vMENTRY, widget, CDK_NEXT, widgetCB, buttonWidget);
180       bindCDKObject (vMENTRY, widget, CDK_PREV, widgetCB, buttonWidget);
181 
182       /* Check if the user wants to set the background of the widget. */
183       setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
184 
185       /* Draw the button widget. */
186       drawCDKButtonbox (buttonWidget, boxWidget);
187    }
188 
189    /*
190     * If the user asked for a shadow, we need to create one.  Do this instead
191     * of using the shadow parameter because the button widget is not part of
192     * the main widget and if the user asks for both buttons and a shadow, we
193     * need to create a shadow big enough for both widgets.  Create the shadow
194     * window using the widgets shadowWin element, so screen refreshes will draw
195     * them as well.
196     */
197    if (shadowWidget == TRUE)
198    {
199       /* Determine the height of the shadow window. */
200       shadowHeight = (buttonWidget == (CDKBUTTONBOX *)NULL ?
201 		      widget->boxHeight :
202 		      widget->boxHeight + buttonWidget->boxHeight - 1);
203 
204       /* Create the shadow window. */
205       widget->shadowWin = newwin (shadowHeight,
206 				  widget->boxWidth,
207 				  getbegy (widget->win) + 1,
208 				  getbegx (widget->win) + 1);
209 
210       /* Make sure we could have created the shadow window. */
211       if (widget->shadowWin != 0)
212       {
213 	 widget->shadow = TRUE;
214 
215 	 /*
216 	  * We force the widget and buttonWidget to be drawn so the
217 	  * buttonbox widget will be drawn when the widget is activated.
218 	  * Otherwise the shadow window will draw over the button widget.
219 	  */
220 	 drawCDKMentry (widget, ObjOf (widget)->box);
221 	 eraseCDKButtonbox (buttonWidget);
222 	 drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
223       }
224    }
225 
226    /* Check if the user wants to set the background of the widget. */
227    setCDKMentryBackgroundColor (widget, CDK_WIDGET_COLOR);
228 
229    /* If there was an initial value, set it. */
230    if (initValue != 0)
231    {
232       setCDKMentryValue (widget, initValue);
233    }
234 
235    /* Activate the widget. */
236    answer = copyChar (activateCDKMentry (widget, 0));
237 
238    /* If there were buttons, get the button selected. */
239    if (buttonWidget != 0)
240    {
241       selection = buttonWidget->currentButton;
242       destroyCDKButtonbox (buttonWidget);
243    }
244 
245    /* End CDK. */
246    destroyCDKMentry (widget);
247    destroyCDKScreen (cdkScreen);
248    endCDK ();
249 
250    /* Print the value from the widget. */
251    if (answer != 0)
252    {
253       fprintf (fp, "%s\n", answer);
254       freeChar (answer);
255    }
256    fclose (fp);
257 
258    /* Exit with the button number picked. */
259    ExitProgram (selection);
260 }
261 
widgetCB(EObjectType cdktype GCC_UNUSED,void * object GCC_UNUSED,void * clientData,chtype key)262 static int widgetCB (EObjectType cdktype GCC_UNUSED,
263 		     void *object GCC_UNUSED,
264 		     void *clientData,
265 		     chtype key)
266 {
267    CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
268    (void) injectCDKButtonbox (buttonbox, key);
269    return (TRUE);
270 }
271