summaryrefslogtreecommitdiff
path: root/src/bin/keyin.c
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2014-08-22 21:54:04 +0200
committerBoris Faure <billiob@gmail.com>2014-08-22 21:54:04 +0200
commit1ef2fbb8a309611873118488d997b9deeb3f2f0a (patch)
treea7f2162eb510829aa9ce9076d6b5e0374ab927bc /src/bin/keyin.c
parent117d9e784081f15f46797a1206ac48157e523e04 (diff)
refactor keys handling in termio: move to keyin, 2nd round!
Diffstat (limited to 'src/bin/keyin.c')
-rw-r--r--src/bin/keyin.c366
1 files changed, 365 insertions, 1 deletions
diff --git a/src/bin/keyin.c b/src/bin/keyin.c
index 9a0c44a..f2d02e6 100644
--- a/src/bin/keyin.c
+++ b/src/bin/keyin.c
@@ -1,5 +1,11 @@
1#include <Elementary.h> 1#include <Elementary.h>
2#include <Ecore_Input.h>
3#include <Ecore_IMF.h>
4#include <Ecore_IMF_Evas.h>
5#include "private.h"
2#include "termpty.h" 6#include "termpty.h"
7#include "termio.h"
8#include "termcmd.h"
3#include "keyin.h" 9#include "keyin.h"
4 10
5typedef struct _Keyout Keyout; 11typedef struct _Keyout Keyout;
@@ -12,6 +18,8 @@ struct _Keyout
12 int outlen; 18 int outlen;
13}; 19};
14 20
21
22
15#define KEY(in, out) {in, out, sizeof(in) - 1, sizeof(out) - 1} 23#define KEY(in, out) {in, out, sizeof(in) - 1, sizeof(out) - 1}
16 24
17static const Keyout crlf_keyout[] = 25static const Keyout crlf_keyout[] =
@@ -399,7 +407,107 @@ _key_try(Termpty *ty, const Keyout *map, const Evas_Event_Key_Down *ev)
399} 407}
400 408
401void 409void
402keyin_handle(Termpty *ty, const Evas_Event_Key_Down *ev, 410keyin_compose_seq_reset(Keys_Handler *khdl)
411{
412 char *str;
413
414 EINA_LIST_FREE(khdl->seq, str) eina_stringshare_del(str);
415 khdl->composing = EINA_FALSE;
416}
417
418static Eina_Bool
419_handle_alt_ctrl(const char *keyname, Evas_Object *term)
420{
421 if (!strcmp(keyname, "equal"))
422 termcmd_do(term, NULL, NULL, "f+");
423 else if (!strcmp(keyname, "minus"))
424 termcmd_do(term, NULL, NULL, "f-");
425 else if (!strcmp(keyname, "0"))
426 termcmd_do(term, NULL, NULL, "f");
427 else if (!strcmp(keyname, "9"))
428 termcmd_do(term, NULL, NULL, "fb");
429 else
430 return EINA_FALSE;
431
432 return EINA_TRUE;
433}
434
435static Eina_Bool
436_handle_shift(const Evas_Event_Key_Down *ev, Termpty *ty)
437{
438 if (!strcmp(ev->key, "Prior"))
439 {
440 if (!ty->altbuf)
441 {
442 termio_scroll_delta(ty->obj, 1, 1);
443 return EINA_TRUE;
444 }
445 return EINA_FALSE;
446 }
447 else if (!strcmp(ev->key, "Next"))
448 {
449 if (!ty->altbuf)
450 {
451 termio_scroll_delta(ty->obj, -1, 1);
452 return EINA_TRUE;
453 }
454 return EINA_FALSE;
455 }
456 else if (!strcmp(ev->key, "Up"))
457 {
458 if (!ty->altbuf)
459 {
460 termio_scroll_delta(ty->obj, 1, 0);
461 return EINA_TRUE;
462 }
463 return EINA_FALSE;
464 }
465 else if (!strcmp(ev->key, "Down"))
466 {
467 if (!ty->altbuf)
468 {
469 termio_scroll_delta(ty->obj, -1, 0);
470 return EINA_TRUE;
471 }
472 return EINA_FALSE;
473 }
474 else if (!strcmp(ev->key, "Insert"))
475 {
476 /*XXX CTRL*/
477 if (evas_key_modifier_is_set(ev->modifiers, "Control"))
478 termio_paste_selection(ty->obj, ELM_SEL_TYPE_CLIPBOARD);
479 else
480 termio_paste_selection(ty->obj, ELM_SEL_TYPE_PRIMARY);
481 }
482 else if (!strcmp(ev->key, "KP_Add"))
483 {
484 Config *config = termpty_config_get(ty);
485
486 if (config) termio_font_size_set(ty->obj, config->font.size + 1);
487 }
488 else if (!strcmp(ev->key, "KP_Subtract"))
489 {
490 Config *config = termpty_config_get(ty);
491
492 if (config) termio_font_size_set(ty->obj, config->font.size - 1);
493 }
494 else if (!strcmp(ev->key, "KP_Multiply"))
495 {
496 Config *config = termpty_config_get(ty);
497
498 if (config) termio_font_size_set(ty->obj, 10);
499 }
500 else if (!strcmp(ev->key, "KP_Divide"))
501 termio_take_selection(ty->obj, ELM_SEL_TYPE_CLIPBOARD);
502 else
503 return EINA_FALSE;
504
505 return EINA_TRUE;
506}
507
508
509static void
510_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
403 int alt, int shift, int ctrl) 511 int alt, int shift, int ctrl)
404{ 512{
405 if (!alt) 513 if (!alt)
@@ -513,3 +621,259 @@ keyin_handle(Termpty *ty, const Evas_Event_Key_Down *ev,
513 termpty_write(ty, ev->string, strlen(ev->string)); 621 termpty_write(ty, ev->string, strlen(ev->string));
514 } 622 }
515} 623}
624
625Eina_Bool
626keyin_handle(Keys_Handler *khdl, Termpty *ty, const Evas_Event_Key_Down *ev,
627 int alt, int shift, int ctrl)
628{
629 if ((!alt) && (ctrl) && (!shift))
630 {
631 if (!strcmp(ev->key, "Prior"))
632 {
633 keyin_compose_seq_reset(khdl);
634 evas_object_smart_callback_call(ty->obj, "prev", NULL);
635 return EINA_TRUE;
636 }
637 else if (!strcmp(ev->key, "Next"))
638 {
639 keyin_compose_seq_reset(khdl);
640 evas_object_smart_callback_call(ty->obj, "next", NULL);
641 return EINA_TRUE;
642 }
643 else if (!strcmp(ev->key, "1"))
644 {
645 keyin_compose_seq_reset(khdl);
646 evas_object_smart_callback_call(ty->obj, "tab,1", NULL);
647 return EINA_TRUE;
648 }
649 else if (!strcmp(ev->key, "2"))
650 {
651 keyin_compose_seq_reset(khdl);
652 evas_object_smart_callback_call(ty->obj, "tab,2", NULL);
653 return EINA_TRUE;
654 }
655 else if (!strcmp(ev->key, "3"))
656 {
657 keyin_compose_seq_reset(khdl);
658 evas_object_smart_callback_call(ty->obj, "tab,3", NULL);
659 return EINA_TRUE;
660 }
661 else if (!strcmp(ev->key, "4"))
662 {
663 keyin_compose_seq_reset(khdl);
664 evas_object_smart_callback_call(ty->obj, "tab,4", NULL);
665 return EINA_TRUE;
666 }
667 else if (!strcmp(ev->key, "5"))
668 {
669 keyin_compose_seq_reset(khdl);
670 evas_object_smart_callback_call(ty->obj, "tab,5", NULL);
671 return EINA_TRUE;
672 }
673 else if (!strcmp(ev->key, "6"))
674 {
675 keyin_compose_seq_reset(khdl);
676 evas_object_smart_callback_call(ty->obj, "tab,6", NULL);
677 return EINA_TRUE;
678 }
679 else if (!strcmp(ev->key, "7"))
680 {
681 keyin_compose_seq_reset(khdl);
682 evas_object_smart_callback_call(ty->obj, "tab,7", NULL);
683 return EINA_TRUE;
684 }
685 else if (!strcmp(ev->key, "8"))
686 {
687 keyin_compose_seq_reset(khdl);
688 evas_object_smart_callback_call(ty->obj, "tab,8", NULL);
689 return EINA_TRUE;
690 }
691 else if (!strcmp(ev->key, "9"))
692 {
693 keyin_compose_seq_reset(khdl);
694 evas_object_smart_callback_call(ty->obj, "tab,9", NULL);
695 return EINA_TRUE;
696 }
697 else if (!strcmp(ev->key, "0"))
698 {
699 keyin_compose_seq_reset(khdl);
700 evas_object_smart_callback_call(ty->obj, "tab,0", NULL);
701 return EINA_TRUE;
702 }
703 }
704 if ((!alt) && (ctrl) && (shift))
705 {
706 if (!strcmp(ev->key, "Prior"))
707 {
708 keyin_compose_seq_reset(khdl);
709 evas_object_smart_callback_call(ty->obj, "split,h", NULL);
710 return EINA_TRUE;
711 }
712 else if (!strcmp(ev->key, "Next"))
713 {
714 keyin_compose_seq_reset(khdl);
715 evas_object_smart_callback_call(ty->obj, "split,v", NULL);
716 return EINA_TRUE;
717 }
718 else if (!strcasecmp(ev->key, "t"))
719 {
720 keyin_compose_seq_reset(khdl);
721 evas_object_smart_callback_call(ty->obj, "new", NULL);
722 return EINA_TRUE;
723 }
724 else if (!strcmp(ev->key, "Home"))
725 {
726 keyin_compose_seq_reset(khdl);
727 evas_object_smart_callback_call(ty->obj, "select", NULL);
728 return EINA_TRUE;
729 }
730 else if (!strcasecmp(ev->key, "c"))
731 {
732 keyin_compose_seq_reset(khdl);
733 termio_take_selection(ty->obj, ELM_SEL_TYPE_CLIPBOARD);
734 return EINA_TRUE;
735 }
736 else if (!strcasecmp(ev->key, "v"))
737 {
738 keyin_compose_seq_reset(khdl);
739 termio_paste_selection(ty->obj, ELM_SEL_TYPE_CLIPBOARD);
740 return EINA_TRUE;
741 }
742 else if (!strcmp(ev->keyname, "h"))
743 {
744 term_miniview_toggle(termio_term_get(ty->obj));
745 return EINA_TRUE;
746 }
747 }
748 if ((alt) && (!shift) && (!ctrl))
749 {
750 if (!strcmp(ev->key, "Home"))
751 {
752 keyin_compose_seq_reset(khdl);
753 evas_object_smart_callback_call(ty->obj, "cmdbox", NULL);
754 return EINA_TRUE;
755 }
756 }
757 if ((alt) && (ctrl) && (!shift))
758 {
759 if (_handle_alt_ctrl(ev->key, ty->obj))
760 {
761 keyin_compose_seq_reset(khdl);
762 return EINA_TRUE;
763 }
764 }
765 if (shift)
766 {
767 if (_handle_shift(ev, ty))
768 {
769 keyin_compose_seq_reset(khdl);
770 return EINA_TRUE;
771 }
772 }
773
774
775 /* actions => return Eina_True */
776
777 /* composing */
778 if (khdl->imf)
779 {
780 // EXCEPTION. Don't filter modifiers alt+shift -> breaks emacs
781 // and jed (alt+shift+5 for search/replace for example)
782 // Don't filter modifiers alt, is used by shells
783 if ((!alt) && (!ctrl))
784 {
785 Ecore_IMF_Event_Key_Down imf_ev;
786
787 ecore_imf_evas_event_key_down_wrap((Evas_Event_Key_Down*)ev, &imf_ev);
788 if (!khdl->composing)
789 {
790 if (ecore_imf_context_filter_event
791 (khdl->imf, ECORE_IMF_EVENT_KEY_DOWN, (Ecore_IMF_Event *)&imf_ev))
792 goto end;
793 }
794 }
795 }
796
797 // if term app asked for kbd lock - dont handle here
798 if (ty->state.kbd_lock) return EINA_TRUE;
799 // if app asked us to not do autorepeat - ignore press if is it is the same
800 // timestamp as last one
801 if ((ty->state.no_autorepeat) &&
802 (ev->timestamp == khdl->last_keyup)) return EINA_TRUE;
803 if (!khdl->composing)
804 {
805 Ecore_Compose_State state;
806 char *compres = NULL;
807
808 keyin_compose_seq_reset(khdl);
809 khdl->seq = eina_list_append(khdl->seq, eina_stringshare_add(ev->key));
810 state = ecore_compose_get(khdl->seq, &compres);
811 if (state == ECORE_COMPOSE_MIDDLE) khdl->composing = EINA_TRUE;
812 else khdl->composing = EINA_FALSE;
813 if (!khdl->composing) keyin_compose_seq_reset(khdl);
814 else goto end;
815 }
816 else
817 {
818 Ecore_Compose_State state;
819 char *compres = NULL;
820
821 if (key_is_modifier(ev->key)) goto end;
822 khdl->seq = eina_list_append(khdl->seq, eina_stringshare_add(ev->key));
823 state = ecore_compose_get(khdl->seq, &compres);
824 if (state == ECORE_COMPOSE_NONE) keyin_compose_seq_reset(khdl);
825 else if (state == ECORE_COMPOSE_DONE)
826 {
827 keyin_compose_seq_reset(khdl);
828 if (compres)
829 {
830 termpty_write(ty, compres, strlen(compres));
831 free(compres);
832 compres = NULL;
833 }
834 goto end;
835 }
836 else goto end;
837 }
838
839
840 _handle_key_to_pty(ty, ev, alt, shift, ctrl);
841
842
843end:
844 return EINA_FALSE;
845}
846
847Eina_Bool
848key_is_modifier(const char *key)
849{
850#define STATIC_STR_EQUAL(STR) (!strncmp(key, STR, strlen(STR)))
851 if ((key != NULL) && (
852 STATIC_STR_EQUAL("Shift") ||
853 STATIC_STR_EQUAL("Control") ||
854 STATIC_STR_EQUAL("Alt") ||
855 STATIC_STR_EQUAL("Meta") ||
856 STATIC_STR_EQUAL("Super") ||
857 STATIC_STR_EQUAL("Hyper") ||
858 STATIC_STR_EQUAL("Scroll_Lock") ||
859 STATIC_STR_EQUAL("Num_Lock") ||
860 STATIC_STR_EQUAL("ISO_Level3_Shift") ||
861 STATIC_STR_EQUAL("Caps_Lock")))
862 return EINA_TRUE;
863#undef STATIC_STR_EQUAL
864 return EINA_FALSE;
865}
866
867void
868keyin_handle_up(Keys_Handler *khdl, Evas_Event_Key_Up *ev)
869{
870 khdl->last_keyup = ev->timestamp;
871 if (khdl->imf)
872 {
873 Ecore_IMF_Event_Key_Up imf_ev;
874 ecore_imf_evas_event_key_up_wrap(ev, &imf_ev);
875 if (ecore_imf_context_filter_event
876 (khdl->imf, ECORE_IMF_EVENT_KEY_UP, (Ecore_IMF_Event *)&imf_ev))
877 return;
878 }
879}