1 /**************************************************************************** 2 * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * 3 * * 4 * Permission is hereby granted, free of charge, to any person obtaining a * 5 * copy of this software and associated documentation files (the * 6 * "Software"), to deal in the Software without restriction, including * 7 * without limitation the rights to use, copy, modify, merge, publish, * 8 * distribute, distribute with modifications, sublicense, and/or sell * 9 * copies of the Software, and to permit persons to whom the Software is * 10 * furnished to do so, subject to the following conditions: * 11 * * 12 * The above copyright notice and this permission notice shall be included * 13 * in all copies or substantial portions of the Software. * 14 * * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22 * * 23 * Except as contained in this notice, the name(s) of the above copyright * 24 * holders shall not be used in advertising or otherwise to promote the * 25 * sale, use or other dealings in this Software without prior written * 26 * authorization. * 27 ****************************************************************************/ 28 29 /**************************************************************************** 30 * Authors: * 31 * Gerhard Fuernkranz 1993 (original) * 32 * Zeyd M. Ben-Halim 1992,1995 (sic) * 33 * Eric S. Raymond * 34 * Juergen Pfeifer 1996-on * 35 * Thomas E. Dickey * 36 ****************************************************************************/ 37 38 /* 39 * lib_slk.c 40 * Soft key routines. 41 */ 42 43 #include <curses.priv.h> 44 #include <ctype.h> 45 46 #ifndef CUR 47 #define CUR SP_TERMTYPE 48 #endif 49 50 MODULE_ID("$Id: lib_slk.c,v 1.48 2011/03/05 21:21:52 tom Exp $") 51 52 #ifdef USE_TERM_DRIVER 53 #define NumLabels InfoOf(SP_PARM).numlabels 54 #define NoColorVideo InfoOf(SP_PARM).nocolorvideo 55 #define LabelWidth InfoOf(SP_PARM).labelwidth 56 #define LabelHeight InfoOf(SP_PARM).labelheight 57 #else 58 #define NumLabels num_labels 59 #define NoColorVideo no_color_video 60 #define LabelWidth label_width 61 #define LabelHeight label_height 62 #endif 63 64 /* 65 * Free any memory related to soft labels, return an error. 66 */ 67 static int 68 slk_failed(NCURSES_SP_DCL0) 69 { 70 if ((0 != SP_PARM) && SP_PARM->_slk) { 71 FreeIfNeeded(SP_PARM->_slk->ent); 72 free(SP_PARM->_slk); 73 SP_PARM->_slk = (SLK *) 0; 74 } 75 return ERR; 76 } 77 78 NCURSES_EXPORT(int) 79 _nc_format_slks(NCURSES_SP_DCLx int cols) 80 { 81 int gap, i, x; 82 int max_length; 83 84 if (!SP_PARM || !SP_PARM->_slk) 85 return ERR; 86 87 max_length = SP_PARM->_slk->maxlen; 88 if (SP_PARM->slk_format >= 3) { /* PC style */ 89 gap = (cols - 3 * (3 + 4 * max_length)) / 2; 90 91 if (gap < 1) 92 gap = 1; 93 94 for (i = x = 0; i < SP_PARM->_slk->maxlab; i++) { 95 SP_PARM->_slk->ent[i].ent_x = x; 96 x += max_length; 97 x += (i == 3 || i == 7) ? gap : 1; 98 } 99 } else { 100 if (SP_PARM->slk_format == 2) { /* 4-4 */ 101 gap = cols - (int) (SP_PARM->_slk->maxlab * max_length) - 6; 102 103 if (gap < 1) 104 gap = 1; 105 for (i = x = 0; i < SP_PARM->_slk->maxlab; i++) { 106 SP_PARM->_slk->ent[i].ent_x = x; 107 x += max_length; 108 x += (i == 3) ? gap : 1; 109 } 110 } else { 111 if (SP_PARM->slk_format == 1) { /* 1 -> 3-2-3 */ 112 gap = (cols - (SP_PARM->_slk->maxlab * max_length) - 5) 113 / 2; 114 115 if (gap < 1) 116 gap = 1; 117 for (i = x = 0; i < SP_PARM->_slk->maxlab; i++) { 118 SP_PARM->_slk->ent[i].ent_x = x; 119 x += max_length; 120 x += (i == 2 || i == 4) ? gap : 1; 121 } 122 } else { 123 return slk_failed(NCURSES_SP_ARG); 124 } 125 } 126 } 127 SP_PARM->_slk->dirty = TRUE; 128 129 return OK; 130 } 131 132 /* 133 * Initialize soft labels. 134 * Called from newterm() 135 */ 136 NCURSES_EXPORT(int) 137 _nc_slk_initialize(WINDOW *stwin, int cols) 138 { 139 int i; 140 int res = OK; 141 size_t max_length; 142 SCREEN *sp; 143 int numlab; 144 145 T((T_CALLED("_nc_slk_initialize()"))); 146 147 assert(stwin); 148 149 sp = _nc_screen_of(stwin); 150 if (0 == sp) 151 returnCode(ERR); 152 153 assert(TerminalOf(SP_PARM)); 154 155 numlab = NumLabels; 156 157 if (SP_PARM->_slk) { /* we did this already, so simply return */ 158 returnCode(OK); 159 } else if ((SP_PARM->_slk = typeCalloc(SLK, 1)) == 0) 160 returnCode(ERR); 161 162 if (!SP_PARM->slk_format) 163 SP_PARM->slk_format = _nc_globals.slk_format; 164 165 /* 166 * If we use colors, vidputs() will suppress video attributes that conflict 167 * with colors. In that case, we're still guaranteed that "reverse" would 168 * work. 169 */ 170 if ((NoColorVideo & 1) == 0) 171 SetAttr(SP_PARM->_slk->attr, A_STANDOUT); 172 else 173 SetAttr(SP_PARM->_slk->attr, A_REVERSE); 174 175 SP_PARM->_slk->maxlab = (short) ((numlab > 0) 176 ? numlab 177 : MAX_SKEY(SP_PARM->slk_format)); 178 SP_PARM->_slk->maxlen = (short) ((numlab > 0) 179 ? LabelWidth * LabelHeight 180 : MAX_SKEY_LEN(SP_PARM->slk_format)); 181 SP_PARM->_slk->labcnt = (short) ((SP_PARM->_slk->maxlab < MAX_SKEY(SP_PARM->slk_format)) 182 ? MAX_SKEY(SP_PARM->slk_format) 183 : SP_PARM->_slk->maxlab); 184 185 if (SP_PARM->_slk->maxlen <= 0 186 || SP_PARM->_slk->labcnt <= 0 187 || (SP_PARM->_slk->ent = typeCalloc(slk_ent, 188 (size_t) SP_PARM->_slk->labcnt)) 189 == NULL) 190 returnCode(slk_failed(NCURSES_SP_ARG)); 191 192 max_length = (size_t) SP_PARM->_slk->maxlen; 193 for (i = 0; i < SP_PARM->_slk->labcnt; i++) { 194 size_t used = max_length + 1; 195 196 SP_PARM->_slk->ent[i].ent_text = (char *) _nc_doalloc(0, used); 197 if (SP_PARM->_slk->ent[i].ent_text == 0) 198 returnCode(slk_failed(NCURSES_SP_ARG)); 199 memset(SP_PARM->_slk->ent[i].ent_text, 0, used); 200 201 SP_PARM->_slk->ent[i].form_text = (char *) _nc_doalloc(0, used); 202 if (SP_PARM->_slk->ent[i].form_text == 0) 203 returnCode(slk_failed(NCURSES_SP_ARG)); 204 205 if (used > 1) { 206 memset(SP_PARM->_slk->ent[i].form_text, ' ', used - 1); 207 } 208 SP_PARM->_slk->ent[i].form_text[used - 1] = '\0'; 209 210 SP_PARM->_slk->ent[i].visible = (char) (i < SP_PARM->_slk->maxlab); 211 } 212 213 res = _nc_format_slks(NCURSES_SP_ARGx cols); 214 215 if ((SP_PARM->_slk->win = stwin) == NULL) { 216 returnCode(slk_failed(NCURSES_SP_ARG)); 217 } 218 219 /* We now reset the format so that the next newterm has again 220 * per default no SLK keys and may call slk_init again to 221 * define a new layout. (juergen 03-Mar-1999) 222 */ 223 _nc_globals.slk_format = 0; 224 returnCode(res); 225 } 226 227 /* 228 * Restore the soft labels on the screen. 229 */ 230 NCURSES_EXPORT(int) 231 NCURSES_SP_NAME(slk_restore) (NCURSES_SP_DCL0) 232 { 233 T((T_CALLED("slk_restore(%p)"), (void *) SP_PARM)); 234 235 if (0 == SP_PARM) 236 returnCode(ERR); 237 if (SP_PARM->_slk == NULL) 238 returnCode(ERR); 239 SP_PARM->_slk->hidden = FALSE; 240 SP_PARM->_slk->dirty = TRUE; 241 242 returnCode(NCURSES_SP_NAME(slk_refresh) (NCURSES_SP_ARG)); 243 } 244 245 #if NCURSES_SP_FUNCS 246 NCURSES_EXPORT(int) 247 slk_restore(void) 248 { 249 return NCURSES_SP_NAME(slk_restore) (CURRENT_SCREEN); 250 } 251 #endif 252