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