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