libpayload: remove trailing whitespace and run dos2unix
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / pdcurses / slk.c
1 /* Public Domain Curses */
2
3 #include <curspriv.h>
4
5 RCSID("$Id: slk.c,v 1.61 2008/07/13 16:08:18 wmcbrine Exp $")
6
7 /*man-start**************************************************************
8
9   Name:                                                         slk
10
11   Synopsis:
12         int slk_init(int fmt);
13         int slk_set(int labnum, const char *label, int justify);
14         int slk_refresh(void);
15         int slk_noutrefresh(void);
16         char *slk_label(int labnum);
17         int slk_clear(void);
18         int slk_restore(void);
19         int slk_touch(void);
20         int slk_attron(const chtype attrs);
21         int slk_attr_on(const attr_t attrs, void *opts);
22         int slk_attrset(const chtype attrs);
23         int slk_attr_set(const attr_t attrs, short color_pair, void *opts);
24         int slk_attroff(const chtype attrs);
25         int slk_attr_off(const attr_t attrs, void *opts);
26         int slk_color(short color_pair);
27
28         int slk_wset(int labnum, const wchar_t *label, int justify);
29
30         int PDC_mouse_in_slk(int y, int x);
31         void PDC_slk_free(void);
32         void PDC_slk_initialize(void);
33
34         wchar_t *slk_wlabel(int labnum)
35
36   Description:
37         These functions manipulate a window that contain Soft Label Keys
38         (SLK). To use the SLK functions, a call to slk_init() must be
39         made BEFORE initscr() or newterm(). slk_init() removes 1 or 2
40         lines from the useable screen, depending on the format selected.
41
42         The line(s) removed from the screen are used as a separate
43         window, in which SLKs are displayed.
44
45         slk_init() requires a single parameter which describes the
46         format of the SLKs as follows:
47
48                 0       3-2-3 format
49                 1       4-4 format
50                 2       4-4-4 format (ncurses extension)
51                 3       4-4-4 format with index line (ncurses extension)
52                         2 lines used
53                 55      5-5 format (pdcurses format)
54
55         slk_refresh(), slk_noutrefresh() and slk_touch() are analogous
56         to refresh(), noutrefresh() and touch().
57
58   Return Value:
59         All functions return OK on success and ERR on error.
60
61   Portability                                X/Open    BSD    SYS V
62         slk_init                                Y       -       Y
63         slk_set                                 Y       -       Y
64         slk_refresh                             Y       -       Y
65         slk_noutrefresh                         Y       -       Y
66         slk_label                               Y       -       Y
67         slk_clear                               Y       -       Y
68         slk_restore                             Y       -       Y
69         slk_touch                               Y       -       Y
70         slk_attron                              Y       -       Y
71         slk_attrset                             Y       -       Y
72         slk_attroff                             Y       -       Y
73         slk_attr_on                             Y
74         slk_attr_set                            Y
75         slk_attr_off                            Y
76         slk_wset                                Y
77         PDC_mouse_in_slk                        -       -       -
78         PDC_slk_free                            -       -       -
79         PDC_slk_initialize                      -       -       -
80         slk_wlabel                              -       -       -
81
82 **man-end****************************************************************/
83
84 #include <stdlib.h>
85
86 enum { LABEL_NORMAL = 8, LABEL_EXTENDED = 10, LABEL_NCURSES_EXTENDED = 12 };
87
88 static int label_length = 0;
89 static int labels = 0;
90 static int label_fmt = 0;
91 static int label_line = 0;
92 static bool hidden = FALSE;
93
94 static struct SLK {
95     chtype label[32];
96     int len;
97     int format;
98     int start_col;
99 } *slk = (struct SLK *)NULL;
100
101 /* slk_init() is the slk initialization routine.
102    This must be called before initscr().
103
104    label_fmt = 0, 1 or 55.
105        0 = 3-2-3 format
106        1 = 4 - 4 format
107        2 = 4-4-4 format (ncurses extension for PC 12 function keys)
108        3 = 4-4-4 format (ncurses extension for PC 12 function keys -
109     with index line)
110       55 = 5 - 5 format (extended for PC, 10 function keys) */
111
112 int slk_init(int fmt)
113 {
114     PDC_LOG(("slk_init() - called\n"));
115
116     if (SP)
117         return ERR;
118
119     switch (fmt)
120     {
121     case 0:  /* 3 - 2 - 3 */
122         labels = LABEL_NORMAL;
123         break;
124
125     case 1:   /* 4 - 4 */
126         labels = LABEL_NORMAL;
127         break;
128
129     case 2:   /* 4 4 4 */
130         labels = LABEL_NCURSES_EXTENDED;
131         break;
132
133     case 3:   /* 4 4 4  with index */
134         labels = LABEL_NCURSES_EXTENDED;
135         break;
136
137     case 55:  /* 5 - 5 */
138         labels = LABEL_EXTENDED;
139         break;
140
141     default:
142         return ERR;
143     }
144
145     label_fmt = fmt;
146
147     slk = calloc(labels, sizeof(struct SLK));
148
149     if (!slk)
150         labels = 0;
151
152     return slk ? OK : ERR;
153 }
154
155 /* draw a single button */
156
157 static void _drawone(int num)
158 {
159     int i, col, slen;
160
161     if (hidden)
162         return;
163
164     slen = slk[num].len;
165
166     switch (slk[num].format)
167     {
168     case 0:  /* LEFT */
169         col = 0;
170         break;
171
172     case 1:  /* CENTER */
173         col = (label_length - slen) / 2;
174
175         if (col + slen > label_length)
176             --col;
177         break;
178
179     default:  /* RIGHT */
180         col = label_length - slen;
181     }
182
183     wmove(SP->slk_winptr, label_line, slk[num].start_col);
184
185     for (i = 0; i < label_length; ++i)
186         waddch(SP->slk_winptr, (i >= col && i < (col + slen)) ?
187                slk[num].label[i - col] : ' ');
188 }
189
190 /* redraw each button */
191
192 static void _redraw(void)
193 {
194     int i;
195
196     for (i = 0; i < labels; ++i)
197         _drawone(i);
198 }
199
200 /* slk_set() Used to set a slk label to a string.
201
202    labnum  = 1 - 8 (or 10) (number of the label)
203    label   = string (8 or 7 bytes total), or NULL
204    justify = 0 : left, 1 : center, 2 : right  */
205
206 int slk_set(int labnum, const char *label, int justify)
207 {
208 #ifdef PDC_WIDE
209     wchar_t wlabel[32];
210
211     PDC_mbstowcs(wlabel, label, 31);
212     return slk_wset(labnum, wlabel, justify);
213 #else
214     PDC_LOG(("slk_set() - called\n"));
215
216     if (labnum < 1 || labnum > labels || justify < 0 || justify > 2)
217         return ERR;
218
219     labnum--;
220
221     if (!label || !(*label))
222     {
223         /* Clear the label */
224
225         *slk[labnum].label = 0;
226         slk[labnum].format = 0;
227         slk[labnum].len = 0;
228     }
229     else
230     {
231         int i, j = 0;
232
233         /* Skip leading spaces */
234
235         while (label[j] == ' ')
236             j++;
237
238         /* Copy it */
239
240         for (i = 0; i < label_length; i++)
241         {
242             chtype ch = label[i + j];
243
244             slk[labnum].label[i] = ch;
245
246             if (!ch)
247                 break;
248         }
249
250         /* Drop trailing spaces */
251
252         while ((i + j) && (label[i + j - 1] == ' '))
253             i--;
254
255         slk[labnum].label[i] = 0;
256         slk[labnum].format = justify;
257         slk[labnum].len = i;
258     }
259
260     _drawone(labnum);
261
262     return OK;
263 #endif
264 }
265
266 int slk_refresh(void)
267 {
268     PDC_LOG(("slk_refresh() - called\n"));
269
270     return (slk_noutrefresh() == ERR) ? ERR : doupdate();
271 }
272
273 int slk_noutrefresh(void)
274 {
275     PDC_LOG(("slk_noutrefresh() - called\n"));
276
277     return wnoutrefresh(SP->slk_winptr);
278 }
279
280 char *slk_label(int labnum)
281 {
282     static char temp[33];
283 #ifdef PDC_WIDE
284     wchar_t *wtemp = slk_wlabel(labnum);
285
286     PDC_wcstombs(temp, wtemp, 32);
287 #else
288     chtype *p;
289     int i;
290
291     PDC_LOG(("slk_label() - called\n"));
292
293     if (labnum < 1 || labnum > labels)
294         return (char *)0;
295
296     for (i = 0, p = slk[labnum - 1].label; *p; i++)
297         temp[i] = *p++;
298
299     temp[i] = '\0';
300 #endif
301     return temp;
302 }
303
304 int slk_clear(void)
305 {
306     PDC_LOG(("slk_clear() - called\n"));
307
308     hidden = TRUE;
309     werase(SP->slk_winptr);
310     return wrefresh(SP->slk_winptr);
311 }
312
313 int slk_restore(void)
314 {
315     PDC_LOG(("slk_restore() - called\n"));
316
317     hidden = FALSE;
318     _redraw();
319     return wrefresh(SP->slk_winptr);
320 }
321
322 int slk_touch(void)
323 {
324     PDC_LOG(("slk_touch() - called\n"));
325
326     return touchwin(SP->slk_winptr);
327 }
328
329 int slk_attron(const chtype attrs)
330 {
331     int rc;
332
333     PDC_LOG(("slk_attron() - called\n"));
334
335     rc = wattron(SP->slk_winptr, attrs);
336     _redraw();
337
338     return rc;
339 }
340
341 int slk_attr_on(const attr_t attrs, void *opts)
342 {
343     PDC_LOG(("slk_attr_on() - called\n"));
344
345     return slk_attron(attrs);
346 }
347
348 int slk_attroff(const chtype attrs)
349 {
350     int rc;
351
352     PDC_LOG(("slk_attroff() - called\n"));
353
354     rc = wattroff(SP->slk_winptr, attrs);
355     _redraw();
356
357     return rc;
358 }
359
360 int slk_attr_off(const attr_t attrs, void *opts)
361 {
362     PDC_LOG(("slk_attr_off() - called\n"));
363
364     return slk_attroff(attrs);
365 }
366
367 int slk_attrset(const chtype attrs)
368 {
369     int rc;
370
371     PDC_LOG(("slk_attrset() - called\n"));
372
373     rc = wattrset(SP->slk_winptr, attrs);
374     _redraw();
375
376     return rc;
377 }
378
379 int slk_color(short color_pair)
380 {
381     int rc;
382
383     PDC_LOG(("slk_color() - called\n"));
384
385     rc = wcolor_set(SP->slk_winptr, color_pair, NULL);
386     _redraw();
387
388     return rc;
389 }
390
391 int slk_attr_set(const attr_t attrs, short color_pair, void *opts)
392 {
393     PDC_LOG(("slk_attr_set() - called\n"));
394
395     return slk_attrset(attrs | COLOR_PAIR(color_pair));
396 }
397
398 static void _slk_calc(void)
399 {
400     int i, center, col = 0;
401     label_length = COLS / labels;
402
403     if (label_length > 31)
404         label_length = 31;
405
406     switch (label_fmt)
407     {
408     case 0:     /* 3 - 2 - 3 F-Key layout */
409
410         --label_length;
411
412         slk[0].start_col = col;
413         slk[1].start_col = (col += label_length);
414         slk[2].start_col = (col += label_length);
415
416         center = COLS / 2;
417
418         slk[3].start_col = center - label_length + 1;
419         slk[4].start_col = center + 1;
420
421         col = COLS - (label_length * 3) + 1;
422
423         slk[5].start_col = col;
424         slk[6].start_col = (col += label_length);
425         slk[7].start_col = (col += label_length);
426         break;
427
428     case 1:     /* 4 - 4 F-Key layout */
429
430         for (i = 0; i < 8; i++)
431         {
432             slk[i].start_col = col;
433             col += label_length;
434
435             if (i == 3)
436                 col = COLS - (label_length * 4) + 1;
437         }
438
439         break;
440
441     case 2:     /* 4 4 4 F-Key layout */
442     case 3:     /* 4 4 4 F-Key layout with index */
443
444         for (i = 0; i < 4; i++)
445         {
446             slk[i].start_col = col;
447             col += label_length;
448         }
449
450         center = COLS/2;
451
452         slk[4].start_col = center - (label_length * 2) + 1;
453         slk[5].start_col = center - label_length - 1;
454         slk[6].start_col = center + 1;
455         slk[7].start_col = center + label_length + 1;
456
457         col = COLS - (label_length * 4) + 1;
458
459         for (i = 8; i < 12; i++)
460         {
461             slk[i].start_col = col;
462             col += label_length;
463         }
464
465         break;
466
467     default:    /* 5 - 5 F-Key layout */
468
469         for (i = 0; i < 10; i++)
470         {
471             slk[i].start_col = col;
472             col += label_length;
473
474             if (i == 4)
475                 col = COLS - (label_length * 5) + 1;
476         }
477     }
478
479     --label_length;
480
481     /* make sure labels are all in window */
482
483     _redraw();
484 }
485
486 void PDC_slk_initialize(void)
487 {
488     if (slk)
489     {
490         if (label_fmt == 3)
491         {
492             SP->slklines = 2;
493             label_line = 1;
494         }
495         else
496             SP->slklines = 1;
497
498         if (!SP->slk_winptr)
499         {
500             if ( !(SP->slk_winptr = newwin(SP->slklines, COLS,
501                                            LINES - SP->slklines, 0)) )
502                 return;
503
504             wattrset(SP->slk_winptr, A_REVERSE);
505         }
506
507         _slk_calc();
508
509         /* if we have an index line, display it now */
510
511         if (label_fmt == 3)
512         {
513             chtype save_attr;
514             int i;
515
516             save_attr = SP->slk_winptr->_attrs;
517             wattrset(SP->slk_winptr, A_NORMAL);
518             wmove(SP->slk_winptr, 0, 0);
519             whline(SP->slk_winptr, 0, COLS);
520
521             for (i = 0; i < labels; i++)
522                 mvwprintw(SP->slk_winptr, 0, slk[i].start_col, "F%d", i + 1);
523
524             SP->slk_winptr->_attrs = save_attr;
525         }
526
527         touchwin(SP->slk_winptr);
528     }
529 }
530
531 void PDC_slk_free(void)
532 {
533     if (slk)
534     {
535         if (SP->slk_winptr)
536         {
537             delwin(SP->slk_winptr);
538             SP->slk_winptr = (WINDOW *)NULL;
539         }
540
541         free(slk);
542         slk = (struct SLK *)NULL;
543
544         label_length = 0;
545         labels = 0;
546         label_fmt = 0;
547         label_line = 0;
548         hidden = FALSE;
549     }
550 }
551
552 int PDC_mouse_in_slk(int y, int x)
553 {
554     int i;
555
556     PDC_LOG(("PDC_mouse_in_slk() - called: y->%d x->%d\n", y, x));
557
558     /* If the line on which the mouse was clicked is NOT the last line
559        of the screen, we are not interested in it. */
560
561     if (!slk || !SP->slk_winptr || (y != SP->slk_winptr->_begy + label_line))
562         return 0;
563
564     for (i = 0; i < labels; i++)
565         if (x >= slk[i].start_col && x < (slk[i].start_col + label_length))
566             return i + 1;
567
568     return 0;
569 }
570
571 #ifdef PDC_WIDE
572 int slk_wset(int labnum, const wchar_t *label, int justify)
573 {
574     PDC_LOG(("slk_wset() - called\n"));
575
576     if (labnum < 1 || labnum > labels || justify < 0 || justify > 2)
577         return ERR;
578
579     labnum--;
580
581     if (!label || !(*label))
582     {
583         /* Clear the label */
584
585         *slk[labnum].label = 0;
586         slk[labnum].format = 0;
587         slk[labnum].len = 0;
588     }
589     else
590     {
591         int i, j = 0;
592
593         /* Skip leading spaces */
594
595         while (label[j] == L' ')
596             j++;
597
598         /* Copy it */
599
600         for (i = 0; i < label_length; i++)
601         {
602             chtype ch = label[i + j];
603
604             slk[labnum].label[i] = ch;
605
606             if (!ch)
607                 break;
608         }
609
610         /* Drop trailing spaces */
611
612         while ((i + j) && (label[i + j - 1] == L' '))
613             i--;
614
615         slk[labnum].label[i] = 0;
616         slk[labnum].format = justify;
617         slk[labnum].len = i;
618     }
619
620     _drawone(labnum);
621
622     return OK;
623 }
624
625 wchar_t *slk_wlabel(int labnum)
626 {
627     static wchar_t temp[33];
628     chtype *p;
629     int i;
630
631     PDC_LOG(("slk_wlabel() - called\n"));
632
633     if (labnum < 1 || labnum > labels)
634         return (wchar_t *)0;
635
636     for (i = 0, p = slk[labnum - 1].label; *p; i++)
637         temp[i] = *p++;
638
639     temp[i] = '\0';
640
641     return temp;
642 }
643 #endif