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