1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1995-1999 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* LINTLIBRARY */ 30 31 /* 32 * slk.c 33 * 34 * XCurses Library 35 * 36 * Copyright 1990, 1995 by Mortice Kern Systems Inc. All rights reserved. 37 * 38 */ 39 40 #if M_RCSID 41 #ifndef lint 42 static char rcsID[] = 43 "$Header: /team/ps/sun_xcurses/archive/local_changes/xcurses/src/lib/" 44 "libxcurses/src/libc/xcurses/rcs/slk.c 1.9 1998/05/20 17:26:23 " 45 "cbates Exp $"; 46 #endif 47 #endif 48 49 #include <private.h> 50 #include <string.h> 51 52 int __m_slk_labels_on; 53 int __m_slk_touched = 0; 54 /* 55 * Flag for initialisation soft label keys once setupterm() has been called. 56 */ 57 int 58 slk_init(int fmt) 59 { 60 int code = ERR; 61 62 if (0 <= fmt && fmt <= 1) { 63 __m_slk_format = fmt; 64 __m_slk_labels_on = 1; 65 code = OK; 66 } 67 68 return (code); 69 } 70 71 int 72 slk_attron(const chtype at) 73 { 74 int code = OK; 75 76 if (__m_screen->_slk._w != NULL) 77 code = wattron(__m_screen->_slk._w, (int) at); 78 79 return (code); 80 } 81 82 int 83 slk_attroff(const chtype at) 84 { 85 int code = OK; 86 87 if (__m_screen->_slk._w != NULL) 88 code = wattroff(__m_screen->_slk._w, (int) at); 89 90 return (code); 91 } 92 93 int 94 slk_attrset(const chtype at) 95 { 96 int code = OK; 97 98 if (__m_screen->_slk._w != NULL) 99 code = wattrset(__m_screen->_slk._w, (int) at); 100 101 return (code); 102 } 103 104 int 105 slk_attr_off(const attr_t at, void *opts) 106 { 107 int code = OK; 108 109 if (__m_screen->_slk._w != NULL) 110 code = wattr_off(__m_screen->_slk._w, at, opts); 111 112 return (code); 113 } 114 115 int 116 slk_attr_on(const attr_t at, void *opts) 117 { 118 int code = OK; 119 120 if (__m_screen->_slk._w != NULL) 121 code = wattr_on(__m_screen->_slk._w, at, opts); 122 123 return (code); 124 } 125 126 int 127 slk_attr_set(const attr_t at, short co, void *opts) 128 { 129 int code = OK; 130 131 if (__m_screen->_slk._w != NULL) 132 code = wattr_set(__m_screen->_slk._w, at, co, opts); 133 134 return (code); 135 } 136 137 int 138 slk_color(short co) 139 { 140 int code = OK; 141 142 if (__m_screen->_slk._w != NULL) 143 code = wcolor_set(__m_screen->_slk._w, co, (void *) 0); 144 145 return (code); 146 } 147 148 int 149 slk_touch(void) 150 { 151 int code = OK; 152 WINDOW *w = __m_screen->_slk._w; 153 154 if (w != NULL) { 155 code = wtouchln(w, 0, 1, 1); 156 wtouchln_hard(w, 0, 1); 157 } else 158 __m_slk_touched = 1; 159 160 return (code); 161 } 162 163 /* 164 * These label start columns assume 80 columns in order to 165 * fit 8 _slk._labels of 8 columns. 166 */ 167 static const int format[][8] = { 168 { 0, 9, 18, 31, 40, 53, 62, 71 }, 169 { 0, 9, 18, 27, 44, 53, 62, 71 }, 170 }; 171 172 #define _LABEL_LENGTH_MALLOC \ 173 (MB_LEN_MAX * ((1 + _M_CCHAR_MAX) * 8) + 1) 174 175 void 176 __m_slk_set_all(void) 177 { 178 int i; 179 180 for (i = 0; i < 8; ++i) { 181 if (__m_screen->_slk._labels[i] != NULL) { 182 (void) slk_set(i + 1, __m_screen->_slk._labels[i], 183 __m_screen->_slk._justify[i]); 184 } 185 } 186 } 187 188 int 189 __m_slk_clear(int kluge) 190 { 191 int i; 192 int index; 193 int code = ERR; 194 195 if (__m_screen->_slk._w != NULL) { 196 cchar_t _bg = __m_screen->_slk._w->_bg; 197 if (kluge) { 198 /* Test suite expects spaces to have FG attributes */ 199 __m_screen->_slk._w->_bg = __m_screen->_slk._w->_fg; 200 } 201 for (index = 0; index < 8; ++index) { 202 i = format[__m_slk_format][index]; 203 (void) __m_cc_erase(__m_screen->_slk._w, 204 0, i, 0, i + 7); 205 } 206 __m_screen->_slk._w->_bg = _bg; /* Restore ... */ 207 208 } else if (plab_norm != NULL) { 209 for (index = 0; index < 8; ++index) { 210 char *p; 211 p = __m_screen->_slk._saved[index]; 212 if (!p) { 213 p = (char *)malloc(_LABEL_LENGTH_MALLOC); 214 if (p == NULL) 215 goto error; 216 __m_screen->_slk._saved[index] = p; 217 } 218 (void) strcpy(p, (kluge) ? "" : " "); 219 } 220 } 221 if (__m_screen->_slk._w != NULL) { 222 code = wrefresh(__m_screen->_slk._w); 223 } else { 224 __m_slk_labels_on = 0; 225 code = slk_refresh(); 226 } 227 228 error: 229 return (code); 230 } 231 232 int 233 slk_clear(void) 234 { 235 return (__m_slk_clear(0)); 236 } 237 238 int 239 slk_restore(void) 240 { 241 int code; 242 243 __m_slk_set_all(); 244 __m_slk_labels_on = 1; 245 code = slk_refresh(); 246 return (code); 247 } 248 249 int 250 slk_noutrefresh(void) 251 { 252 int code; 253 254 if (__m_screen->_slk._w != NULL) 255 code = wnoutrefresh(__m_screen->_slk._w); 256 else { 257 if (__m_slk_touched) { 258 __m_slk_set_all(); 259 __m_slk_touched = 0; 260 } 261 if (__m_slk_labels_on) { 262 if (label_on != NULL) { 263 (void) TPUTS(label_on, 1, __m_outc); 264 } 265 } else { 266 if (label_off != NULL) { 267 (void) TPUTS(label_off, 1, __m_outc); 268 } 269 } 270 (void) fflush(__m_screen->_of); 271 code = OK; 272 } 273 274 return (code); 275 } 276 277 int 278 slk_refresh(void) 279 { 280 int code; 281 282 if ((code = slk_noutrefresh()) == OK) 283 code = doupdate(); 284 285 return (code); 286 } 287 288 void 289 __m_slk_doupdate(void) 290 { 291 if ((__m_screen->_slk._w == NULL) && plab_norm) { 292 int index; 293 for (index = 0; index < 8; index++) { 294 char *s = __m_screen->_slk._saved[index]; 295 if (s) { 296 (void) TPUTS(tparm(plab_norm, (long) index+1, 297 (long) s, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 298 1, __m_outc); 299 } 300 } 301 } 302 } 303 304 char * 305 slk_label(int index) 306 { 307 char *label; 308 309 if (index < 1 || 8 < index) { 310 label = NULL; 311 } else { 312 label = __m_screen->_slk._labels[index-1]; 313 } 314 return (label); 315 } 316 317 int 318 slk_set(int index, const char *label, int justify) 319 { 320 int code = ERR; 321 wchar_t wcs[_M_CCHAR_MAX * 8 + 1]; 322 323 if ((label == NULL) || *label == '\0') 324 label = " "; 325 if (mbstowcs(wcs, label, sizeof (wcs)) != (size_t)-1) 326 code = slk_wset(index, wcs, justify); 327 328 return (code); 329 } 330 331 int 332 slk_wset(int index, const wchar_t *label, int justify) 333 { 334 cchar_t cc; 335 int i, width, code = ERR; 336 wchar_t wcs[_M_CCHAR_MAX * 8 + 1], *wp; 337 char mbs[_LABEL_LENGTH_MALLOC]; 338 char tmbs[_LABEL_LENGTH_MALLOC]; 339 int ww = 0; 340 int left1, left2; 341 static const char *spcs = " "; 342 343 if (index < 1 || 8 < index || justify < 0 || 2 < justify) 344 goto error1; 345 346 index--; /* Shift from {1..8} to {0..7} */ 347 348 if (label == NULL) 349 label = L""; 350 351 /* Copy the characters that fill the first 8 columns of the label. */ 352 for (wp = wcs, width = 0; *label != '\0'; label += i, wp += cc._n) { 353 if ((i = __m_wcs_cc(label, A_NORMAL, 0, &cc)) < 0) 354 goto error1; 355 356 ww += __m_cc_width(&cc); 357 if (ww > 8) 358 break; 359 else 360 width = ww; 361 362 (void) wcsncpy(wp, cc._wc, cc._n); 363 } 364 *wp = '\0'; 365 366 if (wcstombs(tmbs, wcs, sizeof (mbs)) == (size_t) -1) 367 goto error1; 368 369 if (width == 8) { 370 (void) strcpy(mbs, tmbs); 371 } else { 372 switch (justify) { 373 case 0: 374 (void) strcpy(mbs, tmbs); 375 (void) strncat(mbs, spcs, (8 - width)); 376 *(mbs + strlen(tmbs) + (8 - width)) = '\0'; 377 break; 378 case 1: 379 left1 = (8 - width) / 2; 380 (void) strncpy(mbs, spcs, left1); 381 (void) strcpy(mbs + left1, tmbs); 382 left2 = 8 - width - left1; 383 (void) strncat(mbs, spcs, left2); 384 *(mbs + left1 + strlen(tmbs) + left2) = '\0'; 385 break; 386 case 2: 387 left1 = 8 - width; 388 (void) strncpy(mbs, spcs, left1); 389 (void) strcpy(mbs + left1, tmbs); 390 break; 391 } 392 } 393 394 /* Remember the new label. */ 395 __m_screen->_slk._justify[index] = (short) justify; 396 397 if (__m_screen->_slk._labels[index] != NULL) 398 free(__m_screen->_slk._labels[index]); 399 if ((__m_screen->_slk._labels[index] = strdup(tmbs)) == NULL) 400 goto error1; 401 402 if (plab_norm != NULL) { 403 char *p; 404 p = __m_screen->_slk._saved[index]; 405 if (!p) { 406 p = (char *)malloc(_LABEL_LENGTH_MALLOC); 407 if (p == NULL) 408 goto error1; 409 __m_screen->_slk._saved[index] = p; 410 } 411 (void) strcpy(p, mbs); 412 } 413 414 __m_slk_labels_on = 1; 415 416 if (__m_screen->_slk._w != NULL) { 417 cchar_t _bg = __m_screen->_slk._w->_bg; 418 /* Write the justified label into the slk window. */ 419 i = format[__m_slk_format][index]; 420 __m_screen->_slk._w->_bg = __m_screen->_slk._w->_fg; 421 (void) __m_cc_erase(__m_screen->_slk._w, 0, i, 0, i + 7); 422 __m_screen->_slk._w->_bg = _bg; /* Restore ... */ 423 424 (void) mvwaddstr(__m_screen->_slk._w, 0, i, mbs); 425 } 426 427 code = OK; 428 error1: 429 return (code); 430 } 431