2 /***************************************************************************
4 ****************************************************************************
5 * ncurses is copyright (C) 1992-1995 *
7 * zmbenhal@netcom.com *
9 * esr@snark.thyrsus.com *
11 * Permission is hereby granted to reproduce and distribute ncurses *
12 * by any means and for any fee, whether alone or as part of a *
13 * larger distribution, in source or in binary form, PROVIDED *
14 * this notice is included with any such distribution, and is not *
15 * removed from any of its header files. Mention of ncurses in any *
16 * applications linked with it is highly appreciated. *
18 * ncurses comes AS IS with no warranty, implied or expressed. *
20 ***************************************************************************/
27 #include <curses.priv.h>
30 #include <term.h> /* num_labels, label_*, plab_norm */
32 MODULE_ID("$Id: lib_slk.c,v 1.11 1997/01/18 23:06:32 tom Exp $")
34 #define MAX_SKEY_OLD 8 /* count of soft keys */
35 #define MAX_SKEY_LEN_OLD 8 /* max length of soft key text */
36 #define MAX_SKEY_PC 12 /* This is what most PC's have */
37 #define MAX_SKEY_LEN_PC 5
39 #define MAX_SKEY (SLK_STDFMT ? MAX_SKEY_OLD : MAX_SKEY_PC)
40 #define MAX_SKEY_LEN (SLK_STDFMT ? MAX_SKEY_LEN_OLD : MAX_SKEY_LEN_PC)
42 * We'd like to move these into the screen context structure, but cannot,
43 * because slk_init() is called before initscr()/newterm().
45 int _nc_slk_format; /* one more than format specified in slk_init() */
47 static chtype _slk_attr = A_STANDOUT; /* soft label attribute */
49 static void slk_paint_info(WINDOW *win);
52 * Fetch the label text.
58 T(("slk_label(%d)", n));
60 if (SP->_slk == NULL || n < 1 || n > SP->_slk->labcnt)
62 return(SP->_slk->ent[n-1].text);
66 * Write the soft labels to the soft-key window.
70 slk_intern_refresh(SLK *slk)
73 for (i = 0; i < slk->labcnt; i++) {
74 if (slk->dirty || slk->ent[i].dirty) {
75 if (slk->ent[i].visible) {
77 if (num_labels > 0 && SLK_STDFMT)
80 TPUTS_TRACE("plab_norm");
81 putp(tparm(plab_norm, i, slk->win,slk->ent[i].form_text));
85 #endif /* num_labels */
87 wmove(slk->win,SLK_LINES-1,slk->ent[i].x);
88 wattrset(slk->win,_slk_attr);
89 waddnstr(slk->win,slk->ent[i].form_text, MAX_SKEY_LEN);
90 /* if we simulate SLK's, it's looking much more
91 natural to use the current ATTRIBUTE also
92 for the label window */
93 wattrset(slk->win,stdscr->_attrs);
96 slk->ent[i].dirty = FALSE;
105 TPUTS_TRACE("label_off");
110 TPUTS_TRACE("label_on");
113 #endif /* num_labels */
117 * Refresh the soft labels.
121 slk_noutrefresh(void)
123 T(("slk_noutrefresh()"));
125 if (SP->_slk == NULL)
127 if (SP->_slk->hidden)
129 slk_intern_refresh(SP->_slk);
130 return(wnoutrefresh(SP->_slk->win));
134 * Refresh the soft labels.
140 T(("slk_refresh()"));
142 if (SP->_slk == NULL)
144 if (SP->_slk->hidden)
146 slk_intern_refresh(SP->_slk);
147 return(wrefresh(SP->_slk->win));
151 * Restore the soft labels on the screen.
157 T(("slk_restore()"));
159 if (SP->_slk == NULL)
161 SP->_slk->hidden = FALSE;
162 SP->_slk->dirty = TRUE;
163 /* we have to repaint info line eventually */
164 slk_paint_info(SP->_slk->win);
165 return slk_refresh();
169 * Set soft label text.
173 slk_set(int i, const char *astr, int format)
177 const char *str = astr;
180 T(("slk_set(%d, \"%s\", %d)", i, str, format));
182 if (slk == NULL || i < 1 || i > slk->labcnt || format < 0 || format > 2)
187 while (isspace(*str)) str++; /* skip over leading spaces */
189 while (isprint(*p)) p++; /* The first non-print stops */
191 --i; /* Adjust numbering of labels */
193 len = (size_t)(p - str);
194 if (len > (unsigned)slk->maxlen)
197 slk->ent[i].text[0] = 0;
199 (void) strncpy(slk->ent[i].text, str, len);
200 memset(slk->ent[i].form_text,' ', (unsigned)slk->maxlen);
201 slk->ent[i].text[slk->maxlen] = 0;
202 /* len = strlen(slk->ent[i].text); */
205 case 0: /* left-justified */
206 memcpy(slk->ent[i].form_text,
210 case 1: /* centered */
211 memcpy(slk->ent[i].form_text+(slk->maxlen - len)/2,
215 case 2: /* right-justified */
216 memcpy(slk->ent[i].form_text+ slk->maxlen - len,
221 slk->ent[i].form_text[slk->maxlen] = 0;
222 slk->ent[i].dirty = TRUE;
227 * Force the code to believe that the soft keys have been changed.
235 if (SP->_slk == NULL)
237 SP->_slk->dirty = TRUE;
242 * Remove soft labels from the screen.
250 if (SP->_slk == NULL)
252 SP->_slk->hidden = TRUE;
253 /* For simulated SLK's it's looks much more natural to
254 inherit those attributes from the standard screen */
255 SP->_slk->win->_bkgd = stdscr->_bkgd;
256 SP->_slk->win->_attrs = stdscr->_attrs;
257 werase(SP->_slk->win);
258 return wrefresh(SP->_slk->win);
262 * Paint the info line for the PC style SLK emulation.
267 slk_paint_info(WINDOW *win)
269 if (win && _nc_slk_format==4)
273 mvwhline (win,0,0,0,getmaxx(win));
276 for (i = 0; i < _slk->maxlab; i++) {
277 if (win && _nc_slk_format==4)
279 mvwaddch(win,0,_slk->ent[i].x,'F');
285 waddch(win,'0' + (i-9));
293 * Initialize soft labels.
294 * Called from newterm()
298 _nc_slk_initialize(WINDOW *stwin, int cols)
303 T(("slk_initialize()"));
306 { /* we did this already, so simply return */
311 if ((SP->_slk = _slk = typeCalloc(SLK, 1)) == 0)
318 _slk->maxlab = (num_labels > 0) ? num_labels : MAX_SKEY;
319 _slk->maxlen = (num_labels > 0) ? label_width * label_height : MAX_SKEY_LEN;
320 _slk->labcnt = (_slk->maxlab < MAX_SKEY) ? MAX_SKEY : _slk->maxlab;
322 _slk->labcnt = _slk->maxlab = MAX_SKEY;
323 _slk->maxlen = MAX_SKEY_LEN;
324 #endif /* num_labels */
326 _slk->ent = typeCalloc(slk_ent, _slk->labcnt);
327 if (_slk->ent == NULL)
330 p = _slk->buffer = (char*) calloc(2*_slk->labcnt,(1+_slk->maxlen));
331 if (_slk->buffer == NULL)
334 for (i = 0; i < _slk->labcnt; i++) {
335 _slk->ent[i].text = p;
336 p += (1 + _slk->maxlen);
337 _slk->ent[i].form_text = p;
338 p += (1 + _slk->maxlen);
339 memset(_slk->ent[i].form_text, ' ', (unsigned)_slk->maxlen);
340 _slk->ent[i].visible = (i < _slk->maxlab);
342 if (_nc_slk_format >= 3) /* PC style */
344 int gap = (cols - 3 * (3 + 4*_slk->maxlen))/2;
349 for (i = x = 0; i < _slk->maxlab; i++) {
352 x += (i==3 || i==7) ? gap : 1;
354 if (_nc_slk_format == 4)
355 slk_paint_info (stwin);
358 if (_nc_slk_format == 2) { /* 4-4 */
359 int gap = cols - (_slk->maxlab * _slk->maxlen) - 6;
363 for (i = x = 0; i < _slk->maxlab; i++) {
366 x += (i == 3) ? gap : 1;
371 if (_nc_slk_format == 1) { /* 1 -> 3-2-3 */
372 int gap = (cols - (_slk->maxlab * _slk->maxlen) - 5) / 2;
376 for (i = x = 0; i < _slk->maxlab; i++) {
379 x += (i == 2 || i == 4) ? gap : 1;
387 if ((_slk->win = stwin) == NULL)
392 FreeIfNeeded(_slk->buffer);
393 FreeIfNeeded(_slk->ent);
395 SP->_slk = _slk = (SLK*)0;
404 * Initialize soft labels. Called by the user before initscr().
410 if (format < 0 || format > 3)
412 _nc_slk_format = 1 + format;
416 /* Functions to manipulate the soft-label attribute */
419 slk_attrset(const attr_t attr)
426 slk_attron(const attr_t attr)
428 toggle_attr_on(_slk_attr,attr);
433 slk_attroff(const attr_t attr)
435 toggle_attr_off(_slk_attr,attr);