1 /* $Id: cdkscroll.c,v 1.13 2016/12/04 15:22:16 tom Exp $ */
2
3 #include <cdk_test.h>
4
5 #ifdef XCURSES
6 char *XCursesProgramName = "cdkscroll";
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 = "-l List | -f filename [-s Scroll Bar Position] [-n Numbers] [-i Item Index] [-T Title] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-H Height] [-W Width] [-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 CDKSCROLL *widget = 0;
27 CDKBUTTONBOX *buttonWidget = 0;
28 char *CDK_WIDGET_COLOR = 0;
29 char *temp = 0;
30 chtype *holder = 0;
31 int answer = 0;
32 int spos = NONE;
33 int buttonCount = 0;
34 int selection = 0;
35 int scrollLines = -1;
36 int shadowHeight = 0;
37 FILE *fp = stderr;
38 char **scrollList = 0;
39 char **buttonList = 0;
40 int j1, j2;
41
42 CDK_PARAMS params;
43 boolean boxWidget;
44 boolean shadowWidget;
45 char *buttons;
46 char *filename;
47 char *list;
48 char *outputFile;
49 char *title;
50 int height;
51 int numberOutput;
52 int numbers;
53 int width;
54 int xpos;
55 int ypos;
56
57 CDKparseParams (argc, argv, ¶ms, "f:il:ns:B:O:T:" CDK_CLI_PARAMS);
58
59 /* *INDENT-EQLS* */
60 xpos = CDKparamValue (¶ms, 'X', CENTER);
61 ypos = CDKparamValue (¶ms, 'Y', CENTER);
62 height = CDKparamValue (¶ms, 'H', 1);
63 width = CDKparamValue (¶ms, 'W', 1);
64 boxWidget = CDKparamValue (¶ms, 'N', TRUE);
65 shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
66 numberOutput = CDKparamValue (¶ms, 'i', FALSE);
67 numbers = CDKparamValue (¶ms, 'n', FALSE);
68 filename = CDKparamString (¶ms, 'f');
69 list = CDKparamString (¶ms, 'l');
70 buttons = CDKparamString (¶ms, 'B');
71 outputFile = CDKparamString (¶ms, 'O');
72 title = CDKparamString (¶ms, 'T');
73
74 spos = CDKparsePosition (CDKparamString (¶ms, 's'));
75
76 /* If the user asked for an output file, try to open it. */
77 if (outputFile != 0)
78 {
79 if ((fp = fopen (outputFile, "w")) == 0)
80 {
81 fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
82 ExitProgram (CLI_ERROR);
83 }
84 }
85
86 /* Did they provide a list of items. */
87 if (list == 0)
88 {
89 /* Maybe they gave a filename to use to read. */
90 if (filename != 0)
91 {
92 /* Read the file in. */
93 scrollLines = CDKreadFile (filename, &scrollList);
94
95 /* Check if there was an error. */
96 if (scrollLines == -1)
97 {
98 fprintf (stderr, "Error: Could not open the file '%s'.\n", filename);
99 ExitProgram (CLI_ERROR);
100 }
101 }
102 else
103 {
104 /* They didn't provide anything. */
105 fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
106 ExitProgram (CLI_ERROR);
107 }
108 }
109 else
110 {
111 /* Split the scroll lines up. */
112 scrollList = CDKsplitString (list, '\n');
113 scrollLines = (int)CDKcountStrings ((CDK_CSTRING2) scrollList);
114 }
115
116 cdkScreen = initCDKScreen (NULL);
117
118 /* Start color. */
119 initCDKColor ();
120
121 /* Check if the user wants to set the background of the main screen. */
122 if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
123 {
124 holder = char2Chtype (temp, &j1, &j2);
125 wbkgd (cdkScreen->window, holder[0]);
126 wrefresh (cdkScreen->window);
127 freeChtype (holder);
128 }
129
130 /* Get the widget color background color. */
131 if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
132 {
133 CDK_WIDGET_COLOR = 0;
134 }
135
136 /* Create the scrolling list. */
137 widget = newCDKScroll (cdkScreen, xpos, ypos, spos,
138 height, width, title,
139 (CDK_CSTRING2) scrollList, scrollLines,
140 numbers, A_REVERSE,
141 boxWidget, shadowWidget);
142
143 /* Make sure we could create the widget. */
144 if (widget == 0)
145 {
146 CDKfreeStrings (scrollList);
147
148 destroyCDKScreen (cdkScreen);
149 endCDK ();
150
151 fprintf (stderr,
152 "Error: Could not create the scrolling list. "
153 "Is the window too small?\n");
154
155 ExitProgram (CLI_ERROR);
156 }
157
158 /* Split the buttons if they supplied some. */
159 if (buttons != 0)
160 {
161 /* Split the button list up. */
162 buttonList = CDKsplitString (buttons, '\n');
163 buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
164
165 /* We need to create a buttonbox widget. */
166 buttonWidget = newCDKButtonbox (cdkScreen,
167 getbegx (widget->win),
168 (getbegy (widget->win)
169 + widget->boxHeight - 1),
170 1, widget->boxWidth - 1,
171 0, 1, buttonCount,
172 (CDK_CSTRING2) buttonList, buttonCount,
173 A_REVERSE, boxWidget, FALSE);
174 CDKfreeStrings (buttonList);
175
176 setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
177 setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
178
179 /*
180 * We need to set the lower left and right
181 * characters of the widget.
182 */
183 setCDKScrollLLChar (widget, ACS_LTEE);
184 setCDKScrollLRChar (widget, ACS_RTEE);
185
186 /*
187 * Bind the Tab key in the widget to send a
188 * Tab key to the button box widget.
189 */
190 bindCDKObject (vSCROLL, widget, KEY_TAB, widgetCB, buttonWidget);
191 bindCDKObject (vSCROLL, widget, CDK_NEXT, widgetCB, buttonWidget);
192 bindCDKObject (vSCROLL, widget, CDK_PREV, widgetCB, buttonWidget);
193
194 /* Check if the user wants to set the background of the widget. */
195 setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
196
197 /* Draw the button widget. */
198 drawCDKButtonbox (buttonWidget, boxWidget);
199 }
200
201 /*
202 * If the user asked for a shadow, we need to create one. Do this instead
203 * of using the shadow parameter because the button widget is not part of
204 * the main widget and if the user asks for both buttons and a shadow, we
205 * need to create a shadow big enough for both widgets. Create the shadow
206 * window using the widgets shadowWin element, so screen refreshes will draw
207 * them as well.
208 */
209 if (shadowWidget == TRUE)
210 {
211 /* Determine the height of the shadow window. */
212 shadowHeight = (buttonWidget == 0 ?
213 widget->boxHeight :
214 widget->boxHeight + buttonWidget->boxHeight - 1);
215
216 /* Create the shadow window. */
217 widget->shadowWin = newwin (shadowHeight,
218 widget->boxWidth,
219 getbegy (widget->win) + 1,
220 getbegx (widget->win) + 1);
221
222 /* Make sure we could have created the shadow window. */
223 if (widget->shadowWin != 0)
224 {
225 widget->shadow = TRUE;
226
227 /*
228 * We force the widget and buttonWidget to be drawn so the
229 * buttonbox widget will be drawn when the widget is activated.
230 * Otherwise the shadow window will draw over the button widget.
231 */
232 drawCDKScroll (widget, ObjOf (widget)->box);
233 eraseCDKButtonbox (buttonWidget);
234 drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
235 }
236 }
237
238 /* Check if the user wants to set the background of the widget. */
239 setCDKScrollBackgroundColor (widget, CDK_WIDGET_COLOR);
240
241 /* Activate the scrolling list. */
242 answer = activateCDKScroll (widget, 0);
243
244 /* If there were buttons, get the button selected. */
245 if (buttonWidget != 0)
246 {
247 selection = buttonWidget->currentButton;
248 destroyCDKButtonbox (buttonWidget);
249 }
250
251 /* Shut down curses. */
252 destroyCDKScroll (widget);
253 destroyCDKScreen (cdkScreen);
254 endCDK ();
255
256 /* Print out the answer. */
257 if (answer >= 0)
258 {
259 if (numberOutput == TRUE)
260 {
261 fprintf (fp, "%d\n", answer);
262 }
263 else
264 {
265 fprintf (fp, "%s\n", scrollList[answer]);
266 }
267 }
268 fclose (fp);
269
270 CDKfreeStrings (scrollList);
271
272 /* Exit with the answer. */
273 ExitProgram (selection);
274 }
275
widgetCB(EObjectType cdktype GCC_UNUSED,void * object GCC_UNUSED,void * clientData,chtype key)276 static int widgetCB (EObjectType cdktype GCC_UNUSED,
277 void *object GCC_UNUSED,
278 void *clientData,
279 chtype key)
280 {
281 CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
282 (void) injectCDKButtonbox (buttonbox, key);
283 return (TRUE);
284 }
285