Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
9214 turbocat 1
/* PDCurses */
2
 
3
#include 
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
 
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 
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
 
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