1 /* $OpenBSD: lib_slk.c,v 1.4 2001/01/22 18:01:44 millert Exp $ */ 2 3 /**************************************************************************** 4 * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. * 5 * * 6 * Permission is hereby granted, free of charge, to any person obtaining a * 7 * copy of this software and associated documentation files (the * 8 * "Software"), to deal in the Software without restriction, including * 9 * without limitation the rights to use, copy, modify, merge, publish, * 10 * distribute, distribute with modifications, sublicense, and/or sell * 11 * copies of the Software, and to permit persons to whom the Software is * 12 * furnished to do so, subject to the following conditions: * 13 * * 14 * The above copyright notice and this permission notice shall be included * 15 * in all copies or substantial portions of the Software. * 16 * * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 20 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 24 * * 25 * Except as contained in this notice, the name(s) of the above copyright * 26 * holders shall not be used in advertising or otherwise to promote the * 27 * sale, use or other dealings in this Software without prior written * 28 * authorization. * 29 ****************************************************************************/ 30 31 /**************************************************************************** 32 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 33 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 34 ****************************************************************************/ 35 36 /* 37 * lib_slk.c 38 * Soft key routines. 39 */ 40 41 #include <curses.priv.h> 42 43 #include <ctype.h> 44 #include <term.h> /* num_labels, label_*, plab_norm */ 45 46 MODULE_ID("$From: lib_slk.c,v 1.20 2000/12/10 02:43:27 tom Exp $") 47 48 /* 49 * We'd like to move these into the screen context structure, but cannot, 50 * because slk_init() is called before initscr()/newterm(). 51 */ 52 NCURSES_EXPORT_VAR(int) 53 _nc_slk_format = 0; /* one more than format specified in slk_init() */ 54 55 /* 56 * Paint the info line for the PC style SLK emulation. 57 * 58 */ 59 static void 60 slk_paint_info(WINDOW *win) 61 { 62 if (win && SP->slk_format == 4) { 63 int i; 64 65 mvwhline(win, 0, 0, 0, getmaxx(win)); 66 wmove(win, 0, 0); 67 68 for (i = 0; i < SP->_slk->maxlab; i++) { 69 if (win && SP->slk_format == 4) { 70 mvwaddch(win, 0, SP->_slk->ent[i].x, (chtype) 'F'); 71 if (i < 9) 72 waddch(win, (chtype) '1' + i); 73 else { 74 waddch(win, (chtype) '1'); 75 waddch(win, (chtype) '0' + (i - 9)); 76 } 77 } 78 } 79 } 80 } 81 82 /* 83 * Initialize soft labels. 84 * Called from newterm() 85 */ 86 NCURSES_EXPORT(int) 87 _nc_slk_initialize(WINDOW *stwin, int cols) 88 { 89 int i, x; 90 int res = OK; 91 char *p; 92 93 T(("slk_initialize()")); 94 95 if (SP->_slk) { /* we did this already, so simply return */ 96 return (OK); 97 } else if ((SP->_slk = typeCalloc(SLK, 1)) == 0) 98 return (ERR); 99 100 SP->_slk->ent = NULL; 101 SP->_slk->buffer = NULL; 102 SP->_slk->attr = A_STANDOUT; 103 104 SP->_slk->maxlab = (num_labels > 0) ? 105 num_labels : MAX_SKEY(_nc_slk_format); 106 SP->_slk->maxlen = (num_labels > 0) ? 107 label_width * label_height : MAX_SKEY_LEN(_nc_slk_format); 108 SP->_slk->labcnt = (SP->_slk->maxlab < MAX_SKEY(_nc_slk_format)) ? 109 MAX_SKEY(_nc_slk_format) : SP->_slk->maxlab; 110 111 SP->_slk->ent = typeCalloc(slk_ent, SP->_slk->labcnt); 112 if (SP->_slk->ent == NULL) 113 goto exception; 114 115 p = SP->_slk->buffer = (char *) calloc(2 * SP->_slk->labcnt, (1 + SP->_slk->maxlen)); 116 if (SP->_slk->buffer == NULL) 117 goto exception; 118 119 for (i = 0; i < SP->_slk->labcnt; i++) { 120 SP->_slk->ent[i].text = p; 121 p += (1 + SP->_slk->maxlen); 122 SP->_slk->ent[i].form_text = p; 123 p += (1 + SP->_slk->maxlen); 124 memset(SP->_slk->ent[i].form_text, ' ', (unsigned) (SP->_slk->maxlen)); 125 SP->_slk->ent[i].visible = (i < SP->_slk->maxlab); 126 } 127 if (_nc_slk_format >= 3) { /* PC style */ 128 int gap = (cols - 3 * (3 + 4 * SP->_slk->maxlen)) / 2; 129 130 if (gap < 1) 131 gap = 1; 132 133 for (i = x = 0; i < SP->_slk->maxlab; i++) { 134 SP->_slk->ent[i].x = x; 135 x += SP->_slk->maxlen; 136 x += (i == 3 || i == 7) ? gap : 1; 137 } 138 if (_nc_slk_format == 4) 139 slk_paint_info(stwin); 140 } else { 141 if (_nc_slk_format == 2) { /* 4-4 */ 142 int gap = cols - (SP->_slk->maxlab * SP->_slk->maxlen) - 6; 143 144 if (gap < 1) 145 gap = 1; 146 for (i = x = 0; i < SP->_slk->maxlab; i++) { 147 SP->_slk->ent[i].x = x; 148 x += SP->_slk->maxlen; 149 x += (i == 3) ? gap : 1; 150 } 151 } else { 152 if (_nc_slk_format == 1) { /* 1 -> 3-2-3 */ 153 int gap = (cols - (SP->_slk->maxlab * SP->_slk->maxlen) - 5) 154 / 2; 155 156 if (gap < 1) 157 gap = 1; 158 for (i = x = 0; i < SP->_slk->maxlab; i++) { 159 SP->_slk->ent[i].x = x; 160 x += SP->_slk->maxlen; 161 x += (i == 2 || i == 4) ? gap : 1; 162 } 163 } else 164 goto exception; 165 } 166 } 167 SP->_slk->dirty = TRUE; 168 if ((SP->_slk->win = stwin) == NULL) { 169 exception: 170 if (SP->_slk) { 171 FreeIfNeeded(SP->_slk->buffer); 172 FreeIfNeeded(SP->_slk->ent); 173 free(SP->_slk); 174 SP->_slk = (SLK *) 0; 175 res = (ERR); 176 } 177 } 178 179 /* We now reset the format so that the next newterm has again 180 * per default no SLK keys and may call slk_init again to 181 * define a new layout. (juergen 03-Mar-1999) 182 */ 183 SP->slk_format = _nc_slk_format; 184 _nc_slk_format = 0; 185 return (res); 186 } 187 188 /* 189 * Restore the soft labels on the screen. 190 */ 191 NCURSES_EXPORT(int) 192 slk_restore(void) 193 { 194 T((T_CALLED("slk_restore()"))); 195 196 if (SP->_slk == NULL) 197 return (ERR); 198 SP->_slk->hidden = FALSE; 199 SP->_slk->dirty = TRUE; 200 /* we have to repaint info line eventually */ 201 slk_paint_info(SP->_slk->win); 202 203 returnCode(slk_refresh()); 204 } 205