lib_slk.c revision 176187
1/**************************************************************************** 2 * Copyright (c) 1998-2005,2008 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 45#include <ctype.h> 46#include <term.h> /* num_labels, label_*, plab_norm */ 47 48MODULE_ID("$Id: lib_slk.c,v 1.31 2008/01/12 20:21:00 tom Exp $") 49 50/* 51 * We'd like to move these into the screen context structure, but cannot, 52 * because slk_init() is called before initscr()/newterm(). 53 */ 54NCURSES_EXPORT_VAR(int) 55_nc_slk_format = 0; /* one more than format specified in slk_init() */ 56 57/* 58 * Paint the info line for the PC style SLK emulation. 59 */ 60static void 61slk_paint_info(WINDOW *win) 62{ 63 if (win && SP->slk_format == 4) { 64 int i; 65 66 mvwhline(win, 0, 0, 0, getmaxx(win)); 67 wmove(win, 0, 0); 68 69 for (i = 0; i < SP->_slk->maxlab; i++) { 70 mvwprintw(win, 0, SP->_slk->ent[i].ent_x, "F%d", i + 1); 71 } 72 } 73} 74 75/* 76 * Free any memory related to soft labels, return an error. 77 */ 78static int 79slk_failed(void) 80{ 81 if (SP->_slk) { 82 FreeIfNeeded(SP->_slk->ent); 83 free(SP->_slk); 84 SP->_slk = (SLK *) 0; 85 } 86 return ERR; 87} 88 89/* 90 * Initialize soft labels. 91 * Called from newterm() 92 */ 93NCURSES_EXPORT(int) 94_nc_slk_initialize(WINDOW *stwin, int cols) 95{ 96 int i, x; 97 int res = OK; 98 unsigned max_length; 99 100 T((T_CALLED("_nc_slk_initialize()"))); 101 102 if (SP->_slk) { /* we did this already, so simply return */ 103 returnCode(OK); 104 } else if ((SP->_slk = typeCalloc(SLK, 1)) == 0) 105 returnCode(ERR); 106 107 SP->_slk->ent = NULL; 108 109 /* 110 * If we use colors, vidputs() will suppress video attributes that conflict 111 * with colors. In that case, we're still guaranteed that "reverse" would 112 * work. 113 */ 114 if ((no_color_video & 1) == 0) 115 SetAttr(SP->_slk->attr, A_STANDOUT); 116 else 117 SetAttr(SP->_slk->attr, A_REVERSE); 118 119 SP->_slk->maxlab = ((num_labels > 0) 120 ? num_labels 121 : MAX_SKEY(_nc_globals.slk_format)); 122 SP->_slk->maxlen = ((num_labels > 0) 123 ? label_width * label_height 124 : MAX_SKEY_LEN(_nc_globals.slk_format)); 125 SP->_slk->labcnt = ((SP->_slk->maxlab < MAX_SKEY(_nc_globals.slk_format)) 126 ? MAX_SKEY(_nc_globals.slk_format) 127 : SP->_slk->maxlab); 128 129 if (SP->_slk->maxlen <= 0 130 || SP->_slk->labcnt <= 0 131 || (SP->_slk->ent = typeCalloc(slk_ent, 132 (unsigned) SP->_slk->labcnt)) == NULL) 133 returnCode(slk_failed()); 134 135 max_length = SP->_slk->maxlen; 136 for (i = 0; i < SP->_slk->labcnt; i++) { 137 size_t used = max_length + 1; 138 139 if ((SP->_slk->ent[i].ent_text = (char *) _nc_doalloc(0, used)) == 0) 140 returnCode(slk_failed()); 141 memset(SP->_slk->ent[i].ent_text, 0, used); 142 143 if ((SP->_slk->ent[i].form_text = (char *) _nc_doalloc(0, used)) == 0) 144 returnCode(slk_failed()); 145 memset(SP->_slk->ent[i].form_text, 0, used); 146 147 memset(SP->_slk->ent[i].form_text, ' ', max_length); 148 SP->_slk->ent[i].visible = (i < SP->_slk->maxlab); 149 } 150 if (_nc_globals.slk_format >= 3) { /* PC style */ 151 int gap = (cols - 3 * (3 + 4 * max_length)) / 2; 152 153 if (gap < 1) 154 gap = 1; 155 156 for (i = x = 0; i < SP->_slk->maxlab; i++) { 157 SP->_slk->ent[i].ent_x = x; 158 x += max_length; 159 x += (i == 3 || i == 7) ? gap : 1; 160 } 161 slk_paint_info(stwin); 162 } else { 163 if (_nc_globals.slk_format == 2) { /* 4-4 */ 164 int gap = cols - (SP->_slk->maxlab * max_length) - 6; 165 166 if (gap < 1) 167 gap = 1; 168 for (i = x = 0; i < SP->_slk->maxlab; i++) { 169 SP->_slk->ent[i].ent_x = x; 170 x += max_length; 171 x += (i == 3) ? gap : 1; 172 } 173 } else { 174 if (_nc_globals.slk_format == 1) { /* 1 -> 3-2-3 */ 175 int gap = (cols - (SP->_slk->maxlab * max_length) - 5) 176 / 2; 177 178 if (gap < 1) 179 gap = 1; 180 for (i = x = 0; i < SP->_slk->maxlab; i++) { 181 SP->_slk->ent[i].ent_x = x; 182 x += max_length; 183 x += (i == 2 || i == 4) ? gap : 1; 184 } 185 } else 186 returnCode(slk_failed()); 187 } 188 } 189 SP->_slk->dirty = TRUE; 190 if ((SP->_slk->win = stwin) == NULL) { 191 returnCode(slk_failed()); 192 } 193 194 /* We now reset the format so that the next newterm has again 195 * per default no SLK keys and may call slk_init again to 196 * define a new layout. (juergen 03-Mar-1999) 197 */ 198 SP->slk_format = _nc_globals.slk_format; 199 _nc_globals.slk_format = 0; 200 returnCode(res); 201} 202 203/* 204 * Restore the soft labels on the screen. 205 */ 206NCURSES_EXPORT(int) 207slk_restore(void) 208{ 209 T((T_CALLED("slk_restore()"))); 210 211 if (SP->_slk == NULL) 212 return (ERR); 213 SP->_slk->hidden = FALSE; 214 SP->_slk->dirty = TRUE; 215 /* we have to repaint info line eventually */ 216 slk_paint_info(SP->_slk->win); 217 218 returnCode(slk_refresh()); 219} 220