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