Changes in uspace/lib/clui/tinput.c [9f1362d4:5db9084] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/clui/tinput.c
r9f1362d4 r5db9084 40 40 #include <assert.h> 41 41 #include <bool.h> 42 #include <tinput.h> 42 43 #include "tinput.h" 43 44 44 45 /** Seek direction */ … … 48 49 } seek_dir_t; 49 50 50 static void tinput_init(tinput_t * );51 static void tinput_insert_string(tinput_t * , const char *);52 static void tinput_sel_get_bounds(tinput_t * , size_t *, size_t *);53 static bool tinput_sel_active(tinput_t * );54 static void tinput_sel_all(tinput_t * );55 static void tinput_sel_delete(tinput_t * );56 static void tinput_key_ctrl(tinput_t * , console_event_t *);57 static void tinput_key_shift(tinput_t * , console_event_t *);58 static void tinput_key_ctrl_shift(tinput_t * , console_event_t *);59 static void tinput_key_unmod(tinput_t * , console_event_t *);60 static void tinput_pre_seek(tinput_t * , bool);61 static void tinput_post_seek(tinput_t * , bool);51 static void tinput_init(tinput_t *ti); 52 static void tinput_insert_string(tinput_t *ti, const char *str); 53 static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb); 54 static bool tinput_sel_active(tinput_t *ti); 55 static void tinput_sel_all(tinput_t *ti); 56 static void tinput_sel_delete(tinput_t *ti); 57 static void tinput_key_ctrl(tinput_t *ti, console_event_t *ev); 58 static void tinput_key_shift(tinput_t *ti, console_event_t *ev); 59 static void tinput_key_ctrl_shift(tinput_t *ti, console_event_t *ev); 60 static void tinput_key_unmod(tinput_t *ti, console_event_t *ev); 61 static void tinput_pre_seek(tinput_t *ti, bool shift_held); 62 static void tinput_post_seek(tinput_t *ti, bool shift_held); 62 63 63 64 /** Create a new text input field. */ … … 65 66 { 66 67 tinput_t *ti; 67 68 68 69 ti = malloc(sizeof(tinput_t)); 69 70 if (ti == NULL) 70 71 return NULL; 71 72 72 73 tinput_init(ti); 73 74 return ti; … … 80 81 } 81 82 82 static void tinput_display_tail(tinput_t *ti, size_t start, size_t pad)83 { 84 wchar_t dbuf[INPUT_MAX_SIZE + 1];85 86 size_t sa;87 size_t sb; 83 static void tinput_display_tail(tinput_t *ti, int start, int pad) 84 { 85 static wchar_t dbuf[INPUT_MAX_SIZE + 1]; 86 int sa, sb; 87 int i, p; 88 88 89 tinput_sel_get_bounds(ti, &sa, &sb); 89 90 console_ set_pos(fphone(stdout), (ti->col0 + start) % ti->con_cols,90 91 console_goto(fphone(stdout), (ti->col0 + start) % ti->con_cols, 91 92 ti->row0 + (ti->col0 + start) / ti->con_cols); 92 console_set_ style(fphone(stdout), STYLE_NORMAL);93 94 size_tp = start;93 console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0); 94 95 p = start; 95 96 if (p < sa) { 96 97 memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(wchar_t)); … … 99 100 p = sa; 100 101 } 101 102 102 103 if (p < sb) { 103 104 fflush(stdout); 104 console_set_ style(fphone(stdout), STYLE_SELECTED);105 console_set_color(fphone(stdout), COLOR_BLACK, COLOR_RED, 0); 105 106 memcpy(dbuf, ti->buffer + p, 106 107 (sb - p) * sizeof(wchar_t)); … … 109 110 p = sb; 110 111 } 111 112 112 113 fflush(stdout); 113 console_set_ style(fphone(stdout), STYLE_NORMAL);114 114 console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0); 115 115 116 if (p < ti->nc) { 116 117 memcpy(dbuf, ti->buffer + p, … … 119 120 printf("%ls", dbuf); 120 121 } 121 122 for ( p = 0; p < pad; p++)122 123 for (i = 0; i < pad; ++i) 123 124 putchar(' '); 124 125 125 fflush(stdout); 126 126 } … … 133 133 static void tinput_position_caret(tinput_t *ti) 134 134 { 135 console_ set_pos(fphone(stdout), (ti->col0 + ti->pos) % ti->con_cols,135 console_goto(fphone(stdout), (ti->col0 + ti->pos) % ti->con_cols, 136 136 ti->row0 + (ti->col0 + ti->pos) / ti->con_cols); 137 137 } … … 140 140 static void tinput_update_origin(tinput_t *ti) 141 141 { 142 ipcarg_t width = ti->col0 + ti->nc; 143 ipcarg_t rows = (width / ti->con_cols) + 1; 144 142 int width, rows; 143 144 width = ti->col0 + ti->nc; 145 rows = (width / ti->con_cols) + 1; 146 145 147 /* Update row0 if the screen scrolled. */ 146 148 if (ti->row0 + rows > ti->con_rows) 147 ti->row0 = ti->con_rows - rows; 149 ti->row0 = ti->con_rows - rows; 148 150 } 149 151 150 152 static void tinput_insert_char(tinput_t *ti, wchar_t c) 151 153 { 154 int i; 155 int new_width, new_height; 156 152 157 if (ti->nc == INPUT_MAX_SIZE) 153 158 return; 154 155 ipcarg_tnew_width = ti->col0 + ti->nc + 1;159 160 new_width = ti->col0 + ti->nc + 1; 156 161 if (new_width % ti->con_cols == 0) { 157 162 /* Advancing to new line. */ 158 ipcarg_t new_height = (new_width / ti->con_cols) + 1; 159 if (new_height >= ti->con_rows) { 160 /* Disallow text longer than 1 page for now. */ 161 return; 162 } 163 } 164 165 size_t i; 166 for (i = ti->nc; i > ti->pos; i--) 163 new_height = (new_width / ti->con_cols) + 1; 164 if (new_height >= ti->con_rows) 165 return; /* Disallow text longer than 1 page for now. */ 166 } 167 168 for (i = ti->nc; i > ti->pos; --i) 167 169 ti->buffer[i] = ti->buffer[i - 1]; 168 170 169 171 ti->buffer[ti->pos] = c; 170 172 ti->pos += 1; … … 172 174 ti->buffer[ti->nc] = '\0'; 173 175 ti->sel_start = ti->pos; 174 176 175 177 tinput_display_tail(ti, ti->pos - 1, 0); 176 178 tinput_update_origin(ti); … … 180 182 static void tinput_insert_string(tinput_t *ti, const char *str) 181 183 { 182 size_t ilen = min(str_length(str), INPUT_MAX_SIZE - ti->nc); 184 int i; 185 int new_width, new_height; 186 int ilen; 187 wchar_t c; 188 size_t off; 189 190 ilen = min((ssize_t) str_length(str), INPUT_MAX_SIZE - ti->nc); 183 191 if (ilen == 0) 184 192 return; 185 186 ipcarg_t new_width = ti->col0 + ti->nc + ilen; 187 ipcarg_t new_height = (new_width / ti->con_cols) + 1; 188 if (new_height >= ti->con_rows) { 189 /* Disallow text longer than 1 page for now. */ 190 return; 191 } 192 193 if (ti->nc > 0) { 194 size_t i; 195 for (i = ti->nc; i > ti->pos; i--) 196 ti->buffer[i + ilen - 1] = ti->buffer[i - 1]; 197 } 198 199 size_t off = 0; 200 size_t i = 0; 193 194 new_width = ti->col0 + ti->nc + ilen; 195 new_height = (new_width / ti->con_cols) + 1; 196 if (new_height >= ti->con_rows) 197 return; /* Disallow text longer than 1 page for now. */ 198 199 for (i = ti->nc - 1; i >= ti->pos; --i) 200 ti->buffer[i + ilen] = ti->buffer[i]; 201 202 off = 0; i = 0; 201 203 while (i < ilen) { 202 wchar_tc = str_decode(str, &off, STR_NO_LIMIT);204 c = str_decode(str, &off, STR_NO_LIMIT); 203 205 if (c == '\0') 204 206 break; 205 207 206 208 /* Filter out non-printable chars. */ 207 209 if (c < 32) 208 210 c = 32; 209 211 210 212 ti->buffer[ti->pos + i] = c; 211 i++;212 } 213 213 ++i; 214 } 215 214 216 ti->pos += ilen; 215 217 ti->nc += ilen; 216 218 ti->buffer[ti->nc] = '\0'; 217 219 ti->sel_start = ti->pos; 218 220 219 221 tinput_display_tail(ti, ti->pos - ilen, 0); 220 222 tinput_update_origin(ti); … … 224 226 static void tinput_backspace(tinput_t *ti) 225 227 { 228 int i; 229 226 230 if (tinput_sel_active(ti)) { 227 231 tinput_sel_delete(ti); 228 232 return; 229 233 } 230 234 231 235 if (ti->pos == 0) 232 236 return; 233 234 size_t i; 235 for (i = ti->pos; i < ti->nc; i++) 237 238 for (i = ti->pos; i < ti->nc; ++i) 236 239 ti->buffer[i - 1] = ti->buffer[i]; 237 238 240 ti->pos -= 1; 239 241 ti->nc -= 1; 240 242 ti->buffer[ti->nc] = '\0'; 241 243 ti->sel_start = ti->pos; 242 244 243 245 tinput_display_tail(ti, ti->pos, 1); 244 246 tinput_position_caret(ti); … … 251 253 return; 252 254 } 253 255 254 256 if (ti->pos == ti->nc) 255 257 return; 256 258 257 259 ti->pos += 1; 258 260 ti->sel_start = ti->pos; 259 261 260 262 tinput_backspace(ti); 261 263 } … … 264 266 { 265 267 tinput_pre_seek(ti, shift_held); 266 268 267 269 if (dir == seek_forward) { 268 270 if (ti->pos < ti->nc) … … 272 274 ti->pos -= 1; 273 275 } 274 276 275 277 tinput_post_seek(ti, shift_held); 276 278 } … … 279 281 { 280 282 tinput_pre_seek(ti, shift_held); 281 283 282 284 if (dir == seek_forward) { 283 285 if (ti->pos == ti->nc) 284 286 return; 285 286 while ( true) {287 288 while (1) { 287 289 ti->pos += 1; 288 290 289 291 if (ti->pos == ti->nc) 290 292 break; 291 292 if ( (ti->buffer[ti->pos - 1] == ' ')&&293 (ti->buffer[ti->pos] != ' '))293 294 if (ti->buffer[ti->pos - 1] == ' ' && 295 ti->buffer[ti->pos] != ' ') 294 296 break; 295 297 } … … 297 299 if (ti->pos == 0) 298 300 return; 299 300 while ( true) {301 302 while (1) { 301 303 ti->pos -= 1; 302 304 303 305 if (ti->pos == 0) 304 306 break; 305 307 306 308 if (ti->buffer[ti->pos - 1] == ' ' && 307 309 ti->buffer[ti->pos] != ' ') 308 310 break; 309 311 } 310 311 } 312 312 313 } 314 313 315 tinput_post_seek(ti, shift_held); 314 316 } … … 317 319 { 318 320 tinput_pre_seek(ti, shift_held); 319 321 320 322 if (dir == seek_forward) { 321 323 if (ti->pos + ti->con_cols <= ti->nc) 322 324 ti->pos = ti->pos + ti->con_cols; 323 325 } else { 324 if (ti->pos >= ti->con_cols)326 if (ti->pos - ti->con_cols >= 0) 325 327 ti->pos = ti->pos - ti->con_cols; 326 328 } 327 329 328 330 tinput_post_seek(ti, shift_held); 329 331 } … … 332 334 { 333 335 tinput_pre_seek(ti, shift_held); 334 336 335 337 if (dir == seek_backward) 336 338 ti->pos = 0; 337 339 else 338 340 ti->pos = ti->nc; 339 341 340 342 tinput_post_seek(ti, shift_held); 341 343 } … … 343 345 static void tinput_pre_seek(tinput_t *ti, bool shift_held) 344 346 { 345 if ( (tinput_sel_active(ti)) && (!shift_held)) {347 if (tinput_sel_active(ti) && !shift_held) { 346 348 /* Unselect and redraw. */ 347 349 ti->sel_start = ti->pos; … … 360 362 ti->sel_start = ti->pos; 361 363 } 362 363 364 tinput_position_caret(ti); 364 365 } … … 366 367 static void tinput_history_insert(tinput_t *ti, char *str) 367 368 { 369 int i; 370 368 371 if (ti->hnum < HISTORY_LEN) { 369 372 ti->hnum += 1; … … 372 375 free(ti->history[HISTORY_LEN]); 373 376 } 374 375 size_t i; 376 for (i = ti->hnum; i > 1; i--) 377 378 for (i = ti->hnum; i > 1; --i) 377 379 ti->history[i] = ti->history[i - 1]; 378 380 379 381 ti->history[1] = str_dup(str); 380 382 381 383 if (ti->history[0] != NULL) { 382 384 free(ti->history[0]); … … 393 395 } 394 396 395 static void tinput_sel_get_bounds(tinput_t *ti, size_t *sa, size_t *sb)397 static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb) 396 398 { 397 399 if (ti->sel_start < ti->pos) { … … 406 408 static bool tinput_sel_active(tinput_t *ti) 407 409 { 408 return (ti->sel_start != ti->pos);410 return ti->sel_start != ti->pos; 409 411 } 410 412 … … 419 421 static void tinput_sel_delete(tinput_t *ti) 420 422 { 421 size_t sa; 422 size_t sb; 423 423 int sa, sb; 424 424 425 tinput_sel_get_bounds(ti, &sa, &sb); 425 426 if (sa == sb) 426 427 return; 427 428 428 429 memmove(ti->buffer + sa, ti->buffer + sb, 429 430 (ti->nc - sb) * sizeof(wchar_t)); 430 431 431 ti->pos = ti->sel_start = sa; 432 432 ti->nc -= (sb - sa); 433 433 ti->buffer[ti->nc] = '\0'; 434 434 435 435 tinput_display_tail(ti, sa, sb - sa); 436 436 tinput_position_caret(ti); … … 439 439 static void tinput_sel_copy_to_cb(tinput_t *ti) 440 440 { 441 size_t sa;442 size_t sb;443 441 int sa, sb; 442 char *str; 443 444 444 tinput_sel_get_bounds(ti, &sa, &sb); 445 446 char *str; 447 445 448 446 if (sb < ti->nc) { 449 447 wchar_t tmp_c = ti->buffer[sb]; … … 456 454 if (str == NULL) 457 455 goto error; 458 456 459 457 if (clipboard_put_str(str) != EOK) 460 458 goto error; 461 459 462 460 free(str); 463 461 return; 464 465 462 error: 466 /* TODO: Give the user some kind of warning. */467 463 return; 464 /* TODO: Give the user some warning. */ 468 465 } 469 466 … … 471 468 { 472 469 char *str; 473 int rc = clipboard_get_str(&str); 474 475 if ((rc != EOK) || (str == NULL)) { 476 /* TODO: Give the user some kind of warning. */ 477 return; 478 } 479 470 int rc; 471 472 rc = clipboard_get_str(&str); 473 if (rc != EOK || str == NULL) 474 return; /* TODO: Give the user some warning. */ 475 480 476 tinput_insert_string(ti, str); 481 477 free(str); … … 484 480 static void tinput_history_seek(tinput_t *ti, int offs) 485 481 { 486 if (offs >= 0) { 487 if (ti->hpos + offs > ti->hnum) 488 return; 489 } else { 490 if (ti->hpos < (size_t) -offs) 491 return; 492 } 493 482 int pad; 483 484 if (ti->hpos + offs < 0 || ti->hpos + offs > ti->hnum) 485 return; 486 494 487 if (ti->history[ti->hpos] != NULL) { 495 488 free(ti->history[ti->hpos]); 496 489 ti->history[ti->hpos] = NULL; 497 490 } 498 491 499 492 ti->history[ti->hpos] = tinput_get_str(ti); 500 493 ti->hpos += offs; 501 502 int pad = (int) ti->nc - str_length(ti->history[ti->hpos]); 503 if (pad < 0) 504 pad = 0; 505 494 495 pad = ti->nc - str_length(ti->history[ti->hpos]); 496 if (pad < 0) pad = 0; 497 506 498 tinput_set_str(ti, ti->history[ti->hpos]); 507 499 tinput_display_tail(ti, 0, pad); … … 523 515 /** Read in one line of input. 524 516 * 525 * @param ti Text input. 526 * @param dstr Place to save pointer to new string. 527 * 528 * @return EOK on success 529 * @return ENOENT if user requested abort 530 * @return EIO if communication with console failed 531 * 517 * @param ti Text input. 518 * @param dstr Place to save pointer to new string. 519 * @return EOK on success, ENOENT if user requested abort, EIO 520 * if communication with console failed. 532 521 */ 533 522 int tinput_read(tinput_t *ti, char **dstr) 534 523 { 524 console_event_t ev; 525 char *str; 526 535 527 fflush(stdout); 528 536 529 if (console_get_size(fphone(stdin), &ti->con_cols, &ti->con_rows) != EOK) 537 530 return EIO; 538 539 531 if (console_get_pos(fphone(stdin), &ti->col0, &ti->row0) != EOK) 540 532 return EIO; 541 542 ti->pos = 0; 543 ti->sel_start = 0; 533 534 ti->pos = ti->sel_start = 0; 544 535 ti->nc = 0; 545 536 ti->buffer[0] = '\0'; 546 537 ti->done = false; 547 538 ti->exit_clui = false; 548 539 549 540 while (!ti->done) { 550 541 fflush(stdout); 551 552 console_event_t ev;553 542 if (!console_get_event(fphone(stdin), &ev)) 554 543 return EIO; 555 544 556 545 if (ev.type != KEY_PRESS) 557 546 continue; 558 559 if (( (ev.mods & KM_CTRL) != 0)&&560 ( (ev.mods & (KM_ALT | KM_SHIFT)) == 0))547 548 if ((ev.mods & KM_CTRL) != 0 && 549 (ev.mods & (KM_ALT | KM_SHIFT)) == 0) { 561 550 tinput_key_ctrl(ti, &ev); 562 563 if (((ev.mods & KM_SHIFT) != 0) && 564 ((ev.mods & (KM_CTRL | KM_ALT)) == 0)) 551 } 552 553 if ((ev.mods & KM_SHIFT) != 0 && 554 (ev.mods & (KM_CTRL | KM_ALT)) == 0) { 565 555 tinput_key_shift(ti, &ev); 566 567 if (((ev.mods & KM_CTRL) != 0) && 568 ((ev.mods & KM_SHIFT) != 0) && 569 ((ev.mods & KM_ALT) == 0)) 556 } 557 558 if ((ev.mods & KM_CTRL) != 0 && 559 (ev.mods & KM_SHIFT) != 0 && 560 (ev.mods & KM_ALT) == 0) { 570 561 tinput_key_ctrl_shift(ti, &ev); 571 572 if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) 562 } 563 564 if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) { 573 565 tinput_key_unmod(ti, &ev); 574 566 } 567 575 568 if (ev.c >= ' ') { 576 569 tinput_sel_delete(ti); … … 578 571 } 579 572 } 580 573 581 574 if (ti->exit_clui) 582 575 return ENOENT; 583 576 584 577 ti->pos = ti->nc; 585 578 tinput_position_caret(ti); 586 579 putchar('\n'); 587 588 char *str = tinput_get_str(ti);580 581 str = tinput_get_str(ti); 589 582 if (str_cmp(str, "") != 0) 590 583 tinput_history_insert(ti, str); 591 584 592 585 ti->hpos = 0; 593 586 594 587 *dstr = str; 595 588 return EOK; … … 707 700 break; 708 701 case KC_UP: 709 tinput_history_seek(ti, 1);702 tinput_history_seek(ti, +1); 710 703 break; 711 704 case KC_DOWN:
Note:
See TracChangeset
for help on using the changeset viewer.