58 |
int state; |
int state; |
59 |
int esc1; |
int esc1; |
60 |
int shifted; |
int shifted; |
61 |
|
int grab_keys; |
62 |
EditBuffer *b; |
EditBuffer *b; |
63 |
EditBuffer *b_color; /* color buffer, one byte per char */ |
EditBuffer *b_color; /* color buffer, one byte per char */ |
64 |
int is_shell; /* only used to display final message */ |
int is_shell; /* only used to display final message */ |
431 |
e->offset = s->cur_offset; |
e->offset = s->cur_offset; |
432 |
} |
} |
433 |
|
|
434 |
|
void shell_key(void *opaque, int key) |
435 |
|
{ |
436 |
|
ShellState *s = opaque; |
437 |
|
char buf[10]; |
438 |
|
const char *p; |
439 |
|
int len; |
440 |
|
|
441 |
|
if (key == KEY_CTRL('o')) { |
442 |
|
qe_ungrab_keys(); |
443 |
|
unget_key(key); |
444 |
|
return; |
445 |
|
} |
446 |
|
p = buf; |
447 |
|
len = -1; |
448 |
|
switch (key) { |
449 |
|
case KEY_UP: p = s->kcuu1; break; |
450 |
|
case KEY_DOWN: p = s->kcud1; break; |
451 |
|
case KEY_RIGHT: p = s->kcuf1; break; |
452 |
|
case KEY_LEFT: p = s->kcub1; break; |
453 |
|
//case KEY_CTRL_UP: |
454 |
|
//case KEY_CTRL_DOWN: |
455 |
|
//case KEY_CTRL_RIGHT: |
456 |
|
//case KEY_CTRL_LEFT: |
457 |
|
//case KEY_CTRL_END: |
458 |
|
//case KEY_CTRL_HOME: |
459 |
|
//case KEY_CTRL_PAGEUP: |
460 |
|
//case KEY_CTRL_PAGEDOWN: |
461 |
|
case KEY_SHIFT_TAB: p = s->kcbt; break; |
462 |
|
case KEY_HOME: p = s->khome; break; |
463 |
|
case KEY_INSERT: p = s->kich1; break; |
464 |
|
case KEY_DELETE: p = s->kdch1; break; |
465 |
|
case KEY_END: p = s->kend; break; |
466 |
|
case KEY_PAGEUP: p = s->kpp; break; |
467 |
|
case KEY_PAGEDOWN: p = s->knp; break; |
468 |
|
case KEY_F1: p = s->kf1; break; |
469 |
|
case KEY_F2: p = s->kf2; break; |
470 |
|
case KEY_F3: p = s->kf3; break; |
471 |
|
case KEY_F4: p = s->kf4; break; |
472 |
|
case KEY_F5: p = s->kf5; break; |
473 |
|
case KEY_F6: p = s->kf6; break; |
474 |
|
case KEY_F7: p = s->kf7; break; |
475 |
|
case KEY_F8: p = s->kf8; break; |
476 |
|
case KEY_F9: p = s->kf9; break; |
477 |
|
case KEY_F10: p = s->kf10; break; |
478 |
|
case KEY_F11: p = s->kf11; break; |
479 |
|
case KEY_F12: p = s->kf12; break; |
480 |
|
case KEY_F13: p = s->kf13; break; |
481 |
|
case KEY_F14: p = s->kf14; break; |
482 |
|
case KEY_F15: p = s->kf15; break; |
483 |
|
case KEY_F16: p = s->kf16; break; |
484 |
|
case KEY_F17: p = s->kf17; break; |
485 |
|
case KEY_F18: p = s->kf18; break; |
486 |
|
case KEY_F19: p = s->kf19; break; |
487 |
|
case KEY_F20: p = s->kf20; break; |
488 |
|
default: |
489 |
|
if (key < 256) { |
490 |
|
buf[0] = key; |
491 |
|
len = 1; |
492 |
|
} else |
493 |
|
if (key >= KEY_META(0) && key <= KEY_META(255)) { |
494 |
|
buf[0] = '\033'; |
495 |
|
buf[1] = key; |
496 |
|
len = 2; |
497 |
|
} else { |
498 |
|
p = NULL; |
499 |
|
} |
500 |
|
} |
501 |
|
if (p) |
502 |
|
tty_write(s, p, len); |
503 |
|
} |
504 |
|
|
505 |
static void tty_emulate(ShellState *s, int c) |
static void tty_emulate(ShellState *s, int c) |
506 |
{ |
{ |
507 |
int i, offset, offset1, offset2, n; |
int i, offset, offset1, offset2, n; |
508 |
unsigned char buf1[10]; |
unsigned char buf1[10]; |
509 |
|
|
510 |
#define ESC2(c1,c2) (((c1)<<8)|((unsigned char)c2)) |
#define ESC2(c1,c2) (((c1)<<8)|((unsigned char)c2)) |
511 |
|
/* some bytes are state independent */ |
512 |
|
switch (c) { |
513 |
|
case 0x18: |
514 |
|
case 0x1A: |
515 |
|
s->state = TTY_STATE_NORM; |
516 |
|
return; |
517 |
|
case 0x1B: |
518 |
|
s->state = TTY_STATE_ESC; |
519 |
|
return; |
520 |
|
#if 0 |
521 |
|
case 0x9B: |
522 |
|
goto csi_entry; |
523 |
|
#endif |
524 |
|
} |
525 |
|
|
526 |
switch (s->state) { |
switch (s->state) { |
527 |
case TTY_STATE_NORM: |
case TTY_STATE_NORM: |
528 |
switch(c) { |
switch (c) { |
529 |
case 8: |
/* BEL Bell (Ctrl-G) */ |
530 |
|
/* FF Form Feed or New Page (NP) (Ctrl-L) same as LF */ |
531 |
|
/* TAB Horizontal Tab (HT) (Ctrl-I) */ |
532 |
|
/* VT Vertical Tab (Ctrl-K) same as LF */ |
533 |
|
|
534 |
|
case 8: /* ^H BS = backspace */ |
535 |
{ |
{ |
536 |
int c1; |
int c1; |
537 |
c1 = eb_prevc(s->b, s->cur_offset, &offset); |
c1 = eb_prevc(s->b, s->cur_offset, &offset); |
539 |
s->cur_offset = offset; |
s->cur_offset = offset; |
540 |
} |
} |
541 |
break; |
break; |
542 |
case 10: |
case 10: /* ^J NL = line feed */ |
543 |
/* go to next line */ |
/* go to next line */ |
544 |
|
/* CG: should check if column should be kept */ |
545 |
offset = s->cur_offset; |
offset = s->cur_offset; |
546 |
for(;;) { |
for (;;) { |
547 |
if (offset == s->b->total_size) { |
if (offset == s->b->total_size) { |
548 |
/* add a new line */ |
/* add a new line */ |
549 |
buf1[0] = '\n'; |
buf1[0] = '\n'; |
557 |
} |
} |
558 |
s->cur_offset = offset; |
s->cur_offset = offset; |
559 |
break; |
break; |
560 |
case 13: |
case 13: /* ^M CR = carriage return */ |
561 |
/* move to bol */ |
/* move to bol */ |
562 |
for(;;) { |
for (;;) { |
563 |
c = eb_prevc(s->b, s->cur_offset, &offset1); |
c = eb_prevc(s->b, s->cur_offset, &offset1); |
564 |
if (c == '\n') |
if (c == '\n') |
565 |
break; |
break; |
566 |
s->cur_offset = offset1; |
s->cur_offset = offset1; |
567 |
} |
} |
568 |
break; |
break; |
569 |
case 14: |
case 14: /* ^N SO = shift out */ |
570 |
s->shifted = 1; |
s->shifted = 1; |
571 |
break; |
break; |
572 |
case 15: |
case 15: /* ^O SI = shift in */ |
573 |
s->shifted = 0; |
s->shifted = 0; |
574 |
break; |
break; |
|
case 27: |
|
|
s->state = TTY_STATE_ESC; |
|
|
break; |
|
575 |
default: |
default: |
576 |
if (c >= 32 || c == 9) { |
if (c >= 32 || c == 9) { |
577 |
int c1, cur_len, len; |
int c1, cur_len, len; |
679 |
/* 1047, 1048 -> cup mode: |
/* 1047, 1048 -> cup mode: |
680 |
* should grab all keys while active! |
* should grab all keys while active! |
681 |
*/ |
*/ |
682 |
|
if (s->esc_params[0] == 1047) { |
683 |
|
s->grab_keys = 1; |
684 |
|
qe_grab_keys(shell_key, s); |
685 |
|
} |
686 |
|
break; |
687 |
case ESC2('?','l'): /* reset terminal mode */ |
case ESC2('?','l'): /* reset terminal mode */ |
688 |
|
if (s->esc_params[0] == 1047) { |
689 |
|
qe_ungrab_keys(); |
690 |
|
s->grab_keys = 0; |
691 |
|
} |
692 |
break; |
break; |
693 |
case 'A': |
case 'A': |
694 |
/* move relative up */ |
/* move relative up */ |
700 |
break; |
break; |
701 |
case 'C': |
case 'C': |
702 |
/* move relative forward */ |
/* move relative forward */ |
703 |
tty_gotoxy(s, -(s->esc_params[0] + 1 - s->has_params[0]), 0, 1); |
tty_gotoxy(s, (s->esc_params[0] + 1 - s->has_params[0]), 0, 1); |
704 |
break; |
break; |
705 |
case 'D': |
case 'D': |
706 |
/* move relative backward */ |
/* move relative backward */ |
707 |
tty_gotoxy(s, (s->esc_params[0] + 1 - s->has_params[0]), 0, 1); |
tty_gotoxy(s, -(s->esc_params[0] + 1 - s->has_params[0]), 0, 1); |
708 |
break; |
break; |
709 |
case 'H': |
case 'H': |
710 |
/* goto xy */ |
/* goto xy */ |
821 |
} |
} |
822 |
} |
} |
823 |
|
|
824 |
static int shell_get_colorized_line(EditState *e, unsigned int *buf, int buf_size, |
static int shell_get_colorized_line(EditState *e, |
825 |
|
unsigned int *buf, int buf_size, |
826 |
int offset, int line_num) |
int offset, int line_num) |
827 |
{ |
{ |
828 |
EditBuffer *b = e->b; |
EditBuffer *b = e->b; |
917 |
} |
} |
918 |
|
|
919 |
/* remove shell input mode */ |
/* remove shell input mode */ |
920 |
for(e = qs->first_window; e != NULL; e = e->next_window) { |
s->grab_keys = 0; |
921 |
|
qe_ungrab_keys(); |
922 |
|
for (e = qs->first_window; e != NULL; e = e->next_window) { |
923 |
if (e->b == b) |
if (e->b == b) |
924 |
e->interactive = 0; |
e->interactive = 0; |
925 |
} |
} |
1144 |
void do_shell_toggle_input(EditState *e) |
void do_shell_toggle_input(EditState *e) |
1145 |
{ |
{ |
1146 |
e->interactive = !e->interactive; |
e->interactive = !e->interactive; |
1147 |
|
if (e->interactive) { |
1148 |
|
ShellState *s = e->b->priv_data; |
1149 |
|
if (s->grab_keys) |
1150 |
|
qe_grab_keys(shell_key, s); |
1151 |
|
} |
1152 |
#if 0 |
#if 0 |
1153 |
if (e->interactive) { |
if (e->interactive) { |
1154 |
ShellState *s = e->b->priv_data; |
ShellState *s = e->b->priv_data; |